"use client";
import { AnimatePresence, motion } from "motion/react";
import { FrameMode, Palette } from "../lib/tokens";
import { IconBtn, Segmented, TidyButton, TidyState } from "./ui";
import { ShareButton } from "./ShareMenu";
import { Icon } from "./M3Node";
import { Popover } from "./Menus";
import { t, useLang } from "../lib/i18n";
export type Mode = "select" | "hand";
const REPO_URL = "https://github.com/lnkiai/m3e-canvas";
export function GitHubLink({ p, size = 40 }: { p: Palette; size?: number }) {
return (
);
}
function Pill({ p, children }: { p: Palette; children: React.ReactNode }) {
return (
{children}
);
}
export function Toolbar({
p,
mode,
onMode,
frame,
zoom,
onZoom,
onFit,
canUndo,
canRedo,
onUndo,
onRedo,
onClear,
onAddFrame,
onPreview,
rightInset,
mobile,
onPrompt,
onSettings,
onLangSheet,
tidy,
onTidy,
note,
onSaveProject,
onOpenProject,
onShare,
shareState = "idle",
onDraftKeep,
onDraftUndo,
onDraftSave,
quickUndo,
}: {
p: Palette;
mode: Mode;
onMode: (m: Mode) => void;
frame: FrameMode;
onFrame: (f: FrameMode) => void;
zoom: number;
onZoom: (z: number) => void;
onFit: () => void;
canUndo: boolean;
canRedo: boolean;
onUndo: () => void;
onRedo: () => void;
onClear: () => void;
onAddFrame: () => void;
onPreview: () => void;
/** width of the open right panel, so the zoom pill slides out of its way */
rightInset: number;
mobile?: boolean;
onPrompt?: () => void;
onSettings?: () => void;
/** phone: open the language sheet instead of the menu */
onLangSheet?: () => void;
/** the tidy button for the screen being worked on; absent when no screen is in play */
tidy?: TidyState;
onTidy?: () => void;
/** a short message shown beside the tidy button for a moment */
note?: { text: string; icon: string } | null;
onSaveProject?: () => void;
onOpenProject?: () => void;
/** opens the "ask an AI" dialog from the left end of the zoom row */
onShare?: () => void;
/** busy while a model drafts; review while the draft waits to be kept or undone */
shareState?: "idle" | "busy" | "review";
onDraftKeep?: () => void;
onDraftUndo?: () => void;
/** saves the arrived design as a project file, the same as the header's save */
onDraftSave?: () => void;
/** after a kept draft: the header's undo, shown beside the opener so the previous design stays a tap away */
quickUndo?: boolean;
}) {
const lang = useLang();
if (mobile) {
const S = 42;
return (