@pixerate/editor-react 0.78.1 → 0.79.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animation-editor/index.cjs +679 -37
- package/dist/animation-editor/index.cjs.map +1 -1
- package/dist/animation-editor/index.d.cts +29 -3
- package/dist/animation-editor/index.d.ts +29 -3
- package/dist/animation-editor/index.js +128 -37
- package/dist/animation-editor/index.js.map +1 -1
- package/dist/{chunk-S5SSL3ZO.js → chunk-BVP43EWA.js} +2 -2
- package/dist/{chunk-7RMNM3KC.js → chunk-WOQ3H7KA.js} +4 -4
- package/dist/chunk-WOQ3H7KA.js.map +1 -0
- package/dist/effects/index.cjs +3 -3
- package/dist/effects/index.cjs.map +1 -1
- package/dist/effects/index.d.cts +4 -2
- package/dist/effects/index.d.ts +4 -2
- package/dist/effects/index.js +1 -1
- package/dist/image-editor/index.cjs +3 -3
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.js +2 -2
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/vector/index.cjs +649 -9
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +27 -3
- package/dist/vector/index.d.ts +27 -3
- package/dist/vector/index.js +98 -9
- package/dist/vector/index.js.map +1 -1
- package/dist/video-editor/index.cjs +3 -3
- package/dist/video-editor/index.cjs.map +1 -1
- package/dist/video-editor/index.js +1 -1
- package/package.json +3 -3
- package/dist/chunk-7RMNM3KC.js.map +0 -1
- /package/dist/{chunk-S5SSL3ZO.js.map → chunk-BVP43EWA.js.map} +0 -0
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/hooks/usePromptEditor.ts","../src/hooks/useEditor.ts","../src/hooks/useNavigationGuard.ts","../src/hooks/useDismissGuard.ts","../src/hooks/useHistory.ts","../src/hooks/useHistoryDirty.ts","../src/hooks/useHistoryShortcuts.ts","../src/hooks/useFileImport.ts","../src/hooks/useDocxExport.ts","../src/components/ExportDocxButton.tsx","../src/hooks/useAgentToolProvider.ts","../src/hooks/useToolBridge.ts","../src/components/EditorContent.tsx","../src/components/BubbleMenu.tsx","../src/components/TemplateRenderer.tsx","../src/components/VariableForm.tsx","../src/components/MergePreview.tsx","../src/hooks/useMergePreview.ts","../src/hooks/useOutline.ts","../src/components/OutlinePanel.tsx","../src/hooks/useParagraphStyles.ts","../src/components/StylesGallery.tsx","../src/spreadsheet/useSpreadsheetEditor.ts","../src/spreadsheet/SpreadsheetEditor.tsx","../src/spreadsheet/SpreadsheetContextMenu.tsx","../src/spreadsheet/SpreadsheetGroupRow.tsx","../src/spreadsheet/useSpreadsheetTableInteractions.ts","../src/spreadsheet/SpreadsheetValidationDialog.tsx","../src/spreadsheet/SpreadsheetRulePanels.tsx","../src/spreadsheet/useSpreadsheetViewport.ts","../src/spreadsheet/FormulaHints.tsx","../src/spreadsheet/SheetTabs.tsx","../src/spreadsheet/NameManager.tsx","../src/slots.tsx","../src/image-editor/useImageEditor.ts","../src/image-editor/ImageEditor.tsx","../src/image-editor/ControlSlider.tsx","../src/image-editor/Histogram.tsx","../src/image-editor/AdjustmentLayersPanel.tsx","../src/image-editor/CurvesEditor.tsx","../src/image-editor/LayersPanel.tsx","../src/image-editor/LayerEffectsPanel.tsx","../src/image-editor/ImageProviderEffectsPanel.tsx","../src/effects/useEffects.ts","../src/effects/EffectThumbnail.tsx","../src/effects/EffectsBrowser.tsx","../src/effects/EffectParameters.tsx","../src/parameters/fields.tsx","../src/image-editor/BrushOptionsBar.tsx","../src/image-editor/PaintGradientEditor.tsx","../src/paint-editor/PaintGradientEditorView.tsx","../src/image-editor/ColorProfilePanel.tsx","../src/image-editor/SelectionOptionsBar.tsx","../src/image-editor/RefineEdgePanel.tsx","../src/image-editor/FreeTransformOptionsBar.tsx","../src/image-editor/ShapeOptionsBar.tsx","../src/image-editor/TypeOptionsBar.tsx","../src/review/useReview.ts","../src/review/CommentsPanel.tsx","../src/review/ReviewToolbar.tsx","../src/review/CommentButton.tsx","../src/review/useDocumentCompare.ts","../src/review/TrackedChangesList.tsx","../src/commands/useCommandPalette.ts","../src/commands/CommandPalette.tsx","../src/commands/useCommandShortcuts.ts","../src/persistence/useAutosave.ts","../src/persistence/RecoveryPrompt.tsx","../src/generation/useGenerationPlan.ts","../src/generation/GenerationSettings.tsx","../src/generation/JobProgress.tsx","../src/generation/AssetMentionChips.tsx","../src/generation/GenerationHistory.tsx","../src/find-replace/useFindReplace.ts","../src/find-replace/FindReplaceBar.tsx","../src/tables/useTableMenu.ts","../src/tables/TableToolbar.tsx","../src/tables/InsertTableGrid.tsx","../src/tables/TableBubbleMenu.tsx","../src/chart-node/ChartNodeView.tsx","../src/chart/ChartCanvas.tsx","../src/chart/useChartEditor.ts","../src/chart/ChartDataGrid.tsx","../src/chart/styles.ts","../src/chart/ChartInspector.tsx"],"sourcesContent":["export * from \"./hooks/usePromptEditor\";\nexport * from \"./hooks/useEditor\";\nexport * from \"./hooks/useNavigationGuard\";\nexport * from \"./hooks/useDismissGuard\";\nexport * from \"./hooks/useHistory\";\nexport * from \"./hooks/useHistoryDirty\";\nexport * from \"./hooks/useHistoryShortcuts\";\nexport * from \"./hooks/useFileImport\";\nexport * from \"./hooks/useDocxExport\";\nexport * from \"./components/ExportDocxButton\";\nexport * from \"./hooks/useAgentToolProvider\";\nexport * from \"./hooks/useToolBridge\";\nexport * from \"./components/EditorContent\";\nexport * from \"./components/BubbleMenu\";\nexport * from \"./components/TemplateRenderer\";\nexport * from \"./components/VariableForm\";\nexport * from \"./components/MergePreview\";\nexport * from \"./hooks/useMergePreview\";\nexport * from \"./hooks/useOutline\";\nexport * from \"./components/OutlinePanel\";\nexport * from \"./hooks/useParagraphStyles\";\nexport * from \"./components/StylesGallery\";\n\n// Re-export core types for easy consumer access\nexport {\n DirtyTracker,\n createDirtyTracker,\n defaultIsEqual,\n HistoryManager,\n createHistoryManager,\n bindDirtyToHistory,\n withoutDirty,\n} from \"@pixerate/editor\";\nexport type {\n Template,\n TemplateVersion,\n Token,\n TokenType,\n ColorGradient,\n RichTextPresetOptions,\n DirtyTrackerOptions,\n Command,\n HistoryState,\n HistoryManagerOptions,\n HistoryEntry,\n HistoryMark,\n MergedExecutionOptions,\n HistoryDirtyBinding,\n BindDirtyToHistoryOptions,\n} from \"@pixerate/editor\";\nexport type {\n PromptValues,\n PromptDiagnostic,\n VariableFormField,\n MergeDataSource,\n MergeRecord,\n MergeRecordsResult,\n MergeOutput,\n} from \"@pixerate/editor\";\n\nexport * from \"./spreadsheet\";\nexport * from \"./slots\";\nexport * from \"./image-editor\";\nexport * from \"./review\";\nexport * from \"./commands\";\nexport * from \"./persistence\";\nexport * from \"./generation\";\nexport * from \"./find-replace\";\nexport * from \"./tables\";\nexport * from \"./chart-node\";\n","import { useMemo, useEffect, useRef } from \"react\";\nimport { useEditor } from \"@tiptap/react\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport Placeholder from \"@tiptap/extension-placeholder\";\nimport { Slice } from \"@tiptap/pm/model\";\nimport {\n Template,\n ColorGradient,\n GradientText,\n TemplateSuggestions,\n LoadingNode,\n plainTextToTipTapHtml,\n plainTextToSlice,\n getEditorText,\n tokenizePrompt,\n FileImport,\n type FileImportOptions,\n} from \"@pixerate/editor\";\n\nexport interface UsePromptEditorProps {\n /**\n * The editor content as plain text. Changes from the parent (e.g. clearing\n * after submit) are applied to the editor; echoes of the editor's own\n * updates via `onContentChange` are ignored.\n */\n content: string;\n /** Callback fired when the editor content changes (returns plain text) */\n onContentChange: (text: string) => void;\n /** List of available templates to be suggested and highlighted */\n templates?: Template[];\n /** Custom gradient color map for templates */\n templateColorMap?: Map<string, ColorGradient>;\n /** Whether the editor is editable */\n isEditing?: boolean;\n /** Placeholder text for the editor */\n placeholder?: string;\n /** Additional CSS classes for the editor container */\n className?: string;\n /** Callback fired when the Escape key is pressed */\n onEscape?: () => void;\n /** Custom keydown handler. Return true to prevent default behavior */\n onKeyDown?: (event: KeyboardEvent) => boolean;\n /** Callback fired when text selection changes */\n onSelectionChange?: (selection: { from: number; to: number } | null) => void;\n /** Callback fired when a slash command (e.g., /template) matches */\n onSlashCommandMatch?: (\n match: RegExpMatchArray,\n from: number,\n to: number,\n coords: { top: number; left: number },\n ) => void;\n /** Callback to dismiss/clear the active slash command */\n clearSlashCommand?: () => void;\n /** Whether a slash command menu is currently active */\n slashCommandActive?: boolean;\n /**\n * Callback fired the first time each milestone is reached while the editor\n * is mounted: `used_variable` ({variable}) and `used_magic` (__instruction__).\n */\n onMilestone?: (milestone: string) => void;\n /** DOM element ID of the container, used for positioning popovers */\n containerId?: string;\n /** Variable names originating from structured JSON output steps */\n jsonVariables?: string[];\n /** Animation speed for gradient decorations */\n speed?: number;\n /**\n * Import text from .md, .html, .txt and .rtf files dropped onto the editor\n * (opt-in). Content is always inserted as plain text. Pasting keeps the\n * plain-text paste handler, so pasted files are not imported.\n */\n fileImport?: Omit<FileImportOptions, \"asPlainText\"> | boolean;\n}\n\nconst DEFAULT_TEMPLATES: Template[] = [];\nconst DEFAULT_COLOR_MAP = new Map<string, ColorGradient>([\n [\"default\", { from: \"#f43f5e\", to: \"#8b5cf6\" }],\n]);\nconst DEFAULT_CLASS_NAME =\n \"w-full border border-input rounded-md p-3 font-mono text-sm leading-relaxed focus:outline-none focus:ring-2 focus:ring-primary whitespace-pre-wrap break-words\";\n\nconst normalizeNewlines = (text: string) => text.replace(/\\r\\n?/g, \"\\n\");\n\nexport function usePromptEditor({\n content,\n onContentChange,\n templates = DEFAULT_TEMPLATES,\n templateColorMap: userColorMap,\n isEditing = true,\n placeholder = \"Write a prompt, use {{template}}, {variable}, or /command...\",\n className,\n onEscape,\n onKeyDown,\n onSelectionChange,\n onSlashCommandMatch,\n clearSlashCommand,\n slashCommandActive = false,\n onMilestone,\n containerId = \"editor-container\",\n jsonVariables,\n speed = 2,\n fileImport,\n}: UsePromptEditorProps) {\n const fileImportRef = useRef(fileImport);\n fileImportRef.current = fileImport;\n const fileImportEnabled = !!fileImport;\n\n const slashCommandActiveRef = useRef(slashCommandActive);\n slashCommandActiveRef.current = slashCommandActive;\n\n const clearSlashCommandRef = useRef(clearSlashCommand);\n clearSlashCommandRef.current = clearSlashCommand;\n\n const onEscapeRef = useRef(onEscape);\n onEscapeRef.current = onEscape;\n\n const onKeyDownRef = useRef(onKeyDown);\n onKeyDownRef.current = onKeyDown;\n\n const onSelectionChangeRef = useRef(onSelectionChange);\n onSelectionChangeRef.current = onSelectionChange;\n\n const onSlashCommandMatchRef = useRef(onSlashCommandMatch);\n onSlashCommandMatchRef.current = onSlashCommandMatch;\n\n const onContentChangeRef = useRef(onContentChange);\n onContentChangeRef.current = onContentChange;\n\n const onMilestoneRef = useRef(onMilestone);\n onMilestoneRef.current = onMilestone;\n\n const containerIdRef = useRef(containerId);\n containerIdRef.current = containerId;\n\n const templateKey = useMemo(() => {\n return (templates || [])\n .map((t) => `${t.id || t.name}:${(t as any).latestVersion || \"\"}`)\n .sort()\n .join(\",\");\n }, [templates]);\n\n // Key the color map by value so an inline `new Map(...)` does not recreate\n // the editor on every render.\n const colorMapKey = userColorMap\n ? JSON.stringify(Array.from(userColorMap.entries()))\n : \"\";\n const resolvedColorMap = useMemo(() => {\n if (userColorMap) return userColorMap;\n const map = new Map<string, ColorGradient>();\n templates.forEach((t) => {\n map.set(t.name, { from: \"#f43f5e\", to: \"#8b5cf6\" });\n });\n return map.size > 0 ? map : DEFAULT_COLOR_MAP;\n }, [colorMapKey, templateKey]);\n\n const jsonVariablesKey = (jsonVariables || []).join(\"\\u0000\");\n\n const reachedMilestonesRef = useRef(new Set<string>());\n\n const StarterKitExt =\n (StarterKit as any)?.configure\n ? StarterKit\n : (StarterKit as any)?.default?.configure\n ? (StarterKit as any)?.default\n : StarterKit;\n\n const PlaceholderExt =\n (Placeholder as any)?.configure\n ? Placeholder\n : (Placeholder as any)?.default?.configure\n ? (Placeholder as any)?.default\n : Placeholder;\n\n const editor = useEditor(\n {\n immediatelyRender: false,\n enablePasteRules: false,\n enableInputRules: false,\n editable: isEditing,\n extensions: [\n StarterKitExt.configure({\n heading: false,\n codeBlock: false,\n }),\n PlaceholderExt.configure({ placeholder }),\n GradientText.configure({\n templateColorMap: resolvedColorMap,\n speed,\n jsonVariables,\n }),\n TemplateSuggestions.configure({\n templates,\n }),\n LoadingNode,\n ...(fileImportEnabled\n ? [\n FileImport.configure({\n ...(typeof fileImportRef.current === \"object\" ? fileImportRef.current : {}),\n // Prompt editors only ever receive plain text.\n asPlainText: true,\n }),\n ]\n : []),\n ],\n content: plainTextToTipTapHtml(content),\n onUpdate: ({ editor: ed }) => {\n const plainText = getEditorText(ed);\n onContentChangeRef.current?.(plainText);\n\n if (onMilestoneRef.current) {\n const reached = reachedMilestonesRef.current;\n for (const token of tokenizePrompt(plainText)) {\n const milestone =\n token.type === \"variable\"\n ? \"used_variable\"\n : token.type === \"instruction\"\n ? \"used_magic\"\n : null;\n if (milestone && !reached.has(milestone)) {\n reached.add(milestone);\n onMilestoneRef.current(milestone);\n }\n }\n }\n\n const { state, view } = ed;\n const { selection } = state;\n const { $from, from, to } = selection;\n\n onSelectionChangeRef.current?.({ from, to });\n\n if (onSlashCommandMatchRef.current && clearSlashCommandRef.current) {\n const textBeforeCursor = $from?.parent?.textBetween\n ? $from.parent.textBetween(0, $from.parentOffset)\n : \"\";\n const slashMatch = textBeforeCursor.match(\n /(?:^|\\s)\\/([a-zA-Z0-9_-]*)$/,\n );\n\n if (slashMatch) {\n const coords = view.coordsAtPos($from.pos);\n const containerEl =\n document.getElementById(containerIdRef.current) ||\n document.getElementById(\"editor-container\") ||\n (view.dom.closest?.(\".relative\") as HTMLElement | null);\n const containerCoords = containerEl?.getBoundingClientRect();\n\n if (containerCoords) {\n onSlashCommandMatchRef.current(\n slashMatch,\n $from.pos -\n slashMatch[0].length +\n (slashMatch[0].startsWith(\" \") ? 1 : 0),\n $from.pos,\n {\n top: coords.bottom - containerCoords.top + 5,\n left: coords.left - containerCoords.left,\n },\n );\n }\n } else {\n clearSlashCommandRef.current();\n }\n }\n },\n onSelectionUpdate: ({ editor: ed }) => {\n const { from, to } = ed.state.selection;\n onSelectionChangeRef.current?.({ from, to });\n },\n editorProps: {\n attributes: {\n class: className || DEFAULT_CLASS_NAME,\n role: \"textbox\",\n \"aria-label\": \"Prompt editor\",\n },\n handleKeyDown(view, event) {\n if (slashCommandActiveRef.current) {\n if (\n event.key === \"ArrowUp\" ||\n event.key === \"ArrowDown\" ||\n event.key === \"Enter\"\n ) {\n event.preventDefault();\n return true;\n }\n if (event.key === \"Escape\") {\n clearSlashCommandRef.current?.();\n event.preventDefault();\n event.stopPropagation();\n return true;\n }\n }\n if (onKeyDownRef.current && onKeyDownRef.current(event as KeyboardEvent)) {\n return true;\n }\n if (event.key === \"Escape\" && onEscapeRef.current) {\n onEscapeRef.current();\n return true;\n }\n return false;\n },\n handlePaste: (view, event) => {\n // Paste as plain text even when the clipboard also carries HTML.\n const text = event.clipboardData?.getData(\"text/plain\");\n if (!text) return false;\n event.preventDefault();\n const schema = view.state.schema;\n if (!schema) return false;\n view.dispatch(\n view.state.tr.replaceSelection(plainTextToSlice(text, schema)),\n );\n return true;\n },\n clipboardTextParser: (text, context, _plain, view) => {\n const schema =\n (context as any)?.doc?.type?.schema ||\n (context as any)?.schema ||\n view?.state?.schema;\n\n if (!schema) return Slice.empty;\n return plainTextToSlice(text, schema);\n },\n },\n },\n // Only options baked into extensions recreate the editor; editable state,\n // placeholder, class names and content are applied to the live instance.\n [resolvedColorMap, templateKey, speed, jsonVariablesKey, fileImportEnabled],\n );\n\n useEffect(() => {\n if (editor && !editor.isDestroyed) {\n editor.setEditable(isEditing);\n }\n }, [editor, isEditing]);\n\n // Apply content changes made by the parent (e.g. clearing after submit).\n useEffect(() => {\n if (!editor || editor.isDestroyed) return;\n if (normalizeNewlines(content) === getEditorText(editor)) return;\n const { from, to } = editor.state.selection;\n editor.commands.setContent(plainTextToTipTapHtml(content), false);\n const max = editor.state.doc.content.size;\n editor.commands.setTextSelection({\n from: Math.min(from, max),\n to: Math.min(to, max),\n });\n }, [editor, content]);\n\n useEffect(() => {\n if (!editor || editor.isDestroyed) return;\n editor.setOptions({\n editorProps: {\n ...editor.options.editorProps,\n attributes: {\n ...(editor.options.editorProps.attributes as Record<string, string>),\n class: className || DEFAULT_CLASS_NAME,\n },\n },\n });\n }, [editor, className]);\n\n useEffect(() => {\n if (!editor || editor.isDestroyed) return;\n const placeholderExt = editor.extensionManager.extensions.find(\n (ext) => ext.name === \"placeholder\",\n );\n if (!placeholderExt || placeholderExt.options.placeholder === placeholder) {\n return;\n }\n placeholderExt.options.placeholder = placeholder;\n // Re-run decorations so the new placeholder renders.\n editor.view.dispatch(editor.state.tr);\n }, [editor, placeholder]);\n\n return editor;\n}\n","import { useEditor as useTipTapEditor, UseEditorOptions } from \"@tiptap/react\";\nimport {\n createRichTextPreset,\n RichTextPresetOptions,\n type FileImportOptions,\n type RichClipboardOptions,\n} from \"@pixerate/editor\";\n\nexport interface UseRichEditorProps extends UseEditorOptions {\n richTextOptions?: RichTextPresetOptions;\n /**\n * Import .md, .html, .txt and .rtf files dropped or pasted into the editor\n * at the drop position (opt-in; same as `richTextOptions.fileImport`).\n */\n fileImport?: FileImportOptions | boolean;\n /**\n * Copy/paste lossless ProseMirror slices between editors via the\n * `application/x.pixerate.document+json` clipboard type (opt-in; same as\n * `richTextOptions.richClipboard`).\n */\n richClipboard?: RichClipboardOptions | boolean;\n}\n\n/**\n * Hook to initialize a TipTap rich-text editor instance with pre-configured extensions.\n */\nexport function useEditor(options: UseRichEditorProps = {}) {\n const {\n richTextOptions,\n fileImport,\n richClipboard,\n extensions = [],\n ...editorOptions\n } = options;\n\n const preset = createRichTextPreset({\n ...(fileImport !== undefined ? { fileImport } : {}),\n ...(richClipboard !== undefined ? { richClipboard } : {}),\n ...richTextOptions,\n });\n const combinedExtensions = [...preset, ...extensions];\n\n return useTipTapEditor({\n extensions: combinedExtensions,\n ...editorOptions,\n });\n}\n","import { useState, useEffect, useCallback, useRef } from \"react\";\n\nexport interface UseNavigationGuardOptions {\n /** Whether the current form or editor has unsaved changes */\n isDirty: boolean;\n /** Whether guarding is enabled (defaults to true) */\n enabled?: boolean;\n /** Custom navigation function (e.g. router.push from next/navigation or react-router) */\n onNavigate?: (url: string) => void;\n /** Optional callback fired when an internal navigation attempt is intercepted */\n onBlocked?: (url: string) => void;\n}\n\nexport interface UseNavigationGuardReturn {\n /** Whether the unsaved changes confirmation dialog should be displayed */\n showConfirm: boolean;\n /** Setter to manually control the dialog visibility */\n setShowConfirm: (show: boolean) => void;\n /** The target URL that the user attempted to navigate to */\n pendingUrl: string | null;\n /** Proceeds with the blocked navigation and closes the dialog */\n confirmLeave: () => void;\n /** Cancels the navigation attempt and keeps the user on the current page */\n cancelLeave: () => void;\n}\n\n/**\n * Hook to guard against navigation when there are unsaved changes.\n * Intercepts both external unloads (tab closing/refreshing) and internal link clicks.\n */\nexport function useNavigationGuard({\n isDirty,\n enabled = true,\n onNavigate,\n onBlocked,\n}: UseNavigationGuardOptions): UseNavigationGuardReturn {\n const [showConfirm, setShowConfirm] = useState(false);\n const [pendingUrl, setPendingUrl] = useState<string | null>(null);\n\n const onNavigateRef = useRef(onNavigate);\n onNavigateRef.current = onNavigate;\n\n const onBlockedRef = useRef(onBlocked);\n onBlockedRef.current = onBlocked;\n\n // 1. Intercept external navigation / tab close (beforeunload)\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n if (!enabled || !isDirty) return;\n\n const handleBeforeUnload = (e: BeforeUnloadEvent) => {\n e.preventDefault();\n e.returnValue = \"\";\n };\n\n window.addEventListener(\"beforeunload\", handleBeforeUnload);\n return () => {\n window.removeEventListener(\"beforeunload\", handleBeforeUnload);\n };\n }, [enabled, isDirty]);\n\n // 2. Intercept internal anchor link clicks\n useEffect(() => {\n if (typeof document === \"undefined\" || typeof window === \"undefined\")\n return;\n if (!enabled || !isDirty) return;\n\n const handleClick = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null;\n const anchor = target?.closest?.(\"a\");\n\n if (!anchor) return;\n if (anchor.target === \"_blank\") return;\n\n // Only guard internal origins\n const isInternal = anchor.host === window.location.host;\n if (!isInternal) return;\n\n // Ignore navigation to the exact same path & query\n if (\n anchor.pathname === window.location.pathname &&\n anchor.search === window.location.search\n ) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n\n const href = anchor.href;\n setPendingUrl(href);\n setShowConfirm(true);\n onBlockedRef.current?.(href);\n };\n\n document.addEventListener(\"click\", handleClick, { capture: true });\n return () => {\n document.removeEventListener(\"click\", handleClick, { capture: true });\n };\n }, [enabled, isDirty]);\n\n const confirmLeave = useCallback(() => {\n setShowConfirm(false);\n if (pendingUrl) {\n if (onNavigateRef.current) {\n onNavigateRef.current(pendingUrl);\n } else if (typeof window !== \"undefined\") {\n window.location.href = pendingUrl;\n }\n }\n }, [pendingUrl]);\n\n const cancelLeave = useCallback(() => {\n setShowConfirm(false);\n setPendingUrl(null);\n }, []);\n\n return {\n showConfirm,\n setShowConfirm,\n pendingUrl,\n confirmLeave,\n cancelLeave,\n };\n}\n","import { useState, useCallback, useRef } from \"react\";\n\nexport interface UseDismissGuardOptions {\n /** Whether there are unsaved changes */\n isDirty: boolean;\n /** Whether the dismissal guard is enabled (defaults to true) */\n enabled?: boolean;\n /** Callback fired when dismissal is confirmed or when clean dismissal occurs */\n onDismiss?: () => void;\n}\n\nexport interface UseDismissGuardReturn {\n /** Whether the discard confirmation modal should be shown */\n showConfirm: boolean;\n /** Manually update confirmation modal visibility */\n setShowConfirm: (show: boolean) => void;\n /** Request dismissal - checks isDirty and shows confirm or executes onDismiss */\n requestDismiss: () => void;\n /** Confirm discarding changes and dismiss */\n confirmDismiss: () => void;\n /** Cancel discarding and resume editing */\n cancelDismiss: () => void;\n /** Helper keydown handler intercepting Escape key */\n handleKeyDown: (event: React.KeyboardEvent | KeyboardEvent) => boolean;\n}\n\n/**\n * Hook to guard against closing or exiting an editor/dialog with uncommitted changes.\n */\nexport function useDismissGuard({\n isDirty,\n enabled = true,\n onDismiss,\n}: UseDismissGuardOptions): UseDismissGuardReturn {\n const [showConfirm, setShowConfirm] = useState(false);\n\n const onDismissRef = useRef(onDismiss);\n onDismissRef.current = onDismiss;\n\n const requestDismiss = useCallback(() => {\n if (enabled && isDirty) {\n setShowConfirm(true);\n } else {\n onDismissRef.current?.();\n }\n }, [enabled, isDirty]);\n\n const confirmDismiss = useCallback(() => {\n setShowConfirm(false);\n onDismissRef.current?.();\n }, []);\n\n const cancelDismiss = useCallback(() => {\n setShowConfirm(false);\n }, []);\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent | KeyboardEvent) => {\n if (event.key === \"Escape\") {\n if (event.defaultPrevented) return false;\n event.preventDefault();\n requestDismiss();\n return true;\n }\n return false;\n },\n [requestDismiss],\n );\n\n return {\n showConfirm,\n setShowConfirm,\n requestDismiss,\n confirmDismiss,\n cancelDismiss,\n handleKeyDown,\n };\n}\n","import { useSyncExternalStore, useRef, useCallback, useMemo } from \"react\";\nimport {\n HistoryManager,\n HistoryState,\n HistoryEntry,\n HistoryMark,\n Command,\n MergedExecutionOptions,\n createHistoryManager,\n HistoryManagerOptions,\n} from \"@pixerate/editor\";\n\nexport interface UseHistoryResult extends HistoryState {\n manager: HistoryManager;\n /** History panel rows (undo steps, then redo steps). */\n entries: HistoryEntry[];\n undo: () => boolean;\n redo: () => boolean;\n clear: () => void;\n execute: (command: Command) => void;\n executeMerged: (command: Command, options?: MergedExecutionOptions) => void;\n batch: (name: string, fn: () => void) => void;\n /** Undoes / redoes until the entry at `index` is current (`-1` = before all). */\n goTo: (index: number) => number;\n /** Captures the current point, e.g. when a drag starts. */\n mark: () => HistoryMark;\n /** Takes back every step since `mark` without leaving redo (Escape-cancel). */\n revertTo: (mark: HistoryMark) => number;\n /** Joins every merged execute into one step until `endGesture`. */\n beginGesture: (key: string) => void;\n endGesture: () => void;\n}\n\n/**\n * React hook that subscribes to a HistoryManager instance.\n * Accepts an existing HistoryManager or config options to create an instance\n * (options are read on first render only).\n */\nexport function useHistory(\n managerOrOptions?: HistoryManager | HistoryManagerOptions,\n): UseHistoryResult {\n // Options are read once, so passing an inline options object does not\n // create a new manager (and wipe history) on every render.\n const ownManagerRef = useRef<HistoryManager | null>(null);\n let manager: HistoryManager;\n if (managerOrOptions instanceof HistoryManager) {\n manager = managerOrOptions;\n } else {\n ownManagerRef.current ??= createHistoryManager(managerOrOptions);\n manager = ownManagerRef.current;\n }\n\n const state = useSyncExternalStore(\n useCallback(\n (onStoreChange) => manager.subscribe(onStoreChange),\n [manager],\n ),\n () => manager.getState(),\n () => manager.getState(),\n );\n\n // getEntries() is cached per history change, so `state` is a valid dependency.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const entries = useMemo(() => manager.getEntries(), [manager, state]);\n\n const undo = useCallback(() => manager.undo(), [manager]);\n const redo = useCallback(() => manager.redo(), [manager]);\n const clear = useCallback(() => manager.clear(), [manager]);\n const execute = useCallback(\n (cmd: Command) => manager.execute(cmd),\n [manager],\n );\n const executeMerged = useCallback(\n (cmd: Command, opts?: MergedExecutionOptions) =>\n manager.executeMerged(cmd, opts),\n [manager],\n );\n const batch = useCallback(\n (name: string, fn: () => void) => manager.batch(name, fn),\n [manager],\n );\n const goTo = useCallback((index: number) => manager.goTo(index), [manager]);\n const mark = useCallback(() => manager.mark(), [manager]);\n const revertTo = useCallback(\n (m: HistoryMark) => manager.revertTo(m),\n [manager],\n );\n const beginGesture = useCallback(\n (key: string) => manager.beginGesture(key),\n [manager],\n );\n const endGesture = useCallback(() => manager.endGesture(), [manager]);\n\n return {\n ...state,\n manager,\n entries,\n undo,\n redo,\n clear,\n execute,\n executeMerged,\n batch,\n goTo,\n mark,\n revertTo,\n beginGesture,\n endGesture,\n };\n}\n","import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from \"react\";\nimport {\n DirtyTracker,\n bindDirtyToHistory,\n type DirtyTrackerOptions,\n type HistoryDirtyBinding,\n type HistoryManager,\n} from \"@pixerate/editor\";\n\nexport interface UseHistoryDirtyOptions<T> extends DirtyTrackerOptions<T> {\n /** The history whose changes re-check the document. */\n history: HistoryManager;\n /** Reads the current document value (the latest function is always used). */\n getValue: () => T;\n /** Existing tracker to drive (read on first render only). */\n tracker?: DirtyTracker<T>;\n}\n\nexport interface UseHistoryDirtyResult<T> {\n /** Whether the document differs from the saved state. Feed it to `useNavigationGuard`. */\n isDirty: boolean;\n /** Marks the current document as saved. */\n markClean: () => void;\n /** Runs a load / restore without marking the document dirty (re-entrant). */\n suppress: <R>(fn: () => R) => R;\n /** Re-checks after a change made outside the history. */\n refresh: () => boolean;\n tracker: DirtyTracker<T>;\n}\n\n/**\n * Dirty-vs-saved tracking bound to a HistoryManager: undoing back to the saved\n * state makes the document clean again, selection/viewport changes can be\n * ignored with `normalize`, and programmatic loads can be wrapped in `suppress`.\n * Options other than `getValue` and `history` are read on first render only.\n */\nexport function useHistoryDirty<T>(\n options: UseHistoryDirtyOptions<T>,\n): UseHistoryDirtyResult<T> {\n const getValueRef = useRef(options.getValue);\n getValueRef.current = options.getValue;\n\n const [tracker] = useState(\n () =>\n options.tracker ??\n new DirtyTracker<T>(options.getValue(), {\n isEqual: options.isEqual,\n normalize: options.normalize,\n }),\n );\n\n const bindingRef = useRef<HistoryDirtyBinding<T> | null>(null);\n useEffect(() => {\n const binding = bindDirtyToHistory<T>({\n history: options.history,\n getValue: () => getValueRef.current(),\n tracker,\n });\n bindingRef.current = binding;\n return () => {\n binding.destroy();\n if (bindingRef.current === binding) bindingRef.current = null;\n };\n }, [options.history, tracker]);\n\n const isDirty = useSyncExternalStore(\n useCallback((onChange) => tracker.subscribe(onChange), [tracker]),\n () => tracker.dirty,\n () => tracker.dirty,\n );\n\n const markClean = useCallback(\n () => tracker.markClean(getValueRef.current()),\n [tracker],\n );\n const suppress = useCallback(\n <R,>(fn: () => R): R =>\n bindingRef.current ? bindingRef.current.suppress(fn) : tracker.suppress(fn),\n [tracker],\n );\n const refresh = useCallback(\n () => tracker.update(getValueRef.current()),\n [tracker],\n );\n\n return { isDirty, markClean, suppress, refresh, tracker };\n}\n","import { useEffect } from \"react\";\nimport type { HistoryManager } from \"@pixerate/editor/history\";\nimport { matchHistoryShortcut } from \"@pixerate/editor/commands\";\n\nexport interface HistoryShortcutsOptions {\n /**\n * Whether the keyboard shortcuts are enabled. Defaults to true.\n */\n enabled?: boolean;\n /**\n * Target element or window to listen on. Defaults to window.\n */\n target?: Window | HTMLElement | null;\n /**\n * When true (default), shortcuts will not trigger if an <input>, <textarea>,\n * or [contenteditable] element is currently active / focused.\n */\n ignoreEditableElements?: boolean;\n}\n\n/**\n * Attaches keyboard listeners for Undo (Mod+Z) and Redo (Mod+Shift+Z / Mod+Y).\n * Automatically guards against active text inputs and contenteditable editors.\n */\nexport function useHistoryShortcuts(\n manager: HistoryManager,\n options: HistoryShortcutsOptions = {},\n): void {\n const {\n enabled = true,\n target,\n ignoreEditableElements = true,\n } = options;\n\n useEffect(() => {\n if (!enabled) return;\n\n const eventTarget = target ?? (typeof window !== \"undefined\" ? window : null);\n if (!eventTarget) return;\n\n const handleKeyDown = (event: Event) => {\n const e = event as KeyboardEvent;\n // Default bindings from the command system: Mod+Z, Mod+Shift+Z and (off macOS) Mod+Y,\n // matched by `event.code` with `Mod` = ⌘ on macOS and Ctrl elsewhere.\n const action = matchHistoryShortcut(e, { allowInEditable: !ignoreEditableElements });\n if (action === \"undo\" && manager.getState().canUndo) {\n e.preventDefault();\n manager.undo();\n } else if (action === \"redo\" && manager.getState().canRedo) {\n e.preventDefault();\n manager.redo();\n }\n };\n\n eventTarget.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n eventTarget.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [manager, enabled, target, ignoreEditableElements]);\n}\n","import { useEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n FileImportController,\n summarizeImportStructure,\n type FileImportControllerOptions,\n type FileImportState,\n type ImportStructureSummary,\n} from \"@pixerate/editor\";\n\nexport interface UseFileImportResult extends FileImportState {\n /**\n * Structures detected in the last import (headings, lists, tables, columns),\n * or `null` when no adapter reported any (only structure-aware adapters such\n * as PDF do). Turn PDF detection off with\n * `useFileImport(editor, { adapterOptions: { pdf: { structure: false } } })`.\n */\n structureSummary: ImportStructureSummary | null;\n /** Value for `<input type=\"file\" accept={…}>`. */\n accept: string;\n /** Opens the browser file picker and imports the chosen files at the selection. */\n openFilePicker: FileImportController[\"openFilePicker\"];\n /** Imports files (e.g. from your own `<input>` or drop zone) at `at` or the selection. */\n importFiles: FileImportController[\"importFiles\"];\n}\n\n/**\n * Imports markdown, HTML, plain-text and RTF files (or anything registered\n * with `registerImportAdapter` for the `document` target) into an editor.\n * Pair it with `useEditor({ fileImport: true })` to also accept dropped files.\n */\nexport function useFileImport(\n editor: Editor | null | undefined,\n options: FileImportControllerOptions = {},\n): UseFileImportResult {\n const editorRef = useRef(editor);\n editorRef.current = editor;\n\n const controller = useMemo(\n () =>\n new FileImportController(() => {\n const current = editorRef.current;\n return current && !current.isDestroyed ? current : null;\n }, options),\n [],\n );\n\n useEffect(() => {\n controller.setOptions(options);\n });\n\n const state = useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n const structureSummary = useMemo(() => summarizeImportStructure(state.lastOutcomes), [state.lastOutcomes]);\n\n return {\n ...state,\n structureSummary,\n accept: controller.accept,\n openFilePicker: controller.openFilePicker,\n importFiles: controller.importFiles,\n };\n}\n","import { useEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n DocxExportController,\n type DocxExportControllerOptions,\n type DocxExportReport,\n type DocxExportState,\n} from \"@pixerate/editor/export\";\n\nexport interface UseDocxExportResult extends DocxExportState {\n /** Exports the editor (with its comments, tracked changes and styles) and downloads the `.docx`. */\n download: (fileName?: string) => Promise<DocxExportReport | null>;\n /** Builds the `.docx` without downloading it. */\n exportBlob: DocxExportController[\"exportBlob\"];\n}\n\n/**\n * \"Export to Word\": downloads the editor's document as a `.docx` with its\n * comments (from the `Comments` store), tracked changes and paragraph styles.\n * `lastReport` lists anything the export had to leave out.\n */\nexport function useDocxExport(\n editor: Editor | null | undefined,\n options: DocxExportControllerOptions = {},\n): UseDocxExportResult {\n const editorRef = useRef(editor);\n editorRef.current = editor;\n\n const controller = useMemo(\n () =>\n new DocxExportController(() => {\n const current = editorRef.current;\n return current && !current.isDestroyed ? current : null;\n }, options),\n [],\n );\n\n useEffect(() => {\n controller.setOptions(options);\n });\n\n const state = useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n return {\n ...state,\n download: (fileName?: string) => controller.download(fileName),\n exportBlob: () => controller.exportBlob(),\n };\n}\n","import React from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport type { DocxExportControllerOptions, DocxExportReport } from \"@pixerate/editor/export\";\nimport { useDocxExport } from \"../hooks/useDocxExport\";\n\nexport interface ExportDocxButtonProps extends DocxExportControllerOptions {\n editor: Editor | null;\n className?: string;\n children?: React.ReactNode;\n /** Called after the download with the export report. */\n onExported?: (report: DocxExportReport) => void;\n}\n\n/** A button that downloads the editor's document as a Word file (`.docx`). */\nexport const ExportDocxButton: React.FC<ExportDocxButtonProps> = ({\n editor,\n className = \"rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-50\",\n children = \"Export to Word\",\n onExported,\n ...options\n}) => {\n const docx = useDocxExport(editor, options);\n return (\n <button\n type=\"button\"\n className={className}\n disabled={!editor || docx.isExporting}\n aria-busy={docx.isExporting || undefined}\n title={docx.error ? `Export failed: ${docx.error.message}` : undefined}\n onClick={async () => {\n const report = await docx.download();\n if (report) onExported?.(report);\n }}\n >\n {children}\n </button>\n );\n};\n","import { useEffect } from \"react\";\nimport type { AgentToolProvider, ToolRegistry } from \"@pixerate/editor/tools\";\n\n/**\n * Registers a tool provider with a `ToolRegistry` while the component is\n * mounted and unregisters it on unmount (the registry then announces the\n * change through `onListChanged`).\n *\n * Memoize the provider (e.g. `useMemo(() => createRichTextToolProvider(editor,\n * { id }), [editor])`): a new provider object re-registers it. Pass `null`\n * while it isn't ready.\n */\nexport function useAgentToolProvider(\n registry: ToolRegistry | null | undefined,\n provider: AgentToolProvider | null | undefined,\n): void {\n useEffect(() => {\n if (!registry || !provider) return;\n return registry.register(provider);\n }, [registry, provider]);\n}\n","import { useEffect, useState } from \"react\";\nimport { connectToolBridge, type ConnectToolBridgeOptions, type ToolBridgeConnection, type ToolBridgeStatus, type ToolRegistry } from \"@pixerate/editor/tools\";\n\nexport interface UseToolBridgeResult {\n status: ToolBridgeStatus | \"off\";\n /** Why the last connection ended (e.g. \"Bad token\"), when the bridge said. */\n detail?: string;\n /** The id the bridge gave this editor (`list_editors`). */\n editorId: string | null;\n}\n\n/**\n * Connects a `ToolRegistry` to a local MCP bridge (`pixerate-mcp-bridge`) while mounted, so an\n * MCP client can call the page's tools. Pass `null` options to stay disconnected. Memoize the\n * options: changing `url`, `token` or `name` reconnects.\n */\nexport function useToolBridge(registry: ToolRegistry | null | undefined, options: ConnectToolBridgeOptions | null): UseToolBridgeResult {\n const [state, setState] = useState<UseToolBridgeResult>({ status: \"off\", editorId: null });\n const key = options ? JSON.stringify([options.url, options.token, options.name, options.kind, options.reconnect]) : null;\n useEffect(() => {\n if (!registry || !options) {\n setState({ status: \"off\", editorId: null });\n return;\n }\n let connection: ToolBridgeConnection | undefined;\n connection = connectToolBridge(registry, {\n ...options,\n onStatus: (status, detail) => {\n setState({ status, detail, editorId: connection?.editorId ?? null });\n options.onStatus?.(status, detail);\n },\n });\n setState({ status: connection.status, editorId: null });\n return () => connection?.close();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [registry, key]);\n return state;\n}\n","import React from \"react\";\nimport {\n EditorContent as TipTapEditorContent,\n EditorContentProps as TipTapEditorContentProps,\n} from \"@tiptap/react\";\n\nexport interface EditorContentProps extends TipTapEditorContentProps {\n className?: string;\n}\n\nexport const EditorContent: React.FC<EditorContentProps> = ({\n className,\n editor,\n ...props\n}) => {\n return (\n <div className={className}>\n <TipTapEditorContent editor={editor} {...props} />\n </div>\n );\n};\n","import React, { useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n BubbleMenuPlugin,\n type BubbleMenuPluginProps,\n} from \"@tiptap/extension-bubble-menu\";\nimport type { Editor } from \"@tiptap/core\";\n\nexport interface BubbleMenuProps {\n editor: Editor | null;\n className?: string;\n children: React.ReactNode;\n tippyOptions?: BubbleMenuPluginProps[\"tippyOptions\"];\n shouldShow?: BubbleMenuPluginProps[\"shouldShow\"];\n pluginKey?: BubbleMenuPluginProps[\"pluginKey\"];\n updateDelay?: BubbleMenuPluginProps[\"updateDelay\"];\n}\n\nexport const BubbleMenu: React.FC<BubbleMenuProps> = ({\n editor,\n className = \"flex items-center gap-1 bg-popover text-popover-foreground border shadow-md rounded-md p-1\",\n children,\n tippyOptions = { duration: 100 },\n shouldShow = null,\n pluginKey = \"bubbleMenu\",\n updateDelay,\n}) => {\n const menuEl = useRef<HTMLDivElement | null>(null);\n const [mounted, setMounted] = useState(false);\n\n if (!menuEl.current && typeof document !== \"undefined\") {\n menuEl.current = document.createElement(\"div\");\n }\n\n useEffect(() => {\n if (!editor || !menuEl.current || editor.isDestroyed) {\n return;\n }\n\n const element = menuEl.current;\n element.className = className;\n\n const plugin = BubbleMenuPlugin({\n editor,\n element,\n pluginKey,\n tippyOptions,\n shouldShow,\n updateDelay,\n });\n\n editor.registerPlugin(plugin);\n setMounted(true);\n\n return () => {\n setMounted(false);\n editor.unregisterPlugin(pluginKey);\n if (element.parentNode) {\n element.parentNode.removeChild(element);\n }\n };\n }, [editor, className, pluginKey]);\n\n if (!editor || !menuEl.current || !mounted) {\n return null;\n }\n\n return createPortal(children, menuEl.current);\n};\n","import React, { useMemo } from \"react\";\nimport {\n describeConditionalTag,\n evaluatePromptTokens,\n formatConditionalTag,\n resolveTemplates,\n Template,\n ColorGradient,\n PromptValues,\n} from \"@pixerate/editor\";\n\nexport interface TemplateRendererProps {\n /** Raw prompt or text string to render */\n content: string;\n /** Available templates for recursive resolution and custom coloring */\n templates?: Template[];\n /** Custom gradient color map for templates */\n templateColorMap?: Map<string, ColorGradient>;\n /** Whether to resolve nested templates recursively before displaying */\n resolve?: boolean;\n /** Template version bindings used when `resolve` is set */\n bindings?: Record<string, string>;\n /**\n * Variable values. When set, variables show their value (or default),\n * sections whose condition fails are hidden, and section tags are dropped.\n */\n values?: PromptValues;\n /** Custom class name for the wrapper */\n className?: string;\n /** Click callback for template badges */\n onTemplateClick?: (templateName: string) => void;\n /** Click callback for variable badges */\n onVariableClick?: (variableName: string) => void;\n}\n\n\nexport const TemplateRenderer: React.FC<TemplateRendererProps> = ({\n content,\n templates = [],\n templateColorMap,\n resolve = false,\n bindings,\n values,\n className = \"font-mono text-sm leading-relaxed whitespace-pre-wrap break-words\",\n onTemplateClick,\n onVariableClick,\n}) => {\n const displayText = useMemo(() => {\n if (!resolve || templates.length === 0) return content;\n return resolveTemplates(content, templates, { bindings });\n }, [content, templates, resolve, bindings]);\n\n const tokens = useMemo(() => {\n return evaluatePromptTokens(displayText, values);\n }, [displayText, values]);\n\n return (\n <div className={className}>\n {tokens.map((token, index) => {\n if (token.type === \"template\") {\n const colors = templateColorMap?.get(token.value) || {\n from: \"#f43f5e\",\n to: \"#8b5cf6\",\n };\n const style = {\n \"--color-from\": colors.from,\n \"--color-to\": colors.to,\n } as React.CSSProperties;\n\n return (\n <span\n key={index}\n style={style}\n onClick={() => onTemplateClick?.(token.value)}\n className=\"inline-flex items-center px-1.5 py-0.5 mx-0.5 text-xs font-semibold rounded-md border border-[var(--color-to)]/40 bg-gradient-to-r from-[var(--color-from)]/15 to-[var(--color-to)]/15 text-[var(--color-to)] hover:brightness-110 cursor-pointer transition-all\"\n title={`Template: ${token.value}`}\n >\n {`{{${token.value}}}`}\n </span>\n );\n }\n\n if (token.type === \"variable\") {\n const details = [\n `Variable: ${token.value}`,\n token.description,\n token.defaultValue !== undefined\n ? `Default: ${token.defaultValue || \"(empty)\"}`\n : undefined,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n if (token.resolvedValue !== undefined) {\n return (\n <span\n key={index}\n onClick={() => onVariableClick?.(token.value)}\n data-variable={token.value}\n data-value-source={token.valueSource}\n className={\n token.valueSource === \"value\"\n ? \"inline px-1 mx-0.5 rounded-md bg-emerald-400/15 text-emerald-700 dark:text-emerald-300 border-b border-emerald-400/60 cursor-pointer\"\n : \"inline px-1 mx-0.5 rounded-md bg-violet-400/10 text-violet-600 dark:text-violet-300 italic border-b border-dashed border-violet-400/60 cursor-pointer\"\n }\n title={details}\n >\n {token.resolvedValue}\n </span>\n );\n }\n\n return (\n <span\n key={index}\n onClick={() => onVariableClick?.(token.value)}\n data-variable={token.value}\n className=\"inline-flex items-center px-1.5 py-0.5 mx-0.5 text-xs font-medium rounded-md border border-violet-400/40 bg-violet-400/15 text-violet-600 dark:text-violet-300 hover:brightness-110 cursor-pointer transition-all\"\n title={details}\n >\n {`{${token.value}`}\n {token.defaultValue !== undefined && (\n <span className=\"opacity-60\">{`|${token.defaultValue}`}</span>\n )}\n {\"}\"}\n </span>\n );\n }\n\n if (token.type === \"conditional\" && token.conditional) {\n return (\n <span\n key={index}\n data-conditional={token.conditional}\n className=\"inline-flex items-center px-1 py-0.5 mx-0.5 text-xs font-medium rounded-md border border-amber-400/40 bg-amber-400/15 text-amber-700 dark:text-amber-300\"\n title={describeConditionalTag(token)}\n >\n {formatConditionalTag(token)}\n </span>\n );\n }\n\n if (token.type === \"instruction\") {\n return (\n <span\n key={index}\n className=\"inline-flex items-center px-1.5 py-0.5 mx-0.5 text-xs italic font-medium rounded-md border border-rose-400/40 bg-rose-400/15 text-rose-600 dark:text-rose-300\"\n title={`Instruction: ${token.value}`}\n >\n {`__${token.value}__`}\n </span>\n );\n }\n\n return <span key={index}>{token.value}</span>;\n })}\n </div>\n );\n};\n","import React, { useId, useMemo, useState } from \"react\";\nimport {\n compactVariableValues,\n getVariableFormFields,\n PromptValues,\n Template,\n VariableFormField,\n} from \"@pixerate/editor\";\n\nexport interface VariableFormProps {\n /** Prompt whose variables become form fields */\n content: string;\n /** Templates searched recursively for further variables */\n templates?: Template[];\n /** Template version bindings */\n bindings?: Record<string, string>;\n /** Entered text per variable (controlled). Omit to let the form keep its own state. */\n values?: Record<string, string>;\n /** Initial entered text when uncontrolled */\n defaultValues?: Record<string, string>;\n /**\n * Called on every edit with the values to resolve with (blank fields\n * dropped so defaults apply) and the raw entered text.\n */\n onChange?: (values: PromptValues, entered: Record<string, string>) => void;\n /** Custom class name for the wrapper */\n className?: string;\n}\n\n/**\n * Renders one input per prompt variable: labelled with its description,\n * using its default as the placeholder. Variables only used by `{?name}`\n * conditions render as checkboxes.\n */\nexport const VariableForm: React.FC<VariableFormProps> = ({\n content,\n templates,\n bindings,\n values,\n defaultValues,\n onChange,\n className = \"flex flex-col gap-3 text-sm\",\n}) => {\n const idPrefix = useId();\n const [internal, setInternal] = useState<Record<string, string>>(\n () => defaultValues ?? {},\n );\n const entered = values ?? internal;\n\n const fields = useMemo<VariableFormField[]>(\n () => getVariableFormFields(content, { templates, bindings }),\n [content, templates, bindings],\n );\n\n const update = (name: string, value: string) => {\n const next = { ...entered, [name]: value };\n if (values === undefined) setInternal(next);\n onChange?.(compactVariableValues(next), next);\n };\n\n if (fields.length === 0) return null;\n\n return (\n <form className={className} onSubmit={(event) => event.preventDefault()}>\n {fields.map((field) => {\n const id = `${idPrefix}-${field.name}`;\n if (field.conditionOnly) {\n return (\n <label\n key={field.name}\n htmlFor={id}\n className=\"flex items-center gap-2\"\n data-variable-field={field.name}\n >\n <input\n id={id}\n name={field.name}\n type=\"checkbox\"\n checked={(entered[field.name] ?? \"\") !== \"\"}\n onChange={(event) =>\n update(field.name, event.target.checked ? \"true\" : \"\")\n }\n />\n <span>{field.label}</span>\n </label>\n );\n }\n return (\n <label\n key={field.name}\n htmlFor={id}\n className=\"flex flex-col gap-1\"\n data-variable-field={field.name}\n >\n <span className=\"font-medium\">\n {field.label}\n {field.required && (\n <span className=\"text-rose-500\" aria-hidden=\"true\">\n {\" *\"}\n </span>\n )}\n </span>\n <input\n id={id}\n name={field.name}\n type=\"text\"\n value={entered[field.name] ?? \"\"}\n placeholder={field.placeholder}\n aria-required={field.required || undefined}\n onChange={(event) => update(field.name, event.target.value)}\n className=\"px-2 py-1 rounded-md border border-violet-400/40 bg-transparent\"\n />\n </label>\n );\n })}\n </form>\n );\n};\n","import React, { useId, useState } from \"react\";\nimport type {\n ColorGradient,\n MergeRecordsOptions,\n MergeRecordsResult,\n ParseDataSourceOptions,\n Template,\n} from \"@pixerate/editor\";\nimport { TemplateRenderer } from \"./TemplateRenderer\";\nimport { useMergePreview } from \"../hooks/useMergePreview\";\n\nexport interface MergePreviewProps {\n /** The prompt merged with each record. */\n content: string;\n templates?: Template[];\n bindings?: Record<string, string>;\n templateColorMap?: Map<string, ColorGradient>;\n /** Initial CSV / TSV / JSON data source text. */\n defaultSource?: string;\n parseOptions?: ParseDataSourceOptions;\n /** Drop records matching this condition (e.g. `\"status=void\"`) when merging. */\n skipIf?: MergeRecordsOptions[\"skipIf\"];\n /** Separator between merged outputs (default a blank line; `\"none\"` for nothing). */\n separator?: string;\n maxOutputs?: number;\n /** Called after \"Merge all\". */\n onMerge?: (result: MergeRecordsResult) => void;\n /** Base file name for downloads (default `merged`). */\n downloadName?: string;\n className?: string;\n}\n\n/** Saves text as a file through a temporary link. */\nfunction downloadText(text: string, fileName: string, type: string): void {\n if (typeof document === \"undefined\" || typeof URL.createObjectURL !== \"function\") {\n return;\n }\n const url = URL.createObjectURL(new Blob([text], { type }));\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = fileName;\n link.click();\n setTimeout(() => URL.revokeObjectURL(url), 0);\n}\n\n/**\n * Mail-merge preview: paste or pick a CSV / JSON data source, check the\n * automatic field mapping, step through records with the resolved prompt\n * shown by `TemplateRenderer`, and merge every record into text or JSON.\n */\nexport const MergePreview: React.FC<MergePreviewProps> = ({\n content,\n templates,\n bindings,\n templateColorMap,\n defaultSource,\n parseOptions,\n skipIf,\n separator,\n maxOutputs,\n onMerge,\n downloadName = \"merged\",\n className = \"flex flex-col gap-3 text-sm\",\n}) => {\n const id = useId();\n const merge = useMergePreview({\n template: content,\n templates,\n bindings,\n initialSource: defaultSource,\n parseOptions,\n skipIf,\n separator,\n maxOutputs,\n });\n const [copied, setCopied] = useState(false);\n const { source, result } = merge;\n\n const copy = async () => {\n try {\n await navigator.clipboard.writeText(merge.serialize(\"text\"));\n setCopied(true);\n } catch {\n setCopied(false);\n }\n };\n\n return (\n <div className={className} data-merge-preview=\"\">\n <label htmlFor={`${id}-source`} className=\"flex flex-col gap-1\">\n <span className=\"font-medium\">Data source (CSV, TSV or JSON)</span>\n <textarea\n id={`${id}-source`}\n data-merge-source=\"\"\n value={merge.sourceText}\n rows={5}\n spellCheck={false}\n onChange={(event) => merge.setSourceText(event.target.value)}\n className=\"px-2 py-1 font-mono text-xs rounded-md border border-violet-400/40 bg-transparent\"\n />\n </label>\n <div className=\"flex flex-wrap items-center gap-2\">\n <input\n type=\"file\"\n accept=\".csv,.tsv,.txt,.json,text/csv,application/json\"\n aria-label=\"Load data source file\"\n data-merge-file=\"\"\n onChange={(event) => {\n const file = event.target.files?.[0];\n if (file) void merge.loadFile(file);\n }}\n />\n <span data-merge-summary=\"\" className=\"opacity-70\">\n {`${source.records.length} record${source.records.length === 1 ? \"\" : \"s\"} · ${source.fields.length} field${source.fields.length === 1 ? \"\" : \"s\"}`}\n </span>\n </div>\n {source.warnings.length > 0 && merge.sourceText.trim() !== \"\" && (\n <ul data-merge-warnings=\"\" className=\"text-amber-600 text-xs\">\n {source.warnings.map((warning, i) => (\n <li key={i}>{warning.message}</li>\n ))}\n </ul>\n )}\n\n {merge.variables.length > 0 && (\n <fieldset className=\"flex flex-col gap-1\">\n <legend className=\"font-medium\">Field mapping</legend>\n {merge.variables.map((variable) => (\n <label\n key={variable}\n className=\"flex items-center gap-2\"\n data-merge-mapping={variable}\n >\n <span className=\"min-w-24 font-mono\">{`{${variable}}`}</span>\n <select\n value={merge.mapping[variable] ?? \"\"}\n aria-label={`Field for ${variable}`}\n onChange={(event) =>\n merge.setFieldMapping(variable, event.target.value || null)\n }\n className=\"px-1 py-0.5 rounded-md border border-violet-400/40 bg-transparent\"\n >\n <option value=\"\">(none)</option>\n {source.fields.map((field) => (\n <option key={field} value={field}>\n {field}\n </option>\n ))}\n </select>\n </label>\n ))}\n </fieldset>\n )}\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n data-merge-prev=\"\"\n onClick={merge.prev}\n disabled={merge.index <= 0}\n >\n Prev\n </button>\n <span data-merge-position=\"\">\n {merge.count === 0\n ? \"No records\"\n : `Record ${merge.index + 1} of ${merge.count}`}\n </span>\n <button\n type=\"button\"\n data-merge-next=\"\"\n onClick={merge.next}\n disabled={merge.index >= merge.count - 1}\n >\n Next\n </button>\n </div>\n\n <div data-merge-output=\"\">\n <TemplateRenderer\n content={content}\n templates={templates}\n bindings={bindings}\n templateColorMap={templateColorMap}\n resolve={!!templates && templates.length > 0}\n values={merge.values}\n />\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n data-merge-all=\"\"\n disabled={merge.count === 0}\n onClick={() => {\n const merged = merge.merge();\n setCopied(false);\n onMerge?.(merged);\n }}\n >\n Merge all\n </button>\n {result && (\n <>\n <span data-merge-result=\"\">\n {`${result.outputs.length} merged${result.skipped.length ? `, ${result.skipped.length} skipped` : \"\"}${result.truncated ? \" (stopped early)\" : \"\"}`}\n </span>\n <button type=\"button\" data-merge-copy=\"\" onClick={copy}>\n {copied ? \"Copied\" : \"Copy\"}\n </button>\n <button\n type=\"button\"\n data-merge-download=\"text\"\n onClick={() => downloadText(merge.serialize(\"text\"), `${downloadName}.txt`, \"text/plain\")}\n >\n Download .txt\n </button>\n <button\n type=\"button\"\n data-merge-download=\"json\"\n onClick={() =>\n downloadText(merge.serialize(\"json\"), `${downloadName}.json`, \"application/json\")\n }\n >\n Download .json\n </button>\n </>\n )}\n </div>\n {result && (\n <textarea\n readOnly\n aria-label=\"Merged output\"\n data-merge-text=\"\"\n rows={6}\n value={merge.serialize(\"text\")}\n className=\"px-2 py-1 font-mono text-xs rounded-md border border-violet-400/40 bg-transparent\"\n />\n )}\n </div>\n );\n};\n","import { useCallback, useMemo, useState } from \"react\";\nimport {\n extractVariables,\n matchFields,\n mergeRecords,\n parseDataSource,\n recordToValues,\n serializeMergeOutputs,\n type MergeDataSource,\n type MergeRecord,\n type MergeRecordsOptions,\n type MergeRecordsResult,\n type ParseDataSourceOptions,\n type PromptValues,\n type Template,\n} from \"@pixerate/editor\";\n\nexport interface UseMergePreviewOptions {\n /** The prompt merged with each record. */\n template: string;\n templates?: Template[];\n bindings?: Record<string, string>;\n /** Initial CSV / TSV / JSON text. */\n initialSource?: string;\n /** How to read the data source text. */\n parseOptions?: ParseDataSourceOptions;\n /** Passed to `mergeRecords` by `merge()`. */\n skipIf?: MergeRecordsOptions[\"skipIf\"];\n separator?: string;\n maxOutputs?: number;\n}\n\nexport interface MergePreviewState {\n sourceText: string;\n setSourceText: (text: string) => void;\n /** Reads a picked file (CSV, TSV or JSON) into `sourceText`. */\n loadFile: (file: Blob) => Promise<void>;\n source: MergeDataSource;\n /** Variable names the template uses, in order. */\n variables: string[];\n /** Variable → field: automatic matches with the user's overrides applied. */\n mapping: Record<string, string | null>;\n setFieldMapping: (variable: string, field: string | null) => void;\n resetMapping: () => void;\n /** 0-based index of the previewed record. */\n index: number;\n count: number;\n setIndex: (index: number) => void;\n next: () => void;\n prev: () => void;\n record: MergeRecord | undefined;\n /** Prompt values for the previewed record. */\n values: PromptValues;\n /** Merges every record with the current mapping and stores the result. */\n merge: () => MergeRecordsResult;\n result: MergeRecordsResult | null;\n /** The last merge's outputs as text or JSON. */\n serialize: (format: \"text\" | \"json\") => string;\n}\n\n/**\n * Headless state for a mail-merge preview (the counterpart of Svelte's\n * `createMergePreview`): parses a pasted or loaded data source, matches its\n * fields to the template's variables (editable), steps through records and\n * merges them all with `mergeRecords`.\n */\nexport function useMergePreview(options: UseMergePreviewOptions): MergePreviewState {\n const { template, templates, bindings, parseOptions } = options;\n const [sourceText, setSourceTextState] = useState(options.initialSource ?? \"\");\n const [overrides, setOverrides] = useState<Record<string, string | null>>({});\n const [index, setIndexState] = useState(0);\n const [result, setResult] = useState<MergeRecordsResult | null>(null);\n\n const source = useMemo(\n () => parseDataSource(sourceText, parseOptions),\n [sourceText, parseOptions],\n );\n const variables = useMemo(\n () => extractVariables(template, { templates, bindings }).map((v) => v.name),\n [template, templates, bindings],\n );\n const mapping = useMemo(() => {\n const merged: Record<string, string | null> = {\n ...matchFields(variables, source.fields).mapping,\n };\n for (const [variable, field] of Object.entries(overrides)) {\n if (variables.includes(variable) && (field === null || source.fields.includes(field))) {\n merged[variable] = field;\n }\n }\n return merged;\n }, [variables, source.fields, overrides]);\n\n const count = source.records.length;\n const current = count === 0 ? 0 : Math.min(index, count - 1);\n const record = source.records[current];\n const values = useMemo(\n () => (record ? recordToValues(record, mapping) : {}),\n [record, mapping],\n );\n\n const setSourceText = useCallback((text: string) => {\n setSourceTextState(text);\n setIndexState(0);\n setResult(null);\n }, []);\n const loadFile = useCallback(\n async (file: Blob) => setSourceText(await file.text()),\n [setSourceText],\n );\n const setIndex = useCallback(\n (next: number) => setIndexState(Math.max(0, Math.min(next, count - 1))),\n [count],\n );\n const setFieldMapping = useCallback((variable: string, field: string | null) => {\n setOverrides((previous) => ({ ...previous, [variable]: field }));\n setResult(null);\n }, []);\n const resetMapping = useCallback(() => setOverrides({}), []);\n\n const merge = useCallback(() => {\n const merged = mergeRecords(template, source, {\n templates,\n bindings,\n mapping,\n skipIf: options.skipIf,\n separator: options.separator,\n maxOutputs: options.maxOutputs,\n });\n setResult(merged);\n return merged;\n }, [template, source, templates, bindings, mapping, options.skipIf, options.separator, options.maxOutputs]);\n\n const serialize = useCallback(\n (format: \"text\" | \"json\") =>\n result ? serializeMergeOutputs(result.outputs, format, options.separator) : \"\",\n [result, options.separator],\n );\n\n return {\n sourceText,\n setSourceText,\n loadFile,\n source,\n variables,\n mapping,\n setFieldMapping,\n resetMapping,\n index: current,\n count,\n setIndex,\n next: () => setIndex(current + 1),\n prev: () => setIndex(current - 1),\n record,\n values,\n merge,\n result,\n serialize,\n };\n}\n","import { useMemo, useSyncExternalStore } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { createOutlineStore, type OutlineSnapshot } from \"@pixerate/editor\";\n\nexport type { OutlineHeading, OutlineSnapshot, OutlineTreeItem } from \"@pixerate/editor\";\n\n/**\n * Subscribes to an editor's heading outline. Returns the headings (flat and\n * nested) and the id of the heading whose section contains the selection.\n * Re-renders only when the outline or the active heading changes.\n *\n * Install the `Outline` extension (`richTextOptions: { outline: true }`) for\n * stable heading ids; without it, headings are still listed.\n */\nexport function useOutline(editor: Editor | null | undefined): OutlineSnapshot {\n // The store only listens to the editor while subscribed, so it needs no\n // explicit cleanup (and survives StrictMode's double effects).\n const store = useMemo(() => createOutlineStore(editor), [editor]);\n return useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n}\n","import React from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { navigateToHeading, type OutlineHeading } from \"@pixerate/editor\";\nimport { useOutline } from \"../hooks/useOutline\";\n\nexport interface OutlinePanelProps {\n editor: Editor | null;\n /** Heading shown above the list. Pass `null` to hide it. */\n title?: React.ReactNode;\n /** Content shown when the document has no headings. */\n emptyState?: React.ReactNode;\n /** Deepest heading level listed. Defaults to 6. */\n maxLevel?: number;\n /** Whether clicking an entry focuses the editor. Defaults to `true`. */\n focusOnNavigate?: boolean;\n /** Custom class name for the wrapper. */\n className?: string;\n /** Class name for each entry button. */\n itemClassName?: string;\n /** Class name added to the entry of the section containing the selection. */\n activeItemClassName?: string;\n /** Called after navigating to a heading. */\n onNavigate?: (heading: OutlineHeading) => void;\n}\n\n/**\n * Navigation sidebar listing the document's headings (Word's Navigation pane).\n * Clicking an entry moves the caret to that heading; the entry for the\n * section containing the selection is highlighted.\n */\nexport const OutlinePanel: React.FC<OutlinePanelProps> = ({\n editor,\n title = \"Outline\",\n emptyState = \"Add headings to see the outline.\",\n maxLevel = 6,\n focusOnNavigate = true,\n className = \"flex flex-col gap-1 text-sm\",\n itemClassName = \"w-full truncate rounded px-2 py-1 text-left hover:bg-black/5\",\n activeItemClassName = \"font-semibold bg-black/5\",\n onNavigate,\n}) => {\n const { headings, activeId } = useOutline(editor);\n const visible = headings.filter((h) => h.level <= maxLevel);\n\n return (\n <nav className={className} aria-label=\"Document outline\" data-outline-panel=\"\">\n {title != null && <div className=\"pixerate-outline-title\">{title}</div>}\n {visible.length === 0 ? (\n <div className=\"pixerate-outline-empty\">{emptyState}</div>\n ) : (\n <ul role=\"list\" style={{ listStyle: \"none\", margin: 0, padding: 0 }}>\n {visible.map((heading) => {\n const active = heading.id === activeId;\n return (\n <li key={heading.id} data-level={heading.level}>\n <button\n type=\"button\"\n className={active ? `${itemClassName} ${activeItemClassName}` : itemClassName}\n style={{ paddingLeft: `${0.5 + heading.depth * 0.75}rem` }}\n aria-current={active ? \"location\" : undefined}\n data-heading-id={heading.id}\n onClick={() => {\n if (!editor) return;\n if (navigateToHeading(editor, heading, { focus: focusOnNavigate })) {\n onNavigate?.(heading);\n }\n }}\n >\n {heading.text || \"Untitled\"}\n </button>\n </li>\n );\n })}\n </ul>\n )}\n </nav>\n );\n};\n","import { useMemo, useSyncExternalStore } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n createParagraphStylesStore,\n getStyleRegistry,\n type CreateStyleFromSelectionOptions,\n type ParagraphStylesSnapshot,\n type StyleDefinition,\n type StyleRegistry,\n} from \"@pixerate/editor\";\n\nexport type { ParagraphStylesSnapshot, StyleDefinition } from \"@pixerate/editor\";\n\nexport interface UseParagraphStylesResult extends ParagraphStylesSnapshot {\n registry: StyleRegistry | null;\n /** The style of the block at the selection. */\n currentStyle: StyleDefinition | null;\n /** Applies a paragraph style to the selected blocks. */\n apply: (id: string) => boolean;\n /** Resets the selected blocks to Normal. */\n clear: () => boolean;\n /** Updates a style (default: the current one) to the formatting at the selection. */\n updateFromSelection: (id?: string) => boolean;\n /** Creates (and applies) a style from the formatting at the selection; returns its id. */\n createFromSelection: (name: string, options?: CreateStyleFromSelectionOptions) => string | null;\n /** Applies a character style to the selection. */\n applyCharacterStyle: (id: string) => boolean;\n}\n\n/**\n * Subscribes to an editor's paragraph styles (`ParagraphStyles` extension):\n * the gallery, all styles and the style at the selection, with commands.\n * Re-renders only when the styles or the current style change.\n */\nexport function useParagraphStyles(editor: Editor | null | undefined): UseParagraphStylesResult {\n // The store only listens to the editor while subscribed (StrictMode-safe).\n const store = useMemo(() => createParagraphStylesStore(editor), [editor]);\n const snapshot = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n\n return useMemo(() => {\n const registry = getStyleRegistry(editor);\n const live = () => (editor && !editor.isDestroyed ? editor : null);\n return {\n ...snapshot,\n registry,\n currentStyle: (snapshot.currentStyleId && registry?.get(snapshot.currentStyleId)) || null,\n apply: (id) => !!live()?.chain().focus().setParagraphStyle(id).run(),\n clear: () => !!live()?.chain().focus().clearParagraphStyle().run(),\n updateFromSelection: (id) => !!live()?.chain().focus().updateParagraphStyleFromSelection(id).run(),\n createFromSelection: (name, options) => {\n const e = live();\n if (!e || !registry) return null;\n const id = options?.id ?? registry.newId(name.trim());\n const ok = e.chain().focus().createParagraphStyleFromSelection(name, { ...options, id }).run();\n return ok ? id : null;\n },\n applyCharacterStyle: (id) => !!live()?.chain().focus().setCharacterStyle(id).run(),\n };\n }, [snapshot, editor]);\n}\n","import React, { useState } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { useParagraphStyles } from \"../hooks/useParagraphStyles\";\n\nexport interface StylesGalleryProps {\n editor: Editor | null;\n /**\n * `dropdown` (default): a button showing the current style that opens the\n * list. `gallery`: the styles are always shown, in a row.\n */\n variant?: \"dropdown\" | \"gallery\";\n /** List every available paragraph style instead of the gallery (quick) styles. */\n showAllStyles?: boolean;\n /** Show the \"Update to match selection\" and \"New style from selection\" actions. Defaults to `true`. */\n showActions?: boolean;\n /** Preview each style's font, weight, style and color in its entry. Defaults to `true`. */\n preview?: boolean;\n className?: string;\n itemClassName?: string;\n activeItemClassName?: string;\n /** Called after a style is applied, updated or created. */\n onChange?: (event: { type: \"apply\" | \"update\" | \"create\"; id: string }) => void;\n}\n\nconst camel = (property: string) => property.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase());\n\nconst keepSelection = (event: React.MouseEvent) => event.preventDefault();\n\n/**\n * Paragraph styles picker (Word's Styles gallery): shows the style at the\n * selection, applies a style on click, updates the current style to match\n * the selection and creates a new style from the selection. Needs the\n * `ParagraphStyles` extension (`richTextOptions: { paragraphStyles: true }`).\n */\nexport const StylesGallery: React.FC<StylesGalleryProps> = ({\n editor,\n variant = \"dropdown\",\n showAllStyles = false,\n showActions = true,\n preview = true,\n className = \"relative inline-flex flex-wrap items-center gap-1 text-sm\",\n itemClassName = \"rounded px-2 py-1 text-left text-xs text-foreground hover:bg-muted\",\n activeItemClassName = \"bg-primary/10 text-primary\",\n onChange,\n}) => {\n const styles = useParagraphStyles(editor);\n const [open, setOpen] = useState(false);\n const [creating, setCreating] = useState(false);\n const [name, setName] = useState(\"\");\n const list = showAllStyles ? styles.styles : styles.gallery;\n const current = styles.currentStyle;\n const expanded = variant === \"gallery\" || open;\n const close = () => {\n if (variant === \"dropdown\") setOpen(false);\n setCreating(false);\n setName(\"\");\n };\n\n const previewStyle = (id: string): React.CSSProperties | undefined => {\n if (!preview || !styles.registry) return undefined;\n return Object.fromEntries(\n Object.entries(styles.registry.previewDeclarations(id)).map(([k, v]) => [camel(k), v]),\n ) as React.CSSProperties;\n };\n\n const apply = (id: string) => {\n if (styles.apply(id)) onChange?.({ type: \"apply\", id });\n close();\n };\n\n const create = (event: React.FormEvent) => {\n event.preventDefault();\n const id = name.trim() ? styles.createFromSelection(name) : null;\n if (id) onChange?.({ type: \"create\", id });\n close();\n };\n\n return (\n <div className={className} role=\"group\" aria-label=\"Paragraph styles\" data-styles-gallery={variant}>\n {variant === \"dropdown\" && (\n <button\n type=\"button\"\n className={itemClassName}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n disabled={!editor || !styles.registry}\n onMouseDown={keepSelection}\n onClick={() => setOpen((value) => !value)}\n >\n {current?.name ?? \"Styles\"} ▾\n </button>\n )}\n {expanded && (\n <div\n className={\n variant === \"dropdown\"\n ? \"absolute left-0 top-full z-20 mt-1 flex min-w-[12rem] flex-col gap-0.5 rounded-md border border-border bg-background p-1 shadow-md\"\n : \"flex flex-wrap items-center gap-1\"\n }\n >\n <div role=\"listbox\" aria-label=\"Styles\" className={variant === \"dropdown\" ? \"flex flex-col gap-0.5\" : \"flex flex-wrap gap-1\"}>\n {list.map((style) => {\n const active = style.id === styles.currentStyleId;\n return (\n <button\n key={style.id}\n type=\"button\"\n role=\"option\"\n aria-selected={active}\n data-style-id={style.id}\n className={active ? `${itemClassName} ${activeItemClassName}` : itemClassName}\n style={previewStyle(style.id)}\n onMouseDown={keepSelection}\n onClick={() => apply(style.id)}\n >\n {style.name}\n </button>\n );\n })}\n </div>\n {showActions && (\n <div className={variant === \"dropdown\" ? \"mt-1 flex flex-col gap-0.5 border-t border-border pt-1\" : \"flex items-center gap-1\"}>\n <button\n type=\"button\"\n className={itemClassName}\n disabled={!current}\n onMouseDown={keepSelection}\n onClick={() => {\n if (current && styles.updateFromSelection(current.id)) {\n onChange?.({ type: \"update\", id: current.id });\n }\n close();\n }}\n >\n {current ? `Update ${current.name} to match selection` : \"Update to match selection\"}\n </button>\n {creating ? (\n <form className=\"flex items-center gap-1\" onSubmit={create}>\n <input\n aria-label=\"New style name\"\n className=\"w-32 rounded border border-border bg-background px-1 py-0.5 text-xs\"\n value={name}\n autoFocus\n onChange={(event) => setName(event.target.value)}\n />\n <button type=\"submit\" className={itemClassName} disabled={!name.trim()}>\n Create\n </button>\n </form>\n ) : (\n <button\n type=\"button\"\n className={itemClassName}\n disabled={!editor || !styles.registry}\n onMouseDown={keepSelection}\n onClick={() => setCreating(true)}\n >\n New style from selection\n </button>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n );\n};\n","import { useState, useRef, useCallback, useMemo } from 'react';\nimport {\n SpreadsheetController,\n bindSpreadsheetTableActions,\n type SpreadsheetControllerOptions,\n type SpreadsheetDocument,\n type CellCoordinate,\n type CellRange,\n type SpreadsheetColumn,\n type SpreadsheetRow,\n type SpreadsheetDataSource,\n type SpreadsheetDocument as SheetDocument,\n type SpreadsheetNameScope,\n type SpreadsheetCommitResult,\n type SpreadsheetValidationAction,\n type SpreadsheetValidationPrompt\n} from '@pixerate/editor/spreadsheet';\n\nexport function useSpreadsheetEditor(options: SpreadsheetControllerOptions = {}) {\n // Callbacks are read through a ref so they are never stale.\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const settersRef = useRef<{\n setDoc?: (doc: SpreadsheetDocument) => void;\n setActiveCell?: (cell: CellCoordinate | null) => void;\n setSelectedRange?: (range: CellRange | null) => void;\n }>({});\n\n // Create the controller first so the initial state reflects its document\n // (including default rows and columns when no document is passed).\n const [controller] = useState(\n () =>\n new SpreadsheetController({\n ...options,\n onDocumentChange: (updated) => {\n settersRef.current.setDoc?.({ ...updated });\n optionsRef.current.onDocumentChange?.(updated);\n },\n onSelectionChange: (active, range) => {\n settersRef.current.setActiveCell?.(active);\n settersRef.current.setSelectedRange?.(range);\n optionsRef.current.onSelectionChange?.(active, range);\n },\n onCellCommit: (rowId, colId, raw, value) => {\n optionsRef.current.onCellCommit?.(rowId, colId, raw, value);\n },\n }),\n );\n\n const [doc, setDoc] = useState<SpreadsheetDocument>(() => ({ ...controller.document }));\n const [activeCell, setActiveCell] = useState<CellCoordinate | null>(controller.activeCell);\n const [selectedRange, setSelectedRange] = useState<CellRange | null>(controller.selectedRange);\n const [editingCell, setEditingCell] = useState<CellCoordinate | null>(null);\n const [draftValue, setDraftState] = useState<string>('');\n // Invalid input waiting for the user (data validation alert).\n const [validationPrompt, setValidationPrompt] = useState<SpreadsheetValidationPrompt | null>(null);\n settersRef.current = { setDoc, setActiveCell, setSelectedRange };\n\n // The controller commits its own `draftValue` (`commitEditing()` without an\n // argument), so typed text must reach it, not just React state.\n const setDraftValue = useCallback((value: string) => {\n controller.draftValue = value;\n setDraftState(value);\n }, [controller]);\n\n const setCellValue = useCallback((rowId: string, colId: string, raw: string) => {\n controller.setCellValue(rowId, colId, raw);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const selectCell = useCallback((row: number, col: number, extendSelection = false) => {\n controller.selectCell(row, col, extendSelection);\n setActiveCell(controller.activeCell);\n setSelectedRange(controller.selectedRange);\n }, [controller]);\n\n const selectRange = useCallback((range: CellRange) => {\n controller.selectRange(range);\n setSelectedRange(controller.selectedRange);\n }, [controller]);\n\n const startEditing = useCallback((row?: number, col?: number, initialVal?: string) => {\n controller.startEditing(row, col, initialVal);\n setActiveCell(controller.activeCell);\n setEditingCell(controller.editingCell);\n setDraftValue(controller.draftValue);\n }, [controller]);\n\n // Input breaking a data validation rule is not committed: the editor stays\n // open and `validationPrompt` holds the alert until it is resolved.\n const syncEditing = useCallback(() => {\n setEditingCell(controller.editingCell);\n setDraftValue(controller.draftValue);\n setValidationPrompt(controller.validationPrompt);\n setActiveCell(controller.activeCell);\n setSelectedRange(controller.selectedRange);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const commitEditing = useCallback((val?: string): SpreadsheetCommitResult => {\n const result = controller.commitEditing(val);\n syncEditing();\n return result;\n }, [controller, syncEditing]);\n\n /** Commits input from outside the cell editor (formula bar, list dropdown) with validation. */\n const commitCellInput = useCallback((rowId: string, colId: string, raw: string): SpreadsheetCommitResult => {\n const result = controller.commitCellInput(rowId, colId, raw);\n syncEditing();\n return result;\n }, [controller, syncEditing]);\n\n /** Answers the validation alert: accept (warning / information), retry or cancel. */\n const resolveValidationPrompt = useCallback((action: SpreadsheetValidationAction) => {\n controller.resolveValidationPrompt(action);\n syncEditing();\n }, [controller, syncEditing]);\n\n const cancelEditing = useCallback(() => {\n controller.cancelEditing();\n setEditingCell(null);\n setDraftValue('');\n }, [controller]);\n\n const moveCursor = useCallback((dir: 'up' | 'down' | 'left' | 'right', extend = false) => {\n controller.moveCursor(dir, extend);\n setActiveCell(controller.activeCell);\n setSelectedRange(controller.selectedRange);\n }, [controller]);\n\n const insertColumn = useCallback((index: number, config?: Partial<SpreadsheetColumn>) => {\n controller.insertColumn(index, config);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const deleteColumn = useCallback((colId: string) => {\n controller.deleteColumn(colId);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const insertRow = useCallback((index: number, config?: Partial<SpreadsheetRow>) => {\n controller.insertRow(index, config);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const deleteRow = useCallback((rowId: string) => {\n controller.deleteRow(rowId);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const setColumnWidth = useCallback((colId: string, width: number) => {\n controller.setColumnWidth(colId, width);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const autoFitColumnWidth = useCallback((colId: string, customWidth?: number) => {\n controller.autoFitColumnWidth(colId, customWidth);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const registerDataSource = useCallback((ds: SpreadsheetDataSource) => {\n controller.registerDataSource(ds);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const setPrimaryDataSource = useCallback((id: string | undefined) => {\n controller.setPrimaryDataSource(id);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const recalculateAll = useCallback(() => {\n controller.recalculateAll();\n setDoc({ ...controller.document });\n }, [controller]);\n\n // Undo can switch to the sheet the step belongs to.\n const undo = useCallback(() => {\n controller.undo();\n setDoc({ ...controller.document });\n setActiveCell(controller.activeCell);\n setSelectedRange(controller.selectedRange);\n }, [controller]);\n\n const redo = useCallback(() => {\n controller.redo();\n setDoc({ ...controller.document });\n setActiveCell(controller.activeCell);\n setSelectedRange(controller.selectedRange);\n }, [controller]);\n\n // Table operations (sort, filters, freeze, hide, merge, autofill, categories,\n // transpose, CSV, clipboard). The controller reports their changes through\n // onDocumentChange / onSelectionChange, which update the state above.\n const tableActions = useMemo(() => bindSpreadsheetTableActions(controller), [controller]);\n // What to render: visible rows (with group headers) and columns, frozen\n // offsets and merged-cell spans. Recomputed whenever the document changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const viewModel = useMemo(() => controller.getViewModel(), [controller, doc]);\n // Sheet tabs and defined names. Every workbook change notifies through\n // onDocumentChange, so they follow `doc`.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const sheets = useMemo(() => controller.getSheets(), [controller, doc]);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const names = useMemo(() => controller.getNames(), [controller, doc]);\n\n // Switching sheets commits the edit in progress.\n const afterSheetSwitch = useCallback(() => {\n setEditingCell(controller.editingCell);\n setDraftValue(controller.draftValue);\n setActiveCell(controller.activeCell);\n setSelectedRange(controller.selectedRange);\n setDoc({ ...controller.document });\n }, [controller, setDraftValue]);\n\n const workbookActions = useMemo(\n () => ({\n setActiveSheet: (idOrName: string) => {\n const changed = controller.setActiveSheet(idOrName);\n afterSheetSwitch();\n return changed;\n },\n addSheet: (options?: { name?: string; index?: number; document?: Partial<SheetDocument>; activate?: boolean }) => {\n const id = controller.addSheet(options);\n afterSheetSwitch();\n return id;\n },\n renameSheet: (idOrName: string, newName: string) => controller.renameSheet(idOrName, newName),\n moveSheet: (idOrName: string, toIndex: number) => controller.moveSheet(idOrName, toIndex),\n deleteSheet: (idOrName: string) => {\n const deleted = controller.deleteSheet(idOrName);\n afterSheetSwitch();\n return deleted;\n },\n duplicateSheet: (idOrName: string, options?: { name?: string; index?: number; activate?: boolean }) => {\n const id = controller.duplicateSheet(idOrName, options);\n afterSheetSwitch();\n return id;\n },\n defineName: (name: string, refersTo: string, options?: SpreadsheetNameScope & { comment?: string }) =>\n controller.defineName(name, refersTo, options),\n renameName: (oldName: string, newName: string, options?: SpreadsheetNameScope) =>\n controller.renameName(oldName, newName, options),\n deleteName: (name: string, options?: SpreadsheetNameScope) => controller.deleteName(name, options),\n }),\n [controller, afterSheetSwitch],\n );\n\n // Conditional formatting of every formatted cell (re-evaluated incrementally).\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const conditionalFormatOverlay = useMemo(() => controller.getConditionalFormatOverlay(), [controller, doc]);\n\n return {\n document: doc,\n activeCell,\n selectedRange,\n editingCell,\n draftValue,\n setDraftValue,\n validationPrompt,\n resolveValidationPrompt,\n commitCellInput,\n controller,\n getCell: (rowId: string, colId: string) => controller.getCell(rowId, colId),\n setCellValue,\n selectCell,\n selectRange,\n startEditing,\n commitEditing,\n cancelEditing,\n moveCursor,\n insertColumn,\n deleteColumn,\n insertRow,\n deleteRow,\n setColumnWidth,\n autoFitColumnWidth,\n loadDocument: (document: SpreadsheetDocument) => {\n controller.loadDocument(document);\n setDoc({ ...controller.document });\n setActiveCell(null);\n setSelectedRange(null);\n setEditingCell(null);\n setDraftValue('');\n },\n syncWithDataSource: () => {\n controller.syncWithDataSource();\n controller.recalculateAll();\n setDoc({ ...controller.document });\n },\n registerDataSource,\n setPrimaryDataSource,\n recalculateAll,\n exportToTsv: (range?: CellRange | null) => controller.exportToTsv(range),\n importFromTsv: (data: string) => {\n controller.importFromTsv(data);\n setDoc({ ...controller.document });\n },\n ...tableActions,\n viewModel,\n /** The sheets in tab order (see `SpreadsheetController.getSheets`). */\n sheets,\n activeSheetId: controller.activeSheetId,\n /** Defined names (see `SpreadsheetController.getNames`). */\n names,\n ...workbookActions,\n conditionalFormatOverlay,\n undo,\n redo\n };\n}\n","import React, { useRef, useState, useMemo, useEffect, useCallback } from 'react';\nimport {\n indexToColName,\n getSpreadsheetMenuItems,\n normalizeRange,\n rangeContains,\n type SpreadsheetColumn,\n type SpreadsheetRow,\n type CellData,\n type CellRange,\n type SpreadsheetMenuItem,\n type SpreadsheetViewColumn,\n type SpreadsheetViewRow,\n formatCellForDisplay,\n numberFormatColorToCss,\n getConditionalFormatCss,\n getConditionalFormatIcon,\n getDataBarCss,\n type ConditionalCellFormat,\n type SpreadsheetPanelId\n} from '@pixerate/editor/spreadsheet';\nimport { useSpreadsheetEditor } from './useSpreadsheetEditor';\nimport { SpreadsheetContextMenu } from './SpreadsheetContextMenu';\nimport { SpreadsheetGroupRow } from './SpreadsheetGroupRow';\nimport { useFillHandle, useSpreadsheetClipboard } from './useSpreadsheetTableInteractions';\nimport { SpreadsheetValidationDialog } from './SpreadsheetValidationDialog';\nimport { SpreadsheetConditionalFormatPanel, SpreadsheetDataValidationPanel } from './SpreadsheetRulePanels';\nimport { useSpreadsheetViewport } from './useSpreadsheetViewport';\n\n// Sizes of the sticky header row and row-number column, for frozen-pane offsets.\nconst COLUMN_HEADER_HEIGHT = 28;\nconst ROW_HEADER_WIDTH = 48;\n\n/** Sticky positioning for cells in frozen rows and/or columns. */\nfunction frozenCellStyle(\n viewRow: Extract<SpreadsheetViewRow, { kind: 'row' }>,\n viewCol: SpreadsheetViewColumn\n): React.CSSProperties | undefined {\n if (!viewRow.frozen && !viewCol.frozen) return undefined;\n return {\n position: 'sticky',\n ...(viewRow.frozen ? { top: COLUMN_HEADER_HEIGHT + viewRow.stickyTop } : {}),\n ...(viewCol.frozen ? { left: ROW_HEADER_WIDTH + viewCol.stickyLeft } : {}),\n zIndex: viewRow.frozen && viewCol.frozen ? 14 : viewRow.frozen ? 12 : 11,\n background: 'var(--background, #fff)'\n };\n}\nimport { FormulaHints } from './FormulaHints';\nimport { SheetTabs } from './SheetTabs';\n\nconst coordKey = (cell: { row: number; col: number } | null) => (cell ? `${indexToColName(cell.col)}${cell.row + 1}` : '');\n\n/** Thin border drawn on the outer edges of a dynamic array's spill range. */\nfunction spillBorderStyle(range: CellRange, row: number, col: number): React.CSSProperties {\n const line = '1px solid color-mix(in srgb, var(--primary, #6366f1) 60%, transparent)';\n return {\n position: 'absolute',\n inset: 0,\n pointerEvents: 'none',\n zIndex: 5,\n borderTop: row === range.startRow ? line : undefined,\n borderBottom: row === range.endRow ? line : undefined,\n borderLeft: col === range.startCol ? line : undefined,\n borderRight: col === range.endCol ? line : undefined\n };\n}\n\n/**\n * A cell's display text: formatted with its number format, numbers\n * right-aligned, `[Red]`-style colours applied. A conditional format adds a\n * data bar and / or an icon, and its font colour wins over the format's.\n */\nfunction CellText({ cell, conditional }: { cell: CellData; conditional?: ConditionalCellFormat }) {\n const shown = formatCellForDisplay(cell);\n const color = conditional?.color ?? (shown.color ? numberFormatColorToCss(shown.color) : undefined);\n const decorated = !!conditional?.dataBar || !!conditional?.icon;\n const text = (\n <span\n className={`truncate block max-w-full ${cell.error ? 'text-destructive font-semibold' : ''}`}\n title={cell.error ? cell.errorMessage ?? cell.error : undefined}\n data-numeric={shown.numeric ? '' : undefined}\n style={\n shown.numeric || color || decorated\n ? {\n ...(decorated ? { position: 'relative' as const } : {}),\n ...(conditional?.icon ? { flex: 1, minWidth: 0 } : {}),\n ...(shown.numeric ? { textAlign: 'right' as const } : {}),\n ...(color ? { color } : {})\n }\n : undefined\n }\n >\n {conditional?.hideValue ? '' : shown.text}\n </span>\n );\n if (!conditional || !decorated) return text;\n const icon = conditional.icon ? getConditionalFormatIcon(conditional.icon.set, conditional.icon.index) : null;\n return (\n <>\n {conditional.dataBar && (\n <span aria-hidden=\"true\" className=\"spreadsheet-data-bar\" style={getDataBarCss(conditional.dataBar) as React.CSSProperties} />\n )}\n {icon ? (\n <span className=\"flex items-center gap-1 min-w-0\" style={{ position: 'relative' }}>\n <span className=\"spreadsheet-cf-icon shrink-0\" role=\"img\" aria-label={icon.label} data-icon={conditional.icon!.id} style={{ color: icon.color }}>\n {icon.glyph}\n </span>\n {text}\n </span>\n ) : (\n text\n )}\n </>\n );\n}\n\nexport interface SpreadsheetEditorProps {\n state?: ReturnType<typeof useSpreadsheetEditor>;\n readOnly?: boolean;\n customCellRenderer?: (props: { row: SpreadsheetRow; col: SpreadsheetColumn; cell: CellData }) => React.ReactNode;\n onAddColumnClick?: () => void;\n onColumnHeaderClick?: (col: SpreadsheetColumn) => void;\n onColumnResize?: (colId: string, width: number) => void;\n /** Show the sheet tabs bar under the grid (add, switch, rename, reorder, delete sheets). */\n showSheetTabs?: boolean;\n /**\n * Render only the rows and columns in (or near) view. `'auto'` (default)\n * virtualises sheets with more than 200 displayed rows or 60 columns;\n * `true` / `false` force it.\n */\n virtualize?: boolean | 'auto';\n}\n\n/** A rendered column, or the space standing for the columns left out. */\ntype ColumnSlot = { kind: 'col'; viewCol: SpreadsheetViewColumn } | { kind: 'space'; key: string; width: number };\n/** A rendered row, or the space standing for the rows left out. */\ntype RowSlot = { kind: 'row'; viewRow: SpreadsheetViewRow } | { kind: 'space'; key: string; height: number };\n\nexport const SpreadsheetEditor: React.FC<SpreadsheetEditorProps> = ({\n state: externalState,\n readOnly = false,\n customCellRenderer,\n onAddColumnClick,\n onColumnHeaderClick,\n onColumnResize,\n showSheetTabs = false,\n virtualize = 'auto'\n}) => {\n const defaultState = useSpreadsheetEditor();\n const state = externalState || defaultState;\n const gridRef = useRef<HTMLDivElement>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n const formulaBarRef = useRef<HTMLInputElement>(null);\n const cellInputRef = useRef<HTMLInputElement>(null);\n\n const [resizingColId, setResizingColId] = useState<string | null>(null);\n const [hoveredColId, setHoveredColId] = useState<string | null>(null);\n const [resizeStartX, setResizeStartX] = useState(0);\n const [resizeStartWidth, setResizeStartWidth] = useState(0);\n\n // Table operations: render model, clipboard, fill handle and context menu.\n const view = state.viewModel;\n // Virtualised rendering: frozen rows/columns, a spacer, the rows and\n // columns in view, another spacer (everything for small sheets).\n const { window: viewWindow, onScroll: handleGridScroll } = useSpreadsheetViewport(scrollRef, view, {\n virtualize,\n merges: state.document.table?.merges,\n activeCell: state.activeCell\n });\n const columnSlots = useMemo<ColumnSlot[]>(() => {\n const col = (viewCol: SpreadsheetViewColumn): ColumnSlot => ({ kind: 'col', viewCol });\n if (!viewWindow.virtual) return view.columns.map(col);\n const slots = view.columns.slice(0, viewWindow.frozenColumns).map(col);\n if (viewWindow.leftSpace > 0) slots.push({ kind: 'space', key: 'space:left', width: viewWindow.leftSpace });\n for (let i = viewWindow.colStart; i < viewWindow.colEnd; i++) slots.push(col(view.columns[i]));\n if (viewWindow.rightSpace > 0) slots.push({ kind: 'space', key: 'space:right', width: viewWindow.rightSpace });\n return slots;\n }, [view, viewWindow]);\n const renderedColumns = useMemo(\n () => columnSlots.flatMap((slot) => (slot.kind === 'col' ? [slot.viewCol] : [])),\n [columnSlots]\n );\n const rowSlots = useMemo<RowSlot[]>(() => {\n const row = (viewRow: SpreadsheetViewRow): RowSlot => ({ kind: 'row', viewRow });\n if (!viewWindow.virtual) return view.rows.map(row);\n const slots = view.rows.slice(0, viewWindow.frozenRows).map(row);\n if (viewWindow.topSpace > 0) slots.push({ kind: 'space', key: 'space:top', height: viewWindow.topSpace });\n for (let i = viewWindow.rowStart; i < viewWindow.rowEnd; i++) slots.push(row(view.rows[i]));\n if (viewWindow.bottomSpace > 0) slots.push({ kind: 'space', key: 'space:bottom', height: viewWindow.bottomSpace });\n return slots;\n }, [view, viewWindow]);\n const { copyShortcutFallback } = useSpreadsheetClipboard(gridRef, state, readOnly);\n const { fillTarget, startFill, extendFill } = useFillHandle(state);\n const [menu, setMenu] = useState<{ x: number; y: number; items: SpreadsheetMenuItem[] } | null>(null);\n // Conditional formatting / data validation manager, opened from the context menu.\n const [panel, setPanel] = useState<SpreadsheetPanelId | null>(null);\n // List dropdown of a list-validated cell.\n const [listMenu, setListMenu] = useState<{ x: number; y: number; row: number; col: number; values: string[] } | null>(null);\n const overlay = state.conditionalFormatOverlay;\n const filter = state.document.table?.filter;\n const filteredColIds = useMemo(\n () => new Set(filter?.enabled ? filter.rules.map((r) => r.colId) : []),\n [filter]\n );\n\n const handleCellContextMenu = useCallback((rIdx: number, cIdx: number, e: React.MouseEvent) => {\n if (readOnly) return;\n e.preventDefault();\n if (state.editingCell) state.commitEditing();\n if (!state.selectedRange || !rangeContains(state.selectedRange, rIdx, cIdx)) {\n state.selectCell(rIdx, cIdx);\n }\n setMenu({ x: e.clientX, y: e.clientY, items: getSpreadsheetMenuItems(state.controller, { row: rIdx, col: cIdx }) });\n }, [readOnly, state]);\n\n // Defined names for formula autocomplete.\n const nameSuggestions = useMemo(\n () => state.controller.getNameSuggestions(),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [state.controller, state.document]\n );\n\n const activeRawValue = useMemo(() => {\n if (!state.activeCell) return '';\n const row = state.document.rows[state.activeCell.row];\n const col = state.document.columns[state.activeCell.col];\n if (!row || !col) return '';\n return state.getCell(row.id, col.id).raw;\n }, [state.activeCell, state.document]);\n\n // The dynamic array under the active cell (anchor or spilled cell): it gets\n // a border, and a spilled cell shows the anchor's formula greyed out.\n const activeSpill = useMemo(\n () => (state.activeCell ? state.controller.getSpillAt(state.activeCell.row, state.activeCell.col) : null),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [state.controller, state.activeCell, state.document]\n );\n const spillFormula = activeSpill && !activeRawValue && activeSpill.key !== coordKey(state.activeCell) ? activeSpill.formula : '';\n\n const coordLabel = useMemo(() => {\n if (!state.activeCell) return '--';\n const colName = indexToColName(state.activeCell.col);\n return `${colName}${state.activeCell.row + 1}`;\n }, [state.activeCell]);\n\n // Text typed in the formula bar while no cell editor is open.\n const [formulaDraft, setFormulaDraft] = useState<string | null>(null);\n const activeColumn = state.activeCell ? state.document.columns[state.activeCell.col] : undefined;\n const formulaBarReadOnly = readOnly || !state.activeCell || !!activeColumn?.readOnly;\n\n useEffect(() => {\n setFormulaDraft(null);\n }, [state.activeCell?.row, state.activeCell?.col]);\n\n const commitFormulaBar = () => {\n if (state.editingCell) {\n state.commitEditing();\n return;\n }\n if (formulaDraft === null || !state.activeCell) return;\n const row = state.document.rows[state.activeCell.row];\n const col = state.document.columns[state.activeCell.col];\n if (row && col && !formulaBarReadOnly && formulaDraft !== activeRawValue) {\n state.commitCellInput(row.id, col.id, formulaDraft);\n }\n setFormulaDraft(null);\n };\n\n const handleCellClick = useCallback((rIdx: number, cIdx: number, e: React.MouseEvent) => {\n if (state.editingCell && (state.editingCell.row !== rIdx || state.editingCell.col !== cIdx)) {\n state.commitEditing();\n }\n state.selectCell(rIdx, cIdx, e.shiftKey);\n }, [state]);\n\n const handleCellDblClick = useCallback((rIdx: number, cIdx: number) => {\n if (readOnly) return;\n const col = state.document.columns[cIdx];\n if (col?.readOnly) return;\n state.startEditing(rIdx, cIdx);\n }, [readOnly, state]);\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\n if (state.editingCell) {\n if (e.key === 'Enter') {\n e.preventDefault();\n // Invalid input keeps the editor open behind the validation alert.\n if (state.commitEditing().status !== 'committed') return;\n state.moveCursor('down');\n } else if (e.key === 'Escape') {\n e.preventDefault();\n state.cancelEditing();\n } else if (e.key === 'Tab') {\n e.preventDefault();\n if (state.commitEditing().status !== 'committed') return;\n state.moveCursor(e.shiftKey ? 'left' : 'right');\n } else {\n return;\n }\n // The cell input unmounts; keep focus on the grid so typing continues.\n gridRef.current?.focus();\n return;\n }\n\n if (!state.activeCell) return;\n\n if (e.altKey && e.key === 'ArrowDown') {\n // Alt+Down opens the list of a list-validated cell.\n e.preventDefault();\n openListMenu(state.activeCell.row, state.activeCell.col);\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n state.moveCursor('up', e.shiftKey);\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n state.moveCursor('down', e.shiftKey);\n } else if (e.key === 'ArrowLeft') {\n e.preventDefault();\n state.moveCursor('left', e.shiftKey);\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n state.moveCursor('right', e.shiftKey);\n } else if (e.key === 'Tab') {\n e.preventDefault();\n state.moveCursor(e.shiftKey ? 'left' : 'right');\n } else if (e.key === 'Enter') {\n e.preventDefault();\n const col = state.document.columns[state.activeCell.col];\n if (!readOnly && !col?.readOnly) {\n state.startEditing();\n }\n } else if (e.key === 'Backspace' || e.key === 'Delete') {\n if (readOnly) return;\n const row = state.document.rows[state.activeCell.row];\n const col = state.document.columns[state.activeCell.col];\n if (row && col && !col.readOnly) {\n e.preventDefault();\n state.setCellValue(row.id, col.id, '');\n }\n } else if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'z') {\n // With Shift held, e.key is 'Z'.\n e.preventDefault();\n if (e.shiftKey) {\n state.redo();\n } else {\n state.undo();\n }\n } else if (e.ctrlKey && !e.metaKey && e.key.toLowerCase() === 'y') {\n e.preventDefault();\n state.redo();\n } else if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'c') {\n // Copy the selection, not the whole sheet. The browser's copy event\n // writes TSV, HTML and the internal format; the fallback writes TSV.\n copyShortcutFallback();\n } else if (!readOnly && e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {\n const col = state.document.columns[state.activeCell.col];\n if (!col?.readOnly) {\n // The key becomes the draft; without preventDefault the browser would\n // also type it into the newly focused cell input (\"1\" -> \"11\").\n e.preventDefault();\n state.startEditing(state.activeCell.row, state.activeCell.col, e.key);\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [readOnly, state, copyShortcutFallback]);\n\n // --- Data validation: list dropdown, input message, alerts ---\n\n const activeListValues = useMemo(\n () => (state.activeCell && !readOnly ? state.controller.getValidationListValues(state.activeCell.row, state.activeCell.col) : null),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [state.controller, state.activeCell, state.document, readOnly]\n );\n const activeRule = useMemo(\n () => (state.activeCell ? state.controller.getDataValidationAt(state.activeCell.row, state.activeCell.col) : undefined),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [state.controller, state.activeCell, state.document]\n );\n const inputMessage =\n activeRule && activeRule.showInputMessage !== false && (activeRule.inputTitle || activeRule.inputMessage) ? activeRule : null;\n\n function openListMenu(row: number, col: number, anchor?: HTMLElement | null) {\n if (readOnly || state.document.columns[col]?.readOnly) return;\n const values = state.controller.getValidationListValues(row, col);\n if (!values) return;\n const td = anchor ?? gridRef.current?.querySelector<HTMLElement>(`td[data-row=\"${row}\"][data-col=\"${col}\"]`);\n const rect = td?.getBoundingClientRect();\n setListMenu({ x: rect ? rect.left : 0, y: rect ? rect.bottom : 0, row, col, values });\n }\n\n // Close the list on a press outside it (or on its arrow, which toggles it).\n useEffect(() => {\n if (!listMenu) return;\n const close = (e: MouseEvent) => {\n if (!(e.target as Element | null)?.closest?.('[aria-label=\"Allowed values\"], .spreadsheet-list-arrow')) setListMenu(null);\n };\n window.addEventListener('mousedown', close);\n return () => window.removeEventListener('mousedown', close);\n }, [listMenu]);\n\n const chooseListValue = (value: string) => {\n if (!listMenu) return;\n const row = state.document.rows[listMenu.row];\n const col = state.document.columns[listMenu.col];\n setListMenu(null);\n if (row && col) state.commitCellInput(row.id, col.id, value);\n gridRef.current?.focus();\n };\n\n const resolveValidation = (action: 'accept' | 'retry' | 'cancel') => {\n state.resolveValidationPrompt(action);\n // Back to the cell editor when it is still open (retry), else the grid.\n requestAnimationFrame(() => {\n if (cellInputRef.current) cellInputRef.current.focus();\n else gridRef.current?.focus();\n });\n };\n // The resize effect reads these through refs: re-running it on every width\n // update would reset the in-progress drag (and skip onColumnResize).\n const stateRef = useRef(state);\n stateRef.current = state;\n const onColumnResizeRef = useRef(onColumnResize);\n onColumnResizeRef.current = onColumnResize;\n\n useEffect(() => {\n if (!resizingColId) return;\n\n if (typeof document !== 'undefined') {\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n }\n\n let rafId: number | null = null;\n let pendingWidth = resizeStartWidth;\n let hasDragged = false;\n\n const handleMouseMove = (e: MouseEvent) => {\n const delta = e.clientX - resizeStartX;\n if (Math.abs(delta) > 2) {\n hasDragged = true;\n }\n pendingWidth = Math.max(30, resizeStartWidth + delta);\n\n if (rafId === null) {\n rafId = requestAnimationFrame(() => {\n rafId = null;\n stateRef.current.setColumnWidth(resizingColId, pendingWidth);\n });\n }\n };\n\n const handleMouseUp = () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n if (hasDragged) {\n stateRef.current.setColumnWidth(resizingColId, pendingWidth);\n onColumnResizeRef.current?.(resizingColId, pendingWidth);\n }\n setResizingColId(null);\n if (typeof document !== 'undefined') {\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }\n };\n\n window.addEventListener('mousemove', handleMouseMove);\n window.addEventListener('mouseup', handleMouseUp);\n return () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n }\n if (typeof document !== 'undefined') {\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }\n window.removeEventListener('mousemove', handleMouseMove);\n window.removeEventListener('mouseup', handleMouseUp);\n };\n }, [resizingColId, resizeStartX, resizeStartWidth]);\n\n const measureElementContentWidth = useCallback((el: HTMLElement, container: HTMLElement): number => {\n if (typeof document === 'undefined') return 0;\n\n let maxW = el.scrollWidth || 0;\n const firstChild = el.firstElementChild as HTMLElement | null;\n if (firstChild && firstChild.scrollWidth > maxW) {\n maxW = firstChild.scrollWidth;\n }\n\n const truncated = el.querySelectorAll<HTMLElement>('.truncate, [title], span, div');\n truncated.forEach((node) => {\n if (node.scrollWidth > maxW) {\n maxW = node.scrollWidth;\n }\n });\n\n try {\n const clone = (firstChild ? firstChild.cloneNode(true) : el.cloneNode(true)) as HTMLElement;\n clone.style.cssText = `\n position: absolute !important;\n visibility: hidden !important;\n width: max-content !important;\n min-width: max-content !important;\n max-width: none !important;\n overflow: visible !important;\n white-space: nowrap !important;\n pointer-events: none !important;\n top: -9999px !important;\n left: -9999px !important;\n `;\n\n const allNodes = clone.querySelectorAll<HTMLElement>('*');\n allNodes.forEach((node) => {\n node.style.maxWidth = 'none';\n node.style.overflow = 'visible';\n node.style.textOverflow = 'clip';\n node.style.whiteSpace = 'nowrap';\n if (\n node.classList.contains('truncate') ||\n node.classList.contains('min-w-0') ||\n node.classList.contains('w-full') ||\n node.classList.contains('max-w-0') ||\n node.classList.contains('flex-1')\n ) {\n node.style.width = 'max-content';\n node.style.minWidth = 'max-content';\n }\n });\n\n container.appendChild(clone);\n const rect = clone.getBoundingClientRect();\n container.removeChild(clone);\n\n if (rect.width > maxW) {\n maxW = rect.width;\n }\n } catch {\n // Ignore cloning/measuring errors\n }\n\n return maxW;\n }, []);\n\n const autoFitColumn = useCallback((colId: string, colIndex: number) => {\n const col = state.document.columns.find((c) => c.id === colId);\n if (!col) return;\n\n let calculatedWidth = 0;\n\n if (gridRef.current && typeof document !== 'undefined') {\n const table = gridRef.current.querySelector('table');\n if (table) {\n // Look cells up by column index: hidden columns and merges shift DOM positions.\n const th = table.querySelector(`thead th[data-col=\"${colIndex}\"]`) as HTMLElement | null;\n if (th) {\n const headerInner = (th.firstElementChild as HTMLElement) || th;\n const headerW = measureElementContentWidth(headerInner, gridRef.current);\n calculatedWidth = Math.max(calculatedWidth, headerW + 28);\n }\n\n const rows = table.querySelectorAll('tbody tr');\n const sampleLimit = Math.min(rows.length, 150);\n for (let r = 0; r < sampleLimit; r++) {\n const tr = rows[r];\n const td = tr.querySelector(`td[data-col=\"${colIndex}\"][colspan=\"1\"]`) as HTMLElement | null;\n if (td) {\n const cellW = measureElementContentWidth(td, gridRef.current);\n calculatedWidth = Math.max(calculatedWidth, cellW + 20);\n }\n }\n }\n }\n\n if (calculatedWidth > 0) {\n const finalWidth = Math.min(600, Math.max(50, Math.ceil(calculatedWidth)));\n state.setColumnWidth(colId, finalWidth);\n } else {\n state.autoFitColumnWidth?.(colId);\n }\n\n const updatedCol = state.document.columns.find((c) => c.id === colId);\n if (updatedCol && onColumnResize) {\n onColumnResize(updatedCol.id, updatedCol.width || 130);\n }\n }, [state, measureElementContentWidth, onColumnResize]);\n\n const handleResizeDblClick = useCallback((colId: string, colIndex: number, e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n autoFitColumn(colId, colIndex);\n }, [autoFitColumn]);\n\n const handleHeaderDblClick = useCallback((colId: string, colIndex: number, e: React.MouseEvent) => {\n const target = e.currentTarget as HTMLElement | null;\n if (target) {\n const rect = target.getBoundingClientRect();\n if (rect.right - e.clientX <= 12) {\n e.preventDefault();\n e.stopPropagation();\n autoFitColumn(colId, colIndex);\n }\n }\n }, [autoFitColumn]);\n\n const isCellSelected = (rIdx: number, cIdx: number) => {\n if (!state.selectedRange) return false;\n const minR = Math.min(state.selectedRange.startRow, state.selectedRange.endRow);\n const maxR = Math.max(state.selectedRange.startRow, state.selectedRange.endRow);\n const minC = Math.min(state.selectedRange.startCol, state.selectedRange.endCol);\n const maxC = Math.max(state.selectedRange.startCol, state.selectedRange.endCol);\n return rIdx >= minR && rIdx <= maxR && cIdx >= minC && cIdx <= maxC;\n };\n\n const isActiveCell = (rIdx: number, cIdx: number) => {\n return state.activeCell?.row === rIdx && state.activeCell?.col === cIdx;\n };\n\n const grid = (\n <div\n ref={gridRef}\n className=\"flex flex-col h-full w-full overflow-hidden border border-border bg-background select-none outline-none text-foreground font-sans text-xs\"\n tabIndex={0}\n onKeyDown={handleKeyDown}\n role=\"grid\"\n aria-label=\"Spreadsheet\"\n >\n {/* Formula Bar */}\n <div className=\"flex items-center gap-2 border-b border-border bg-muted/20 px-3 py-1.5 text-xs font-mono\">\n <div className=\"flex h-6 min-w-[3rem] items-center justify-center rounded border border-border bg-background px-1.5 font-semibold text-foreground\">\n {coordLabel}\n </div>\n <div className=\"flex items-center text-muted-foreground select-none\">\n <span className=\"italic font-serif font-bold text-sm text-primary\">fx</span>\n </div>\n <input\n ref={formulaBarRef}\n type=\"text\"\n className=\"flex-1 bg-transparent px-2 py-0.5 outline-none font-sans text-xs text-foreground placeholder:text-muted-foreground/60 focus:bg-background focus:ring-1 focus:ring-primary rounded\"\n placeholder=\"Enter a value or formula (e.g. =SUM(A1:A5))\"\n aria-label=\"Formula bar\"\n readOnly={formulaBarReadOnly}\n data-spill-formula={!state.editingCell && formulaDraft === null && spillFormula ? 'true' : undefined}\n style={!state.editingCell && formulaDraft === null && spillFormula ? { color: 'var(--muted-foreground, #94a3b8)' } : undefined}\n value={state.editingCell ? state.draftValue : formulaDraft ?? (activeRawValue || spillFormula)}\n onFocus={() => {\n if (!state.editingCell) setFormulaDraft(activeRawValue);\n }}\n onChange={(e) => {\n if (state.editingCell) {\n state.setDraftValue(e.target.value);\n } else if (state.activeCell) {\n setFormulaDraft(e.target.value);\n }\n }}\n onBlur={() => commitFormulaBar()}\n onKeyDown={(e) => {\n // Keys typed here must not reach the grid's navigation handler.\n e.stopPropagation();\n if (e.key === 'Enter') {\n e.preventDefault();\n commitFormulaBar();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n setFormulaDraft(null);\n if (state.editingCell) state.cancelEditing();\n }\n }}\n />\n {!formulaBarReadOnly && (\n <FormulaHints\n inputRef={formulaBarRef}\n value={state.editingCell ? state.draftValue : formulaDraft ?? activeRawValue}\n onAccept={(next) => (state.editingCell ? state.setDraftValue(next) : setFormulaDraft(next))}\n names={nameSuggestions}\n />\n )}\n </div>\n\n {inputMessage && (\n <div role=\"note\" data-validation-input-message=\"\" className=\"border-b border-border bg-muted/30 px-3 py-1 text-[11px] text-muted-foreground\">\n {inputMessage.inputTitle && <span className=\"mr-1 font-semibold text-foreground\">{inputMessage.inputTitle}</span>}\n {inputMessage.inputMessage}\n </div>\n )}\n\n {/* Main Grid */}\n <div ref={scrollRef} className=\"relative flex-1 overflow-auto\" onScroll={handleGridScroll}>\n <table className=\"border-separate border-spacing-0 table-fixed w-max min-w-full [&>*>tr:not([data-spacer])>*]:border-b [&>*>tr>*]:border-border\">\n <thead>\n <tr className=\"h-7 bg-muted sticky top-0 z-20 border-b border-border shadow-xs\">\n <th className=\"w-12 min-w-[3rem] sticky left-0 z-30 bg-muted border-r border-border text-center text-[10px] text-muted-foreground font-medium\">\n #\n </th>\n {columnSlots.map((slot) => slot.kind === 'space' ? (\n <th\n key={slot.key}\n aria-hidden=\"true\"\n data-spacer=\"\"\n className=\"p-0\"\n style={{ width: slot.width, minWidth: slot.width, maxWidth: slot.width, padding: 0 }}\n />\n ) : ((({ column: col, index: cIdx, frozen, stickyLeft }) => (\n <th\n key={col.id}\n data-col={cIdx}\n className={`relative border-r border-border px-2 text-left font-medium text-muted-foreground hover:bg-muted/90 transition-colors group overflow-hidden max-w-0 ${\n onColumnHeaderClick ? 'cursor-pointer' : 'cursor-default'\n }`}\n style={{\n width: col.width || 130,\n minWidth: col.width || 130,\n maxWidth: col.width || 130,\n overflow: 'hidden',\n ...(frozen ? { position: 'sticky', left: ROW_HEADER_WIDTH + stickyLeft, zIndex: 25, background: 'var(--muted, #f4f4f5)' } : {})\n }}\n onClick={() => onColumnHeaderClick?.(col)}\n onDoubleClick={(e) => handleHeaderDblClick(col.id, cIdx, e)}\n >\n <div className=\"flex items-center justify-between gap-1 min-w-0 overflow-hidden truncate\">\n <span className=\"truncate font-semibold text-foreground text-xs min-w-0\">{col.title}</span>\n {filteredColIds.has(col.id) && (\n <span className=\"text-[10px] text-primary shrink-0\" title=\"Filtered\" data-filtered=\"true\">⏷</span>\n )}\n <span className=\"text-[10px] text-muted-foreground/70 font-mono font-normal shrink-0\">({col.key})</span>\n </div>\n {/* Column Resize Handle */}\n <div\n className=\"col-resize-handle\"\n style={{ position: 'absolute', top: 0, bottom: 0, width: 12, right: -6, cursor: 'col-resize', zIndex: 20, display: 'flex', justifyContent: 'center', touchAction: 'none' }}\n onMouseEnter={() => setHoveredColId(col.id)}\n onMouseLeave={() => setHoveredColId((cur) => cur === col.id ? null : cur)}\n onMouseDown={(e) => {\n e.preventDefault();\n e.stopPropagation();\n setResizingColId(col.id);\n setResizeStartX(e.clientX);\n setResizeStartWidth(col.width || 130);\n }}\n onDoubleClick={(e) => handleResizeDblClick(col.id, cIdx, e)}\n role=\"separator\"\n aria-orientation=\"vertical\"\n >\n <div\n className=\"col-resize-handle-line\"\n style={{\n width: 2,\n height: '100%',\n pointerEvents: 'none',\n transition: 'background-color 150ms ease',\n backgroundColor: resizingColId === col.id ? 'var(--primary, #6366f1)' : hoveredColId === col.id ? 'color-mix(in srgb, var(--primary, #6366f1) 75%, transparent)' : 'transparent'\n }}\n />\n </div>\n </th>\n ))(slot.viewCol)))}\n {onAddColumnClick && (\n <th\n className=\"w-10 min-w-[2.5rem] px-1 text-center bg-muted/40 hover:bg-muted cursor-pointer transition-colors\"\n onClick={onAddColumnClick}\n title=\"Add Column\"\n >\n <span className=\"text-xs font-bold text-muted-foreground\">+</span>\n </th>\n )}\n </tr>\n </thead>\n <tbody>\n {rowSlots.map((rowSlot) => {\n if (rowSlot.kind === 'space') {\n return (\n <tr key={rowSlot.key} aria-hidden=\"true\" data-spacer=\"\" style={{ height: rowSlot.height }}>\n <td colSpan={columnSlots.length + 2} style={{ padding: 0, border: 0 }} />\n </tr>\n );\n }\n const viewRow = rowSlot.viewRow;\n if (viewRow.kind === 'group') {\n return (\n <SpreadsheetGroupRow\n key={`group:${viewRow.group.key}`}\n group={viewRow.group}\n columns={renderedColumns}\n labelColumns={view.columns}\n leadingColumns={viewWindow.virtual ? viewWindow.frozenColumns : undefined}\n leftSpace={viewWindow.leftSpace}\n rightSpace={viewWindow.rightSpace}\n groupColId={state.document.table?.grouping?.colId ?? ''}\n onToggle={state.toggleGroupCollapsed}\n trailingCell={!!onAddColumnClick}\n />\n );\n }\n const displayRowIndex = viewRow.index;\n const selection = state.selectedRange ? normalizeRange(state.selectedRange) : null;\n return (\n <tr\n key={viewRow.row.id}\n data-row={displayRowIndex}\n className={`border-b border-border hover:bg-muted/10 transition-colors ${viewRow.section !== 'body' ? 'bg-muted/30 font-semibold' : ''}`}\n style={{ height: viewRow.row.height || 32 }}\n >\n <td\n className=\"w-12 min-w-[3rem] sticky left-0 z-10 bg-muted border-r border-border text-center text-[10px] text-muted-foreground font-mono select-none\"\n style={viewRow.frozen ? { top: COLUMN_HEADER_HEIGHT + viewRow.stickyTop, zIndex: 15 } : undefined}\n >\n {displayRowIndex + 1}\n </td>\n {columnSlots.map((slot) => {\n if (slot.kind === 'space') return <td key={slot.key} aria-hidden=\"true\" data-spacer=\"\" style={{ padding: 0 }} />;\n const viewCol = slot.viewCol;\n // A merged cell renders its top-left cell, spanning the merge.\n const span = view.getCellSpan(displayRowIndex, viewCol.index);\n if (!span) return null;\n const rIdx = span.source.row;\n const cIdx = span.source.col;\n const row = state.document.rows[rIdx];\n const col = state.document.columns[cIdx];\n const cell = state.getCell(row.id, col.id);\n const selected = isCellSelected(rIdx, cIdx);\n const active = isActiveCell(rIdx, cIdx);\n const isEditing = state.editingCell?.row === rIdx && state.editingCell?.col === cIdx;\n\n const conditional = overlay.get(rIdx, cIdx);\n const conditionalCss = getConditionalFormatCss(conditional);\n const circled = state.controller.isInvalidDataCircled(rIdx, cIdx);\n const showListArrow = active && !isEditing && !!activeListValues;\n const inFillPreview = !!fillTarget && !selected && rangeContains(fillTarget, displayRowIndex, viewCol.index);\n const showFillHandle =\n !readOnly &&\n !isEditing &&\n !!selection &&\n (span.merge\n ? rangeContains(span.merge, selection.endRow, selection.endCol)\n : selection.endRow === rIdx && selection.endCol === cIdx);\n\n return (\n <td\n key={viewCol.column.id}\n data-row={rIdx}\n data-col={cIdx}\n rowSpan={span.rowSpan}\n colSpan={span.colSpan}\n className={`relative border-r border-border px-2 py-1 truncate max-w-0 text-foreground transition-colors ${\n selected ? 'bg-primary/10' : ''\n } ${active ? 'ring-2 ring-primary ring-inset z-10' : ''} ${viewCol.header ? 'font-semibold' : ''}`}\n style={{\n maxWidth: 0,\n overflow: 'hidden',\n ...frozenCellStyle(viewRow, viewCol),\n ...conditionalCss,\n // Keep the selection tint visible over a conditional fill.\n ...(conditionalCss.background && selected\n ? { boxShadow: 'inset 0 0 0 9999px color-mix(in srgb, var(--primary, #6366f1) 12%, transparent)' }\n : {}),\n ...(inFillPreview ? { outline: '1px dashed var(--primary, #6366f1)', outlineOffset: -1 } : {})\n }}\n data-cf-fill={conditional?.fill}\n onClick={(e) => handleCellClick(rIdx, cIdx, e)}\n onDoubleClick={() => handleCellDblClick(rIdx, cIdx)}\n onContextMenu={(e) => handleCellContextMenu(rIdx, cIdx, e)}\n onMouseOver={() => extendFill(displayRowIndex, viewCol.index)}\n >\n {isEditing ? (\n <>\n <input\n ref={cellInputRef}\n type=\"text\"\n className=\"absolute inset-0 w-full h-full px-2 py-1 bg-background text-foreground outline-none font-sans text-xs border-2 border-primary z-20\"\n value={state.draftValue}\n onChange={(e) => state.setDraftValue(e.target.value)}\n onBlur={() => state.commitEditing()}\n onFocus={(e) => {\n // Caret after the draft (e.g. the key that started editing).\n const end = e.currentTarget.value.length;\n e.currentTarget.setSelectionRange(end, end);\n }}\n autoFocus\n />\n <FormulaHints inputRef={cellInputRef} value={state.draftValue} onAccept={state.setDraftValue} names={nameSuggestions} />\n </>\n ) : customCellRenderer ? (\n customCellRenderer({ row, col, cell })\n ) : (\n <CellText cell={cell} conditional={conditional} />\n )}\n {circled && (\n <span\n className=\"spreadsheet-invalid-circle\"\n aria-label=\"Invalid value\"\n style={{ position: 'absolute', inset: '1px 2px', border: '2px solid #e11d48', borderRadius: '50%', pointerEvents: 'none', zIndex: 6 }}\n />\n )}\n {showListArrow && (\n <button\n type=\"button\"\n className=\"spreadsheet-list-arrow\"\n aria-label=\"Show allowed values\"\n aria-haspopup=\"listbox\"\n tabIndex={-1}\n style={{ position: 'absolute', right: 1, top: 1, bottom: 1, width: 16, zIndex: 24, fontSize: 10, lineHeight: 1, background: 'var(--muted, #f4f4f5)', border: '1px solid var(--border, #e4e4e7)', borderRadius: 2, cursor: 'pointer', padding: 0 }}\n onMouseDown={(e) => e.stopPropagation()}\n onClick={(e) => {\n e.stopPropagation();\n if (listMenu) setListMenu(null);\n else openListMenu(rIdx, cIdx, e.currentTarget.parentElement);\n }}\n >\n ▾\n </button>\n )}\n {activeSpill && rangeContains(activeSpill.range, rIdx, cIdx) && (\n <span aria-hidden=\"true\" className=\"spreadsheet-spill-border\" style={spillBorderStyle(activeSpill.range, rIdx, cIdx)} />\n )}\n {showFillHandle && (\n <div\n className=\"spreadsheet-fill-handle\"\n aria-label=\"Fill handle\"\n onMouseDown={startFill}\n onClick={(e) => e.stopPropagation()}\n style={{ position: 'absolute', right: 0, bottom: 0, width: 7, height: 7, background: 'var(--primary, #6366f1)', cursor: 'crosshair', zIndex: 25 }}\n />\n )}\n </td>\n );\n })}\n {onAddColumnClick && <td className=\"w-10 min-w-[2.5rem] bg-muted/10 border-r border-border\" />}\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n {menu && (\n <SpreadsheetContextMenu\n items={menu.items}\n x={menu.x}\n y={menu.y}\n onClose={() => {\n setMenu(null);\n gridRef.current?.focus();\n }}\n onOpenPanel={setPanel}\n />\n )}\n {panel === 'conditionalFormatting' && <SpreadsheetConditionalFormatPanel state={state} onClose={() => setPanel(null)} />}\n {panel === 'dataValidation' && <SpreadsheetDataValidationPanel state={state} onClose={() => setPanel(null)} />}\n {listMenu && (\n <div\n role=\"listbox\"\n aria-label=\"Allowed values\"\n className=\"fixed z-50 max-h-60 min-w-[8rem] overflow-y-auto rounded-md border border-border bg-popover py-1 text-xs text-popover-foreground shadow-lg\"\n style={{ left: listMenu.x, top: listMenu.y, background: 'var(--popover, var(--background, #fff))' }}\n onKeyDown={(e) => {\n e.stopPropagation();\n if (e.key === 'Escape') {\n setListMenu(null);\n gridRef.current?.focus();\n }\n }}\n >\n {listMenu.values.length === 0 && <div className=\"px-3 py-1 text-muted-foreground\">No values</div>}\n {listMenu.values.map((value, i) => (\n <button\n key={`${i}:${value}`}\n type=\"button\"\n role=\"option\"\n aria-selected={false}\n className=\"block w-full px-3 py-1 text-left hover:bg-muted\"\n onClick={() => chooseListValue(value)}\n >\n {value}\n </button>\n ))}\n </div>\n )}\n {state.validationPrompt && <SpreadsheetValidationDialog prompt={state.validationPrompt} onResolve={resolveValidation} />}\n <style>{`\n .col-resize-handle:hover .col-resize-handle-line {\n background-color: var(--primary, #6366f1);\n opacity: 0.75;\n }\n .col-resize-handle.active .col-resize-handle-line {\n background-color: var(--primary, #6366f1);\n opacity: 1;\n }\n table.table-fixed th {\n overflow: hidden;\n }\n table.table-fixed td {\n max-width: 0;\n overflow: hidden;\n }\n `}</style>\n </div>\n );\n\n if (!showSheetTabs) return grid;\n return (\n <div className=\"flex h-full w-full flex-col\">\n <div className=\"min-h-0 flex-1\">{grid}</div>\n <SheetTabs state={state} readOnly={readOnly} />\n </div>\n );\n};\n","import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { clampMenuPosition, runSpreadsheetMenuItem, type SpreadsheetMenuItem, type SpreadsheetPanelId } from '@pixerate/editor/spreadsheet';\n\n// Gap kept between the menu and the viewport edges.\nconst VIEWPORT_MARGIN = 4;\n\nexport interface SpreadsheetContextMenuProps {\n items: SpreadsheetMenuItem[];\n x: number;\n y: number;\n onClose: () => void;\n /** Accessible name of the menu (default \"Table actions\"). */\n ariaLabel?: string;\n /** Opens a panel for items with `panel` (conditional formatting, data validation). */\n onOpenPanel?: (panel: SpreadsheetPanelId) => void;\n}\n\n/** The table context menu (sort, filter, freeze, hide, merge, categories, transpose). */\nexport const SpreadsheetContextMenu: React.FC<SpreadsheetContextMenuProps> = ({ items, x, y, onClose, onOpenPanel, ariaLabel = 'Table actions' }) => {\n const menuRef = useRef<HTMLDivElement>(null);\n const onCloseRef = useRef(onClose);\n onCloseRef.current = onClose;\n const [position, setPosition] = useState({ x, y });\n\n // Keep the (fixed) menu inside the viewport: near the right or bottom edge\n // it opens to the left of / above the pointer instead of being cut off.\n useLayoutEffect(() => {\n const menu = menuRef.current;\n if (!menu || typeof window === 'undefined') return;\n const { width, height } = menu.getBoundingClientRect();\n const next = clampMenuPosition(\n { x, y },\n { width, height },\n { width: window.innerWidth, height: window.innerHeight },\n VIEWPORT_MARGIN\n );\n setPosition((prev) => (prev.x === next.x && prev.y === next.y ? prev : next));\n }, [x, y, items]);\n\n useEffect(() => {\n const handlePointer = (e: MouseEvent) => {\n if (!menuRef.current?.contains(e.target as Node)) onCloseRef.current();\n };\n const handleKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onCloseRef.current();\n };\n window.addEventListener('mousedown', handlePointer);\n window.addEventListener('keydown', handleKey);\n return () => {\n window.removeEventListener('mousedown', handlePointer);\n window.removeEventListener('keydown', handleKey);\n };\n }, []);\n\n return (\n <div\n ref={menuRef}\n role=\"menu\"\n aria-label={ariaLabel}\n className=\"fixed z-50 min-w-[14rem] rounded-md border border-border bg-popover py-1 text-xs text-popover-foreground shadow-lg\"\n style={{\n left: position.x,\n top: position.y,\n maxHeight: `calc(100vh - ${VIEWPORT_MARGIN * 2}px)`,\n overflowY: 'auto',\n background: 'var(--popover, var(--background, #fff))'\n }}\n onContextMenu={(e) => e.preventDefault()}\n onKeyDown={(e) => e.stopPropagation()}\n >\n {items.map((item) => (\n <React.Fragment key={item.id}>\n {item.separatorBefore && <div role=\"separator\" className=\"my-1 h-px bg-border\" />}\n <button\n type=\"button\"\n role=\"menuitem\"\n data-action={item.id}\n data-checked={item.checked ? '' : undefined}\n disabled={item.disabled}\n className={`block w-full px-3 py-1 text-left hover:bg-muted disabled:cursor-default disabled:opacity-40 disabled:hover:bg-transparent ${\n item.checked ? 'font-semibold' : ''\n }`}\n onClick={() => {\n onClose();\n if (item.panel) onOpenPanel?.(item.panel);\n else runSpreadsheetMenuItem(item);\n }}\n >\n {item.label}\n </button>\n </React.Fragment>\n ))}\n </div>\n );\n};\n","import React from 'react';\nimport type { SpreadsheetRowGroup, SpreadsheetViewColumn } from '@pixerate/editor/spreadsheet';\n\nexport interface SpreadsheetGroupRowProps {\n group: SpreadsheetRowGroup;\n columns: SpreadsheetViewColumn[];\n /** Column the rows are grouped by: shows the group label and toggle. */\n groupColId: string;\n onToggle: (key: string) => void;\n /** Render a trailing cell for the \"add column\" column. */\n trailingCell?: boolean;\n /** Every displayed column, when `columns` is a virtualised window of them (picks the label column). */\n labelColumns?: SpreadsheetViewColumn[];\n /** Virtualised: columns before the left spacer (the frozen ones), and the spacers' widths. */\n leadingColumns?: number;\n leftSpace?: number;\n rightSpace?: number;\n}\n\nconst formatSummary = (value: number | null) => (value === null ? '–' : String(value));\n\n/** A category header row: collapse toggle, label, row count and per-column summaries. */\nexport const SpreadsheetGroupRow: React.FC<SpreadsheetGroupRowProps> = ({\n group,\n columns,\n groupColId,\n onToggle,\n trailingCell,\n labelColumns = columns,\n leadingColumns,\n leftSpace = 0,\n rightSpace = 0\n}) => {\n // The label goes in the grouping column, or the first column when that one is hidden.\n const labelColId = labelColumns.some((c) => c.column.id === groupColId) ? groupColId : labelColumns[0]?.column.id;\n const spacer = (key: string) => <td key={key} aria-hidden=\"true\" data-spacer=\"\" style={{ padding: 0 }} />;\n return (\n <tr className=\"border-b border-border bg-muted/40 font-semibold\" data-group-key={group.key} style={{ height: 28 }}>\n <td className=\"w-12 min-w-[3rem] sticky left-0 z-10 bg-muted border-r border-border text-center\">\n <button\n type=\"button\"\n aria-label={`${group.collapsed ? 'Expand' : 'Collapse'} group ${group.label}`}\n aria-expanded={!group.collapsed}\n className=\"h-5 w-5 rounded text-[10px] text-muted-foreground hover:bg-muted\"\n onClick={(e) => {\n e.stopPropagation();\n onToggle(group.key);\n }}\n >\n {group.collapsed ? '▸' : '▾'}\n </button>\n </td>\n {columns.map(({ column }, i) => {\n const summary = group.summaries[column.id];\n const before = leadingColumns !== undefined && i === leadingColumns && leftSpace > 0 ? spacer('space:left') : null;\n return (\n <React.Fragment key={column.id}>\n {before}\n <td className=\"border-r border-border px-2 py-1 truncate max-w-0 text-foreground\" style={{ maxWidth: 0, overflow: 'hidden' }}>\n {column.id === labelColId ? (\n <span className=\"truncate\">\n {group.label} <span className=\"font-normal text-muted-foreground\">({group.rowIndices.length})</span>\n </span>\n ) : summary !== undefined ? (\n <span className=\"truncate\" data-summary={column.id}>{formatSummary(summary)}</span>\n ) : null}\n </td>\n </React.Fragment>\n );\n })}\n {leadingColumns !== undefined && leadingColumns >= columns.length && leftSpace > 0 && spacer('space:left')}\n {rightSpace > 0 && spacer('space:right')}\n {trailingCell && <td className=\"w-10 min-w-[2.5rem] bg-muted/10 border-r border-border\" />}\n </tr>\n );\n};\n","import { useCallback, useEffect, useRef, useState, type RefObject } from 'react';\nimport {\n computeFillTarget,\n normalizeRange,\n type CellRange\n} from '@pixerate/editor/spreadsheet';\nimport type { useSpreadsheetEditor } from './useSpreadsheetEditor';\n\ntype SpreadsheetState = ReturnType<typeof useSpreadsheetEditor>;\n\n/** True when focus is in the grid itself, not in a text input (cell editor, formula bar). */\nfunction gridHasFocus(grid: HTMLElement | null): boolean {\n if (!grid || typeof document === 'undefined') return false;\n const active = document.activeElement;\n if (!active || !grid.contains(active)) return false;\n return !(active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement);\n}\n\n/**\n * Copy and paste for the grid. Copy writes TSV, an HTML table and the\n * lossless `application/x.pixerate.spreadsheet+json` format; paste prefers\n * that format, then HTML, then TSV.\n *\n * The listeners are on `document`: with no text selection the browser fires\n * `copy`/`paste` at `<body>`, not at the focused grid. Text inputs inside the\n * grid keep native copy/paste.\n */\nexport function useSpreadsheetClipboard(\n gridRef: RefObject<HTMLElement | null>,\n state: SpreadsheetState,\n readOnly: boolean\n) {\n const stateRef = useRef(state);\n stateRef.current = state;\n const readOnlyRef = useRef(readOnly);\n readOnlyRef.current = readOnly;\n // Set when a copy event wrote the selection, so the keyboard fallback is skipped.\n const copiedRef = useRef(false);\n\n useEffect(() => {\n if (typeof document === 'undefined') return;\n const handleCopy = (e: ClipboardEvent) => {\n const s = stateRef.current;\n if (!gridHasFocus(gridRef.current) || s.editingCell || !e.clipboardData || !s.selectedRange) return;\n for (const [type, data] of Object.entries(s.copyToClipboardData(s.selectedRange))) {\n e.clipboardData.setData(type, data);\n }\n copiedRef.current = true;\n e.preventDefault();\n };\n const handlePaste = (e: ClipboardEvent) => {\n const s = stateRef.current;\n if (readOnlyRef.current || !gridHasFocus(gridRef.current) || s.editingCell || !e.clipboardData) return;\n if (s.pasteClipboardData(e.clipboardData)) e.preventDefault();\n };\n document.addEventListener('copy', handleCopy);\n document.addEventListener('paste', handlePaste);\n return () => {\n document.removeEventListener('copy', handleCopy);\n document.removeEventListener('paste', handlePaste);\n };\n }, [gridRef]);\n\n /**\n * Call on Mod+C (without preventing default). The browser normally follows\n * with a `copy` event; where it doesn't (no selection in some browsers),\n * the selection is written as plain TSV instead.\n */\n const copyShortcutFallback = useCallback(() => {\n copiedRef.current = false;\n setTimeout(() => {\n if (copiedRef.current) return;\n const s = stateRef.current;\n // Rejected when clipboard access is denied; nothing else to fall back to.\n Promise.resolve(navigator.clipboard?.writeText(s.exportToTsv(s.selectedRange))).catch(() => {});\n }, 0);\n }, []);\n\n return { copyShortcutFallback };\n}\n\n/**\n * Fill handle dragging: press on the handle, move over cells, release to\n * autofill from the selection into the dragged range (one undo step).\n */\nexport function useFillHandle(state: SpreadsheetState) {\n const [drag, setDrag] = useState<{ source: CellRange; target: CellRange | null } | null>(null);\n const dragRef = useRef(drag);\n dragRef.current = drag;\n const stateRef = useRef(state);\n stateRef.current = state;\n const dragging = drag !== null;\n\n useEffect(() => {\n if (!dragging) return;\n const handleMouseUp = () => {\n const current = dragRef.current;\n setDrag(null);\n if (current?.target) stateRef.current.autofill(current.source, current.target);\n };\n window.addEventListener('mouseup', handleMouseUp);\n return () => window.removeEventListener('mouseup', handleMouseUp);\n }, [dragging]);\n\n const startFill = useCallback((e: { preventDefault(): void; stopPropagation(): void }) => {\n e.preventDefault();\n e.stopPropagation();\n const range = stateRef.current.selectedRange;\n if (range) setDrag({ source: normalizeRange(range), target: null });\n }, []);\n\n const extendFill = useCallback((row: number, col: number) => {\n const current = dragRef.current;\n if (!current) return;\n setDrag({ source: current.source, target: computeFillTarget(current.source, { row, col }) });\n }, []);\n\n return { fillTarget: drag?.target ?? null, isFilling: dragging, startFill, extendFill };\n}\n","import React, { useEffect, useRef } from 'react';\nimport type { SpreadsheetValidationAction, SpreadsheetValidationPrompt } from '@pixerate/editor/spreadsheet';\n\nexport interface SpreadsheetValidationDialogProps {\n prompt: SpreadsheetValidationPrompt;\n onResolve: (action: SpreadsheetValidationAction) => void;\n}\n\n/**\n * The data validation alert: Stop (Retry / Cancel), Warning (\"Continue?\"\n * Yes / No / Cancel) or Information (OK / Cancel), as in Excel.\n */\nexport const SpreadsheetValidationDialog: React.FC<SpreadsheetValidationDialogProps> = ({ prompt, onResolve }) => {\n const style = prompt.result.errorStyle ?? 'stop';\n const firstButton = useRef<HTMLButtonElement>(null);\n useEffect(() => {\n firstButton.current?.focus();\n }, [prompt]);\n\n const buttons: Array<{ label: string; action: SpreadsheetValidationAction }> =\n style === 'stop'\n ? [\n { label: 'Retry', action: 'retry' },\n { label: 'Cancel', action: 'cancel' }\n ]\n : style === 'warning'\n ? [\n { label: 'Yes', action: 'accept' },\n { label: 'No', action: 'retry' },\n { label: 'Cancel', action: 'cancel' }\n ]\n : [\n { label: 'OK', action: 'accept' },\n { label: 'Cancel', action: 'cancel' }\n ];\n const icon = style === 'stop' ? '⛔' : style === 'warning' ? '⚠' : 'ℹ';\n\n return (\n <div\n className=\"fixed inset-0 z-[60] flex items-center justify-center bg-black/30\"\n onMouseDown={(e) => e.preventDefault()}\n onKeyDown={(e) => {\n e.stopPropagation();\n if (e.key === 'Escape') {\n e.preventDefault();\n onResolve('cancel');\n }\n }}\n >\n <div\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-labelledby=\"spreadsheet-validation-title\"\n aria-describedby=\"spreadsheet-validation-message\"\n data-error-style={style}\n className=\"w-[22rem] max-w-[calc(100vw-2rem)] rounded-md border border-border bg-popover p-4 text-xs text-popover-foreground shadow-xl\"\n style={{ background: 'var(--popover, var(--background, #fff))' }}\n >\n <div className=\"flex items-start gap-3\">\n <span aria-hidden=\"true\" className=\"text-lg leading-none\">{icon}</span>\n <div className=\"min-w-0 flex-1\">\n <h2 id=\"spreadsheet-validation-title\" className=\"mb-1 text-sm font-semibold\">\n {prompt.result.title}\n </h2>\n <p id=\"spreadsheet-validation-message\" className=\"whitespace-pre-wrap\">\n {prompt.result.message}\n </p>\n {style === 'warning' && <p className=\"mt-2\">Continue?</p>}\n </div>\n </div>\n <div className=\"mt-4 flex justify-end gap-2\">\n {buttons.map((button, i) => (\n <button\n key={button.action}\n ref={i === 0 ? firstButton : undefined}\n type=\"button\"\n data-action={button.action}\n className={`rounded border border-border px-3 py-1 ${i === 0 ? 'bg-primary text-primary-foreground' : 'hover:bg-muted'}`}\n onClick={() => onResolve(button.action)}\n >\n {button.label}\n </button>\n ))}\n </div>\n </div>\n </div>\n );\n};\n","import React, { useMemo, useState } from 'react';\nimport {\n CONDITIONAL_FORMAT_ICON_SETS,\n CONDITIONAL_FORMAT_PRESETS,\n CONDITIONAL_FORMAT_STYLE_PRESETS,\n CONDITIONAL_FORMAT_TIME_PERIODS,\n DATA_VALIDATION_ERROR_STYLE_OPTIONS,\n DATA_VALIDATION_OPERATOR_OPTIONS,\n DATA_VALIDATION_TYPE_OPTIONS,\n createConditionalFormatRule,\n describeConditionalFormat,\n describeDataValidation,\n formatRuleRanges,\n getConditionalFormatCss,\n parseRuleRanges,\n type CellRange,\n type ConditionalFormatIconSet,\n type ConditionalFormatPresetKind,\n type ConditionalFormatRule,\n type ConditionalFormatTimePeriod,\n type DataValidationErrorStyle,\n type DataValidationOperator,\n type DataValidationType\n} from '@pixerate/editor/spreadsheet';\nimport type { useSpreadsheetEditor } from './useSpreadsheetEditor';\n\ntype SpreadsheetState = ReturnType<typeof useSpreadsheetEditor>;\n\nexport interface SpreadsheetRulePanelProps {\n state: SpreadsheetState;\n onClose: () => void;\n}\n\nconst inputClass = 'w-full rounded border border-border bg-background px-1.5 py-0.5 text-xs text-foreground';\nconst buttonClass = 'rounded border border-border px-2 py-0.5 hover:bg-muted disabled:opacity-40';\n\nfunction selectionText(range: CellRange | null): string {\n return range ? formatRuleRanges([range]) : 'A1';\n}\n\n/** Frame shared by both managers: a compact side panel that keeps keys away from the grid. */\nconst PanelFrame: React.FC<{ title: string; label: string; onClose: () => void; children: React.ReactNode }> = ({\n title,\n label,\n onClose,\n children\n}) => (\n <div\n role=\"dialog\"\n aria-label={label}\n className=\"fixed right-4 top-16 z-40 flex max-h-[calc(100vh-5rem)] w-80 flex-col overflow-y-auto rounded-md border border-border bg-popover p-3 text-xs text-popover-foreground shadow-lg\"\n style={{ background: 'var(--popover, var(--background, #fff))' }}\n onKeyDown={(e) => {\n e.stopPropagation();\n if (e.key === 'Escape') onClose();\n }}\n onContextMenu={(e) => e.stopPropagation()}\n >\n <div className=\"mb-2 flex items-center justify-between\">\n <h2 className=\"text-sm font-semibold\">{title}</h2>\n <button type=\"button\" aria-label=\"Close\" className=\"px-1 text-muted-foreground hover:text-foreground\" onClick={onClose}>\n ✕\n </button>\n </div>\n {children}\n </div>\n);\n\n/** Swatch showing a rule's look (fill, font colour, bold) or its kind. */\nfunction RuleSwatch({ rule }: { rule: ConditionalFormatRule }) {\n if (rule.type === 'colorScale') {\n return (\n <span\n aria-hidden=\"true\"\n className=\"inline-block h-3 w-6 shrink-0 rounded-sm border border-border\"\n style={{ background: `linear-gradient(90deg, ${rule.stops.map((s) => s.color).join(', ')})` }}\n />\n );\n }\n if (rule.type === 'dataBar') {\n return <span aria-hidden=\"true\" className=\"inline-block h-3 w-6 shrink-0 rounded-sm\" style={{ background: rule.color ?? '#638ec6' }} />;\n }\n if (rule.type === 'iconSet') return <span aria-hidden=\"true\" className=\"shrink-0\">●</span>;\n const css = getConditionalFormatCss(rule.style);\n return (\n <span aria-hidden=\"true\" className=\"inline-flex h-4 w-6 shrink-0 items-center justify-center rounded-sm border border-border\" style={css}>\n Aa\n </span>\n );\n}\n\n/**\n * Conditional formatting manager: the sheet's rules in priority order (move,\n * stop if true, delete) and a form to add a rule to a range.\n */\nexport const SpreadsheetConditionalFormatPanel: React.FC<SpreadsheetRulePanelProps> = ({ state, onClose }) => {\n const rules = state.document.table?.conditionalFormats ?? [];\n const [kind, setKind] = useState<ConditionalFormatPresetKind>('greaterThan');\n const [appliesTo, setAppliesTo] = useState(() => selectionText(state.selectedRange));\n const [value, setValue] = useState('');\n const [value2, setValue2] = useState('');\n const [text, setText] = useState('');\n const [formula, setFormula] = useState('=');\n const [rank, setRank] = useState('10');\n const [period, setPeriod] = useState<ConditionalFormatTimePeriod>('today');\n const [iconSet, setIconSet] = useState<ConditionalFormatIconSet>('3TrafficLights1');\n const [color, setColor] = useState('#638ec6');\n const [styleId, setStyleId] = useState(CONDITIONAL_FORMAT_STYLE_PRESETS[0].id);\n const preset = useMemo(() => CONDITIONAL_FORMAT_PRESETS.find((p) => p.kind === kind)!, [kind]);\n const ranges = parseRuleRanges(appliesTo);\n\n const add = () => {\n if (!ranges) return;\n state.addConditionalFormat(\n createConditionalFormatRule({\n kind,\n ranges,\n value,\n value2,\n text,\n formula,\n rank: Number(rank) || 10,\n period,\n iconSet,\n color,\n style: CONDITIONAL_FORMAT_STYLE_PRESETS.find((s) => s.id === styleId)?.style\n })\n );\n };\n\n return (\n <PanelFrame title=\"Conditional formatting\" label=\"Conditional formatting rules\" onClose={onClose}>\n <ol className=\"mb-3 flex flex-col gap-1\" aria-label=\"Rules in priority order\">\n {rules.length === 0 && <li className=\"text-muted-foreground\">No rules on this sheet.</li>}\n {rules.map((rule, i) => (\n <li key={rule.id} data-rule-id={rule.id} className=\"flex items-center gap-1.5 rounded border border-border px-1.5 py-1\">\n <RuleSwatch rule={rule} />\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate\" title={describeConditionalFormat(rule)}>\n {describeConditionalFormat(rule)}\n </div>\n <div className=\"truncate font-mono text-[10px] text-muted-foreground\">{formatRuleRanges(rule.ranges)}</div>\n </div>\n <label className=\"flex items-center gap-0.5 text-[10px]\" title=\"Stop if true\">\n <input\n type=\"checkbox\"\n aria-label=\"Stop if true\"\n checked={!!rule.stopIfTrue}\n onChange={(e) => state.updateConditionalFormat(rule.id, { stopIfTrue: e.target.checked })}\n />\n Stop\n </label>\n <button type=\"button\" aria-label=\"Move up\" className={buttonClass} disabled={i === 0} onClick={() => state.moveConditionalFormat(rule.id, { by: -1 })}>\n ▲\n </button>\n <button\n type=\"button\"\n aria-label=\"Move down\"\n className={buttonClass}\n disabled={i === rules.length - 1}\n onClick={() => state.moveConditionalFormat(rule.id, { by: 1 })}\n >\n ▼\n </button>\n <button type=\"button\" aria-label=\"Delete rule\" className={buttonClass} onClick={() => state.deleteConditionalFormat(rule.id)}>\n ✕\n </button>\n </li>\n ))}\n </ol>\n\n <fieldset className=\"flex flex-col gap-1.5 border-t border-border pt-2\">\n <legend className=\"sr-only\">New rule</legend>\n <label className=\"flex flex-col gap-0.5\">\n Format cells\n <select aria-label=\"Rule type\" className={inputClass} value={kind} onChange={(e) => setKind(e.target.value as ConditionalFormatPresetKind)}>\n {CONDITIONAL_FORMAT_PRESETS.map((p) => (\n <option key={p.kind} value={p.kind}>\n {p.label}\n </option>\n ))}\n </select>\n </label>\n {preset.fields.includes('value') && (\n <input aria-label=\"Value\" placeholder=\"Value or =formula\" className={inputClass} value={value} onChange={(e) => setValue(e.target.value)} />\n )}\n {preset.fields.includes('value2') && (\n <input aria-label=\"Second value\" placeholder=\"and\" className={inputClass} value={value2} onChange={(e) => setValue2(e.target.value)} />\n )}\n {preset.fields.includes('text') && (\n <input aria-label=\"Text\" placeholder=\"Text\" className={inputClass} value={text} onChange={(e) => setText(e.target.value)} />\n )}\n {preset.fields.includes('formula') && (\n <input aria-label=\"Formula\" placeholder=\"=$A1>10\" className={inputClass} value={formula} onChange={(e) => setFormula(e.target.value)} />\n )}\n {preset.fields.includes('rank') && (\n <input aria-label=\"Rank\" type=\"number\" min={1} className={inputClass} value={rank} onChange={(e) => setRank(e.target.value)} />\n )}\n {preset.fields.includes('period') && (\n <select aria-label=\"Period\" className={inputClass} value={period} onChange={(e) => setPeriod(e.target.value as ConditionalFormatTimePeriod)}>\n {CONDITIONAL_FORMAT_TIME_PERIODS.map((p) => (\n <option key={p.period} value={p.period}>\n {p.label}\n </option>\n ))}\n </select>\n )}\n {preset.fields.includes('iconSet') && (\n <select aria-label=\"Icon set\" className={inputClass} value={iconSet} onChange={(e) => setIconSet(e.target.value as ConditionalFormatIconSet)}>\n {CONDITIONAL_FORMAT_ICON_SETS.map((set) => (\n <option key={set} value={set}>\n {set}\n </option>\n ))}\n </select>\n )}\n {preset.fields.includes('color') && (\n <input aria-label=\"Bar colour\" type=\"color\" className=\"h-6 w-12\" value={color} onChange={(e) => setColor(e.target.value)} />\n )}\n {preset.usesStyle && (\n <select aria-label=\"Style\" className={inputClass} value={styleId} onChange={(e) => setStyleId(e.target.value)}>\n {CONDITIONAL_FORMAT_STYLE_PRESETS.map((s) => (\n <option key={s.id} value={s.id}>\n {s.label}\n </option>\n ))}\n </select>\n )}\n <label className=\"flex flex-col gap-0.5\">\n Applies to\n <input aria-label=\"Applies to\" className={`${inputClass} font-mono`} value={appliesTo} onChange={(e) => setAppliesTo(e.target.value)} />\n </label>\n <div className=\"flex justify-between gap-2\">\n <button type=\"button\" className={buttonClass} onClick={() => setAppliesTo(selectionText(state.selectedRange))}>\n Use selection\n </button>\n <button type=\"button\" className={buttonClass} disabled={!ranges} onClick={add}>\n Add rule\n </button>\n </div>\n </fieldset>\n </PanelFrame>\n );\n};\n\n/**\n * Data validation manager: the sheet's rules (delete), a form to validate a\n * range, and \"circle invalid data\".\n */\nexport const SpreadsheetDataValidationPanel: React.FC<SpreadsheetRulePanelProps> = ({ state, onClose }) => {\n const rules = state.document.table?.dataValidations ?? [];\n const [type, setType] = useState<DataValidationType>('list');\n const [operator, setOperator] = useState<DataValidationOperator>('between');\n const [formula1, setFormula1] = useState('');\n const [formula2, setFormula2] = useState('');\n const [errorStyle, setErrorStyle] = useState<DataValidationErrorStyle>('stop');\n const [errorMessage, setErrorMessage] = useState('');\n const [inputMessage, setInputMessage] = useState('');\n const [ignoreBlank, setIgnoreBlank] = useState(true);\n const [appliesTo, setAppliesTo] = useState(() => selectionText(state.selectedRange));\n const ranges = parseRuleRanges(appliesTo);\n const usesOperator = type === 'whole' || type === 'decimal' || type === 'date' || type === 'time' || type === 'textLength';\n const needsTwo = usesOperator && (operator === 'between' || operator === 'notBetween');\n const circles = state.controller.getInvalidDataCircles();\n\n const apply = () => {\n if (!ranges) return;\n state.addDataValidation({\n ranges,\n type,\n ...(usesOperator ? { operator } : {}),\n ...(formula1 ? { formula1 } : {}),\n ...(needsTwo && formula2 ? { formula2 } : {}),\n errorStyle,\n ...(errorMessage ? { errorMessage } : {}),\n ...(inputMessage ? { inputMessage } : {}),\n ignoreBlank\n });\n };\n\n return (\n <PanelFrame title=\"Data validation\" label=\"Data validation rules\" onClose={onClose}>\n <ul className=\"mb-3 flex flex-col gap-1\" aria-label=\"Validation rules\">\n {rules.length === 0 && <li className=\"text-muted-foreground\">No validation on this sheet.</li>}\n {rules.map((rule) => (\n <li key={rule.id} data-rule-id={rule.id} className=\"flex items-center gap-1.5 rounded border border-border px-1.5 py-1\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate\" title={describeDataValidation(rule)}>\n {describeDataValidation(rule)}\n </div>\n <div className=\"truncate font-mono text-[10px] text-muted-foreground\">\n {formatRuleRanges(rule.ranges)} · {rule.errorStyle ?? 'stop'}\n </div>\n </div>\n <button type=\"button\" aria-label=\"Delete rule\" className={buttonClass} onClick={() => state.deleteDataValidation(rule.id)}>\n ✕\n </button>\n </li>\n ))}\n </ul>\n\n <fieldset className=\"flex flex-col gap-1.5 border-t border-border pt-2\">\n <legend className=\"sr-only\">New validation</legend>\n <label className=\"flex flex-col gap-0.5\">\n Allow\n <select aria-label=\"Allow\" className={inputClass} value={type} onChange={(e) => setType(e.target.value as DataValidationType)}>\n {DATA_VALIDATION_TYPE_OPTIONS.map((o) => (\n <option key={o.type} value={o.type}>\n {o.label}\n </option>\n ))}\n </select>\n </label>\n {usesOperator && (\n <select aria-label=\"Operator\" className={inputClass} value={operator} onChange={(e) => setOperator(e.target.value as DataValidationOperator)}>\n {DATA_VALIDATION_OPERATOR_OPTIONS.map((o) => (\n <option key={o.operator} value={o.operator}>\n {o.label}\n </option>\n ))}\n </select>\n )}\n {type !== 'any' && (\n <input\n aria-label={type === 'list' ? 'Source' : type === 'custom' ? 'Formula' : needsTwo ? 'Minimum' : 'Value'}\n placeholder={type === 'list' ? 'Low,Medium,High or =$H$1:$H$5' : type === 'custom' ? '=A1>0' : 'Value or =formula'}\n className={inputClass}\n value={formula1}\n onChange={(e) => setFormula1(e.target.value)}\n />\n )}\n {needsTwo && <input aria-label=\"Maximum\" placeholder=\"Maximum\" className={inputClass} value={formula2} onChange={(e) => setFormula2(e.target.value)} />}\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" checked={ignoreBlank} onChange={(e) => setIgnoreBlank(e.target.checked)} /> Ignore blank\n </label>\n <input aria-label=\"Input message\" placeholder=\"Input message (optional)\" className={inputClass} value={inputMessage} onChange={(e) => setInputMessage(e.target.value)} />\n <div className=\"flex gap-1\">\n <select aria-label=\"Error style\" className={inputClass} value={errorStyle} onChange={(e) => setErrorStyle(e.target.value as DataValidationErrorStyle)}>\n {DATA_VALIDATION_ERROR_STYLE_OPTIONS.map((o) => (\n <option key={o.style} value={o.style}>\n {o.label}\n </option>\n ))}\n </select>\n </div>\n <input aria-label=\"Error message\" placeholder=\"Error message (optional)\" className={inputClass} value={errorMessage} onChange={(e) => setErrorMessage(e.target.value)} />\n <label className=\"flex flex-col gap-0.5\">\n Applies to\n <input aria-label=\"Applies to\" className={`${inputClass} font-mono`} value={appliesTo} onChange={(e) => setAppliesTo(e.target.value)} />\n </label>\n <div className=\"flex flex-wrap justify-between gap-2\">\n <button type=\"button\" className={buttonClass} onClick={() => setAppliesTo(selectionText(state.selectedRange))}>\n Use selection\n </button>\n <button type=\"button\" className={buttonClass} disabled={!ranges} onClick={() => ranges && ranges.forEach((r) => state.clearDataValidation(r))}>\n Clear\n </button>\n <button type=\"button\" className={buttonClass} disabled={!ranges} onClick={apply}>\n Apply\n </button>\n </div>\n <button type=\"button\" className={buttonClass} aria-pressed={circles} onClick={() => state.setInvalidDataCircles(!circles)}>\n {circles ? 'Clear validation circles' : 'Circle invalid data'}\n </button>\n </fieldset>\n </PanelFrame>\n );\n};\n","import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, type RefObject } from 'react';\nimport {\n fullSpreadsheetViewWindow,\n getSpreadsheetScrollToCell,\n getSpreadsheetViewWindow,\n measureSpreadsheetView,\n sameSpreadsheetViewWindow,\n shouldVirtualizeSpreadsheet,\n type CellCoordinate,\n type CellRange,\n type SpreadsheetViewMetrics,\n type SpreadsheetViewModel,\n type SpreadsheetViewport,\n type SpreadsheetViewWindow\n} from '@pixerate/editor/spreadsheet';\n\n// Browsers without layout effects on the server: fall back to useEffect there.\nconst useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;\n\nexport interface SpreadsheetViewportOptions {\n /** `'auto'` (default): virtualise large views only; `true` / `false` force it. */\n virtualize?: boolean | 'auto';\n /** Merged ranges, rendered whole when they cross the window's edge. */\n merges?: readonly CellRange[];\n /** Scrolled into view when it changes (virtualised views only). */\n activeCell?: CellCoordinate | null;\n overscanRows?: number;\n overscanColumns?: number;\n}\n\nexport interface SpreadsheetViewportState {\n metrics: SpreadsheetViewMetrics;\n /** What to render; `virtual: false` renders every row and column. */\n window: SpreadsheetViewWindow;\n /** Attach to the scroll container's `onScroll`. */\n onScroll: () => void;\n}\n\n/**\n * Virtualised rendering for `SpreadsheetEditor`: tracks the scroll\n * container (`scrollRef`), works out the window of rows and columns to\n * render, and scrolls the active cell into view.\n */\nexport function useSpreadsheetViewport(\n scrollRef: RefObject<HTMLElement | null>,\n view: SpreadsheetViewModel,\n options: SpreadsheetViewportOptions = {}\n): SpreadsheetViewportState {\n const metrics = useMemo(() => measureSpreadsheetView(view), [view]);\n const virtual = shouldVirtualizeSpreadsheet(view, options.virtualize ?? 'auto');\n const [viewport, setViewport] = useState<SpreadsheetViewport>({ scrollTop: 0, scrollLeft: 0, width: 0, height: 0 });\n const windowOptions = useMemo(\n () => ({ merges: options.merges, overscanRows: options.overscanRows, overscanColumns: options.overscanColumns }),\n [options.merges, options.overscanRows, options.overscanColumns]\n );\n\n const win = useMemo(\n () => (virtual ? getSpreadsheetViewWindow(metrics, viewport, windowOptions) : fullSpreadsheetViewWindow(metrics)),\n [virtual, metrics, viewport, windowOptions]\n );\n\n // Read by the scroll handler, which must not change identity.\n const latest = useRef({ metrics, viewport, virtual, windowOptions });\n latest.current = { metrics, viewport, virtual, windowOptions };\n\n const readViewport = useCallback((): SpreadsheetViewport | null => {\n const el = scrollRef.current;\n if (!el) return null;\n return { scrollTop: el.scrollTop, scrollLeft: el.scrollLeft, width: el.clientWidth, height: el.clientHeight };\n }, [scrollRef]);\n\n /** Stores a new viewport, re-rendering only when the window it gives changes. */\n const updateViewport = useCallback((next: SpreadsheetViewport) => {\n setViewport((prev) => {\n const { metrics: m, virtual: v, windowOptions: o } = latest.current;\n if (!v) return prev;\n const same =\n prev.width === next.width &&\n prev.height === next.height &&\n sameSpreadsheetViewWindow(getSpreadsheetViewWindow(m, prev, o), getSpreadsheetViewWindow(m, next, o));\n return same ? prev : next;\n });\n }, []);\n\n const onScroll = useCallback(() => {\n const next = readViewport();\n if (next) updateViewport(next);\n }, [readViewport, updateViewport]);\n\n // Measure the container, and again whenever it is resized.\n useIsomorphicLayoutEffect(() => {\n if (!virtual) return;\n onScroll();\n const el = scrollRef.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => onScroll());\n observer.observe(el);\n return () => observer.disconnect();\n }, [virtual, onScroll, scrollRef]);\n\n // Keyboard navigation and selection: bring the active cell into view.\n const activeRow = options.activeCell?.row;\n const activeCol = options.activeCell?.col;\n useIsomorphicLayoutEffect(() => {\n if (!virtual || activeRow === undefined || activeCol === undefined) return;\n const el = scrollRef.current;\n const current = latest.current.viewport;\n const measured = readViewport();\n const base: SpreadsheetViewport = measured\n ? { ...measured, scrollTop: Math.max(measured.scrollTop, 0), scrollLeft: Math.max(measured.scrollLeft, 0) }\n : current;\n const target = getSpreadsheetScrollToCell(latest.current.metrics, base, { row: activeRow, col: activeCol });\n if (!target) return;\n const next = { ...base, ...target };\n if (el) {\n if (target.scrollTop !== undefined) el.scrollTop = target.scrollTop;\n if (target.scrollLeft !== undefined) el.scrollLeft = target.scrollLeft;\n }\n // Some environments (jsdom) never fire the scroll event.\n updateViewport(next);\n // Only the active cell and the mode: scrolling away from the active cell\n // (or an edit elsewhere) must not snap back.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [virtual, activeRow, activeCol]);\n\n return { metrics, window: win, onScroll };\n}\n","import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { applyFormulaSuggestion, getFormulaHints, type FormulaNameSuggestionSource } from '@pixerate/editor/spreadsheet';\n\nexport interface FormulaHintsProps {\n /** The input being edited (a cell editor or the formula bar). */\n inputRef: React.RefObject<HTMLInputElement | null>;\n /** The input's current value. */\n value: string;\n /** Called with the new value when a suggestion is accepted. */\n onAccept: (value: string) => void;\n /** Maximum number of function suggestions (default 8). */\n limit?: number;\n /** Defined names to suggest too (e.g. `controller.getNameSuggestions()`). */\n names?: readonly FormulaNameSuggestionSource[];\n}\n\n/**\n * Formula autocomplete for an input: while the value starts with `=`, lists\n * functions matching the name at the caret (name, signature, description) and,\n * inside a call, shows the signature with the current argument highlighted.\n *\n * Keys are handled on the input itself, before the grid sees them: ArrowUp /\n * ArrowDown move the selection, Tab accepts it, Escape closes the list.\n * Enter is left alone so it still commits the cell.\n */\nexport const FormulaHints: React.FC<FormulaHintsProps> = ({ inputRef, value, onAccept, limit = 8, names }) => {\n const [caret, setCaret] = useState<number | null>(null);\n const [focused, setFocused] = useState(false);\n const [selected, setSelected] = useState(0);\n const [dismissed, setDismissed] = useState(false);\n const [position, setPosition] = useState<{ top: number; left: number; width: number } | null>(null);\n const pendingCaret = useRef<number | null>(null);\n\n const hints = useMemo(\n () => getFormulaHints(value, caret ?? value.length, { limit, names }),\n [value, caret, limit, names],\n );\n const suggestions = dismissed ? [] : hints.suggestions;\n const selectedIndex = Math.max(0, Math.min(selected, suggestions.length - 1));\n const visible = focused && value.trimStart().startsWith('=') && (suggestions.length > 0 || !!hints.activeCall);\n\n // The key listener reads the latest state through a ref.\n const latest = useRef({ suggestions, selected: selectedIndex, value, caret, onAccept });\n latest.current = { suggestions, selected: selectedIndex, value, caret, onAccept };\n\n const accept = (index: number) => {\n const { suggestions: list, value: current, caret: at, onAccept: commit } = latest.current;\n const suggestion = list[index];\n if (!suggestion) return;\n const next = applyFormulaSuggestion(current, at ?? current.length, suggestion);\n pendingCaret.current = next.caret;\n commit(next.value);\n };\n\n useEffect(() => {\n const input = inputRef.current;\n if (!input) return;\n const syncCaret = () => setCaret(input.selectionStart ?? input.value.length);\n const onInput = () => {\n setDismissed(false);\n setSelected(0);\n syncCaret();\n };\n const onFocus = () => {\n setFocused(true);\n syncCaret();\n };\n const onBlur = () => setFocused(false);\n // A native listener on the input runs before React's delegated handlers,\n // so stopping propagation keeps these keys away from the grid.\n const onKeyDown = (e: KeyboardEvent) => {\n const { suggestions: list } = latest.current;\n if (list.length === 0) return;\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n e.preventDefault();\n e.stopPropagation();\n const step = e.key === 'ArrowDown' ? 1 : -1;\n setSelected((i) => (i + step + list.length) % list.length);\n } else if (e.key === 'Tab' && !e.shiftKey) {\n e.preventDefault();\n e.stopPropagation();\n accept(latest.current.selected);\n } else if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n setDismissed(true);\n }\n };\n\n input.addEventListener('input', onInput);\n input.addEventListener('keyup', syncCaret);\n input.addEventListener('click', syncCaret);\n input.addEventListener('select', syncCaret);\n input.addEventListener('focus', onFocus);\n input.addEventListener('blur', onBlur);\n input.addEventListener('keydown', onKeyDown);\n // Inputs focused on mount (autoFocus) fired `focus` before this effect ran.\n if (typeof document !== 'undefined' && document.activeElement === input) onFocus();\n return () => {\n input.removeEventListener('input', onInput);\n input.removeEventListener('keyup', syncCaret);\n input.removeEventListener('click', syncCaret);\n input.removeEventListener('select', syncCaret);\n input.removeEventListener('focus', onFocus);\n input.removeEventListener('blur', onBlur);\n input.removeEventListener('keydown', onKeyDown);\n };\n }, [inputRef]);\n\n // After accepting, put the caret inside the inserted parenthesis.\n useLayoutEffect(() => {\n const input = inputRef.current;\n const at = pendingCaret.current;\n if (!input || at === null || input.value !== value) return;\n pendingCaret.current = null;\n input.setSelectionRange(at, at);\n setCaret(at);\n setSelected(0);\n }, [value, inputRef]);\n\n useLayoutEffect(() => {\n const input = inputRef.current;\n if (!visible || !input) return;\n const rect = input.getBoundingClientRect();\n setPosition({ top: rect.bottom + 2, left: rect.left, width: rect.width });\n }, [visible, value, inputRef]);\n\n if (!visible) return null;\n\n const { activeCall } = hints;\n return (\n <div\n data-formula-hints=\"\"\n className=\"rounded-md border border-border bg-popover text-popover-foreground shadow-md text-xs font-sans overflow-hidden\"\n style={{\n position: 'fixed',\n top: position?.top ?? 0,\n left: position?.left ?? 0,\n minWidth: Math.max(260, position?.width ?? 0),\n maxWidth: 440,\n zIndex: 50,\n visibility: position ? 'visible' : 'hidden'\n }}\n onMouseDown={(e) => e.preventDefault()}\n >\n {activeCall && (\n <div data-formula-signature=\"\" className=\"px-2 py-1.5 border-b border-border bg-muted/30\">\n <div className=\"font-mono\">\n {activeCall.parts.map((part, i) => (\n <span\n key={i}\n data-active={part.active ? '' : undefined}\n className={part.active ? 'font-bold text-primary underline' : ''}\n >\n {part.text}\n </span>\n ))}\n </div>\n <div className=\"mt-0.5 text-muted-foreground\">\n {activeCall.argument ? (\n <>\n <span className=\"font-semibold\">{activeCall.argument.name}</span>: {activeCall.argument.description}\n </>\n ) : (\n activeCall.description\n )}\n </div>\n </div>\n )}\n {suggestions.length > 0 && (\n <ul role=\"listbox\" aria-label=\"Formula suggestions\" className=\"max-h-64 overflow-auto py-1 m-0 list-none p-0\">\n {suggestions.map((s, i) => (\n <li\n key={`${s.kind ?? 'fn'}:${s.name}`}\n role=\"option\"\n aria-selected={i === selectedIndex}\n className={`cursor-pointer px-2 py-1 ${i === selectedIndex ? 'bg-primary/10' : 'hover:bg-muted/50'}`}\n onMouseEnter={() => setSelected(i)}\n onMouseDown={(e) => {\n // Keep focus in the input so the edit isn't committed by blur.\n e.preventDefault();\n accept(i);\n }}\n >\n <div className=\"font-mono font-semibold text-foreground\">{s.signature}</div>\n <div className=\"text-muted-foreground truncate\">{s.description}</div>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n};\n","import React, { useRef, useState } from 'react';\nimport { getSheetTabMenuItems, sheetDropIndex, type SpreadsheetMenuItem } from '@pixerate/editor/spreadsheet';\nimport type { useSpreadsheetEditor } from './useSpreadsheetEditor';\nimport { SpreadsheetContextMenu } from './SpreadsheetContextMenu';\n\nexport interface SheetTabsProps {\n state: ReturnType<typeof useSpreadsheetEditor>;\n readOnly?: boolean;\n className?: string;\n}\n\n/**\n * The workbook's sheet tabs: click to switch, double-click to rename, drag\n * to reorder, right-click for insert / rename / duplicate / move / delete\n * (delete asks to confirm), and a `+` button to add a sheet.\n */\nexport const SheetTabs: React.FC<SheetTabsProps> = ({ state, readOnly = false, className = '' }) => {\n const { controller, sheets } = state;\n const [renaming, setRenaming] = useState<{ id: string; draft: string } | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [menu, setMenu] = useState<{ x: number; y: number; items: SpreadsheetMenuItem[] } | null>(null);\n const dragFrom = useRef<number | null>(null);\n const [dropTarget, setDropTarget] = useState<{ index: number; after: boolean } | null>(null);\n\n const commitRename = (cancelOnError: boolean) => {\n if (!renaming) return;\n const sheet = sheets.find((s) => s.id === renaming.id);\n const name = renaming.draft.trim();\n if (!sheet || !name || name === sheet.name) {\n setRenaming(null);\n setError(null);\n return;\n }\n try {\n state.renameSheet(renaming.id, name);\n setRenaming(null);\n setError(null);\n } catch (err: any) {\n setError(err?.message ?? String(err));\n if (cancelOnError) setRenaming(null);\n }\n };\n\n const dropAfter = (e: React.DragEvent<HTMLElement>) => {\n const rect = e.currentTarget.getBoundingClientRect();\n return e.clientX > rect.left + rect.width / 2;\n };\n\n return (\n <div className={`flex flex-col ${className}`} data-sheet-tabs=\"\">\n <div\n role=\"tablist\"\n aria-label=\"Sheets\"\n className=\"flex items-center gap-0.5 overflow-x-auto border-t border-border bg-muted px-1 py-1 text-xs\"\n >\n {sheets.map((sheet, index) =>\n renaming?.id === sheet.id ? (\n <input\n key={sheet.id}\n aria-label=\"Sheet name\"\n autoFocus\n className=\"w-32 rounded border border-primary bg-background px-2 py-0.5 text-xs outline-none\"\n value={renaming.draft}\n onChange={(e) => setRenaming({ id: sheet.id, draft: e.target.value })}\n onFocus={(e) => e.currentTarget.select()}\n onKeyDown={(e) => {\n e.stopPropagation();\n if (e.key === 'Enter') commitRename(false);\n else if (e.key === 'Escape') {\n setRenaming(null);\n setError(null);\n }\n }}\n onBlur={() => commitRename(true)}\n />\n ) : (\n <button\n key={sheet.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={sheet.active}\n data-sheet-id={sheet.id}\n draggable={!readOnly}\n title={readOnly ? sheet.name : `${sheet.name} — double-click to rename, drag to move`}\n className={`whitespace-nowrap rounded px-3 py-0.5 ${\n sheet.active ? 'bg-background font-semibold text-foreground shadow-sm' : 'text-muted-foreground hover:bg-background/60'\n } ${dropTarget?.index === index ? (dropTarget.after ? 'border-r-2 border-primary' : 'border-l-2 border-primary') : ''}`}\n onClick={() => state.setActiveSheet(sheet.id)}\n onDoubleClick={() => {\n if (readOnly) return;\n setError(null);\n setRenaming({ id: sheet.id, draft: sheet.name });\n }}\n onContextMenu={(e) => {\n if (readOnly) return;\n e.preventDefault();\n setMenu({ x: e.clientX, y: e.clientY, items: getSheetTabMenuItems(controller, sheet.id, { onError: setError }) });\n }}\n onDragStart={(e) => {\n dragFrom.current = index;\n e.dataTransfer?.setData('text/plain', sheet.id);\n if (e.dataTransfer) e.dataTransfer.effectAllowed = 'move';\n }}\n onDragOver={(e) => {\n if (dragFrom.current === null) return;\n e.preventDefault();\n const after = dropAfter(e);\n setDropTarget((prev) => (prev?.index === index && prev.after === after ? prev : { index, after }));\n }}\n onDragLeave={() => setDropTarget(null)}\n onDrop={(e) => {\n e.preventDefault();\n const from = dragFrom.current;\n dragFrom.current = null;\n setDropTarget(null);\n if (from === null) return;\n state.moveSheet(sheets[from].id, sheetDropIndex(from, index, dropAfter(e)));\n }}\n onDragEnd={() => {\n dragFrom.current = null;\n setDropTarget(null);\n }}\n >\n {sheet.name}\n </button>\n ),\n )}\n {!readOnly && (\n <button\n type=\"button\"\n aria-label=\"Add sheet\"\n title=\"Add sheet\"\n className=\"rounded px-2 py-0.5 text-muted-foreground hover:bg-background/60\"\n onClick={() => {\n setError(null);\n state.addSheet();\n }}\n >\n +\n </button>\n )}\n </div>\n {error && (\n <div role=\"alert\" className=\"px-2 py-1 text-xs text-destructive\">\n {error}\n </div>\n )}\n {menu && (\n <SpreadsheetContextMenu\n items={menu.items}\n x={menu.x}\n y={menu.y}\n ariaLabel=\"Sheet actions\"\n onClose={() => setMenu(null)}\n />\n )}\n </div>\n );\n};\n","import React, { useMemo, useState } from 'react';\nimport { getNameManagerRows, parseFormula, type SpreadsheetNameRow } from '@pixerate/editor/spreadsheet';\nimport type { useSpreadsheetEditor } from './useSpreadsheetEditor';\n\nexport interface NameManagerProps {\n state: ReturnType<typeof useSpreadsheetEditor>;\n readOnly?: boolean;\n onClose?: () => void;\n className?: string;\n}\n\ninterface Draft {\n /** The name being edited (null for a new one). */\n original: { name: string; sheetId?: string } | null;\n name: string;\n refersTo: string;\n /** Sheet id, or '' for workbook scope. */\n scope: string;\n comment: string;\n}\n\nconst EMPTY_DRAFT: Draft = { original: null, name: '', refersTo: '=', scope: '', comment: '' };\n\n/**\n * A simple Name Manager: lists defined names (name, current value, formula,\n * scope) and adds, edits, renames and deletes them. Renaming a name rewrites\n * the formulas that use it; deleting one leaves them showing `#NAME?`.\n */\nexport const NameManager: React.FC<NameManagerProps> = ({ state, readOnly = false, onClose, className = '' }) => {\n const { controller, sheets } = state;\n const rows = useMemo(\n () => getNameManagerRows(controller),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [controller, state.document, state.names],\n );\n const [draft, setDraft] = useState<Draft>(EMPTY_DRAFT);\n const [error, setError] = useState<string | null>(null);\n\n const edit = (row: SpreadsheetNameRow) => {\n setError(null);\n setDraft({\n original: { name: row.name, sheetId: row.sheetId },\n name: row.name,\n refersTo: row.refersTo,\n scope: row.sheetId ?? '',\n comment: row.comment ?? '',\n });\n };\n\n const save = (e: React.FormEvent) => {\n e.preventDefault();\n const scope = draft.scope ? { sheet: draft.scope } : {};\n try {\n // Check before changing anything, so a failed edit keeps the old name.\n const invalid = controller.validateDefinedName(draft.name.trim());\n if (invalid) throw new Error(invalid);\n try {\n parseFormula(draft.refersTo.trim().startsWith('=') ? draft.refersTo.trim() : `=${draft.refersTo.trim()}`);\n } catch (err: any) {\n throw new Error(`There's a problem with this formula: ${err?.message ?? draft.refersTo}`);\n }\n const original = draft.original;\n if (original) {\n const originalScope = original.sheetId ? { sheet: original.sheetId } : {};\n if ((original.sheetId ?? '') !== draft.scope) {\n state.deleteName(original.name, originalScope);\n } else if (original.name !== draft.name) {\n state.renameName(original.name, draft.name.trim(), originalScope);\n }\n }\n state.defineName(draft.name.trim(), draft.refersTo, { ...scope, comment: draft.comment || undefined });\n setDraft(EMPTY_DRAFT);\n setError(null);\n } catch (err: any) {\n setError(err?.message ?? String(err));\n }\n };\n\n return (\n <section aria-label=\"Name Manager\" className={`flex flex-col gap-2 text-xs ${className}`} data-name-manager=\"\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"m-0 text-sm font-semibold\">Name Manager</h3>\n {onClose && (\n <button type=\"button\" aria-label=\"Close Name Manager\" className=\"rounded px-2 hover:bg-muted\" onClick={onClose}>\n ×\n </button>\n )}\n </div>\n <table className=\"w-full border-collapse\">\n <thead>\n <tr className=\"text-left text-muted-foreground\">\n <th className=\"px-1 font-medium\">Name</th>\n <th className=\"px-1 font-medium\">Value</th>\n <th className=\"px-1 font-medium\">Refers to</th>\n <th className=\"px-1 font-medium\">Scope</th>\n {!readOnly && <th className=\"px-1\" />}\n </tr>\n </thead>\n <tbody>\n {rows.length === 0 && (\n <tr>\n <td colSpan={5} className=\"px-1 py-2 text-muted-foreground\">\n No names yet.\n </td>\n </tr>\n )}\n {rows.map((row) => (\n <tr key={`${row.sheetId ?? ''}!${row.name}`} data-name={row.name} className=\"border-t border-border\" title={row.comment}>\n <td className=\"px-1 py-0.5 font-mono font-semibold\">{row.name}</td>\n <td className=\"px-1 py-0.5\">{row.value}</td>\n <td className=\"px-1 py-0.5 font-mono\">{row.refersTo}</td>\n <td className=\"px-1 py-0.5\">{row.scopeLabel}</td>\n {!readOnly && (\n <td className=\"whitespace-nowrap px-1 py-0.5 text-right\">\n <button type=\"button\" aria-label={`Edit ${row.name}`} className=\"rounded px-1 hover:bg-muted\" onClick={() => edit(row)}>\n Edit\n </button>\n <button\n type=\"button\"\n aria-label={`Delete ${row.name}`}\n className=\"rounded px-1 text-destructive hover:bg-muted\"\n onClick={() => {\n state.deleteName(row.name, row.sheetId ? { sheet: row.sheetId } : {});\n if (draft.original?.name === row.name && (draft.original.sheetId ?? '') === (row.sheetId ?? '')) setDraft(EMPTY_DRAFT);\n }}\n >\n Delete\n </button>\n </td>\n )}\n </tr>\n ))}\n </tbody>\n </table>\n {!readOnly && (\n <form className=\"grid grid-cols-[auto_1fr] items-center gap-x-2 gap-y-1\" onSubmit={save} aria-label={draft.original ? `Edit name ${draft.original.name}` : 'New name'}>\n <label htmlFor=\"pixerate-name-manager-name\">Name</label>\n <input\n id=\"pixerate-name-manager-name\"\n className=\"rounded border border-border bg-background px-1 py-0.5\"\n value={draft.name}\n onChange={(e) => setDraft({ ...draft, name: e.target.value })}\n />\n <label htmlFor=\"pixerate-name-manager-refers\">Refers to</label>\n <input\n id=\"pixerate-name-manager-refers\"\n className=\"rounded border border-border bg-background px-1 py-0.5 font-mono\"\n value={draft.refersTo}\n onChange={(e) => setDraft({ ...draft, refersTo: e.target.value })}\n />\n <label htmlFor=\"pixerate-name-manager-scope\">Scope</label>\n <select\n id=\"pixerate-name-manager-scope\"\n className=\"rounded border border-border bg-background px-1 py-0.5\"\n value={draft.scope}\n onChange={(e) => setDraft({ ...draft, scope: e.target.value })}\n >\n <option value=\"\">Workbook</option>\n {sheets.map((sheet) => (\n <option key={sheet.id} value={sheet.id}>\n {sheet.name}\n </option>\n ))}\n </select>\n <label htmlFor=\"pixerate-name-manager-comment\">Comment</label>\n <input\n id=\"pixerate-name-manager-comment\"\n className=\"rounded border border-border bg-background px-1 py-0.5\"\n value={draft.comment}\n onChange={(e) => setDraft({ ...draft, comment: e.target.value })}\n />\n <div className=\"col-span-2 flex gap-2\">\n <button type=\"submit\" className=\"rounded bg-primary px-2 py-0.5 text-primary-foreground\">\n {draft.original ? 'Save' : 'Add name'}\n </button>\n {draft.original && (\n <button\n type=\"button\"\n className=\"rounded px-2 py-0.5 hover:bg-muted\"\n onClick={() => {\n setDraft(EMPTY_DRAFT);\n setError(null);\n }}\n >\n Cancel\n </button>\n )}\n </div>\n </form>\n )}\n {error && (\n <div role=\"alert\" className=\"text-destructive\">\n {error}\n </div>\n )}\n </section>\n );\n};\n","import React, { createContext, useContext, useMemo } from 'react';\nimport type {\n\tButtonSlotProps,\n\tEditorSlotsMap,\n\tNodeHeaderSlotProps,\n\tTooltipSlotProps\n} from '@pixerate/editor';\n\nconst defaultSlots: EditorSlotsMap = {\n\tButton: (props: ButtonSlotProps) => (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclassName={`pixerate-btn ${props.className || ''}`}\n\t\t\tonClick={props.onClick}\n\t\t\tdisabled={props.disabled}\n\t\t>\n\t\t\t{props.children}\n\t\t</button>\n\t),\n\tTooltip: (props: TooltipSlotProps) => (\n\t\t<div className={`pixerate-tooltip-container ${props.className || ''}`} title={String(props.content)}>\n\t\t\t{props.children}\n\t\t</div>\n\t),\n\tNodeHeader: (props: NodeHeaderSlotProps) => (\n\t\t<div className={`pixerate-node-header flex items-center justify-between ${props.className || ''}`}>\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t{props.icon}\n\t\t\t\t<span className=\"font-semibold\">{props.title}</span>\n\t\t\t</div>\n\t\t\t{props.onClose && (\n\t\t\t\t<button type=\"button\" onClick={props.onClose} className=\"opacity-70 hover:opacity-100\">\n\t\t\t\t\t×\n\t\t\t\t</button>\n\t\t\t)}\n\t\t</div>\n\t)\n};\n\nconst EditorSlotsContext = createContext<EditorSlotsMap>(defaultSlots);\n\nexport interface EditorSlotsProviderProps {\n\tslots?: Partial<EditorSlotsMap>;\n\tchildren: React.ReactNode;\n}\n\n/**\n * Context provider allowing consumers to inject custom design system components into the editor.\n */\nexport function EditorSlotsProvider({ slots, children }: EditorSlotsProviderProps) {\n\tconst mergedSlots = useMemo(() => ({ ...defaultSlots, ...slots }), [slots]);\n\n\treturn (\n\t\t<EditorSlotsContext.Provider value={mergedSlots}>\n\t\t\t{children}\n\t\t</EditorSlotsContext.Provider>\n\t);\n}\n\n/**\n * Hook to access injected design system slots.\n */\nexport function useEditorSlots(): EditorSlotsMap {\n\treturn useContext(EditorSlotsContext);\n}\n","import { useRef, useState, useEffect, useCallback, useMemo } from 'react';\nimport type { ToolRegistry } from '@pixerate/editor/tools';\nimport {\n ImageEditorController,\n createImageEffectsToolProvider,\n type ImageEffectsToolProviderOptions,\n type ImageEditorOptions,\n type ImageEditorState,\n type ImageEditorTool,\n type CropBox,\n type AspectRatio,\n type ImageAdjustments,\n type DepthMaskOptions,\n type Annotation,\n type CreateAnnotationPayload,\n type ExportOptions,\n type SerializedImageEditorState,\n type AIResultOptions,\n type ImagePoint,\n type AdjustmentKind,\n type AdjustmentLayerInit,\n type AdjustmentLayerUpdate,\n type ImageHistogram,\n} from '@pixerate/editor/image-editor';\n\nexport interface UseImageEditorReturn {\n controller: ImageEditorController;\n state: ImageEditorState;\n canUndo: boolean;\n canRedo: boolean;\n setTool: (tool: ImageEditorTool) => void;\n setCrop: (crop: CropBox | null, addToHistory?: boolean) => void;\n applyCropPreset: (ratio: AspectRatio) => void;\n resetCrop: () => void;\n rotate: (degrees: number) => void;\n setRotation: (degrees: number) => void;\n flipHorizontal: () => void;\n flipVertical: () => void;\n setAdjustments: (partial: Partial<ImageAdjustments>, commitToHistory?: boolean) => void;\n resetAdjustments: () => void;\n /** Update to Current Process: re-render the adjustments with the latest process (one undo step). */\n upgradeProcess: () => boolean;\n /** Adds an adjustment layer (one undo step) and returns its id. */\n addAdjustmentLayer: (init: AdjustmentKind | AdjustmentLayerInit, index?: number) => string;\n updateAdjustmentLayer: (id: string, update: AdjustmentLayerUpdate, commitToHistory?: boolean) => boolean;\n removeAdjustmentLayer: (id: string) => boolean;\n moveAdjustmentLayer: (id: string, toIndex: number) => boolean;\n toggleAdjustmentLayer: (id: string, enabled?: boolean) => boolean;\n /** Histogram of the last rendered preview (after adjustments and layers); null before a render. */\n histogram: ImageHistogram | null;\n setDepthMask: (partial: Partial<DepthMaskOptions>) => void;\n resetDepthMask: () => void;\n addAnnotation: (annotation: CreateAnnotationPayload) => string;\n updateAnnotation: (id: string, partial: Partial<Annotation>, commitToHistory?: boolean) => void;\n removeAnnotation: (id: string) => void;\n clearAnnotations: () => void;\n selectAnnotation: (id: string | null) => void;\n undo: () => boolean;\n redo: () => boolean;\n reset: () => void;\n zoomIn: (factor?: number) => void;\n zoomOut: (factor?: number) => void;\n resetZoom: () => void;\n setZoom: (zoom: number) => void;\n setPan: (pan: ImagePoint) => void;\n setComparing: (comparing: boolean) => void;\n loadImage: (src: string | HTMLImageElement) => Promise<void>;\n toDataURL: (options?: ExportOptions) => Promise<string>;\n toBlob: (options?: ExportOptions) => Promise<Blob>;\n toJSON: () => SerializedImageEditorState;\n loadJSON: (data: SerializedImageEditorState) => void;\n renderMask: (options?: { useAnnotations?: boolean; useCrop?: boolean }) => Promise<HTMLCanvasElement>;\n toMaskDataURL: (options?: { useAnnotations?: boolean; useCrop?: boolean }) => Promise<string>;\n toSourceDataURL: (options?: Pick<ExportOptions, 'format' | 'quality'>) => Promise<string>;\n /** In documents with several layers (or `target: 'new-layer'`) the result goes to a new layer. */\n applyInpaintedImage: (newDataUrl: string, options?: AIResultOptions) => Promise<string | void>;\n /** In documents with several layers (or `target: 'new-layer'`) the result's alpha masks the active layer. */\n applyBackgroundRemovedImage: (newDataUrl: string, options?: AIResultOptions) => Promise<string | void>;\n}\n\nexport function useImageEditor(options: ImageEditorOptions = {}): UseImageEditorReturn {\n const controllerRef = useRef<ImageEditorController | null>(null);\n\n if (!controllerRef.current) {\n controllerRef.current = new ImageEditorController(options);\n }\n\n const controller = controllerRef.current;\n const [state, setState] = useState<ImageEditorState>(() => controller.getState());\n const [historyTicks, setHistoryTicks] = useState(0);\n const [histogram, setHistogram] = useState<ImageHistogram | null>(() => controller.getHistogram());\n\n useEffect(() => controller.subscribeHistogram(setHistogram), [controller]);\n\n useEffect(() => {\n const unsub = controller.subscribe((next) => {\n setState(next);\n setHistoryTicks((t) => t + 1);\n });\n return unsub;\n }, [controller]);\n\n // The constructor loads the initial image. Reload only when the `image`\n // option itself changes, not whenever the controller's source differs from\n // it (AI edits replace the source with a data URL and must not be reverted).\n const loadedImageRef = useRef(options.image);\n useEffect(() => {\n if (options.image === loadedImageRef.current) return;\n loadedImageRef.current = options.image;\n if (options.image) {\n controller.loadImage(options.image);\n }\n }, [options.image, controller]);\n\n const setTool = useCallback((tool: ImageEditorTool) => controller.setTool(tool), [controller]);\n const setCrop = useCallback(\n (crop: CropBox | null, addToHistory = true) => controller.setCrop(crop, addToHistory),\n [controller]\n );\n const applyCropPreset = useCallback((ratio: AspectRatio) => controller.applyCropPreset(ratio), [controller]);\n const resetCrop = useCallback(() => controller.resetCrop(), [controller]);\n const rotate = useCallback((deg: number) => controller.rotate(deg), [controller]);\n const setRotation = useCallback((deg: number) => controller.setRotation(deg), [controller]);\n const flipHorizontal = useCallback(() => controller.flipHorizontal(), [controller]);\n const flipVertical = useCallback(() => controller.flipVertical(), [controller]);\n const setAdjustments = useCallback(\n (partial: Partial<ImageAdjustments>, commitToHistory = true) =>\n controller.setAdjustments(partial, commitToHistory),\n [controller]\n );\n const resetAdjustments = useCallback(() => controller.resetAdjustments(), [controller]);\n const upgradeProcess = useCallback(() => controller.upgradeProcess(), [controller]);\n const addAdjustmentLayer = useCallback(\n (init: AdjustmentKind | AdjustmentLayerInit, index?: number) => controller.addAdjustmentLayer(init, index),\n [controller]\n );\n const updateAdjustmentLayer = useCallback(\n (id: string, update: AdjustmentLayerUpdate, commitToHistory = true) =>\n controller.updateAdjustmentLayer(id, update, commitToHistory),\n [controller]\n );\n const removeAdjustmentLayer = useCallback((id: string) => controller.removeAdjustmentLayer(id), [controller]);\n const moveAdjustmentLayer = useCallback((id: string, to: number) => controller.moveAdjustmentLayer(id, to), [controller]);\n const toggleAdjustmentLayer = useCallback(\n (id: string, enabled?: boolean) => controller.toggleAdjustmentLayer(id, enabled),\n [controller]\n );\n const setDepthMask = useCallback((partial: Partial<DepthMaskOptions>) => controller.setDepthMask(partial), [controller]);\n const resetDepthMask = useCallback(() => controller.resetDepthMask(), [controller]);\n const addAnnotation = useCallback((ann: CreateAnnotationPayload) => controller.addAnnotation(ann), [controller]);\n const updateAnnotation = useCallback(\n (id: string, partial: Partial<Annotation>, commitToHistory = true) =>\n controller.updateAnnotation(id, partial, commitToHistory),\n [controller]\n );\n const removeAnnotation = useCallback((id: string) => controller.removeAnnotation(id), [controller]);\n const clearAnnotations = useCallback(() => controller.clearAnnotations(), [controller]);\n const selectAnnotation = useCallback((id: string | null) => controller.selectAnnotation(id), [controller]);\n const undo = useCallback(() => controller.undo(), [controller]);\n const redo = useCallback(() => controller.redo(), [controller]);\n const reset = useCallback(() => controller.reset(), [controller]);\n const zoomIn = useCallback((factor?: number) => controller.zoomIn(factor), [controller]);\n const zoomOut = useCallback((factor?: number) => controller.zoomOut(factor), [controller]);\n const resetZoom = useCallback(() => controller.resetZoom(), [controller]);\n const setZoom = useCallback((zoom: number) => controller.setZoom(zoom), [controller]);\n const setPan = useCallback((pan: ImagePoint) => controller.setPan(pan), [controller]);\n const setComparing = useCallback((comp: boolean) => controller.setComparing(comp), [controller]);\n const loadImage = useCallback((src: string | HTMLImageElement) => controller.loadImage(src), [controller]);\n const toDataURL = useCallback((opts?: ExportOptions) => controller.toDataURL(opts), [controller]);\n const toBlob = useCallback((opts?: ExportOptions) => controller.toBlob(opts), [controller]);\n const toJSON = useCallback(() => controller.toJSON(), [controller]);\n const loadJSON = useCallback((data: SerializedImageEditorState) => controller.loadJSON(data), [controller]);\n const renderMask = useCallback(\n (opts?: { useAnnotations?: boolean; useCrop?: boolean }) => controller.renderMask(opts),\n [controller]\n );\n const toMaskDataURL = useCallback(\n (opts?: { useAnnotations?: boolean; useCrop?: boolean }) => controller.toMaskDataURL(opts),\n [controller]\n );\n const toSourceDataURL = useCallback(\n (opts?: Pick<ExportOptions, 'format' | 'quality'>) => controller.toSourceDataURL(opts),\n [controller]\n );\n const applyInpaintedImage = useCallback(\n (newDataUrl: string, options?: AIResultOptions) => controller.applyInpaintedImage(newDataUrl, options),\n [controller]\n );\n const applyBackgroundRemovedImage = useCallback(\n (newDataUrl: string, options?: AIResultOptions) => controller.applyBackgroundRemovedImage(newDataUrl, options),\n [controller]\n );\n\n return useMemo(\n () => ({\n controller,\n state,\n canUndo: controller.canUndo,\n canRedo: controller.canRedo,\n setTool,\n setCrop,\n applyCropPreset,\n resetCrop,\n rotate,\n setRotation,\n flipHorizontal,\n flipVertical,\n setAdjustments,\n resetAdjustments,\n upgradeProcess,\n addAdjustmentLayer,\n updateAdjustmentLayer,\n removeAdjustmentLayer,\n moveAdjustmentLayer,\n toggleAdjustmentLayer,\n histogram,\n setDepthMask,\n resetDepthMask,\n addAnnotation,\n updateAnnotation,\n removeAnnotation,\n clearAnnotations,\n selectAnnotation,\n undo,\n redo,\n reset,\n zoomIn,\n zoomOut,\n resetZoom,\n setZoom,\n setPan,\n setComparing,\n loadImage,\n toDataURL,\n toBlob,\n toJSON,\n loadJSON,\n renderMask,\n toMaskDataURL,\n toSourceDataURL,\n applyInpaintedImage,\n applyBackgroundRemovedImage,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [controller, state, historyTicks, histogram]\n );\n}\n\n/**\n * Registers the image editor's provider-effect tools (`search_effects`, `describe_effect`,\n * `apply_effect`, `add_effect_layer`, …) in `registry` while mounted. They work once an effects\n * provider is registered (see `useEffects`); before that the read tools say so and the write tools\n * refuse.\n */\nexport function useImageEffectsTools(\n registry: ToolRegistry | null | undefined,\n controller: ImageEditorController,\n options: ImageEffectsToolProviderOptions = {},\n): void {\n const { id, namespace, readOnly } = options;\n useEffect(() => {\n if (!registry) return;\n return registry.register(createImageEffectsToolProvider(controller, { id, namespace, readOnly }));\n }, [registry, controller, id, namespace, readOnly]);\n}\n","import React, { useRef, useEffect, useState, useCallback } from 'react';\nimport type {\n Annotation,\n CropBox,\n CropHandle,\n ExportOptions,\n ImageEditorTool,\n ImagePoint,\n InpaintHook,\n RemoveBackgroundHook,\n ImageEditorAIHooks,\n} from '@pixerate/editor/image-editor';\nimport {\n canvasToImagePoint,\n hitTestCrop,\n getCropCursor,\n calculateCropDrag,\n hitTestAnnotation,\n normalizeProcessVersion,\n LATEST_PROCESS_VERSION,\n IMAGE_ADJUSTMENT_CONTROLS,\n readAdjustmentControls,\n DEFAULT_SELECTION_TOOL_OPTIONS,\n SelectionGesture,\n PaintGesture,\n handlePaintShortcut,\n pointerPressure,\n FreeTransformTool,\n getViewportProjection,\n ShapeDrawGesture,\n TypeToolGesture,\n DEFAULT_SHAPE_TOOL_OPTIONS,\n DEFAULT_TYPE_TOOL_OPTIONS,\n type SelectionToolOptions,\n type ShapeToolOptions,\n type TypeToolOptions,\n type TransformHandle,\n} from '@pixerate/editor/image-editor';\nimport { useImageEditor, type UseImageEditorReturn } from './useImageEditor';\nimport { ControlSlider } from './ControlSlider';\nimport { Histogram } from './Histogram';\nimport { AdjustmentLayersPanel } from './AdjustmentLayersPanel';\nimport { LayersPanel } from './LayersPanel';\nimport { ImageProviderEffectsPanel } from './ImageProviderEffectsPanel';\nimport type { EffectProvider } from '@pixerate/editor/effects';\nimport { useEffects } from '../effects';\nimport { BrushOptionsBar } from './BrushOptionsBar';\nimport { ColorProfilePanel } from './ColorProfilePanel';\nimport { SelectionOptionsBar } from './SelectionOptionsBar';\nimport { RefineEdgePanel } from './RefineEdgePanel';\nimport { FreeTransformOptionsBar } from './FreeTransformOptionsBar';\nimport { ShapeOptionsBar } from './ShapeOptionsBar';\nimport { TypeOptionsBar } from './TypeOptionsBar';\n\nexport interface ImageEditorProps {\n editor?: UseImageEditorReturn;\n src?: string;\n className?: string;\n style?: React.CSSProperties;\n onSave?: (dataUrl: string) => void;\n exportOptions?: ExportOptions;\n onInpaint?: InpaintHook;\n onRemoveBackground?: RemoveBackgroundHook;\n aiHooks?: ImageEditorAIHooks;\n /**\n * An effects provider (see `@pixerate/editor/effects`), registered with the controller while\n * mounted: filter effects as smart filters and generator or overlay effects as effect layers,\n * with an Effects section in the Layers tab. Optional: without one the editor is as before.\n */\n effects?: EffectProvider | null;\n}\n\ntype TabType = 'crop' | 'adjust' | 'layers' | 'paint' | 'select' | 'annotate' | 'depth' | 'ai';\n\nexport const ImageEditor: React.FC<ImageEditorProps> = ({\n editor: externalEditor,\n src,\n className = '',\n style,\n onSave,\n exportOptions,\n onInpaint,\n onRemoveBackground,\n aiHooks,\n effects,\n}) => {\n const internalEditor = useImageEditor({ image: src });\n const editor = externalEditor || internalEditor;\n const { state, controller } = editor;\n useEffects(controller, effects);\n const effectsShown = !!controller.effectsProvider || state.layers.some(function has(l): boolean {\n return (l.type === 'pixel' && !!l.generator) || (l.type === 'smart' && !!l.smartFilters?.filters.some((f) => f.kind === 'effect')) || (l.type === 'group' && l.children.some(has));\n });\n const legacyProcess = normalizeProcessVersion(state.adjustments.process) < LATEST_PROCESS_VERSION;\n\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const [activeTab, setActiveTab] = useState<TabType>('crop');\n const [activeCropRatio, setActiveCropRatio] = useState<number | null>(null);\n\n // Selection tools (magic wand, marquees, lasso): options bar state and the pointer gesture.\n const [selectionOptions, setSelectionOptions] = useState<SelectionToolOptions>(DEFAULT_SELECTION_TOOL_OPTIONS);\n const selectionOptionsRef = useRef(selectionOptions);\n selectionOptionsRef.current = selectionOptions;\n const selectionGestureRef = useRef<SelectionGesture | null>(null);\n if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {\n selectionGestureRef.current = new SelectionGesture(controller, () => selectionOptionsRef.current);\n }\n const selectionDraftRef = useRef<ImagePoint[] | null>(null);\n const [selectionError, setSelectionError] = useState<string | null>(null);\n\n // Paint tools (Move, Brush, Eraser): the pointer gesture and the brush cursor.\n const paintGestureRef = useRef<PaintGesture | null>(null);\n const paintControllerRef = useRef(controller);\n if (!paintGestureRef.current || paintControllerRef.current !== controller) {\n paintGestureRef.current = new PaintGesture(controller);\n paintControllerRef.current = controller;\n }\n const brushCursorRef = useRef<ImagePoint | null>(null);\n const [paintError, setPaintError] = useState<string | null>(null);\n\n // Free Transform (Ctrl/Cmd+T): the shared tool drives a session; its overlay is drawn by the renderer.\n const transformToolRef = useRef<FreeTransformTool | null>(null);\n const transformControllerRef = useRef(controller);\n if (!transformToolRef.current || transformControllerRef.current !== controller) {\n transformToolRef.current?.cancel();\n transformToolRef.current = new FreeTransformTool(controller, {\n schedule: (run) => (typeof requestAnimationFrame !== 'undefined' ? requestAnimationFrame(run) : run()),\n });\n transformControllerRef.current = controller;\n }\n const transformTool = transformToolRef.current;\n const [, setTransformTick] = useState(0);\n const [transformCursor, setTransformCursor] = useState('default');\n\n // Shape and type tools: their options and gestures; type is edited on the canvas through a hidden textarea.\n const [shapeOptions, setShapeOptions] = useState<ShapeToolOptions>(DEFAULT_SHAPE_TOOL_OPTIONS);\n const shapeOptionsRef = useRef(shapeOptions);\n shapeOptionsRef.current = shapeOptions;\n const [typeOptions, setTypeOptions] = useState<TypeToolOptions>(DEFAULT_TYPE_TOOL_OPTIONS);\n const typeOptionsRef = useRef(typeOptions);\n typeOptionsRef.current = typeOptions;\n const shapeGestureRef = useRef<ShapeDrawGesture | null>(null);\n const typeToolRef = useRef<TypeToolGesture | null>(null);\n const shapeTypeControllerRef = useRef(controller);\n if (!shapeGestureRef.current || !typeToolRef.current || shapeTypeControllerRef.current !== controller) {\n typeToolRef.current?.finish();\n shapeGestureRef.current = new ShapeDrawGesture(controller, () => shapeOptionsRef.current);\n typeToolRef.current = new TypeToolGesture(controller, () => typeOptionsRef.current);\n shapeTypeControllerRef.current = controller;\n }\n const typeInputRef = useRef<HTMLTextAreaElement>(null);\n const [typeSession, setTypeSession] = useState(typeToolRef.current.session);\n const [shapeTypeError, setShapeTypeError] = useState<string | null>(null);\n\n // AI Tools state\n const [inpaintPrompt, setInpaintPrompt] = useState('');\n const [inpaintMaskMode, setInpaintMaskMode] = useState<'annotations' | 'crop'>('annotations');\n const [isRemovingBg, setIsRemovingBg] = useState(false);\n const [isInpainting, setIsInpainting] = useState(false);\n const [aiError, setAiError] = useState<string | null>(null);\n const [aiSuccess, setAiSuccess] = useState<string | null>(null);\n /** Where AI results go: by layer count (auto), a new layer / mask, or replacing the Background. */\n const [aiTarget, setAiTarget] = useState<'auto' | 'new-layer' | 'replace'>('auto');\n const aiOptions = aiTarget === 'auto' ? {} : { target: aiTarget };\n\n const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;\n const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;\n\n const handleRemoveBackground = async () => {\n if (!effectiveOnRemoveBg) {\n setAiError('No background removal hook is configured.');\n return;\n }\n setAiError(null);\n setAiSuccess(null);\n setIsRemovingBg(true);\n try {\n // AI hooks work in natural pixels (no crop or rotation): the source when the result replaces\n // it, the composite of the layers when the result becomes a layer or mask.\n const imageDataUrl = await controller.toAIInputDataURL(aiOptions);\n const result = await effectiveOnRemoveBg({ imageDataUrl });\n if (typeof result === 'string') {\n await editor.applyBackgroundRemovedImage(result, aiOptions);\n setAiSuccess('Background removed successfully!');\n } else {\n setAiSuccess('Background removal complete.');\n }\n } catch (err: any) {\n setAiError(err?.message || 'Failed to remove background.');\n } finally {\n setIsRemovingBg(false);\n }\n };\n\n const handleInpaint = async () => {\n if (!effectiveOnInpaint) {\n setAiError('No inpainting hook is configured.');\n return;\n }\n if (!inpaintPrompt.trim()) {\n setAiError('Please enter an inpainting prompt.');\n return;\n }\n setAiError(null);\n setAiSuccess(null);\n setIsInpainting(true);\n try {\n // Source image and mask share natural image space so they line up exactly.\n const imageDataUrl = await controller.toAIInputDataURL(aiOptions);\n const maskDataUrl = await editor.toMaskDataURL({\n useAnnotations: inpaintMaskMode === 'annotations',\n useCrop: inpaintMaskMode === 'crop',\n });\n const result = await effectiveOnInpaint({\n prompt: inpaintPrompt.trim(),\n imageDataUrl,\n maskDataUrl,\n cropBox: inpaintMaskMode === 'crop' ? editor.state.crop : null,\n });\n if (typeof result === 'string') {\n await editor.applyInpaintedImage(result, aiOptions);\n setAiSuccess('Inpainting applied successfully!');\n } else {\n setAiSuccess('Inpainting complete.');\n }\n } catch (err: any) {\n setAiError(err?.message || 'Failed to apply inpainting.');\n } finally {\n setIsInpainting(false);\n }\n };\n\n // Annotation drafting state\n const [activeColor, setActiveColor] = useState('#ef4444');\n const [strokeWidth, setStrokeWidth] = useState(3);\n const [fontSize, setFontSize] = useState(24);\n const [textInput, setTextInput] = useState('');\n\n // Live draft and drag references\n const draftAnnotationRef = useRef<Annotation | null>(null);\n const draftCropRef = useRef<CropBox | null>(null);\n const cropDragInfoRef = useRef<{\n handle: CropHandle | 'new';\n startCanvasPt: ImagePoint;\n startImgPt: ImagePoint;\n startCrop: CropBox;\n } | null>(null);\n const annotationDragInfoRef = useRef<{\n annId: string;\n startImgPt: ImagePoint;\n initialAnn: Annotation;\n } | null>(null);\n const isDrawingRef = useRef(false);\n const currentPathRef = useRef<ImagePoint[]>([]);\n const dragStartPointRef = useRef<ImagePoint | null>(null);\n\n // Canvas viewport sizing and re-render\n const renderCanvas = useCallback(\n async (draftAnnotation?: Annotation | null, draftCrop?: CropBox | null) => {\n const canvas = canvasRef.current;\n const container = containerRef.current;\n if (!canvas || !container) return;\n\n const vpWidth = container.clientWidth || 800;\n const vpHeight = container.clientHeight || 500;\n\n await controller.render(canvas, {\n viewportWidth: vpWidth,\n viewportHeight: vpHeight,\n showCropOverlay: activeTab === 'crop',\n showSelectionOverlay: true,\n interactive: true,\n draftAnnotation: draftAnnotation !== undefined ? draftAnnotation : draftAnnotationRef.current,\n draftCrop: draftCrop !== undefined ? draftCrop : draftCropRef.current,\n draftSelectionPath: selectionDraftRef.current,\n brushCursor:\n activeTab === 'paint' && brushCursorRef.current && controller.getState().activeTool !== 'move' && !transformTool.active\n ? { ...brushCursorRef.current, diameter: controller.getState().paint.brush.size }\n : null,\n freeTransform: transformTool.overlay(),\n textEdit: typeToolRef.current?.session?.alive ? typeToolRef.current.session.overlay() : null,\n });\n },\n [controller, activeTab, transformTool]\n );\n\n // The text being edited: re-render on every change, and end it when the tool or tab changes.\n useEffect(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);\n useEffect(() => {\n if (activeTab === 'annotate' && state.activeTool === 'type') return;\n if (typeToolRef.current?.session) {\n typeToolRef.current.finish();\n setTypeSession(null);\n void renderCanvas();\n }\n }, [activeTab, state.activeTool, renderCanvas]);\n const finishTyping = () => {\n typeToolRef.current?.finish();\n setTypeSession(null);\n void renderCanvas();\n };\n const handleTypeKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n const session = typeToolRef.current?.session;\n if (!session || e.nativeEvent.isComposing) return;\n if (e.key === 'Escape') {\n e.preventDefault();\n finishTyping();\n return;\n }\n if ((e.metaKey || e.ctrlKey) && ['z', 'y', 'c', 'x', 'v'].includes(e.key.toLowerCase())) return;\n if (session.handleKey(e)) {\n e.preventDefault();\n setShapeTypeError(session.error);\n }\n };\n const handleTypeInput = (e: React.FormEvent<HTMLTextAreaElement>) => {\n // Composed (IME) and pasted text arrives here; plain keys were handled on keydown.\n const el = e.currentTarget;\n const session = typeToolRef.current?.session;\n if (session && el.value && !(e.nativeEvent as InputEvent).isComposing) {\n session.insert(el.value);\n el.value = '';\n }\n };\n\n useEffect(() => transformTool.subscribe(() => {\n setTransformTick((n) => n + 1);\n void renderCanvas();\n }), [transformTool, renderCanvas]);\n\n /** The canvas point of a pointer event, its document point, and the screen scale. */\n const transformPoint = (e: React.PointerEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current!;\n const rect = canvas.getBoundingClientRect();\n const sx = rect.width > 0 ? canvas.width / rect.width : 1;\n const sy = rect.height > 0 ? canvas.height / rect.height : 1;\n const s = controller.getState();\n const cropping = activeTab === 'crop';\n const projection = getViewportProjection(s, canvas.width, canvas.height, cropping);\n const pt = canvasToImagePoint({ x: (e.clientX - rect.left) * sx, y: (e.clientY - rect.top) * sy }, s, canvas.width, canvas.height, cropping);\n transformTool.setView(projection.scale);\n return { pt, tolerance: 6 / (projection.scale || 1) };\n };\n const handleTransformPointerDown = (e: React.PointerEvent<HTMLCanvasElement>): boolean => {\n if (!transformTool.active) return false;\n if (e.button !== 0) return true;\n e.preventDefault();\n try {\n e.currentTarget.setPointerCapture?.(e.pointerId);\n } catch {\n // Synthetic events have no active pointer to capture.\n }\n const { pt, tolerance } = transformPoint(e);\n transformTool.down(pt, tolerance);\n return true;\n };\n const handleTransformPointerMove = (e: React.PointerEvent<HTMLCanvasElement>): boolean => {\n if (!transformTool.active) return false;\n const { pt, tolerance } = transformPoint(e);\n if (e.buttons & 1) transformTool.move(pt, e);\n else {\n const over: TransformHandle | null = transformTool.hit(pt, tolerance);\n setTransformCursor(transformTool.cursor(over));\n }\n return true;\n };\n const handleTransformPointerUp = (): boolean => {\n if (!transformTool.active) return false;\n transformTool.up();\n return true;\n };\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const onKey = (e: KeyboardEvent) => {\n if (transformTool.key(e)) e.preventDefault();\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [transformTool]);\n\n\n useEffect(() => {\n const raf =\n typeof requestAnimationFrame !== 'undefined'\n ? requestAnimationFrame\n : (cb: () => void) => setTimeout(cb, 0) as unknown as number;\n const caf =\n typeof cancelAnimationFrame !== 'undefined'\n ? cancelAnimationFrame\n : (id: number) => clearTimeout(id);\n\n const animId = raf(() => {\n renderCanvas();\n });\n return () => caf(animId);\n }, [renderCanvas, state]);\n\n // Synchronize initial tool with activeTab\n useEffect(() => {\n if (activeTab === 'crop' && editor.state.activeTool !== 'crop') {\n editor.setTool('crop');\n }\n }, [activeTab, editor]);\n\n // Container resize observer to safely adapt viewport without feedback loops\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n if (typeof ResizeObserver !== 'undefined') {\n const observer = new ResizeObserver(() => {\n renderCanvas();\n });\n observer.observe(container);\n return () => observer.disconnect();\n } else {\n const handleResize = () => renderCanvas();\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }\n }, [renderCanvas]);\n\n // Convert mouse event coordinates to internal canvas pixel space\n const getCanvasEventPoint = (e: React.MouseEvent<HTMLCanvasElement>): ImagePoint => {\n const canvas = canvasRef.current;\n if (!canvas) return { x: 0, y: 0 };\n const rect = canvas.getBoundingClientRect();\n const scaleX = rect.width > 0 ? canvas.width / rect.width : 1;\n const scaleY = rect.height > 0 ? canvas.height / rect.height : 1;\n return {\n x: (e.clientX - rect.left) * scaleX,\n y: (e.clientY - rect.top) * scaleY,\n };\n };\n\n // Paint tools: pointer events (coalesced samples, pointer capture) into strokes and moves.\n const paintSamples = (e: React.PointerEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current!;\n const native = e.nativeEvent as PointerEvent;\n const events = typeof native.getCoalescedEvents === 'function' ? native.getCoalescedEvents() : [];\n const list = events.length ? events : [native];\n const rect = canvas.getBoundingClientRect();\n const sx = rect.width > 0 ? canvas.width / rect.width : 1;\n const sy = rect.height > 0 ? canvas.height / rect.height : 1;\n const s = controller.getState();\n return list.map((ev) => ({\n ...canvasToImagePoint({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),\n pressure: pointerPressure(ev),\n }));\n };\n const handlePaintPointerDown = (e: React.PointerEvent<HTMLCanvasElement>) => {\n if (handleTransformPointerDown(e)) return;\n if (activeTab !== 'paint' || e.button !== 0) return;\n e.preventDefault();\n try {\n e.currentTarget.setPointerCapture?.(e.pointerId);\n } catch {\n // Synthetic events have no active pointer to capture.\n }\n const [first] = paintSamples(e);\n setPaintError(paintGestureRef.current!.down({ ...first, altKey: e.altKey }));\n };\n const handlePaintPointerMove = (e: React.PointerEvent<HTMLCanvasElement>) => {\n if (handleTransformPointerMove(e)) return;\n if (activeTab !== 'paint') return;\n const samples = paintSamples(e);\n brushCursorRef.current = samples[samples.length - 1] ?? null;\n if (paintGestureRef.current!.active) paintGestureRef.current!.moveTo(samples);\n else void renderCanvas();\n };\n const handlePaintPointerUp = () => {\n if (handleTransformPointerUp()) return;\n if (activeTab !== 'paint') return;\n const g = paintGestureRef.current!;\n if (g.active) {\n g.up();\n if (g.error) setPaintError(g.error);\n }\n };\n\n useEffect(() => {\n if (activeTab !== 'paint' || typeof window === 'undefined') return;\n const onKey = (e: KeyboardEvent) => {\n if (handlePaintShortcut(controller, e)) e.preventDefault();\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [activeTab, controller]);\n\n // Pointer event handlers for drawing and annotations\n const handleMouseDown = (e: React.MouseEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current;\n if (!canvas || transformTool.active) return;\n const canvasPt = getCanvasEventPoint(e);\n\n if (activeTab === 'select') {\n const gesture = selectionGestureRef.current!;\n const imgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false);\n void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));\n return;\n }\n\n if (activeTab === 'crop') {\n const activeCrop = draftCropRef.current || state.crop || {\n x: 0,\n y: 0,\n width: state.imageDimensions.width,\n height: state.imageDimensions.height,\n };\n const handle = hitTestCrop(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);\n const startImgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, true);\n\n if (handle) {\n cropDragInfoRef.current = {\n handle,\n startCanvasPt: canvasPt,\n startImgPt,\n startCrop: activeCrop,\n };\n } else {\n // Clicked outside crop box: start new crop selection\n cropDragInfoRef.current = {\n handle: 'new',\n startCanvasPt: canvasPt,\n startImgPt,\n startCrop: { x: startImgPt.x, y: startImgPt.y, width: 0, height: 0 },\n };\n }\n return;\n }\n\n if (activeTab === 'annotate' && (state.activeTool === 'shape' || state.activeTool === 'type')) {\n const imgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false);\n setShapeTypeError(null);\n if (state.activeTool === 'shape') shapeGestureRef.current!.down(imgPt);\n else {\n typeToolRef.current!.down(imgPt, { shift: e.shiftKey });\n setTypeSession(typeToolRef.current!.session);\n void renderCanvas();\n }\n return;\n }\n\n if (activeTab === 'annotate') {\n const imgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false);\n dragStartPointRef.current = imgPt;\n\n if (state.activeTool === 'select') {\n for (let i = state.annotations.length - 1; i >= 0; i--) {\n const ann = state.annotations[i];\n if (hitTestAnnotation(imgPt, ann)) {\n editor.selectAnnotation(ann.id);\n annotationDragInfoRef.current = {\n annId: ann.id,\n startImgPt: imgPt,\n initialAnn: { ...ann },\n };\n return;\n }\n }\n editor.selectAnnotation(null);\n return;\n }\n\n if (state.activeTool === 'pen') {\n isDrawingRef.current = true;\n currentPathRef.current = [imgPt];\n const draft: Annotation = {\n id: 'draft',\n type: 'pen',\n x: 0,\n y: 0,\n points: [imgPt],\n strokeColor: activeColor,\n strokeWidth,\n };\n draftAnnotationRef.current = draft;\n renderCanvas(draft);\n }\n }\n };\n\n const handleMouseMove = (e: React.MouseEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current;\n if (!canvas || transformTool.active) return;\n const canvasPt = getCanvasEventPoint(e);\n\n if (activeTab === 'select') {\n const gesture = selectionGestureRef.current!;\n if (gesture.active && gesture.move(canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false))) {\n selectionDraftRef.current = gesture.draftPath;\n renderCanvas();\n }\n return;\n }\n\n if (activeTab === 'crop') {\n const drag = cropDragInfoRef.current;\n if (drag) {\n const currentImgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, true);\n let newCrop: CropBox;\n\n if (drag.handle === 'new') {\n const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));\n const minY = Math.max(0, Math.min(drag.startImgPt.y, currentImgPt.y));\n const maxX = Math.min(state.imageDimensions.width, Math.max(drag.startImgPt.x, currentImgPt.x));\n const maxY = Math.min(state.imageDimensions.height, Math.max(drag.startImgPt.y, currentImgPt.y));\n newCrop = {\n x: Math.round(minX),\n y: Math.round(minY),\n width: Math.round(Math.max(20, maxX - minX)),\n height: Math.round(Math.max(20, maxY - minY)),\n };\n } else {\n newCrop = calculateCropDrag(\n drag.startCrop,\n drag.handle,\n drag.startImgPt,\n currentImgPt,\n state.imageDimensions.width,\n state.imageDimensions.height,\n activeCropRatio,\n state.transform\n );\n }\n\n draftCropRef.current = newCrop;\n renderCanvas(null, newCrop);\n } else {\n const activeCrop = draftCropRef.current || state.crop || {\n x: 0,\n y: 0,\n width: state.imageDimensions.width,\n height: state.imageDimensions.height,\n };\n const handle = hitTestCrop(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);\n canvas.style.cursor = getCropCursor(handle, state.transform);\n }\n return;\n }\n\n if (activeTab === 'annotate' && state.activeTool === 'shape') {\n const g = shapeGestureRef.current!;\n if (g.active) {\n g.move(canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false), { shift: e.shiftKey, alt: e.altKey });\n if (g.error) setShapeTypeError(g.error);\n }\n return;\n }\n\n if (activeTab === 'annotate') {\n // If moving selected annotation\n if (annotationDragInfoRef.current) {\n const drag = annotationDragInfoRef.current;\n const currentImgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false);\n const dx = currentImgPt.x - drag.startImgPt.x;\n const dy = currentImgPt.y - drag.startImgPt.y;\n editor.updateAnnotation(drag.annId, {\n x: Math.round(drag.initialAnn.x + dx),\n y: Math.round(drag.initialAnn.y + dy),\n });\n return;\n }\n\n const startPt = dragStartPointRef.current;\n if (!startPt) {\n // Update cursor for hover on select tool\n if (state.activeTool === 'select') {\n const imgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false);\n let hovered = false;\n for (let i = state.annotations.length - 1; i >= 0; i--) {\n if (hitTestAnnotation(imgPt, state.annotations[i])) {\n hovered = true;\n break;\n }\n }\n canvas.style.cursor = hovered ? 'move' : 'default';\n } else {\n canvas.style.cursor = 'crosshair';\n }\n return;\n }\n\n const currentImgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false);\n\n if (state.activeTool === 'pen' && isDrawingRef.current) {\n currentPathRef.current.push(currentImgPt);\n const draft: Annotation = {\n id: 'draft',\n type: 'pen',\n x: 0,\n y: 0,\n points: [...currentPathRef.current],\n strokeColor: activeColor,\n strokeWidth,\n };\n draftAnnotationRef.current = draft;\n renderCanvas(draft);\n } else if (state.activeTool === 'rect') {\n const w = currentImgPt.x - startPt.x;\n const h = currentImgPt.y - startPt.y;\n const draft: Annotation = {\n id: 'draft',\n type: 'rect',\n x: Math.min(startPt.x, currentImgPt.x),\n y: Math.min(startPt.y, currentImgPt.y),\n width: Math.abs(w),\n height: Math.abs(h),\n strokeColor: activeColor,\n strokeWidth,\n };\n draftAnnotationRef.current = draft;\n renderCanvas(draft);\n } else if (state.activeTool === 'circle') {\n const rx = Math.abs(currentImgPt.x - startPt.x) / 2;\n const ry = Math.abs(currentImgPt.y - startPt.y) / 2;\n const draft: Annotation = {\n id: 'draft',\n type: 'circle',\n x: Math.min(startPt.x, currentImgPt.x) + rx,\n y: Math.min(startPt.y, currentImgPt.y) + ry,\n radiusX: rx,\n radiusY: ry,\n strokeColor: activeColor,\n strokeWidth,\n };\n draftAnnotationRef.current = draft;\n renderCanvas(draft);\n } else if (state.activeTool === 'arrow') {\n const draft: Annotation = {\n id: 'draft',\n type: 'arrow',\n x: startPt.x,\n y: startPt.y,\n endX: currentImgPt.x,\n endY: currentImgPt.y,\n strokeColor: activeColor,\n strokeWidth,\n };\n draftAnnotationRef.current = draft;\n renderCanvas(draft);\n } else if (state.activeTool === 'line') {\n const draft: Annotation = {\n id: 'draft',\n type: 'line',\n x: startPt.x,\n y: startPt.y,\n endX: currentImgPt.x,\n endY: currentImgPt.y,\n strokeColor: activeColor,\n strokeWidth,\n };\n draftAnnotationRef.current = draft;\n renderCanvas(draft);\n }\n }\n };\n\n const handleMouseUp = (e: React.MouseEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current;\n if (!canvas || transformTool.active) return;\n const canvasPt = getCanvasEventPoint(e);\n\n if (activeTab === 'select') {\n const gesture = selectionGestureRef.current!;\n if (gesture.active) {\n gesture.end(canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false), e);\n selectionDraftRef.current = null;\n renderCanvas();\n }\n return;\n }\n\n if (activeTab === 'crop') {\n if (cropDragInfoRef.current) {\n if (\n draftCropRef.current &&\n draftCropRef.current.width >= 20 &&\n draftCropRef.current.height >= 20\n ) {\n editor.setCrop(draftCropRef.current, true);\n }\n cropDragInfoRef.current = null;\n draftCropRef.current = null;\n renderCanvas();\n }\n return;\n }\n\n if (activeTab === 'annotate' && state.activeTool === 'shape') {\n shapeGestureRef.current!.up();\n return;\n }\n if (activeTab === 'annotate' && state.activeTool === 'type') {\n const tool = typeToolRef.current!;\n tool.up(canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false));\n setTypeSession(tool.session);\n if (tool.error) setShapeTypeError(tool.error);\n void renderCanvas();\n // Keystrokes go to the hidden textarea while text is being edited.\n if (tool.session) setTimeout(() => typeInputRef.current?.focus(), 0);\n return;\n }\n\n if (activeTab === 'annotate') {\n if (annotationDragInfoRef.current) {\n annotationDragInfoRef.current = null;\n return;\n }\n\n const startPt = dragStartPointRef.current;\n if (startPt) {\n const currentImgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false);\n\n if (state.activeTool === 'pen' && isDrawingRef.current) {\n if (currentPathRef.current.length > 1) {\n editor.addAnnotation({\n type: 'pen',\n x: 0,\n y: 0,\n points: [...currentPathRef.current],\n strokeColor: activeColor,\n strokeWidth,\n });\n }\n isDrawingRef.current = false;\n currentPathRef.current = [];\n } else if (state.activeTool === 'rect') {\n const w = Math.abs(currentImgPt.x - startPt.x);\n const h = Math.abs(currentImgPt.y - startPt.y);\n if (w > 4 && h > 4) {\n editor.addAnnotation({\n type: 'rect',\n x: Math.min(startPt.x, currentImgPt.x),\n y: Math.min(startPt.y, currentImgPt.y),\n width: w,\n height: h,\n strokeColor: activeColor,\n strokeWidth,\n });\n }\n } else if (state.activeTool === 'circle') {\n const rx = Math.abs(currentImgPt.x - startPt.x) / 2;\n const ry = Math.abs(currentImgPt.y - startPt.y) / 2;\n if (rx > 4 && ry > 4) {\n editor.addAnnotation({\n type: 'circle',\n x: Math.min(startPt.x, currentImgPt.x) + rx,\n y: Math.min(startPt.y, currentImgPt.y) + ry,\n radiusX: rx,\n radiusY: ry,\n strokeColor: activeColor,\n strokeWidth,\n });\n }\n } else if (state.activeTool === 'arrow') {\n if (Math.hypot(currentImgPt.x - startPt.x, currentImgPt.y - startPt.y) > 4) {\n editor.addAnnotation({\n type: 'arrow',\n x: startPt.x,\n y: startPt.y,\n endX: currentImgPt.x,\n endY: currentImgPt.y,\n strokeColor: activeColor,\n strokeWidth,\n });\n }\n } else if (state.activeTool === 'line') {\n if (Math.hypot(currentImgPt.x - startPt.x, currentImgPt.y - startPt.y) > 4) {\n editor.addAnnotation({\n type: 'line',\n x: startPt.x,\n y: startPt.y,\n endX: currentImgPt.x,\n endY: currentImgPt.y,\n strokeColor: activeColor,\n strokeWidth,\n });\n }\n }\n\n draftAnnotationRef.current = null;\n dragStartPointRef.current = null;\n renderCanvas();\n }\n }\n };\n\n const handleAddText = () => {\n if (!textInput.trim()) return;\n editor.addAnnotation({\n type: 'text',\n x: 50,\n y: 50,\n text: textInput.trim(),\n fontSize,\n color: activeColor,\n });\n setTextInput('');\n };\n\n const handleExport = async () => {\n const dataUrl = await editor.toDataURL(exportOptions);\n if (onSave) {\n onSave(dataUrl);\n } else {\n // Default download trigger\n const link = document.createElement('a');\n link.download = `edited-image-${Date.now()}.png`;\n link.href = dataUrl;\n link.click();\n }\n };\n\n return (\n <div\n className={`flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`}\n style={style}\n >\n {/* Top Action Header */}\n <div className=\"flex flex-wrap items-center justify-between px-4 py-3 bg-slate-950/80 border-b border-slate-800 gap-3\">\n {/* Navigation Tabs */}\n <div className=\"flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs\">\n <button\n type=\"button\"\n onClick={() => {\n setActiveTab('crop');\n editor.setTool('crop');\n }}\n className={`px-3 py-1.5 rounded-md font-medium transition-colors ${\n activeTab === 'crop' ? 'bg-indigo-600 text-white shadow' : 'text-slate-400 hover:text-slate-200'\n }`}\n >\n Transform & Crop\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveTab('adjust');\n editor.setTool('select');\n }}\n className={`px-3 py-1.5 rounded-md font-medium transition-colors ${\n activeTab === 'adjust' ? 'bg-indigo-600 text-white shadow' : 'text-slate-400 hover:text-slate-200'\n }`}\n >\n Adjustments\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveTab('layers');\n editor.setTool('select');\n }}\n className={`px-3 py-1.5 rounded-md font-medium transition-colors ${\n activeTab === 'layers' ? 'bg-indigo-600 text-white shadow' : 'text-slate-400 hover:text-slate-200'\n }`}\n >\n Layers\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveTab('paint');\n editor.setTool('brush');\n }}\n className={`px-3 py-1.5 rounded-md font-medium transition-colors ${\n activeTab === 'paint' ? 'bg-indigo-600 text-white shadow' : 'text-slate-400 hover:text-slate-200'\n }`}\n >\n Paint\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveTab('select');\n editor.setTool('select');\n }}\n className={`px-3 py-1.5 rounded-md font-medium transition-colors ${\n activeTab === 'select' ? 'bg-indigo-600 text-white shadow' : 'text-slate-400 hover:text-slate-200'\n }`}\n >\n Select & Mask\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveTab('annotate');\n editor.setTool('pen');\n }}\n className={`px-3 py-1.5 rounded-md font-medium transition-colors ${\n activeTab === 'annotate' ? 'bg-indigo-600 text-white shadow' : 'text-slate-400 hover:text-slate-200'\n }`}\n >\n Annotations\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveTab('depth');\n editor.setTool('select');\n }}\n className={`px-3 py-1.5 rounded-md font-medium transition-colors ${\n activeTab === 'depth' ? 'bg-indigo-600 text-white shadow' : 'text-slate-400 hover:text-slate-200'\n }`}\n >\n Depth Mask\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveTab('ai');\n editor.setTool('select');\n }}\n className={`px-3 py-1.5 rounded-md font-medium transition-colors flex items-center gap-1.5 ${\n activeTab === 'ai' ? 'bg-indigo-600 text-white shadow' : 'text-slate-400 hover:text-slate-200'\n }`}\n >\n <svg className=\"w-3.5 h-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83\" />\n </svg>\n AI Tools\n </button>\n </div>\n\n {/* Global Action Tools (Undo/Redo, Zoom, Compare, Save) */}\n <div className=\"flex items-center gap-2 text-xs\">\n <button\n type=\"button\"\n disabled={!editor.canUndo}\n onClick={() => editor.undo()}\n className=\"p-1.5 rounded-lg border border-slate-800 bg-slate-900 text-slate-300 disabled:opacity-40 disabled:cursor-not-allowed hover:bg-slate-800\"\n title=\"Undo\"\n >\n ↩\n </button>\n <button\n type=\"button\"\n disabled={!editor.canRedo}\n onClick={() => editor.redo()}\n className=\"p-1.5 rounded-lg border border-slate-800 bg-slate-900 text-slate-300 disabled:opacity-40 disabled:cursor-not-allowed hover:bg-slate-800\"\n title=\"Redo\"\n >\n ↪\n </button>\n <button\n type=\"button\"\n onClick={() => editor.reset()}\n className=\"px-2 py-1.5 rounded-lg border border-slate-800 bg-slate-900 text-slate-400 hover:text-slate-200 hover:bg-slate-800\"\n >\n Reset\n </button>\n\n <div className=\"h-4 w-px bg-slate-800 mx-1\" />\n\n {/* Zoom */}\n <button\n type=\"button\"\n onClick={() => editor.zoomOut()}\n className=\"p-1.5 rounded-lg border border-slate-800 bg-slate-900 text-slate-300 hover:bg-slate-800\"\n title=\"Zoom Out\"\n >\n -\n </button>\n <span className=\"font-mono text-slate-400 w-10 text-center\">{Math.round(state.zoom * 100)}%</span>\n <button\n type=\"button\"\n onClick={() => editor.zoomIn()}\n className=\"p-1.5 rounded-lg border border-slate-800 bg-slate-900 text-slate-300 hover:bg-slate-800\"\n title=\"Zoom In\"\n >\n +\n </button>\n\n <div className=\"h-4 w-px bg-slate-800 mx-1\" />\n\n {/* Live Compare */}\n <button\n type=\"button\"\n onMouseDown={() => editor.setComparing(true)}\n onMouseUp={() => editor.setComparing(false)}\n onMouseLeave={() => editor.setComparing(false)}\n className=\"px-2.5 py-1.5 rounded-lg border border-slate-800 bg-slate-900 text-amber-400 hover:bg-slate-800 select-none active:bg-amber-950/40\"\n >\n Hold Compare\n </button>\n\n {/* Save / Export */}\n <button\n type=\"button\"\n onClick={handleExport}\n className=\"px-4 py-1.5 rounded-lg bg-emerald-600 hover:bg-emerald-500 text-white font-medium shadow-md shadow-emerald-900/30 transition-colors\"\n >\n Export Image\n </button>\n </div>\n </div>\n\n {/* Free Transform options bar (Ctrl/Cmd+T), above the viewport while a transform is open */}\n {transformTool.active && <FreeTransformOptionsBar tool={transformTool} className=\"border-b border-slate-800 bg-slate-900/95 px-4 py-2\" />}\n {!transformTool.active && transformTool.error && (\n <div role=\"alert\" className=\"border-b border-rose-900 bg-rose-950/80 px-4 py-1.5 text-xs text-rose-200\">\n {transformTool.error}\n </div>\n )}\n\n {/* Main Viewport + Sidebar Layout */}\n <div className=\"flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]\">\n {/* Canvas Area */}\n <div\n ref={containerRef}\n className=\"relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none\"\n >\n <canvas\n ref={canvasRef}\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n onPointerDown={handlePaintPointerDown}\n onPointerMove={handlePaintPointerMove}\n onPointerUp={handlePaintPointerUp}\n onPointerCancel={() => paintGestureRef.current?.cancel()}\n data-testid=\"image-editor-canvas\"\n style={transformTool.active ? { cursor: transformCursor } : undefined}\n className={`absolute inset-0 w-full h-full block ${transformTool.active ? 'touch-none' : activeTab === 'paint' ? 'touch-none cursor-crosshair' : activeTab === 'annotate' && state.activeTool === 'type' ? 'cursor-text' : activeTab === 'annotate' && state.activeTool === 'shape' ? 'cursor-crosshair' : ''}`}\n />\n {typeSession && (\n <textarea\n ref={typeInputRef}\n aria-label=\"Edit text\"\n data-testid=\"type-input\"\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n onKeyDown={handleTypeKeyDown}\n onInput={handleTypeInput}\n onCompositionEnd={(e) => {\n const session = typeToolRef.current?.session;\n if (session && e.data) session.insert(e.data);\n e.currentTarget.value = '';\n }}\n className=\"absolute left-0 top-0 h-px w-px opacity-0\"\n />\n )}\n\n </div>\n\n {/* Tab Controls Sidebar */}\n <div className=\"w-full md:w-80 bg-slate-900/90 border-t md:border-t-0 md:border-l border-slate-800 p-4 overflow-y-auto h-auto md:h-full md:max-h-[560px]\">\n {/* TAB 1: CROP & TRANSFORM */}\n {activeTab === 'crop' && (\n <div className=\"flex flex-col gap-4 text-xs\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">\n Aspect Ratio Presets\n </span>\n <div className=\"grid grid-cols-3 gap-2\">\n <button\n type=\"button\"\n onClick={() => {\n setActiveCropRatio(null);\n editor.applyCropPreset(null);\n }}\n className={`px-2.5 py-2 rounded-lg border font-medium ${\n activeCropRatio === null && state.crop\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 hover:bg-slate-700 text-slate-200 border-slate-700'\n }`}\n >\n Freeform\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveCropRatio(1);\n editor.applyCropPreset(1);\n }}\n className={`px-2.5 py-2 rounded-lg border font-medium ${\n activeCropRatio === 1\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 hover:bg-slate-700 text-slate-200 border-slate-700'\n }`}\n >\n 1:1 Square\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveCropRatio(4 / 3);\n editor.applyCropPreset(4 / 3);\n }}\n className={`px-2.5 py-2 rounded-lg border font-medium ${\n activeCropRatio === 4 / 3\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 hover:bg-slate-700 text-slate-200 border-slate-700'\n }`}\n >\n 4:3 Standard\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveCropRatio(16 / 9);\n editor.applyCropPreset(16 / 9);\n }}\n className={`px-2.5 py-2 rounded-lg border font-medium ${\n activeCropRatio === 16 / 9\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 hover:bg-slate-700 text-slate-200 border-slate-700'\n }`}\n >\n 16:9 Wide\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveCropRatio(3 / 2);\n editor.applyCropPreset(3 / 2);\n }}\n className={`px-2.5 py-2 rounded-lg border font-medium ${\n activeCropRatio === 3 / 2\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 hover:bg-slate-700 text-slate-200 border-slate-700'\n }`}\n >\n 3:2 Photo\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveCropRatio(null);\n editor.resetCrop();\n }}\n className=\"px-2.5 py-2 rounded-lg bg-rose-950/40 hover:bg-rose-900/60 text-rose-300 border border-rose-800/40 font-medium\"\n >\n Clear Crop\n </button>\n </div>\n\n <div className=\"h-px bg-slate-800 my-1\" />\n\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">\n Orientation & Flips\n </span>\n <div className=\"grid grid-cols-2 gap-2\">\n <button\n type=\"button\"\n onClick={() => editor.rotate(-90)}\n className=\"px-3 py-2 rounded-lg bg-slate-800 hover:bg-slate-700 text-slate-200 border border-slate-700\"\n >\n Rotate -90°\n </button>\n <button\n type=\"button\"\n onClick={() => editor.rotate(90)}\n className=\"px-3 py-2 rounded-lg bg-slate-800 hover:bg-slate-700 text-slate-200 border border-slate-700\"\n >\n Rotate +90°\n </button>\n <button\n type=\"button\"\n onClick={() => editor.flipHorizontal()}\n className={`px-3 py-2 rounded-lg border transition-colors ${\n state.transform.flipH\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 border-slate-700 text-slate-200 hover:bg-slate-700'\n }`}\n >\n Flip Horizontal\n </button>\n <button\n type=\"button\"\n onClick={() => editor.flipVertical()}\n className={`px-3 py-2 rounded-lg border transition-colors ${\n state.transform.flipV\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 border-slate-700 text-slate-200 hover:bg-slate-700'\n }`}\n >\n Flip Vertical\n </button>\n </div>\n </div>\n )}\n\n {/* TAB 2: ADJUSTMENTS */}\n {activeTab === 'adjust' && (\n <div className=\"flex flex-col gap-3 text-xs\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">\n Color Adjustments\n </span>\n <button\n type=\"button\"\n onClick={() => editor.resetAdjustments()}\n className=\"text-[10px] text-rose-400 hover:underline\"\n >\n Reset Sliders\n </button>\n </div>\n\n <Histogram histogram={editor.histogram} />\n\n {IMAGE_ADJUSTMENT_CONTROLS.map((spec) => (\n <React.Fragment key={spec.id}>\n <ControlSlider\n spec={spec}\n value={readAdjustmentControls(state.adjustments)[spec.id]}\n disabled={spec.requiresProcess !== undefined && legacyProcess}\n onChange={(v) => editor.setAdjustments({ [spec.id]: v })}\n />\n {spec.id === 'tint' && legacyProcess && (\n <div\n className=\"flex items-center justify-between gap-2 rounded border border-amber-500/30 bg-amber-500/10 px-2 py-1.5 text-[10px] text-amber-200\"\n data-testid=\"image-editor-process-notice\"\n >\n <span>Legacy rendering (process 1). Tint needs the current process.</span>\n <button\n type=\"button\"\n onClick={() => editor.upgradeProcess()}\n className=\"shrink-0 rounded bg-amber-500/20 px-2 py-0.5 hover:bg-amber-500/30\"\n >\n Update\n </button>\n </div>\n )}\n </React.Fragment>\n ))}\n\n <div className=\"border-t border-slate-700/60 pt-3\">\n <AdjustmentLayersPanel\n controller={controller}\n layers={state.adjustments.layers}\n histogram={editor.histogram}\n />\n </div>\n </div>\n )}\n\n {/* TAB: LAYERS */}\n {activeTab === 'layers' && (\n <div className=\"flex flex-col gap-3 text-xs\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">Layers</span>\n <button\n type=\"button\"\n title=\"Edit › Free Transform (Ctrl/Cmd+T): the selected pixels, or the whole active layer\"\n className=\"px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40\"\n disabled={transformTool.active}\n onClick={() => transformTool.begin()}\n >\n Free Transform\n </button>\n <LayersPanel controller={controller} />\n {effectsShown && <ImageProviderEffectsPanel controller={controller} className=\"border-t border-slate-700/60 pt-3\" />}\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">Colour</span>\n <ColorProfilePanel controller={controller} />\n </div>\n )}\n\n {/* TAB: PAINT */}\n {activeTab === 'paint' && (\n <div className=\"flex flex-col gap-3 text-xs\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">Paint</span>\n <BrushOptionsBar controller={controller} />\n <button\n type=\"button\"\n title=\"Edit › Free Transform (Ctrl/Cmd+T): the selected pixels, or the whole active layer\"\n className=\"px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start\"\n disabled={transformTool.active}\n onClick={() => transformTool.begin()}\n >\n Free Transform\n </button>\n {paintError && (\n <p role=\"alert\" className=\"text-rose-400\" data-testid=\"paint-error\">\n {paintError}\n </p>\n )}\n <div className=\"border-t border-slate-700/60 pt-3\">\n <LayersPanel controller={controller} />\n </div>\n </div>\n )}\n\n {/* TAB 3: ANNOTATIONS */}\n {activeTab === 'annotate' && (\n <div className=\"flex flex-col gap-3 text-xs\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">Shape & Type Layers</span>\n <div className=\"grid grid-cols-2 gap-1.5\">\n {(['shape', 'type'] as ImageEditorTool[]).map((t) => (\n <button\n key={t}\n type=\"button\"\n aria-pressed={state.activeTool === t}\n onClick={() => editor.setTool(t)}\n className={`py-1.5 px-2 rounded-lg font-medium border transition-colors ${\n state.activeTool === t ? 'bg-indigo-600 border-indigo-500 text-white' : 'bg-slate-800 border-slate-700 text-slate-300 hover:bg-slate-700'\n }`}\n >\n {t === 'shape' ? 'Shape' : 'Type'}\n </button>\n ))}\n </div>\n {state.activeTool === 'shape' && <ShapeOptionsBar controller={controller} options={shapeOptions} onChange={setShapeOptions} />}\n {state.activeTool === 'type' && (\n <TypeOptionsBar controller={controller} options={typeOptions} onChange={setTypeOptions} session={typeSession} />\n )}\n {state.activeTool === 'type' && typeSession && (\n <button type=\"button\" onClick={finishTyping} className=\"self-start rounded bg-slate-800 px-2 py-1 text-[11px] text-slate-200 hover:bg-slate-700\">\n Done editing text\n </button>\n )}\n {shapeTypeError && (\n <p role=\"alert\" className=\"text-rose-400\" data-testid=\"shape-type-error\">\n {shapeTypeError}\n </p>\n )}\n <div className=\"h-px bg-slate-800 my-1\" />\n\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">\n Draw & Annotate\n </span>\n\n {/* Tool Picker */}\n <div className=\"grid grid-cols-3 gap-1.5\">\n {(['pen', 'rect', 'circle', 'arrow', 'line'] as ImageEditorTool[]).map((t) => (\n <button\n key={t}\n type=\"button\"\n onClick={() => editor.setTool(t)}\n className={`py-1.5 px-2 rounded-lg font-medium capitalize border transition-colors ${\n state.activeTool === t\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 border-slate-700 text-slate-300 hover:bg-slate-700'\n }`}\n >\n {t}\n </button>\n ))}\n </div>\n\n {/* Color & Size */}\n <div className=\"flex items-center gap-2 mt-2\">\n <label className=\"text-slate-400\">Color:</label>\n <input\n type=\"color\"\n value={activeColor}\n onChange={(e) => setActiveColor(e.target.value)}\n className=\"w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent\"\n />\n <div className=\"flex-1 ml-2\">\n <div className=\"flex justify-between text-slate-400 mb-0.5\">\n <span>Width:</span>\n <span className=\"font-mono\">{strokeWidth}px</span>\n </div>\n <input\n type=\"range\"\n min=\"1\"\n max=\"20\"\n value={strokeWidth}\n onChange={(e) => setStrokeWidth(Number(e.target.value))}\n className=\"w-full accent-indigo-500\"\n />\n </div>\n </div>\n\n <div className=\"h-px bg-slate-800 my-1\" />\n\n {/* Text Tool */}\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">Add Text</span>\n <div className=\"flex gap-2\">\n <input\n type=\"text\"\n placeholder=\"Type watermark or label...\"\n value={textInput}\n onChange={(e) => setTextInput(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && handleAddText()}\n className=\"flex-1 bg-slate-950 border border-slate-700 rounded-lg px-2.5 py-1.5 text-xs text-slate-100 placeholder-slate-500 focus:outline-none focus:border-indigo-500\"\n />\n <button\n type=\"button\"\n onClick={handleAddText}\n className=\"px-3 py-1.5 rounded-lg bg-indigo-600 hover:bg-indigo-500 text-white font-medium shadow\"\n >\n Add\n </button>\n </div>\n <div className=\"flex items-center justify-between text-slate-400\">\n <span>Font Size:</span>\n <span className=\"font-mono\">{fontSize}px</span>\n </div>\n <input\n type=\"range\"\n min=\"12\"\n max=\"72\"\n value={fontSize}\n onChange={(e) => setFontSize(Number(e.target.value))}\n className=\"w-full accent-indigo-500\"\n />\n\n {/* Layers & Selected Annotation */}\n <div className=\"h-px bg-slate-800 my-1\" />\n <div className=\"flex items-center justify-between\">\n <span className=\"text-slate-400\">Layers ({state.annotations.length})</span>\n {state.selectedAnnotationId && (\n <button\n type=\"button\"\n onClick={() => editor.removeAnnotation(state.selectedAnnotationId!)}\n className=\"text-rose-400 hover:underline text-[11px]\"\n >\n Delete Selected\n </button>\n )}\n {state.annotations.length > 0 && (\n <button\n type=\"button\"\n onClick={() => editor.clearAnnotations()}\n className=\"text-slate-400 hover:text-slate-200 text-[11px]\"\n >\n Clear All\n </button>\n )}\n </div>\n </div>\n )}\n\n {/* TAB 4: GLEAMFORGE DEPTH MASKING */}\n {activeTab === 'depth' && (\n <div className=\"flex flex-col gap-3 text-xs\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">\n Depth Masking\n </span>\n <button\n type=\"button\"\n onClick={() => editor.resetDepthMask()}\n className=\"text-[10px] text-rose-400 hover:underline\"\n >\n Reset Mask\n </button>\n </div>\n\n <label className=\"flex items-center gap-2 cursor-pointer text-slate-300\">\n <input\n type=\"checkbox\"\n checked={state.depthMask.enabled}\n onChange={(e) => editor.setDepthMask({ enabled: e.target.checked })}\n className=\"rounded accent-indigo-500\"\n />\n <span>Enable Depth / Alpha Mask</span>\n </label>\n\n {state.depthMask.enabled && (\n <>\n <div>\n <label className=\"text-slate-400 block mb-1\">Mask Image URL:</label>\n <input\n type=\"text\"\n placeholder=\"https://.../depthmap.png\"\n value={state.depthMask.maskSource || ''}\n onChange={(e) => editor.setDepthMask({ maskSource: e.target.value || null })}\n className=\"w-full bg-slate-950 border border-slate-700 rounded-lg px-2.5 py-1.5 text-xs text-slate-100 placeholder-slate-500\"\n />\n </div>\n\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={() => editor.setDepthMask({ mode: 'threshold' })}\n className={`flex-1 py-1.5 rounded-lg border text-xs font-medium ${\n state.depthMask.mode === 'threshold'\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 border-slate-700 text-slate-300'\n }`}\n >\n Threshold Mode\n </button>\n <button\n type=\"button\"\n onClick={() => editor.setDepthMask({ mode: 'brightness' })}\n className={`flex-1 py-1.5 rounded-lg border text-xs font-medium ${\n state.depthMask.mode === 'brightness'\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 border-slate-700 text-slate-300'\n }`}\n >\n Brightness Mode\n </button>\n </div>\n\n <div>\n <div className=\"flex justify-between text-slate-400 mb-1\">\n <span>Depth Start (Lower):</span>\n <span className=\"font-mono\">{state.depthMask.depthRange[0]}</span>\n </div>\n <input\n type=\"range\"\n min=\"0\"\n max=\"255\"\n value={state.depthMask.depthRange[0]}\n onChange={(e) =>\n editor.setDepthMask({\n depthRange: [Number(e.target.value), state.depthMask.depthRange[1]],\n })\n }\n className=\"w-full accent-indigo-500\"\n />\n </div>\n\n <div>\n <div className=\"flex justify-between text-slate-400 mb-1\">\n <span>Depth Stop (Upper):</span>\n <span className=\"font-mono\">{state.depthMask.depthRange[1]}</span>\n </div>\n <input\n type=\"range\"\n min=\"0\"\n max=\"255\"\n value={state.depthMask.depthRange[1]}\n onChange={(e) =>\n editor.setDepthMask({\n depthRange: [state.depthMask.depthRange[0], Number(e.target.value)],\n })\n }\n className=\"w-full accent-indigo-500\"\n />\n </div>\n\n <div>\n <div className=\"flex justify-between text-slate-400 mb-1\">\n <span>Softness:</span>\n <span className=\"font-mono\">{state.depthMask.softness}</span>\n </div>\n <input\n type=\"range\"\n min=\"1\"\n max=\"50\"\n value={state.depthMask.softness}\n onChange={(e) => editor.setDepthMask({ softness: Number(e.target.value) })}\n className=\"w-full accent-indigo-500\"\n />\n </div>\n\n <label className=\"flex items-center gap-2 cursor-pointer text-slate-300 mt-1\">\n <input\n type=\"checkbox\"\n checked={state.depthMask.invert}\n onChange={(e) => editor.setDepthMask({ invert: e.target.checked })}\n className=\"rounded accent-indigo-500\"\n />\n <span>Invert Mask</span>\n </label>\n </>\n )}\n </div>\n )}\n\n {/* SELECT & MASK: selection tools, refine edge, layer masks */}\n {activeTab === 'select' && (\n <div className=\"flex flex-col gap-4 text-xs\">\n <SelectionOptionsBar\n controller={controller}\n options={selectionOptions}\n onOptionsChange={setSelectionOptions}\n selection={state.selection ?? null}\n quickMask={Boolean(state.quickMask)}\n />\n {selectionError && (\n <p role=\"alert\" className=\"text-rose-400\">\n {selectionError}\n </p>\n )}\n <div className=\"flex gap-1\">\n <button\n type=\"button\"\n title=\"Select › Transform Selection: the outline only\"\n className=\"px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40\"\n disabled={transformTool.active}\n onClick={() => transformTool.begin({ content: 'selection-outline' })}\n >\n Transform Selection\n </button>\n <button\n type=\"button\"\n title=\"Edit › Free Transform: the selected pixels of the active layer\"\n className=\"px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40\"\n disabled={transformTool.active}\n onClick={() => transformTool.begin({ content: 'selection' })}\n >\n Free Transform Pixels\n </button>\n </div>\n <RefineEdgePanel controller={controller} selection={state.selection ?? null} layers={state.adjustments.layers} />\n </div>\n )}\n\n {/* TAB 5: AI TOOLS / INPAINTING & BACKGROUND REMOVAL */}\n {activeTab === 'ai' && (\n <div className=\"flex flex-col gap-4 text-xs\">\n <label className=\"flex items-center justify-between gap-2 text-slate-300\">\n <span>Results go to</span>\n <select\n aria-label=\"AI result target\"\n value={aiTarget}\n onChange={(e) => setAiTarget(e.target.value as typeof aiTarget)}\n className=\"bg-slate-800 border border-slate-700 rounded px-1.5 py-1\"\n >\n <option value=\"auto\">{controller.isMultiLayer ? 'Auto (new layer)' : 'Auto (replace image)'}</option>\n <option value=\"new-layer\">New layer / mask</option>\n <option value=\"replace\">Replace image</option>\n </select>\n </label>\n {/* Background Removal Section */}\n <div className=\"p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5\">\n <svg className=\"w-3.5 h-3.5 text-indigo-400\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M6 3v12M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6z\" />\n </svg>\n Background Removal\n </span>\n {isRemovingBg && (\n <span className=\"inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-indigo-900/60 text-indigo-300 animate-pulse\">\n Removing...\n </span>\n )}\n </div>\n\n <p className=\"text-slate-400 text-[11px] leading-relaxed\">\n Isolate foreground subject with AI alpha transparency segmentation.\n </p>\n\n <button\n type=\"button\"\n onClick={handleRemoveBackground}\n disabled={isRemovingBg || isInpainting}\n className=\"mt-1 px-3 py-2 rounded-lg bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 text-white font-medium shadow transition-colors flex items-center justify-center gap-2\"\n >\n {isRemovingBg ? (\n <>\n <div className=\"w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin\" />\n Removing Background...\n </>\n ) : (\n <>\n <svg className=\"w-3.5 h-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83\" />\n </svg>\n Remove Background\n </>\n )}\n </button>\n </div>\n\n {/* AI Inpainting / Generative Fill Section */}\n <div className=\"p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5\">\n <svg className=\"w-3.5 h-3.5 text-purple-400\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"m21.64 3.64-1.28-1.28a1.2 1.2 0 0 0-1.7 0l-9.72 9.72-1.94 4.86 4.86-1.94 9.72-9.72a1.2 1.2 0 0 0 .06-1.64z\" />\n <path d=\"m14 7 3 3\" />\n </svg>\n Generative Inpainting\n </span>\n {isInpainting && (\n <span className=\"inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-purple-900/60 text-purple-300 animate-pulse\">\n Inpainting...\n </span>\n )}\n </div>\n\n <p className=\"text-slate-400 text-[11px] leading-relaxed\">\n Replace, modify, or fill selected regions using prompt-guided generative inpainting.\n </p>\n\n <div className=\"flex flex-col gap-1\">\n <label htmlFor=\"ai-inpaint-prompt-react\" className=\"text-slate-300 text-[11px] font-medium\">Prompt</label>\n <textarea\n id=\"ai-inpaint-prompt-react\"\n value={inpaintPrompt}\n onChange={(e) => setInpaintPrompt(e.target.value)}\n placeholder=\"e.g. replace sunglasses with steampunk goggles, remove person in background...\"\n rows={3}\n className=\"w-full bg-slate-900 border border-slate-700 rounded-lg p-2 text-xs text-slate-100 placeholder-slate-500 focus:outline-none focus:border-indigo-500 resize-none\"\n />\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-slate-300 text-[11px] font-medium\">Target Mask Region</span>\n <div className=\"grid grid-cols-2 gap-1.5\">\n <button\n type=\"button\"\n onClick={() => setInpaintMaskMode('annotations')}\n className={`px-2 py-1.5 rounded border text-[11px] font-medium text-left transition-colors ${\n inpaintMaskMode === 'annotations'\n ? 'bg-purple-600/30 border-purple-500 text-purple-200'\n : 'bg-slate-900 border-slate-700 text-slate-400 hover:text-slate-200'\n }`}\n >\n Drawn Shapes ({state.annotations.length})\n </button>\n <button\n type=\"button\"\n onClick={() => setInpaintMaskMode('crop')}\n className={`px-2 py-1.5 rounded border text-[11px] font-medium text-left transition-colors ${\n inpaintMaskMode === 'crop'\n ? 'bg-purple-600/30 border-purple-500 text-purple-200'\n : 'bg-slate-900 border-slate-700 text-slate-400 hover:text-slate-200'\n }`}\n >\n Crop Box ({state.crop ? 'Selected' : 'Full'})\n </button>\n </div>\n </div>\n\n <button\n type=\"button\"\n onClick={handleInpaint}\n disabled={isInpainting || isRemovingBg || !inpaintPrompt.trim()}\n className=\"mt-1 px-3 py-2 rounded-lg bg-purple-600 hover:bg-purple-500 disabled:opacity-50 text-white font-medium shadow transition-colors flex items-center justify-center gap-2\"\n >\n {isInpainting ? (\n <>\n <div className=\"w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin\" />\n Generating Inpaint...\n </>\n ) : (\n <>\n <svg className=\"w-3.5 h-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83\" />\n </svg>\n Apply Inpainting\n </>\n )}\n </button>\n </div>\n\n {aiError && (\n <div className=\"p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]\">\n {aiError}\n </div>\n )}\n\n {aiSuccess && (\n <div className=\"p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]\">\n {aiSuccess}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n};\n","import React from 'react';\nimport type { ControlSpec } from '@pixerate/editor/image-editor';\nimport { controlTrackBackground, formatControlValue } from '@pixerate/editor/image-editor';\n\nexport interface ControlSliderProps {\n spec: ControlSpec;\n value: number;\n onChange: (value: number) => void;\n disabled?: boolean;\n /** Overrides `spec.label` (also the accessible name). */\n label?: string;\n}\n\n/** A labelled range input described by a control-table entry. */\nexport const ControlSlider: React.FC<ControlSliderProps> = ({ spec, value, onChange, disabled, label }) => {\n const name = label ?? spec.label;\n const track = controlTrackBackground(spec);\n return (\n <div data-control-id={spec.id}>\n <div className=\"flex justify-between text-slate-400 mb-1\">\n <span>{name}</span>\n <span className=\"font-mono\">{formatControlValue(spec, value)}</span>\n </div>\n <input\n type=\"range\"\n min={spec.min}\n max={spec.max}\n step={spec.step}\n aria-label={name}\n disabled={disabled}\n value={value}\n onChange={(e) => onChange(Number(e.target.value))}\n className=\"w-full accent-indigo-500 disabled:opacity-40\"\n />\n {track && <div className=\"h-0.5 rounded-full opacity-70\" style={{ background: track }} />}\n </div>\n );\n};\n","import React, { useEffect, useMemo, useState } from 'react';\nimport type { ImageEditorController, ImageHistogram } from '@pixerate/editor/image-editor';\nimport { histogramPath } from '@pixerate/editor/image-editor';\n\nexport interface HistogramProps {\n histogram: ImageHistogram | null;\n /** `rgb` overlays the three channels on the luminance; a single channel draws just that one. */\n channel?: 'rgb' | 'luminance' | 'red' | 'green' | 'blue';\n height?: number;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst FILL: Record<'luminance' | 'red' | 'green' | 'blue', string> = {\n luminance: 'rgba(148, 163, 184, 0.45)',\n red: 'rgba(239, 68, 68, 0.45)',\n green: 'rgba(34, 197, 94, 0.45)',\n blue: 'rgba(59, 130, 246, 0.45)',\n};\n\nconst W = 256;\n\n/** SVG histogram of an image (see `computeHistogram` / `controller.subscribeHistogram`). */\nexport const Histogram: React.FC<HistogramProps> = ({ histogram, channel = 'rgb', height = 64, className = '', style }) => {\n const channels = channel === 'rgb' ? (['luminance', 'red', 'green', 'blue'] as const) : ([channel] as const);\n const paths = useMemo(\n () => (histogram && histogram.samples > 0 ? channels.map((c) => ({ c, d: histogramPath(histogram, c, W, height) })) : []),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [histogram, channel, height]\n );\n const clipLow = histogram && histogram.samples ? Math.max(...histogram.shadows) / histogram.samples : 0;\n const clipHigh = histogram && histogram.samples ? Math.max(...histogram.highlights) / histogram.samples : 0;\n return (\n <svg\n viewBox={`0 0 ${W} ${height}`}\n preserveAspectRatio=\"none\"\n role=\"img\"\n aria-label={histogram ? `Histogram of ${histogram.samples} pixels` : 'Histogram (no data)'}\n data-testid=\"image-editor-histogram\"\n className={`w-full rounded bg-slate-950/60 ${className}`}\n style={{ height, ...style }}\n >\n {paths.map(({ c, d }) => (\n <path key={c} d={d} fill={FILL[c]} stroke=\"none\" />\n ))}\n {clipLow > 0.005 && <rect x={0} y={0} width={3} height={height} fill=\"#3b82f6\" data-testid=\"histogram-clip-shadows\" />}\n {clipHigh > 0.005 && <rect x={W - 3} y={0} width={3} height={height} fill=\"#ef4444\" data-testid=\"histogram-clip-highlights\" />}\n </svg>\n );\n};\n\n/** The preview histogram of an image editor, updated after every render. */\nexport function useImageHistogram(controller: ImageEditorController): ImageHistogram | null {\n const [histogram, setHistogram] = useState<ImageHistogram | null>(() => controller.getHistogram());\n useEffect(() => controller.subscribeHistogram(setHistogram), [controller]);\n return histogram;\n}\n","import React, { useEffect, useState } from 'react';\nimport type {\n AdjustmentKind,\n AdjustmentLayer,\n BlendMode,\n ControlSpec,\n CurvePoint,\n ImageEditorController,\n ImageHistogram,\n} from '@pixerate/editor/image-editor';\nimport {\n ADJUSTMENT_KINDS,\n ADJUSTMENT_LAYER_CONTROLS,\n ADJUSTMENT_LAYER_OPACITY_CONTROL,\n BLEND_MODES,\n HUE_RANGE_LABELS,\n adjustmentKindLabel,\n getControlPath,\n hueRangeWeight,\n setControlPath,\n} from '@pixerate/editor/image-editor';\nimport { ControlSlider } from './ControlSlider';\nimport { CurvesEditor } from './CurvesEditor';\n\nexport interface AdjustmentLayersPanelProps {\n controller: ImageEditorController;\n /** The current layers (`state.adjustments.layers`), bottom to top. Omit to follow the controller. */\n layers?: AdjustmentLayer[];\n histogram?: ImageHistogram | null;\n}\n\ntype Channel = 'master' | 'red' | 'green' | 'blue';\nconst CHANNELS: { id: Channel; label: string }[] = [\n { id: 'master', label: 'RGB' },\n { id: 'red', label: 'Red' },\n { id: 'green', label: 'Green' },\n { id: 'blue', label: 'Blue' },\n];\nconst TONES = [\n { id: 'shadows', label: 'Shadows' },\n { id: 'midtones', label: 'Midtones' },\n { id: 'highlights', label: 'Highlights' },\n] as const;\n\nconst selectClass = 'bg-slate-800 border border-slate-700 rounded px-1.5 py-1 text-slate-200';\nconst chipClass = (on: boolean) =>\n `px-2 py-0.5 rounded text-[10px] ${on ? 'bg-indigo-600 text-white' : 'bg-slate-800 text-slate-400 hover:text-slate-200'}`;\n\n/** Hue strip with the weight of one Hue/Saturation range drawn over it. */\nconst HueRangeStrip: React.FC<{ bounds: [number, number, number, number] }> = ({ bounds }) => {\n const pts = Array.from({ length: 73 }, (_, i) => `${(i / 72) * 360},${20 - hueRangeWeight({ bounds }, i * 5) * 18}`).join(' ');\n return (\n <svg viewBox=\"0 0 360 20\" preserveAspectRatio=\"none\" className=\"w-full h-4 rounded\" data-testid=\"hue-range-strip\">\n <defs>\n <linearGradient id=\"pixerate-hue-strip\">\n {[0, 60, 120, 180, 240, 300, 360].map((h) => (\n <stop key={h} offset={`${(h / 360) * 100}%`} stopColor={`hsl(${h}, 90%, 50%)`} />\n ))}\n </linearGradient>\n </defs>\n <rect width={360} height={20} fill=\"url(#pixerate-hue-strip)\" opacity={0.6} />\n <polyline points={pts} fill=\"none\" stroke=\"#fff\" strokeWidth={1.5} />\n </svg>\n );\n};\n\n/**\n * Adjustment-layer stack: add, reorder, show / hide and remove layers, and edit the selected\n * one (curves over the histogram, levels, hue/saturation ranges, colour balance, …).\n */\nexport const AdjustmentLayersPanel: React.FC<AdjustmentLayersPanelProps> = ({ controller, layers: layersProp, histogram }) => {\n // Follows the controller when no `layers` prop is given.\n const follow = layersProp === undefined;\n const [, setTick] = useState(0);\n useEffect(() => (follow ? controller.subscribe(() => setTick((n) => n + 1)) : undefined), [controller, follow]);\n const layers = layersProp ?? controller.getAdjustmentLayers();\n const [newKind, setNewKind] = useState<AdjustmentKind>('curves');\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const [channel, setChannel] = useState<Channel>('master');\n const [range, setRange] = useState<number>(-1);\n const [tone, setTone] = useState<(typeof TONES)[number]['id']>('midtones');\n\n const selected = layers.find((l) => l.id === selectedId) ?? null;\n const topFirst = [...layers].reverse();\n\n const setParam = (layer: AdjustmentLayer, path: string, value: unknown, commit = true) =>\n controller.updateAdjustmentLayer(layer.id, { params: setControlPath(layer.params, path, value) as never }, commit);\n\n const slider = (layer: AdjustmentLayer, spec: ControlSpec, label?: string) => (\n <ControlSlider\n key={spec.id}\n spec={spec}\n label={label}\n value={Number(getControlPath(layer.params, spec.id) ?? spec.default)}\n onChange={(v) => setParam(layer, spec.id, v)}\n />\n );\n const controlsOf = (layer: AdjustmentLayer, filter: (spec: ControlSpec) => boolean = () => true) =>\n ADJUSTMENT_LAYER_CONTROLS[layer.kind].filter(filter);\n const checkbox = (layer: AdjustmentLayer, path: string, label: string) => (\n <label className=\"flex items-center gap-2 text-slate-300\">\n <input\n type=\"checkbox\"\n checked={Boolean(getControlPath(layer.params, path))}\n onChange={(e) => setParam(layer, path, e.target.checked)}\n className=\"accent-indigo-500\"\n />\n {label}\n </label>\n );\n\n const editor = (layer: AdjustmentLayer) => {\n switch (layer.kind) {\n case 'curves':\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex gap-1\" role=\"group\" aria-label=\"Curve channel\">\n {CHANNELS.map((c) => (\n <button key={c.id} type=\"button\" className={chipClass(channel === c.id)} onClick={() => setChannel(c.id)}>\n {c.label}\n </button>\n ))}\n </div>\n <CurvesEditor\n points={layer.params[channel]}\n channel={channel}\n histogram={histogram}\n onChange={(points: CurvePoint[], commit) => setParam(layer, channel, points, commit)}\n />\n </div>\n );\n case 'levels':\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex gap-1\" role=\"group\" aria-label=\"Levels channel\">\n {CHANNELS.map((c) => (\n <button key={c.id} type=\"button\" className={chipClass(channel === c.id)} onClick={() => setChannel(c.id)}>\n {c.label}\n </button>\n ))}\n </div>\n {controlsOf(layer, (s) => s.id.startsWith(`${channel}.`)).map((s) => slider(layer, s))}\n </div>\n );\n case 'hueSaturation':\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex flex-wrap gap-1\" role=\"group\" aria-label=\"Hue range\">\n <button type=\"button\" className={chipClass(range === -1)} onClick={() => setRange(-1)}>\n Master\n </button>\n {HUE_RANGE_LABELS.map((name, i) => (\n <button key={name} type=\"button\" className={chipClass(range === i)} onClick={() => setRange(i)} disabled={layer.params.colorize}>\n {name}\n </button>\n ))}\n </div>\n {range >= 0 && !layer.params.colorize && <HueRangeStrip bounds={layer.params.ranges[range].bounds} />}\n {controlsOf(layer, (s) => (range === -1 || layer.params.colorize ? !s.id.startsWith('ranges.') : s.id.startsWith(`ranges.${range}.`))).map((s) =>\n slider(layer, s)\n )}\n {range === -1 && checkbox(layer, 'colorize', 'Colorize')}\n </div>\n );\n case 'colorBalance':\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex gap-1\" role=\"group\" aria-label=\"Tone\">\n {TONES.map((t) => (\n <button key={t.id} type=\"button\" className={chipClass(tone === t.id)} onClick={() => setTone(t.id)}>\n {t.label}\n </button>\n ))}\n </div>\n {controlsOf(layer, (s) => s.id.startsWith(`${tone}.`)).map((s) => slider(layer, s))}\n {checkbox(layer, 'preserveLuminosity', 'Preserve luminosity')}\n </div>\n );\n case 'blackWhite':\n return (\n <div className=\"flex flex-col gap-2\">\n {controlsOf(layer).map((s) => slider(layer, s))}\n <label className=\"flex items-center gap-2 text-slate-300\">\n <input\n type=\"checkbox\"\n checked={layer.params.tint !== null}\n onChange={(e) => setParam(layer, 'tint', e.target.checked ? '#e1d3b3' : null)}\n className=\"accent-indigo-500\"\n />\n Tint\n {layer.params.tint && (\n <input\n type=\"color\"\n aria-label=\"Tint colour\"\n value={layer.params.tint}\n onChange={(e) => setParam(layer, 'tint', e.target.value)}\n className=\"h-5 w-8 bg-transparent\"\n />\n )}\n </label>\n </div>\n );\n case 'photoFilter':\n return (\n <div className=\"flex flex-col gap-2\">\n <label className=\"flex items-center gap-2 text-slate-300\">\n Filter colour\n <input\n type=\"color\"\n aria-label=\"Filter colour\"\n value={layer.params.color}\n onChange={(e) => setParam(layer, 'color', e.target.value)}\n className=\"h-5 w-8 bg-transparent\"\n />\n </label>\n {controlsOf(layer).map((s) => slider(layer, s))}\n {checkbox(layer, 'preserveLuminosity', 'Preserve luminosity')}\n </div>\n );\n case 'invert':\n return <p className=\"text-slate-500 text-[11px]\">Invert has no settings.</p>;\n default:\n return <div className=\"flex flex-col gap-2\">{controlsOf(layer).map((s) => slider(layer, s))}</div>;\n }\n };\n\n return (\n <div className=\"flex flex-col gap-2 text-xs\" data-testid=\"adjustment-layers-panel\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">Adjustment Layers</span>\n </div>\n <div className=\"flex gap-1.5\">\n <select\n aria-label=\"New adjustment layer kind\"\n className={`${selectClass} flex-1`}\n value={newKind}\n onChange={(e) => setNewKind(e.target.value as AdjustmentKind)}\n >\n {ADJUSTMENT_KINDS.map((k) => (\n <option key={k.kind} value={k.kind}>\n {k.label}\n </option>\n ))}\n </select>\n <button\n type=\"button\"\n className=\"px-2 py-1 rounded bg-indigo-600 text-white hover:bg-indigo-500\"\n onClick={() => {\n setSelectedId(controller.addAdjustmentLayer(newKind));\n setChannel('master');\n setRange(-1);\n }}\n >\n Add Layer\n </button>\n </div>\n\n {topFirst.length > 0 && (\n <ul className=\"flex flex-col gap-1\" aria-label=\"Adjustment layers\">\n {topFirst.map((layer) => {\n const index = layers.indexOf(layer);\n const label = layer.name || adjustmentKindLabel(layer.kind);\n return (\n <li\n key={layer.id}\n className={`flex items-center gap-1.5 rounded px-1.5 py-1 ${layer.id === selectedId ? 'bg-indigo-600/20 ring-1 ring-indigo-500/50' : 'bg-slate-800/60'}`}\n >\n <input\n type=\"checkbox\"\n aria-label={`Show ${label}`}\n checked={layer.enabled}\n onChange={() => controller.toggleAdjustmentLayer(layer.id)}\n className=\"accent-indigo-500\"\n />\n <button\n type=\"button\"\n className={`flex-1 text-left truncate ${layer.enabled ? 'text-slate-200' : 'text-slate-500 line-through'}`}\n onClick={() => setSelectedId(layer.id === selectedId ? null : layer.id)}\n aria-pressed={layer.id === selectedId}\n >\n {label}\n </button>\n <button\n type=\"button\"\n aria-label={`Move ${label} up`}\n disabled={index === layers.length - 1}\n onClick={() => controller.moveAdjustmentLayer(layer.id, index + 1)}\n className=\"px-1 text-slate-400 hover:text-slate-200 disabled:opacity-30\"\n >\n ↑\n </button>\n <button\n type=\"button\"\n aria-label={`Move ${label} down`}\n disabled={index === 0}\n onClick={() => controller.moveAdjustmentLayer(layer.id, index - 1)}\n className=\"px-1 text-slate-400 hover:text-slate-200 disabled:opacity-30\"\n >\n ↓\n </button>\n <button\n type=\"button\"\n aria-label={`Remove ${label}`}\n onClick={() => {\n controller.removeAdjustmentLayer(layer.id);\n if (selectedId === layer.id) setSelectedId(null);\n }}\n className=\"px-1 text-rose-400 hover:text-rose-300\"\n >\n ✕\n </button>\n </li>\n );\n })}\n </ul>\n )}\n\n {selected && (\n <div className=\"flex flex-col gap-2 rounded border border-slate-700/60 p-2\" data-testid=\"adjustment-layer-editor\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-slate-400\">Blend</span>\n <select\n aria-label=\"Blend mode\"\n className={`${selectClass} flex-1`}\n value={selected.blend}\n onChange={(e) => controller.updateAdjustmentLayer(selected.id, { blend: e.target.value as BlendMode })}\n >\n {BLEND_MODES.map((m) => (\n <option key={m.id} value={m.id}>\n {m.label}\n </option>\n ))}\n </select>\n </div>\n <ControlSlider\n spec={ADJUSTMENT_LAYER_OPACITY_CONTROL}\n label=\"Layer opacity\"\n value={selected.opacity}\n onChange={(v) => controller.updateAdjustmentLayer(selected.id, { opacity: v })}\n />\n {editor(selected)}\n </div>\n )}\n </div>\n );\n};\n","import React, { useRef, useState } from 'react';\nimport type { CurvePoint, ImageHistogram } from '@pixerate/editor/image-editor';\nimport {\n boxToCurvePoint,\n curvePointToBox,\n curveSvgPath,\n hitTestCurvePoint,\n histogramPath,\n insertCurvePoint,\n moveCurvePoint,\n removeCurvePoint,\n} from '@pixerate/editor/image-editor';\n\nexport interface CurvesEditorProps {\n points: CurvePoint[];\n /** `commit` is true for the first change of a gesture (one undo step), false for the drag moves. */\n onChange: (points: CurvePoint[], commit: boolean) => void;\n histogram?: ImageHistogram | null;\n channel?: 'master' | 'red' | 'green' | 'blue';\n size?: number;\n}\n\nconst BOX = 256;\nconst STROKE = { master: '#e2e8f0', red: '#ef4444', green: '#22c55e', blue: '#3b82f6' };\n\n/**\n * Curves editor over the histogram: click to add a point, drag to move it, double-click to\n * remove it.\n */\nexport const CurvesEditor: React.FC<CurvesEditorProps> = ({ points, onChange, histogram, channel = 'master', size = 200 }) => {\n const svgRef = useRef<SVGSVGElement>(null);\n const [drag, setDrag] = useState<number | null>(null);\n\n const toBox = (e: React.PointerEvent | React.MouseEvent) => {\n const rect = svgRef.current?.getBoundingClientRect();\n if (!rect || !rect.width || !rect.height) return { x: 0, y: 0 };\n return { x: ((e.clientX - rect.left) / rect.width) * BOX, y: ((e.clientY - rect.top) / rect.height) * BOX };\n };\n\n const onPointerDown = (e: React.PointerEvent) => {\n const { x, y } = toBox(e);\n let index = hitTestCurvePoint(points, x, y, BOX, BOX, 10);\n if (index === -1) {\n const inserted = insertCurvePoint(points, boxToCurvePoint(x, y, BOX, BOX));\n onChange(inserted.points, true);\n index = inserted.index;\n } else {\n onChange(points, true);\n }\n setDrag(index);\n (e.target as Element).setPointerCapture?.(e.pointerId);\n };\n\n const onPointerMove = (e: React.PointerEvent) => {\n if (drag === null) return;\n onChange(moveCurvePoint(points, drag, boxToCurvePoint(toBox(e).x, toBox(e).y, BOX, BOX)), false);\n };\n\n const onDoubleClick = (e: React.MouseEvent) => {\n const { x, y } = toBox(e);\n const index = hitTestCurvePoint(points, x, y, BOX, BOX, 10);\n if (index !== -1 && points.length > 2) onChange(removeCurvePoint(points, index), true);\n };\n\n const histChannel = channel === 'master' ? 'luminance' : channel;\n return (\n <svg\n ref={svgRef}\n viewBox={`0 0 ${BOX} ${BOX}`}\n width={size}\n height={size}\n role=\"application\"\n aria-label={`${channel} curve`}\n data-testid=\"curves-editor\"\n className=\"rounded bg-slate-950/70 touch-none select-none cursor-crosshair\"\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={() => setDrag(null)}\n onPointerCancel={() => setDrag(null)}\n onDoubleClick={onDoubleClick}\n >\n {histogram && histogram.samples > 0 && (\n <path d={histogramPath(histogram, histChannel, BOX, BOX)} fill=\"rgba(148, 163, 184, 0.25)\" />\n )}\n {[64, 128, 192].map((v) => (\n <g key={v} stroke=\"rgba(148, 163, 184, 0.2)\" strokeWidth={1}>\n <line x1={v} y1={0} x2={v} y2={BOX} />\n <line x1={0} y1={v} x2={BOX} y2={v} />\n </g>\n ))}\n <line x1={0} y1={BOX} x2={BOX} y2={0} stroke=\"rgba(148, 163, 184, 0.35)\" strokeDasharray=\"4 4\" />\n <path d={curveSvgPath(points, BOX, BOX)} fill=\"none\" stroke={STROKE[channel]} strokeWidth={2} />\n {points.map((p, i) => {\n const b = curvePointToBox(p, BOX, BOX);\n return (\n <circle\n key={i}\n cx={b.x}\n cy={b.y}\n r={5}\n fill={drag === i ? STROKE[channel] : '#0f172a'}\n stroke={STROKE[channel]}\n strokeWidth={2}\n aria-label={`Point ${p.input} to ${p.output}`}\n />\n );\n })}\n </svg>\n );\n};\n","import React, { useEffect, useRef, useState } from 'react';\nimport type { ImageEditorController, ImageLayer, LayerMenuAction, LayerPanelRow, PixelBuffer } from '@pixerate/editor/image-editor';\nimport { LayerEffectsPanel } from './LayerEffectsPanel';\nimport {\n BIT_DEPTH_OPTIONS,\n BLEND_MODES,\n PSD_FILE_ACCEPT,\n downloadPsd,\n dropPlacement,\n dropZone,\n openPsdFile,\n layerBadge,\n layerHasThumbnail,\n layerWarning,\n layerEffectsBadge,\n layerMenu,\n layerPanelRows,\n runLayerMenuAction,\n} from '@pixerate/editor/image-editor';\n\nexport interface LayersPanelProps {\n controller: ImageEditorController;\n /** Thumbnail size in px (default 32). */\n thumbnailSize?: number;\n /** Show Open PSD / Export PSD (default true). */\n psd?: boolean;\n /** Base name of exported PSD files (default `image`). */\n psdFileName?: string;\n /** Show the active layer's effects section (default true). */\n effects?: boolean;\n className?: string;\n}\n\nconst iconButton = 'px-1.5 py-0.5 rounded text-[10px] bg-slate-800 text-slate-300 hover:text-white disabled:opacity-40';\nconst rowClass = (active: boolean) =>\n `flex items-center gap-1.5 px-1.5 py-1 rounded cursor-pointer select-none ${active ? 'bg-indigo-600/30 ring-1 ring-indigo-500' : 'hover:bg-slate-800'}`;\n\n/** Draws a thumbnail (RGBA pixels) into a small canvas; nothing without a 2D context. */\nconst Thumbnail: React.FC<{ pixels: PixelBuffer | null; size: number; label: string; onClick?: (e: React.MouseEvent) => void; selected?: boolean; testId?: string }> = ({\n pixels,\n size,\n label,\n onClick,\n selected,\n testId,\n}) => {\n const ref = useRef<HTMLCanvasElement>(null);\n useEffect(() => {\n const canvas = ref.current;\n const ctx = canvas?.getContext('2d');\n if (!canvas || !ctx || !pixels || typeof ctx.createImageData !== 'function') return;\n canvas.width = pixels.width;\n canvas.height = pixels.height;\n const img = ctx.createImageData(pixels.width, pixels.height);\n img.data.set(pixels.data as ArrayLike<number>);\n ctx.putImageData(img, 0, 0);\n }, [pixels]);\n return (\n <canvas\n ref={ref}\n role={onClick ? 'button' : 'img'}\n aria-label={label}\n data-testid={testId}\n onClick={onClick}\n style={{ width: size, height: size }}\n className={`shrink-0 rounded bg-[repeating-conic-gradient(#334155_0%_25%,#1e293b_0%_50%)] [background-size:8px_8px] object-contain ${selected ? 'ring-2 ring-white' : 'ring-1 ring-slate-700'}`}\n />\n );\n};\n\n/**\n * The layer stack, top first: visibility, thumbnails, names (double-click to rename), locks,\n * mask thumbnails (click to paint the mask, Shift-click to disable it), drag to reorder or drop\n * into a group, opacity / fill / blend / clipping for the active layer, and the layer menu\n * (right-click a row, or the ⋯ button), an fx badge on rows with effects (click to switch them\n * on or off) and the active layer's effects. Every action is one undo step on the controller.\n */\nexport const LayersPanel: React.FC<LayersPanelProps> = ({ controller, thumbnailSize = 32, psd = true, psdFileName = 'image', effects = true, className }) => {\n const [, setTick] = useState(0);\n useEffect(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);\n const [error, setError] = useState<string | null>(null);\n const [renaming, setRenaming] = useState<string | null>(null);\n const [menu, setMenu] = useState<{ x: number; y: number } | null>(null);\n const [drag, setDrag] = useState<string | null>(null);\n /** Warnings of the last PSD open or export. */\n const [psdNotes, setPsdNotes] = useState<string[]>([]);\n const fileInput = useRef<HTMLInputElement>(null);\n const psdTask = async (fn: () => Promise<string[]>) => {\n try {\n setError(null);\n setPsdNotes(await fn());\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n }\n };\n /** Whether the next slider change records an undo step (the first of a drag does, the rest replace it). */\n const commitNext = useRef(true);\n\n const state = controller.getState();\n const rows = layerPanelRows(state.layers, state.activeLayerId);\n const active = controller.getActiveLayer();\n\n const attempt = (fn: () => unknown) => {\n try {\n setError(null);\n fn();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n }\n };\n const run = async (action: LayerMenuAction) => {\n setMenu(null);\n setError(await runLayerMenuAction(controller, action));\n };\n const prop = (key: 'opacity' | 'fillOpacity', value: number) =>\n attempt(() => {\n controller.setLayerProperties(active!.id, { [key]: value }, commitNext.current);\n commitNext.current = false;\n });\n const sliderEvents = {\n onPointerDown: () => (commitNext.current = true),\n onPointerUp: () => (commitNext.current = true),\n onKeyDown: () => (commitNext.current = true),\n };\n\n const onDrop = (e: React.DragEvent, row: LayerPanelRow) => {\n e.preventDefault();\n const id = e.dataTransfer.getData('text/x-pixerate-layer') || drag;\n setDrag(null);\n if (!id) return;\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n const fraction = rect.height ? (e.clientY - rect.top) / rect.height : 0.5;\n const placement = dropPlacement(state.layers, id, row.layer.id, dropZone(fraction, row.layer.type === 'group'));\n if (placement) attempt(() => controller.moveLayer(id, placement));\n };\n\n const thumb = (layer: ImageLayer) => (layerHasThumbnail(layer) ? controller.getLayerThumbnail(layer.id, { maxSide: 64 }) : null);\n const maskThumb = (layer: ImageLayer) => (layer.mask && !layer.mask.source ? controller.getLayerThumbnail(layer.id, { maxSide: 64, mask: true }) : null);\n\n const locked = (layer: ImageLayer) => Boolean(layer.locks?.all || layer.locks?.pixels || layer.locks?.position || layer.locks?.transparency);\n\n return (\n <div className={`flex flex-col gap-2 text-xs text-slate-200 ${className ?? ''}`} data-testid=\"layers-panel\" onClick={() => menu && setMenu(null)}>\n <div className=\"flex flex-wrap items-center gap-1\" role=\"toolbar\" aria-label=\"Layer actions\">\n <button type=\"button\" className={iconButton} onClick={() => run('new-layer')}>New Layer</button>\n <button type=\"button\" className={iconButton} onClick={() => run('new-group')}>New Group</button>\n <button type=\"button\" className={iconButton} disabled={!active} onClick={() => run('duplicate')}>Duplicate</button>\n <button type=\"button\" className={iconButton} disabled={!active} onClick={() => run('add-mask')}>Add Mask</button>\n <button type=\"button\" className={iconButton} disabled={!active} onClick={() => run('delete')}>Delete</button>\n <button\n type=\"button\"\n className={iconButton}\n aria-label=\"Layer menu\"\n aria-haspopup=\"menu\"\n onClick={(e) => {\n e.stopPropagation();\n const r = (e.currentTarget as HTMLElement).getBoundingClientRect();\n setMenu(menu ? null : { x: r.left, y: r.bottom });\n }}\n >\n ⋯\n </button>\n <select\n aria-label=\"Bits per channel\"\n title=\"Image › Mode: bits per channel\"\n className=\"rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200\"\n value={controller.bitDepth}\n onChange={(e) => attempt(() => controller.setBitDepth(Number(e.target.value) as 8 | 16 | 32))}\n >\n {BIT_DEPTH_OPTIONS.map((o) => (\n <option key={o.depth} value={o.depth} title={o.title}>\n {o.label}\n </option>\n ))}\n </select>\n {psd && (\n <>\n <button type=\"button\" className={iconButton} onClick={() => fileInput.current?.click()}>Open PSD…</button>\n <button type=\"button\" className={iconButton} onClick={() => psdTask(async () => (await downloadPsd(controller, psdFileName)).warnings)}>Export PSD</button>\n <input\n ref={fileInput}\n type=\"file\"\n accept={PSD_FILE_ACCEPT}\n className=\"hidden\"\n data-testid=\"psd-file-input\"\n aria-label=\"Open a PSD file\"\n onChange={(e) => {\n const file = e.currentTarget.files?.[0];\n e.currentTarget.value = '';\n if (file) psdTask(() => openPsdFile(controller, file));\n }}\n />\n </>\n )}\n </div>\n {psdNotes.length > 0 && (\n <ul className=\"rounded bg-amber-900/30 text-amber-200 px-2 py-1 space-y-0.5\" data-testid=\"psd-warnings\" aria-label=\"PSD warnings\">\n {psdNotes.map((n) => (\n <li key={n}>{n}</li>\n ))}\n <li>\n <button type=\"button\" className=\"underline\" onClick={() => setPsdNotes([])}>Dismiss</button>\n </li>\n </ul>\n )}\n\n {active && (\n <div className=\"grid grid-cols-2 gap-x-2 gap-y-1 items-center\" data-testid=\"layer-properties\">\n <label className=\"flex flex-col gap-0.5\">\n <span className=\"text-slate-400\">Opacity {Math.round(active.opacity * 100)}%</span>\n <input\n type=\"range\"\n min={0}\n max={100}\n aria-label=\"Layer opacity\"\n value={Math.round(active.opacity * 100)}\n {...sliderEvents}\n onChange={(e) => prop('opacity', Number(e.target.value) / 100)}\n className=\"accent-indigo-500\"\n />\n </label>\n <label className=\"flex flex-col gap-0.5\">\n <span className=\"text-slate-400\">Fill {Math.round(((active.type === 'pixel' ? active.fillOpacity : undefined) ?? 1) * 100)}%</span>\n <input\n type=\"range\"\n min={0}\n max={100}\n aria-label=\"Layer fill\"\n disabled={active.type !== 'pixel'}\n value={Math.round(((active.type === 'pixel' ? active.fillOpacity : undefined) ?? 1) * 100)}\n {...sliderEvents}\n onChange={(e) => prop('fillOpacity', Number(e.target.value) / 100)}\n className=\"accent-indigo-500 disabled:opacity-40\"\n />\n </label>\n <select\n aria-label=\"Layer blend mode\"\n className=\"bg-slate-800 border border-slate-700 rounded px-1.5 py-1\"\n value={active.blend}\n onChange={(e) => attempt(() => controller.setLayerProperties(active.id, { blend: e.target.value as never }))}\n >\n {active.type === 'group' && <option value=\"pass-through\">Pass Through</option>}\n {BLEND_MODES.map((m) => (\n <option key={m.id} value={m.id}>{m.label}</option>\n ))}\n </select>\n <label className=\"flex items-center gap-1.5 text-slate-300\">\n <input\n type=\"checkbox\"\n aria-label=\"Clip to layer below\"\n checked={Boolean(active.clipped)}\n onChange={(e) => attempt(() => controller.setLayerProperties(active.id, { clipped: e.target.checked }))}\n className=\"accent-indigo-500\"\n />\n Clip to below\n </label>\n <div className=\"col-span-2 flex flex-wrap gap-2 text-slate-400\" role=\"group\" aria-label=\"Layer locks\">\n {(['pixels', 'transparency', 'position', 'all'] as const).map((k) => (\n <label key={k} className=\"flex items-center gap-1\">\n <input\n type=\"checkbox\"\n aria-label={`Lock ${k}`}\n checked={Boolean(active.locks?.[k])}\n onChange={(e) => attempt(() => controller.setLayerProperties(active.id, { locks: { ...active.locks, [k]: e.target.checked } }))}\n className=\"accent-indigo-500\"\n />\n {k}\n </label>\n ))}\n </div>\n </div>\n )}\n\n {effects && active && active.type !== 'adjustment' && <LayerEffectsPanel controller={controller} className=\"border-t border-slate-800 pt-1.5\" />}\n\n <ul className=\"flex flex-col gap-0.5\" role=\"tree\" aria-label=\"Layers\">\n {rows.map((row) => {\n const { layer } = row;\n return (\n <li\n key={layer.id}\n role=\"treeitem\"\n aria-selected={row.active}\n aria-level={row.depth + 1}\n data-layer-id={layer.id}\n draggable={!layer.locks?.all}\n onDragStart={(e) => {\n e.dataTransfer.setData('text/x-pixerate-layer', layer.id);\n setDrag(layer.id);\n }}\n onDragOver={(e) => e.preventDefault()}\n onDrop={(e) => onDrop(e, row)}\n tabIndex={0}\n onClick={() => attempt(() => controller.setActiveLayer(layer.id, 'pixels'))}\n onKeyDown={(e) => {\n if (e.target === e.currentTarget && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n attempt(() => controller.setActiveLayer(layer.id, 'pixels'));\n }\n }}\n onContextMenu={(e) => {\n e.preventDefault();\n controller.setActiveLayer(layer.id, state.activeLayerId === layer.id ? state.activeTarget : 'pixels');\n setMenu({ x: e.clientX, y: e.clientY });\n }}\n className={rowClass(row.active)}\n style={{ paddingLeft: 6 + row.depth * 14 }}\n >\n <button\n type=\"button\"\n aria-label={layer.visible ? `Hide ${row.label}` : `Show ${row.label}`}\n aria-pressed={layer.visible}\n className=\"w-4 text-center text-slate-300\"\n onClick={(e) => {\n e.stopPropagation();\n attempt(() => controller.setLayerProperties(layer.id, { visible: !layer.visible }));\n }}\n >\n {layer.visible ? '●' : '○'}\n </button>\n {layer.type === 'group' && (\n <button\n type=\"button\"\n aria-label={layer.collapsed ? `Expand ${row.label}` : `Collapse ${row.label}`}\n className=\"w-3 text-slate-400\"\n onClick={(e) => {\n e.stopPropagation();\n attempt(() => controller.setLayerProperties(layer.id, { collapsed: !layer.collapsed }));\n }}\n >\n {layer.collapsed ? '▸' : '▾'}\n </button>\n )}\n {row.clipped && <span className=\"text-slate-500\" aria-label=\"Clipped\">↳</span>}\n {layerHasThumbnail(layer) ? (\n <span className=\"relative shrink-0\">\n <Thumbnail\n pixels={thumb(layer)}\n size={thumbnailSize}\n label={`${row.label} pixels`}\n selected={row.active && state.activeTarget === 'pixels' && Boolean(layer.mask)}\n />\n {layer.type !== 'pixel' && (\n <span\n data-testid=\"layer-kind-badge\"\n className=\"absolute -bottom-1 -right-1 rounded bg-slate-700 px-0.5 text-[8px] font-bold leading-tight text-slate-100 ring-1 ring-slate-900\"\n >\n {layerBadge(layer)}\n </span>\n )}\n </span>\n ) : (\n <span\n className=\"shrink-0 grid place-items-center rounded bg-slate-800 text-[9px] text-slate-400 ring-1 ring-slate-700\"\n style={{ width: thumbnailSize, height: thumbnailSize }}\n >\n {layerBadge(layer)}\n </span>\n )}\n {layer.mask && !layer.mask.source && layer.type === 'pixel' && (\n <button\n type=\"button\"\n aria-label={`${layer.mask.linked === false ? 'Link' : 'Unlink'} ${row.label} mask`}\n aria-pressed={layer.mask.linked !== false}\n title={layer.mask.linked === false ? 'Mask unlinked: it stays put when the layer moves or transforms. Click to link.' : 'Mask linked: it moves with the layer. Click to unlink.'}\n data-testid=\"layer-mask-link\"\n className={`shrink-0 text-[10px] leading-none ${layer.mask.linked === false ? 'text-slate-600' : 'text-slate-300'}`}\n onClick={(e) => {\n e.stopPropagation();\n attempt(() => controller.setLayerMaskProps(layer.id, { linked: layer.mask!.linked === false }));\n }}\n >\n {layer.mask.linked === false ? '⛓︎̸' : '⛓︎'}\n </button>\n )}\n {layer.mask && (\n <Thumbnail\n pixels={maskThumb(layer)}\n size={thumbnailSize}\n label={`${row.label} mask${layer.mask.enabled === false ? ' (disabled)' : ''}`}\n testId=\"layer-mask-thumbnail\"\n selected={row.active && state.activeTarget === 'mask'}\n onClick={(e) => {\n e.stopPropagation();\n if (e.shiftKey) attempt(() => controller.setLayerMaskProps(layer.id, { enabled: layer.mask!.enabled === false }));\n else attempt(() => controller.setActiveLayer(layer.id, 'mask'));\n }}\n />\n )}\n {renaming === layer.id ? (\n <input\n autoFocus\n aria-label=\"Layer name\"\n defaultValue={layer.name || row.label}\n className=\"flex-1 min-w-0 bg-slate-900 border border-slate-600 rounded px-1\"\n onClick={(e) => e.stopPropagation()}\n onBlur={(e) => {\n setRenaming(null);\n if (e.target.value.trim() && e.target.value !== layer.name) attempt(() => controller.setLayerProperties(layer.id, { name: e.target.value }));\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') (e.target as HTMLInputElement).blur();\n if (e.key === 'Escape') setRenaming(null);\n }}\n />\n ) : (\n <span\n className={`flex-1 min-w-0 truncate ${layer.visible ? '' : 'text-slate-500'}`}\n onDoubleClick={(e) => {\n e.stopPropagation();\n setRenaming(layer.id);\n }}\n >\n {row.label}\n </span>\n )}\n {layerWarning(layer) && (\n <span role=\"img\" data-testid=\"layer-warning\" aria-label={layerWarning(layer)!} title={layerWarning(layer)!} className=\"text-[10px] text-amber-400\">\n ⚠\n </span>\n )}\n {layerEffectsBadge(layer) && (\n <button\n type=\"button\"\n data-testid=\"layer-fx-badge\"\n aria-label={layerEffectsBadge(layer) === 'on' ? `Turn effects off for ${row.label}` : `Turn effects on for ${row.label}`}\n aria-pressed={layerEffectsBadge(layer) === 'on'}\n className={`text-[9px] italic font-semibold ${layerEffectsBadge(layer) === 'on' ? 'text-indigo-300' : 'text-slate-600 line-through'}`}\n onClick={(e) => {\n e.stopPropagation();\n attempt(() => controller.setLayerEffectsEnabled(layer.id, layerEffectsBadge(layer) !== 'on'));\n }}\n >\n fx\n </button>\n )}\n {locked(layer) && <span aria-label=\"Locked\" className=\"text-slate-400\">🔒</span>}\n {layer.blend !== 'normal' && layer.blend !== 'pass-through' && <span className=\"text-[9px] text-slate-500\">{layer.blend}</span>}\n </li>\n );\n })}\n </ul>\n\n {error && (\n <p role=\"alert\" className=\"text-rose-400\">\n {error}\n </p>\n )}\n\n {menu && (\n <div\n role=\"menu\"\n aria-label=\"Layer menu\"\n className=\"fixed z-50 min-w-44 rounded border border-slate-700 bg-slate-900 py-1 shadow-xl\"\n style={{ left: menu.x, top: menu.y }}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.key === 'Escape' && setMenu(null)}\n >\n {layerMenu(controller).map((item) => (\n <button\n key={item.action}\n type=\"button\"\n role=\"menuitem\"\n disabled={!item.enabled}\n className=\"block w-full px-3 py-1 text-left hover:bg-slate-800 disabled:opacity-40\"\n onClick={() => run(item.action)}\n >\n {item.label}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n};\n","import React, { useEffect, useRef, useState } from 'react';\nimport type { EffectControl, ImageEditorController, LayerEffectKind } from '@pixerate/editor/image-editor';\nimport { LAYER_EFFECT_MENU, effectControlChange, layerEffectControls, layerEffectsPanel } from '@pixerate/editor/image-editor';\n\nexport interface LayerEffectsPanelProps {\n controller: ImageEditorController;\n /** The layer whose effects to show (default: the active layer). */\n layerId?: string | null;\n className?: string;\n}\n\nconst button = 'px-1.5 py-0.5 rounded text-[10px] bg-slate-800 text-slate-300 hover:text-white disabled:opacity-40';\n\n/**\n * A layer's effects (Photoshop's layer styles): the master switch, Scale Effects, an \"Add effect\"\n * menu, and each effect with its enabled toggle, remove button and, when expanded, its settings.\n * Every change is one undo step (a slider drag is one step too).\n */\nexport const LayerEffectsPanel: React.FC<LayerEffectsPanelProps> = ({ controller, layerId, className }) => {\n const [, setTick] = useState(0);\n useEffect(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);\n const [open, setOpen] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n /** Whether the next slider change records an undo step (the first of a drag does, the rest replace it). */\n const commitNext = useRef(true);\n\n const layer = layerId ? controller.getLayer(layerId) : controller.getActiveLayer();\n const model = layerEffectsPanel(layer);\n const id = layer?.id;\n const attempt = (fn: () => unknown) => {\n try {\n setError(null);\n fn();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n }\n };\n const sliderEvents = {\n onPointerDown: () => (commitNext.current = true),\n onPointerUp: () => (commitNext.current = true),\n onKeyDown: () => (commitNext.current = true),\n };\n\n if (!model.available || !id) {\n return (\n <div className={`text-xs text-slate-500 ${className ?? ''}`} data-testid=\"layer-effects\">\n {model.reason}\n </div>\n );\n }\n const effects = controller.getLayerEffects(id);\n const patterns = controller.getDocumentPatterns();\n const change = (effectId: string, control: EffectControl, value: unknown, drag = false) =>\n attempt(() => {\n const effect = controller.getLayerEffects(id).items.find((e) => e.id === effectId)!;\n controller.updateLayerEffect(id, effectId, effectControlChange(effect, control.key, value, patterns), drag ? commitNext.current : true);\n if (drag) commitNext.current = false;\n });\n\n const renderControl = (effectId: string, c: EffectControl) => {\n const label = `${c.label}`;\n switch (c.type) {\n case 'range': {\n const k = c.percent ? 100 : 1;\n const shown = Math.round(c.value * k * 100) / 100;\n return (\n <label key={c.key} className=\"flex flex-col gap-0.5\">\n <span className=\"text-slate-400\">\n {label} {shown}\n {c.unit}\n </span>\n <input\n type=\"range\"\n aria-label={label}\n min={c.min * k}\n max={c.max * k}\n step={c.step * k}\n value={shown}\n disabled={model.readOnly}\n {...sliderEvents}\n onChange={(e) => change(effectId, c, Number(e.target.value) / k, true)}\n className=\"accent-indigo-500\"\n />\n </label>\n );\n }\n case 'color':\n return (\n <label key={c.key} className=\"flex items-center gap-1.5 text-slate-300\">\n <input type=\"color\" aria-label={label} value={c.value} disabled={model.readOnly} onChange={(e) => change(effectId, c, e.target.value)} />\n {label}\n </label>\n );\n case 'checkbox':\n return (\n <label key={c.key} className=\"flex items-center gap-1.5 text-slate-300\">\n <input type=\"checkbox\" aria-label={label} checked={c.value} disabled={model.readOnly} onChange={(e) => change(effectId, c, e.target.checked)} className=\"accent-indigo-500\" />\n {label}\n </label>\n );\n case 'select':\n return (\n <label key={c.key} className=\"flex flex-col gap-0.5\">\n <span className=\"text-slate-400\">{label}</span>\n <select\n aria-label={label}\n value={c.value}\n disabled={model.readOnly}\n onChange={(e) => change(effectId, c, e.target.value)}\n className=\"bg-slate-800 border border-slate-700 rounded px-1.5 py-1\"\n >\n {c.options.map((o) => (\n <option key={o.value} value={o.value}>\n {o.label}\n </option>\n ))}\n </select>\n </label>\n );\n }\n };\n\n return (\n <div className={`flex flex-col gap-1.5 text-xs text-slate-200 ${className ?? ''}`} data-testid=\"layer-effects\" aria-label=\"Layer effects\" role=\"group\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-semibold text-slate-300\">fx Effects</span>\n <label className=\"flex items-center gap-1 text-slate-300\">\n <input\n type=\"checkbox\"\n aria-label=\"Effects on\"\n checked={model.enabled}\n disabled={model.readOnly}\n onChange={(e) => attempt(() => controller.setLayerEffectsEnabled(id, e.target.checked))}\n className=\"accent-indigo-500\"\n />\n On\n </label>\n <label className=\"flex items-center gap-1 text-slate-400\">\n Scale\n <input\n type=\"number\"\n aria-label=\"Scale effects\"\n min={1}\n max={1000}\n step={1}\n value={Math.round(model.scale * 100)}\n disabled={model.readOnly}\n onChange={(e) => {\n const v = Number(e.target.value);\n if (v >= 1 && v <= 1000) attempt(() => controller.setLayerEffectsEnabled(id, model.enabled, v / 100));\n }}\n className=\"w-14 bg-slate-800 border border-slate-700 rounded px-1\"\n />\n %\n </label>\n <select\n aria-label=\"Add effect\"\n value=\"\"\n disabled={model.readOnly}\n onChange={(e) => {\n const kind = e.target.value as LayerEffectKind;\n if (!kind) return;\n attempt(() => setOpen(controller.addLayerEffect(id, kind).effect.id));\n }}\n className=\"bg-slate-800 border border-slate-700 rounded px-1.5 py-1\"\n >\n <option value=\"\">Add effect…</option>\n {LAYER_EFFECT_MENU.map((m) => (\n <option key={m.kind} value={m.kind}>\n {m.label}\n </option>\n ))}\n </select>\n </div>\n {model.readOnly && model.reason && <p className=\"text-slate-500\">{model.reason}</p>}\n <ul className=\"flex flex-col gap-1\" aria-label=\"Effects\">\n {model.rows.map((row) => {\n const effect = effects.items.find((e) => e.id === row.id)!;\n const expanded = open === row.id;\n return (\n <li key={row.id} data-effect-id={row.id} className=\"rounded bg-slate-900/60 ring-1 ring-slate-800\">\n <div className=\"flex items-center gap-1.5 px-1.5 py-1\">\n <input\n type=\"checkbox\"\n aria-label={`${row.label} on`}\n checked={row.enabled}\n disabled={model.readOnly}\n onChange={(e) => attempt(() => controller.updateLayerEffect(id, row.id, { enabled: e.target.checked }))}\n className=\"accent-indigo-500\"\n />\n <button\n type=\"button\"\n aria-expanded={expanded}\n className={`flex-1 text-left ${row.enabled && model.enabled ? '' : 'text-slate-500'}`}\n onClick={() => setOpen(expanded ? null : row.id)}\n >\n {row.label}\n </button>\n <button type=\"button\" className={button} aria-label={`Remove ${row.label}`} disabled={model.readOnly} onClick={() => attempt(() => controller.removeLayerEffect(id, row.id))}>\n ✕\n </button>\n </div>\n {expanded && (\n <div className=\"grid grid-cols-2 gap-x-2 gap-y-1 px-1.5 pb-1.5\" data-testid=\"effect-settings\">\n {layerEffectControls(effect, patterns).map((c) => renderControl(row.id, c))}\n </div>\n )}\n </li>\n );\n })}\n </ul>\n {error && (\n <p role=\"alert\" className=\"text-rose-400\">\n {error}\n </p>\n )}\n </div>\n );\n};\n","import React, { useEffect, useState } from 'react';\nimport { findLayer, type ImageEditorController, type ImageLayer, type SmartObjectLayer } from '@pixerate/editor/image-editor';\nimport type { EffectProvider } from '@pixerate/editor/effects';\nimport { EffectParameters, EffectsBrowser, useEffectDescription } from '../effects';\n\nexport interface ImageProviderEffectsPanelProps {\n controller: ImageEditorController;\n className?: string;\n}\n\nconst btn = 'rounded border border-slate-700 px-1.5 py-0.5 text-[11px] text-slate-300 hover:text-white disabled:opacity-40';\n\n/** One effect's controls, loaded from the provider; a note when it does not have the effect. */\nfunction Controls({\n provider,\n effect,\n name,\n values,\n onChange,\n onPreset,\n}: {\n provider: EffectProvider | null;\n effect: string;\n name?: string;\n values: Readonly<Record<string, unknown>>;\n onChange: (control: string, value: unknown, gesture: string | null) => void;\n onPreset: (values: Readonly<Record<string, unknown>>) => void;\n}) {\n const { description, error } = useEffectDescription(provider, effect);\n if (!provider) return <p className=\"text-[11px] text-slate-400\">No effects provider: \"{name ?? effect}\" is kept but not drawn.</p>;\n if (error) return <p className=\"text-[11px] text-amber-400\">{error}</p>;\n if (!description) return <p className=\"text-[11px] text-slate-400\">Loading…</p>;\n return <EffectParameters description={description} values={values} onChange={onChange} onReset={(k) => onChange(k, description.defaults[k], null)} onPreset={onPreset} />;\n}\n\n/**\n * Provider effects in the image editor, for the active layer: its effect smart filters (apply,\n * turn on and off, opacity, reorder, change controls, remove) and, for an effect layer, its own\n * controls; plus adding effect layers. Applying a filter effect to a pixel layer converts it to a\n * smart object in the same undo step. Without a provider it says why nothing can be added.\n */\nexport function ImageProviderEffectsPanel({ controller, className = '' }: ImageProviderEffectsPanelProps) {\n const [, setTick] = useState(0);\n useEffect(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);\n const [browse, setBrowse] = useState<null | 'filter' | 'layer'>(null);\n const [message, setMessage] = useState<string | null>(null);\n const [open, setOpen] = useState<string | null>(null);\n const provider = controller.effectsProvider;\n const state = controller.getState();\n const layer: ImageLayer | null = state.activeLayerId ? (findLayer(state.layers, state.activeLayerId)?.layer ?? null) : null;\n const run = (work: () => unknown) => {\n setMessage(null);\n Promise.resolve()\n .then(work)\n .catch((e: unknown) => setMessage(e instanceof Error ? e.message : String(e)));\n };\n const drags = React.useRef(new Set<string>());\n /** Changes during a drag skip the undo stack; the last one (gesture ended) records one step. */\n const commit = (gesture: string | null) => {\n if (gesture) {\n if (!drags.current.has(gesture)) {\n drags.current.add(gesture);\n return true;\n }\n return false;\n }\n return true;\n };\n const filters = layer?.type === 'smart' ? ((layer as SmartObjectLayer).smartFilters?.filters ?? []).filter((f) => f.kind === 'effect') : [];\n const generator = layer?.type === 'pixel' ? layer.generator : undefined;\n const canFilter = !!layer && layer.type !== 'adjustment' && layer.type !== 'annotation';\n\n return (\n <section className={`flex flex-col gap-2 text-xs ${className}`} aria-label=\"Provider effects\" data-image-provider-effects=\"\">\n <div className=\"flex items-center gap-1\">\n <span className=\"flex-1 font-semibold uppercase tracking-wider text-[11px] text-slate-200\">Effects</span>\n <button type=\"button\" className={btn} disabled={!provider || !canFilter} aria-pressed={browse === 'filter'} onClick={() => setBrowse(browse === 'filter' ? null : 'filter')}>\n Apply effect…\n </button>\n <button type=\"button\" className={btn} disabled={!provider} aria-pressed={browse === 'layer'} onClick={() => setBrowse(browse === 'layer' ? null : 'layer')}>\n Effect layer…\n </button>\n </div>\n {!provider && <p className=\"text-[11px] text-slate-400\">No effects provider is registered. Effects in the document are kept.</p>}\n {browse === 'filter' && layer && (\n <EffectsBrowser provider={provider} uses={['filter']} title=\"Filters\" onPick={(e) => (setBrowse(null), run(() => controller.applyEffectFilter(layer.id, e.id)))} />\n )}\n {browse === 'layer' && (\n <EffectsBrowser provider={provider} uses={['generator', 'overlay', 'title']} title=\"Generators and overlays\" onPick={(e) => (setBrowse(null), run(() => controller.addEffectLayer(e.id)))} />\n )}\n {generator && layer && (\n <div className=\"space-y-1\" data-effect-part=\"generator\">\n <div className=\"flex items-center gap-1\">\n <span className=\"flex-1 font-medium text-slate-200\">{generator.name ?? generator.effect}</span>\n <button type=\"button\" className={btn} title=\"Keep the pixels as a plain layer\" onClick={() => run(() => controller.rasterizeEffectLayer(layer.id))}>\n Rasterize\n </button>\n </div>\n <Controls\n provider={provider}\n effect={generator.effect}\n name={generator.name}\n values={generator.values}\n onChange={(k, v, gesture) => run(() => controller.updateEffectLayer(layer.id, { values: { [k]: v as never } }, commit(gesture)))}\n onPreset={(values) => run(() => controller.updateEffectLayer(layer.id, { values: values as never }))}\n />\n </div>\n )}\n {filters.length > 0 && layer && (\n <ol className=\"space-y-1\" data-effect-part=\"filters\">\n {filters.map((f) => {\n const label = f.kind === 'effect' ? (f.name ?? f.effect) : f.kind;\n const all = (layer as SmartObjectLayer).smartFilters!.filters;\n const index = all.indexOf(f);\n if (f.kind !== 'effect') return null;\n return (\n <li key={f.id} className=\"rounded border border-slate-700 p-1\" data-smart-effect={f.id}>\n <div className=\"flex items-center gap-1\">\n <input type=\"checkbox\" checked={f.enabled} aria-label={`${label} on`} onChange={(e) => {\n const enabled = e.currentTarget.checked;\n run(() => controller.updateEffectFilter(layer.id, f.id, { enabled }));\n }} />\n <button type=\"button\" className=\"min-w-0 flex-1 truncate text-left text-slate-200\" aria-expanded={open === f.id} onClick={() => setOpen(open === f.id ? null : f.id)}>\n {label}\n </button>\n <button type=\"button\" className={btn} disabled={index === all.length - 1} aria-label=\"Move up\" onClick={() => run(() => controller.updateEffectFilter(layer.id, f.id, { index: index + 1 }))}>\n ↑\n </button>\n <button type=\"button\" className={btn} disabled={index === 0} aria-label=\"Move down\" onClick={() => run(() => controller.updateEffectFilter(layer.id, f.id, { index: index - 1 }))}>\n ↓\n </button>\n <button type=\"button\" className={btn} aria-label={`Remove ${label}`} onClick={() => run(() => controller.removeSmartFilter(layer.id, f.id))}>\n ✕\n </button>\n </div>\n {open === f.id && (\n <div className=\"mt-1 space-y-2\">\n <label className=\"flex items-center gap-1\">\n <span className=\"w-14 text-[11px] text-slate-300\">Opacity</span>\n <input\n type=\"range\"\n min={0}\n max={1}\n step={0.01}\n className=\"flex-1\"\n value={f.opacity}\n aria-label={`${label} opacity`}\n onChange={(e) => {\n const opacity = Number(e.currentTarget.value);\n run(() => controller.updateEffectFilter(layer.id, f.id, { opacity }));\n }}\n />\n </label>\n <Controls\n provider={provider}\n effect={f.effect}\n name={f.name}\n values={f.values}\n onChange={(k, v, gesture) => run(() => controller.updateEffectFilter(layer.id, f.id, { values: { [k]: v as never } }, commit(gesture)))}\n onPreset={(values) => run(() => controller.updateEffectFilter(layer.id, f.id, { values: values as never }))}\n />\n </div>\n )}\n </li>\n );\n })}\n </ol>\n )}\n {!layer && <p className=\"text-[11px] text-slate-400\">Select a layer to apply effects to it.</p>}\n {message && (\n <p role=\"alert\" className=\"text-[11px] text-rose-400\">\n {message}\n </p>\n )}\n </section>\n );\n}\n","import { useEffect, useState } from 'react';\nimport type { EffectDescription, EffectProvider } from '@pixerate/editor/effects';\n\n/** Anything that takes an effects provider: every editor controller with effects support. */\nexport interface EffectsHost {\n useEffects(provider: EffectProvider): () => void;\n}\n\n/**\n * Registers `provider` with an editor while mounted (or while it is the one passed), and removes it\n * again on unmount. Pass `null` or `undefined` for no provider: the editor then behaves as without\n * effects support.\n */\nexport function useEffects(host: EffectsHost | null | undefined, provider: EffectProvider | null | undefined): void {\n useEffect(() => {\n if (!host || !provider) return;\n return host.useEffects(provider);\n }, [host, provider]);\n}\n\n/** An effect's description from the provider, loaded when `effect` changes (`null` while loading or on error). */\nexport function useEffectDescription(provider: EffectProvider | null | undefined, effect: string | null | undefined): { description: EffectDescription | null; error: string | null } {\n const [state, setState] = useState<{ key: string; description: EffectDescription | null; error: string | null }>({ key: '', description: null, error: null });\n const key = provider && effect ? `${provider.id}:${effect}` : '';\n useEffect(() => {\n if (!provider || !effect) return;\n let live = true;\n Promise.resolve()\n .then(() => provider.describe(effect))\n .then(\n (description) => live && setState({ key, description, error: null }),\n (e: unknown) => live && setState({ key, description: null, error: e instanceof Error ? e.message : String(e) }),\n );\n return () => {\n live = false;\n };\n }, [provider, effect, key]);\n return state.key === key ? { description: state.description, error: state.error } : { description: null, error: null };\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { renderEffectThumbnail, type EffectProvider, type EffectSummary } from '@pixerate/editor/effects';\n\nexport interface EffectThumbnailProps {\n provider: EffectProvider;\n effect: EffectSummary;\n /** Pixel size of the preview (default 96 × 54). */\n width?: number;\n height?: number;\n className?: string;\n}\n\n/**\n * A preview of an effect drawn by the provider's own renderer (filters on a sample picture,\n * transitions half way, generators mid-way through). Motion effects and failures show a label.\n */\nexport function EffectThumbnail({ provider, effect, width = 96, height = 54, className = '' }: EffectThumbnailProps) {\n const ref = useRef<HTMLCanvasElement>(null);\n const [failed, setFailed] = useState(effect.kind === 'motion');\n useEffect(() => {\n if (effect.kind === 'motion') return;\n let live = true;\n renderEffectThumbnail(provider, effect, { width, height }).then(\n (pixels) => {\n const ctx = live ? ref.current?.getContext('2d') : null;\n if (!ctx || typeof ImageData === 'undefined') return;\n ctx.putImageData(new ImageData(new Uint8ClampedArray(pixels.data), pixels.width, pixels.height), 0, 0);\n },\n () => live && setFailed(true),\n );\n return () => {\n live = false;\n };\n }, [provider, effect, width, height]);\n return (\n <div\n className={`relative overflow-hidden rounded border border-border bg-[repeating-conic-gradient(#8884_0_25%,transparent_0_50%)] bg-[length:12px_12px] ${className}`}\n style={{ aspectRatio: `${width} / ${height}` }}\n data-effect-thumbnail={effect.id}\n >\n {failed ? (\n <span className=\"absolute inset-0 flex items-center justify-center text-[10px] text-muted-foreground\">{effect.kind === 'motion' ? 'Motion' : 'No preview'}</span>\n ) : (\n <canvas ref={ref} width={width} height={height} className=\"h-full w-full\" aria-hidden=\"true\" />\n )}\n </div>\n );\n}\n","import React, { useEffect, useMemo, useState } from 'react';\nimport { EFFECT_USE_LABELS, type EffectProvider, type EffectSummary, type EffectUse } from '@pixerate/editor/effects';\nimport { EffectThumbnail } from './EffectThumbnail';\n\nexport interface EffectsBrowserProps {\n /** The editor's provider; without one the browser says effects are unavailable. */\n provider: EffectProvider | null | undefined;\n /** Only effects with one of these uses (default: all but motion). */\n uses?: readonly EffectUse[];\n /** Called with the effect the user picks. */\n onPick: (effect: EffectSummary) => void;\n /** Draw previews with the provider's renderer (default true). */\n thumbnails?: boolean;\n /** Heading (default \"Effects\"). */\n title?: React.ReactNode;\n className?: string;\n}\n\n/**\n * Browses a provider's effects: a search box, a category filter (and a use filter when more than\n * one use is allowed), and a grid of effects with previews. Picking one calls `onPick`.\n */\nexport function EffectsBrowser({ provider, uses, onPick, thumbnails = true, title = 'Effects', className = '' }: EffectsBrowserProps) {\n const [all, setAll] = useState<readonly EffectSummary[]>([]);\n const [query, setQuery] = useState('');\n const [category, setCategory] = useState('');\n const [use, setUse] = useState<EffectUse | ''>('');\n const [error, setError] = useState<string | null>(null);\n useEffect(() => {\n if (!provider) return setAll([]);\n let live = true;\n Promise.resolve()\n .then(() => provider.list())\n .then(\n (list) => live && (setAll(list), setError(null)),\n (e: unknown) => live && setError(e instanceof Error ? e.message : String(e)),\n );\n return () => {\n live = false;\n };\n }, [provider]);\n const [found, setFound] = useState<readonly EffectSummary[]>([]);\n useEffect(() => {\n if (!provider) return setFound([]);\n let live = true;\n Promise.resolve()\n .then(() => provider.search(query, { ...(category ? { category } : {}), ...(use ? { use } : {}) }))\n .then((list) => live && setFound(list), () => live && setFound([]));\n return () => {\n live = false;\n };\n }, [provider, query, category, use]);\n const allowed = (e: EffectSummary) => (uses ? e.kind !== 'motion' || uses.includes('motion') : e.kind !== 'motion') && (!uses || e.uses.some((u) => uses.includes(u)));\n const categories = useMemo(() => [...new Set(all.filter(allowed).map((e) => e.category))], [all, uses]);\n const shown = found.filter(allowed);\n if (!provider)\n return (\n <div className={`rounded-md border border-dashed border-border p-3 text-xs text-muted-foreground ${className}`} data-effects-browser=\"\" data-effects-unavailable=\"\">\n No effects provider is registered, so effects cannot be added. Effects already in the document are kept.\n </div>\n );\n return (\n <section className={`flex flex-col gap-2 ${className}`} data-effects-browser=\"\" aria-label=\"Effects browser\">\n {title && <h3 className=\"text-xs font-semibold\">{title}</h3>}\n <div className=\"flex flex-wrap gap-1\">\n <input\n type=\"search\"\n className=\"min-w-0 flex-1 rounded border border-border bg-transparent px-1.5 py-0.5 text-xs\"\n placeholder=\"Search effects\"\n aria-label=\"Search effects\"\n value={query}\n onChange={(e) => setQuery(e.currentTarget.value)}\n />\n <select className=\"rounded border border-border bg-transparent px-1 py-0.5 text-xs\" aria-label=\"Category\" value={category} onChange={(e) => setCategory(e.currentTarget.value)}>\n <option value=\"\">All categories</option>\n {categories.map((c) => (\n <option key={c} value={c}>\n {c}\n </option>\n ))}\n </select>\n {uses && uses.length > 1 && (\n <select className=\"rounded border border-border bg-transparent px-1 py-0.5 text-xs\" aria-label=\"Use\" value={use} onChange={(e) => setUse(e.currentTarget.value as EffectUse | '')}>\n <option value=\"\">Any use</option>\n {uses.map((u) => (\n <option key={u} value={u}>\n {EFFECT_USE_LABELS[u]}\n </option>\n ))}\n </select>\n )}\n </div>\n {error && <p role=\"alert\" className=\"text-[11px] text-destructive\">{error}</p>}\n <ul className=\"grid max-h-96 grid-cols-[repeat(auto-fill,minmax(6.5rem,1fr))] gap-1.5 overflow-y-auto\" role=\"list\">\n {shown.map((e) => (\n <li key={e.id}>\n <button\n type=\"button\"\n className=\"flex w-full flex-col gap-1 rounded border border-transparent p-1 text-left hover:border-border focus-visible:border-border\"\n title={e.description ?? e.name}\n data-effect-id={e.id}\n onClick={() => onPick(e)}\n >\n {thumbnails && <EffectThumbnail provider={provider} effect={e} />}\n <span className=\"truncate text-[11px] font-medium\">{e.name}</span>\n <span className=\"truncate text-[10px] text-muted-foreground\">{e.uses.map((u) => EFFECT_USE_LABELS[u]).join(' · ')}</span>\n </button>\n </li>\n ))}\n </ul>\n {!shown.length && !error && <p className=\"text-[11px] text-muted-foreground\">No effects match.</p>}\n </section>\n );\n}\n","import React, { useId, useMemo } from 'react';\nimport { effectFieldValue, effectParameterFields, type EffectDescription } from '@pixerate/editor/effects';\nimport { parameterLabel, parameterValuesEqual, type ParameterValue } from '@pixerate/editor/parameters';\nimport { ParameterFieldControl } from '../parameters/fields';\n\nexport interface EffectParametersProps {\n /** The effect's description (`describe`). */\n description: EffectDescription;\n /** Its saved values; controls left out show their defaults. */\n values: Readonly<Record<string, unknown>>;\n /**\n * A control changed. While a slider or colour drag is under way `gesture` is a key unique to\n * that drag, so the host can fold its changes into one undo step; otherwise `null`.\n */\n onChange: (control: string, value: ParameterValue, gesture: string | null) => void;\n /** Resets one control to its default. */\n onReset?: (control: string) => void;\n /** Controls that are keyframed: shown read-only with a note (edit them as keyframes). */\n keyframed?: ReadonlySet<string>;\n /** Applies a preset's values. */\n onPreset?: (values: Readonly<Record<string, unknown>>) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * The parameter panel of an effect, generated from its JSON Schema controls: sliders for bounded\n * numbers, switches, choices, colour pickers, vectors and text, with each control's description,\n * per-control reset and the effect's presets.\n */\nexport function EffectParameters({ description, values, onChange, onReset, keyframed, onPreset, disabled = false, className = '' }: EffectParametersProps) {\n const fields = useMemo(() => effectParameterFields(description), [description]);\n const idBase = useId();\n const gesture = React.useRef<string | null>(null);\n const count = React.useRef(0);\n return (\n <div className={`space-y-2 ${className}`} data-effect-parameters={description.id}>\n {onPreset && description.presets.length > 0 && (\n <select\n className=\"w-full rounded border border-border bg-transparent px-1 py-0.5 text-xs\"\n aria-label={`${description.name} presets`}\n value=\"\"\n disabled={disabled}\n onChange={(e) => {\n const preset = description.presets.find((p) => p.name === e.currentTarget.value);\n if (preset) onPreset({ ...description.defaults, ...preset.values });\n }}\n >\n <option value=\"\">Presets…</option>\n {description.presets.map((p) => (\n <option key={p.name} value={p.name}>\n {p.name}\n </option>\n ))}\n </select>\n )}\n {fields.map((field) => {\n const label = parameterLabel(field);\n const inputId = `${idBase}-${field.id}`;\n const keyed = keyframed?.has(field.id) ?? false;\n const value = effectFieldValue(field, values[field.id]);\n const changed = !keyed && !parameterValuesEqual(value, field.default);\n return (\n <div key={field.id} className=\"space-y-1\" data-effect-control={field.id}>\n <div className=\"flex items-center gap-1.5\">\n <label htmlFor={inputId} className=\"min-w-0 flex-1 truncate text-xs font-medium\" title={field.description}>\n {label}\n </label>\n {keyed && <span className=\"text-[10px] text-muted-foreground\">keyframed</span>}\n {onReset && changed && !disabled && (\n <button type=\"button\" className=\"rounded px-1 text-[11px] text-muted-foreground hover:text-foreground\" aria-label={`Reset ${label}`} onClick={() => onReset(field.id)}>\n ↺\n </button>\n )}\n </div>\n <ParameterFieldControl\n field={field}\n value={value}\n id={inputId}\n disabled={disabled || keyed}\n onChange={(v) => onChange(field.id, v, gesture.current)}\n onGestureStart={() => (gesture.current = `${idBase}:${field.id}:${++count.current}`)}\n onGestureEnd={() => (gesture.current = null)}\n />\n </div>\n );\n })}\n {!fields.length && <p className=\"text-[11px] text-muted-foreground\">No controls.</p>}\n </div>\n );\n}\n","import React, { useRef } from 'react';\nimport {\n choiceOptionLabel,\n formatParameterNumber,\n getChoiceOptions,\n isSliderField,\n normalizeHexColor,\n parameterLabel,\n parameterStep,\n parseParameterNumberInput,\n clampParameterNumber,\n vectorComponentField,\n vectorSize,\n type BooleanParameterField,\n type ChoiceParameterField,\n type ColorParameterField,\n type ImageParameterField,\n type NumberParameterField,\n type ParameterField,\n type ParameterKeyState,\n type ParameterValue,\n type TextParameterField,\n type VectorParameterField,\n} from '@pixerate/editor/parameters';\n\n/** Props every field control takes. Controls are controller-free: wire them to anything. */\nexport interface ParameterControlProps<F extends ParameterField, V extends ParameterValue> {\n field: F;\n value: V;\n onChange: (value: V) => void;\n /** A continuous edit (slider drag, colour pick) started: merge changes into one undo step. */\n onGestureStart?: () => void;\n onGestureEnd?: () => void;\n disabled?: boolean;\n /** DOM id of the main input (for a `<label htmlFor>`). */\n id?: string;\n}\n\nexport const parameterInputClass =\n 'h-7 w-full min-w-0 rounded-md border border-input bg-background px-2 text-xs text-foreground tabular-nums focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:cursor-not-allowed disabled:opacity-50';\nexport const parameterButtonClass =\n 'inline-flex h-7 items-center justify-center gap-1 rounded-md border border-input bg-background px-2 text-xs text-foreground hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-50';\nconst rangeClass = 'h-4 w-full min-w-0 flex-1 cursor-pointer accent-primary disabled:cursor-not-allowed disabled:opacity-50';\n\ntype CommitInputProps = {\n value: string;\n /** Called with the text and the element (e.g. to show the stored value again after a refused edit). */\n onCommit: (value: string, input: HTMLInputElement | HTMLTextAreaElement) => void;\n multiline?: boolean;\n} & Omit<React.InputHTMLAttributes<HTMLInputElement> & React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'value' | 'onChange' | 'defaultValue'>;\n\n/** A text box that commits on blur or Enter (Mod+Enter when multiline) and resets on Escape. */\nexport function ParameterCommitInput({ value, onCommit, multiline, className, onKeyDown, ...rest }: CommitInputProps) {\n const commit = (el: HTMLInputElement | HTMLTextAreaElement) => {\n if (el.value !== value) onCommit(el.value, el);\n };\n const keyDown = (e: React.KeyboardEvent<HTMLInputElement & HTMLTextAreaElement>) => {\n onKeyDown?.(e);\n if (e.defaultPrevented) return;\n if (e.key === 'Enter' && (!multiline || e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n commit(e.currentTarget);\n }\n if (e.key === 'Escape') e.currentTarget.value = value;\n };\n const props = {\n defaultValue: value,\n className: className ?? parameterInputClass,\n onBlur: (e: React.FocusEvent<HTMLInputElement & HTMLTextAreaElement>) => commit(e.currentTarget),\n onKeyDown: keyDown,\n ...rest,\n };\n // `key` remounts the box when the value changes from outside.\n return multiline ? (\n <textarea key={value} {...props} className={`${props.className} h-auto min-h-[3.5rem] py-1`} />\n ) : (\n <input key={value} type=\"text\" {...props} />\n );\n}\n\nconst plainNumber = (field: NumberParameterField, value: number) => formatParameterNumber({ ...field, unit: undefined }, value);\n\n/** A number box: type a value (units allowed), or step with the arrow keys (Shift ×10). */\nexport function ParameterNumberInput({\n field,\n value,\n onChange,\n disabled,\n id,\n 'aria-label': ariaLabel,\n}: ParameterControlProps<NumberParameterField, number> & { 'aria-label'?: string }) {\n return (\n <div className=\"relative min-w-0 flex-1\">\n <ParameterCommitInput\n id={id}\n inputMode=\"decimal\"\n aria-label={ariaLabel ?? parameterLabel(field)}\n value={plainNumber(field, value)}\n disabled={disabled || field.readOnly}\n className={`${parameterInputClass} ${field.unit ? 'pr-6' : ''}`}\n onCommit={(text, input) => {\n const n = parseParameterNumberInput(field, text);\n // Show the stored value again when the text was not a number or clamps to it.\n if (n === null || n === value) input.value = plainNumber(field, value);\n else onChange(n);\n }}\n onKeyDown={(e) => {\n if (e.key !== 'ArrowUp' && e.key !== 'ArrowDown') return;\n e.preventDefault();\n const step = parameterStep(field) * (e.shiftKey ? 10 : 1);\n onChange(clampParameterNumber(field, value + (e.key === 'ArrowUp' ? step : -step)));\n }}\n />\n {field.unit && (\n <span className=\"pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 text-[10px] text-muted-foreground\">{field.unit}</span>\n )}\n </div>\n );\n}\n\n/** A slider plus number box for `number` / `int` fields (number box only for `control: 'input'` or unbounded fields). */\nexport function ParameterSlider(props: ParameterControlProps<NumberParameterField, number>) {\n const { field, value, onChange, onGestureStart, onGestureEnd, disabled } = props;\n const dragging = useRef(false);\n const end = () => {\n if (!dragging.current) return;\n dragging.current = false;\n onGestureEnd?.();\n };\n if (!isSliderField(field)) return <ParameterNumberInput {...props} />;\n const step = parameterStep(field);\n return (\n <div className=\"flex items-center gap-2\">\n <input\n type=\"range\"\n aria-label={parameterLabel(field)}\n aria-valuetext={formatParameterNumber(field, value)}\n min={field.min}\n max={field.max}\n step={step}\n value={value}\n disabled={disabled || field.readOnly}\n className={rangeClass}\n onPointerDown={() => {\n if (dragging.current) return;\n dragging.current = true;\n onGestureStart?.();\n }}\n onPointerUp={end}\n onPointerCancel={end}\n onBlur={end}\n onChange={(e) => onChange(clampParameterNumber(field, Number(e.target.value)))}\n />\n <div className=\"w-20 shrink-0\">\n <ParameterNumberInput {...props} id={props.id} aria-label={`${parameterLabel(field)} value`} />\n </div>\n </div>\n );\n}\n\n/** An on/off switch for `boolean` fields. */\nexport function ParameterToggle({ field, value, onChange, disabled, id }: ParameterControlProps<BooleanParameterField, boolean>) {\n return (\n <button\n type=\"button\"\n role=\"switch\"\n id={id}\n aria-checked={value}\n aria-label={parameterLabel(field)}\n disabled={disabled || field.readOnly}\n onClick={() => onChange(!value)}\n className={`relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-transparent transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:opacity-50 ${\n value ? 'bg-primary' : 'bg-muted'\n }`}\n >\n <span\n className={`pointer-events-none block h-4 w-4 rounded-full bg-background shadow transition-transform ${value ? 'translate-x-4' : 'translate-x-0.5'}`}\n />\n </button>\n );\n}\n\n/** A dropdown (or segmented buttons with `control: 'segmented'`) for `choice` fields. */\nexport function ParameterSelect({ field, value, onChange, disabled, id }: ParameterControlProps<ChoiceParameterField, string | number>) {\n const options = getChoiceOptions(field);\n const off = disabled || field.readOnly;\n if (field.control === 'segmented') {\n return (\n <div role=\"radiogroup\" aria-label={parameterLabel(field)} className=\"inline-flex flex-wrap rounded-md border border-input bg-muted p-0.5\">\n {options.map((o) => (\n <button\n key={String(o.value)}\n type=\"button\"\n role=\"radio\"\n aria-checked={o.value === value}\n title={o.description}\n disabled={off}\n onClick={() => onChange(o.value)}\n className={`rounded px-2 py-0.5 text-xs disabled:opacity-50 ${\n o.value === value ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'\n }`}\n >\n {choiceOptionLabel(o)}\n </button>\n ))}\n </div>\n );\n }\n const index = options.findIndex((o) => o.value === value);\n return (\n <select\n id={id}\n aria-label={parameterLabel(field)}\n value={String(index)}\n disabled={off}\n onChange={(e) => {\n const option = options[Number(e.target.value)];\n if (option) onChange(option.value);\n }}\n className={parameterInputClass}\n >\n {options.map((o, i) => (\n <option key={String(o.value)} value={String(i)} title={o.description}>\n {choiceOptionLabel(o)}\n </option>\n ))}\n </select>\n );\n}\n\n/** A colour picker with a hex box, an alpha slider (with `alpha`) and swatches. */\nexport function ParameterColor({ field, value, onChange, onGestureStart, onGestureEnd, disabled, id }: ParameterControlProps<ColorParameterField, string>) {\n const picking = useRef(false);\n const alpha = !!field.alpha;\n const hex = normalizeHexColor(value, true) ?? '#000000ff';\n const rgb = hex.slice(0, 7);\n const a = hex.slice(7);\n const off = disabled || field.readOnly;\n const start = () => {\n if (picking.current) return;\n picking.current = true;\n onGestureStart?.();\n };\n const end = () => {\n if (!picking.current) return;\n picking.current = false;\n onGestureEnd?.();\n };\n return (\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-2\">\n <span className=\"relative h-7 w-9 shrink-0 overflow-hidden rounded-md border border-input bg-[repeating-conic-gradient(#d4d4d8_0_25%,#fff_0_50%)] bg-[length:8px_8px]\">\n <span className=\"absolute inset-0\" style={{ background: alpha ? hex : rgb }} />\n <input\n type=\"color\"\n aria-label={parameterLabel(field)}\n value={rgb}\n disabled={off}\n className=\"absolute inset-0 h-full w-full cursor-pointer opacity-0 disabled:cursor-not-allowed\"\n onChange={(e) => {\n start();\n onChange(alpha ? `${e.target.value}${a}` : e.target.value);\n }}\n onBlur={end}\n />\n </span>\n <ParameterCommitInput\n id={id}\n aria-label={`${parameterLabel(field)} hex`}\n value={alpha ? hex : rgb}\n disabled={off}\n spellCheck={false}\n className={`${parameterInputClass} font-mono`}\n onCommit={(text) => {\n const next = normalizeHexColor(text, alpha);\n if (next) onChange(next);\n }}\n />\n </div>\n {alpha && (\n <input\n type=\"range\"\n aria-label={`${parameterLabel(field)} opacity`}\n min={0}\n max={255}\n step={1}\n value={parseInt(a, 16)}\n disabled={off}\n className={rangeClass}\n onPointerDown={start}\n onPointerUp={end}\n onPointerCancel={end}\n onBlur={end}\n onChange={(e) => onChange(`${rgb}${Number(e.target.value).toString(16).padStart(2, '0')}`)}\n />\n )}\n {field.swatches && field.swatches.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {field.swatches.map((s) => {\n const swatch = normalizeHexColor(s, alpha);\n if (!swatch) return null;\n return (\n <button\n key={s}\n type=\"button\"\n title={swatch}\n aria-label={`${parameterLabel(field)} ${swatch}`}\n aria-pressed={swatch === (alpha ? hex : rgb)}\n disabled={off}\n onClick={() => onChange(swatch)}\n className=\"h-5 w-5 rounded border border-input aria-pressed:ring-1 aria-pressed:ring-primary\"\n style={{ background: swatch }}\n />\n );\n })}\n </div>\n )}\n </div>\n );\n}\n\n/** One number box per component for `vector` fields. */\nexport function ParameterVector({ field, value, onChange, disabled, id }: ParameterControlProps<VectorParameterField, number[]>) {\n const size = vectorSize(field);\n return (\n <div className=\"grid gap-1.5\" style={{ gridTemplateColumns: `repeat(${size}, minmax(0, 1fr))` }}>\n {Array.from({ length: size }, (_, i) => {\n const component = vectorComponentField(field, i);\n return (\n <label key={i} className=\"flex min-w-0 items-center gap-1\">\n <span className=\"w-3 shrink-0 text-[10px] uppercase text-muted-foreground\">{component.label}</span>\n <ParameterNumberInput\n field={component}\n value={value[i] ?? 0}\n id={i === 0 ? id : undefined}\n aria-label={`${parameterLabel(field)} ${component.label}`}\n disabled={disabled || field.readOnly}\n onChange={(n) => onChange(Array.from({ length: size }, (_, j) => (j === i ? n : (value[j] ?? 0))))}\n />\n </label>\n );\n })}\n </div>\n );\n}\n\nexport interface ParameterImageProps extends ParameterControlProps<ImageParameterField, string> {\n /** Turns a picked file into a URL (upload it, or `URL.createObjectURL`). Without it there is no file button. */\n resolveFile?: (file: File) => string | Promise<string>;\n}\n\n/** An image picker: suggested thumbnails, a URL box, an optional file button and a clear button. */\nexport function ParameterImage({ field, value, onChange, disabled, id, resolveFile }: ParameterImageProps) {\n const off = disabled || field.readOnly;\n const name = parameterLabel(field);\n return (\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-2\">\n <div className=\"flex h-12 w-16 shrink-0 items-center justify-center overflow-hidden rounded-md border border-input bg-muted\">\n {value ? (\n <img src={value} alt={name} className=\"h-full w-full object-cover\" />\n ) : (\n <span className=\"text-[10px] text-muted-foreground\">None</span>\n )}\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n <ParameterCommitInput\n id={id}\n aria-label={`${name} URL`}\n placeholder=\"Image URL\"\n value={value.startsWith('data:') ? '' : value}\n disabled={off}\n onCommit={(text) => onChange(text.trim())}\n />\n <div className=\"flex gap-1\">\n {resolveFile && (\n <label className={`${parameterButtonClass} cursor-pointer ${off ? 'pointer-events-none opacity-50' : ''}`}>\n Choose file…\n <input\n type=\"file\"\n className=\"sr-only\"\n accept={field.accept ?? 'image/*'}\n disabled={off}\n aria-label={`${name} file`}\n onChange={async (e) => {\n const file = e.target.files?.[0];\n e.target.value = '';\n if (file) onChange(await resolveFile(file));\n }}\n />\n </label>\n )}\n {value && (\n <button type=\"button\" className={parameterButtonClass} disabled={off} onClick={() => onChange('')} aria-label={`Clear ${name}`}>\n Clear\n </button>\n )}\n </div>\n </div>\n </div>\n {field.options && field.options.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {field.options.map((o) => (\n <button\n key={o.url}\n type=\"button\"\n title={o.label ?? o.url}\n aria-label={o.label ?? o.url}\n aria-pressed={o.url === value}\n disabled={off}\n onClick={() => onChange(o.url)}\n className=\"h-9 w-12 overflow-hidden rounded border border-input aria-pressed:ring-2 aria-pressed:ring-primary\"\n >\n <img src={o.url} alt=\"\" className=\"h-full w-full object-cover\" />\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/** A text box (or textarea with `multiline`) that commits on blur or Enter. */\nexport function ParameterText({ field, value, onChange, disabled, id }: ParameterControlProps<TextParameterField, string>) {\n return (\n <ParameterCommitInput\n id={id}\n aria-label={parameterLabel(field)}\n multiline={field.multiline}\n placeholder={field.placeholder}\n maxLength={field.maxLength}\n value={value}\n disabled={disabled || field.readOnly}\n onCommit={onChange}\n />\n );\n}\n\nexport interface KeyframeDiamondProps {\n state: ParameterKeyState;\n onToggle: () => void;\n /** The parameter's label (for the accessible name). */\n label: string;\n disabled?: boolean;\n className?: string;\n}\n\n/** A keyframe toggle: filled when a key sits at the playhead, tinted when the value is animated. */\nexport function KeyframeDiamond({ state, onToggle, label, disabled, className = '' }: KeyframeDiamondProps) {\n const keyed = state === 'keyed';\n return (\n <button\n type=\"button\"\n data-key-state={state}\n aria-pressed={keyed}\n aria-label={`${keyed ? 'Remove' : 'Add'} keyframe for ${label}`}\n title={keyed ? 'Remove keyframe here' : 'Add keyframe at the playhead'}\n disabled={disabled}\n onClick={onToggle}\n className={`inline-flex h-4 w-4 shrink-0 items-center justify-center rounded-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:opacity-40 ${\n state === 'none' ? 'text-muted-foreground hover:text-foreground' : 'text-amber-500'\n } ${className}`}\n >\n <svg viewBox=\"0 0 10 10\" className=\"h-2.5 w-2.5\" aria-hidden=\"true\">\n <path\n d=\"M5 0.8 9.2 5 5 9.2 0.8 5Z\"\n fill={keyed ? 'currentColor' : 'none'}\n stroke=\"currentColor\"\n strokeWidth=\"1.3\"\n opacity={state === 'animated' ? 0.7 : 1}\n />\n </svg>\n </button>\n );\n}\n\nexport interface ParameterFieldControlProps extends ParameterControlProps<ParameterField, ParameterValue> {\n resolveFile?: ParameterImageProps['resolveFile'];\n}\n\n/** The control for any field type. */\nexport function ParameterFieldControl({ field, value, onChange, resolveFile, ...rest }: ParameterFieldControlProps) {\n const set = onChange as (value: any) => void;\n switch (field.type) {\n case 'number':\n case 'int':\n return <ParameterSlider field={field} value={value as number} onChange={set} {...rest} />;\n case 'boolean':\n return <ParameterToggle field={field} value={value as boolean} onChange={set} {...rest} />;\n case 'choice':\n return <ParameterSelect field={field} value={value as string | number} onChange={set} {...rest} />;\n case 'color':\n return <ParameterColor field={field} value={value as string} onChange={set} {...rest} />;\n case 'vector':\n return <ParameterVector field={field} value={value as number[]} onChange={set} {...rest} />;\n case 'image':\n return <ParameterImage field={field} value={value as string} onChange={set} resolveFile={resolveFile} {...rest} />;\n case 'text':\n return <ParameterText field={field} value={value as string} onChange={set} {...rest} />;\n }\n}\n\n","import React, { useEffect, useState } from 'react';\nimport type { ImageEditorController } from '@pixerate/editor/image-editor';\nimport {\n BRUSH_OPTION_CONTROLS,\n MIXER_MIXING_OPTIONS,\n MIXER_OPTION_CONTROLS,\n PAINT_TOOLS,\n RETOUCH_CHOICES,\n RETOUCH_OPTION_CONTROLS,\n RETOUCH_TOGGLES,\n cloneSourceLabel,\n isRetouchPaintTool,\n rgbUnitToHex,\n setRetouchChoice,\n} from '@pixerate/editor/image-editor';\nimport { DEFAULT_PAINT_GRADIENT } from '@pixerate/editor/image-editor';\nimport { PaintGradientEditor } from './PaintGradientEditor';\nimport { ControlSlider } from './ControlSlider';\n\nexport interface BrushOptionsBarProps {\n controller: ImageEditorController;\n className?: string;\n}\n\nconst chip = (on: boolean) => `px-2 py-1 rounded text-[11px] ${on ? 'bg-indigo-600 text-white' : 'bg-slate-800 text-slate-300 hover:text-white'}`;\n\n/**\n * The paint tools: Move / Brush / Mixer / Eraser, the brush's size, hardness, opacity, flow and\n * smoothing, pressure toggles, the foreground and background colours (D resets, X swaps) and\n * Edit › Fill / Clear on the active layer, and gradient paint for the brush (the colour changes as\n * the stroke goes; `PaintGradientEditor`). With the Mixer Brush: its load (Load brush / Clean\n * brush), Wet / Load / Mix, load and clean each stroke, and the RGB / Pigment mixing toggle.\n * With a retouching tool: the clone source (Alt-click the canvas to set it), Sample, the Spot\n * Healing type, the tone Range, Exposure / Strength and the Aligned / Protect tones / Vibrance\n * toggles that tool uses.\n * Shortcuts are handled by `handlePaintShortcut` in the editor.\n */\nexport const BrushOptionsBar: React.FC<BrushOptionsBarProps> = ({ controller, className }) => {\n const [, setTick] = useState(0);\n useEffect(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);\n const [error, setError] = useState<string | null>(null);\n const state = controller.getState();\n const { brush, foreground, background, mixer, mixerLoad, retouch, cloneSource, paint } = state.paint;\n const tool = state.activeTool as (typeof PAINT_TOOLS)[number]['id'];\n const attempt = (fn: () => unknown) => {\n try {\n setError(null);\n fn();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n }\n };\n\n return (\n <div className={`flex flex-col gap-2 text-xs text-slate-200 ${className ?? ''}`} data-testid=\"brush-options\">\n <div className=\"flex flex-wrap gap-1\" role=\"toolbar\" aria-label=\"Paint tools\">\n {PAINT_TOOLS.map((t) => (\n <button\n key={t.id}\n type=\"button\"\n aria-pressed={state.activeTool === t.id}\n title={t.shortcut ? `${t.label} (${t.shortcut})` : t.label}\n className={chip(state.activeTool === t.id)}\n onClick={() => controller.setTool(t.id)}\n >\n {t.label}\n </button>\n ))}\n </div>\n\n <div className=\"flex items-center gap-2\" role=\"group\" aria-label=\"Colours\">\n <label className=\"flex items-center gap-1\">\n <input\n type=\"color\"\n aria-label=\"Foreground colour\"\n value={foreground}\n onChange={(e) => controller.setPaintOptions({ foreground: e.target.value })}\n className=\"h-6 w-8 rounded border border-slate-700 bg-transparent\"\n />\n <span className=\"text-slate-400\">FG</span>\n </label>\n <label className=\"flex items-center gap-1\">\n <input\n type=\"color\"\n aria-label=\"Background colour\"\n value={background}\n onChange={(e) => controller.setPaintOptions({ background: e.target.value })}\n className=\"h-6 w-8 rounded border border-slate-700 bg-transparent\"\n />\n <span className=\"text-slate-400\">BG</span>\n </label>\n <button type=\"button\" title=\"Swap colours (X)\" className={chip(false)} onClick={() => controller.swapPaintColors()}>\n Swap\n </button>\n <button type=\"button\" title=\"Default colours (D)\" className={chip(false)} onClick={() => controller.resetPaintColors()}>\n Default\n </button>\n {state.activeTool === 'brush' && (\n <button\n type=\"button\"\n aria-pressed={paint.type === 'gradient'}\n title=\"Gradient paint: the brush changes colour as the stroke goes\"\n className={chip(paint.type === 'gradient')}\n onClick={() => attempt(() => controller.setPaintOptions(paint.type === 'gradient' ? { foreground } : { paint: DEFAULT_PAINT_GRADIENT }))}\n >\n Gradient\n </button>\n )}\n </div>\n {state.activeTool === 'brush' && paint.type === 'gradient' && (\n <PaintGradientEditor value={paint} colors={{ paint: foreground, secondary: background }} onChange={(g) => attempt(() => controller.setPaintOptions({ paint: g }))} />\n )}\n\n {BRUSH_OPTION_CONTROLS.map((spec) => (\n <ControlSlider\n key={spec.id}\n spec={spec}\n value={brush[spec.id]}\n onChange={(v) => controller.setPaintOptions({ brush: { [spec.id]: v } })}\n />\n ))}\n\n {state.activeTool === 'mixer' && (\n <div className=\"flex flex-col gap-2 border-t border-slate-800 pt-2\" role=\"group\" aria-label=\"Mixer Brush\" data-testid=\"mixer-options\">\n <div className=\"flex items-center gap-2\">\n <span\n aria-label=\"Brush load\"\n title={mixerLoad.reservoir ? `Loaded ${rgbUnitToHex(mixerLoad.reservoir)}, ${Math.round(mixerLoad.amount * 100)}% left` : 'Unloaded'}\n className=\"h-6 w-6 rounded border border-slate-700\"\n style={{ background: mixerLoad.reservoir ? rgbUnitToHex(mixerLoad.reservoir) : 'transparent' }}\n />\n <button type=\"button\" title=\"Fill the reservoir with the foreground colour\" className={chip(false)} onClick={() => controller.loadMixerBrush()}>\n Load brush\n </button>\n <button type=\"button\" title=\"Empty the picked-up colour\" className={chip(false)} onClick={() => controller.cleanMixerBrush()}>\n Clean brush\n </button>\n </div>\n <div className=\"flex gap-1\" role=\"group\" aria-label=\"Mixing\">\n {MIXER_MIXING_OPTIONS.map((m) => (\n <button\n key={m.id}\n type=\"button\"\n aria-pressed={mixer.mixing === m.id}\n title={m.title}\n className={chip(mixer.mixing === m.id)}\n onClick={() => controller.setPaintOptions({ mixer: { mixing: m.id } })}\n >\n {m.label}\n </button>\n ))}\n </div>\n {MIXER_OPTION_CONTROLS.map((spec) => (\n <ControlSlider key={spec.id} spec={spec} value={mixer[spec.id]} onChange={(v) => controller.setPaintOptions({ mixer: { [spec.id]: v } })} />\n ))}\n <div className=\"flex flex-wrap gap-3 text-slate-300\">\n <label className=\"flex items-center gap-1.5\">\n <input\n type=\"checkbox\"\n aria-label=\"Load the brush after each stroke\"\n checked={mixer.loadEachStroke}\n onChange={(e) => controller.setPaintOptions({ mixer: { loadEachStroke: e.target.checked } })}\n className=\"accent-indigo-500\"\n />\n Load each stroke\n </label>\n <label className=\"flex items-center gap-1.5\">\n <input\n type=\"checkbox\"\n aria-label=\"Clean the brush after each stroke\"\n checked={mixer.cleanEachStroke}\n onChange={(e) => controller.setPaintOptions({ mixer: { cleanEachStroke: e.target.checked } })}\n className=\"accent-indigo-500\"\n />\n Clean each stroke\n </label>\n </div>\n </div>\n )}\n\n {isRetouchPaintTool(tool) && (\n <div className=\"flex flex-col gap-2 border-t border-slate-800 pt-2\" role=\"group\" aria-label=\"Retouch options\" data-testid=\"retouch-options\">\n {(tool === 'clone' || tool === 'heal') && (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-slate-400\" data-testid=\"clone-source\">\n {cloneSourceLabel(controller)}\n </span>\n {cloneSource && (\n <button type=\"button\" title=\"Forget the source point\" className={chip(false)} onClick={() => controller.setCloneSource(null)}>\n Clear source\n </button>\n )}\n </div>\n )}\n {RETOUCH_CHOICES.filter((c) => c.tools.includes(tool)).map((choice) => (\n <div key={choice.id} className=\"flex flex-wrap items-center gap-1\" role=\"group\" aria-label={choice.label}>\n <span className=\"text-slate-400\">{choice.label}</span>\n {choice.options.map((o) => (\n <button\n key={o.id}\n type=\"button\"\n aria-pressed={retouch[choice.id] === o.id}\n title={o.title}\n className={chip(retouch[choice.id] === o.id)}\n onClick={() => setRetouchChoice(controller, choice.id, o.id)}\n >\n {o.label}\n </button>\n ))}\n </div>\n ))}\n {RETOUCH_OPTION_CONTROLS.filter((c) => c.tools.includes(tool)).map((spec) => (\n <ControlSlider key={spec.id} spec={spec} value={retouch[spec.id]} onChange={(v) => controller.setPaintOptions({ retouch: { [spec.id]: v } })} />\n ))}\n <div className=\"flex flex-wrap gap-3 text-slate-300\">\n {RETOUCH_TOGGLES.filter((t) => t.tools.includes(tool)).map((t) => (\n <label key={t.id} className=\"flex items-center gap-1.5\">\n <input\n type=\"checkbox\"\n aria-label={t.label}\n checked={retouch[t.id]}\n onChange={(e) => controller.setPaintOptions({ retouch: { [t.id]: e.target.checked } })}\n className=\"accent-indigo-500\"\n />\n {t.label}\n </label>\n ))}\n </div>\n </div>\n )}\n\n <div className=\"flex flex-wrap gap-3 text-slate-300\" role=\"group\" aria-label=\"Pressure\">\n <label className=\"flex items-center gap-1.5\">\n <input\n type=\"checkbox\"\n aria-label=\"Pressure controls size\"\n checked={brush.pressureSize}\n onChange={(e) => controller.setPaintOptions({ brush: { pressureSize: e.target.checked } })}\n className=\"accent-indigo-500\"\n />\n Pressure size\n </label>\n <label className=\"flex items-center gap-1.5\">\n <input\n type=\"checkbox\"\n aria-label=\"Pressure controls opacity\"\n checked={brush.pressureOpacity}\n onChange={(e) => controller.setPaintOptions({ brush: { pressureOpacity: e.target.checked } })}\n className=\"accent-indigo-500\"\n />\n Pressure opacity\n </label>\n </div>\n\n <div className=\"flex gap-1\">\n <button type=\"button\" className={chip(false)} onClick={() => attempt(() => controller.fillPixels())}>\n Fill\n </button>\n <button type=\"button\" className={chip(false)} onClick={() => attempt(() => controller.clearPixels())}>\n Clear\n </button>\n </div>\n {error && (\n <p role=\"alert\" className=\"text-rose-400\">\n {error}\n </p>\n )}\n </div>\n );\n};\n","import React from 'react';\nimport { PAINT_GRADIENT_KIT } from '@pixerate/editor/image-editor';\nimport { PaintGradientEditorView, type PaintGradientEditorProps } from '../paint-editor/PaintGradientEditorView';\n\nexport type { PaintGradientEditorProps } from '../paint-editor/PaintGradientEditorView';\n\n/** The gradient paint editor for the image editor's brush (see `PaintGradientEditorView`). */\nexport const PaintGradientEditor: React.FC<PaintGradientEditorProps> = (props) => <PaintGradientEditorView {...props} kit={PAINT_GRADIENT_KIT} />;\n","import React, { useState } from 'react';\nimport type { PaintGradientKit, PaintGradientMappingKind, PaintGradientRepeat, PaintGradientSource, PaintGradientSpace } from '@pixerate/editor/paint-editor';\n\nexport interface PaintGradientEditorProps {\n value: PaintGradientSource;\n onChange: (paint: PaintGradientSource) => void;\n /** What `paint` / `secondary` stops show as (the editor's two colours). */\n colors: { paint: string; secondary: string };\n className?: string;\n}\n\nexport interface PaintGradientEditorViewProps extends PaintGradientEditorProps {\n /** The gradient helpers (`PAINT_GRADIENT_KIT`, from the editor's own entry). */\n kit: PaintGradientKit;\n}\n\nconst button = 'px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-200 hover:bg-slate-700 disabled:opacity-40';\nconst select = 'rounded bg-slate-800 px-1 py-0.5 text-[11px]';\nconst number = 'w-16 rounded bg-slate-800 px-1 py-0.5 text-[11px]';\nconst pct = (v: number) => Math.round(v * 1000) / 10;\n\n/**\n * Gradient paint editor (the vector editor's stop ramp, for paint): click the ramp to add a stop,\n * pick a stop to edit its colour (or the paint / second colour), opacity, position and midpoint;\n * the mixing space, what moves the stroke along it (distance with length and repeat, pressure,\n * tilt, speed, direction, time, across the tip, random), softness, reverse, and starting presets.\n */\nexport const PaintGradientEditorView: React.FC<PaintGradientEditorViewProps> = ({ value, onChange, colors, className, kit }) => {\n const {\n PAINT_GRADIENT_MAPPINGS,\n PAINT_GRADIENT_MAPPING_LABELS,\n PAINT_GRADIENT_PRESETS,\n PAINT_GRADIENT_REPEATS,\n PAINT_GRADIENT_REPEAT_LABELS,\n PAINT_GRADIENT_SPACES,\n PAINT_GRADIENT_SPACE_LABELS,\n addPaintGradientStop,\n paintGradientMappingFor,\n paintSourceCss,\n removePaintGradientStop,\n reversePaintGradient,\n updatePaintGradientStop,\n } = kit;\n const [selected, setSelected] = useState(0);\n const sel = Math.min(selected, value.stops.length - 1);\n const stop = value.stops[sel];\n const map = value.map;\n const stopHex = (c: string) => (c === 'paint' ? colors.paint : c === 'secondary' ? colors.secondary : c);\n const patchStop = (patch: Parameters<PaintGradientKit['updatePaintGradientStop']>[2]) => {\n const r = updatePaintGradientStop(value, sel, patch);\n setSelected(r.index);\n onChange(r.paint);\n };\n return (\n <div className={`flex flex-col gap-1.5 text-xs text-slate-200 ${className ?? ''}`} data-testid=\"paint-gradient-editor\" aria-label=\"Gradient paint\">\n <div className=\"flex items-center gap-1\">\n <select aria-label=\"Gradient preset\" className={select} value=\"\" onChange={(e) => e.target.value && (setSelected(0), onChange(PAINT_GRADIENT_PRESETS[Number(e.target.value)].paint))}>\n <option value=\"\">Presets…</option>\n {PAINT_GRADIENT_PRESETS.map((p, i) => (\n <option key={p.name} value={i}>\n {p.name}\n </option>\n ))}\n </select>\n <button type=\"button\" className={button} onClick={() => onChange(reversePaintGradient(value))}>\n Reverse\n </button>\n </div>\n <div\n role=\"slider\"\n tabIndex={0}\n aria-label=\"Gradient ramp: click to add a stop\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={pct(stop.offset)}\n data-testid=\"paint-gradient-ramp\"\n className=\"relative h-6 cursor-copy rounded ring-1 ring-slate-700\"\n style={{ background: paintSourceCss(value, colors) }}\n onClick={(e) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const r = addPaintGradientStop(value, rect.width ? (e.clientX - rect.left) / rect.width : 0.5, colors);\n if (r.index >= 0) {\n setSelected(r.index);\n onChange(r.paint);\n }\n }}\n />\n <div className=\"relative h-4\" aria-label=\"Stops\">\n {value.stops.map((s, i) => (\n <button\n key={i}\n type=\"button\"\n aria-label={`Stop ${i + 1} at ${pct(s.offset)}%`}\n aria-pressed={i === sel}\n className={`absolute top-0 h-4 w-3 -translate-x-1/2 rounded-sm ring-1 ${i === sel ? 'ring-white' : 'ring-slate-600'}`}\n style={{ left: `${s.offset * 100}%`, background: stopHex(s.color) }}\n onClick={() => setSelected(i)}\n />\n ))}\n </div>\n <div className=\"flex flex-wrap items-center gap-1\" data-testid=\"paint-gradient-stop\">\n <select aria-label=\"Stop colour source\" className={select} value={stop.color === 'paint' || stop.color === 'secondary' ? stop.color : 'color'} onChange={(e) => patchStop({ color: e.target.value === 'color' ? stopHex(stop.color) : e.target.value })}>\n <option value=\"color\">Colour</option>\n <option value=\"paint\">Paint colour</option>\n <option value=\"secondary\">Second colour</option>\n </select>\n {stop.color !== 'paint' && stop.color !== 'secondary' && <input type=\"color\" aria-label=\"Stop colour\" value={stop.color} onChange={(e) => patchStop({ color: e.target.value })} className=\"h-6 w-8 rounded bg-transparent\" />}\n <label className=\"flex items-center gap-1\">\n At\n <input type=\"number\" aria-label=\"Stop position\" min={0} max={100} step={1} value={pct(stop.offset)} onChange={(e) => patchStop({ offset: Number(e.target.value) / 100 })} className={number} />%\n </label>\n <label className=\"flex items-center gap-1\">\n Opacity\n <input type=\"number\" aria-label=\"Stop opacity\" min={0} max={100} step={5} value={pct(stop.opacity ?? 1)} onChange={(e) => patchStop({ opacity: Number(e.target.value) / 100 })} className={number} />%\n </label>\n {sel < value.stops.length - 1 && (\n <label className=\"flex items-center gap-1\">\n Midpoint\n <input type=\"number\" aria-label=\"Stop midpoint\" min={5} max={95} step={1} value={pct(stop.midpoint ?? 0.5)} onChange={(e) => patchStop({ midpoint: Number(e.target.value) / 100 })} className={number} />%\n </label>\n )}\n <button type=\"button\" className={button} disabled={value.stops.length <= 2} onClick={() => (setSelected(Math.max(0, sel - 1)), onChange(removePaintGradientStop(value, sel)))}>\n Remove stop\n </button>\n </div>\n <div className=\"flex flex-wrap items-center gap-1\" data-testid=\"paint-gradient-mapping\">\n <select aria-label=\"Gradient follows\" className={select} value={map.by} onChange={(e) => onChange({ ...value, map: paintGradientMappingFor(e.target.value as PaintGradientMappingKind, map) })}>\n {PAINT_GRADIENT_MAPPINGS.map((m) => (\n <option key={m} value={m}>\n {PAINT_GRADIENT_MAPPING_LABELS[m]}\n </option>\n ))}\n </select>\n {map.by === 'distance' && (\n <>\n <input type=\"number\" aria-label=\"Gradient length\" min={1} max={100000} value={map.length} onChange={(e) => onChange({ ...value, map: { ...map, length: Math.max(1, Number(e.target.value) || 1) } })} className={number} />\n <select aria-label=\"Gradient length unit\" className={select} value={map.unit ?? 'px'} onChange={(e) => onChange({ ...value, map: { ...map, unit: e.target.value as 'px' | 'dabs' } })}>\n <option value=\"px\">px</option>\n <option value=\"dabs\">dabs</option>\n </select>\n </>\n )}\n {map.by === 'time' && <input type=\"number\" aria-label=\"Gradient duration\" min={1} max={600000} value={map.duration} onChange={(e) => onChange({ ...value, map: { ...map, duration: Math.max(1, Number(e.target.value) || 1) } })} className={number} />}\n {map.by === 'random' && <input type=\"number\" aria-label=\"Dabs per pick\" min={1} max={500} value={map.every ?? 1} onChange={(e) => onChange({ ...value, map: { ...map, every: Math.max(1, Math.round(Number(e.target.value) || 1)) } })} className={number} />}\n {(map.by === 'distance' || map.by === 'time') && (\n <select aria-label=\"Gradient repeat\" className={select} value={map.repeat ?? 'clamp'} onChange={(e) => onChange({ ...value, map: { ...map, repeat: e.target.value as PaintGradientRepeat } })}>\n {PAINT_GRADIENT_REPEATS.map((r) => (\n <option key={r} value={r}>\n {PAINT_GRADIENT_REPEAT_LABELS[r]}\n </option>\n ))}\n </select>\n )}\n </div>\n <div className=\"flex items-center gap-1\">\n <select aria-label=\"Gradient mixing\" className={select} value={value.space} onChange={(e) => onChange({ ...value, space: e.target.value as PaintGradientSpace })}>\n {PAINT_GRADIENT_SPACES.map((s) => (\n <option key={s} value={s}>\n {PAINT_GRADIENT_SPACE_LABELS[s]}\n </option>\n ))}\n </select>\n <label className=\"flex flex-1 items-center gap-1\">\n Softness\n <input type=\"range\" aria-label=\"Gradient softness\" min={0} max={1} step={0.05} value={value.softness ?? 1} onChange={(e) => onChange({ ...value, softness: Number(e.target.value) })} className=\"flex-1 accent-indigo-500\" />\n </label>\n </div>\n </div>\n );\n};\n","import React, { useEffect, useState } from 'react';\nimport type { ImageEditorController, Intent } from '@pixerate/editor/image-editor';\nimport { COLOR_MODE_OPTIONS, INTENT_OPTIONS, PROOF_PROFILE_OPTIONS, WORKING_SPACE_OPTIONS, colorPanelView } from '@pixerate/editor/image-editor';\n\nexport interface ColorProfilePanelProps {\n controller: ImageEditorController;\n className?: string;\n}\n\nconst chip = 'px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white';\nconst select = 'rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200';\n\n/**\n * Colour management: the document's profile (working space) with Assign Profile and Convert to\n * Profile (intent, black point compensation), Image › Mode (RGB, CMYK, Lab), and View › Proof\n * Setup (profile, intent, simulate paper, gamut warning).\n */\nexport const ColorProfilePanel: React.FC<ColorProfilePanelProps> = ({ controller, className }) => {\n const [, setTick] = useState(0);\n useEffect(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);\n const [target, setTarget] = useState<string>('display-p3');\n const [intent, setIntent] = useState<Intent>('relative');\n const [bpc, setBpc] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const view = colorPanelView(controller);\n const attempt = (fn: () => unknown) => {\n try {\n setError(null);\n fn();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n }\n };\n const proofWith = (patch: Partial<{ id: string; intent: Intent; simulatePaper: boolean; gamutWarning: boolean }>) => {\n const cur = view.proof;\n const id = patch.id ?? cur?.id ?? 'coated-cmyk';\n attempt(() =>\n controller.setProofSetup({\n profile: id,\n intent: patch.intent ?? cur?.intent ?? 'relative',\n simulatePaper: patch.simulatePaper ?? cur?.simulatePaper ?? false,\n gamutWarning: patch.gamutWarning ?? cur?.gamutWarning ?? false,\n })\n );\n };\n\n return (\n <div className={`flex flex-col gap-2 text-xs text-slate-200 ${className ?? ''}`} data-testid=\"color-profile-panel\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-slate-400\">Profile</span>\n <span data-testid=\"color-profile-name\">{view.profileName}</span>\n </div>\n <div className=\"flex flex-wrap items-center gap-1\" role=\"group\" aria-label=\"Colour mode\">\n <span className=\"text-slate-400\">Mode</span>\n <select aria-label=\"Colour mode\" className={select} value={view.mode} onChange={(e) => attempt(() => controller.setColorMode(e.target.value as 'rgb' | 'cmyk' | 'lab'))}>\n {COLOR_MODE_OPTIONS.map((o) => (\n <option key={o.id} value={o.id} title={o.title}>\n {o.label}\n </option>\n ))}\n </select>\n {view.cmykProfileName && <span className=\"text-slate-400\">{view.cmykProfileName}</span>}\n </div>\n <div className=\"flex flex-wrap items-center gap-1\" role=\"group\" aria-label=\"Assign or convert\">\n <select aria-label=\"Target profile\" className={select} value={target} onChange={(e) => setTarget(e.target.value)}>\n {WORKING_SPACE_OPTIONS.map((o) => (\n <option key={o.id} value={o.id}>\n {o.label}\n </option>\n ))}\n </select>\n <select aria-label=\"Rendering intent\" className={select} value={intent} onChange={(e) => setIntent(e.target.value as Intent)}>\n {INTENT_OPTIONS.map((o) => (\n <option key={o.id} value={o.id} title={o.title}>\n {o.label}\n </option>\n ))}\n </select>\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" aria-label=\"Black point compensation\" checked={bpc} onChange={(e) => setBpc(e.target.checked)} className=\"accent-indigo-500\" />\n BPC\n </label>\n <button type=\"button\" className={chip} title=\"Edit › Assign Profile: keep the numbers\" onClick={() => attempt(() => controller.assignProfile(target))}>\n Assign\n </button>\n <button type=\"button\" className={chip} title=\"Edit › Convert to Profile: keep the look\" onClick={() => attempt(() => controller.convertToProfile(target, { intent, bpc }))}>\n Convert\n </button>\n </div>\n <div className=\"flex flex-wrap items-center gap-1\" role=\"group\" aria-label=\"Proof setup\">\n <span className=\"text-slate-400\">Proof</span>\n <select\n aria-label=\"Proof profile\"\n className={select}\n value={view.proof?.id ?? ''}\n onChange={(e) => (e.target.value ? proofWith({ id: e.target.value }) : attempt(() => controller.setProofSetup(null)))}\n >\n <option value=\"\">Off</option>\n {PROOF_PROFILE_OPTIONS.map((o) => (\n <option key={o.id} value={o.id}>\n {o.label}\n </option>\n ))}\n </select>\n {view.proof && (\n <>\n <select aria-label=\"Proof intent\" className={select} value={view.proof.intent} onChange={(e) => proofWith({ intent: e.target.value as Intent })}>\n {INTENT_OPTIONS.map((o) => (\n <option key={o.id} value={o.id}>\n {o.label}\n </option>\n ))}\n </select>\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" aria-label=\"Simulate paper colour\" checked={view.proof.simulatePaper} onChange={(e) => proofWith({ simulatePaper: e.target.checked })} className=\"accent-indigo-500\" />\n Paper\n </label>\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" aria-label=\"Gamut warning\" checked={view.proof.gamutWarning} onChange={(e) => proofWith({ gamutWarning: e.target.checked })} className=\"accent-indigo-500\" />\n Gamut warning\n </label>\n </>\n )}\n </div>\n {error && (\n <p role=\"alert\" className=\"text-rose-400\">\n {error}\n </p>\n )}\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport type { ImageEditorController, SelectionMask, SelectionModifyOp, SelectionToolOptions } from '@pixerate/editor/image-editor';\nimport {\n SELECTION_MODES,\n SELECTION_MODE_LABELS,\n SELECTION_TOOLS,\n describeSelection,\n} from '@pixerate/editor/image-editor';\n\nexport interface SelectionOptionsBarProps {\n controller: ImageEditorController;\n options: SelectionToolOptions;\n onOptionsChange: (next: SelectionToolOptions) => void;\n /** The current selection (pass `state.selection` so the bar re-renders with it). */\n selection?: SelectionMask | null;\n /** The current Quick Mask view flag (`state.quickMask`). */\n quickMask?: boolean;\n className?: string;\n}\n\nconst MODIFY_OPS: { op: SelectionModifyOp; label: string }[] = [\n { op: 'grow', label: 'Grow' },\n { op: 'shrink', label: 'Shrink' },\n { op: 'feather', label: 'Feather' },\n { op: 'border', label: 'Border' },\n { op: 'smooth', label: 'Smooth' },\n];\n\nconst btn = (on: boolean) =>\n `px-2 py-1 rounded-md border text-[11px] transition-colors ${\n on ? 'bg-indigo-600 border-indigo-500 text-white' : 'bg-slate-950 border-slate-800 text-slate-300 hover:text-white'\n }`;\n\n/**\n * Options bar of the selection tools: tool, mode (new / add / subtract / intersect), magic wand\n * tolerance and contiguous, anti-alias, sample merged, Select › All / Deselect / Inverse,\n * Modify (grow, shrink, feather, border, smooth) and the Quick Mask toggle.\n */\nexport const SelectionOptionsBar: React.FC<SelectionOptionsBarProps> = ({\n controller,\n options,\n onOptionsChange,\n selection,\n quickMask,\n className = '',\n}) => {\n const [radius, setRadius] = useState(2);\n const set = (patch: Partial<SelectionToolOptions>) => onOptionsChange({ ...options, ...patch });\n const sel = selection === undefined ? controller.getSelection() : selection;\n const qm = quickMask ?? Boolean(controller.getState().quickMask);\n return (\n <div data-testid=\"selection-options-bar\" className={`flex flex-col gap-3 text-xs ${className}`}>\n <div role=\"group\" aria-label=\"Selection tool\" className=\"flex flex-wrap gap-1\">\n {SELECTION_TOOLS.map((t) => (\n <button key={t.id} type=\"button\" aria-pressed={options.tool === t.id} className={btn(options.tool === t.id)} onClick={() => set({ tool: t.id })}>\n {t.label}\n </button>\n ))}\n </div>\n <div role=\"group\" aria-label=\"Selection mode\" className=\"flex flex-wrap gap-1\">\n {SELECTION_MODES.map((m) => (\n <button key={m} type=\"button\" aria-pressed={options.mode === m} className={btn(options.mode === m)} onClick={() => set({ mode: m })}>\n {SELECTION_MODE_LABELS[m]}\n </button>\n ))}\n </div>\n {options.tool === 'wand' && (\n <div className=\"flex flex-col gap-2\">\n <label className=\"flex flex-col gap-1\">\n <span className=\"flex justify-between text-slate-400\">\n <span>Tolerance</span>\n <span className=\"font-mono\">{options.tolerance}</span>\n </span>\n <input\n type=\"range\"\n min={0}\n max={255}\n step={1}\n aria-label=\"Tolerance\"\n value={options.tolerance}\n onChange={(e) => set({ tolerance: Number(e.target.value) })}\n className=\"w-full accent-indigo-500\"\n />\n </label>\n <label className=\"flex items-center gap-2 text-slate-300\">\n <input type=\"checkbox\" checked={options.contiguous} onChange={(e) => set({ contiguous: e.target.checked })} />\n Contiguous\n </label>\n <label className=\"flex items-center gap-2 text-slate-300\">\n <input type=\"checkbox\" checked={options.sampleMerged} onChange={(e) => set({ sampleMerged: e.target.checked })} />\n Sample adjusted image\n </label>\n <label className=\"flex items-center gap-2 text-slate-300\">\n Sample\n <select\n aria-label=\"Sample from\"\n value={options.sample ?? 'composite'}\n onChange={(e) => set({ sample: e.target.value as 'composite' | 'active-layer' })}\n className=\"bg-slate-800 border border-slate-700 rounded px-1 py-0.5\"\n >\n <option value=\"composite\">All layers</option>\n <option value=\"active-layer\">Active layer</option>\n </select>\n </label>\n </div>\n )}\n <label className=\"flex items-center gap-2 text-slate-300\">\n <input type=\"checkbox\" checked={options.antiAlias} onChange={(e) => set({ antiAlias: e.target.checked })} />\n Anti-alias\n </label>\n <div className=\"flex flex-wrap gap-1\">\n <button type=\"button\" className={btn(false)} onClick={() => controller.selectAll()}>\n Select All\n </button>\n <button type=\"button\" className={btn(false)} disabled={!sel} onClick={() => controller.deselect()}>\n Deselect\n </button>\n <button type=\"button\" className={btn(false)} onClick={() => controller.invertSelection()}>\n Inverse\n </button>\n <button type=\"button\" aria-pressed={qm} className={btn(qm)} onClick={() => controller.setQuickMask(!qm)}>\n Quick Mask\n </button>\n </div>\n <div className=\"flex flex-wrap items-center gap-1\">\n <label className=\"flex items-center gap-1 text-slate-400\">\n Radius\n <input\n type=\"number\"\n min={0}\n max={500}\n step={1}\n aria-label=\"Modify radius\"\n value={radius}\n onChange={(e) => setRadius(Math.max(0, Number(e.target.value) || 0))}\n className=\"w-14 bg-slate-950 border border-slate-800 rounded px-1 py-0.5 text-slate-200\"\n />\n </label>\n {MODIFY_OPS.map(({ op, label }) => (\n <button key={op} type=\"button\" className={btn(false)} disabled={!sel} onClick={() => controller.modifySelection(op, radius)}>\n {label}\n </button>\n ))}\n </div>\n <p data-testid=\"selection-status\" className=\"text-slate-400\">\n {describeSelection(sel)}\n </p>\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport type { AdjustmentKind, AdjustmentLayer, ImageEditorController, RefineEdgeParams, SelectionMask } from '@pixerate/editor/image-editor';\nimport {\n ADJUSTMENT_KINDS,\n REFINE_EDGE_CONTROLS,\n adjustmentKindLabel,\n layerMaskFromSelection,\n} from '@pixerate/editor/image-editor';\n\nexport interface RefineEdgePanelProps {\n controller: ImageEditorController;\n /** The current selection (`state.selection`), so the panel re-renders with it. */\n selection?: SelectionMask | null;\n /** The adjustment layers (`state.adjustments.layers`), for the mask actions. */\n layers?: AdjustmentLayer[];\n className?: string;\n}\n\nconst DEFAULT_PARAMS: Required<RefineEdgeParams> = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };\n\nconst button =\n 'px-2 py-1 rounded-md border border-slate-800 bg-slate-950 text-[11px] text-slate-200 hover:text-white disabled:opacity-40';\n\n/**\n * Refine Edge (snap the selection, e.g. a coarse AI mask, to the image's edges) and layer masks:\n * use the selection as an adjustment layer's mask, edit mask density and feather, load a mask\n * back as a selection.\n */\nexport const RefineEdgePanel: React.FC<RefineEdgePanelProps> = ({ controller, selection, layers, className = '' }) => {\n const [params, setParams] = useState<Required<RefineEdgeParams>>(DEFAULT_PARAMS);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [layerId, setLayerId] = useState('');\n const [newKind, setNewKind] = useState<AdjustmentKind>('hueSaturation');\n const sel = selection === undefined ? controller.getSelection() : selection;\n const list = layers ?? controller.getAdjustmentLayers();\n const target = list.find((l) => l.id === layerId) ?? list[list.length - 1];\n\n const refine = async () => {\n setBusy(true);\n setError(null);\n try {\n await controller.refineSelection(params);\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <div data-testid=\"refine-edge-panel\" className={`flex flex-col gap-3 text-xs ${className}`}>\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">Refine Edge</span>\n {REFINE_EDGE_CONTROLS.map((c) => (\n <label key={c.id} className=\"flex flex-col gap-1\">\n <span className=\"flex justify-between text-slate-400\">\n <span>{c.label}</span>\n <span className=\"font-mono\">\n {params[c.id]}\n {c.unit}\n </span>\n </span>\n <input\n type=\"range\"\n min={c.min}\n max={c.max}\n step={c.step}\n aria-label={c.label}\n value={params[c.id]}\n onChange={(e) => setParams({ ...params, [c.id]: Number(e.target.value) })}\n className=\"w-full accent-indigo-500\"\n />\n </label>\n ))}\n <label className=\"flex items-center gap-2 text-slate-300\">\n <input type=\"checkbox\" checked={params.smartRadius} onChange={(e) => setParams({ ...params, smartRadius: e.target.checked })} />\n Smart Radius\n </label>\n <div className=\"flex gap-1\">\n <button type=\"button\" className={button} disabled={!sel || busy} onClick={refine}>\n Refine Edge\n </button>\n <button type=\"button\" className={button} onClick={() => setParams(DEFAULT_PARAMS)}>\n Reset\n </button>\n </div>\n {error && (\n <p role=\"alert\" className=\"text-rose-400\">\n {error}\n </p>\n )}\n\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2\">Layer Mask</span>\n <div className=\"flex gap-1 items-center\">\n <select\n aria-label=\"New masked layer kind\"\n value={newKind}\n onChange={(e) => setNewKind(e.target.value as AdjustmentKind)}\n className=\"flex-1 bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200\"\n >\n {ADJUSTMENT_KINDS.map((k) => (\n <option key={k.kind} value={k.kind}>\n {k.label}\n </option>\n ))}\n </select>\n <button\n type=\"button\"\n className={button}\n disabled={!sel}\n onClick={() => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: layerMaskFromSelection(sel) }))}\n >\n New Masked Layer\n </button>\n </div>\n {list.length > 0 && target && (\n <div className=\"flex flex-col gap-2\">\n <select\n aria-label=\"Mask layer\"\n value={target.id}\n onChange={(e) => setLayerId(e.target.value)}\n className=\"bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200\"\n >\n {list.map((l) => (\n <option key={l.id} value={l.id}>\n {l.name || adjustmentKindLabel(l.kind)}\n {l.mask ? ' (masked)' : ''}\n </option>\n ))}\n </select>\n <div className=\"flex flex-wrap gap-1\">\n <button type=\"button\" className={button} disabled={!sel} onClick={() => controller.applySelectionAsLayerMask(target.id)}>\n Mask with Selection\n </button>\n <button type=\"button\" className={button} disabled={!target.mask} onClick={() => controller.selectionFromLayerMask(target.id)}>\n Load as Selection\n </button>\n <button type=\"button\" className={button} disabled={!target.mask} onClick={() => controller.setAdjustmentLayerMask(target.id, null)}>\n Remove Mask\n </button>\n </div>\n {target.mask && (\n <>\n <label className=\"flex flex-col gap-1\">\n <span className=\"flex justify-between text-slate-400\">\n <span>Density</span>\n <span className=\"font-mono\">{Math.round((target.mask.density ?? 1) * 100)}%</span>\n </span>\n <input\n type=\"range\"\n min={0}\n max={100}\n step={1}\n aria-label=\"Mask density\"\n value={Math.round((target.mask.density ?? 1) * 100)}\n onChange={(e) => controller.setAdjustmentLayerMaskProps(target.id, { density: Number(e.target.value) / 100 })}\n className=\"w-full accent-indigo-500\"\n />\n </label>\n <label className=\"flex flex-col gap-1\">\n <span className=\"flex justify-between text-slate-400\">\n <span>Mask Feather</span>\n <span className=\"font-mono\">{target.mask.feather ?? 0}px</span>\n </span>\n <input\n type=\"range\"\n min={0}\n max={50}\n step={0.5}\n aria-label=\"Mask feather\"\n value={target.mask.feather ?? 0}\n onChange={(e) => controller.setAdjustmentLayerMaskProps(target.id, { feather: Number(e.target.value) })}\n className=\"w-full accent-indigo-500\"\n />\n </label>\n </>\n )}\n </div>\n )}\n </div>\n );\n};\n","import React, { useEffect, useState } from 'react';\nimport type { FreeTransformField, FreeTransformTool, Interpolation, TransformAnchor, WarpBar } from '@pixerate/editor/image-editor';\nimport { FREE_TRANSFORM_FIELDS, FREE_TRANSFORM_MODE_OPTIONS, INTERPOLATIONS, TRANSFORM_ANCHORS, WARP_GRID_OPTIONS, WARP_STYLE_OPTIONS } from '@pixerate/editor/image-editor';\n\nexport interface FreeTransformOptionsBarProps {\n tool: FreeTransformTool;\n className?: string;\n}\n\nconst chip = (on: boolean) => `px-2 py-1 rounded text-[11px] ${on ? 'bg-indigo-600 text-white' : 'bg-slate-800 text-slate-300 hover:text-white'}`;\nconst round = (v: number, unit: string) => (unit === 'px' ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100);\n\n/**\n * Free Transform's options bar (Photoshop's): the mode switch (Free, Rotate, Skew, Distort,\n * Perspective, Warp), the reference-point locator, X / Y of the reference point, W / H in percent\n * with the proportional chain, the angle and skews, the interpolation, and Commit (Enter) / Cancel\n * (Esc). In Warp mode the numbers give way to the warp style, bend, horizontal and vertical\n * distortion, orientation and grid. Typed values apply on Enter or when the field loses focus.\n */\nexport const FreeTransformOptionsBar: React.FC<FreeTransformOptionsBarProps> = ({ tool, className }) => {\n const [, setTick] = useState(0);\n useEffect(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);\n const bar = tool.bar();\n if (!tool.active || !bar) return null;\n const warp = tool.warpBar();\n const warpNumber = (key: 'bend' | 'horizontal' | 'vertical', raw: string) => {\n const v = Number(raw);\n if (raw.trim() !== '' && Number.isFinite(v) && v !== warp[key]) tool.setWarp({ [key]: Math.max(-100, Math.min(100, v)) } as Partial<WarpBar>);\n };\n const apply = (field: FreeTransformField, raw: string) => {\n const v = Number(raw);\n if (raw.trim() !== '' && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);\n };\n\n return (\n <div className={`flex flex-wrap items-center gap-2 text-xs text-slate-200 ${className ?? ''}`} data-testid=\"free-transform-options\" role=\"toolbar\" aria-label=\"Free Transform options\">\n <div className=\"flex gap-1\" role=\"group\" aria-label=\"Transform mode\">\n {FREE_TRANSFORM_MODE_OPTIONS.map((m) => (\n <button key={m.id} type=\"button\" title={m.title} aria-pressed={tool.mode === m.id} className={chip(tool.mode === m.id)} onClick={() => tool.setMode(m.id)}>\n {m.label}\n </button>\n ))}\n </div>\n <div className=\"grid grid-cols-3 gap-px\" role=\"group\" aria-label=\"Reference point\">\n {TRANSFORM_ANCHORS.map((a: TransformAnchor) => (\n <button key={a} type=\"button\" aria-label={`Reference point ${a}`} title={`Reference point: ${a}`} className=\"h-2.5 w-2.5 rounded-sm bg-slate-700 hover:bg-indigo-500\" onClick={() => tool.setReference(a)} />\n ))}\n </div>\n {tool.mode === 'warp' && (\n <div className=\"flex flex-wrap items-center gap-2\" role=\"group\" aria-label=\"Warp options\">\n <label className=\"flex items-center gap-1\">\n <span className=\"text-slate-400\">Warp</span>\n <select aria-label=\"Warp style\" value={warp.style} onChange={(e) => tool.setWarp({ style: e.target.value as WarpBar['style'] })} className=\"rounded border border-slate-700 bg-slate-900 px-1 py-0.5\">\n {WARP_STYLE_OPTIONS.map((o) => (\n <option key={o.id} value={o.id}>\n {o.label}\n </option>\n ))}\n </select>\n </label>\n {(['bend', 'horizontal', 'vertical'] as const).map((k) => (\n <label key={k} className=\"flex items-center gap-1\">\n <span className=\"text-slate-400\">{k === 'bend' ? 'Bend' : k === 'horizontal' ? 'H' : 'V'}</span>\n <input\n key={`${k}:${warp[k]}`}\n type=\"number\"\n aria-label={k === 'bend' ? 'Warp bend in percent' : `Warp ${k} distortion in percent`}\n defaultValue={warp[k]}\n min={-100}\n max={100}\n disabled={warp.style === 'custom'}\n className=\"w-14 rounded border border-slate-700 bg-slate-900 px-1 py-0.5 text-right disabled:opacity-40\"\n onBlur={(e) => warpNumber(k, e.currentTarget.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n e.stopPropagation();\n warpNumber(k, e.currentTarget.value);\n }\n }}\n />\n <span className=\"text-slate-500\">%</span>\n </label>\n ))}\n <button\n type=\"button\"\n title=\"Bend along the vertical axis\"\n aria-pressed={warp.orientation === 'vertical'}\n disabled={warp.style === 'custom'}\n className={chip(warp.orientation === 'vertical')}\n onClick={() => tool.setWarp({ orientation: warp.orientation === 'vertical' ? 'horizontal' : 'vertical' })}\n >\n Vertical\n </button>\n <label className=\"flex items-center gap-1\">\n <span className=\"text-slate-400\">Grid</span>\n <select\n aria-label=\"Warp grid\"\n value={WARP_GRID_OPTIONS.find((g) => g.columns === warp.columns && g.rows === warp.rows)?.id ?? '1x1'}\n onChange={(e) => {\n const g = WARP_GRID_OPTIONS.find((o) => o.id === e.target.value)!;\n tool.setWarp({ columns: g.columns, rows: g.rows });\n }}\n className=\"rounded border border-slate-700 bg-slate-900 px-1 py-0.5\"\n >\n {WARP_GRID_OPTIONS.map((g) => (\n <option key={g.id} value={g.id}>\n {g.label}\n </option>\n ))}\n </select>\n </label>\n </div>\n )}\n {tool.mode !== 'warp' && FREE_TRANSFORM_FIELDS.map((f) => (\n <label key={f.id} className=\"flex items-center gap-1\" title={f.title}>\n <span className=\"text-slate-400\">{f.label}</span>\n <input\n key={`${f.id}:${round(bar[f.id], f.unit)}`}\n type=\"number\"\n aria-label={f.title}\n defaultValue={round(bar[f.id], f.unit)}\n disabled={!bar.affine}\n step={f.unit === 'px' ? 1 : 0.1}\n className=\"w-16 rounded border border-slate-700 bg-slate-900 px-1 py-0.5 text-right disabled:opacity-40\"\n onBlur={(e) => apply(f.id, e.currentTarget.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n e.stopPropagation();\n apply(f.id, e.currentTarget.value);\n }\n }}\n />\n <span className=\"text-slate-500\">{f.unit}</span>\n {f.id === 'scaleX' && (\n <button\n type=\"button\"\n aria-label=\"Keep width and height proportional\"\n aria-pressed={tool.proportional}\n className={chip(tool.proportional)}\n onClick={() => {\n tool.proportional = !tool.proportional;\n setTick((n) => n + 1);\n }}\n >\n ⛓︎\n </button>\n )}\n </label>\n ))}\n <label className=\"flex items-center gap-1\">\n <span className=\"text-slate-400\">Interpolation</span>\n <select\n aria-label=\"Interpolation\"\n value={tool.interpolation}\n onChange={(e) => tool.setInterpolation(e.target.value as Interpolation)}\n className=\"rounded border border-slate-700 bg-slate-900 px-1 py-0.5\"\n >\n {INTERPOLATIONS.map((i) => (\n <option key={i} value={i}>\n {i[0].toUpperCase() + i.slice(1)}\n </option>\n ))}\n </select>\n </label>\n <button type=\"button\" title=\"Commit (Enter)\" className=\"px-2 py-1 rounded bg-emerald-600 text-white hover:bg-emerald-500\" onClick={() => tool.commit()}>\n Commit\n </button>\n <button type=\"button\" title=\"Cancel (Esc)\" className={chip(false)} onClick={() => tool.cancel()}>\n Cancel\n </button>\n {tool.error && (\n <span role=\"alert\" className=\"text-rose-400\">\n {tool.error}\n </span>\n )}\n </div>\n );\n};\n","import React, { useEffect, useState } from 'react';\nimport type { ImageEditorController, LiveShapeKind, ShapeToolOptions } from '@pixerate/editor/image-editor';\nimport { LIVE_SHAPE_KINDS, SHAPE_KIND_LABELS, applyShapeOptions } from '@pixerate/editor/image-editor';\n\nexport interface ShapeOptionsBarProps {\n controller: ImageEditorController;\n options: ShapeToolOptions;\n onChange: (options: ShapeToolOptions) => void;\n className?: string;\n}\n\nconst chip = (on: boolean) => `px-2 py-1 rounded text-[11px] ${on ? 'bg-indigo-600 text-white' : 'bg-slate-800 text-slate-300 hover:text-white'}`;\n\n/**\n * The shape tool's options: the kind to draw, fill and stroke (colour or none), stroke width and\n * the kind's own settings (corner radius, sides, points, line weight and arrowhead). Changes also\n * apply to the active shape layer, as one undo step each.\n */\nexport const ShapeOptionsBar: React.FC<ShapeOptionsBarProps> = ({ controller, options, onChange, className }) => {\n const [, setTick] = useState(0);\n useEffect(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);\n const [error, setError] = useState<string | null>(null);\n const active = controller.getActiveLayer();\n const shapeId = active?.type === 'shape' ? active.id : null;\n const set = (change: Partial<ShapeToolOptions>) => {\n onChange({ ...options, ...change });\n if (!shapeId) return;\n try {\n setError(null);\n applyShapeOptions(controller, shapeId, change);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n };\n const num = (v: string, min: number, max: number) => Math.max(min, Math.min(max, Number(v) || min));\n\n return (\n <div className={`flex flex-col gap-2 text-xs text-slate-200 ${className ?? ''}`} data-testid=\"shape-options\">\n <div className=\"flex flex-wrap gap-1\" role=\"toolbar\" aria-label=\"Shape kind\">\n {LIVE_SHAPE_KINDS.map((k: LiveShapeKind) => (\n <button key={k} type=\"button\" aria-pressed={options.kind === k} className={chip(options.kind === k)} onClick={() => onChange({ ...options, kind: k })}>\n {SHAPE_KIND_LABELS[k]}\n </button>\n ))}\n </div>\n <div className=\"flex flex-wrap items-center gap-3\">\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" aria-label=\"Fill\" checked={options.fill !== null} onChange={(e) => set({ fill: e.target.checked ? '#4f46e5' : null })} />\n Fill\n <input\n type=\"color\"\n aria-label=\"Fill colour\"\n disabled={options.fill === null}\n value={options.fill ?? '#4f46e5'}\n onChange={(e) => set({ fill: e.target.value })}\n className=\"h-6 w-8 rounded border border-slate-700 bg-transparent\"\n />\n </label>\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" aria-label=\"Stroke\" checked={options.stroke !== null} onChange={(e) => set({ stroke: e.target.checked ? '#000000' : null })} />\n Stroke\n <input\n type=\"color\"\n aria-label=\"Stroke colour\"\n disabled={options.stroke === null}\n value={options.stroke ?? '#000000'}\n onChange={(e) => set({ stroke: e.target.value })}\n className=\"h-6 w-8 rounded border border-slate-700 bg-transparent\"\n />\n </label>\n <label className=\"flex items-center gap-1\">\n Width\n <input\n type=\"number\"\n aria-label=\"Stroke width\"\n min={0}\n max={200}\n value={options.strokeWidth}\n onChange={(e) => set({ strokeWidth: num(e.target.value, 0, 200) })}\n className=\"w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5\"\n />\n </label>\n </div>\n <div className=\"flex flex-wrap items-center gap-3\">\n {options.kind === 'rect' && (\n <label className=\"flex items-center gap-1\">\n Radius\n <input type=\"number\" aria-label=\"Corner radius\" min={0} max={1000} value={options.radius} onChange={(e) => set({ radius: num(e.target.value, 0, 1000) })} className=\"w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5\" />\n </label>\n )}\n {options.kind === 'polygon' && (\n <label className=\"flex items-center gap-1\">\n Sides\n <input type=\"number\" aria-label=\"Sides\" min={3} max={100} value={options.sides} onChange={(e) => set({ sides: num(e.target.value, 3, 100) })} className=\"w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5\" />\n </label>\n )}\n {options.kind === 'star' && (\n <>\n <label className=\"flex items-center gap-1\">\n Points\n <input type=\"number\" aria-label=\"Points\" min={3} max={100} value={options.points} onChange={(e) => set({ points: num(e.target.value, 3, 100) })} className=\"w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5\" />\n </label>\n <label className=\"flex items-center gap-1\">\n Inner\n <input\n type=\"range\"\n aria-label=\"Inner radius\"\n min={0.05}\n max={1}\n step={0.05}\n value={options.innerRatio}\n onChange={(e) => set({ innerRatio: Number(e.target.value) })}\n className=\"accent-indigo-500\"\n />\n </label>\n </>\n )}\n {options.kind === 'line' && (\n <>\n <label className=\"flex items-center gap-1\">\n Weight\n <input type=\"number\" aria-label=\"Line weight\" min={1} max={200} value={options.weight} onChange={(e) => set({ weight: num(e.target.value, 1, 200) })} className=\"w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5\" />\n </label>\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" aria-label=\"Arrowhead\" checked={options.arrow} onChange={(e) => set({ arrow: e.target.checked })} />\n Arrowhead\n </label>\n </>\n )}\n </div>\n <p className=\"text-[10px] text-slate-500\">Drag on the image to draw. Shift: square, circle or 45° line. Alt: from the centre.</p>\n {error && (\n <p role=\"alert\" className=\"text-rose-400\">\n {error}\n </p>\n )}\n </div>\n );\n};\n","import React, { useEffect, useState } from 'react';\nimport type { ImageEditorController, TextAlign, TextEditSession, TextStyle, TypeToolOptions } from '@pixerate/editor/image-editor';\nimport { TEXT_ALIGNS } from '@pixerate/editor/image-editor';\n\nexport interface TypeOptionsBarProps {\n controller: ImageEditorController;\n options: TypeToolOptions;\n onChange: (options: TypeToolOptions) => void;\n /** The text being edited on the canvas: changes style its selection (or all of it). */\n session?: TextEditSession | null;\n className?: string;\n}\n\nconst chip = (on: boolean) => `px-2 py-1 rounded text-[11px] ${on ? 'bg-indigo-600 text-white' : 'bg-slate-800 text-slate-300 hover:text-white'}`;\nconst ALIGN_LABELS: Record<TextAlign, string> = { left: 'Left', center: 'Centre', right: 'Right', justify: 'Justify' };\n\n/**\n * The type tool's options: font family (from the editor's fonts), size, bold, italic, colour and\n * alignment. While text is being edited they style the selection (or the whole text); with a\n * type layer active they style all of it; otherwise they set what the next text uses.\n */\nexport const TypeOptionsBar: React.FC<TypeOptionsBarProps> = ({ controller, options, onChange, session, className }) => {\n const [, setTick] = useState(0);\n useEffect(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);\n useEffect(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);\n const [error, setError] = useState<string | null>(null);\n const active = controller.getActiveLayer();\n const typeId = !session && active?.type === 'type' ? active.id : null;\n const here: Partial<TextStyle> = session?.alive ? session.styleHere() : {};\n const shown: TypeToolOptions = {\n ...options,\n ...(here.fontFamily ? { fontFamily: here.fontFamily } : {}),\n ...(here.fontSize ? { fontSize: here.fontSize } : {}),\n ...(here.fontWeight ? { fontWeight: here.fontWeight } : {}),\n ...(session?.alive ? { italic: Boolean(here.italic), color: here.color ?? options.color } : {}),\n };\n const fonts = controller.listFonts();\n const missing = active?.type === 'type' ? active.missingFonts ?? [] : [];\n\n const style = (change: Partial<TypeToolOptions>) => {\n onChange({ ...options, ...change });\n const s: Record<string, unknown> = {};\n for (const k of ['fontFamily', 'fontSize', 'fontWeight', 'italic', 'color'] as const) if (k in change) s[k] = change[k];\n const p = change.align ? { align: change.align } : null;\n try {\n setError(null);\n if (session?.alive) {\n if (Object.keys(s).length) session.setStyle(s as Partial<TextStyle>);\n if (p) session.setParagraph(p);\n if (session.error) setError(session.error);\n } else if (typeId) {\n if (Object.keys(s).length) controller.setTextStyle(typeId, s);\n if (p) controller.setParagraphStyle(typeId, p);\n }\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n };\n\n return (\n <div className={`flex flex-col gap-2 text-xs text-slate-200 ${className ?? ''}`} data-testid=\"type-options\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <label className=\"flex items-center gap-1\">\n Font\n <input\n list=\"pixerate-type-fonts\"\n aria-label=\"Font family\"\n value={shown.fontFamily}\n onChange={(e) => e.target.value.trim() && style({ fontFamily: e.target.value })}\n className=\"w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5\"\n />\n <datalist id=\"pixerate-type-fonts\">\n {fonts.map((f) => (\n <option key={f} value={f} />\n ))}\n </datalist>\n </label>\n <label className=\"flex items-center gap-1\">\n Size\n <input\n type=\"number\"\n aria-label=\"Font size\"\n min={1}\n max={2000}\n value={Math.round(shown.fontSize * 10) / 10}\n onChange={(e) => Number(e.target.value) > 0 && style({ fontSize: Number(e.target.value) })}\n className=\"w-16 rounded border border-slate-700 bg-slate-950 px-1 py-0.5\"\n />\n </label>\n <button type=\"button\" aria-pressed={shown.fontWeight >= 600} className={`${chip(shown.fontWeight >= 600)} font-bold`} onClick={() => style({ fontWeight: shown.fontWeight >= 600 ? 400 : 700 })}>\n B\n </button>\n <button type=\"button\" aria-pressed={shown.italic} className={`${chip(shown.italic)} italic`} onClick={() => style({ italic: !shown.italic })}>\n I\n </button>\n <input type=\"color\" aria-label=\"Text colour\" value={shown.color} onChange={(e) => style({ color: e.target.value })} className=\"h-6 w-8 rounded border border-slate-700 bg-transparent\" />\n </div>\n <div className=\"flex gap-1\" role=\"toolbar\" aria-label=\"Alignment\">\n {TEXT_ALIGNS.map((a) => (\n <button key={a} type=\"button\" aria-pressed={options.align === a} className={chip(options.align === a)} onClick={() => style({ align: a })}>\n {ALIGN_LABELS[a]}\n </button>\n ))}\n </div>\n <p className=\"text-[10px] text-slate-500\">Click to type point text, drag for a paragraph box, click text to edit it. Esc finishes.</p>\n {missing.length > 0 && (\n <p role=\"status\" className=\"text-amber-400\" data-testid=\"type-missing-fonts\">\n Missing {missing.length === 1 ? 'font' : 'fonts'}: {missing.join(', ')}\n </p>\n )}\n {error && (\n <p role=\"alert\" className=\"text-rose-400\">\n {error}\n </p>\n )}\n </div>\n );\n};\n","import { useCallback, useMemo, useSyncExternalStore } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n getCommentStore,\n getTrackChangesStore,\n type CommentStore,\n type CommentStoreSnapshot,\n type TrackChangesSnapshot,\n type TrackedChange,\n} from \"@pixerate/editor\";\n\nconst EMPTY_COMMENTS: CommentStoreSnapshot = Object.freeze({\n threads: [],\n activeThreadId: null,\n}) as CommentStoreSnapshot;\n\nconst EMPTY_TRACK_CHANGES: TrackChangesSnapshot = Object.freeze({\n enabled: false,\n author: { id: \"anonymous\", name: \"Anonymous\" },\n changes: [],\n currentChangeId: null,\n}) as TrackChangesSnapshot;\n\nconst noopUnsubscribe = () => {};\n\nfunction isCommentStore(value: unknown): value is CommentStore {\n return (\n !!value &&\n typeof (value as CommentStore).getSnapshot === \"function\" &&\n typeof (value as CommentStore).createThread === \"function\"\n );\n}\n\nexport interface UseCommentsResult extends CommentStoreSnapshot {\n store: CommentStore | null;\n}\n\n/**\n * Subscribes to a comment store: pass the store itself, or an editor using\n * the `Comments` extension (`null` while the editor is being created).\n */\nexport function useComments(\n source: Editor | CommentStore | null | undefined,\n): UseCommentsResult {\n const store = isCommentStore(source) ? source : getCommentStore(source as Editor | null);\n const subscribe = useCallback(\n (onChange: () => void) => (store ? store.subscribe(() => onChange()) : noopUnsubscribe),\n [store],\n );\n const getSnapshot = () => store?.getSnapshot() ?? EMPTY_COMMENTS;\n const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n return useMemo(() => ({ ...snapshot, store }), [snapshot, store]);\n}\n\nexport interface UseTrackChangesResult extends TrackChangesSnapshot {\n currentChange: TrackedChange | null;\n setEnabled: (enabled: boolean) => void;\n toggle: () => void;\n accept: (id: string) => void;\n reject: (id: string) => void;\n acceptAll: () => void;\n rejectAll: () => void;\n next: () => void;\n previous: () => void;\n /** Selects a change in the editor. */\n select: (id: string) => void;\n /** Accepts a tracked move (both ends). */\n acceptMove: (id: string) => void;\n /** Rejects a tracked move (both ends). */\n rejectMove: (id: string) => void;\n}\n\n/**\n * Subscribes to the tracked-change state of an editor using the\n * `TrackChanges` extension and exposes its commands.\n */\nexport function useTrackChanges(editor: Editor | null | undefined): UseTrackChangesResult {\n const store = getTrackChangesStore(editor ?? null);\n const subscribe = useCallback(\n (onChange: () => void) => (store ? store.subscribe(() => onChange()) : noopUnsubscribe),\n [store],\n );\n const getSnapshot = () => store?.getSnapshot() ?? EMPTY_TRACK_CHANGES;\n const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n return useMemo(() => {\n const run = (fn: (e: Editor) => void) => () => {\n if (editor && !editor.isDestroyed) fn(editor);\n };\n return {\n ...snapshot,\n currentChange:\n snapshot.changes.find((c) => c.id === snapshot.currentChangeId) ?? null,\n setEnabled: (enabled: boolean) => run((e) => e.commands.setTrackChanges(enabled))(),\n toggle: run((e) => e.commands.toggleTrackChanges()),\n accept: (id: string) => run((e) => e.commands.acceptChange(id))(),\n reject: (id: string) => run((e) => e.commands.rejectChange(id))(),\n acceptAll: run((e) => e.commands.acceptAllChanges()),\n rejectAll: run((e) => e.commands.rejectAllChanges()),\n next: run((e) => e.chain().focus().selectNextChange().run()),\n previous: run((e) => e.chain().focus().selectPreviousChange().run()),\n select: (id: string) => run((e) => e.chain().focus().selectChange(id).run())(),\n acceptMove: (id: string) => run((e) => e.commands.acceptMove(id))(),\n rejectMove: (id: string) => run((e) => e.commands.rejectMove(id))(),\n };\n }, [snapshot, editor]);\n}\n","import React, { useState } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n formatReviewTime,\n getCommentAuthor,\n type CommentStore,\n type CommentThread,\n type ReviewAuthor,\n} from \"@pixerate/editor\";\nimport { useComments } from \"./useReview\";\n\nexport interface CommentsPanelProps {\n editor: Editor | null;\n /** Defaults to the store of the editor's `Comments` extension. */\n store?: CommentStore;\n /** Author of replies. Defaults to the `Comments` extension's author. */\n author?: ReviewAuthor;\n /** Initially show resolved threads. */\n showResolved?: boolean;\n className?: string;\n formatTime?: (timestamp: number) => string;\n emptyMessage?: string;\n}\n\nconst buttonClass =\n \"rounded px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-50\";\nconst primaryButtonClass =\n \"rounded px-2 py-1 text-xs bg-primary/10 text-primary hover:bg-primary/20 disabled:opacity-50\";\nconst textareaClass =\n \"w-full resize-y rounded-md border border-input bg-background p-2 text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-primary\";\n\n/**\n * Lists comment threads with reply, resolve and delete actions. Clicking a\n * thread selects its text in the editor. Threads with an empty body are\n * drafts (e.g. created by `CommentButton`) and show a compose box.\n */\nexport const CommentsPanel: React.FC<CommentsPanelProps> = ({\n editor,\n store: storeProp,\n author: authorProp,\n showResolved: showResolvedInitial = false,\n className = \"flex flex-col gap-2 text-sm text-foreground\",\n formatTime = (t) => formatReviewTime(t),\n emptyMessage = \"No comments yet. Select text and add a comment.\",\n}) => {\n const { threads, activeThreadId, store } = useComments(storeProp ?? editor);\n const [showResolved, setShowResolved] = useState(showResolvedInitial);\n const author = authorProp ?? getCommentAuthor(editor) ?? { id: \"anonymous\", name: \"Anonymous\" };\n\n const visible = threads.filter((t) => showResolved || !t.resolved);\n const resolvedCount = threads.filter((t) => t.resolved).length;\n\n return (\n <aside className={className} aria-label=\"Comments\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n {threads.length - resolvedCount} open\n {resolvedCount > 0 ? ` · ${resolvedCount} resolved` : \"\"}\n </span>\n {resolvedCount > 0 && (\n <button\n type=\"button\"\n className={buttonClass}\n aria-pressed={showResolved}\n onClick={() => setShowResolved((v) => !v)}\n >\n {showResolved ? \"Hide resolved\" : \"Show resolved\"}\n </button>\n )}\n </div>\n {visible.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">{emptyMessage}</p>\n ) : (\n <ul className=\"flex flex-col gap-2\" role=\"list\">\n {visible.map((thread) => (\n <CommentThreadCard\n key={thread.id}\n thread={thread}\n active={thread.id === activeThreadId}\n editor={editor}\n store={store}\n author={author}\n formatTime={formatTime}\n />\n ))}\n </ul>\n )}\n </aside>\n );\n};\n\ninterface CommentThreadCardProps {\n thread: CommentThread;\n active: boolean;\n editor: Editor | null;\n store: CommentStore | null;\n author: ReviewAuthor;\n formatTime: (timestamp: number) => string;\n}\n\nconst CommentThreadCard: React.FC<CommentThreadCardProps> = ({\n thread,\n active,\n editor,\n store,\n author,\n formatTime,\n}) => {\n const [draft, setDraft] = useState(\"\");\n const isDraft = thread.body === \"\";\n const quote = thread.anchor?.quote ?? thread.lastQuote ?? \"\";\n const live = editor && !editor.isDestroyed ? editor : null;\n\n const focus = () => {\n if (!active) {\n if (live && !thread.orphaned) live.commands.focusComment(thread.id);\n else store?.setActiveThread(thread.id);\n }\n };\n const remove = () => {\n if (live) live.commands.deleteComment(thread.id);\n else store?.deleteThread(thread.id);\n };\n const setResolved = (resolved: boolean) => {\n if (live) live.commands.resolveComment(thread.id, resolved);\n else store?.resolveThread(thread.id, resolved, author);\n };\n const submit = () => {\n const body = draft.trim();\n if (!body || !store) return;\n if (isDraft) store.editComment(thread.id, body);\n else store.addReply(thread.id, { body, author });\n setDraft(\"\");\n };\n const stop = (e: React.SyntheticEvent) => e.stopPropagation();\n\n return (\n <li\n className={`flex flex-col gap-2 rounded-md border bg-background p-3 cursor-pointer ${\n active ? \"border-primary ring-1 ring-primary\" : \"border-border\"\n } ${thread.resolved ? \"opacity-70\" : \"\"}`}\n data-thread-id={thread.id}\n data-active={active || undefined}\n aria-current={active || undefined}\n tabIndex={0}\n onClick={focus}\n onKeyDown={(e) => {\n if (e.target === e.currentTarget && (e.key === \"Enter\" || e.key === \" \")) {\n e.preventDefault();\n focus();\n }\n }}\n >\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"font-medium\">{thread.author.name}</span>\n <span className=\"text-xs text-muted-foreground\">{formatTime(thread.createdAt)}</span>\n </div>\n {quote && (\n <blockquote className=\"border-l-2 border-border pl-2 text-xs text-muted-foreground line-clamp-2\">\n {quote}\n </blockquote>\n )}\n {thread.orphaned && (\n <span className=\"text-xs text-destructive\">The commented text was deleted.</span>\n )}\n {thread.resolved && <span className=\"text-xs text-muted-foreground\">Resolved</span>}\n {!isDraft && <p className=\"whitespace-pre-wrap break-words\">{thread.body}</p>}\n {thread.replies.length > 0 && (\n <ul className=\"flex flex-col gap-2 border-l border-border pl-3\" role=\"list\">\n {thread.replies.map((reply) => (\n <li key={reply.id} className=\"flex flex-col gap-0.5\" data-reply-id={reply.id}>\n <span className=\"text-xs\">\n <span className=\"font-medium\">{reply.author.name}</span>{\" \"}\n <span className=\"text-muted-foreground\">{formatTime(reply.createdAt)}</span>\n </span>\n <p className=\"whitespace-pre-wrap break-words\">{reply.body}</p>\n </li>\n ))}\n </ul>\n )}\n {(active || isDraft) && !thread.resolved && (\n <div className=\"flex flex-col gap-1\" onClick={stop}>\n <textarea\n className={textareaClass}\n rows={2}\n value={draft}\n aria-label={isDraft ? \"Comment\" : \"Reply\"}\n placeholder={isDraft ? \"Add a comment…\" : \"Reply…\"}\n autoFocus={isDraft}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n submit();\n }\n }}\n />\n <div className=\"flex justify-end gap-1\">\n {isDraft && (\n <button type=\"button\" className={buttonClass} onClick={remove}>\n Cancel\n </button>\n )}\n <button\n type=\"button\"\n className={primaryButtonClass}\n disabled={!draft.trim()}\n onClick={submit}\n >\n {isDraft ? \"Comment\" : \"Reply\"}\n </button>\n </div>\n </div>\n )}\n {!isDraft && (\n <div className=\"flex justify-end gap-1\" onClick={stop}>\n <button type=\"button\" className={buttonClass} onClick={() => setResolved(!thread.resolved)}>\n {thread.resolved ? \"Reopen\" : \"Resolve\"}\n </button>\n <button\n type=\"button\"\n className={`${buttonClass} hover:text-destructive`}\n onClick={remove}\n >\n Delete\n </button>\n </div>\n )}\n </li>\n );\n};\n","import React from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { useTrackChanges } from \"./useReview\";\n\nexport interface ReviewToolbarProps {\n editor: Editor | null;\n className?: string;\n /**\n * Show the current change's author and description (e.g. \"Alice: Formatted:\n * Bold\"). Defaults to `true`.\n */\n showDescription?: boolean;\n /** Class of the description label. */\n descriptionClassName?: string;\n}\n\nconst defaultDescriptionClass = \"max-w-[16rem] truncate px-1 text-xs text-muted-foreground\";\n\nconst buttonClass =\n \"rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent\";\n\n/**\n * Toolbar for tracked changes: toggle tracking, step through changes\n * (insertions, deletions, formatting and block changes, with a description\n * of the current one), and accept or reject the current change or all\n * changes.\n */\nexport const ReviewToolbar: React.FC<ReviewToolbarProps> = ({\n editor,\n className = \"flex flex-wrap items-center gap-1 rounded-md border border-border bg-background p-1 text-sm\",\n showDescription = true,\n descriptionClassName = defaultDescriptionClass,\n}) => {\n const review = useTrackChanges(editor);\n const count = review.changes.length;\n const current = review.currentChange;\n const index = current ? review.changes.findIndex((c) => c.id === current.id) + 1 : 0;\n\n return (\n <div className={className} role=\"toolbar\" aria-label=\"Review\">\n <button\n type=\"button\"\n className={`${buttonClass} ${review.enabled ? \"bg-primary/10 text-primary\" : \"\"}`}\n aria-pressed={review.enabled}\n disabled={!editor}\n onClick={review.toggle}\n >\n {review.enabled ? \"Tracking on\" : \"Track changes\"}\n </button>\n <span className=\"mx-1 h-4 w-px bg-border\" aria-hidden=\"true\" />\n <button\n type=\"button\"\n className={buttonClass}\n aria-label=\"Previous change\"\n disabled={count === 0}\n onClick={review.previous}\n >\n ‹\n </button>\n <span className=\"min-w-[4rem] text-center text-xs text-muted-foreground\" aria-live=\"polite\">\n {count === 0 ? \"No changes\" : current ? `${index} of ${count}` : `${count} changes`}\n </span>\n <button\n type=\"button\"\n className={buttonClass}\n aria-label=\"Next change\"\n disabled={count === 0}\n onClick={review.next}\n >\n ›\n </button>\n {showDescription && current && (\n <span\n className={descriptionClassName}\n data-change-type={current.type}\n title={`${current.author.name}: ${current.description}`}\n >\n {current.author.name ? `${current.author.name}: ` : \"\"}\n {current.description}\n </span>\n )}\n <span className=\"mx-1 h-4 w-px bg-border\" aria-hidden=\"true\" />\n <button\n type=\"button\"\n className={buttonClass}\n disabled={!current}\n onClick={() => current && review.accept(current.id)}\n >\n Accept\n </button>\n <button\n type=\"button\"\n className={buttonClass}\n disabled={!current}\n onClick={() => current && review.reject(current.id)}\n >\n Reject\n </button>\n <button type=\"button\" className={buttonClass} disabled={count === 0} onClick={review.acceptAll}>\n Accept all\n </button>\n <button type=\"button\" className={buttonClass} disabled={count === 0} onClick={review.rejectAll}>\n Reject all\n </button>\n </div>\n );\n};\n","import React from \"react\";\nimport type { Editor } from \"@tiptap/core\";\n\nexport interface CommentButtonProps {\n editor: Editor | null;\n className?: string;\n children?: React.ReactNode;\n}\n\n/**\n * Adds a draft comment on the selection; drop it into a `BubbleMenu`. The\n * draft is completed in `CommentsPanel`.\n */\nexport const CommentButton: React.FC<CommentButtonProps> = ({\n editor,\n className = \"rounded px-2 py-1 text-xs text-popover-foreground hover:bg-muted\",\n children = \"Comment\",\n}) => (\n <button\n type=\"button\"\n className={className}\n disabled={!editor}\n onClick={() => editor?.chain().focus().addComment().run()}\n >\n {children}\n </button>\n);\n","import { useCallback, useMemo, useRef, useState } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n applyDocumentComparison,\n type CompareSource,\n type CompareSummary,\n type EditorCompareOptions,\n} from \"@pixerate/editor\";\n\nexport type { CompareSource, CompareSummary, EditorCompareOptions } from \"@pixerate/editor\";\n\nexport interface UseDocumentCompareResult {\n /** Summary of the last comparison, or `null`. */\n summary: CompareSummary | null;\n /**\n * Replaces the editor content with the comparison of two versions (nodes,\n * JSON or HTML) as tracked changes, ready to review with `ReviewToolbar`.\n * Returns the summary, or `null` without an editor.\n */\n compare: (\n original: CompareSource,\n revised: CompareSource,\n options?: EditorCompareOptions,\n ) => CompareSummary | null;\n /** Forgets the last summary. */\n clear: () => void;\n}\n\n/**\n * Compare two document versions into an editor using `TrackChanges`.\n * `options` are defaults for every comparison.\n */\nexport function useDocumentCompare(\n editor: Editor | null | undefined,\n options?: EditorCompareOptions,\n): UseDocumentCompareResult {\n const [summary, setSummary] = useState<CompareSummary | null>(null);\n const defaults = useRef(options);\n defaults.current = options;\n const compare = useCallback(\n (original: CompareSource, revised: CompareSource, overrides?: EditorCompareOptions) => {\n if (!editor || editor.isDestroyed) return null;\n const result = applyDocumentComparison(editor, original, revised, {\n ...defaults.current,\n ...overrides,\n });\n setSummary(result.summary);\n return result.summary;\n },\n [editor],\n );\n const clear = useCallback(() => setSummary(null), []);\n return useMemo(() => ({ summary, compare, clear }), [summary, compare, clear]);\n}\n","import React from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { trackedChangeLabel } from \"@pixerate/editor\";\nimport { useTrackChanges } from \"./useReview\";\n\nexport interface TrackedChangesListProps {\n editor: Editor | null;\n className?: string;\n itemClassName?: string;\n activeItemClassName?: string;\n /** Content shown when there are no changes. */\n emptyState?: React.ReactNode;\n}\n\nconst buttonClass =\n \"rounded px-1.5 py-0.5 text-xs text-foreground hover:bg-muted disabled:opacity-40\";\n\n/**\n * Lists the document's tracked changes (insertions, deletions, moves,\n * formatting and block changes) with their author and description, and\n * accepts or rejects each one. A move is one entry: accepting or rejecting\n * it resolves both its source and its destination. Clicking an entry\n * selects the change in the editor.\n */\nexport const TrackedChangesList: React.FC<TrackedChangesListProps> = ({\n editor,\n className = \"flex flex-col gap-1 text-sm\",\n itemClassName = \"flex items-center gap-2 rounded px-2 py-1 hover:bg-muted/50\",\n activeItemClassName = \"bg-primary/10\",\n emptyState = \"No tracked changes.\",\n}) => {\n const review = useTrackChanges(editor);\n\n if (review.changes.length === 0) {\n return (\n <div className={className} data-tracked-changes-list=\"\">\n <div className=\"pixerate-changes-empty text-xs text-muted-foreground\">{emptyState}</div>\n </div>\n );\n }\n\n return (\n <ul className={className} role=\"list\" aria-label=\"Tracked changes\" data-tracked-changes-list=\"\">\n {review.changes.map((change) => {\n const active = change.id === review.currentChangeId;\n return (\n <li\n key={`${change.type}:${change.id}`}\n className={active ? `${itemClassName} ${activeItemClassName}` : itemClassName}\n data-change-type={change.type}\n data-change-id={change.id}\n >\n <button\n type=\"button\"\n className=\"min-w-0 flex-1 truncate text-left text-xs\"\n title={`${change.author.name}: ${change.description}`}\n onClick={() => review.select(change.id)}\n >\n <span className=\"font-medium\">{trackedChangeLabel(change)}</span>\n {change.author.name ? ` · ${change.author.name}` : \"\"}\n <span className=\"block truncate text-muted-foreground\">{change.description}</span>\n </button>\n <button type=\"button\" className={buttonClass} onClick={() => review.accept(change.id)}>\n Accept\n </button>\n <button type=\"button\" className={buttonClass} onClick={() => review.reject(change.id)}>\n Reject\n </button>\n </li>\n );\n })}\n </ul>\n );\n};\n","import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport {\n createCommandPaletteController,\n matchPaletteHotkey,\n type CommandPaletteController,\n type CommandPaletteOptions,\n type CommandPaletteState,\n type CommandRegistry,\n} from '@pixerate/editor/commands';\n\nexport interface UseCommandPaletteOptions<TContext = any> extends CommandPaletteOptions<TContext> {\n /** Chord that toggles the palette from anywhere, also while typing (e.g. `Mod+K`). */\n hotkey?: string;\n /** Element or window the hotkey listens on (default: `window`). */\n hotkeyTarget?: Window | HTMLElement | null;\n}\n\nexport interface UseCommandPaletteResult extends CommandPaletteState {\n controller: CommandPaletteController;\n setOpen: (open: boolean) => void;\n toggle: () => void;\n setQuery: (query: string) => void;\n setActiveIndex: (index: number) => void;\n move: (delta: number) => void;\n run: CommandPaletteController['run'];\n runActive: CommandPaletteController['runActive'];\n handleKeyDown: CommandPaletteController['handleKeyDown'];\n}\n\n/**\n * Command palette state over a `CommandRegistry` (ranked rows with shortcuts and\n * disabled reasons, active row, recents). Render it with `<CommandPalette palette={…} />`\n * or your own UI. Options are read live; the registry identity is the dependency.\n */\nexport function useCommandPalette<TContext = any>(\n registry: CommandRegistry<TContext>,\n options: UseCommandPaletteOptions<TContext> = {},\n): UseCommandPaletteResult {\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const controller = useMemo(\n () =>\n createCommandPaletteController(registry, {\n context: () => {\n const c = optionsRef.current.context;\n if (c === undefined) return registry.context;\n return (typeof c === 'function' ? (c as () => TContext)() : c) as TContext;\n },\n scope: () => {\n const s = optionsRef.current.scope;\n return typeof s === 'function' ? s() : s;\n },\n recents: options.recents,\n recentLimit: options.recentLimit,\n limit: options.limit,\n platform: options.platform,\n onRecentsChange: (recents) => optionsRef.current.onRecentsChange?.(recents),\n onRun: (result) => optionsRef.current.onRun?.(result),\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [registry],\n );\n\n const state = useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n\n const { hotkey, hotkeyTarget } = options;\n useEffect(() => {\n if (!hotkey) return;\n const target = hotkeyTarget ?? (typeof window !== 'undefined' ? window : null);\n if (!target) return;\n const onKeyDown = (event: Event) => {\n const e = event as KeyboardEvent;\n if (e.defaultPrevented || !matchPaletteHotkey(e, hotkey, optionsRef.current.platform)) return;\n e.preventDefault();\n controller.toggle();\n };\n target.addEventListener('keydown', onKeyDown);\n return () => target.removeEventListener('keydown', onKeyDown);\n }, [controller, hotkey, hotkeyTarget]);\n\n return {\n ...state,\n controller,\n setOpen: controller.setOpen,\n toggle: controller.toggle,\n setQuery: controller.setQuery,\n setActiveIndex: controller.setActiveIndex,\n move: controller.move,\n run: controller.run,\n runActive: controller.runActive,\n handleKeyDown: controller.handleKeyDown,\n };\n}\n","import React, { useEffect, useId, useRef } from 'react';\nimport type { CommandPaletteItem } from '@pixerate/editor/commands';\nimport type { UseCommandPaletteResult } from './useCommandPalette';\n\nexport interface CommandPaletteProps {\n /** State from `useCommandPalette`. */\n palette: UseCommandPaletteResult;\n placeholder?: string;\n emptyMessage?: string;\n /** Extra classes for the dialog panel. */\n className?: string;\n}\n\n/** Label with the fuzzy-matched characters emphasised. */\nfunction HighlightedLabel({ item }: { item: CommandPaletteItem }) {\n if (item.labelIndices.length === 0) return <>{item.label}</>;\n const marked = new Set(item.labelIndices);\n return (\n <>\n {Array.from(item.label).map((ch, i) =>\n marked.has(i) ? (\n <span key={i} className=\"font-semibold text-foreground\" data-match=\"\">\n {ch}\n </span>\n ) : (\n <React.Fragment key={i}>{ch}</React.Fragment>\n ),\n )}\n </>\n );\n}\n\n/**\n * Headless-styled command palette (Tailwind + theme tokens): a search box over the\n * registry's commands showing each command's group, shortcut and, for disabled\n * commands, the reason. Arrow keys move, Enter runs, Escape or a backdrop click closes.\n */\nexport const CommandPalette: React.FC<CommandPaletteProps> = ({\n palette,\n placeholder = 'Type a command…',\n emptyMessage = 'No matching commands',\n className = '',\n}) => {\n const inputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLUListElement>(null);\n const baseId = useId();\n const listId = `${baseId}-list`;\n const optionId = (index: number) => `${baseId}-option-${index}`;\n const { open, query, items, activeIndex } = palette;\n\n useEffect(() => {\n if (open) inputRef.current?.focus();\n }, [open]);\n\n useEffect(() => {\n if (!open) return;\n const active = listRef.current?.querySelector<HTMLElement>('[aria-selected=\"true\"]');\n active?.scrollIntoView?.({ block: 'nearest' });\n }, [open, activeIndex]);\n\n if (!open) return null;\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-start justify-center bg-black/30 px-4 pt-[15vh]\"\n data-command-palette-backdrop=\"\"\n onMouseDown={(e) => {\n if (e.target === e.currentTarget) palette.setOpen(false);\n }}\n >\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Command palette\"\n className={`w-full max-w-lg overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-xl ${className}`}\n style={{ background: 'var(--popover, var(--background, #fff))' }}\n >\n <input\n ref={inputRef}\n type=\"text\"\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={listId}\n aria-autocomplete=\"list\"\n aria-activedescendant={items.length ? optionId(activeIndex) : undefined}\n aria-label=\"Search commands\"\n placeholder={placeholder}\n value={query}\n onChange={(e) => palette.setQuery(e.target.value)}\n onKeyDown={(e) => {\n if (palette.handleKeyDown(e.nativeEvent)) e.stopPropagation();\n }}\n className=\"w-full border-b border-border bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground\"\n />\n {items.length === 0 ? (\n <div className=\"px-3 py-6 text-center text-sm text-muted-foreground\">{emptyMessage}</div>\n ) : (\n <ul ref={listRef} id={listId} role=\"listbox\" aria-label=\"Commands\" className=\"max-h-80 overflow-y-auto py-1\">\n {items.map((item, index) => (\n <li\n key={item.id}\n id={optionId(index)}\n role=\"option\"\n aria-selected={index === activeIndex}\n aria-disabled={!item.enabled || undefined}\n data-command-id={item.id}\n data-recent={item.recent ? '' : undefined}\n title={item.disabledReason}\n onMouseMove={() => index !== activeIndex && palette.setActiveIndex(index)}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => palette.run(item.id)}\n className={`flex cursor-pointer items-center gap-2 px-3 py-1.5 text-sm ${\n index === activeIndex ? 'bg-muted' : ''\n } ${item.enabled ? '' : 'cursor-default opacity-50'}`}\n >\n <span className=\"min-w-0 flex-1 truncate\">\n <HighlightedLabel item={item} />\n {item.disabledReason && (\n <span className=\"ml-2 text-xs text-muted-foreground\" data-disabled-reason=\"\">\n {item.disabledReason}\n </span>\n )}\n </span>\n {item.group && <span className=\"shrink-0 text-xs text-muted-foreground\">{item.group}</span>}\n {item.shortcut && (\n <kbd className=\"shrink-0 rounded border border-border px-1.5 font-mono text-[10px] text-muted-foreground\">\n {item.shortcut}\n </kbd>\n )}\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n );\n};\n","import { useEffect, useRef } from 'react';\nimport type { CommandRegistry, CommandResult, CommandSpec } from '@pixerate/editor/commands';\n\nexport interface UseCommandShortcutsOptions<TContext = any> {\n /** Default `true`. */\n enabled?: boolean;\n /** Element or window to listen on (default: `window`). */\n target?: Window | HTMLElement | null;\n /** Active scopes, most specific first (e.g. `'canvas'` while the canvas has focus). */\n scopes?: string | readonly string[];\n /** Context for the commands (default: the registry's). */\n context?: TContext;\n /** Fire even while typing in inputs / contenteditable (default: per binding). */\n allowInEditable?: boolean;\n /** Called after a shortcut ran a command. */\n onRun?: (result: CommandResult) => void;\n}\n\n/**\n * Runs the registry's commands from their keyboard shortcuts (`registry.handleKeyDown`).\n * Typing in inputs and editors is never hijacked, and disabled commands leave the\n * event alone. Options are read live.\n */\nexport function useCommandShortcuts<TContext = any>(\n registry: CommandRegistry<TContext> | null | undefined,\n options: UseCommandShortcutsOptions<TContext> = {},\n): void {\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const { enabled = true, target } = options;\n\n useEffect(() => {\n if (!registry || !enabled) return;\n const eventTarget = target ?? (typeof window !== 'undefined' ? window : null);\n if (!eventTarget) return;\n const onKeyDown = (event: Event) => {\n const { scopes, context, allowInEditable, onRun } = optionsRef.current;\n const result = registry.handleKeyDown(event as KeyboardEvent, {\n scopes,\n ...(allowInEditable !== undefined ? { allowInEditable } : {}),\n ...(context !== undefined ? { context } : {}),\n });\n if (result) onRun?.(result);\n };\n eventTarget.addEventListener('keydown', onKeyDown);\n return () => eventTarget.removeEventListener('keydown', onKeyDown);\n }, [registry, enabled, target]);\n}\n\n/**\n * Registers commands while the component is mounted. Memoize `specs` (e.g. with\n * `useMemo(() => createHistoryCommands(manager), [manager])`): a new array re-registers.\n */\nexport function useRegisterCommands<TContext = any>(\n registry: CommandRegistry<TContext> | null | undefined,\n specs: readonly CommandSpec<TContext>[] | null | undefined,\n): void {\n useEffect(() => {\n if (!registry || !specs || specs.length === 0) return;\n return registry.register(specs);\n }, [registry, specs]);\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n createAutosaveController,\n createRevisionTracker,\n type AutosaveController,\n type AutosaveRecovery,\n type AutosaveStatusInfo,\n type DirtyFlagSource,\n type RevisionChangeSource,\n type RevisionTracker,\n type StorageAdapter,\n} from '@pixerate/editor/persistence';\n\nexport interface UseAutosaveOptions<T> {\n storage: StorageAdapter;\n /** Snapshot key (the meta lives at `<key>:meta`). */\n key: string;\n /** Reads the current document (the latest function is always used). */\n getSnapshot: () => T;\n serialize?: (snapshot: T) => string;\n deserialize?: (text: string) => T;\n /** Document name stored with the snapshot. */\n name?: string;\n /** Change notifications, e.g. a `HistoryManager`. */\n history?: RevisionChangeSource;\n /** Saved-vs-current flag, e.g. `useHistoryDirty().tracker` or a `bindDirtyToHistory` binding. */\n dirty?: DirtyFlagSource;\n interval?: number;\n debounceMs?: number;\n retryBaseMs?: number;\n retryMaxMs?: number;\n /**\n * Whether the document has finished loading (default `true`). Snapshots start\n * once this is true and any recovered snapshot was restored or discarded.\n */\n ready?: boolean;\n /** Look for an earlier session's snapshot on mount (default `true`). */\n recover?: boolean;\n /** Write pending changes on `pagehide` and when the tab is hidden (default `true`). */\n flushOnHide?: boolean;\n}\n\nexport interface UseAutosaveResult<T> {\n status: AutosaveStatusInfo;\n /** An earlier session's unsaved snapshot, until restored or discarded. */\n recovery: AutosaveRecovery<T> | null;\n /** True while the recovery check runs or a recovered snapshot awaits a decision. */\n pendingRecovery: boolean;\n /** Takes the recovered snapshot (apply it to the editor) and starts autosaving. */\n restore: () => T | undefined;\n /** Deletes the recovered snapshot and starts autosaving. */\n discard: () => Promise<void>;\n /** Writes pending changes now. */\n flushNow: () => Promise<void>;\n /** Call after an explicit save: marks the current revision saved and retires this session's snapshot. */\n markClean: () => Promise<void>;\n /** Records a change made outside `history`. */\n notifyChange: () => void;\n controller: AutosaveController<T> | null;\n}\n\nconst IDLE: AutosaveStatusInfo = {\n status: 'idle',\n error: null,\n failures: 0,\n nextAttemptAt: null,\n lastSavedAt: null,\n ready: false,\n};\n\n/**\n * Crash-recovery autosave bound to a history and dirty flag, with page\n * lifecycle flushing and a recovery check on mount (see\n * `createAutosaveController` in `@pixerate/editor/persistence`). Render\n * `<RecoveryPrompt>` with `recovery`, `restore` and `discard`.\n */\nexport function useAutosave<T>(options: UseAutosaveOptions<T>): UseAutosaveResult<T> {\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const { storage, key, history, dirty } = options;\n const recover = options.recover !== false;\n const flushOnHide = options.flushOnHide !== false;\n const ready = options.ready !== false;\n\n const [controller, setController] = useState<AutosaveController<T> | null>(null);\n const [status, setStatus] = useState<AutosaveStatusInfo>(IDLE);\n const [recovery, setRecovery] = useState<AutosaveRecovery<T> | null>(null);\n const [pendingRecovery, setPendingRecovery] = useState(recover);\n const revisionsRef = useRef<RevisionTracker | null>(null);\n\n useEffect(() => {\n const revisions = createRevisionTracker({ history, dirty });\n const o = optionsRef.current;\n const instance = createAutosaveController<T>({\n storage,\n key,\n getSnapshot: () => optionsRef.current.getSnapshot(),\n serialize: o.serialize,\n deserialize: o.deserialize,\n name: () => optionsRef.current.name,\n revision: revisions.revision,\n savedRevision: revisions.savedRevision,\n interval: o.interval,\n debounceMs: o.debounceMs,\n retryBaseMs: o.retryBaseMs,\n retryMaxMs: o.retryMaxMs,\n });\n const unsubscribeStatus = instance.subscribe(setStatus);\n const unsubscribeRevisions = revisions.subscribe(() => instance.notify());\n revisionsRef.current = revisions;\n setController(instance);\n setStatus(instance.getStatus());\n\n let active = true;\n if (recover) {\n setPendingRecovery(true);\n instance\n .checkRecovery()\n .catch(() => null)\n .then((found) => {\n if (!active) return;\n setRecovery(found);\n setPendingRecovery(found !== null);\n });\n } else {\n setRecovery(null);\n setPendingRecovery(false);\n }\n\n return () => {\n active = false;\n unsubscribeStatus();\n unsubscribeRevisions();\n revisions.destroy();\n instance.destroy();\n if (revisionsRef.current === revisions) revisionsRef.current = null;\n };\n }, [storage, key, history, dirty, recover]);\n\n useEffect(() => {\n if (controller && ready && !pendingRecovery) controller.ready();\n }, [controller, ready, pendingRecovery]);\n\n useEffect(() => {\n if (!controller || !flushOnHide || typeof window === 'undefined') return;\n const flush = () => void controller.flushNow();\n const onVisibility = () => {\n if (document.visibilityState === 'hidden') flush();\n };\n window.addEventListener('pagehide', flush);\n document.addEventListener('visibilitychange', onVisibility);\n return () => {\n window.removeEventListener('pagehide', flush);\n document.removeEventListener('visibilitychange', onVisibility);\n };\n }, [controller, flushOnHide]);\n\n const restore = useCallback(() => {\n const snapshot = recovery?.snapshot;\n setRecovery(null);\n setPendingRecovery(false);\n return snapshot;\n }, [recovery]);\n\n const discard = useCallback(async () => {\n if (controller) await controller.discardRecovery();\n setRecovery(null);\n setPendingRecovery(false);\n }, [controller]);\n\n const flushNow = useCallback(async () => {\n await controller?.flushNow();\n }, [controller]);\n\n const markClean = useCallback(async () => {\n revisionsRef.current?.markSaved();\n await controller?.markClean();\n }, [controller]);\n\n const notifyChange = useCallback(() => revisionsRef.current?.bump(), []);\n\n return { status, recovery, pendingRecovery, restore, discard, flushNow, markClean, notifyChange, controller };\n}\n","import React from 'react';\nimport { formatRecoveryMessage, type RecoveryMeta } from '@pixerate/editor/persistence';\n\nexport interface RecoveryPromptProps {\n /** `useAutosave().recovery`; nothing renders while it is `null`. */\n recovery: { meta: RecoveryMeta } | null;\n onRestore: () => void;\n onDiscard: () => void;\n /** Formats the snapshot time (default `toLocaleString`). */\n formatTime?: (time: number) => string;\n restoreLabel?: string;\n discardLabel?: string;\n className?: string;\n}\n\n/**\n * \"Restore unsaved changes from <time>?\" banner with Restore / Discard buttons\n * (Tailwind + theme tokens).\n */\nexport const RecoveryPrompt: React.FC<RecoveryPromptProps> = ({\n recovery,\n onRestore,\n onDiscard,\n formatTime,\n restoreLabel = 'Restore',\n discardLabel = 'Discard',\n className = '',\n}) => {\n if (!recovery) return null;\n const { name } = recovery.meta;\n return (\n <div\n role=\"alertdialog\"\n aria-label=\"Unsaved changes found\"\n data-recovery-prompt=\"\"\n className={`flex flex-wrap items-center gap-3 rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground shadow-sm ${className}`}\n >\n <span className=\"min-w-0 flex-1\">\n {formatRecoveryMessage(recovery.meta, formatTime)}\n {name ? <span className=\"ml-1 text-xs text-muted-foreground\">({name})</span> : null}\n </span>\n <button\n type=\"button\"\n data-recovery-restore=\"\"\n onClick={onRestore}\n className=\"rounded-md bg-primary px-3 py-1 text-xs font-medium text-primary-foreground hover:opacity-90\"\n >\n {restoreLabel}\n </button>\n <button\n type=\"button\"\n data-recovery-discard=\"\"\n onClick={onDiscard}\n className=\"rounded-md border border-border px-3 py-1 text-xs font-medium hover:bg-muted\"\n >\n {discardLabel}\n </button>\n </div>\n );\n};\n","import { useEffect, useMemo, useState } from 'react';\nimport {\n estimateJobProgress,\n planGenerationRequest,\n type GenerationPlan,\n type GenerationRequest,\n type JobProgressEstimate,\n type ModelCapabilities,\n type PlanOptions,\n} from '@pixerate/editor/generation';\n\n/**\n * Plans `request` against `capabilities` (see `planGenerationRequest`) and\n * returns the adjusted request, adjustments and errors. Recomputed only when\n * the request, capabilities or options change by value, so inline objects are fine.\n */\nexport function useGenerationPlan(\n request: GenerationRequest,\n capabilities: ModelCapabilities,\n options: PlanOptions = {},\n): GenerationPlan {\n const key = JSON.stringify([request, capabilities, options]);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useMemo(() => planGenerationRequest(request, capabilities, options), [key]);\n}\n\nexport interface UseJobProgressOptions {\n startedAt: number | Date | string;\n expectedMs?: number;\n done?: boolean;\n /** Fixed current time (disables ticking; useful for SSR and tests). */\n now?: number | Date | string;\n /** Re-render interval while running in ms (default 1000). */\n intervalMs?: number;\n}\n\n/** Ticking `estimateJobProgress` for a running job; stops ticking when `done`. */\nexport function useJobProgress(options: UseJobProgressOptions): JobProgressEstimate {\n const { startedAt, expectedMs, done, now, intervalMs = 1000 } = options;\n const [tick, setTick] = useState(() => Date.now());\n const ticking = !done && now === undefined;\n useEffect(() => {\n if (!ticking) return;\n setTick(Date.now());\n const id = setInterval(() => setTick(Date.now()), Math.max(16, intervalMs));\n return () => clearInterval(id);\n }, [ticking, intervalMs]);\n return estimateJobProgress({ startedAt, expectedMs, done, now: now ?? tick });\n}\n","import React, { useId, useMemo } from 'react';\nimport {\n getGenerationControls,\n getReferenceSlots,\n getRequestValue,\n parseControlValue,\n removeReference,\n setRequestValue,\n type GenerationControl,\n type GenerationPlan,\n type GenerationReference,\n type GenerationRequest,\n type ModelCapabilities,\n type PlanStrategy,\n type ReferenceRole,\n} from '@pixerate/editor/generation';\nimport { useGenerationPlan } from './useGenerationPlan';\n\nexport interface GenerationSettingsProps {\n capabilities: ModelCapabilities;\n /** The request being edited (controlled). */\n value: GenerationRequest;\n onChange: (next: GenerationRequest) => void;\n /** A plan computed elsewhere; otherwise one is computed with `strategy`. */\n plan?: GenerationPlan;\n /** Strategy for the built-in plan (default `nearest`). */\n strategy?: PlanStrategy;\n /** List plan adjustments and errors under the controls (default `true`). */\n showAdjustments?: boolean;\n /** Shows an \"Add\" button per reference role; you pick the asset and call `onChange`. */\n onAddReference?: (role: ReferenceRole) => void;\n /** Custom rendering of a reference chip (default: its id). */\n renderReference?: (reference: GenerationReference) => React.ReactNode;\n className?: string;\n}\n\nconst inputClass =\n 'w-full rounded-md border border-border bg-background px-2 py-1 text-sm outline-none focus:ring-1 focus:ring-ring';\n\nfunction Control({\n control,\n value,\n id,\n onValue,\n}: {\n control: GenerationControl;\n value: unknown;\n id: string;\n onValue: (value: unknown) => void;\n}) {\n const shown = value ?? control.defaultValue;\n if (control.kind === 'checkbox') {\n return (\n <input\n id={id}\n type=\"checkbox\"\n data-field={control.key}\n checked={Boolean(shown)}\n onChange={(e) => onValue(parseControlValue(control, e.target.checked))}\n />\n );\n }\n if (control.kind === 'select') {\n return (\n <select\n id={id}\n data-field={control.key}\n className={inputClass}\n value={shown === undefined ? '' : String(shown)}\n onChange={(e) => onValue(parseControlValue(control, e.target.value))}\n >\n {shown === undefined && <option value=\"\">Default</option>}\n {control.options!.map((option) => (\n <option key={String(option.value)} value={String(option.value)}>\n {option.label}\n </option>\n ))}\n </select>\n );\n }\n if (control.kind === 'textarea') {\n return (\n <textarea\n id={id}\n data-field={control.key}\n className={inputClass}\n rows={2}\n maxLength={control.maxLength}\n value={typeof value === 'string' ? value : ''}\n onChange={(e) => onValue(parseControlValue(control, e.target.value))}\n />\n );\n }\n const numeric = typeof shown === 'number' ? shown : undefined;\n return (\n <div className=\"flex items-center gap-2\">\n <input\n id={id}\n type={control.kind === 'range' ? 'range' : 'number'}\n data-field={control.key}\n className={control.kind === 'range' ? 'flex-1' : inputClass}\n min={control.min}\n max={control.max}\n step={control.step ?? 'any'}\n value={numeric ?? (control.kind === 'range' ? (control.min ?? 0) : '')}\n onChange={(e) => onValue(parseControlValue(control, e.target.value))}\n />\n {control.kind === 'range' && (\n <span className=\"w-10 text-right tabular-nums text-muted-foreground\" data-field-value=\"\">\n {numeric ?? '–'}\n </span>\n )}\n </div>\n );\n}\n\n/**\n * Headless-styled settings form generated from a model's capabilities:\n * selects for choices, sliders/number inputs for ranges, text areas for\n * negative/system prompts, checkboxes for boolean params, reference slots by\n * role, and the plan's adjustments and errors. Controlled via `value` / `onChange`.\n */\nexport const GenerationSettings: React.FC<GenerationSettingsProps> = ({\n capabilities,\n value,\n onChange,\n plan: planProp,\n strategy,\n showAdjustments = true,\n onAddReference,\n renderReference,\n className = '',\n}) => {\n const baseId = useId();\n const controls = useMemo(() => getGenerationControls(capabilities), [capabilities]);\n const computed = useGenerationPlan(value, capabilities, { strategy });\n const plan = planProp ?? computed;\n const slots = getReferenceSlots(capabilities, value);\n\n return (\n <div className={`flex flex-col gap-3 text-sm ${className}`} data-generation-settings=\"\" data-model={capabilities.id}>\n {controls.map((control) => {\n const id = `${baseId}-${control.key}`;\n return (\n <div key={control.key} className=\"flex flex-col gap-1\" data-control={control.key}>\n <label htmlFor={id} className=\"text-xs font-medium text-muted-foreground\" title={control.description}>\n {control.label}\n </label>\n <Control\n control={control}\n id={id}\n value={getRequestValue(value, control.key)}\n onValue={(next) => onChange(setRequestValue(value, control.key, next))}\n />\n </div>\n );\n })}\n\n {slots.map((slot) => (\n <fieldset key={slot.role} className=\"flex flex-col gap-1\" data-reference-role={slot.role}>\n <legend className=\"text-xs font-medium text-muted-foreground\" title={slot.description}>\n {slot.label}{' '}\n <span className=\"tabular-nums\" data-reference-count=\"\">\n ({slot.references.length}/{slot.max})\n </span>\n {slot.min > 0 && <span className=\"text-destructive\"> *</span>}\n </legend>\n <ul className=\"flex flex-wrap gap-1\">\n {slot.references.map((ref) => (\n <li key={ref.id} className=\"flex items-center gap-1 rounded border border-border px-1.5 py-0.5\" data-reference-id={ref.id}>\n {renderReference ? renderReference(ref) : <span className=\"max-w-[10rem] truncate\">{ref.id}</span>}\n <button\n type=\"button\"\n aria-label={`Remove ${slot.label} ${ref.id}`}\n className=\"text-muted-foreground hover:text-foreground\"\n onClick={() => onChange(removeReference(value, slot.role, ref.id))}\n >\n ×\n </button>\n </li>\n ))}\n {onAddReference && slot.canAdd && (\n <li>\n <button\n type=\"button\"\n className=\"rounded border border-dashed border-border px-1.5 py-0.5 text-muted-foreground hover:text-foreground\"\n onClick={() => onAddReference(slot.role)}\n >\n Add\n </button>\n </li>\n )}\n </ul>\n </fieldset>\n ))}\n\n {showAdjustments && plan.adjustments.length > 0 && (\n <ul role=\"status\" className=\"flex flex-col gap-0.5 text-xs text-muted-foreground\" data-generation-adjustments=\"\">\n {plan.adjustments.map((adjustment, index) => (\n <li key={index} data-adjustment-field={adjustment.field} data-adjustment-kind={adjustment.kind}>\n {adjustment.reason}\n </li>\n ))}\n </ul>\n )}\n {showAdjustments && plan.errors.length > 0 && (\n <ul role=\"alert\" className=\"flex flex-col gap-0.5 text-xs text-destructive\" data-generation-errors=\"\">\n {plan.errors.map((error, index) => (\n <li key={index} data-error-field={error.field}>\n {error.message}\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n};\n","import React from 'react';\nimport { useJobProgress, type UseJobProgressOptions } from './useGenerationPlan';\n\nexport interface JobProgressProps extends UseJobProgressOptions {\n /** Text shown before the time label, e.g. the model name. */\n title?: string;\n /** Extra classes for the root. */\n className?: string;\n}\n\n/**\n * Headless-styled progress bar for a generation job that reports no progress\n * of its own: time-based percent (held at 95% until `done`) with a\n * \"~2m left\" / \"Almost done…\" label. Exposes `role=\"progressbar\"`.\n */\nexport const JobProgress: React.FC<JobProgressProps> = ({ title, className = '', ...options }) => {\n const progress = useJobProgress(options);\n return (\n <div className={`flex flex-col gap-1 text-sm ${className}`} data-job-progress=\"\" data-done={options.done ? '' : undefined}>\n <div className=\"flex items-center justify-between gap-2 text-muted-foreground\">\n {title && <span className=\"truncate text-foreground\">{title}</span>}\n <span data-job-progress-label=\"\" aria-live=\"polite\">\n {progress.label}\n </span>\n </div>\n <div\n role=\"progressbar\"\n aria-label={title ?? 'Generation progress'}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={progress.percent}\n aria-valuetext={`${progress.percent}%, ${progress.label}`}\n className=\"h-1.5 w-full overflow-hidden rounded-full bg-muted\"\n >\n <div\n className=\"h-full rounded-full bg-primary transition-[width] duration-500\"\n style={{ width: `${progress.percent}%`, background: 'var(--primary, currentColor)' }}\n />\n </div>\n </div>\n );\n};\n","import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n defaultAssetRoleOptions,\n describeAssetMentions,\n findTextMentions,\n getAssetRoleOptions,\n setMentionRoleInText,\n type AssetInfo,\n type AssetMentionChip,\n type AssetRoleOption,\n type ModelCapabilities,\n} from '@pixerate/editor/generation';\n\nexport interface AssetMentionChipsProps {\n /** Prompt text containing `@asset` / `@asset:role` mentions. */\n content: string;\n /** Called with the text after a role is picked (`@fox` → `@fox:style_ref`). */\n onChange: (next: string) => void;\n /** Mentionable assets; mentions that match none (by id or label) are not shown. */\n assets: readonly AssetInfo[];\n /** The selected model: its roles are offered and mentions are checked against it. */\n capabilities?: ModelCapabilities;\n /** Role options (default: the model's roles, else the built-in roles). */\n roles?: readonly AssetRoleOption[];\n /** Custom chip content (default: the asset label). */\n renderAsset?: (chip: AssetMentionChip) => React.ReactNode;\n className?: string;\n}\n\n/**\n * The asset mentions of a prompt as chips with role badges. Clicking a chip\n * opens a role picker popover; picking a role rewrites the mention's `:role`\n * suffix in the text. Chips with problems for the model (unsupported role,\n * wrong media type, too many for the role) are flagged.\n */\nexport const AssetMentionChips: React.FC<AssetMentionChipsProps> = ({\n content,\n onChange,\n assets,\n capabilities,\n roles,\n renderAsset,\n className = '',\n}) => {\n const [open, setOpen] = useState<number | null>(null);\n const rootRef = useRef<HTMLDivElement>(null);\n const chips = useMemo(\n () => describeAssetMentions(findTextMentions(content), assets, capabilities),\n [content, assets, capabilities],\n );\n const options = roles ?? (capabilities ? getAssetRoleOptions(capabilities) : defaultAssetRoleOptions());\n\n useEffect(() => {\n if (open === null) return;\n const onPointer = (event: MouseEvent) => {\n if (!rootRef.current?.contains(event.target as Node)) setOpen(null);\n };\n document.addEventListener('mousedown', onPointer);\n return () => document.removeEventListener('mousedown', onPointer);\n }, [open]);\n\n const pick = (chip: AssetMentionChip, role: string | null) => {\n setOpen(null);\n if (chip.start === undefined) return;\n onChange(setMentionRoleInText(content, chip.start, role));\n };\n\n if (chips.length === 0) return null;\n return (\n <div ref={rootRef} className={`flex flex-wrap gap-1.5 ${className}`} data-asset-mention-chips=\"\">\n {chips.map((chip) => {\n const error = chip.issues.find((issue) => issue.severity === 'error');\n const warning = chip.issues.find((issue) => issue.severity === 'warning');\n const problem = error ?? warning;\n const isOpen = open === chip.index;\n return (\n <span key={`${chip.start}-${chip.index}`} className=\"relative inline-flex\" data-asset-chip={chip.asset.id}>\n <button\n type=\"button\"\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n title={problem?.message}\n data-issue={problem?.code}\n onClick={() => setOpen(isOpen ? null : chip.index)}\n onKeyDown={(e) => {\n if (e.key === 'Escape') setOpen(null);\n }}\n className={`inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs ${\n error ? 'border-red-500/60' : warning ? 'border-amber-500/60' : 'border-border'\n } bg-muted/40 hover:bg-muted`}\n >\n <span>{renderAsset ? renderAsset(chip) : `@${chip.asset.label ?? chip.handle}`}</span>\n <span\n className={`rounded px-1 text-[10px] uppercase tracking-wide ${chip.role ? 'bg-primary/15' : 'opacity-60'}`}\n data-role-badge={chip.role ?? ''}\n >\n {chip.roleLabel ?? 'No role'}\n </span>\n </button>\n {isOpen && (\n <div\n role=\"listbox\"\n aria-label={`Role for ${chip.asset.label ?? chip.handle}`}\n className=\"absolute left-0 top-full z-50 mt-1 flex min-w-[12rem] flex-col rounded-md border border-border bg-background p-1 text-xs shadow-lg\"\n data-role-picker=\"\"\n onKeyDown={(e) => {\n if (e.key === 'Escape') setOpen(null);\n }}\n >\n {options.map((option) => (\n <button\n key={option.role}\n type=\"button\"\n role=\"option\"\n aria-selected={chip.role === option.role}\n data-role-option={option.role}\n title={option.description}\n onClick={() => pick(chip, option.role)}\n className=\"flex items-center justify-between gap-2 rounded px-2 py-1 text-left hover:bg-muted\"\n >\n <span>{option.label}</span>\n {option.accepts?.length ? (\n <span className=\"text-[10px] opacity-60\">{option.accepts.join(', ')}</span>\n ) : null}\n </button>\n ))}\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={!chip.role}\n data-role-option=\"\"\n onClick={() => pick(chip, null)}\n className=\"rounded px-2 py-1 text-left opacity-70 hover:bg-muted\"\n >\n No role\n </button>\n {chip.issues.length > 0 && (\n <ul className=\"mt-1 border-t border-border px-2 pt-1 text-[10px]\" data-chip-issues=\"\">\n {chip.issues.map((issue, i) => (\n <li key={i} className={issue.severity === 'error' ? 'text-red-500' : 'text-amber-500'}>\n {issue.message}\n </li>\n ))}\n </ul>\n )}\n </div>\n )}\n </span>\n );\n })}\n </div>\n );\n};\n","import React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n DRIFT_TYPE_LABELS,\n recreateRequest,\n referenceRoleLabel,\n stableStringify,\n variationRequest,\n type AssetLookup,\n type GenerationRecord,\n type GenerationRecordFilter,\n type GenerationRecordStore,\n type ModelCapabilities,\n type RecreateMode,\n type RecreateOptions,\n type RecreateResult,\n} from '@pixerate/editor/generation';\n\ntype Template = NonNullable<RecreateOptions['templates']>[number];\n\nexport interface UseGenerationRecordsResult {\n records: GenerationRecord[];\n loading: boolean;\n error: unknown;\n refresh: () => Promise<void>;\n}\n\n/**\n * Loads records from a `GenerationRecordStore` (newest first) and reloads\n * whenever the store changes. `filter` is compared by value.\n */\nexport function useGenerationRecords(\n store: GenerationRecordStore | null | undefined,\n filter?: GenerationRecordFilter,\n): UseGenerationRecordsResult {\n const [records, setRecords] = useState<GenerationRecord[]>([]);\n const [loading, setLoading] = useState(!!store);\n const [error, setError] = useState<unknown>(null);\n const filterKey = stableStringify(filter ?? {});\n\n const refresh = useCallback(async () => {\n if (!store) {\n setRecords([]);\n setLoading(false);\n return;\n }\n setLoading(true);\n try {\n const next = await store.list(filter);\n setRecords(next);\n setError(null);\n } catch (err) {\n setError(err);\n } finally {\n setLoading(false);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [store, filterKey]);\n\n useEffect(() => {\n void refresh();\n if (!store) return;\n return store.subscribe(() => void refresh());\n }, [store, refresh]);\n\n return { records, loading, error, refresh };\n}\n\nexport interface GenerationHistoryProps {\n records: readonly GenerationRecord[];\n /** Current templates (drift detection, and resolution in `latest` mode). */\n templates?: readonly Template[];\n /** Current models (capability drift and re-planning). */\n capabilities?: ModelCapabilities | readonly ModelCapabilities[];\n /** Current assets (missing / changed asset drift). */\n assets?: AssetLookup;\n /** Recreate mode (controlled); otherwise a toggle starting at `exact`. */\n mode?: RecreateMode;\n onModeChange?: (mode: RecreateMode) => void;\n /** \"Recreate\": receives the rebuilt request and drift report. */\n onRecreate?: (result: RecreateResult, record: GenerationRecord) => void;\n /** \"Variation\": same request with a new seed. */\n onVariation?: (result: RecreateResult, record: GenerationRecord) => void;\n onRemove?: (record: GenerationRecord) => void;\n /** Extra content per record (e.g. output thumbnails). */\n renderPreview?: (record: GenerationRecord) => React.ReactNode;\n emptyText?: string;\n className?: string;\n}\n\nconst severityClass = {\n info: 'text-sky-600 dark:text-sky-300',\n warning: 'text-amber-600 dark:text-amber-300',\n error: 'text-red-600 dark:text-red-400',\n} as const;\n\n/**\n * Generation history: one entry per record with its model, prompt, asset\n * role badges and the drift since it was made (templates edited, model\n * capabilities changed, settings no longer supported, assets missing), plus\n * Recreate and Variation buttons. Recreate is disabled when drift blocks it.\n */\nexport const GenerationHistory: React.FC<GenerationHistoryProps> = ({\n records,\n templates,\n capabilities,\n assets,\n mode: modeProp,\n onModeChange,\n onRecreate,\n onVariation,\n onRemove,\n renderPreview,\n emptyText = 'No generations yet.',\n className = '',\n}) => {\n const [innerMode, setInnerMode] = useState<RecreateMode>('exact');\n const mode = modeProp ?? innerMode;\n const setMode = (next: RecreateMode) => {\n if (modeProp === undefined) setInnerMode(next);\n onModeChange?.(next);\n };\n const options = useMemo(() => ({ templates, capabilities, assets, mode }), [templates, capabilities, assets, mode]);\n const results = useMemo(() => records.map((record) => recreateRequest(record, options)), [records, options]);\n const models = useMemo(\n () => (capabilities ? (Array.isArray(capabilities) ? capabilities : [capabilities as ModelCapabilities]) : []),\n [capabilities],\n );\n\n return (\n <div className={`flex flex-col gap-2 text-sm ${className}`} data-generation-history=\"\">\n <div className=\"flex items-center gap-2 text-xs\" role=\"radiogroup\" aria-label=\"Recreate mode\">\n {(['exact', 'latest'] as const).map((value) => (\n <label key={value} className=\"inline-flex items-center gap-1\">\n <input\n type=\"radio\"\n name=\"generation-history-mode\"\n value={value}\n checked={mode === value}\n onChange={() => setMode(value)}\n data-mode={value}\n />\n {value === 'exact' ? 'Exact (recorded versions)' : 'Latest templates & settings'}\n </label>\n ))}\n </div>\n {records.length === 0 && <p className=\"text-xs text-muted-foreground\">{emptyText}</p>}\n <ul className=\"flex flex-col gap-2\">\n {records.map((record, i) => {\n const result = results[i];\n const model = models.find((m) => m.id === record.provenance.modelId);\n const blocked = !result.ok;\n return (\n <li\n key={record.id}\n className=\"rounded-md border border-border p-2\"\n data-record={record.id}\n data-drift={result.drift.length}\n >\n <div className=\"flex flex-wrap items-center justify-between gap-2 text-xs\">\n <span className=\"font-medium\">{model?.name ?? record.provenance.modelId}</span>\n <span className=\"text-muted-foreground\">\n {record.kind !== 'generate' && <span data-kind=\"\">{record.kind} · </span>}\n <time dateTime={record.createdAt}>{record.createdAt.replace('T', ' ').slice(0, 16)}</time>\n {record.seed !== undefined && <> · seed {record.seed}</>}\n </span>\n </div>\n <p className=\"mt-1 line-clamp-3 break-words text-xs\" data-record-prompt=\"\">\n {record.provenance.resolvedPrompt}\n </p>\n {record.assets.length > 0 && (\n <div className=\"mt-1 flex flex-wrap gap-1\">\n {record.assets.map((asset) => (\n <span\n key={`${asset.role}:${asset.id}`}\n className=\"rounded-full bg-muted px-2 py-0.5 text-[10px]\"\n data-asset-role={asset.role}\n >\n {asset.id} · {referenceRoleLabel(asset.role, model)}\n </span>\n ))}\n </div>\n )}\n {renderPreview?.(record)}\n {result.drift.length > 0 && (\n <ul className=\"mt-1 flex flex-col gap-0.5 text-[11px]\" data-drift-report=\"\">\n {result.drift.map((item, j) => (\n <li key={j} className={severityClass[item.severity]} data-drift-type={item.type}>\n <strong>{DRIFT_TYPE_LABELS[item.type]}:</strong> {item.message}\n </li>\n ))}\n </ul>\n )}\n <div className=\"mt-2 flex gap-2\">\n {onRecreate && (\n <button\n type=\"button\"\n disabled={blocked}\n title={blocked ? 'This generation cannot be recreated as recorded.' : undefined}\n onClick={() => onRecreate(result, record)}\n className=\"rounded border border-border px-2 py-0.5 text-xs hover:bg-muted disabled:opacity-50\"\n data-action=\"recreate\"\n >\n Recreate\n </button>\n )}\n {onVariation && (\n <button\n type=\"button\"\n onClick={() => onVariation(variationRequest(record, {}, options), record)}\n className=\"rounded border border-border px-2 py-0.5 text-xs hover:bg-muted\"\n data-action=\"variation\"\n >\n Variation\n </button>\n )}\n {onRemove && (\n <button\n type=\"button\"\n onClick={() => onRemove(record)}\n className=\"ml-auto rounded px-2 py-0.5 text-xs text-muted-foreground hover:bg-muted\"\n data-action=\"remove\"\n >\n Remove\n </button>\n )}\n </div>\n </li>\n );\n })}\n </ul>\n </div>\n );\n};\n","import { useCallback, useMemo, useSyncExternalStore } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n EMPTY_FIND_REPLACE_SNAPSHOT,\n getFindReplaceStore,\n type FindOptions,\n type FindReplaceMode,\n type FindReplaceSnapshot,\n} from \"@pixerate/editor\";\n\nexport interface UseFindReplaceResult extends FindReplaceSnapshot {\n /** Whether the editor has the `FindReplace` extension. */\n available: boolean;\n matchCount: number;\n open: boolean;\n show: (mode?: FindReplaceMode) => void;\n close: () => void;\n setQuery: (query: string) => void;\n setReplacement: (replacement: string) => void;\n setOptions: (options: Partial<FindOptions>) => void;\n toggleOption: (option: keyof FindOptions) => void;\n next: () => void;\n previous: () => void;\n replace: () => void;\n replaceAll: () => void;\n clear: () => void;\n}\n\nconst noopUnsubscribe = () => {};\n\n/**\n * Subscribes to an editor's Find and Replace state (`FindReplace` extension)\n * and exposes its commands.\n */\nexport function useFindReplace(editor: Editor | null | undefined): UseFindReplaceResult {\n const store = getFindReplaceStore(editor ?? null);\n const subscribe = useCallback(\n (onChange: () => void) => (store ? store.subscribe(() => onChange()) : noopUnsubscribe),\n [store],\n );\n const getSnapshot = () => store?.getSnapshot() ?? EMPTY_FIND_REPLACE_SNAPSHOT;\n const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n return useMemo(() => {\n const run = (fn: (e: Editor) => void) => {\n if (editor && !editor.isDestroyed && store) fn(editor);\n };\n return {\n ...snapshot,\n available: !!store,\n matchCount: snapshot.matches.length,\n show: (mode: FindReplaceMode = \"find\") =>\n run((e) => e.commands.openFindReplace({ mode })),\n close: () => run((e) => e.commands.closeFindReplace()),\n setQuery: (query: string) => run((e) => e.commands.setSearch({ query })),\n setReplacement: (replacement: string) => run((e) => e.commands.setSearch({ replacement })),\n setOptions: (options: Partial<FindOptions>) => run((e) => e.commands.setSearch({ options })),\n toggleOption: (option: keyof FindOptions) =>\n run((e) => e.commands.setSearch({ options: { [option]: !snapshot.options[option] } })),\n next: () => run((e) => e.commands.findNext()),\n previous: () => run((e) => e.commands.findPrevious()),\n replace: () => run((e) => e.commands.replaceCurrent()),\n replaceAll: () => run((e) => e.commands.replaceAll()),\n clear: () => run((e) => e.commands.clearSearch()),\n };\n }, [snapshot, editor, store]);\n}\n","import React, { useEffect, useRef, useState } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { FIND_OPTION_TOGGLES, formatFindStatus } from \"@pixerate/editor\";\nimport { useFindReplace } from \"./useFindReplace\";\n\nexport interface FindReplaceBarProps {\n editor: Editor | null;\n className?: string;\n /** Render even while the find state is closed (default: only after Mod+F / Mod+H / `openFindReplace`). */\n alwaysOpen?: boolean;\n /** Show the \"More options\" toggle (prefix, suffix, ignore punctuation/white space, literal). Default `true`. */\n showMoreOptions?: boolean;\n /** Called after the bar closes (Escape or the close button). */\n onClose?: () => void;\n}\n\nconst inputClass =\n \"min-w-0 flex-1 rounded border border-input bg-background px-2 py-1 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-ring\";\nconst buttonClass =\n \"rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent\";\nconst toggleClass = (on: boolean) =>\n `${buttonClass} font-mono ${on ? \"bg-primary/10 text-primary\" : \"text-muted-foreground\"}`;\n\nconst isMod = (e: React.KeyboardEvent) => e.metaKey || e.ctrlKey;\n\n/**\n * Word-style find bar for an editor using the `FindReplace` extension: find\n * and replace fields, option toggles, \"3 of 12\" counter, previous/next,\n * Replace and Replace All. Enter / Shift+Enter step through matches, Enter in\n * the replace field replaces, Mod+Enter replaces all, Escape closes.\n */\nexport const FindReplaceBar: React.FC<FindReplaceBarProps> = ({\n editor,\n className = \"flex flex-col gap-1 rounded-md border border-border bg-background p-1 text-sm shadow-sm\",\n alwaysOpen = false,\n showMoreOptions = true,\n onClose,\n}) => {\n const find = useFindReplace(editor);\n const findInput = useRef<HTMLInputElement>(null);\n const [moreOpen, setMoreOpen] = useState(false);\n const visible = find.available && (alwaysOpen || find.open);\n\n // Mod+F / Mod+H (in the editor or the bar) focus and select the find field.\n useEffect(() => {\n if (!visible || find.focusRequest === 0) return;\n findInput.current?.focus();\n findInput.current?.select();\n }, [visible, find.focusRequest]);\n\n if (!visible) return null;\n\n const showReplace = find.mode === \"replace\";\n const status = formatFindStatus(find);\n const hasMatches = find.matchCount > 0;\n\n const close = () => {\n find.close();\n editor?.commands.focus();\n onClose?.();\n };\n\n const onBarKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n close();\n } else if (isMod(e) && (e.key === \"f\" || e.key === \"F\")) {\n e.preventDefault();\n find.show(\"find\");\n } else if (isMod(e) && (e.key === \"h\" || e.key === \"H\")) {\n e.preventDefault();\n find.show(\"replace\");\n }\n };\n\n const onFindKeyDown = (e: React.KeyboardEvent) => {\n if (e.key !== \"Enter\") return;\n e.preventDefault();\n if (e.shiftKey) find.previous();\n else find.next();\n };\n\n const onReplaceKeyDown = (e: React.KeyboardEvent) => {\n if (e.key !== \"Enter\") return;\n e.preventDefault();\n if (isMod(e)) find.replaceAll();\n else find.replace();\n };\n\n return (\n <div className={className} role=\"search\" aria-label=\"Find and replace\" onKeyDown={onBarKeyDown}>\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n className={buttonClass}\n aria-label=\"Toggle replace\"\n aria-expanded={showReplace}\n onClick={() => find.show(showReplace ? \"find\" : \"replace\")}\n >\n {showReplace ? \"▾\" : \"▸\"}\n </button>\n <input\n ref={findInput}\n type=\"text\"\n className={inputClass}\n placeholder=\"Find\"\n aria-label=\"Find\"\n aria-invalid={!!find.error}\n value={find.query}\n onChange={(e) => find.setQuery(e.target.value)}\n onKeyDown={onFindKeyDown}\n />\n {FIND_OPTION_TOGGLES.filter((t) => !t.advanced).map((t) => (\n <button\n key={t.key}\n type=\"button\"\n className={toggleClass(!!find.options[t.key])}\n aria-label={t.label}\n title={t.label}\n aria-pressed={!!find.options[t.key]}\n onClick={() => find.toggleOption(t.key)}\n >\n {t.short}\n </button>\n ))}\n <span\n className={`min-w-[5rem] px-1 text-center text-xs ${find.error ? \"text-destructive\" : \"text-muted-foreground\"}`}\n aria-live=\"polite\"\n role={find.error ? \"alert\" : \"status\"}\n data-testid=\"find-status\"\n >\n {status}\n </span>\n <button type=\"button\" className={buttonClass} aria-label=\"Previous match\" disabled={!hasMatches} onClick={find.previous}>\n ↑\n </button>\n <button type=\"button\" className={buttonClass} aria-label=\"Next match\" disabled={!hasMatches} onClick={find.next}>\n ↓\n </button>\n {showMoreOptions && (\n <button\n type=\"button\"\n className={buttonClass}\n aria-label=\"More options\"\n aria-expanded={moreOpen}\n onClick={() => setMoreOpen((v) => !v)}\n >\n …\n </button>\n )}\n <button type=\"button\" className={buttonClass} aria-label=\"Close find\" onClick={close}>\n ×\n </button>\n </div>\n {showReplace && (\n <div className=\"flex items-center gap-1 pl-7\">\n <input\n type=\"text\"\n className={inputClass}\n placeholder=\"Replace\"\n aria-label=\"Replace\"\n value={find.replacement}\n onChange={(e) => find.setReplacement(e.target.value)}\n onKeyDown={onReplaceKeyDown}\n />\n <button\n type=\"button\"\n className={buttonClass}\n disabled={!hasMatches || find.currentIndex < 0}\n onClick={find.replace}\n >\n Replace\n </button>\n <button type=\"button\" className={buttonClass} disabled={!hasMatches} onClick={find.replaceAll}>\n Replace all\n </button>\n {find.lastReplaceCount !== null && (\n <span className=\"px-1 text-xs text-muted-foreground\" aria-live=\"polite\">\n {find.lastReplaceCount === 1 ? \"1 replaced\" : `${find.lastReplaceCount} replaced`}\n </span>\n )}\n </div>\n )}\n {showMoreOptions && moreOpen && (\n <div className=\"flex flex-wrap items-center gap-x-3 gap-y-1 pl-7 text-xs text-muted-foreground\">\n {FIND_OPTION_TOGGLES.filter((t) => t.advanced).map((t) => (\n <label key={t.key} className=\"flex items-center gap-1\">\n <input\n type=\"checkbox\"\n checked={!!find.options[t.key]}\n onChange={() => find.toggleOption(t.key)}\n />\n {t.label}\n </label>\n ))}\n </div>\n )}\n </div>\n );\n};\n","import { useMemo, useSyncExternalStore } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n createTableStore,\n getTableActionState,\n runTableAction,\n type TableAction,\n type TableActionParams,\n type TableState,\n} from \"@pixerate/editor\";\n\nexport type { TableAction, TableActionParams, TableState } from \"@pixerate/editor\";\n\nexport interface UseTableMenuResult extends TableState {\n /** Runs a table action (focusing the editor); `false` when it cannot run. */\n run: (action: TableAction, params?: TableActionParams) => boolean;\n /** `true`, or why the action cannot run with these params. */\n check: (action: TableAction, params?: TableActionParams) => true | string;\n}\n\n/**\n * Subscribes to the table at the editor's selection: whether the selection\n * is in a table, its size, header state, the cell's alignment and\n * background, and the enablement (with reasons) of every table action.\n * Re-renders only when that state changes. The Svelte counterpart is\n * `createTableMenu`.\n */\nexport function useTableMenu(editor: Editor | null | undefined): UseTableMenuResult {\n // The store only listens to the editor while subscribed (StrictMode-safe).\n const store = useMemo(() => createTableStore(editor), [editor]);\n const snapshot = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n return useMemo(\n () => ({\n ...snapshot,\n run: (action, params) => runTableAction(editor, action, params, { focus: true }),\n check: (action, params) => getTableActionState(editor, action, params),\n }),\n [snapshot, editor],\n );\n}\n","import React from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { DEFAULT_TABLE_TOOLBAR, type TableToolbarItem } from \"@pixerate/editor\";\nimport { useTableMenu } from \"./useTableMenu\";\n\nexport interface TableToolbarProps {\n editor: Editor | null;\n /** Buttons to show (default `DEFAULT_TABLE_TOOLBAR`). */\n items?: readonly TableToolbarItem[];\n /** Render (with disabled buttons) when the selection is not in a table. Default `false`. */\n showWhenOutside?: boolean;\n className?: string;\n buttonClassName?: string;\n activeButtonClassName?: string;\n separatorClassName?: string;\n /** Called after a button ran its action. */\n onAction?: (item: TableToolbarItem) => void;\n}\n\nconst keepSelection = (event: React.MouseEvent) => event.preventDefault();\n\n/**\n * Table toolbar: insert/delete rows and columns, merge/split cells, header\n * toggles, cell alignment and delete table. Rendered only while the\n * selection is in a table (unless `showWhenOutside`); disabled buttons say\n * why in their tooltip. Use it inline, or inside `TableBubbleMenu`.\n */\nexport const TableToolbar: React.FC<TableToolbarProps> = ({\n editor,\n items = DEFAULT_TABLE_TOOLBAR,\n showWhenOutside = false,\n className = \"flex flex-wrap items-center gap-1 text-xs\",\n buttonClassName = \"rounded px-2 py-1 text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent\",\n activeButtonClassName = \"bg-primary/10 text-primary\",\n separatorClassName = \"mx-1 h-4 w-px bg-border\",\n onAction,\n}) => {\n const table = useTableMenu(editor);\n if (!editor || (!table.inTable && !showWhenOutside)) return null;\n\n return (\n <div className={className} role=\"toolbar\" aria-label=\"Table\" data-table-toolbar=\"\">\n {items.map((item, index) => {\n const status = table.check(item.action, item.params);\n const enabled = status === true;\n const active = item.active?.(table);\n const separator = index > 0 && items[index - 1].group !== item.group;\n return (\n <React.Fragment key={item.id}>\n {separator && <span className={separatorClassName} aria-hidden=\"true\" />}\n <button\n type=\"button\"\n data-action={item.id}\n aria-label={item.title}\n title={enabled ? item.title : `${item.title}: ${status}`}\n {...(item.active ? { \"aria-pressed\": !!active } : {})}\n disabled={!enabled}\n className={active ? `${buttonClassName} ${activeButtonClassName}` : buttonClassName}\n onMouseDown={keepSelection}\n onClick={() => {\n if (table.run(item.action, item.params)) onAction?.(item);\n }}\n >\n {item.label}\n </button>\n </React.Fragment>\n );\n })}\n </div>\n );\n};\n","import React, { useState } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { useTableMenu } from \"./useTableMenu\";\n\nexport interface InsertTableGridProps {\n editor: Editor | null;\n /** Grid size offered (default 8 × 8). */\n rows?: number;\n cols?: number;\n /** Insert with a header row (default `true`). */\n withHeaderRow?: boolean;\n className?: string;\n cellClassName?: string;\n activeCellClassName?: string;\n /** Called after a table was inserted. */\n onInsert?: (size: { rows: number; cols: number }) => void;\n}\n\nconst keepSelection = (event: React.MouseEvent) => event.preventDefault();\n\n/**\n * Word-style insert-table picker: hover (or focus) a cell of the grid to\n * choose the size, click to insert a table of that size at the cursor. The\n * grid is disabled (with the reason as its title) where a table cannot be\n * inserted, e.g. inside another table.\n */\nexport const InsertTableGrid: React.FC<InsertTableGridProps> = ({\n editor,\n rows = 8,\n cols = 8,\n withHeaderRow = true,\n className = \"inline-flex flex-col gap-1 rounded-md border border-border bg-background p-2 text-xs shadow-md\",\n cellClassName = \"h-4 w-4 rounded-sm border border-border bg-background disabled:opacity-40\",\n activeCellClassName = \"border-primary bg-primary/20\",\n onInsert,\n}) => {\n const table = useTableMenu(editor);\n const [hover, setHover] = useState<{ rows: number; cols: number } | null>(null);\n const status = table.actions.insertTable;\n const disabled = !editor || !status.enabled;\n\n const insert = (size: { rows: number; cols: number }) => {\n if (table.run(\"insertTable\", { ...size, withHeaderRow })) onInsert?.(size);\n setHover(null);\n };\n\n return (\n <div\n className={className}\n role=\"group\"\n aria-label=\"Insert table\"\n title={disabled ? status.reason : undefined}\n data-insert-table-grid=\"\"\n onMouseLeave={() => setHover(null)}\n >\n <div\n role=\"grid\"\n aria-label=\"Table size\"\n style={{ display: \"grid\", gridTemplateColumns: `repeat(${cols}, max-content)`, gap: 2 }}\n >\n {Array.from({ length: rows * cols }, (_, i) => {\n const size = { rows: Math.floor(i / cols) + 1, cols: (i % cols) + 1 };\n const active = !!hover && size.rows <= hover.rows && size.cols <= hover.cols;\n return (\n <button\n key={i}\n type=\"button\"\n data-rows={size.rows}\n data-cols={size.cols}\n data-active={active}\n aria-label={`${size.rows} × ${size.cols} table`}\n disabled={disabled}\n className={active ? `${cellClassName} ${activeCellClassName}` : cellClassName}\n onMouseDown={keepSelection}\n onMouseEnter={() => setHover(size)}\n onFocus={() => setHover(size)}\n onClick={() => insert(size)}\n />\n );\n })}\n </div>\n <div aria-live=\"polite\" data-testid=\"insert-table-size\">\n {disabled ? status.reason : hover ? `${hover.rows} × ${hover.cols}` : \"Insert table\"}\n </div>\n </div>\n );\n};\n","import React from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { shouldShowTableBubbleMenu } from \"@pixerate/editor\";\nimport { BubbleMenu, type BubbleMenuProps } from \"../components/BubbleMenu\";\nimport { TableToolbar, type TableToolbarProps } from \"./TableToolbar\";\n\nexport interface TableBubbleMenuProps\n extends Omit<BubbleMenuProps, \"editor\" | \"children\" | \"shouldShow\"> {\n editor: Editor | null;\n /** Custom content (default: a `TableToolbar`). */\n children?: React.ReactNode;\n /** Props for the default `TableToolbar`. */\n toolbarProps?: Omit<TableToolbarProps, \"editor\">;\n}\n\n/**\n * A bubble menu that follows the selection while it is in a table (even a\n * collapsed cursor), with the table toolbar or your own `children`. It uses\n * its own plugin key (`tableBubbleMenu`), so it can be combined with the\n * formatting `BubbleMenu`.\n */\nexport const TableBubbleMenu: React.FC<TableBubbleMenuProps> = ({\n editor,\n children,\n toolbarProps,\n pluginKey = \"tableBubbleMenu\",\n ...rest\n}) => (\n <BubbleMenu editor={editor} pluginKey={pluginKey} shouldShow={shouldShowTableBubbleMenu as BubbleMenuProps[\"shouldShow\"]} {...rest}>\n {children ?? <TableToolbar editor={editor} {...toolbarProps} />}\n </BubbleMenu>\n);\n","import React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport type { ChartNodeViewMount, ChartNodeViewState } from '@pixerate/editor';\nimport type { ChartTheme } from '@pixerate/editor/chart';\nimport { ChartCanvas } from '../chart/ChartCanvas';\nimport { ChartDataGrid } from '../chart/ChartDataGrid';\nimport { ChartInspector } from '../chart/ChartInspector';\nimport { chartButtonClass } from '../chart/styles';\n\nexport interface ChartNodeViewProps {\n /** What the editor's `chart` node passes (see `ChartNodeViewState`). */\n state: ChartNodeViewState;\n /** Chart colours (default: the CSS-variable theme). */\n theme?: Partial<ChartTheme>;\n /** Show the data grid under the chart while editing (default `true`). */\n showDataGrid?: boolean;\n}\n\n/**\n * A chart inside a rich-text document: read-only until clicked, then editable on the canvas\n * with the data grid and the inspector in a panel below (side by side when there is room). \"Done\", Escape or moving the\n * selection away closes it. Edits are written back to the document as undo steps.\n */\nexport function ChartNodeView({ state, theme, showDataGrid = true }: ChartNodeViewProps) {\n const { controller, editing, editable, selected, width, height, setEditing } = state;\n const open = () => {\n if (editable && !editing) setEditing(true);\n };\n return (\n <div\n className={`not-prose my-2 rounded-md border bg-background p-1 ${selected ? 'border-primary ring-1 ring-primary' : 'border-border'}`}\n data-chart-node-view=\"\"\n data-editing={editing ? '' : undefined}\n onKeyDown={(e) => {\n if (editing && e.key === 'Escape') {\n e.stopPropagation();\n setEditing(false);\n }\n }}\n >\n {editing && (\n <div className=\"mb-1 flex items-center justify-between gap-2 px-1\" data-chart-node-toolbar=\"\">\n <span className=\"text-xs text-muted-foreground\">Editing chart</span>\n <button type=\"button\" className={chartButtonClass} data-action=\"done\" onClick={() => setEditing(false)}>\n Done\n </button>\n </div>\n )}\n <div\n className={editable && !editing ? 'cursor-pointer' : undefined}\n onClick={open}\n title={editable && !editing ? 'Click to edit the chart' : undefined}\n data-chart-node-canvas=\"\"\n >\n <ChartCanvas controller={controller} width={width ?? 640} height={height} responsive={width === null} editable={editing} theme={theme} />\n </div>\n {editing && (\n // Wraps by the document's width, not the viewport's: side by side when there is room.\n <div className=\"mt-2 flex flex-wrap items-start gap-2\" data-chart-node-panel=\"\">\n {showDataGrid && (\n <div className=\"min-w-0 flex-[1_1_20rem] overflow-x-auto\">\n <ChartDataGrid controller={controller} />\n </div>\n )}\n <ChartInspector controller={controller} className=\"max-h-96 min-w-0 flex-[1_1_16rem] overflow-y-auto rounded-md border border-border p-3\" />\n </div>\n )}\n </div>\n );\n}\n\nexport interface ReactChartNodeViewOptions extends Omit<ChartNodeViewProps, 'state'> {\n /** Draw something else for each chart (default `ChartNodeView`). */\n component?: React.ComponentType<ChartNodeViewProps>;\n}\n\n/**\n * The `nodeView` for the core `chart` node, drawing `ChartNodeView` in its own React root:\n * `createRichTextPreset({ chart: { nodeView: createReactChartNodeView() } })`. Works with any\n * TipTap editor (it does not need `EditorContent`); app context does not reach the chart.\n */\nexport function createReactChartNodeView(options: ReactChartNodeViewOptions = {}): ChartNodeViewMount {\n const { component: Component = ChartNodeView, ...props } = options;\n return (dom, state) => {\n const root = createRoot(dom);\n let latest = state;\n let scheduled = false;\n let destroyed = false;\n // ProseMirror creates and updates node views inside other renders (e.g. while\n // `EditorContent` mounts), where rendering another root is an error: render in a microtask.\n const schedule = () => {\n if (scheduled) return;\n scheduled = true;\n queueMicrotask(() => {\n scheduled = false;\n if (!destroyed) root.render(<Component {...props} state={latest} />);\n });\n };\n schedule();\n return {\n update: (next) => {\n latest = next;\n schedule();\n },\n destroy: () => {\n destroyed = true;\n queueMicrotask(() => root.unmount());\n },\n };\n };\n}\n","import React, { useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';\nimport {\n CSS_VARIABLE_CHART_THEME,\n chartClientToScene,\n chartTextBaseline,\n chartTextTransform,\n describeChartSelection,\n handleChartKey,\n layoutChart,\n startChartPointDrag,\n type ChartController,\n type ChartMark,\n type ChartPointDrag,\n type ChartPresence,\n type ChartScene,\n type ChartTextMeasure,\n type ChartTheme,\n} from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\n\nexport interface ChartCanvasProps {\n controller: ChartController;\n /** Scene width; with `responsive` this is only the fallback before the container is measured (default 640). */\n width?: number;\n /** Scene height in pixels (default 400). */\n height?: number;\n /** Follow the container's width (default `true`). */\n responsive?: boolean;\n /** Colours and type (default: shadcn-style CSS variables). */\n theme?: Partial<ChartTheme>;\n /** Click to select, drag bars and points, keyboard editing (default `true`). */\n editable?: boolean;\n /** Text width for layout (default: an estimate). */\n measureText?: ChartTextMeasure;\n emptyMessage?: string;\n className?: string;\n /** Agent cursors to draw over the chart (see `ChartDirector`). */\n presence?: ChartPresence;\n /** Receives the scene as drawn (e.g. for `ChartDirector`'s `scene`). */\n sceneRef?: { current: ChartScene | null };\n}\n\n/** SVG attributes for one mark (colours go in `style` so CSS variables work). */\nexport function renderChartMark(mark: ChartMark, fontFamily: string, interactive: boolean): React.ReactNode {\n const common = {\n 'data-role': mark.role,\n 'data-chart-key': mark.target ? mark.key : undefined,\n 'data-selected': mark.selected ? '' : undefined,\n opacity: mark.opacity,\n pointerEvents: mark.role === 'selection' || mark.role === 'drag-readout' || (!mark.target && mark.role !== 'background') ? ('none' as const) : undefined,\n cursor: interactive && mark.target && mark.role !== 'background' ? 'pointer' : undefined,\n };\n switch (mark.kind) {\n case 'rect':\n return <rect key={mark.key} {...common} x={mark.x} y={mark.y} width={mark.width} height={mark.height} rx={mark.radius} style={{ fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'path':\n return (\n <path\n key={mark.key}\n {...common}\n d={mark.d}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n strokeDasharray={mark.dash}\n style={{ fill: mark.fill ?? 'none', stroke: mark.stroke, strokeWidth: mark.strokeWidth }}\n />\n );\n case 'circle':\n return <circle key={mark.key} {...common} cx={mark.cx} cy={mark.cy} r={mark.r} style={{ fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'line':\n return <line key={mark.key} {...common} x1={mark.x1} y1={mark.y1} x2={mark.x2} y2={mark.y2} strokeDasharray={mark.dash} style={{ stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'text':\n return (\n <text\n key={mark.key}\n {...common}\n x={mark.x}\n y={mark.y}\n textAnchor={mark.anchor}\n dominantBaseline={chartTextBaseline(mark.baseline)}\n transform={chartTextTransform(mark)}\n style={{ fill: mark.fill, fontSize: mark.size, fontWeight: mark.weight, fontFamily, userSelect: 'none' }}\n >\n {mark.text}\n </text>\n );\n }\n}\n\n/** Agent cursors and notes, drawn in scene coordinates inside the chart's SVG. */\nexport function ChartPresenceLayer({ presence }: { presence: ChartPresence }) {\n const { actors } = useSyncExternalStore(presence.subscribe, presence.getState, presence.getState);\n return (\n <g data-chart-presence=\"\" pointerEvents=\"none\">\n {actors.map((a) => (\n <g key={a.id} transform={`translate(${a.x} ${a.y})`} data-actor={a.id}>\n <path d=\"M0,0 L0,14 L4,10.5 L7,17 L9.5,16 L6.5,9.5 L11.5,9.5 Z\" style={{ fill: a.color, stroke: '#ffffff', strokeWidth: 1 }} transform={a.pressed ? 'scale(0.9)' : undefined} />\n <g transform=\"translate(13 16)\">\n <rect x={0} y={0} rx={4} height={18} width={Math.max(28, (a.message ?? a.name).length * 6.4 + 12)} style={{ fill: a.color }} />\n <text x={6} y={9} dominantBaseline=\"central\" style={{ fill: '#ffffff', fontSize: 11, fontWeight: 600, fontFamily: 'inherit' }}>\n {a.message ?? a.name}\n </text>\n </g>\n </g>\n ))}\n </g>\n );\n}\n\n/** A laid-out scene as an SVG (no interaction): for read-only views, streaming and exports. */\nexport function ChartSceneSvg({ scene, label, className }: { scene: ChartScene; label?: string; className?: string }) {\n return (\n <svg width={scene.width} height={scene.height} viewBox={`0 0 ${scene.width} ${scene.height}`} role=\"img\" aria-label={label} className={`block max-w-full ${className ?? ''}`}>\n {scene.marks.map((m) => renderChartMark(m, scene.theme.fontFamily, false))}\n </svg>\n );\n}\n\ninterface Frozen {\n valueDomain: ChartPointDrag['valueDomain'];\n valueDomain2: ChartPointDrag['valueDomain2'] | null;\n xDomain: ChartPointDrag['xDomain'] | null;\n readout: ChartPointDrag['target'];\n}\n\n/**\n * Draws a chart controller's spec as SVG. Click a mark to select it, drag a bar or point to\n * change its value (one undo step; Alt for fine steps, Shift to keep one axis on scatter\n * charts, Ctrl / ⌘ to skip snapping, Escape to cancel), and with the chart focused use\n * ← → ↑ ↓, Delete and Escape (see `handleChartKey`).\n */\nexport function ChartCanvas({ controller, width = 640, height = 400, responsive = true, theme, editable = true, measureText, emptyMessage, className, presence, sceneRef }: ChartCanvasProps) {\n const state = useChartState(controller);\n const wrapper = useRef<HTMLDivElement>(null);\n const svg = useRef<SVGSVGElement>(null);\n const drag = useRef<ChartPointDrag | null>(null);\n const [measured, setMeasured] = useState<number | null>(null);\n // Frozen while a point is dragged so the axes do not rescale under the pointer.\n const [frozen, setFrozen] = useState<Frozen | null>(null);\n\n useEffect(() => {\n const el = wrapper.current;\n if (!responsive || !el || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(([entry]) => {\n const w = Math.round(entry.contentRect.width);\n if (w > 0) setMeasured(w);\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, [responsive]);\n\n const sceneWidth = (responsive && measured) || width;\n const fullTheme = useMemo(() => ({ ...CSS_VARIABLE_CHART_THEME, ...theme }), [theme]);\n const scene = useMemo(\n () =>\n layoutChart(state.spec, {\n width: sceneWidth,\n height,\n theme: fullTheme,\n selection: editable ? state.selection : null,\n measureText,\n emptyMessage,\n valueDomain: frozen?.valueDomain,\n valueDomain2: frozen?.valueDomain2,\n xDomain: frozen?.xDomain,\n readout: frozen?.readout,\n }),\n [state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage, frozen],\n );\n if (sceneRef) sceneRef.current = scene;\n const byKey = useMemo(() => new Map(scene.marks.map((m) => [m.key, m])), [scene]);\n\n useEffect(() => () => drag.current?.end(), []);\n\n const scenePoint = (e: React.PointerEvent) => chartClientToScene(scene, svg.current!.getBoundingClientRect(), e.clientX, e.clientY);\n\n const onPointerDown = (e: React.PointerEvent<SVGSVGElement>) => {\n if (!editable || e.button !== 0) return;\n const key = (e.target as Element).closest?.('[data-chart-key]')?.getAttribute('data-chart-key');\n const target = key ? byKey.get(key)?.target : undefined;\n controller.select(target ?? null);\n drag.current = startChartPointDrag(controller, scene, target, scenePoint(e));\n if (drag.current) {\n const d = drag.current;\n setFrozen({ valueDomain: d.valueDomain, valueDomain2: d.valueDomain2 ?? null, xDomain: d.xDomain ?? null, readout: d.target });\n svg.current?.setPointerCapture?.(e.pointerId);\n }\n };\n const onPointerMove = (e: React.PointerEvent<SVGSVGElement>) => {\n if (drag.current) drag.current.move(scenePoint(e), { fine: e.altKey, lockAxis: e.shiftKey, noSnap: e.ctrlKey || e.metaKey });\n };\n const endDrag = () => {\n drag.current?.end();\n drag.current = null;\n setFrozen(null);\n };\n const onKeyDown = (e: React.KeyboardEvent<SVGSVGElement>) => {\n if (drag.current && e.key === 'Escape') {\n drag.current.cancel();\n drag.current = null;\n setFrozen(null);\n e.preventDefault();\n return;\n }\n if (editable && handleChartKey(controller, scene, e)) e.preventDefault();\n };\n\n const label = state.spec.title || 'Chart';\n return (\n <div ref={wrapper} className={`w-full ${className ?? ''}`} data-chart-canvas=\"\">\n <svg\n ref={svg}\n width={sceneWidth}\n height={height}\n viewBox={`0 0 ${scene.width} ${scene.height}`}\n role=\"img\"\n aria-label={editable ? `${label}. ${describeChartSelection(controller, state.selection)}` : label}\n tabIndex={editable ? 0 : undefined}\n className=\"block max-w-full touch-none select-none rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary\"\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n onKeyDown={onKeyDown}\n >\n {scene.marks.map((m) => renderChartMark(m, scene.theme.fontFamily, editable))}\n {presence && <ChartPresenceLayer presence={presence} />}\n </svg>\n </div>\n );\n}\n","import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport type { ToolRegistry } from '@pixerate/editor/tools';\nimport {\n ChartController,\n ChartDirector,\n ChartPresence,\n createChartCommands,\n createChartRasterizer,\n createChartToolProvider,\n createOfficeChartToolProvider,\n type OfficeChartToolProviderOptions,\n layoutChart,\n type ChartScene,\n type ChartToolProviderOptions,\n type ChartActionResult,\n type ChartCommandOptions,\n type ChartControllerOptions,\n type ChartSelection,\n type ChartSpecPatch,\n type ChartState,\n type ChartType,\n} from '@pixerate/editor/chart';\n\n/** A `ChartController` created once for the component's lifetime. */\nexport function useChartController(options: ChartControllerOptions = {}): ChartController {\n const ref = useRef<ChartController | null>(null);\n if (!ref.current) ref.current = new ChartController(options);\n return ref.current;\n}\n\n/** The controller's state (re-renders on every change). */\nexport function useChartState(controller: ChartController): ChartState {\n return useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n}\n\nexport interface UseChartEditorResult {\n controller: ChartController;\n state: ChartState;\n spec: ChartState['spec'];\n selection: ChartSelection | null;\n update: (patch: ChartSpecPatch) => ChartActionResult;\n setType: (type: ChartType) => ChartActionResult;\n setValue: (seriesId: string, index: number, value: unknown) => ChartActionResult;\n select: (selection: ChartSelection | null) => void;\n undo: () => void;\n redo: () => void;\n}\n\n/**\n * Subscribes to a chart controller and exposes its state with bound actions. Pass options\n * instead of a controller to create one for the component's lifetime.\n */\nexport function useChartEditor(controllerOrOptions: ChartController | ChartControllerOptions = {}): UseChartEditorResult {\n const own = useRef<ChartController | null>(null);\n let controller: ChartController;\n if (controllerOrOptions instanceof ChartController) controller = controllerOrOptions;\n else {\n if (!own.current) own.current = new ChartController(controllerOrOptions);\n controller = own.current;\n }\n const state = useChartState(controller);\n const actions = useMemo(\n () => ({\n update: (patch: ChartSpecPatch) => controller.update(patch),\n setType: (type: ChartType) => controller.setType(type),\n setValue: (seriesId: string, index: number, value: unknown) => controller.setValue(seriesId, index, value),\n select: (selection: ChartSelection | null) => controller.select(selection),\n undo: () => void controller.undo(),\n redo: () => void controller.redo(),\n }),\n [controller],\n );\n return { controller, state, spec: state.spec, selection: state.selection, ...actions };\n}\n\n/** Anything with `register(specs) → unregister` (a `CommandRegistry`). */\nexport interface ChartCommandTarget {\n register(specs: any): () => void;\n}\n\n/**\n * Registers the controller's palette / agent commands (`chart.describe`, `chart.update`,\n * `chart.setValues`, …) in `registry` while mounted.\n */\nexport function useChartCommands(registry: ChartCommandTarget | null | undefined, controller: ChartController, options: ChartCommandOptions = {}): void {\n const { prefix, group, scope } = options;\n useEffect(() => {\n if (!registry) return;\n return registry.register(createChartCommands(controller, { prefix, group, scope }));\n }, [registry, controller, prefix, group, scope]);\n}\n\n/** `useChartToolProvider` options: `rasterize` defaults to a canvas rasterizer in the browser (`false` turns PNG off). */\nexport type ChartToolProviderHookOptions = Omit<ChartToolProviderOptions, 'rasterize'> & { rasterize?: ChartToolProviderOptions['rasterize'] | false };\n\n/**\n * Registers the chart's agent tools (`createChartToolProvider`) with a `ToolRegistry` while\n * mounted. Options are read when the controller or registry changes. In the browser,\n * `render_chart { format: \"png\" }` works out of the box (`createChartRasterizer`).\n */\nexport function useChartToolProvider(registry: ToolRegistry | null | undefined, controller: ChartController, options: ChartToolProviderHookOptions = {}): void {\n const latest = useRef(options);\n latest.current = options;\n const { id, namespace } = options;\n useEffect(() => {\n if (!registry) return;\n const { rasterize, ...rest } = latest.current;\n return registry.register(createChartToolProvider(controller, { ...rest, id, namespace, rasterize: rasterize === false ? undefined : (rasterize ?? createChartRasterizer()) }));\n }, [registry, controller, id, namespace]);\n}\n\n/**\n * Registers the Office-file chart tools (`createOfficeChartToolProvider`: `list_file_charts`,\n * `get_file_chart`, and `load_file_chart` with a `controller`) while mounted. `files` and\n * `readOnly` are read on every call, so they can change without re-registering.\n */\nexport function useOfficeChartToolProvider(registry: ToolRegistry | null | undefined, options: OfficeChartToolProviderOptions = {}): void {\n const latest = useRef(options);\n latest.current = options;\n const { id, namespace, controller } = options;\n const hasFiles = !!options.files;\n useEffect(() => {\n if (!registry) return;\n const current = latest.current;\n return registry.register(\n createOfficeChartToolProvider({\n ...current,\n id,\n namespace,\n controller,\n files: hasFiles ? () => latest.current.files?.() ?? [] : undefined,\n readOnly: () => {\n const r = latest.current.readOnly;\n return (typeof r === 'function' ? r() : r) ?? false;\n },\n }),\n );\n }, [registry, id, namespace, controller, hasFiles]);\n}\n\n/**\n * A `ChartPresence` and `ChartDirector` for a chart: pass `presence` and `sceneRef` to\n * `ChartCanvas`, and `director` to `useChartToolProvider` so agent edits are acted out with a\n * cursor.\n */\nexport function useChartDirector(controller: ChartController, options: { speed?: number; size?: { width: number; height: number } } = {}) {\n const sceneRef = useRef<ChartScene | null>(null);\n const ref = useRef<{ presence: ChartPresence; director: ChartDirector } | null>(null);\n if (!ref.current) {\n const presence = new ChartPresence();\n const size = options.size ?? { width: 640, height: 400 };\n const director = new ChartDirector(controller, presence, { scene: () => sceneRef.current ?? layoutChart(controller.getSpec(), size), speed: options.speed });\n ref.current = { presence, director };\n }\n return { ...ref.current, sceneRef };\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { chartColorInputValue, chartSeriesColor, formatChartNumber, type ChartController } from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\nimport { chartButtonClass, chartCellClass, chartIconButtonClass, chartInputClass } from './styles';\n\ntype CommitInputProps = {\n value: string;\n /** Called with the typed text. Return `false` to show the stored value again (a refused edit). */\n onCommit: (value: string) => boolean | void;\n} & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange' | 'defaultValue'>;\n\n/** A text box that commits on blur or Enter and resets on Escape. Follows `value` unless the user is typing. */\nexport function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }: CommitInputProps) {\n const [draft, setDraft] = useState(value);\n const typing = useRef(false);\n useEffect(() => {\n if (!typing.current) setDraft(value);\n }, [value]);\n const commit = () => {\n if (!typing.current) return;\n typing.current = false;\n if (draft === value) return;\n if (onCommit(draft) === false) setDraft(value);\n };\n return (\n <input\n {...rest}\n value={draft}\n onChange={(e) => {\n typing.current = true;\n setDraft(e.currentTarget.value);\n }}\n onBlur={(e) => {\n onBlur?.(e);\n commit();\n }}\n onKeyDown={(e) => {\n onKeyDown?.(e);\n if (e.defaultPrevented) return;\n if (e.key === 'Enter') {\n e.preventDefault();\n commit();\n } else if (e.key === 'Escape') {\n typing.current = false;\n setDraft(value);\n }\n }}\n />\n );\n}\n\nexport interface ChartDataGridProps {\n controller: ChartController;\n /** Header of the category column (default \"Category\"). */\n categoryHeader?: string;\n /** Hide the add / delete buttons. */\n readOnly?: boolean;\n className?: string;\n}\n\n/**\n * The chart's data as an editable grid: categories down the side, one column per series\n * (name, colour, show / hide, delete). Cells take numbers as people type them (`1,200`,\n * `12%`, blank for a gap); pasting TSV or CSV fills and grows the grid from the cell.\n */\nexport function ChartDataGrid({ controller, categoryHeader = 'Category', readOnly = false, className }: ChartDataGridProps) {\n const { spec, selection } = useChartState(controller);\n const paste = (row: number, column: number) => (e: React.ClipboardEvent<HTMLInputElement>) => {\n const text = e.clipboardData?.getData('text/plain') ?? '';\n if (!/[\\t\\n]/.test(text.replace(/\\n$/, ''))) return;\n e.preventDefault();\n controller.pasteCells(row, column, text);\n };\n return (\n <div className={`overflow-auto rounded-md border border-border ${className ?? ''}`} data-chart-grid=\"\">\n <table className=\"w-full border-collapse text-xs\">\n <thead className=\"bg-muted/50\">\n <tr>\n <th className=\"border-b border-r border-border px-2 py-1 text-left font-medium text-muted-foreground\">{categoryHeader}</th>\n {spec.series.map((s, si) => {\n const color = chartSeriesColor(spec, si);\n const selected = selection?.kind === 'series' && selection.seriesId === s.id;\n return (\n <th key={s.id} data-series-id={s.id} className={`border-b border-r border-border px-1 py-1 font-medium ${selected ? 'bg-primary/10' : ''}`}>\n <div className=\"flex items-center gap-1\">\n <input\n type=\"color\"\n aria-label={`${s.name} colour`}\n value={chartColorInputValue(color)}\n disabled={readOnly}\n onPointerDown={() => controller.beginGesture(`color:${s.id}`)}\n onChange={(e) => controller.updateSeries(s.id, { color: e.currentTarget.value })}\n onBlur={() => controller.endGesture()}\n className=\"h-5 w-5 shrink-0 cursor-pointer rounded border-0 bg-transparent p-0\"\n />\n <ChartCommitInput\n value={s.name}\n aria-label=\"Series name\"\n onFocus={() => controller.select({ kind: 'series', seriesId: s.id })}\n onCommit={(name) => void controller.updateSeries(s.id, { name })}\n className={`${chartInputClass} h-6 min-w-[5rem] border-transparent bg-transparent font-medium ${s.hidden ? 'text-muted-foreground line-through' : ''}`}\n />\n {!readOnly && (\n <>\n <button\n type=\"button\"\n className={chartIconButtonClass}\n title={s.hidden ? 'Show series' : 'Hide series'}\n aria-label={s.hidden ? `Show ${s.name}` : `Hide ${s.name}`}\n aria-pressed={!s.hidden}\n data-action=\"toggle-series\"\n onClick={() => controller.toggleSeries(s.id)}\n >\n {s.hidden ? '○' : '●'}\n </button>\n <button type=\"button\" className={chartIconButtonClass} title=\"Delete series\" aria-label={`Delete ${s.name}`} data-action=\"remove-series\" onClick={() => controller.removeSeries(s.id)}>\n ×\n </button>\n </>\n )}\n </div>\n </th>\n );\n })}\n {!readOnly && (\n <th className=\"w-8 border-b border-border px-1\">\n <button type=\"button\" className={chartIconButtonClass} title=\"Add series\" aria-label=\"Add series\" data-action=\"add-series\" onClick={() => controller.addSeries()}>\n +\n </button>\n </th>\n )}\n </tr>\n </thead>\n <tbody>\n {spec.categories.map((category, i) => {\n const rowSelected = selection?.kind === 'category' && selection.index === i;\n return (\n <tr key={i} data-category-index={i} className={rowSelected ? 'bg-primary/10' : undefined}>\n <th className=\"border-b border-r border-border p-0 text-left font-normal\">\n <ChartCommitInput\n value={category}\n aria-label={`Category ${i + 1}`}\n onFocus={() => controller.select({ kind: 'category', index: i })}\n onPaste={paste(i, -1)}\n onCommit={(label) => void controller.renameCategory(i, label)}\n className={`${chartCellClass} text-left`}\n />\n </th>\n {spec.series.map((s) => {\n const value = s.values[i];\n const selected = selection?.kind === 'point' && selection.seriesId === s.id && selection.index === i;\n return (\n <td key={s.id} className={`border-b border-r border-border p-0 ${selected ? 'bg-primary/10' : ''}`}>\n <ChartCommitInput\n value={value === null || value === undefined ? '' : String(value)}\n inputMode=\"decimal\"\n aria-label={`${s.name}, ${category}`}\n title={value === null ? undefined : formatChartNumber(value, spec.yAxis.format)}\n data-cell={`${s.id}:${i}`}\n onFocus={() => controller.select({ kind: 'point', seriesId: s.id, index: i })}\n onPaste={paste(i, spec.series.indexOf(s))}\n onCommit={(text) => controller.setValue(s.id, i, text).ok}\n className={chartCellClass}\n />\n </td>\n );\n })}\n {!readOnly && (\n <td className=\"border-b border-border px-1\">\n <button type=\"button\" className={chartIconButtonClass} title=\"Delete category\" aria-label={`Delete ${category}`} data-action=\"remove-category\" onClick={() => controller.removeCategory(i)}>\n ×\n </button>\n </td>\n )}\n </tr>\n );\n })}\n </tbody>\n </table>\n {!readOnly && (\n <div className=\"p-1\">\n <button type=\"button\" className={`${chartButtonClass} h-6 border-dashed`} data-action=\"add-category\" onClick={() => controller.addCategory()}>\n + Add category\n </button>\n </div>\n )}\n </div>\n );\n}\n","// Class names shared by the chart components (the same as the Svelte package's).\nexport const chartInputClass =\n 'h-7 w-full min-w-0 rounded-md border border-input bg-background px-2 text-xs text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:cursor-not-allowed disabled:opacity-50';\nexport const chartButtonClass =\n 'inline-flex h-7 items-center justify-center gap-1 rounded-md border border-input bg-background px-2 text-xs text-foreground hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-50';\nexport const chartIconButtonClass =\n 'inline-flex h-6 w-6 shrink-0 items-center justify-center rounded text-xs text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-40';\nexport const chartSegmentClass = (active: boolean) =>\n `inline-flex h-7 flex-1 items-center justify-center rounded px-2 text-xs focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary ${\n active ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'\n }`;\nexport const chartLabelClass = 'text-[11px] font-medium text-muted-foreground';\nexport const chartSectionClass = 'space-y-2 border-b border-border pb-3 last:border-b-0';\nexport const chartCellClass =\n 'h-7 w-full min-w-[4.5rem] bg-transparent px-2 text-right text-xs tabular-nums text-foreground focus-visible:bg-background focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-primary';\n","import React, { useId } from 'react';\nimport {\n CHART_COLOR_SCHEMES,\n CHART_ERROR_BAR_DIRECTIONS,\n CHART_ERROR_BAR_LABELS,\n CHART_ERROR_BAR_TYPES,\n CHART_LABEL_POSITIONS,\n CHART_LAYOUT_PRESETS,\n CHART_MARKERS,\n CHART_TRENDLINE_TYPES,\n checkChartColors,\n chartFamily,\n chartSupportsTrendlines,\n chartTrendlineName,\n CHART_CURVES,\n CHART_LEGEND_POSITIONS,\n CHART_NUMBER_STYLES,\n CHART_SERIES_TYPES,\n CHART_STACKINGS,\n CHART_TYPE_LABELS,\n CHART_TYPES,\n chartColorInputValue,\n chartErrorBarsOfType,\n chartSeriesColor,\n defaultChartErrorBarValue,\n formatChartAmountList,\n parseChartAmountList,\n chartSeriesType,\n isCartesianChart,\n type ChartAxis,\n type ChartController,\n type ChartErrorBars,\n type ChartErrorBarType,\n type ChartNumberFormat,\n type ChartSeries,\n} from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\nimport { ChartCommitInput } from './ChartDataGrid';\nimport { chartButtonClass, chartInputClass, chartLabelClass, chartSectionClass, chartSegmentClass } from './styles';\n\nexport interface ChartInspectorProps {\n controller: ChartController;\n /** Which sections to show (default: all that apply to the chart). */\n sections?: readonly ChartInspectorSection[];\n className?: string;\n}\n\nexport type ChartInspectorSection = 'type' | 'style' | 'titles' | 'options' | 'legend' | 'axes' | 'series';\n\nconst cap = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);\n\nfunction Field({ label, htmlFor, children }: { label: string; htmlFor?: string; children: React.ReactNode }) {\n return (\n <div className=\"flex items-center gap-2\">\n <label htmlFor={htmlFor} className={`${chartLabelClass} w-20 shrink-0`}>\n {label}\n </label>\n <div className=\"min-w-0 flex-1\">{children}</div>\n </div>\n );\n}\n\nfunction Toggle({ label, checked, onChange, name }: { label: string; checked: boolean; onChange: (checked: boolean) => void; name: string }) {\n return (\n <label className=\"flex cursor-pointer items-center gap-2 text-xs text-foreground\">\n <input type=\"checkbox\" className=\"h-3.5 w-3.5 accent-primary\" checked={checked} data-option={name} onChange={(e) => onChange(e.currentTarget.checked)} />\n {label}\n </label>\n );\n}\n\nfunction Select<T extends string>({ id, value, options, onChange, name, labels }: { id?: string; value: T; options: readonly T[]; onChange: (value: T) => void; name: string; labels?: Partial<Record<T, string>> }) {\n return (\n <select id={id} className={chartInputClass} value={value} data-option={name} onChange={(e) => onChange(e.currentTarget.value as T)}>\n {options.map((o) => (\n <option key={o} value={o}>\n {labels?.[o] ?? cap(o)}\n </option>\n ))}\n </select>\n );\n}\n\nfunction AxisSection({ controller, axis, value, idBase, horizontal, numeric = false, scales = false }: { controller: ChartController; axis: 'x' | 'y' | 'y2'; value: ChartAxis; idBase: string; horizontal: boolean; numeric?: boolean; scales?: boolean }) {\n const set = (patch: Partial<ChartAxis>) => controller.setAxis(axis, patch);\n const setFormat = (patch: Partial<ChartNumberFormat>) => set({ format: { ...value.format, ...patch } });\n const bound = (key: 'min' | 'max') => (\n <ChartCommitInput\n id={`${idBase}-${axis}-${key}`}\n value={value[key] === null ? '' : String(value[key])}\n placeholder=\"Auto\"\n inputMode=\"decimal\"\n data-option={`${axis}Axis.${key}`}\n className={chartInputClass}\n onCommit={(text) => set({ [key]: text.trim() === '' ? null : Number(text) }).ok}\n />\n );\n const name = axis === 'x' ? (numeric ? 'X axis' : 'Category axis') : axis === 'y' ? 'Value axis' : 'Secondary axis';\n const valueAxis = axis !== 'x' || numeric;\n const key = axis === 'y2' ? 'yAxis2' : `${axis}Axis`;\n return (\n <div className={chartSectionClass} data-section={`axis-${axis}`}>\n <div className=\"flex items-center justify-between\">\n <h4 className=\"text-xs font-semibold text-foreground\">\n {name}\n <span className=\"ml-1 font-normal text-muted-foreground\">({axis === 'x' ? (horizontal ? 'left' : 'bottom') : axis === 'y2' ? (horizontal ? 'top' : 'right') : horizontal ? 'bottom' : 'left'})</span>\n </h4>\n <Toggle label=\"Show\" name={`${axis}Axis.show`} checked={value.show} onChange={(show) => set({ show })} />\n </div>\n <Field label=\"Title\" htmlFor={`${idBase}-${axis}-title`}>\n <ChartCommitInput id={`${idBase}-${axis}-title`} value={value.title} data-option={`${axis}Axis.title`} className={chartInputClass} onCommit={(title) => void set({ title })} />\n </Field>\n <div className=\"flex flex-wrap gap-x-4 gap-y-1\">\n <Toggle label=\"Grid lines\" name={`${key}.gridlines`} checked={value.gridlines} onChange={(gridlines) => set({ gridlines })} />\n {axis === 'x' && !numeric && <Toggle label=\"Dates\" name=\"xAxis.kind\" checked={value.kind === 'date'} onChange={(dates) => set({ kind: dates ? 'date' : undefined } as Partial<ChartAxis>)} />}\n {scales && <Toggle label=\"Reverse\" name={`${key}.reverse`} checked={!!value.reverse} onChange={(reverse) => set({ reverse })} />}\n {scales && valueAxis && <Toggle label=\"Log scale\" name={`${key}.scale`} checked={value.scale === 'log'} onChange={(log) => set({ scale: log ? 'log' : 'linear' })} />}\n </div>\n {scales && valueAxis && value.scale === 'log' && (\n <Field label=\"Log base\" htmlFor={`${idBase}-${axis}-log-base`}>\n <ChartCommitInput\n id={`${idBase}-${axis}-log-base`}\n value={String(value.logBase ?? 10)}\n inputMode=\"decimal\"\n data-option={`${key}.logBase`}\n className={chartInputClass}\n onCommit={(text) => set({ logBase: text.trim() === '' ? undefined : Number(text) }).ok}\n />\n </Field>\n )}\n {valueAxis && value.scale !== 'log' && (\n <Field label=\"Step\" htmlFor={`${idBase}-${axis}-step`}>\n <ChartCommitInput\n id={`${idBase}-${axis}-step`}\n value={value.step === null ? '' : String(value.step)}\n placeholder=\"Auto\"\n inputMode=\"decimal\"\n data-option={`${key}.step`}\n className={chartInputClass}\n onCommit={(text) => set({ step: text.trim() === '' ? null : Number(text) }).ok}\n />\n </Field>\n )}\n {valueAxis && (\n <>\n <Field label=\"Min / max\">\n <div className=\"flex gap-1\">\n {bound('min')}\n {bound('max')}\n </div>\n </Field>\n <Field label=\"Format\" htmlFor={`${idBase}-${axis}-format`}>\n <div className=\"flex gap-1\">\n <Select id={`${idBase}-${axis}-format`} name={`${key}.format.style`} value={value.format.style ?? 'number'} options={CHART_NUMBER_STYLES} onChange={(style) => setFormat({ style })} />\n <ChartCommitInput\n value={value.format.decimals === undefined ? '' : String(value.format.decimals)}\n placeholder=\"Auto\"\n aria-label=\"Decimals\"\n title=\"Decimals\"\n inputMode=\"numeric\"\n data-option={`${key}.format.decimals`}\n className={`${chartInputClass} w-14 shrink-0`}\n onCommit={(text) => {\n const format = { ...value.format };\n if (text.trim() === '') delete format.decimals;\n else format.decimals = Number(text);\n return set({ format }).ok;\n }}\n />\n </div>\n </Field>\n {value.format.style === 'currency' && (\n <Field label=\"Currency\" htmlFor={`${idBase}-${axis}-currency`}>\n <ChartCommitInput id={`${idBase}-${axis}-currency`} value={value.format.currency ?? 'USD'} data-option={`${key}.format.currency`} className={chartInputClass} onCommit={(currency) => void setFormat({ currency: currency.toUpperCase() })} />\n </Field>\n )}\n <Field label=\"Code\" htmlFor={`${idBase}-${axis}-code`}>\n <ChartCommitInput\n id={`${idBase}-${axis}-code`}\n value={value.format.code ?? ''}\n placeholder={'e.g. #,##0.0,,\"M\"'}\n data-option={`${key}.format.code`}\n className={chartInputClass}\n onCommit={(code) => {\n const format = { ...value.format };\n if (code.trim()) format.code = code.trim();\n else delete format.code;\n return set({ format }).ok;\n }}\n />\n </Field>\n </>\n )}\n </div>\n );\n}\n\n/** Error bar type, amount, direction and caps for one series (`which`: y or x error bars). */\nfunction ErrorBarFields({ controller, series, which, idBase }: { controller: ChartController; series: ChartSeries; which: 'errorBars' | 'xErrorBars'; idBase: string }) {\n const bars = series[which];\n const key = `series.${which}`;\n const id = `${idBase}-${which}`;\n const values = which === 'xErrorBars' ? (series.x ?? []) : series.values;\n const set = (next: ChartErrorBars | null) => controller.updateSeries(series.id, { [which]: next });\n const patch = (p: Partial<ChartErrorBars>) => bars && set({ ...bars, ...p });\n return (\n <div className=\"space-y-1.5\" data-section={which === 'errorBars' ? 'error-bars' : 'x-error-bars'}>\n <Field label={which === 'errorBars' ? 'Error bars' : 'X error bars'} htmlFor={`${id}-type`}>\n <select id={`${id}-type`} className={chartInputClass} value={bars?.type ?? ''} data-option={`${key}.type`} onChange={(e) => set(chartErrorBarsOfType(e.currentTarget.value as ChartErrorBarType | '', bars, values))}>\n <option value=\"\">None</option>\n {CHART_ERROR_BAR_TYPES.map((t) => (\n <option key={t} value={t}>\n {CHART_ERROR_BAR_LABELS[t]}\n </option>\n ))}\n </select>\n </Field>\n {bars && (bars.type === 'fixed' || bars.type === 'percent' || bars.type === 'stddev') && (\n <Field label={bars.type === 'percent' ? 'Percent' : bars.type === 'stddev' ? 'Deviations' : 'Amount'} htmlFor={`${id}-value`}>\n <ChartCommitInput id={`${id}-value`} value={String(bars.value ?? defaultChartErrorBarValue(bars.type))} inputMode=\"decimal\" data-option={`${key}.value`} className={chartInputClass} onCommit={(text) => !!patch({ value: text.trim() === '' ? undefined : Number(text) })?.ok} />\n </Field>\n )}\n {bars?.type === 'custom' && (\n <>\n <Field label=\"Plus\" htmlFor={`${id}-plus`}>\n <ChartCommitInput id={`${id}-plus`} value={formatChartAmountList(bars.plus)} placeholder=\"1, 2, -, 0.5\" data-option={`${key}.plus`} className={chartInputClass} onCommit={(text) => !!patch({ plus: parseChartAmountList(text) as ChartErrorBars['plus'] })?.ok} />\n </Field>\n <Field label=\"Minus\" htmlFor={`${id}-minus`}>\n <ChartCommitInput\n id={`${id}-minus`}\n value={formatChartAmountList(bars.minus)}\n placeholder=\"Same as plus\"\n data-option={`${key}.minus`}\n className={chartInputClass}\n onCommit={(text) => {\n const next = { ...bars };\n if (text.trim()) next.minus = parseChartAmountList(text) as ChartErrorBars['minus'];\n else delete next.minus;\n return set(next).ok;\n }}\n />\n </Field>\n </>\n )}\n {bars && (\n <div className=\"flex items-center gap-2\">\n <select className={`${chartInputClass} flex-1`} aria-label=\"Error bar direction\" value={bars.direction ?? 'both'} data-option={`${key}.direction`} onChange={(e) => patch({ direction: e.currentTarget.value as ChartErrorBars['direction'] })}>\n {CHART_ERROR_BAR_DIRECTIONS.map((d) => (\n <option key={d} value={d}>\n {d === 'both' ? 'Both ways' : d === 'plus' ? 'Plus only' : 'Minus only'}\n </option>\n ))}\n </select>\n <Toggle label=\"Caps\" name={`${key}.cap`} checked={bars.cap !== false} onChange={(cap) => patch({ cap })} />\n </div>\n )}\n </div>\n );\n}\n\n/**\n * Settings for a chart controller: type, titles, stacking and line options, legend, both\n * axes and the selected series. Every change is one undo step.\n */\nexport function ChartInspector({ controller, sections, className }: ChartInspectorProps) {\n const { spec, selectedSeries } = useChartState(controller);\n const idBase = useId();\n const show = (section: ChartInspectorSection) => !sections || sections.includes(section);\n const cartesian = isCartesianChart(spec.type);\n const family = chartFamily(spec);\n const hasAxes = family === 'cartesian' || family === 'xy' || family === 'waterfall' || family === 'histogram' || family === 'box';\n const types = spec.series.map((s) => chartSeriesType(spec, s));\n const usesSecondary = family === 'cartesian' && spec.series.some((s) => s.axis === 'secondary' && !s.hidden);\n const colorCheck = checkChartColors(spec.series.filter((s) => !s.hidden).map((s) => chartSeriesColor(spec, spec.series.indexOf(s))));\n const hasBars = cartesian && types.includes('bar');\n const hasLines = cartesian && types.some((t) => t === 'line' || t === 'area');\n const seriesIndex = selectedSeries ? spec.series.findIndex((s) => s.id === selectedSeries.id) : -1;\n // Log and reversed axes and error bars are drawn by the bar / line / area / scatter layouts.\n const scales = family === 'cartesian' || family === 'xy';\n\n return (\n <div className={`space-y-3 text-xs ${className ?? ''}`} data-chart-inspector=\"\">\n {show('type') && (\n <div className={chartSectionClass} data-section=\"type\">\n <div className=\"grid grid-cols-3 gap-0.5 rounded-md bg-muted p-0.5\" role=\"radiogroup\" aria-label=\"Chart type\">\n {CHART_TYPES.map((type) => (\n <button key={type} type=\"button\" role=\"radio\" aria-checked={spec.type === type} data-chart-type={type} className={chartSegmentClass(spec.type === type)} onClick={() => controller.setType(type)}>\n {CHART_TYPE_LABELS[type]}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {show('style') && (\n <div className={chartSectionClass} data-section=\"style\">\n <Field label=\"Layout\" htmlFor={`${idBase}-layout`}>\n <select id={`${idBase}-layout`} className={chartInputClass} value=\"\" data-option=\"preset.layout\" onChange={(e) => e.currentTarget.value && controller.applyPreset({ layout: e.currentTarget.value })}>\n <option value=\"\">Quick layout…</option>\n {CHART_LAYOUT_PRESETS.map((p) => (\n <option key={p.id} value={p.id} title={p.description}>\n {p.label}\n </option>\n ))}\n </select>\n </Field>\n <Field label=\"Colours\" htmlFor={`${idBase}-colors`}>\n <select id={`${idBase}-colors`} className={chartInputClass} value={CHART_COLOR_SCHEMES.find((c) => c.palette.join() === spec.palette.join())?.id ?? ''} data-option=\"preset.colors\" onChange={(e) => e.currentTarget.value && controller.applyPreset({ colors: e.currentTarget.value })}>\n <option value=\"\">Custom</option>\n {CHART_COLOR_SCHEMES.map((c) => (\n <option key={c.id} value={c.id} title={c.description}>\n {c.label}\n </option>\n ))}\n </select>\n </Field>\n {!colorCheck.ok && (\n <p className=\"text-[11px] leading-snug text-amber-600 dark:text-amber-400\" data-chart-color-warning=\"\">\n {colorCheck.issues[0]}\n </p>\n )}\n <button type=\"button\" className={chartButtonClass} data-action=\"transpose\" onClick={() => controller.transpose()}>\n Switch rows and columns\n </button>\n </div>\n )}\n\n {show('titles') && (\n <div className={chartSectionClass} data-section=\"titles\">\n <Field label=\"Title\" htmlFor={`${idBase}-title`}>\n <ChartCommitInput id={`${idBase}-title`} value={spec.title} data-option=\"title\" className={chartInputClass} onCommit={(title) => void controller.setTitle(title)} />\n </Field>\n <Field label=\"Subtitle\" htmlFor={`${idBase}-subtitle`}>\n <ChartCommitInput id={`${idBase}-subtitle`} value={spec.subtitle} data-option=\"subtitle\" className={chartInputClass} onCommit={(subtitle) => void controller.setSubtitle(subtitle)} />\n </Field>\n </div>\n )}\n\n {show('options') && (\n <div className={chartSectionClass} data-section=\"options\">\n {cartesian && (\n <Field label=\"Stacking\" htmlFor={`${idBase}-stacking`}>\n <Select id={`${idBase}-stacking`} name=\"stacking\" value={spec.stacking} options={CHART_STACKINGS} labels={{ none: 'None', stacked: 'Stacked', percent: '100%' }} onChange={(stacking) => controller.update({ stacking })} />\n </Field>\n )}\n {hasBars && (\n <Field label=\"Bars\">\n <div className=\"flex gap-0.5 rounded-md bg-muted p-0.5\">\n {(['vertical', 'horizontal'] as const).map((o) => (\n <button key={o} type=\"button\" aria-pressed={spec.orientation === o} data-option={`orientation.${o}`} className={chartSegmentClass(spec.orientation === o)} onClick={() => controller.update({ orientation: o })}>\n {cap(o)}\n </button>\n ))}\n </div>\n </Field>\n )}\n {hasLines && (\n <Field label=\"Lines\" htmlFor={`${idBase}-curve`}>\n <Select id={`${idBase}-curve`} name=\"curve\" value={spec.curve} options={CHART_CURVES} onChange={(curve) => controller.update({ curve })} />\n </Field>\n )}\n {spec.type === 'donut' && (\n <Field label=\"Hole\" htmlFor={`${idBase}-hole`}>\n <input\n id={`${idBase}-hole`}\n type=\"range\"\n min={0}\n max={0.9}\n step={0.05}\n value={spec.innerRadius}\n data-option=\"innerRadius\"\n className=\"w-full accent-primary\"\n onPointerDown={() => controller.beginGesture('innerRadius')}\n onPointerUp={() => controller.endGesture()}\n onChange={(e) => controller.update({ innerRadius: Number(e.currentTarget.value) })}\n />\n </Field>\n )}\n {hasBars && (\n <Field label=\"Spacing\" htmlFor={`${idBase}-gap`}>\n <input\n id={`${idBase}-gap`}\n type=\"range\"\n min={0}\n max={0.9}\n step={0.02}\n value={spec.gapWidth}\n data-option=\"gapWidth\"\n className=\"w-full accent-primary\"\n onPointerDown={() => controller.beginGesture('gapWidth')}\n onPointerUp={() => controller.endGesture()}\n onChange={(e) => controller.update({ gapWidth: Number(e.currentTarget.value) })}\n />\n </Field>\n )}\n {spec.dataLabels && hasBars && (\n <Field label=\"Labels\" htmlFor={`${idBase}-label-position`}>\n <Select id={`${idBase}-label-position`} name=\"labelPosition\" value={spec.labelPosition} options={CHART_LABEL_POSITIONS} onChange={(labelPosition) => controller.update({ labelPosition })} />\n </Field>\n )}\n {spec.type === 'histogram' && (\n <Field label=\"Bins\" htmlFor={`${idBase}-bins`}>\n <ChartCommitInput id={`${idBase}-bins`} value={spec.bins === null ? '' : String(spec.bins)} placeholder=\"Auto\" inputMode=\"numeric\" data-option=\"bins\" className={chartInputClass} onCommit={(text) => controller.update({ bins: text.trim() === '' ? null : Number(text) }).ok} />\n </Field>\n )}\n <div className=\"flex flex-wrap gap-x-4 gap-y-1\">\n {spec.type === 'waterfall' && <Toggle label=\"Total bar\" name=\"showTotal\" checked={spec.showTotal} onChange={(showTotal) => controller.update({ showTotal })} />}\n {hasLines && <Toggle label=\"Points\" name=\"points\" checked={spec.points} onChange={(points) => controller.update({ points })} />}\n <Toggle label=\"Data labels\" name=\"dataLabels\" checked={spec.dataLabels} onChange={(dataLabels) => controller.update({ dataLabels })} />\n </div>\n </div>\n )}\n\n {show('legend') && (\n <div className={chartSectionClass} data-section=\"legend\">\n <div className=\"flex items-center justify-between\">\n <h4 className=\"text-xs font-semibold text-foreground\">Legend</h4>\n <Toggle label=\"Show\" name=\"legend.show\" checked={spec.legend.show} onChange={(v) => controller.setLegend({ show: v })} />\n </div>\n {spec.legend.show && (\n <div className=\"flex gap-0.5 rounded-md bg-muted p-0.5\">\n {CHART_LEGEND_POSITIONS.map((p) => (\n <button key={p} type=\"button\" aria-pressed={spec.legend.position === p} data-option={`legend.${p}`} className={chartSegmentClass(spec.legend.position === p)} onClick={() => controller.setLegend({ position: p })}>\n {cap(p)}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n\n {show('axes') && hasAxes && (\n <>\n {family !== 'box' && family !== 'histogram' && <AxisSection controller={controller} axis=\"x\" value={spec.xAxis} idBase={idBase} horizontal={spec.orientation === 'horizontal'} numeric={family === 'xy'} scales={scales} />}\n <AxisSection controller={controller} axis=\"y\" value={spec.yAxis} idBase={idBase} horizontal={spec.orientation === 'horizontal'} scales={scales} />\n {usesSecondary && <AxisSection controller={controller} axis=\"y2\" value={spec.yAxis2} idBase={idBase} horizontal={spec.orientation === 'horizontal'} scales={scales} />}\n </>\n )}\n\n {show('series') && selectedSeries && (\n <div className={chartSectionClass} data-section=\"series\" data-series-id={selectedSeries.id}>\n <h4 className=\"text-xs font-semibold text-foreground\">Series</h4>\n <Field label=\"Name\" htmlFor={`${idBase}-series-name`}>\n <ChartCommitInput id={`${idBase}-series-name`} value={selectedSeries.name} data-option=\"series.name\" className={chartInputClass} onCommit={(name) => void controller.updateSeries(selectedSeries.id, { name })} />\n </Field>\n <Field label=\"Colour\" htmlFor={`${idBase}-series-color`}>\n <div className=\"flex items-center gap-1\">\n <input\n id={`${idBase}-series-color`}\n type=\"color\"\n value={chartColorInputValue(chartSeriesColor(spec, seriesIndex))}\n data-option=\"series.color\"\n className=\"h-7 w-9 shrink-0 cursor-pointer rounded border border-input bg-background p-0.5\"\n onPointerDown={() => controller.beginGesture(`color:${selectedSeries.id}`)}\n onBlur={() => controller.endGesture()}\n onChange={(e) => controller.updateSeries(selectedSeries.id, { color: e.currentTarget.value })}\n />\n {selectedSeries.color && (\n <button type=\"button\" className={chartButtonClass} data-action=\"reset-color\" onClick={() => controller.updateSeries(selectedSeries.id, { color: null })}>\n Palette\n </button>\n )}\n </div>\n </Field>\n {cartesian && (\n <Field label=\"Draw as\" htmlFor={`${idBase}-series-type`}>\n <select\n id={`${idBase}-series-type`}\n className={chartInputClass}\n value={selectedSeries.type ?? ''}\n data-option=\"series.type\"\n onChange={(e) => controller.updateSeries(selectedSeries.id, { type: (e.currentTarget.value || null) as any })}\n >\n <option value=\"\">Chart type</option>\n {CHART_SERIES_TYPES.map((t) => (\n <option key={t} value={t}>\n {CHART_TYPE_LABELS[t]}\n </option>\n ))}\n </select>\n </Field>\n )}\n {(cartesian || family === 'xy') && ['line', 'area', 'scatter'].includes(chartSeriesType(spec, selectedSeries)) && (\n <Field label=\"Marker\" htmlFor={`${idBase}-series-marker`}>\n <select\n id={`${idBase}-series-marker`}\n className={chartInputClass}\n value={selectedSeries.marker ?? ''}\n data-option=\"series.marker\"\n onChange={(e) => controller.updateSeries(selectedSeries.id, { marker: (e.currentTarget.value || null) as any })}\n >\n <option value=\"\">Default</option>\n {CHART_MARKERS.map((m) => (\n <option key={m} value={m}>\n {cap(m)}\n </option>\n ))}\n </select>\n </Field>\n )}\n {scales && <ErrorBarFields controller={controller} series={selectedSeries} which=\"errorBars\" idBase={idBase} />}\n {family === 'xy' && <ErrorBarFields controller={controller} series={selectedSeries} which=\"xErrorBars\" idBase={idBase} />}\n {chartSupportsTrendlines(spec.type, spec.stacking) && (\n <div className=\"space-y-1\" data-section=\"trendlines\">\n {(selectedSeries.trendlines ?? []).map((t, i) => (\n <div key={i} className=\"flex items-center gap-1\" data-trendline={i}>\n <span className=\"flex-1 truncate text-muted-foreground\">{chartTrendlineName(t, selectedSeries.name)}</span>\n <Toggle label=\"R²\" name={`trendline.${i}.showR2`} checked={!!t.showR2} onChange={(showR2) => controller.updateTrendline(selectedSeries.id, i, { showR2 })} />\n <button type=\"button\" className={chartButtonClass} aria-label=\"Delete trendline\" data-action=\"trendline-delete\" onClick={() => controller.removeTrendline(selectedSeries.id, i)}>\n ×\n </button>\n </div>\n ))}\n <select\n className={chartInputClass}\n value=\"\"\n aria-label=\"Add trendline\"\n data-option=\"trendline.add\"\n onChange={(e) => e.currentTarget.value && controller.addTrendline(selectedSeries.id, { type: e.currentTarget.value as any })}\n >\n <option value=\"\">Add trendline…</option>\n {CHART_TRENDLINE_TYPES.map((t) => (\n <option key={t} value={t}>\n {cap(t.replace('-', ' '))}\n </option>\n ))}\n </select>\n </div>\n )}\n <div className=\"flex flex-wrap items-center gap-1\">\n <Toggle label=\"Hidden\" name=\"series.hidden\" checked={!!selectedSeries.hidden} onChange={(hidden) => controller.updateSeries(selectedSeries.id, { hidden })} />\n {family === 'cartesian' && <Toggle label=\"Secondary axis\" name=\"series.axis\" checked={selectedSeries.axis === 'secondary'} onChange={(secondary) => controller.updateSeries(selectedSeries.id, { axis: secondary ? 'secondary' : null })} />}\n <span className=\"flex-1\" />\n <button type=\"button\" className={chartButtonClass} disabled={seriesIndex <= 0} aria-label=\"Move series earlier\" data-action=\"series-up\" onClick={() => controller.moveSeries(selectedSeries.id, seriesIndex - 1)}>\n ↑\n </button>\n <button type=\"button\" className={chartButtonClass} disabled={seriesIndex >= spec.series.length - 1} aria-label=\"Move series later\" data-action=\"series-down\" onClick={() => controller.moveSeries(selectedSeries.id, seriesIndex + 1)}>\n ↓\n </button>\n <button type=\"button\" className={`${chartButtonClass} text-destructive`} data-action=\"series-delete\" onClick={() => controller.removeSeries(selectedSeries.id)}>\n Delete\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["useEditor","import_react","StarterKit","Placeholder","import_react","import_editor","useEditor","useTipTapEditor","import_react","import_react","import_react","import_editor","import_react","import_editor","import_react","import_react","import_editor","import_react","import_react","import_react","import_react","import_jsx_runtime","TipTapEditorContent","import_react","import_react","import_editor","import_jsx_runtime","import_react","import_editor","import_jsx_runtime","import_react","import_react","import_editor","import_jsx_runtime","import_react","import_editor","import_editor","import_jsx_runtime","import_react","import_editor","import_react","import_jsx_runtime","import_editor","import_react","options","document","import_react","import_spreadsheet","import_react","import_spreadsheet","import_jsx_runtime","React","import_react","import_jsx_runtime","React","import_react","import_spreadsheet","import_react","import_jsx_runtime","button","import_react","import_spreadsheet","import_jsx_runtime","import_react","import_spreadsheet","import_react","import_spreadsheet","import_jsx_runtime","import_react","import_spreadsheet","import_jsx_runtime","import_jsx_runtime","import_react","import_spreadsheet","import_jsx_runtime","import_react","import_jsx_runtime","import_react","options","import_react","import_image_editor","import_image_editor","import_jsx_runtime","import_react","import_image_editor","import_jsx_runtime","import_react","import_image_editor","import_react","import_image_editor","import_jsx_runtime","import_jsx_runtime","import_react","import_react","import_image_editor","import_jsx_runtime","import_image_editor","import_jsx_runtime","import_react","import_image_editor","import_react","import_react","import_jsx_runtime","import_react","import_effects","import_jsx_runtime","import_react","import_effects","import_parameters","import_react","import_jsx_runtime","_","import_jsx_runtime","React","import_jsx_runtime","React","import_react","import_image_editor","import_image_editor","import_react","import_jsx_runtime","button","import_jsx_runtime","import_jsx_runtime","import_react","import_image_editor","import_jsx_runtime","chip","select","import_react","import_image_editor","import_jsx_runtime","btn","import_react","import_image_editor","import_jsx_runtime","button","import_react","import_image_editor","import_jsx_runtime","chip","import_react","import_image_editor","import_jsx_runtime","chip","import_react","import_image_editor","import_jsx_runtime","chip","import_jsx_runtime","currentImgPt","React","import_react","import_editor","import_react","import_editor","import_jsx_runtime","buttonClass","import_jsx_runtime","buttonClass","import_jsx_runtime","import_react","import_editor","import_editor","import_jsx_runtime","buttonClass","import_react","import_commands","import_react","import_jsx_runtime","React","import_react","import_react","import_persistence","import_jsx_runtime","import_react","import_react","import_generation","import_jsx_runtime","inputClass","import_jsx_runtime","import_react","import_generation","import_jsx_runtime","chip","import_react","import_generation","import_jsx_runtime","import_react","import_editor","noopUnsubscribe","import_react","import_editor","import_jsx_runtime","inputClass","buttonClass","import_react","import_editor","import_react","import_editor","import_jsx_runtime","keepSelection","React","import_react","import_jsx_runtime","keepSelection","import_editor","import_jsx_runtime","import_react","import_chart","import_react","import_jsx_runtime","import_react","import_chart","import_jsx_runtime","import_react","import_chart","import_jsx_runtime","key","cap","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/hooks/usePromptEditor.ts","../src/hooks/useEditor.ts","../src/hooks/useNavigationGuard.ts","../src/hooks/useDismissGuard.ts","../src/hooks/useHistory.ts","../src/hooks/useHistoryDirty.ts","../src/hooks/useHistoryShortcuts.ts","../src/hooks/useFileImport.ts","../src/hooks/useDocxExport.ts","../src/components/ExportDocxButton.tsx","../src/hooks/useAgentToolProvider.ts","../src/hooks/useToolBridge.ts","../src/components/EditorContent.tsx","../src/components/BubbleMenu.tsx","../src/components/TemplateRenderer.tsx","../src/components/VariableForm.tsx","../src/components/MergePreview.tsx","../src/hooks/useMergePreview.ts","../src/hooks/useOutline.ts","../src/components/OutlinePanel.tsx","../src/hooks/useParagraphStyles.ts","../src/components/StylesGallery.tsx","../src/spreadsheet/useSpreadsheetEditor.ts","../src/spreadsheet/SpreadsheetEditor.tsx","../src/spreadsheet/SpreadsheetContextMenu.tsx","../src/spreadsheet/SpreadsheetGroupRow.tsx","../src/spreadsheet/useSpreadsheetTableInteractions.ts","../src/spreadsheet/SpreadsheetValidationDialog.tsx","../src/spreadsheet/SpreadsheetRulePanels.tsx","../src/spreadsheet/useSpreadsheetViewport.ts","../src/spreadsheet/FormulaHints.tsx","../src/spreadsheet/SheetTabs.tsx","../src/spreadsheet/NameManager.tsx","../src/slots.tsx","../src/image-editor/useImageEditor.ts","../src/image-editor/ImageEditor.tsx","../src/image-editor/ControlSlider.tsx","../src/image-editor/Histogram.tsx","../src/image-editor/AdjustmentLayersPanel.tsx","../src/image-editor/CurvesEditor.tsx","../src/image-editor/LayersPanel.tsx","../src/image-editor/LayerEffectsPanel.tsx","../src/image-editor/ImageProviderEffectsPanel.tsx","../src/effects/useEffects.ts","../src/effects/EffectThumbnail.tsx","../src/effects/EffectsBrowser.tsx","../src/effects/EffectParameters.tsx","../src/parameters/fields.tsx","../src/image-editor/BrushOptionsBar.tsx","../src/image-editor/PaintGradientEditor.tsx","../src/paint-editor/PaintGradientEditorView.tsx","../src/image-editor/ColorProfilePanel.tsx","../src/image-editor/SelectionOptionsBar.tsx","../src/image-editor/RefineEdgePanel.tsx","../src/image-editor/FreeTransformOptionsBar.tsx","../src/image-editor/ShapeOptionsBar.tsx","../src/image-editor/TypeOptionsBar.tsx","../src/review/useReview.ts","../src/review/CommentsPanel.tsx","../src/review/ReviewToolbar.tsx","../src/review/CommentButton.tsx","../src/review/useDocumentCompare.ts","../src/review/TrackedChangesList.tsx","../src/commands/useCommandPalette.ts","../src/commands/CommandPalette.tsx","../src/commands/useCommandShortcuts.ts","../src/persistence/useAutosave.ts","../src/persistence/RecoveryPrompt.tsx","../src/generation/useGenerationPlan.ts","../src/generation/GenerationSettings.tsx","../src/generation/JobProgress.tsx","../src/generation/AssetMentionChips.tsx","../src/generation/GenerationHistory.tsx","../src/find-replace/useFindReplace.ts","../src/find-replace/FindReplaceBar.tsx","../src/tables/useTableMenu.ts","../src/tables/TableToolbar.tsx","../src/tables/InsertTableGrid.tsx","../src/tables/TableBubbleMenu.tsx","../src/chart-node/ChartNodeView.tsx","../src/chart/ChartCanvas.tsx","../src/chart/useChartEditor.ts","../src/chart/ChartDataGrid.tsx","../src/chart/styles.ts","../src/chart/ChartInspector.tsx"],"sourcesContent":["export * from \"./hooks/usePromptEditor\";\nexport * from \"./hooks/useEditor\";\nexport * from \"./hooks/useNavigationGuard\";\nexport * from \"./hooks/useDismissGuard\";\nexport * from \"./hooks/useHistory\";\nexport * from \"./hooks/useHistoryDirty\";\nexport * from \"./hooks/useHistoryShortcuts\";\nexport * from \"./hooks/useFileImport\";\nexport * from \"./hooks/useDocxExport\";\nexport * from \"./components/ExportDocxButton\";\nexport * from \"./hooks/useAgentToolProvider\";\nexport * from \"./hooks/useToolBridge\";\nexport * from \"./components/EditorContent\";\nexport * from \"./components/BubbleMenu\";\nexport * from \"./components/TemplateRenderer\";\nexport * from \"./components/VariableForm\";\nexport * from \"./components/MergePreview\";\nexport * from \"./hooks/useMergePreview\";\nexport * from \"./hooks/useOutline\";\nexport * from \"./components/OutlinePanel\";\nexport * from \"./hooks/useParagraphStyles\";\nexport * from \"./components/StylesGallery\";\n\n// Re-export core types for easy consumer access\nexport {\n DirtyTracker,\n createDirtyTracker,\n defaultIsEqual,\n HistoryManager,\n createHistoryManager,\n bindDirtyToHistory,\n withoutDirty,\n} from \"@pixerate/editor\";\nexport type {\n Template,\n TemplateVersion,\n Token,\n TokenType,\n ColorGradient,\n RichTextPresetOptions,\n DirtyTrackerOptions,\n Command,\n HistoryState,\n HistoryManagerOptions,\n HistoryEntry,\n HistoryMark,\n MergedExecutionOptions,\n HistoryDirtyBinding,\n BindDirtyToHistoryOptions,\n} from \"@pixerate/editor\";\nexport type {\n PromptValues,\n PromptDiagnostic,\n VariableFormField,\n MergeDataSource,\n MergeRecord,\n MergeRecordsResult,\n MergeOutput,\n} from \"@pixerate/editor\";\n\nexport * from \"./spreadsheet\";\nexport * from \"./slots\";\nexport * from \"./image-editor\";\nexport * from \"./review\";\nexport * from \"./commands\";\nexport * from \"./persistence\";\nexport * from \"./generation\";\nexport * from \"./find-replace\";\nexport * from \"./tables\";\nexport * from \"./chart-node\";\n","import { useMemo, useEffect, useRef } from \"react\";\nimport { useEditor } from \"@tiptap/react\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport Placeholder from \"@tiptap/extension-placeholder\";\nimport { Slice } from \"@tiptap/pm/model\";\nimport {\n Template,\n ColorGradient,\n GradientText,\n TemplateSuggestions,\n LoadingNode,\n plainTextToTipTapHtml,\n plainTextToSlice,\n getEditorText,\n tokenizePrompt,\n FileImport,\n type FileImportOptions,\n} from \"@pixerate/editor\";\n\nexport interface UsePromptEditorProps {\n /**\n * The editor content as plain text. Changes from the parent (e.g. clearing\n * after submit) are applied to the editor; echoes of the editor's own\n * updates via `onContentChange` are ignored.\n */\n content: string;\n /** Callback fired when the editor content changes (returns plain text) */\n onContentChange: (text: string) => void;\n /** List of available templates to be suggested and highlighted */\n templates?: Template[];\n /** Custom gradient color map for templates */\n templateColorMap?: Map<string, ColorGradient>;\n /** Whether the editor is editable */\n isEditing?: boolean;\n /** Placeholder text for the editor */\n placeholder?: string;\n /** Additional CSS classes for the editor container */\n className?: string;\n /** Callback fired when the Escape key is pressed */\n onEscape?: () => void;\n /** Custom keydown handler. Return true to prevent default behavior */\n onKeyDown?: (event: KeyboardEvent) => boolean;\n /** Callback fired when text selection changes */\n onSelectionChange?: (selection: { from: number; to: number } | null) => void;\n /** Callback fired when a slash command (e.g., /template) matches */\n onSlashCommandMatch?: (\n match: RegExpMatchArray,\n from: number,\n to: number,\n coords: { top: number; left: number },\n ) => void;\n /** Callback to dismiss/clear the active slash command */\n clearSlashCommand?: () => void;\n /** Whether a slash command menu is currently active */\n slashCommandActive?: boolean;\n /**\n * Callback fired the first time each milestone is reached while the editor\n * is mounted: `used_variable` ({variable}) and `used_magic` (__instruction__).\n */\n onMilestone?: (milestone: string) => void;\n /** DOM element ID of the container, used for positioning popovers */\n containerId?: string;\n /** Variable names originating from structured JSON output steps */\n jsonVariables?: string[];\n /** Animation speed for gradient decorations */\n speed?: number;\n /**\n * Import text from .md, .html, .txt and .rtf files dropped onto the editor\n * (opt-in). Content is always inserted as plain text. Pasting keeps the\n * plain-text paste handler, so pasted files are not imported.\n */\n fileImport?: Omit<FileImportOptions, \"asPlainText\"> | boolean;\n}\n\nconst DEFAULT_TEMPLATES: Template[] = [];\nconst DEFAULT_COLOR_MAP = new Map<string, ColorGradient>([\n [\"default\", { from: \"#f43f5e\", to: \"#8b5cf6\" }],\n]);\nconst DEFAULT_CLASS_NAME =\n \"w-full border border-input rounded-md p-3 font-mono text-sm leading-relaxed focus:outline-none focus:ring-2 focus:ring-primary whitespace-pre-wrap break-words\";\n\nconst normalizeNewlines = (text: string) => text.replace(/\\r\\n?/g, \"\\n\");\n\nexport function usePromptEditor({\n content,\n onContentChange,\n templates = DEFAULT_TEMPLATES,\n templateColorMap: userColorMap,\n isEditing = true,\n placeholder = \"Write a prompt, use {{template}}, {variable}, or /command...\",\n className,\n onEscape,\n onKeyDown,\n onSelectionChange,\n onSlashCommandMatch,\n clearSlashCommand,\n slashCommandActive = false,\n onMilestone,\n containerId = \"editor-container\",\n jsonVariables,\n speed = 2,\n fileImport,\n}: UsePromptEditorProps) {\n const fileImportRef = useRef(fileImport);\n fileImportRef.current = fileImport;\n const fileImportEnabled = !!fileImport;\n\n const slashCommandActiveRef = useRef(slashCommandActive);\n slashCommandActiveRef.current = slashCommandActive;\n\n const clearSlashCommandRef = useRef(clearSlashCommand);\n clearSlashCommandRef.current = clearSlashCommand;\n\n const onEscapeRef = useRef(onEscape);\n onEscapeRef.current = onEscape;\n\n const onKeyDownRef = useRef(onKeyDown);\n onKeyDownRef.current = onKeyDown;\n\n const onSelectionChangeRef = useRef(onSelectionChange);\n onSelectionChangeRef.current = onSelectionChange;\n\n const onSlashCommandMatchRef = useRef(onSlashCommandMatch);\n onSlashCommandMatchRef.current = onSlashCommandMatch;\n\n const onContentChangeRef = useRef(onContentChange);\n onContentChangeRef.current = onContentChange;\n\n const onMilestoneRef = useRef(onMilestone);\n onMilestoneRef.current = onMilestone;\n\n const containerIdRef = useRef(containerId);\n containerIdRef.current = containerId;\n\n const templateKey = useMemo(() => {\n return (templates || [])\n .map((t) => `${t.id || t.name}:${(t as any).latestVersion || \"\"}`)\n .sort()\n .join(\",\");\n }, [templates]);\n\n // Key the color map by value so an inline `new Map(...)` does not recreate\n // the editor on every render.\n const colorMapKey = userColorMap\n ? JSON.stringify(Array.from(userColorMap.entries()))\n : \"\";\n const resolvedColorMap = useMemo(() => {\n if (userColorMap) return userColorMap;\n const map = new Map<string, ColorGradient>();\n templates.forEach((t) => {\n map.set(t.name, { from: \"#f43f5e\", to: \"#8b5cf6\" });\n });\n return map.size > 0 ? map : DEFAULT_COLOR_MAP;\n }, [colorMapKey, templateKey]);\n\n const jsonVariablesKey = (jsonVariables || []).join(\"\\u0000\");\n\n const reachedMilestonesRef = useRef(new Set<string>());\n\n const StarterKitExt =\n (StarterKit as any)?.configure\n ? StarterKit\n : (StarterKit as any)?.default?.configure\n ? (StarterKit as any)?.default\n : StarterKit;\n\n const PlaceholderExt =\n (Placeholder as any)?.configure\n ? Placeholder\n : (Placeholder as any)?.default?.configure\n ? (Placeholder as any)?.default\n : Placeholder;\n\n const editor = useEditor(\n {\n immediatelyRender: false,\n enablePasteRules: false,\n enableInputRules: false,\n editable: isEditing,\n extensions: [\n StarterKitExt.configure({\n heading: false,\n codeBlock: false,\n }),\n PlaceholderExt.configure({ placeholder }),\n GradientText.configure({\n templateColorMap: resolvedColorMap,\n speed,\n jsonVariables,\n }),\n TemplateSuggestions.configure({\n templates,\n }),\n LoadingNode,\n ...(fileImportEnabled\n ? [\n FileImport.configure({\n ...(typeof fileImportRef.current === \"object\" ? fileImportRef.current : {}),\n // Prompt editors only ever receive plain text.\n asPlainText: true,\n }),\n ]\n : []),\n ],\n content: plainTextToTipTapHtml(content),\n onUpdate: ({ editor: ed }) => {\n const plainText = getEditorText(ed);\n onContentChangeRef.current?.(plainText);\n\n if (onMilestoneRef.current) {\n const reached = reachedMilestonesRef.current;\n for (const token of tokenizePrompt(plainText)) {\n const milestone =\n token.type === \"variable\"\n ? \"used_variable\"\n : token.type === \"instruction\"\n ? \"used_magic\"\n : null;\n if (milestone && !reached.has(milestone)) {\n reached.add(milestone);\n onMilestoneRef.current(milestone);\n }\n }\n }\n\n const { state, view } = ed;\n const { selection } = state;\n const { $from, from, to } = selection;\n\n onSelectionChangeRef.current?.({ from, to });\n\n if (onSlashCommandMatchRef.current && clearSlashCommandRef.current) {\n const textBeforeCursor = $from?.parent?.textBetween\n ? $from.parent.textBetween(0, $from.parentOffset)\n : \"\";\n const slashMatch = textBeforeCursor.match(\n /(?:^|\\s)\\/([a-zA-Z0-9_-]*)$/,\n );\n\n if (slashMatch) {\n const coords = view.coordsAtPos($from.pos);\n const containerEl =\n document.getElementById(containerIdRef.current) ||\n document.getElementById(\"editor-container\") ||\n (view.dom.closest?.(\".relative\") as HTMLElement | null);\n const containerCoords = containerEl?.getBoundingClientRect();\n\n if (containerCoords) {\n onSlashCommandMatchRef.current(\n slashMatch,\n $from.pos -\n slashMatch[0].length +\n (slashMatch[0].startsWith(\" \") ? 1 : 0),\n $from.pos,\n {\n top: coords.bottom - containerCoords.top + 5,\n left: coords.left - containerCoords.left,\n },\n );\n }\n } else {\n clearSlashCommandRef.current();\n }\n }\n },\n onSelectionUpdate: ({ editor: ed }) => {\n const { from, to } = ed.state.selection;\n onSelectionChangeRef.current?.({ from, to });\n },\n editorProps: {\n attributes: {\n class: className || DEFAULT_CLASS_NAME,\n role: \"textbox\",\n \"aria-label\": \"Prompt editor\",\n },\n handleKeyDown(view, event) {\n if (slashCommandActiveRef.current) {\n if (\n event.key === \"ArrowUp\" ||\n event.key === \"ArrowDown\" ||\n event.key === \"Enter\"\n ) {\n event.preventDefault();\n return true;\n }\n if (event.key === \"Escape\") {\n clearSlashCommandRef.current?.();\n event.preventDefault();\n event.stopPropagation();\n return true;\n }\n }\n if (onKeyDownRef.current && onKeyDownRef.current(event as KeyboardEvent)) {\n return true;\n }\n if (event.key === \"Escape\" && onEscapeRef.current) {\n onEscapeRef.current();\n return true;\n }\n return false;\n },\n handlePaste: (view, event) => {\n // Paste as plain text even when the clipboard also carries HTML.\n const text = event.clipboardData?.getData(\"text/plain\");\n if (!text) return false;\n event.preventDefault();\n const schema = view.state.schema;\n if (!schema) return false;\n view.dispatch(\n view.state.tr.replaceSelection(plainTextToSlice(text, schema)),\n );\n return true;\n },\n clipboardTextParser: (text, context, _plain, view) => {\n const schema =\n (context as any)?.doc?.type?.schema ||\n (context as any)?.schema ||\n view?.state?.schema;\n\n if (!schema) return Slice.empty;\n return plainTextToSlice(text, schema);\n },\n },\n },\n // Only options baked into extensions recreate the editor; editable state,\n // placeholder, class names and content are applied to the live instance.\n [resolvedColorMap, templateKey, speed, jsonVariablesKey, fileImportEnabled],\n );\n\n useEffect(() => {\n if (editor && !editor.isDestroyed) {\n editor.setEditable(isEditing);\n }\n }, [editor, isEditing]);\n\n // Apply content changes made by the parent (e.g. clearing after submit).\n useEffect(() => {\n if (!editor || editor.isDestroyed) return;\n if (normalizeNewlines(content) === getEditorText(editor)) return;\n const { from, to } = editor.state.selection;\n editor.commands.setContent(plainTextToTipTapHtml(content), false);\n const max = editor.state.doc.content.size;\n editor.commands.setTextSelection({\n from: Math.min(from, max),\n to: Math.min(to, max),\n });\n }, [editor, content]);\n\n useEffect(() => {\n if (!editor || editor.isDestroyed) return;\n editor.setOptions({\n editorProps: {\n ...editor.options.editorProps,\n attributes: {\n ...(editor.options.editorProps.attributes as Record<string, string>),\n class: className || DEFAULT_CLASS_NAME,\n },\n },\n });\n }, [editor, className]);\n\n useEffect(() => {\n if (!editor || editor.isDestroyed) return;\n const placeholderExt = editor.extensionManager.extensions.find(\n (ext) => ext.name === \"placeholder\",\n );\n if (!placeholderExt || placeholderExt.options.placeholder === placeholder) {\n return;\n }\n placeholderExt.options.placeholder = placeholder;\n // Re-run decorations so the new placeholder renders.\n editor.view.dispatch(editor.state.tr);\n }, [editor, placeholder]);\n\n return editor;\n}\n","import { useEditor as useTipTapEditor, UseEditorOptions } from \"@tiptap/react\";\nimport {\n createRichTextPreset,\n RichTextPresetOptions,\n type FileImportOptions,\n type RichClipboardOptions,\n} from \"@pixerate/editor\";\n\nexport interface UseRichEditorProps extends UseEditorOptions {\n richTextOptions?: RichTextPresetOptions;\n /**\n * Import .md, .html, .txt and .rtf files dropped or pasted into the editor\n * at the drop position (opt-in; same as `richTextOptions.fileImport`).\n */\n fileImport?: FileImportOptions | boolean;\n /**\n * Copy/paste lossless ProseMirror slices between editors via the\n * `application/x.pixerate.document+json` clipboard type (opt-in; same as\n * `richTextOptions.richClipboard`).\n */\n richClipboard?: RichClipboardOptions | boolean;\n}\n\n/**\n * Hook to initialize a TipTap rich-text editor instance with pre-configured extensions.\n */\nexport function useEditor(options: UseRichEditorProps = {}) {\n const {\n richTextOptions,\n fileImport,\n richClipboard,\n extensions = [],\n ...editorOptions\n } = options;\n\n const preset = createRichTextPreset({\n ...(fileImport !== undefined ? { fileImport } : {}),\n ...(richClipboard !== undefined ? { richClipboard } : {}),\n ...richTextOptions,\n });\n const combinedExtensions = [...preset, ...extensions];\n\n return useTipTapEditor({\n extensions: combinedExtensions,\n ...editorOptions,\n });\n}\n","import { useState, useEffect, useCallback, useRef } from \"react\";\n\nexport interface UseNavigationGuardOptions {\n /** Whether the current form or editor has unsaved changes */\n isDirty: boolean;\n /** Whether guarding is enabled (defaults to true) */\n enabled?: boolean;\n /** Custom navigation function (e.g. router.push from next/navigation or react-router) */\n onNavigate?: (url: string) => void;\n /** Optional callback fired when an internal navigation attempt is intercepted */\n onBlocked?: (url: string) => void;\n}\n\nexport interface UseNavigationGuardReturn {\n /** Whether the unsaved changes confirmation dialog should be displayed */\n showConfirm: boolean;\n /** Setter to manually control the dialog visibility */\n setShowConfirm: (show: boolean) => void;\n /** The target URL that the user attempted to navigate to */\n pendingUrl: string | null;\n /** Proceeds with the blocked navigation and closes the dialog */\n confirmLeave: () => void;\n /** Cancels the navigation attempt and keeps the user on the current page */\n cancelLeave: () => void;\n}\n\n/**\n * Hook to guard against navigation when there are unsaved changes.\n * Intercepts both external unloads (tab closing/refreshing) and internal link clicks.\n */\nexport function useNavigationGuard({\n isDirty,\n enabled = true,\n onNavigate,\n onBlocked,\n}: UseNavigationGuardOptions): UseNavigationGuardReturn {\n const [showConfirm, setShowConfirm] = useState(false);\n const [pendingUrl, setPendingUrl] = useState<string | null>(null);\n\n const onNavigateRef = useRef(onNavigate);\n onNavigateRef.current = onNavigate;\n\n const onBlockedRef = useRef(onBlocked);\n onBlockedRef.current = onBlocked;\n\n // 1. Intercept external navigation / tab close (beforeunload)\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n if (!enabled || !isDirty) return;\n\n const handleBeforeUnload = (e: BeforeUnloadEvent) => {\n e.preventDefault();\n e.returnValue = \"\";\n };\n\n window.addEventListener(\"beforeunload\", handleBeforeUnload);\n return () => {\n window.removeEventListener(\"beforeunload\", handleBeforeUnload);\n };\n }, [enabled, isDirty]);\n\n // 2. Intercept internal anchor link clicks\n useEffect(() => {\n if (typeof document === \"undefined\" || typeof window === \"undefined\")\n return;\n if (!enabled || !isDirty) return;\n\n const handleClick = (e: MouseEvent) => {\n const target = e.target as HTMLElement | null;\n const anchor = target?.closest?.(\"a\");\n\n if (!anchor) return;\n if (anchor.target === \"_blank\") return;\n\n // Only guard internal origins\n const isInternal = anchor.host === window.location.host;\n if (!isInternal) return;\n\n // Ignore navigation to the exact same path & query\n if (\n anchor.pathname === window.location.pathname &&\n anchor.search === window.location.search\n ) {\n return;\n }\n\n e.preventDefault();\n e.stopPropagation();\n\n const href = anchor.href;\n setPendingUrl(href);\n setShowConfirm(true);\n onBlockedRef.current?.(href);\n };\n\n document.addEventListener(\"click\", handleClick, { capture: true });\n return () => {\n document.removeEventListener(\"click\", handleClick, { capture: true });\n };\n }, [enabled, isDirty]);\n\n const confirmLeave = useCallback(() => {\n setShowConfirm(false);\n if (pendingUrl) {\n if (onNavigateRef.current) {\n onNavigateRef.current(pendingUrl);\n } else if (typeof window !== \"undefined\") {\n window.location.href = pendingUrl;\n }\n }\n }, [pendingUrl]);\n\n const cancelLeave = useCallback(() => {\n setShowConfirm(false);\n setPendingUrl(null);\n }, []);\n\n return {\n showConfirm,\n setShowConfirm,\n pendingUrl,\n confirmLeave,\n cancelLeave,\n };\n}\n","import { useState, useCallback, useRef } from \"react\";\n\nexport interface UseDismissGuardOptions {\n /** Whether there are unsaved changes */\n isDirty: boolean;\n /** Whether the dismissal guard is enabled (defaults to true) */\n enabled?: boolean;\n /** Callback fired when dismissal is confirmed or when clean dismissal occurs */\n onDismiss?: () => void;\n}\n\nexport interface UseDismissGuardReturn {\n /** Whether the discard confirmation modal should be shown */\n showConfirm: boolean;\n /** Manually update confirmation modal visibility */\n setShowConfirm: (show: boolean) => void;\n /** Request dismissal - checks isDirty and shows confirm or executes onDismiss */\n requestDismiss: () => void;\n /** Confirm discarding changes and dismiss */\n confirmDismiss: () => void;\n /** Cancel discarding and resume editing */\n cancelDismiss: () => void;\n /** Helper keydown handler intercepting Escape key */\n handleKeyDown: (event: React.KeyboardEvent | KeyboardEvent) => boolean;\n}\n\n/**\n * Hook to guard against closing or exiting an editor/dialog with uncommitted changes.\n */\nexport function useDismissGuard({\n isDirty,\n enabled = true,\n onDismiss,\n}: UseDismissGuardOptions): UseDismissGuardReturn {\n const [showConfirm, setShowConfirm] = useState(false);\n\n const onDismissRef = useRef(onDismiss);\n onDismissRef.current = onDismiss;\n\n const requestDismiss = useCallback(() => {\n if (enabled && isDirty) {\n setShowConfirm(true);\n } else {\n onDismissRef.current?.();\n }\n }, [enabled, isDirty]);\n\n const confirmDismiss = useCallback(() => {\n setShowConfirm(false);\n onDismissRef.current?.();\n }, []);\n\n const cancelDismiss = useCallback(() => {\n setShowConfirm(false);\n }, []);\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent | KeyboardEvent) => {\n if (event.key === \"Escape\") {\n if (event.defaultPrevented) return false;\n event.preventDefault();\n requestDismiss();\n return true;\n }\n return false;\n },\n [requestDismiss],\n );\n\n return {\n showConfirm,\n setShowConfirm,\n requestDismiss,\n confirmDismiss,\n cancelDismiss,\n handleKeyDown,\n };\n}\n","import { useSyncExternalStore, useRef, useCallback, useMemo } from \"react\";\nimport {\n HistoryManager,\n HistoryState,\n HistoryEntry,\n HistoryMark,\n Command,\n MergedExecutionOptions,\n createHistoryManager,\n HistoryManagerOptions,\n} from \"@pixerate/editor\";\n\nexport interface UseHistoryResult extends HistoryState {\n manager: HistoryManager;\n /** History panel rows (undo steps, then redo steps). */\n entries: HistoryEntry[];\n undo: () => boolean;\n redo: () => boolean;\n clear: () => void;\n execute: (command: Command) => void;\n executeMerged: (command: Command, options?: MergedExecutionOptions) => void;\n batch: (name: string, fn: () => void) => void;\n /** Undoes / redoes until the entry at `index` is current (`-1` = before all). */\n goTo: (index: number) => number;\n /** Captures the current point, e.g. when a drag starts. */\n mark: () => HistoryMark;\n /** Takes back every step since `mark` without leaving redo (Escape-cancel). */\n revertTo: (mark: HistoryMark) => number;\n /** Joins every merged execute into one step until `endGesture`. */\n beginGesture: (key: string) => void;\n endGesture: () => void;\n}\n\n/**\n * React hook that subscribes to a HistoryManager instance.\n * Accepts an existing HistoryManager or config options to create an instance\n * (options are read on first render only).\n */\nexport function useHistory(\n managerOrOptions?: HistoryManager | HistoryManagerOptions,\n): UseHistoryResult {\n // Options are read once, so passing an inline options object does not\n // create a new manager (and wipe history) on every render.\n const ownManagerRef = useRef<HistoryManager | null>(null);\n let manager: HistoryManager;\n if (managerOrOptions instanceof HistoryManager) {\n manager = managerOrOptions;\n } else {\n ownManagerRef.current ??= createHistoryManager(managerOrOptions);\n manager = ownManagerRef.current;\n }\n\n const state = useSyncExternalStore(\n useCallback(\n (onStoreChange) => manager.subscribe(onStoreChange),\n [manager],\n ),\n () => manager.getState(),\n () => manager.getState(),\n );\n\n // getEntries() is cached per history change, so `state` is a valid dependency.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const entries = useMemo(() => manager.getEntries(), [manager, state]);\n\n const undo = useCallback(() => manager.undo(), [manager]);\n const redo = useCallback(() => manager.redo(), [manager]);\n const clear = useCallback(() => manager.clear(), [manager]);\n const execute = useCallback(\n (cmd: Command) => manager.execute(cmd),\n [manager],\n );\n const executeMerged = useCallback(\n (cmd: Command, opts?: MergedExecutionOptions) =>\n manager.executeMerged(cmd, opts),\n [manager],\n );\n const batch = useCallback(\n (name: string, fn: () => void) => manager.batch(name, fn),\n [manager],\n );\n const goTo = useCallback((index: number) => manager.goTo(index), [manager]);\n const mark = useCallback(() => manager.mark(), [manager]);\n const revertTo = useCallback(\n (m: HistoryMark) => manager.revertTo(m),\n [manager],\n );\n const beginGesture = useCallback(\n (key: string) => manager.beginGesture(key),\n [manager],\n );\n const endGesture = useCallback(() => manager.endGesture(), [manager]);\n\n return {\n ...state,\n manager,\n entries,\n undo,\n redo,\n clear,\n execute,\n executeMerged,\n batch,\n goTo,\n mark,\n revertTo,\n beginGesture,\n endGesture,\n };\n}\n","import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from \"react\";\nimport {\n DirtyTracker,\n bindDirtyToHistory,\n type DirtyTrackerOptions,\n type HistoryDirtyBinding,\n type HistoryManager,\n} from \"@pixerate/editor\";\n\nexport interface UseHistoryDirtyOptions<T> extends DirtyTrackerOptions<T> {\n /** The history whose changes re-check the document. */\n history: HistoryManager;\n /** Reads the current document value (the latest function is always used). */\n getValue: () => T;\n /** Existing tracker to drive (read on first render only). */\n tracker?: DirtyTracker<T>;\n}\n\nexport interface UseHistoryDirtyResult<T> {\n /** Whether the document differs from the saved state. Feed it to `useNavigationGuard`. */\n isDirty: boolean;\n /** Marks the current document as saved. */\n markClean: () => void;\n /** Runs a load / restore without marking the document dirty (re-entrant). */\n suppress: <R>(fn: () => R) => R;\n /** Re-checks after a change made outside the history. */\n refresh: () => boolean;\n tracker: DirtyTracker<T>;\n}\n\n/**\n * Dirty-vs-saved tracking bound to a HistoryManager: undoing back to the saved\n * state makes the document clean again, selection/viewport changes can be\n * ignored with `normalize`, and programmatic loads can be wrapped in `suppress`.\n * Options other than `getValue` and `history` are read on first render only.\n */\nexport function useHistoryDirty<T>(\n options: UseHistoryDirtyOptions<T>,\n): UseHistoryDirtyResult<T> {\n const getValueRef = useRef(options.getValue);\n getValueRef.current = options.getValue;\n\n const [tracker] = useState(\n () =>\n options.tracker ??\n new DirtyTracker<T>(options.getValue(), {\n isEqual: options.isEqual,\n normalize: options.normalize,\n }),\n );\n\n const bindingRef = useRef<HistoryDirtyBinding<T> | null>(null);\n useEffect(() => {\n const binding = bindDirtyToHistory<T>({\n history: options.history,\n getValue: () => getValueRef.current(),\n tracker,\n });\n bindingRef.current = binding;\n return () => {\n binding.destroy();\n if (bindingRef.current === binding) bindingRef.current = null;\n };\n }, [options.history, tracker]);\n\n const isDirty = useSyncExternalStore(\n useCallback((onChange) => tracker.subscribe(onChange), [tracker]),\n () => tracker.dirty,\n () => tracker.dirty,\n );\n\n const markClean = useCallback(\n () => tracker.markClean(getValueRef.current()),\n [tracker],\n );\n const suppress = useCallback(\n <R,>(fn: () => R): R =>\n bindingRef.current ? bindingRef.current.suppress(fn) : tracker.suppress(fn),\n [tracker],\n );\n const refresh = useCallback(\n () => tracker.update(getValueRef.current()),\n [tracker],\n );\n\n return { isDirty, markClean, suppress, refresh, tracker };\n}\n","import { useEffect } from \"react\";\nimport type { HistoryManager } from \"@pixerate/editor/history\";\nimport { matchHistoryShortcut } from \"@pixerate/editor/commands\";\n\nexport interface HistoryShortcutsOptions {\n /**\n * Whether the keyboard shortcuts are enabled. Defaults to true.\n */\n enabled?: boolean;\n /**\n * Target element or window to listen on. Defaults to window.\n */\n target?: Window | HTMLElement | null;\n /**\n * When true (default), shortcuts will not trigger if an <input>, <textarea>,\n * or [contenteditable] element is currently active / focused.\n */\n ignoreEditableElements?: boolean;\n}\n\n/**\n * Attaches keyboard listeners for Undo (Mod+Z) and Redo (Mod+Shift+Z / Mod+Y).\n * Automatically guards against active text inputs and contenteditable editors.\n */\nexport function useHistoryShortcuts(\n manager: HistoryManager,\n options: HistoryShortcutsOptions = {},\n): void {\n const {\n enabled = true,\n target,\n ignoreEditableElements = true,\n } = options;\n\n useEffect(() => {\n if (!enabled) return;\n\n const eventTarget = target ?? (typeof window !== \"undefined\" ? window : null);\n if (!eventTarget) return;\n\n const handleKeyDown = (event: Event) => {\n const e = event as KeyboardEvent;\n // Default bindings from the command system: Mod+Z, Mod+Shift+Z and (off macOS) Mod+Y,\n // matched by `event.code` with `Mod` = ⌘ on macOS and Ctrl elsewhere.\n const action = matchHistoryShortcut(e, { allowInEditable: !ignoreEditableElements });\n if (action === \"undo\" && manager.getState().canUndo) {\n e.preventDefault();\n manager.undo();\n } else if (action === \"redo\" && manager.getState().canRedo) {\n e.preventDefault();\n manager.redo();\n }\n };\n\n eventTarget.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n eventTarget.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [manager, enabled, target, ignoreEditableElements]);\n}\n","import { useEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n FileImportController,\n summarizeImportStructure,\n type FileImportControllerOptions,\n type FileImportState,\n type ImportStructureSummary,\n} from \"@pixerate/editor\";\n\nexport interface UseFileImportResult extends FileImportState {\n /**\n * Structures detected in the last import (headings, lists, tables, columns),\n * or `null` when no adapter reported any (only structure-aware adapters such\n * as PDF do). Turn PDF detection off with\n * `useFileImport(editor, { adapterOptions: { pdf: { structure: false } } })`.\n */\n structureSummary: ImportStructureSummary | null;\n /** Value for `<input type=\"file\" accept={…}>`. */\n accept: string;\n /** Opens the browser file picker and imports the chosen files at the selection. */\n openFilePicker: FileImportController[\"openFilePicker\"];\n /** Imports files (e.g. from your own `<input>` or drop zone) at `at` or the selection. */\n importFiles: FileImportController[\"importFiles\"];\n}\n\n/**\n * Imports markdown, HTML, plain-text and RTF files (or anything registered\n * with `registerImportAdapter` for the `document` target) into an editor.\n * Pair it with `useEditor({ fileImport: true })` to also accept dropped files.\n */\nexport function useFileImport(\n editor: Editor | null | undefined,\n options: FileImportControllerOptions = {},\n): UseFileImportResult {\n const editorRef = useRef(editor);\n editorRef.current = editor;\n\n const controller = useMemo(\n () =>\n new FileImportController(() => {\n const current = editorRef.current;\n return current && !current.isDestroyed ? current : null;\n }, options),\n [],\n );\n\n useEffect(() => {\n controller.setOptions(options);\n });\n\n const state = useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n const structureSummary = useMemo(() => summarizeImportStructure(state.lastOutcomes), [state.lastOutcomes]);\n\n return {\n ...state,\n structureSummary,\n accept: controller.accept,\n openFilePicker: controller.openFilePicker,\n importFiles: controller.importFiles,\n };\n}\n","import { useEffect, useMemo, useRef, useSyncExternalStore } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n DocxExportController,\n type DocxExportControllerOptions,\n type DocxExportReport,\n type DocxExportState,\n} from \"@pixerate/editor/export\";\n\nexport interface UseDocxExportResult extends DocxExportState {\n /** Exports the editor (with its comments, tracked changes and styles) and downloads the `.docx`. */\n download: (fileName?: string) => Promise<DocxExportReport | null>;\n /** Builds the `.docx` without downloading it. */\n exportBlob: DocxExportController[\"exportBlob\"];\n}\n\n/**\n * \"Export to Word\": downloads the editor's document as a `.docx` with its\n * comments (from the `Comments` store), tracked changes and paragraph styles.\n * `lastReport` lists anything the export had to leave out.\n */\nexport function useDocxExport(\n editor: Editor | null | undefined,\n options: DocxExportControllerOptions = {},\n): UseDocxExportResult {\n const editorRef = useRef(editor);\n editorRef.current = editor;\n\n const controller = useMemo(\n () =>\n new DocxExportController(() => {\n const current = editorRef.current;\n return current && !current.isDestroyed ? current : null;\n }, options),\n [],\n );\n\n useEffect(() => {\n controller.setOptions(options);\n });\n\n const state = useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n return {\n ...state,\n download: (fileName?: string) => controller.download(fileName),\n exportBlob: () => controller.exportBlob(),\n };\n}\n","import React from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport type { DocxExportControllerOptions, DocxExportReport } from \"@pixerate/editor/export\";\nimport { useDocxExport } from \"../hooks/useDocxExport\";\n\nexport interface ExportDocxButtonProps extends DocxExportControllerOptions {\n editor: Editor | null;\n className?: string;\n children?: React.ReactNode;\n /** Called after the download with the export report. */\n onExported?: (report: DocxExportReport) => void;\n}\n\n/** A button that downloads the editor's document as a Word file (`.docx`). */\nexport const ExportDocxButton: React.FC<ExportDocxButtonProps> = ({\n editor,\n className = \"rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-50\",\n children = \"Export to Word\",\n onExported,\n ...options\n}) => {\n const docx = useDocxExport(editor, options);\n return (\n <button\n type=\"button\"\n className={className}\n disabled={!editor || docx.isExporting}\n aria-busy={docx.isExporting || undefined}\n title={docx.error ? `Export failed: ${docx.error.message}` : undefined}\n onClick={async () => {\n const report = await docx.download();\n if (report) onExported?.(report);\n }}\n >\n {children}\n </button>\n );\n};\n","import { useEffect } from \"react\";\nimport type { AgentToolProvider, ToolRegistry } from \"@pixerate/editor/tools\";\n\n/**\n * Registers a tool provider with a `ToolRegistry` while the component is\n * mounted and unregisters it on unmount (the registry then announces the\n * change through `onListChanged`).\n *\n * Memoize the provider (e.g. `useMemo(() => createRichTextToolProvider(editor,\n * { id }), [editor])`): a new provider object re-registers it. Pass `null`\n * while it isn't ready.\n */\nexport function useAgentToolProvider(\n registry: ToolRegistry | null | undefined,\n provider: AgentToolProvider | null | undefined,\n): void {\n useEffect(() => {\n if (!registry || !provider) return;\n return registry.register(provider);\n }, [registry, provider]);\n}\n","import { useEffect, useState } from \"react\";\nimport { connectToolBridge, type ConnectToolBridgeOptions, type ToolBridgeConnection, type ToolBridgeStatus, type ToolRegistry } from \"@pixerate/editor/tools\";\n\nexport interface UseToolBridgeResult {\n status: ToolBridgeStatus | \"off\";\n /** Why the last connection ended (e.g. \"Bad token\"), when the bridge said. */\n detail?: string;\n /** The id the bridge gave this editor (`list_editors`). */\n editorId: string | null;\n}\n\n/**\n * Connects a `ToolRegistry` to a local MCP bridge (`pixerate-mcp-bridge`) while mounted, so an\n * MCP client can call the page's tools. Pass `null` options to stay disconnected. Memoize the\n * options: changing `url`, `token` or `name` reconnects.\n */\nexport function useToolBridge(registry: ToolRegistry | null | undefined, options: ConnectToolBridgeOptions | null): UseToolBridgeResult {\n const [state, setState] = useState<UseToolBridgeResult>({ status: \"off\", editorId: null });\n const key = options ? JSON.stringify([options.url, options.token, options.name, options.kind, options.reconnect]) : null;\n useEffect(() => {\n if (!registry || !options) {\n setState({ status: \"off\", editorId: null });\n return;\n }\n let connection: ToolBridgeConnection | undefined;\n connection = connectToolBridge(registry, {\n ...options,\n onStatus: (status, detail) => {\n setState({ status, detail, editorId: connection?.editorId ?? null });\n options.onStatus?.(status, detail);\n },\n });\n setState({ status: connection.status, editorId: null });\n return () => connection?.close();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [registry, key]);\n return state;\n}\n","import React from \"react\";\nimport {\n EditorContent as TipTapEditorContent,\n EditorContentProps as TipTapEditorContentProps,\n} from \"@tiptap/react\";\n\nexport interface EditorContentProps extends TipTapEditorContentProps {\n className?: string;\n}\n\nexport const EditorContent: React.FC<EditorContentProps> = ({\n className,\n editor,\n ...props\n}) => {\n return (\n <div className={className}>\n <TipTapEditorContent editor={editor} {...props} />\n </div>\n );\n};\n","import React, { useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n BubbleMenuPlugin,\n type BubbleMenuPluginProps,\n} from \"@tiptap/extension-bubble-menu\";\nimport type { Editor } from \"@tiptap/core\";\n\nexport interface BubbleMenuProps {\n editor: Editor | null;\n className?: string;\n children: React.ReactNode;\n tippyOptions?: BubbleMenuPluginProps[\"tippyOptions\"];\n shouldShow?: BubbleMenuPluginProps[\"shouldShow\"];\n pluginKey?: BubbleMenuPluginProps[\"pluginKey\"];\n updateDelay?: BubbleMenuPluginProps[\"updateDelay\"];\n}\n\nexport const BubbleMenu: React.FC<BubbleMenuProps> = ({\n editor,\n className = \"flex items-center gap-1 bg-popover text-popover-foreground border shadow-md rounded-md p-1\",\n children,\n tippyOptions = { duration: 100 },\n shouldShow = null,\n pluginKey = \"bubbleMenu\",\n updateDelay,\n}) => {\n const menuEl = useRef<HTMLDivElement | null>(null);\n const [mounted, setMounted] = useState(false);\n\n if (!menuEl.current && typeof document !== \"undefined\") {\n menuEl.current = document.createElement(\"div\");\n }\n\n useEffect(() => {\n if (!editor || !menuEl.current || editor.isDestroyed) {\n return;\n }\n\n const element = menuEl.current;\n element.className = className;\n\n const plugin = BubbleMenuPlugin({\n editor,\n element,\n pluginKey,\n tippyOptions,\n shouldShow,\n updateDelay,\n });\n\n editor.registerPlugin(plugin);\n setMounted(true);\n\n return () => {\n setMounted(false);\n editor.unregisterPlugin(pluginKey);\n if (element.parentNode) {\n element.parentNode.removeChild(element);\n }\n };\n }, [editor, className, pluginKey]);\n\n if (!editor || !menuEl.current || !mounted) {\n return null;\n }\n\n return createPortal(children, menuEl.current);\n};\n","import React, { useMemo } from \"react\";\nimport {\n describeConditionalTag,\n evaluatePromptTokens,\n formatConditionalTag,\n resolveTemplates,\n Template,\n ColorGradient,\n PromptValues,\n} from \"@pixerate/editor\";\n\nexport interface TemplateRendererProps {\n /** Raw prompt or text string to render */\n content: string;\n /** Available templates for recursive resolution and custom coloring */\n templates?: Template[];\n /** Custom gradient color map for templates */\n templateColorMap?: Map<string, ColorGradient>;\n /** Whether to resolve nested templates recursively before displaying */\n resolve?: boolean;\n /** Template version bindings used when `resolve` is set */\n bindings?: Record<string, string>;\n /**\n * Variable values. When set, variables show their value (or default),\n * sections whose condition fails are hidden, and section tags are dropped.\n */\n values?: PromptValues;\n /** Custom class name for the wrapper */\n className?: string;\n /** Click callback for template badges */\n onTemplateClick?: (templateName: string) => void;\n /** Click callback for variable badges */\n onVariableClick?: (variableName: string) => void;\n}\n\n\nexport const TemplateRenderer: React.FC<TemplateRendererProps> = ({\n content,\n templates = [],\n templateColorMap,\n resolve = false,\n bindings,\n values,\n className = \"font-mono text-sm leading-relaxed whitespace-pre-wrap break-words\",\n onTemplateClick,\n onVariableClick,\n}) => {\n const displayText = useMemo(() => {\n if (!resolve || templates.length === 0) return content;\n return resolveTemplates(content, templates, { bindings });\n }, [content, templates, resolve, bindings]);\n\n const tokens = useMemo(() => {\n return evaluatePromptTokens(displayText, values);\n }, [displayText, values]);\n\n return (\n <div className={className}>\n {tokens.map((token, index) => {\n if (token.type === \"template\") {\n const colors = templateColorMap?.get(token.value) || {\n from: \"#f43f5e\",\n to: \"#8b5cf6\",\n };\n const style = {\n \"--color-from\": colors.from,\n \"--color-to\": colors.to,\n } as React.CSSProperties;\n\n return (\n <span\n key={index}\n style={style}\n onClick={() => onTemplateClick?.(token.value)}\n className=\"inline-flex items-center px-1.5 py-0.5 mx-0.5 text-xs font-semibold rounded-md border border-[var(--color-to)]/40 bg-gradient-to-r from-[var(--color-from)]/15 to-[var(--color-to)]/15 text-[var(--color-to)] hover:brightness-110 cursor-pointer transition-all\"\n title={`Template: ${token.value}`}\n >\n {`{{${token.value}}}`}\n </span>\n );\n }\n\n if (token.type === \"variable\") {\n const details = [\n `Variable: ${token.value}`,\n token.description,\n token.defaultValue !== undefined\n ? `Default: ${token.defaultValue || \"(empty)\"}`\n : undefined,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n if (token.resolvedValue !== undefined) {\n return (\n <span\n key={index}\n onClick={() => onVariableClick?.(token.value)}\n data-variable={token.value}\n data-value-source={token.valueSource}\n className={\n token.valueSource === \"value\"\n ? \"inline px-1 mx-0.5 rounded-md bg-emerald-400/15 text-emerald-700 dark:text-emerald-300 border-b border-emerald-400/60 cursor-pointer\"\n : \"inline px-1 mx-0.5 rounded-md bg-violet-400/10 text-violet-600 dark:text-violet-300 italic border-b border-dashed border-violet-400/60 cursor-pointer\"\n }\n title={details}\n >\n {token.resolvedValue}\n </span>\n );\n }\n\n return (\n <span\n key={index}\n onClick={() => onVariableClick?.(token.value)}\n data-variable={token.value}\n className=\"inline-flex items-center px-1.5 py-0.5 mx-0.5 text-xs font-medium rounded-md border border-violet-400/40 bg-violet-400/15 text-violet-600 dark:text-violet-300 hover:brightness-110 cursor-pointer transition-all\"\n title={details}\n >\n {`{${token.value}`}\n {token.defaultValue !== undefined && (\n <span className=\"opacity-60\">{`|${token.defaultValue}`}</span>\n )}\n {\"}\"}\n </span>\n );\n }\n\n if (token.type === \"conditional\" && token.conditional) {\n return (\n <span\n key={index}\n data-conditional={token.conditional}\n className=\"inline-flex items-center px-1 py-0.5 mx-0.5 text-xs font-medium rounded-md border border-amber-400/40 bg-amber-400/15 text-amber-700 dark:text-amber-300\"\n title={describeConditionalTag(token)}\n >\n {formatConditionalTag(token)}\n </span>\n );\n }\n\n if (token.type === \"instruction\") {\n return (\n <span\n key={index}\n className=\"inline-flex items-center px-1.5 py-0.5 mx-0.5 text-xs italic font-medium rounded-md border border-rose-400/40 bg-rose-400/15 text-rose-600 dark:text-rose-300\"\n title={`Instruction: ${token.value}`}\n >\n {`__${token.value}__`}\n </span>\n );\n }\n\n return <span key={index}>{token.value}</span>;\n })}\n </div>\n );\n};\n","import React, { useId, useMemo, useState } from \"react\";\nimport {\n compactVariableValues,\n getVariableFormFields,\n PromptValues,\n Template,\n VariableFormField,\n} from \"@pixerate/editor\";\n\nexport interface VariableFormProps {\n /** Prompt whose variables become form fields */\n content: string;\n /** Templates searched recursively for further variables */\n templates?: Template[];\n /** Template version bindings */\n bindings?: Record<string, string>;\n /** Entered text per variable (controlled). Omit to let the form keep its own state. */\n values?: Record<string, string>;\n /** Initial entered text when uncontrolled */\n defaultValues?: Record<string, string>;\n /**\n * Called on every edit with the values to resolve with (blank fields\n * dropped so defaults apply) and the raw entered text.\n */\n onChange?: (values: PromptValues, entered: Record<string, string>) => void;\n /** Custom class name for the wrapper */\n className?: string;\n}\n\n/**\n * Renders one input per prompt variable: labelled with its description,\n * using its default as the placeholder. Variables only used by `{?name}`\n * conditions render as checkboxes.\n */\nexport const VariableForm: React.FC<VariableFormProps> = ({\n content,\n templates,\n bindings,\n values,\n defaultValues,\n onChange,\n className = \"flex flex-col gap-3 text-sm\",\n}) => {\n const idPrefix = useId();\n const [internal, setInternal] = useState<Record<string, string>>(\n () => defaultValues ?? {},\n );\n const entered = values ?? internal;\n\n const fields = useMemo<VariableFormField[]>(\n () => getVariableFormFields(content, { templates, bindings }),\n [content, templates, bindings],\n );\n\n const update = (name: string, value: string) => {\n const next = { ...entered, [name]: value };\n if (values === undefined) setInternal(next);\n onChange?.(compactVariableValues(next), next);\n };\n\n if (fields.length === 0) return null;\n\n return (\n <form className={className} onSubmit={(event) => event.preventDefault()}>\n {fields.map((field) => {\n const id = `${idPrefix}-${field.name}`;\n if (field.conditionOnly) {\n return (\n <label\n key={field.name}\n htmlFor={id}\n className=\"flex items-center gap-2\"\n data-variable-field={field.name}\n >\n <input\n id={id}\n name={field.name}\n type=\"checkbox\"\n checked={(entered[field.name] ?? \"\") !== \"\"}\n onChange={(event) =>\n update(field.name, event.target.checked ? \"true\" : \"\")\n }\n />\n <span>{field.label}</span>\n </label>\n );\n }\n return (\n <label\n key={field.name}\n htmlFor={id}\n className=\"flex flex-col gap-1\"\n data-variable-field={field.name}\n >\n <span className=\"font-medium\">\n {field.label}\n {field.required && (\n <span className=\"text-rose-500\" aria-hidden=\"true\">\n {\" *\"}\n </span>\n )}\n </span>\n <input\n id={id}\n name={field.name}\n type=\"text\"\n value={entered[field.name] ?? \"\"}\n placeholder={field.placeholder}\n aria-required={field.required || undefined}\n onChange={(event) => update(field.name, event.target.value)}\n className=\"px-2 py-1 rounded-md border border-violet-400/40 bg-transparent\"\n />\n </label>\n );\n })}\n </form>\n );\n};\n","import React, { useId, useState } from \"react\";\nimport type {\n ColorGradient,\n MergeRecordsOptions,\n MergeRecordsResult,\n ParseDataSourceOptions,\n Template,\n} from \"@pixerate/editor\";\nimport { TemplateRenderer } from \"./TemplateRenderer\";\nimport { useMergePreview } from \"../hooks/useMergePreview\";\n\nexport interface MergePreviewProps {\n /** The prompt merged with each record. */\n content: string;\n templates?: Template[];\n bindings?: Record<string, string>;\n templateColorMap?: Map<string, ColorGradient>;\n /** Initial CSV / TSV / JSON data source text. */\n defaultSource?: string;\n parseOptions?: ParseDataSourceOptions;\n /** Drop records matching this condition (e.g. `\"status=void\"`) when merging. */\n skipIf?: MergeRecordsOptions[\"skipIf\"];\n /** Separator between merged outputs (default a blank line; `\"none\"` for nothing). */\n separator?: string;\n maxOutputs?: number;\n /** Called after \"Merge all\". */\n onMerge?: (result: MergeRecordsResult) => void;\n /** Base file name for downloads (default `merged`). */\n downloadName?: string;\n className?: string;\n}\n\n/** Saves text as a file through a temporary link. */\nfunction downloadText(text: string, fileName: string, type: string): void {\n if (typeof document === \"undefined\" || typeof URL.createObjectURL !== \"function\") {\n return;\n }\n const url = URL.createObjectURL(new Blob([text], { type }));\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = fileName;\n link.click();\n setTimeout(() => URL.revokeObjectURL(url), 0);\n}\n\n/**\n * Mail-merge preview: paste or pick a CSV / JSON data source, check the\n * automatic field mapping, step through records with the resolved prompt\n * shown by `TemplateRenderer`, and merge every record into text or JSON.\n */\nexport const MergePreview: React.FC<MergePreviewProps> = ({\n content,\n templates,\n bindings,\n templateColorMap,\n defaultSource,\n parseOptions,\n skipIf,\n separator,\n maxOutputs,\n onMerge,\n downloadName = \"merged\",\n className = \"flex flex-col gap-3 text-sm\",\n}) => {\n const id = useId();\n const merge = useMergePreview({\n template: content,\n templates,\n bindings,\n initialSource: defaultSource,\n parseOptions,\n skipIf,\n separator,\n maxOutputs,\n });\n const [copied, setCopied] = useState(false);\n const { source, result } = merge;\n\n const copy = async () => {\n try {\n await navigator.clipboard.writeText(merge.serialize(\"text\"));\n setCopied(true);\n } catch {\n setCopied(false);\n }\n };\n\n return (\n <div className={className} data-merge-preview=\"\">\n <label htmlFor={`${id}-source`} className=\"flex flex-col gap-1\">\n <span className=\"font-medium\">Data source (CSV, TSV or JSON)</span>\n <textarea\n id={`${id}-source`}\n data-merge-source=\"\"\n value={merge.sourceText}\n rows={5}\n spellCheck={false}\n onChange={(event) => merge.setSourceText(event.target.value)}\n className=\"px-2 py-1 font-mono text-xs rounded-md border border-violet-400/40 bg-transparent\"\n />\n </label>\n <div className=\"flex flex-wrap items-center gap-2\">\n <input\n type=\"file\"\n accept=\".csv,.tsv,.txt,.json,text/csv,application/json\"\n aria-label=\"Load data source file\"\n data-merge-file=\"\"\n onChange={(event) => {\n const file = event.target.files?.[0];\n if (file) void merge.loadFile(file);\n }}\n />\n <span data-merge-summary=\"\" className=\"opacity-70\">\n {`${source.records.length} record${source.records.length === 1 ? \"\" : \"s\"} · ${source.fields.length} field${source.fields.length === 1 ? \"\" : \"s\"}`}\n </span>\n </div>\n {source.warnings.length > 0 && merge.sourceText.trim() !== \"\" && (\n <ul data-merge-warnings=\"\" className=\"text-amber-600 text-xs\">\n {source.warnings.map((warning, i) => (\n <li key={i}>{warning.message}</li>\n ))}\n </ul>\n )}\n\n {merge.variables.length > 0 && (\n <fieldset className=\"flex flex-col gap-1\">\n <legend className=\"font-medium\">Field mapping</legend>\n {merge.variables.map((variable) => (\n <label\n key={variable}\n className=\"flex items-center gap-2\"\n data-merge-mapping={variable}\n >\n <span className=\"min-w-24 font-mono\">{`{${variable}}`}</span>\n <select\n value={merge.mapping[variable] ?? \"\"}\n aria-label={`Field for ${variable}`}\n onChange={(event) =>\n merge.setFieldMapping(variable, event.target.value || null)\n }\n className=\"px-1 py-0.5 rounded-md border border-violet-400/40 bg-transparent\"\n >\n <option value=\"\">(none)</option>\n {source.fields.map((field) => (\n <option key={field} value={field}>\n {field}\n </option>\n ))}\n </select>\n </label>\n ))}\n </fieldset>\n )}\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n data-merge-prev=\"\"\n onClick={merge.prev}\n disabled={merge.index <= 0}\n >\n Prev\n </button>\n <span data-merge-position=\"\">\n {merge.count === 0\n ? \"No records\"\n : `Record ${merge.index + 1} of ${merge.count}`}\n </span>\n <button\n type=\"button\"\n data-merge-next=\"\"\n onClick={merge.next}\n disabled={merge.index >= merge.count - 1}\n >\n Next\n </button>\n </div>\n\n <div data-merge-output=\"\">\n <TemplateRenderer\n content={content}\n templates={templates}\n bindings={bindings}\n templateColorMap={templateColorMap}\n resolve={!!templates && templates.length > 0}\n values={merge.values}\n />\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n data-merge-all=\"\"\n disabled={merge.count === 0}\n onClick={() => {\n const merged = merge.merge();\n setCopied(false);\n onMerge?.(merged);\n }}\n >\n Merge all\n </button>\n {result && (\n <>\n <span data-merge-result=\"\">\n {`${result.outputs.length} merged${result.skipped.length ? `, ${result.skipped.length} skipped` : \"\"}${result.truncated ? \" (stopped early)\" : \"\"}`}\n </span>\n <button type=\"button\" data-merge-copy=\"\" onClick={copy}>\n {copied ? \"Copied\" : \"Copy\"}\n </button>\n <button\n type=\"button\"\n data-merge-download=\"text\"\n onClick={() => downloadText(merge.serialize(\"text\"), `${downloadName}.txt`, \"text/plain\")}\n >\n Download .txt\n </button>\n <button\n type=\"button\"\n data-merge-download=\"json\"\n onClick={() =>\n downloadText(merge.serialize(\"json\"), `${downloadName}.json`, \"application/json\")\n }\n >\n Download .json\n </button>\n </>\n )}\n </div>\n {result && (\n <textarea\n readOnly\n aria-label=\"Merged output\"\n data-merge-text=\"\"\n rows={6}\n value={merge.serialize(\"text\")}\n className=\"px-2 py-1 font-mono text-xs rounded-md border border-violet-400/40 bg-transparent\"\n />\n )}\n </div>\n );\n};\n","import { useCallback, useMemo, useState } from \"react\";\nimport {\n extractVariables,\n matchFields,\n mergeRecords,\n parseDataSource,\n recordToValues,\n serializeMergeOutputs,\n type MergeDataSource,\n type MergeRecord,\n type MergeRecordsOptions,\n type MergeRecordsResult,\n type ParseDataSourceOptions,\n type PromptValues,\n type Template,\n} from \"@pixerate/editor\";\n\nexport interface UseMergePreviewOptions {\n /** The prompt merged with each record. */\n template: string;\n templates?: Template[];\n bindings?: Record<string, string>;\n /** Initial CSV / TSV / JSON text. */\n initialSource?: string;\n /** How to read the data source text. */\n parseOptions?: ParseDataSourceOptions;\n /** Passed to `mergeRecords` by `merge()`. */\n skipIf?: MergeRecordsOptions[\"skipIf\"];\n separator?: string;\n maxOutputs?: number;\n}\n\nexport interface MergePreviewState {\n sourceText: string;\n setSourceText: (text: string) => void;\n /** Reads a picked file (CSV, TSV or JSON) into `sourceText`. */\n loadFile: (file: Blob) => Promise<void>;\n source: MergeDataSource;\n /** Variable names the template uses, in order. */\n variables: string[];\n /** Variable → field: automatic matches with the user's overrides applied. */\n mapping: Record<string, string | null>;\n setFieldMapping: (variable: string, field: string | null) => void;\n resetMapping: () => void;\n /** 0-based index of the previewed record. */\n index: number;\n count: number;\n setIndex: (index: number) => void;\n next: () => void;\n prev: () => void;\n record: MergeRecord | undefined;\n /** Prompt values for the previewed record. */\n values: PromptValues;\n /** Merges every record with the current mapping and stores the result. */\n merge: () => MergeRecordsResult;\n result: MergeRecordsResult | null;\n /** The last merge's outputs as text or JSON. */\n serialize: (format: \"text\" | \"json\") => string;\n}\n\n/**\n * Headless state for a mail-merge preview (the counterpart of Svelte's\n * `createMergePreview`): parses a pasted or loaded data source, matches its\n * fields to the template's variables (editable), steps through records and\n * merges them all with `mergeRecords`.\n */\nexport function useMergePreview(options: UseMergePreviewOptions): MergePreviewState {\n const { template, templates, bindings, parseOptions } = options;\n const [sourceText, setSourceTextState] = useState(options.initialSource ?? \"\");\n const [overrides, setOverrides] = useState<Record<string, string | null>>({});\n const [index, setIndexState] = useState(0);\n const [result, setResult] = useState<MergeRecordsResult | null>(null);\n\n const source = useMemo(\n () => parseDataSource(sourceText, parseOptions),\n [sourceText, parseOptions],\n );\n const variables = useMemo(\n () => extractVariables(template, { templates, bindings }).map((v) => v.name),\n [template, templates, bindings],\n );\n const mapping = useMemo(() => {\n const merged: Record<string, string | null> = {\n ...matchFields(variables, source.fields).mapping,\n };\n for (const [variable, field] of Object.entries(overrides)) {\n if (variables.includes(variable) && (field === null || source.fields.includes(field))) {\n merged[variable] = field;\n }\n }\n return merged;\n }, [variables, source.fields, overrides]);\n\n const count = source.records.length;\n const current = count === 0 ? 0 : Math.min(index, count - 1);\n const record = source.records[current];\n const values = useMemo(\n () => (record ? recordToValues(record, mapping) : {}),\n [record, mapping],\n );\n\n const setSourceText = useCallback((text: string) => {\n setSourceTextState(text);\n setIndexState(0);\n setResult(null);\n }, []);\n const loadFile = useCallback(\n async (file: Blob) => setSourceText(await file.text()),\n [setSourceText],\n );\n const setIndex = useCallback(\n (next: number) => setIndexState(Math.max(0, Math.min(next, count - 1))),\n [count],\n );\n const setFieldMapping = useCallback((variable: string, field: string | null) => {\n setOverrides((previous) => ({ ...previous, [variable]: field }));\n setResult(null);\n }, []);\n const resetMapping = useCallback(() => setOverrides({}), []);\n\n const merge = useCallback(() => {\n const merged = mergeRecords(template, source, {\n templates,\n bindings,\n mapping,\n skipIf: options.skipIf,\n separator: options.separator,\n maxOutputs: options.maxOutputs,\n });\n setResult(merged);\n return merged;\n }, [template, source, templates, bindings, mapping, options.skipIf, options.separator, options.maxOutputs]);\n\n const serialize = useCallback(\n (format: \"text\" | \"json\") =>\n result ? serializeMergeOutputs(result.outputs, format, options.separator) : \"\",\n [result, options.separator],\n );\n\n return {\n sourceText,\n setSourceText,\n loadFile,\n source,\n variables,\n mapping,\n setFieldMapping,\n resetMapping,\n index: current,\n count,\n setIndex,\n next: () => setIndex(current + 1),\n prev: () => setIndex(current - 1),\n record,\n values,\n merge,\n result,\n serialize,\n };\n}\n","import { useMemo, useSyncExternalStore } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { createOutlineStore, type OutlineSnapshot } from \"@pixerate/editor\";\n\nexport type { OutlineHeading, OutlineSnapshot, OutlineTreeItem } from \"@pixerate/editor\";\n\n/**\n * Subscribes to an editor's heading outline. Returns the headings (flat and\n * nested) and the id of the heading whose section contains the selection.\n * Re-renders only when the outline or the active heading changes.\n *\n * Install the `Outline` extension (`richTextOptions: { outline: true }`) for\n * stable heading ids; without it, headings are still listed.\n */\nexport function useOutline(editor: Editor | null | undefined): OutlineSnapshot {\n // The store only listens to the editor while subscribed, so it needs no\n // explicit cleanup (and survives StrictMode's double effects).\n const store = useMemo(() => createOutlineStore(editor), [editor]);\n return useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n}\n","import React from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { navigateToHeading, type OutlineHeading } from \"@pixerate/editor\";\nimport { useOutline } from \"../hooks/useOutline\";\n\nexport interface OutlinePanelProps {\n editor: Editor | null;\n /** Heading shown above the list. Pass `null` to hide it. */\n title?: React.ReactNode;\n /** Content shown when the document has no headings. */\n emptyState?: React.ReactNode;\n /** Deepest heading level listed. Defaults to 6. */\n maxLevel?: number;\n /** Whether clicking an entry focuses the editor. Defaults to `true`. */\n focusOnNavigate?: boolean;\n /** Custom class name for the wrapper. */\n className?: string;\n /** Class name for each entry button. */\n itemClassName?: string;\n /** Class name added to the entry of the section containing the selection. */\n activeItemClassName?: string;\n /** Called after navigating to a heading. */\n onNavigate?: (heading: OutlineHeading) => void;\n}\n\n/**\n * Navigation sidebar listing the document's headings (Word's Navigation pane).\n * Clicking an entry moves the caret to that heading; the entry for the\n * section containing the selection is highlighted.\n */\nexport const OutlinePanel: React.FC<OutlinePanelProps> = ({\n editor,\n title = \"Outline\",\n emptyState = \"Add headings to see the outline.\",\n maxLevel = 6,\n focusOnNavigate = true,\n className = \"flex flex-col gap-1 text-sm\",\n itemClassName = \"w-full truncate rounded px-2 py-1 text-left hover:bg-black/5\",\n activeItemClassName = \"font-semibold bg-black/5\",\n onNavigate,\n}) => {\n const { headings, activeId } = useOutline(editor);\n const visible = headings.filter((h) => h.level <= maxLevel);\n\n return (\n <nav className={className} aria-label=\"Document outline\" data-outline-panel=\"\">\n {title != null && <div className=\"pixerate-outline-title\">{title}</div>}\n {visible.length === 0 ? (\n <div className=\"pixerate-outline-empty\">{emptyState}</div>\n ) : (\n <ul role=\"list\" style={{ listStyle: \"none\", margin: 0, padding: 0 }}>\n {visible.map((heading) => {\n const active = heading.id === activeId;\n return (\n <li key={heading.id} data-level={heading.level}>\n <button\n type=\"button\"\n className={active ? `${itemClassName} ${activeItemClassName}` : itemClassName}\n style={{ paddingLeft: `${0.5 + heading.depth * 0.75}rem` }}\n aria-current={active ? \"location\" : undefined}\n data-heading-id={heading.id}\n onClick={() => {\n if (!editor) return;\n if (navigateToHeading(editor, heading, { focus: focusOnNavigate })) {\n onNavigate?.(heading);\n }\n }}\n >\n {heading.text || \"Untitled\"}\n </button>\n </li>\n );\n })}\n </ul>\n )}\n </nav>\n );\n};\n","import { useMemo, useSyncExternalStore } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n createParagraphStylesStore,\n getStyleRegistry,\n type CreateStyleFromSelectionOptions,\n type ParagraphStylesSnapshot,\n type StyleDefinition,\n type StyleRegistry,\n} from \"@pixerate/editor\";\n\nexport type { ParagraphStylesSnapshot, StyleDefinition } from \"@pixerate/editor\";\n\nexport interface UseParagraphStylesResult extends ParagraphStylesSnapshot {\n registry: StyleRegistry | null;\n /** The style of the block at the selection. */\n currentStyle: StyleDefinition | null;\n /** Applies a paragraph style to the selected blocks. */\n apply: (id: string) => boolean;\n /** Resets the selected blocks to Normal. */\n clear: () => boolean;\n /** Updates a style (default: the current one) to the formatting at the selection. */\n updateFromSelection: (id?: string) => boolean;\n /** Creates (and applies) a style from the formatting at the selection; returns its id. */\n createFromSelection: (name: string, options?: CreateStyleFromSelectionOptions) => string | null;\n /** Applies a character style to the selection. */\n applyCharacterStyle: (id: string) => boolean;\n}\n\n/**\n * Subscribes to an editor's paragraph styles (`ParagraphStyles` extension):\n * the gallery, all styles and the style at the selection, with commands.\n * Re-renders only when the styles or the current style change.\n */\nexport function useParagraphStyles(editor: Editor | null | undefined): UseParagraphStylesResult {\n // The store only listens to the editor while subscribed (StrictMode-safe).\n const store = useMemo(() => createParagraphStylesStore(editor), [editor]);\n const snapshot = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n\n return useMemo(() => {\n const registry = getStyleRegistry(editor);\n const live = () => (editor && !editor.isDestroyed ? editor : null);\n return {\n ...snapshot,\n registry,\n currentStyle: (snapshot.currentStyleId && registry?.get(snapshot.currentStyleId)) || null,\n apply: (id) => !!live()?.chain().focus().setParagraphStyle(id).run(),\n clear: () => !!live()?.chain().focus().clearParagraphStyle().run(),\n updateFromSelection: (id) => !!live()?.chain().focus().updateParagraphStyleFromSelection(id).run(),\n createFromSelection: (name, options) => {\n const e = live();\n if (!e || !registry) return null;\n const id = options?.id ?? registry.newId(name.trim());\n const ok = e.chain().focus().createParagraphStyleFromSelection(name, { ...options, id }).run();\n return ok ? id : null;\n },\n applyCharacterStyle: (id) => !!live()?.chain().focus().setCharacterStyle(id).run(),\n };\n }, [snapshot, editor]);\n}\n","import React, { useState } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { useParagraphStyles } from \"../hooks/useParagraphStyles\";\n\nexport interface StylesGalleryProps {\n editor: Editor | null;\n /**\n * `dropdown` (default): a button showing the current style that opens the\n * list. `gallery`: the styles are always shown, in a row.\n */\n variant?: \"dropdown\" | \"gallery\";\n /** List every available paragraph style instead of the gallery (quick) styles. */\n showAllStyles?: boolean;\n /** Show the \"Update to match selection\" and \"New style from selection\" actions. Defaults to `true`. */\n showActions?: boolean;\n /** Preview each style's font, weight, style and color in its entry. Defaults to `true`. */\n preview?: boolean;\n className?: string;\n itemClassName?: string;\n activeItemClassName?: string;\n /** Called after a style is applied, updated or created. */\n onChange?: (event: { type: \"apply\" | \"update\" | \"create\"; id: string }) => void;\n}\n\nconst camel = (property: string) => property.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase());\n\nconst keepSelection = (event: React.MouseEvent) => event.preventDefault();\n\n/**\n * Paragraph styles picker (Word's Styles gallery): shows the style at the\n * selection, applies a style on click, updates the current style to match\n * the selection and creates a new style from the selection. Needs the\n * `ParagraphStyles` extension (`richTextOptions: { paragraphStyles: true }`).\n */\nexport const StylesGallery: React.FC<StylesGalleryProps> = ({\n editor,\n variant = \"dropdown\",\n showAllStyles = false,\n showActions = true,\n preview = true,\n className = \"relative inline-flex flex-wrap items-center gap-1 text-sm\",\n itemClassName = \"rounded px-2 py-1 text-left text-xs text-foreground hover:bg-muted\",\n activeItemClassName = \"bg-primary/10 text-primary\",\n onChange,\n}) => {\n const styles = useParagraphStyles(editor);\n const [open, setOpen] = useState(false);\n const [creating, setCreating] = useState(false);\n const [name, setName] = useState(\"\");\n const list = showAllStyles ? styles.styles : styles.gallery;\n const current = styles.currentStyle;\n const expanded = variant === \"gallery\" || open;\n const close = () => {\n if (variant === \"dropdown\") setOpen(false);\n setCreating(false);\n setName(\"\");\n };\n\n const previewStyle = (id: string): React.CSSProperties | undefined => {\n if (!preview || !styles.registry) return undefined;\n return Object.fromEntries(\n Object.entries(styles.registry.previewDeclarations(id)).map(([k, v]) => [camel(k), v]),\n ) as React.CSSProperties;\n };\n\n const apply = (id: string) => {\n if (styles.apply(id)) onChange?.({ type: \"apply\", id });\n close();\n };\n\n const create = (event: React.FormEvent) => {\n event.preventDefault();\n const id = name.trim() ? styles.createFromSelection(name) : null;\n if (id) onChange?.({ type: \"create\", id });\n close();\n };\n\n return (\n <div className={className} role=\"group\" aria-label=\"Paragraph styles\" data-styles-gallery={variant}>\n {variant === \"dropdown\" && (\n <button\n type=\"button\"\n className={itemClassName}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n disabled={!editor || !styles.registry}\n onMouseDown={keepSelection}\n onClick={() => setOpen((value) => !value)}\n >\n {current?.name ?? \"Styles\"} ▾\n </button>\n )}\n {expanded && (\n <div\n className={\n variant === \"dropdown\"\n ? \"absolute left-0 top-full z-20 mt-1 flex min-w-[12rem] flex-col gap-0.5 rounded-md border border-border bg-background p-1 shadow-md\"\n : \"flex flex-wrap items-center gap-1\"\n }\n >\n <div role=\"listbox\" aria-label=\"Styles\" className={variant === \"dropdown\" ? \"flex flex-col gap-0.5\" : \"flex flex-wrap gap-1\"}>\n {list.map((style) => {\n const active = style.id === styles.currentStyleId;\n return (\n <button\n key={style.id}\n type=\"button\"\n role=\"option\"\n aria-selected={active}\n data-style-id={style.id}\n className={active ? `${itemClassName} ${activeItemClassName}` : itemClassName}\n style={previewStyle(style.id)}\n onMouseDown={keepSelection}\n onClick={() => apply(style.id)}\n >\n {style.name}\n </button>\n );\n })}\n </div>\n {showActions && (\n <div className={variant === \"dropdown\" ? \"mt-1 flex flex-col gap-0.5 border-t border-border pt-1\" : \"flex items-center gap-1\"}>\n <button\n type=\"button\"\n className={itemClassName}\n disabled={!current}\n onMouseDown={keepSelection}\n onClick={() => {\n if (current && styles.updateFromSelection(current.id)) {\n onChange?.({ type: \"update\", id: current.id });\n }\n close();\n }}\n >\n {current ? `Update ${current.name} to match selection` : \"Update to match selection\"}\n </button>\n {creating ? (\n <form className=\"flex items-center gap-1\" onSubmit={create}>\n <input\n aria-label=\"New style name\"\n className=\"w-32 rounded border border-border bg-background px-1 py-0.5 text-xs\"\n value={name}\n autoFocus\n onChange={(event) => setName(event.target.value)}\n />\n <button type=\"submit\" className={itemClassName} disabled={!name.trim()}>\n Create\n </button>\n </form>\n ) : (\n <button\n type=\"button\"\n className={itemClassName}\n disabled={!editor || !styles.registry}\n onMouseDown={keepSelection}\n onClick={() => setCreating(true)}\n >\n New style from selection\n </button>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n );\n};\n","import { useState, useRef, useCallback, useMemo } from 'react';\nimport {\n SpreadsheetController,\n bindSpreadsheetTableActions,\n type SpreadsheetControllerOptions,\n type SpreadsheetDocument,\n type CellCoordinate,\n type CellRange,\n type SpreadsheetColumn,\n type SpreadsheetRow,\n type SpreadsheetDataSource,\n type SpreadsheetDocument as SheetDocument,\n type SpreadsheetNameScope,\n type SpreadsheetCommitResult,\n type SpreadsheetValidationAction,\n type SpreadsheetValidationPrompt\n} from '@pixerate/editor/spreadsheet';\n\nexport function useSpreadsheetEditor(options: SpreadsheetControllerOptions = {}) {\n // Callbacks are read through a ref so they are never stale.\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const settersRef = useRef<{\n setDoc?: (doc: SpreadsheetDocument) => void;\n setActiveCell?: (cell: CellCoordinate | null) => void;\n setSelectedRange?: (range: CellRange | null) => void;\n }>({});\n\n // Create the controller first so the initial state reflects its document\n // (including default rows and columns when no document is passed).\n const [controller] = useState(\n () =>\n new SpreadsheetController({\n ...options,\n onDocumentChange: (updated) => {\n settersRef.current.setDoc?.({ ...updated });\n optionsRef.current.onDocumentChange?.(updated);\n },\n onSelectionChange: (active, range) => {\n settersRef.current.setActiveCell?.(active);\n settersRef.current.setSelectedRange?.(range);\n optionsRef.current.onSelectionChange?.(active, range);\n },\n onCellCommit: (rowId, colId, raw, value) => {\n optionsRef.current.onCellCommit?.(rowId, colId, raw, value);\n },\n }),\n );\n\n const [doc, setDoc] = useState<SpreadsheetDocument>(() => ({ ...controller.document }));\n const [activeCell, setActiveCell] = useState<CellCoordinate | null>(controller.activeCell);\n const [selectedRange, setSelectedRange] = useState<CellRange | null>(controller.selectedRange);\n const [editingCell, setEditingCell] = useState<CellCoordinate | null>(null);\n const [draftValue, setDraftState] = useState<string>('');\n // Invalid input waiting for the user (data validation alert).\n const [validationPrompt, setValidationPrompt] = useState<SpreadsheetValidationPrompt | null>(null);\n settersRef.current = { setDoc, setActiveCell, setSelectedRange };\n\n // The controller commits its own `draftValue` (`commitEditing()` without an\n // argument), so typed text must reach it, not just React state.\n const setDraftValue = useCallback((value: string) => {\n controller.draftValue = value;\n setDraftState(value);\n }, [controller]);\n\n const setCellValue = useCallback((rowId: string, colId: string, raw: string) => {\n controller.setCellValue(rowId, colId, raw);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const selectCell = useCallback((row: number, col: number, extendSelection = false) => {\n controller.selectCell(row, col, extendSelection);\n setActiveCell(controller.activeCell);\n setSelectedRange(controller.selectedRange);\n }, [controller]);\n\n const selectRange = useCallback((range: CellRange) => {\n controller.selectRange(range);\n setSelectedRange(controller.selectedRange);\n }, [controller]);\n\n const startEditing = useCallback((row?: number, col?: number, initialVal?: string) => {\n controller.startEditing(row, col, initialVal);\n setActiveCell(controller.activeCell);\n setEditingCell(controller.editingCell);\n setDraftValue(controller.draftValue);\n }, [controller]);\n\n // Input breaking a data validation rule is not committed: the editor stays\n // open and `validationPrompt` holds the alert until it is resolved.\n const syncEditing = useCallback(() => {\n setEditingCell(controller.editingCell);\n setDraftValue(controller.draftValue);\n setValidationPrompt(controller.validationPrompt);\n setActiveCell(controller.activeCell);\n setSelectedRange(controller.selectedRange);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const commitEditing = useCallback((val?: string): SpreadsheetCommitResult => {\n const result = controller.commitEditing(val);\n syncEditing();\n return result;\n }, [controller, syncEditing]);\n\n /** Commits input from outside the cell editor (formula bar, list dropdown) with validation. */\n const commitCellInput = useCallback((rowId: string, colId: string, raw: string): SpreadsheetCommitResult => {\n const result = controller.commitCellInput(rowId, colId, raw);\n syncEditing();\n return result;\n }, [controller, syncEditing]);\n\n /** Answers the validation alert: accept (warning / information), retry or cancel. */\n const resolveValidationPrompt = useCallback((action: SpreadsheetValidationAction) => {\n controller.resolveValidationPrompt(action);\n syncEditing();\n }, [controller, syncEditing]);\n\n const cancelEditing = useCallback(() => {\n controller.cancelEditing();\n setEditingCell(null);\n setDraftValue('');\n }, [controller]);\n\n const moveCursor = useCallback((dir: 'up' | 'down' | 'left' | 'right', extend = false) => {\n controller.moveCursor(dir, extend);\n setActiveCell(controller.activeCell);\n setSelectedRange(controller.selectedRange);\n }, [controller]);\n\n const insertColumn = useCallback((index: number, config?: Partial<SpreadsheetColumn>) => {\n controller.insertColumn(index, config);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const deleteColumn = useCallback((colId: string) => {\n controller.deleteColumn(colId);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const insertRow = useCallback((index: number, config?: Partial<SpreadsheetRow>) => {\n controller.insertRow(index, config);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const deleteRow = useCallback((rowId: string) => {\n controller.deleteRow(rowId);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const setColumnWidth = useCallback((colId: string, width: number) => {\n controller.setColumnWidth(colId, width);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const autoFitColumnWidth = useCallback((colId: string, customWidth?: number) => {\n controller.autoFitColumnWidth(colId, customWidth);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const registerDataSource = useCallback((ds: SpreadsheetDataSource) => {\n controller.registerDataSource(ds);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const setPrimaryDataSource = useCallback((id: string | undefined) => {\n controller.setPrimaryDataSource(id);\n setDoc({ ...controller.document });\n }, [controller]);\n\n const recalculateAll = useCallback(() => {\n controller.recalculateAll();\n setDoc({ ...controller.document });\n }, [controller]);\n\n // Undo can switch to the sheet the step belongs to.\n const undo = useCallback(() => {\n controller.undo();\n setDoc({ ...controller.document });\n setActiveCell(controller.activeCell);\n setSelectedRange(controller.selectedRange);\n }, [controller]);\n\n const redo = useCallback(() => {\n controller.redo();\n setDoc({ ...controller.document });\n setActiveCell(controller.activeCell);\n setSelectedRange(controller.selectedRange);\n }, [controller]);\n\n // Table operations (sort, filters, freeze, hide, merge, autofill, categories,\n // transpose, CSV, clipboard). The controller reports their changes through\n // onDocumentChange / onSelectionChange, which update the state above.\n const tableActions = useMemo(() => bindSpreadsheetTableActions(controller), [controller]);\n // What to render: visible rows (with group headers) and columns, frozen\n // offsets and merged-cell spans. Recomputed whenever the document changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const viewModel = useMemo(() => controller.getViewModel(), [controller, doc]);\n // Sheet tabs and defined names. Every workbook change notifies through\n // onDocumentChange, so they follow `doc`.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const sheets = useMemo(() => controller.getSheets(), [controller, doc]);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const names = useMemo(() => controller.getNames(), [controller, doc]);\n\n // Switching sheets commits the edit in progress.\n const afterSheetSwitch = useCallback(() => {\n setEditingCell(controller.editingCell);\n setDraftValue(controller.draftValue);\n setActiveCell(controller.activeCell);\n setSelectedRange(controller.selectedRange);\n setDoc({ ...controller.document });\n }, [controller, setDraftValue]);\n\n const workbookActions = useMemo(\n () => ({\n setActiveSheet: (idOrName: string) => {\n const changed = controller.setActiveSheet(idOrName);\n afterSheetSwitch();\n return changed;\n },\n addSheet: (options?: { name?: string; index?: number; document?: Partial<SheetDocument>; activate?: boolean }) => {\n const id = controller.addSheet(options);\n afterSheetSwitch();\n return id;\n },\n renameSheet: (idOrName: string, newName: string) => controller.renameSheet(idOrName, newName),\n moveSheet: (idOrName: string, toIndex: number) => controller.moveSheet(idOrName, toIndex),\n deleteSheet: (idOrName: string) => {\n const deleted = controller.deleteSheet(idOrName);\n afterSheetSwitch();\n return deleted;\n },\n duplicateSheet: (idOrName: string, options?: { name?: string; index?: number; activate?: boolean }) => {\n const id = controller.duplicateSheet(idOrName, options);\n afterSheetSwitch();\n return id;\n },\n defineName: (name: string, refersTo: string, options?: SpreadsheetNameScope & { comment?: string }) =>\n controller.defineName(name, refersTo, options),\n renameName: (oldName: string, newName: string, options?: SpreadsheetNameScope) =>\n controller.renameName(oldName, newName, options),\n deleteName: (name: string, options?: SpreadsheetNameScope) => controller.deleteName(name, options),\n }),\n [controller, afterSheetSwitch],\n );\n\n // Conditional formatting of every formatted cell (re-evaluated incrementally).\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const conditionalFormatOverlay = useMemo(() => controller.getConditionalFormatOverlay(), [controller, doc]);\n\n return {\n document: doc,\n activeCell,\n selectedRange,\n editingCell,\n draftValue,\n setDraftValue,\n validationPrompt,\n resolveValidationPrompt,\n commitCellInput,\n controller,\n getCell: (rowId: string, colId: string) => controller.getCell(rowId, colId),\n setCellValue,\n selectCell,\n selectRange,\n startEditing,\n commitEditing,\n cancelEditing,\n moveCursor,\n insertColumn,\n deleteColumn,\n insertRow,\n deleteRow,\n setColumnWidth,\n autoFitColumnWidth,\n loadDocument: (document: SpreadsheetDocument) => {\n controller.loadDocument(document);\n setDoc({ ...controller.document });\n setActiveCell(null);\n setSelectedRange(null);\n setEditingCell(null);\n setDraftValue('');\n },\n syncWithDataSource: () => {\n controller.syncWithDataSource();\n controller.recalculateAll();\n setDoc({ ...controller.document });\n },\n registerDataSource,\n setPrimaryDataSource,\n recalculateAll,\n exportToTsv: (range?: CellRange | null) => controller.exportToTsv(range),\n importFromTsv: (data: string) => {\n controller.importFromTsv(data);\n setDoc({ ...controller.document });\n },\n ...tableActions,\n viewModel,\n /** The sheets in tab order (see `SpreadsheetController.getSheets`). */\n sheets,\n activeSheetId: controller.activeSheetId,\n /** Defined names (see `SpreadsheetController.getNames`). */\n names,\n ...workbookActions,\n conditionalFormatOverlay,\n undo,\n redo\n };\n}\n","import React, { useRef, useState, useMemo, useEffect, useCallback } from 'react';\nimport {\n indexToColName,\n getSpreadsheetMenuItems,\n normalizeRange,\n rangeContains,\n type SpreadsheetColumn,\n type SpreadsheetRow,\n type CellData,\n type CellRange,\n type SpreadsheetMenuItem,\n type SpreadsheetViewColumn,\n type SpreadsheetViewRow,\n formatCellForDisplay,\n numberFormatColorToCss,\n getConditionalFormatCss,\n getConditionalFormatIcon,\n getDataBarCss,\n type ConditionalCellFormat,\n type SpreadsheetPanelId\n} from '@pixerate/editor/spreadsheet';\nimport { useSpreadsheetEditor } from './useSpreadsheetEditor';\nimport { SpreadsheetContextMenu } from './SpreadsheetContextMenu';\nimport { SpreadsheetGroupRow } from './SpreadsheetGroupRow';\nimport { useFillHandle, useSpreadsheetClipboard } from './useSpreadsheetTableInteractions';\nimport { SpreadsheetValidationDialog } from './SpreadsheetValidationDialog';\nimport { SpreadsheetConditionalFormatPanel, SpreadsheetDataValidationPanel } from './SpreadsheetRulePanels';\nimport { useSpreadsheetViewport } from './useSpreadsheetViewport';\n\n// Sizes of the sticky header row and row-number column, for frozen-pane offsets.\nconst COLUMN_HEADER_HEIGHT = 28;\nconst ROW_HEADER_WIDTH = 48;\n\n/** Sticky positioning for cells in frozen rows and/or columns. */\nfunction frozenCellStyle(\n viewRow: Extract<SpreadsheetViewRow, { kind: 'row' }>,\n viewCol: SpreadsheetViewColumn\n): React.CSSProperties | undefined {\n if (!viewRow.frozen && !viewCol.frozen) return undefined;\n return {\n position: 'sticky',\n ...(viewRow.frozen ? { top: COLUMN_HEADER_HEIGHT + viewRow.stickyTop } : {}),\n ...(viewCol.frozen ? { left: ROW_HEADER_WIDTH + viewCol.stickyLeft } : {}),\n zIndex: viewRow.frozen && viewCol.frozen ? 14 : viewRow.frozen ? 12 : 11,\n background: 'var(--background, #fff)'\n };\n}\nimport { FormulaHints } from './FormulaHints';\nimport { SheetTabs } from './SheetTabs';\n\nconst coordKey = (cell: { row: number; col: number } | null) => (cell ? `${indexToColName(cell.col)}${cell.row + 1}` : '');\n\n/** Thin border drawn on the outer edges of a dynamic array's spill range. */\nfunction spillBorderStyle(range: CellRange, row: number, col: number): React.CSSProperties {\n const line = '1px solid color-mix(in srgb, var(--primary, #6366f1) 60%, transparent)';\n return {\n position: 'absolute',\n inset: 0,\n pointerEvents: 'none',\n zIndex: 5,\n borderTop: row === range.startRow ? line : undefined,\n borderBottom: row === range.endRow ? line : undefined,\n borderLeft: col === range.startCol ? line : undefined,\n borderRight: col === range.endCol ? line : undefined\n };\n}\n\n/**\n * A cell's display text: formatted with its number format, numbers\n * right-aligned, `[Red]`-style colours applied. A conditional format adds a\n * data bar and / or an icon, and its font colour wins over the format's.\n */\nfunction CellText({ cell, conditional }: { cell: CellData; conditional?: ConditionalCellFormat }) {\n const shown = formatCellForDisplay(cell);\n const color = conditional?.color ?? (shown.color ? numberFormatColorToCss(shown.color) : undefined);\n const decorated = !!conditional?.dataBar || !!conditional?.icon;\n const text = (\n <span\n className={`truncate block max-w-full ${cell.error ? 'text-destructive font-semibold' : ''}`}\n title={cell.error ? cell.errorMessage ?? cell.error : undefined}\n data-numeric={shown.numeric ? '' : undefined}\n style={\n shown.numeric || color || decorated\n ? {\n ...(decorated ? { position: 'relative' as const } : {}),\n ...(conditional?.icon ? { flex: 1, minWidth: 0 } : {}),\n ...(shown.numeric ? { textAlign: 'right' as const } : {}),\n ...(color ? { color } : {})\n }\n : undefined\n }\n >\n {conditional?.hideValue ? '' : shown.text}\n </span>\n );\n if (!conditional || !decorated) return text;\n const icon = conditional.icon ? getConditionalFormatIcon(conditional.icon.set, conditional.icon.index) : null;\n return (\n <>\n {conditional.dataBar && (\n <span aria-hidden=\"true\" className=\"spreadsheet-data-bar\" style={getDataBarCss(conditional.dataBar) as React.CSSProperties} />\n )}\n {icon ? (\n <span className=\"flex items-center gap-1 min-w-0\" style={{ position: 'relative' }}>\n <span className=\"spreadsheet-cf-icon shrink-0\" role=\"img\" aria-label={icon.label} data-icon={conditional.icon!.id} style={{ color: icon.color }}>\n {icon.glyph}\n </span>\n {text}\n </span>\n ) : (\n text\n )}\n </>\n );\n}\n\nexport interface SpreadsheetEditorProps {\n state?: ReturnType<typeof useSpreadsheetEditor>;\n readOnly?: boolean;\n customCellRenderer?: (props: { row: SpreadsheetRow; col: SpreadsheetColumn; cell: CellData }) => React.ReactNode;\n onAddColumnClick?: () => void;\n onColumnHeaderClick?: (col: SpreadsheetColumn) => void;\n onColumnResize?: (colId: string, width: number) => void;\n /** Show the sheet tabs bar under the grid (add, switch, rename, reorder, delete sheets). */\n showSheetTabs?: boolean;\n /**\n * Render only the rows and columns in (or near) view. `'auto'` (default)\n * virtualises sheets with more than 200 displayed rows or 60 columns;\n * `true` / `false` force it.\n */\n virtualize?: boolean | 'auto';\n}\n\n/** A rendered column, or the space standing for the columns left out. */\ntype ColumnSlot = { kind: 'col'; viewCol: SpreadsheetViewColumn } | { kind: 'space'; key: string; width: number };\n/** A rendered row, or the space standing for the rows left out. */\ntype RowSlot = { kind: 'row'; viewRow: SpreadsheetViewRow } | { kind: 'space'; key: string; height: number };\n\nexport const SpreadsheetEditor: React.FC<SpreadsheetEditorProps> = ({\n state: externalState,\n readOnly = false,\n customCellRenderer,\n onAddColumnClick,\n onColumnHeaderClick,\n onColumnResize,\n showSheetTabs = false,\n virtualize = 'auto'\n}) => {\n const defaultState = useSpreadsheetEditor();\n const state = externalState || defaultState;\n const gridRef = useRef<HTMLDivElement>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n const formulaBarRef = useRef<HTMLInputElement>(null);\n const cellInputRef = useRef<HTMLInputElement>(null);\n\n const [resizingColId, setResizingColId] = useState<string | null>(null);\n const [hoveredColId, setHoveredColId] = useState<string | null>(null);\n const [resizeStartX, setResizeStartX] = useState(0);\n const [resizeStartWidth, setResizeStartWidth] = useState(0);\n\n // Table operations: render model, clipboard, fill handle and context menu.\n const view = state.viewModel;\n // Virtualised rendering: frozen rows/columns, a spacer, the rows and\n // columns in view, another spacer (everything for small sheets).\n const { window: viewWindow, onScroll: handleGridScroll } = useSpreadsheetViewport(scrollRef, view, {\n virtualize,\n merges: state.document.table?.merges,\n activeCell: state.activeCell\n });\n const columnSlots = useMemo<ColumnSlot[]>(() => {\n const col = (viewCol: SpreadsheetViewColumn): ColumnSlot => ({ kind: 'col', viewCol });\n if (!viewWindow.virtual) return view.columns.map(col);\n const slots = view.columns.slice(0, viewWindow.frozenColumns).map(col);\n if (viewWindow.leftSpace > 0) slots.push({ kind: 'space', key: 'space:left', width: viewWindow.leftSpace });\n for (let i = viewWindow.colStart; i < viewWindow.colEnd; i++) slots.push(col(view.columns[i]));\n if (viewWindow.rightSpace > 0) slots.push({ kind: 'space', key: 'space:right', width: viewWindow.rightSpace });\n return slots;\n }, [view, viewWindow]);\n const renderedColumns = useMemo(\n () => columnSlots.flatMap((slot) => (slot.kind === 'col' ? [slot.viewCol] : [])),\n [columnSlots]\n );\n const rowSlots = useMemo<RowSlot[]>(() => {\n const row = (viewRow: SpreadsheetViewRow): RowSlot => ({ kind: 'row', viewRow });\n if (!viewWindow.virtual) return view.rows.map(row);\n const slots = view.rows.slice(0, viewWindow.frozenRows).map(row);\n if (viewWindow.topSpace > 0) slots.push({ kind: 'space', key: 'space:top', height: viewWindow.topSpace });\n for (let i = viewWindow.rowStart; i < viewWindow.rowEnd; i++) slots.push(row(view.rows[i]));\n if (viewWindow.bottomSpace > 0) slots.push({ kind: 'space', key: 'space:bottom', height: viewWindow.bottomSpace });\n return slots;\n }, [view, viewWindow]);\n const { copyShortcutFallback } = useSpreadsheetClipboard(gridRef, state, readOnly);\n const { fillTarget, startFill, extendFill } = useFillHandle(state);\n const [menu, setMenu] = useState<{ x: number; y: number; items: SpreadsheetMenuItem[] } | null>(null);\n // Conditional formatting / data validation manager, opened from the context menu.\n const [panel, setPanel] = useState<SpreadsheetPanelId | null>(null);\n // List dropdown of a list-validated cell.\n const [listMenu, setListMenu] = useState<{ x: number; y: number; row: number; col: number; values: string[] } | null>(null);\n const overlay = state.conditionalFormatOverlay;\n const filter = state.document.table?.filter;\n const filteredColIds = useMemo(\n () => new Set(filter?.enabled ? filter.rules.map((r) => r.colId) : []),\n [filter]\n );\n\n const handleCellContextMenu = useCallback((rIdx: number, cIdx: number, e: React.MouseEvent) => {\n if (readOnly) return;\n e.preventDefault();\n if (state.editingCell) state.commitEditing();\n if (!state.selectedRange || !rangeContains(state.selectedRange, rIdx, cIdx)) {\n state.selectCell(rIdx, cIdx);\n }\n setMenu({ x: e.clientX, y: e.clientY, items: getSpreadsheetMenuItems(state.controller, { row: rIdx, col: cIdx }) });\n }, [readOnly, state]);\n\n // Defined names for formula autocomplete.\n const nameSuggestions = useMemo(\n () => state.controller.getNameSuggestions(),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [state.controller, state.document]\n );\n\n const activeRawValue = useMemo(() => {\n if (!state.activeCell) return '';\n const row = state.document.rows[state.activeCell.row];\n const col = state.document.columns[state.activeCell.col];\n if (!row || !col) return '';\n return state.getCell(row.id, col.id).raw;\n }, [state.activeCell, state.document]);\n\n // The dynamic array under the active cell (anchor or spilled cell): it gets\n // a border, and a spilled cell shows the anchor's formula greyed out.\n const activeSpill = useMemo(\n () => (state.activeCell ? state.controller.getSpillAt(state.activeCell.row, state.activeCell.col) : null),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [state.controller, state.activeCell, state.document]\n );\n const spillFormula = activeSpill && !activeRawValue && activeSpill.key !== coordKey(state.activeCell) ? activeSpill.formula : '';\n\n const coordLabel = useMemo(() => {\n if (!state.activeCell) return '--';\n const colName = indexToColName(state.activeCell.col);\n return `${colName}${state.activeCell.row + 1}`;\n }, [state.activeCell]);\n\n // Text typed in the formula bar while no cell editor is open.\n const [formulaDraft, setFormulaDraft] = useState<string | null>(null);\n const activeColumn = state.activeCell ? state.document.columns[state.activeCell.col] : undefined;\n const formulaBarReadOnly = readOnly || !state.activeCell || !!activeColumn?.readOnly;\n\n useEffect(() => {\n setFormulaDraft(null);\n }, [state.activeCell?.row, state.activeCell?.col]);\n\n const commitFormulaBar = () => {\n if (state.editingCell) {\n state.commitEditing();\n return;\n }\n if (formulaDraft === null || !state.activeCell) return;\n const row = state.document.rows[state.activeCell.row];\n const col = state.document.columns[state.activeCell.col];\n if (row && col && !formulaBarReadOnly && formulaDraft !== activeRawValue) {\n state.commitCellInput(row.id, col.id, formulaDraft);\n }\n setFormulaDraft(null);\n };\n\n const handleCellClick = useCallback((rIdx: number, cIdx: number, e: React.MouseEvent) => {\n if (state.editingCell && (state.editingCell.row !== rIdx || state.editingCell.col !== cIdx)) {\n state.commitEditing();\n }\n state.selectCell(rIdx, cIdx, e.shiftKey);\n }, [state]);\n\n const handleCellDblClick = useCallback((rIdx: number, cIdx: number) => {\n if (readOnly) return;\n const col = state.document.columns[cIdx];\n if (col?.readOnly) return;\n state.startEditing(rIdx, cIdx);\n }, [readOnly, state]);\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\n if (state.editingCell) {\n if (e.key === 'Enter') {\n e.preventDefault();\n // Invalid input keeps the editor open behind the validation alert.\n if (state.commitEditing().status !== 'committed') return;\n state.moveCursor('down');\n } else if (e.key === 'Escape') {\n e.preventDefault();\n state.cancelEditing();\n } else if (e.key === 'Tab') {\n e.preventDefault();\n if (state.commitEditing().status !== 'committed') return;\n state.moveCursor(e.shiftKey ? 'left' : 'right');\n } else {\n return;\n }\n // The cell input unmounts; keep focus on the grid so typing continues.\n gridRef.current?.focus();\n return;\n }\n\n if (!state.activeCell) return;\n\n if (e.altKey && e.key === 'ArrowDown') {\n // Alt+Down opens the list of a list-validated cell.\n e.preventDefault();\n openListMenu(state.activeCell.row, state.activeCell.col);\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n state.moveCursor('up', e.shiftKey);\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n state.moveCursor('down', e.shiftKey);\n } else if (e.key === 'ArrowLeft') {\n e.preventDefault();\n state.moveCursor('left', e.shiftKey);\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n state.moveCursor('right', e.shiftKey);\n } else if (e.key === 'Tab') {\n e.preventDefault();\n state.moveCursor(e.shiftKey ? 'left' : 'right');\n } else if (e.key === 'Enter') {\n e.preventDefault();\n const col = state.document.columns[state.activeCell.col];\n if (!readOnly && !col?.readOnly) {\n state.startEditing();\n }\n } else if (e.key === 'Backspace' || e.key === 'Delete') {\n if (readOnly) return;\n const row = state.document.rows[state.activeCell.row];\n const col = state.document.columns[state.activeCell.col];\n if (row && col && !col.readOnly) {\n e.preventDefault();\n state.setCellValue(row.id, col.id, '');\n }\n } else if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'z') {\n // With Shift held, e.key is 'Z'.\n e.preventDefault();\n if (e.shiftKey) {\n state.redo();\n } else {\n state.undo();\n }\n } else if (e.ctrlKey && !e.metaKey && e.key.toLowerCase() === 'y') {\n e.preventDefault();\n state.redo();\n } else if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'c') {\n // Copy the selection, not the whole sheet. The browser's copy event\n // writes TSV, HTML and the internal format; the fallback writes TSV.\n copyShortcutFallback();\n } else if (!readOnly && e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey) {\n const col = state.document.columns[state.activeCell.col];\n if (!col?.readOnly) {\n // The key becomes the draft; without preventDefault the browser would\n // also type it into the newly focused cell input (\"1\" -> \"11\").\n e.preventDefault();\n state.startEditing(state.activeCell.row, state.activeCell.col, e.key);\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [readOnly, state, copyShortcutFallback]);\n\n // --- Data validation: list dropdown, input message, alerts ---\n\n const activeListValues = useMemo(\n () => (state.activeCell && !readOnly ? state.controller.getValidationListValues(state.activeCell.row, state.activeCell.col) : null),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [state.controller, state.activeCell, state.document, readOnly]\n );\n const activeRule = useMemo(\n () => (state.activeCell ? state.controller.getDataValidationAt(state.activeCell.row, state.activeCell.col) : undefined),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [state.controller, state.activeCell, state.document]\n );\n const inputMessage =\n activeRule && activeRule.showInputMessage !== false && (activeRule.inputTitle || activeRule.inputMessage) ? activeRule : null;\n\n function openListMenu(row: number, col: number, anchor?: HTMLElement | null) {\n if (readOnly || state.document.columns[col]?.readOnly) return;\n const values = state.controller.getValidationListValues(row, col);\n if (!values) return;\n const td = anchor ?? gridRef.current?.querySelector<HTMLElement>(`td[data-row=\"${row}\"][data-col=\"${col}\"]`);\n const rect = td?.getBoundingClientRect();\n setListMenu({ x: rect ? rect.left : 0, y: rect ? rect.bottom : 0, row, col, values });\n }\n\n // Close the list on a press outside it (or on its arrow, which toggles it).\n useEffect(() => {\n if (!listMenu) return;\n const close = (e: MouseEvent) => {\n if (!(e.target as Element | null)?.closest?.('[aria-label=\"Allowed values\"], .spreadsheet-list-arrow')) setListMenu(null);\n };\n window.addEventListener('mousedown', close);\n return () => window.removeEventListener('mousedown', close);\n }, [listMenu]);\n\n const chooseListValue = (value: string) => {\n if (!listMenu) return;\n const row = state.document.rows[listMenu.row];\n const col = state.document.columns[listMenu.col];\n setListMenu(null);\n if (row && col) state.commitCellInput(row.id, col.id, value);\n gridRef.current?.focus();\n };\n\n const resolveValidation = (action: 'accept' | 'retry' | 'cancel') => {\n state.resolveValidationPrompt(action);\n // Back to the cell editor when it is still open (retry), else the grid.\n requestAnimationFrame(() => {\n if (cellInputRef.current) cellInputRef.current.focus();\n else gridRef.current?.focus();\n });\n };\n // The resize effect reads these through refs: re-running it on every width\n // update would reset the in-progress drag (and skip onColumnResize).\n const stateRef = useRef(state);\n stateRef.current = state;\n const onColumnResizeRef = useRef(onColumnResize);\n onColumnResizeRef.current = onColumnResize;\n\n useEffect(() => {\n if (!resizingColId) return;\n\n if (typeof document !== 'undefined') {\n document.body.style.cursor = 'col-resize';\n document.body.style.userSelect = 'none';\n }\n\n let rafId: number | null = null;\n let pendingWidth = resizeStartWidth;\n let hasDragged = false;\n\n const handleMouseMove = (e: MouseEvent) => {\n const delta = e.clientX - resizeStartX;\n if (Math.abs(delta) > 2) {\n hasDragged = true;\n }\n pendingWidth = Math.max(30, resizeStartWidth + delta);\n\n if (rafId === null) {\n rafId = requestAnimationFrame(() => {\n rafId = null;\n stateRef.current.setColumnWidth(resizingColId, pendingWidth);\n });\n }\n };\n\n const handleMouseUp = () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n rafId = null;\n }\n if (hasDragged) {\n stateRef.current.setColumnWidth(resizingColId, pendingWidth);\n onColumnResizeRef.current?.(resizingColId, pendingWidth);\n }\n setResizingColId(null);\n if (typeof document !== 'undefined') {\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }\n };\n\n window.addEventListener('mousemove', handleMouseMove);\n window.addEventListener('mouseup', handleMouseUp);\n return () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n }\n if (typeof document !== 'undefined') {\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }\n window.removeEventListener('mousemove', handleMouseMove);\n window.removeEventListener('mouseup', handleMouseUp);\n };\n }, [resizingColId, resizeStartX, resizeStartWidth]);\n\n const measureElementContentWidth = useCallback((el: HTMLElement, container: HTMLElement): number => {\n if (typeof document === 'undefined') return 0;\n\n let maxW = el.scrollWidth || 0;\n const firstChild = el.firstElementChild as HTMLElement | null;\n if (firstChild && firstChild.scrollWidth > maxW) {\n maxW = firstChild.scrollWidth;\n }\n\n const truncated = el.querySelectorAll<HTMLElement>('.truncate, [title], span, div');\n truncated.forEach((node) => {\n if (node.scrollWidth > maxW) {\n maxW = node.scrollWidth;\n }\n });\n\n try {\n const clone = (firstChild ? firstChild.cloneNode(true) : el.cloneNode(true)) as HTMLElement;\n clone.style.cssText = `\n position: absolute !important;\n visibility: hidden !important;\n width: max-content !important;\n min-width: max-content !important;\n max-width: none !important;\n overflow: visible !important;\n white-space: nowrap !important;\n pointer-events: none !important;\n top: -9999px !important;\n left: -9999px !important;\n `;\n\n const allNodes = clone.querySelectorAll<HTMLElement>('*');\n allNodes.forEach((node) => {\n node.style.maxWidth = 'none';\n node.style.overflow = 'visible';\n node.style.textOverflow = 'clip';\n node.style.whiteSpace = 'nowrap';\n if (\n node.classList.contains('truncate') ||\n node.classList.contains('min-w-0') ||\n node.classList.contains('w-full') ||\n node.classList.contains('max-w-0') ||\n node.classList.contains('flex-1')\n ) {\n node.style.width = 'max-content';\n node.style.minWidth = 'max-content';\n }\n });\n\n container.appendChild(clone);\n const rect = clone.getBoundingClientRect();\n container.removeChild(clone);\n\n if (rect.width > maxW) {\n maxW = rect.width;\n }\n } catch {\n // Ignore cloning/measuring errors\n }\n\n return maxW;\n }, []);\n\n const autoFitColumn = useCallback((colId: string, colIndex: number) => {\n const col = state.document.columns.find((c) => c.id === colId);\n if (!col) return;\n\n let calculatedWidth = 0;\n\n if (gridRef.current && typeof document !== 'undefined') {\n const table = gridRef.current.querySelector('table');\n if (table) {\n // Look cells up by column index: hidden columns and merges shift DOM positions.\n const th = table.querySelector(`thead th[data-col=\"${colIndex}\"]`) as HTMLElement | null;\n if (th) {\n const headerInner = (th.firstElementChild as HTMLElement) || th;\n const headerW = measureElementContentWidth(headerInner, gridRef.current);\n calculatedWidth = Math.max(calculatedWidth, headerW + 28);\n }\n\n const rows = table.querySelectorAll('tbody tr');\n const sampleLimit = Math.min(rows.length, 150);\n for (let r = 0; r < sampleLimit; r++) {\n const tr = rows[r];\n const td = tr.querySelector(`td[data-col=\"${colIndex}\"][colspan=\"1\"]`) as HTMLElement | null;\n if (td) {\n const cellW = measureElementContentWidth(td, gridRef.current);\n calculatedWidth = Math.max(calculatedWidth, cellW + 20);\n }\n }\n }\n }\n\n if (calculatedWidth > 0) {\n const finalWidth = Math.min(600, Math.max(50, Math.ceil(calculatedWidth)));\n state.setColumnWidth(colId, finalWidth);\n } else {\n state.autoFitColumnWidth?.(colId);\n }\n\n const updatedCol = state.document.columns.find((c) => c.id === colId);\n if (updatedCol && onColumnResize) {\n onColumnResize(updatedCol.id, updatedCol.width || 130);\n }\n }, [state, measureElementContentWidth, onColumnResize]);\n\n const handleResizeDblClick = useCallback((colId: string, colIndex: number, e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n autoFitColumn(colId, colIndex);\n }, [autoFitColumn]);\n\n const handleHeaderDblClick = useCallback((colId: string, colIndex: number, e: React.MouseEvent) => {\n const target = e.currentTarget as HTMLElement | null;\n if (target) {\n const rect = target.getBoundingClientRect();\n if (rect.right - e.clientX <= 12) {\n e.preventDefault();\n e.stopPropagation();\n autoFitColumn(colId, colIndex);\n }\n }\n }, [autoFitColumn]);\n\n const isCellSelected = (rIdx: number, cIdx: number) => {\n if (!state.selectedRange) return false;\n const minR = Math.min(state.selectedRange.startRow, state.selectedRange.endRow);\n const maxR = Math.max(state.selectedRange.startRow, state.selectedRange.endRow);\n const minC = Math.min(state.selectedRange.startCol, state.selectedRange.endCol);\n const maxC = Math.max(state.selectedRange.startCol, state.selectedRange.endCol);\n return rIdx >= minR && rIdx <= maxR && cIdx >= minC && cIdx <= maxC;\n };\n\n const isActiveCell = (rIdx: number, cIdx: number) => {\n return state.activeCell?.row === rIdx && state.activeCell?.col === cIdx;\n };\n\n const grid = (\n <div\n ref={gridRef}\n className=\"flex flex-col h-full w-full overflow-hidden border border-border bg-background select-none outline-none text-foreground font-sans text-xs\"\n tabIndex={0}\n onKeyDown={handleKeyDown}\n role=\"grid\"\n aria-label=\"Spreadsheet\"\n >\n {/* Formula Bar */}\n <div className=\"flex items-center gap-2 border-b border-border bg-muted/20 px-3 py-1.5 text-xs font-mono\">\n <div className=\"flex h-6 min-w-[3rem] items-center justify-center rounded border border-border bg-background px-1.5 font-semibold text-foreground\">\n {coordLabel}\n </div>\n <div className=\"flex items-center text-muted-foreground select-none\">\n <span className=\"italic font-serif font-bold text-sm text-primary\">fx</span>\n </div>\n <input\n ref={formulaBarRef}\n type=\"text\"\n className=\"flex-1 bg-transparent px-2 py-0.5 outline-none font-sans text-xs text-foreground placeholder:text-muted-foreground/60 focus:bg-background focus:ring-1 focus:ring-primary rounded\"\n placeholder=\"Enter a value or formula (e.g. =SUM(A1:A5))\"\n aria-label=\"Formula bar\"\n readOnly={formulaBarReadOnly}\n data-spill-formula={!state.editingCell && formulaDraft === null && spillFormula ? 'true' : undefined}\n style={!state.editingCell && formulaDraft === null && spillFormula ? { color: 'var(--muted-foreground, #94a3b8)' } : undefined}\n value={state.editingCell ? state.draftValue : formulaDraft ?? (activeRawValue || spillFormula)}\n onFocus={() => {\n if (!state.editingCell) setFormulaDraft(activeRawValue);\n }}\n onChange={(e) => {\n if (state.editingCell) {\n state.setDraftValue(e.target.value);\n } else if (state.activeCell) {\n setFormulaDraft(e.target.value);\n }\n }}\n onBlur={() => commitFormulaBar()}\n onKeyDown={(e) => {\n // Keys typed here must not reach the grid's navigation handler.\n e.stopPropagation();\n if (e.key === 'Enter') {\n e.preventDefault();\n commitFormulaBar();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n setFormulaDraft(null);\n if (state.editingCell) state.cancelEditing();\n }\n }}\n />\n {!formulaBarReadOnly && (\n <FormulaHints\n inputRef={formulaBarRef}\n value={state.editingCell ? state.draftValue : formulaDraft ?? activeRawValue}\n onAccept={(next) => (state.editingCell ? state.setDraftValue(next) : setFormulaDraft(next))}\n names={nameSuggestions}\n />\n )}\n </div>\n\n {inputMessage && (\n <div role=\"note\" data-validation-input-message=\"\" className=\"border-b border-border bg-muted/30 px-3 py-1 text-[11px] text-muted-foreground\">\n {inputMessage.inputTitle && <span className=\"mr-1 font-semibold text-foreground\">{inputMessage.inputTitle}</span>}\n {inputMessage.inputMessage}\n </div>\n )}\n\n {/* Main Grid */}\n <div ref={scrollRef} className=\"relative flex-1 overflow-auto\" onScroll={handleGridScroll}>\n <table className=\"border-separate border-spacing-0 table-fixed w-max min-w-full [&>*>tr:not([data-spacer])>*]:border-b [&>*>tr>*]:border-border\">\n <thead>\n <tr className=\"h-7 bg-muted sticky top-0 z-20 border-b border-border shadow-xs\">\n <th className=\"w-12 min-w-[3rem] sticky left-0 z-30 bg-muted border-r border-border text-center text-[10px] text-muted-foreground font-medium\">\n #\n </th>\n {columnSlots.map((slot) => slot.kind === 'space' ? (\n <th\n key={slot.key}\n aria-hidden=\"true\"\n data-spacer=\"\"\n className=\"p-0\"\n style={{ width: slot.width, minWidth: slot.width, maxWidth: slot.width, padding: 0 }}\n />\n ) : ((({ column: col, index: cIdx, frozen, stickyLeft }) => (\n <th\n key={col.id}\n data-col={cIdx}\n className={`relative border-r border-border px-2 text-left font-medium text-muted-foreground hover:bg-muted/90 transition-colors group overflow-hidden max-w-0 ${\n onColumnHeaderClick ? 'cursor-pointer' : 'cursor-default'\n }`}\n style={{\n width: col.width || 130,\n minWidth: col.width || 130,\n maxWidth: col.width || 130,\n overflow: 'hidden',\n ...(frozen ? { position: 'sticky', left: ROW_HEADER_WIDTH + stickyLeft, zIndex: 25, background: 'var(--muted, #f4f4f5)' } : {})\n }}\n onClick={() => onColumnHeaderClick?.(col)}\n onDoubleClick={(e) => handleHeaderDblClick(col.id, cIdx, e)}\n >\n <div className=\"flex items-center justify-between gap-1 min-w-0 overflow-hidden truncate\">\n <span className=\"truncate font-semibold text-foreground text-xs min-w-0\">{col.title}</span>\n {filteredColIds.has(col.id) && (\n <span className=\"text-[10px] text-primary shrink-0\" title=\"Filtered\" data-filtered=\"true\">⏷</span>\n )}\n <span className=\"text-[10px] text-muted-foreground/70 font-mono font-normal shrink-0\">({col.key})</span>\n </div>\n {/* Column Resize Handle */}\n <div\n className=\"col-resize-handle\"\n style={{ position: 'absolute', top: 0, bottom: 0, width: 12, right: -6, cursor: 'col-resize', zIndex: 20, display: 'flex', justifyContent: 'center', touchAction: 'none' }}\n onMouseEnter={() => setHoveredColId(col.id)}\n onMouseLeave={() => setHoveredColId((cur) => cur === col.id ? null : cur)}\n onMouseDown={(e) => {\n e.preventDefault();\n e.stopPropagation();\n setResizingColId(col.id);\n setResizeStartX(e.clientX);\n setResizeStartWidth(col.width || 130);\n }}\n onDoubleClick={(e) => handleResizeDblClick(col.id, cIdx, e)}\n role=\"separator\"\n aria-orientation=\"vertical\"\n >\n <div\n className=\"col-resize-handle-line\"\n style={{\n width: 2,\n height: '100%',\n pointerEvents: 'none',\n transition: 'background-color 150ms ease',\n backgroundColor: resizingColId === col.id ? 'var(--primary, #6366f1)' : hoveredColId === col.id ? 'color-mix(in srgb, var(--primary, #6366f1) 75%, transparent)' : 'transparent'\n }}\n />\n </div>\n </th>\n ))(slot.viewCol)))}\n {onAddColumnClick && (\n <th\n className=\"w-10 min-w-[2.5rem] px-1 text-center bg-muted/40 hover:bg-muted cursor-pointer transition-colors\"\n onClick={onAddColumnClick}\n title=\"Add Column\"\n >\n <span className=\"text-xs font-bold text-muted-foreground\">+</span>\n </th>\n )}\n </tr>\n </thead>\n <tbody>\n {rowSlots.map((rowSlot) => {\n if (rowSlot.kind === 'space') {\n return (\n <tr key={rowSlot.key} aria-hidden=\"true\" data-spacer=\"\" style={{ height: rowSlot.height }}>\n <td colSpan={columnSlots.length + 2} style={{ padding: 0, border: 0 }} />\n </tr>\n );\n }\n const viewRow = rowSlot.viewRow;\n if (viewRow.kind === 'group') {\n return (\n <SpreadsheetGroupRow\n key={`group:${viewRow.group.key}`}\n group={viewRow.group}\n columns={renderedColumns}\n labelColumns={view.columns}\n leadingColumns={viewWindow.virtual ? viewWindow.frozenColumns : undefined}\n leftSpace={viewWindow.leftSpace}\n rightSpace={viewWindow.rightSpace}\n groupColId={state.document.table?.grouping?.colId ?? ''}\n onToggle={state.toggleGroupCollapsed}\n trailingCell={!!onAddColumnClick}\n />\n );\n }\n const displayRowIndex = viewRow.index;\n const selection = state.selectedRange ? normalizeRange(state.selectedRange) : null;\n return (\n <tr\n key={viewRow.row.id}\n data-row={displayRowIndex}\n className={`border-b border-border hover:bg-muted/10 transition-colors ${viewRow.section !== 'body' ? 'bg-muted/30 font-semibold' : ''}`}\n style={{ height: viewRow.row.height || 32 }}\n >\n <td\n className=\"w-12 min-w-[3rem] sticky left-0 z-10 bg-muted border-r border-border text-center text-[10px] text-muted-foreground font-mono select-none\"\n style={viewRow.frozen ? { top: COLUMN_HEADER_HEIGHT + viewRow.stickyTop, zIndex: 15 } : undefined}\n >\n {displayRowIndex + 1}\n </td>\n {columnSlots.map((slot) => {\n if (slot.kind === 'space') return <td key={slot.key} aria-hidden=\"true\" data-spacer=\"\" style={{ padding: 0 }} />;\n const viewCol = slot.viewCol;\n // A merged cell renders its top-left cell, spanning the merge.\n const span = view.getCellSpan(displayRowIndex, viewCol.index);\n if (!span) return null;\n const rIdx = span.source.row;\n const cIdx = span.source.col;\n const row = state.document.rows[rIdx];\n const col = state.document.columns[cIdx];\n const cell = state.getCell(row.id, col.id);\n const selected = isCellSelected(rIdx, cIdx);\n const active = isActiveCell(rIdx, cIdx);\n const isEditing = state.editingCell?.row === rIdx && state.editingCell?.col === cIdx;\n\n const conditional = overlay.get(rIdx, cIdx);\n const conditionalCss = getConditionalFormatCss(conditional);\n const circled = state.controller.isInvalidDataCircled(rIdx, cIdx);\n const showListArrow = active && !isEditing && !!activeListValues;\n const inFillPreview = !!fillTarget && !selected && rangeContains(fillTarget, displayRowIndex, viewCol.index);\n const showFillHandle =\n !readOnly &&\n !isEditing &&\n !!selection &&\n (span.merge\n ? rangeContains(span.merge, selection.endRow, selection.endCol)\n : selection.endRow === rIdx && selection.endCol === cIdx);\n\n return (\n <td\n key={viewCol.column.id}\n data-row={rIdx}\n data-col={cIdx}\n rowSpan={span.rowSpan}\n colSpan={span.colSpan}\n className={`relative border-r border-border px-2 py-1 truncate max-w-0 text-foreground transition-colors ${\n selected ? 'bg-primary/10' : ''\n } ${active ? 'ring-2 ring-primary ring-inset z-10' : ''} ${viewCol.header ? 'font-semibold' : ''}`}\n style={{\n maxWidth: 0,\n overflow: 'hidden',\n ...frozenCellStyle(viewRow, viewCol),\n ...conditionalCss,\n // Keep the selection tint visible over a conditional fill.\n ...(conditionalCss.background && selected\n ? { boxShadow: 'inset 0 0 0 9999px color-mix(in srgb, var(--primary, #6366f1) 12%, transparent)' }\n : {}),\n ...(inFillPreview ? { outline: '1px dashed var(--primary, #6366f1)', outlineOffset: -1 } : {})\n }}\n data-cf-fill={conditional?.fill}\n onClick={(e) => handleCellClick(rIdx, cIdx, e)}\n onDoubleClick={() => handleCellDblClick(rIdx, cIdx)}\n onContextMenu={(e) => handleCellContextMenu(rIdx, cIdx, e)}\n onMouseOver={() => extendFill(displayRowIndex, viewCol.index)}\n >\n {isEditing ? (\n <>\n <input\n ref={cellInputRef}\n type=\"text\"\n className=\"absolute inset-0 w-full h-full px-2 py-1 bg-background text-foreground outline-none font-sans text-xs border-2 border-primary z-20\"\n value={state.draftValue}\n onChange={(e) => state.setDraftValue(e.target.value)}\n onBlur={() => state.commitEditing()}\n onFocus={(e) => {\n // Caret after the draft (e.g. the key that started editing).\n const end = e.currentTarget.value.length;\n e.currentTarget.setSelectionRange(end, end);\n }}\n autoFocus\n />\n <FormulaHints inputRef={cellInputRef} value={state.draftValue} onAccept={state.setDraftValue} names={nameSuggestions} />\n </>\n ) : customCellRenderer ? (\n customCellRenderer({ row, col, cell })\n ) : (\n <CellText cell={cell} conditional={conditional} />\n )}\n {circled && (\n <span\n className=\"spreadsheet-invalid-circle\"\n aria-label=\"Invalid value\"\n style={{ position: 'absolute', inset: '1px 2px', border: '2px solid #e11d48', borderRadius: '50%', pointerEvents: 'none', zIndex: 6 }}\n />\n )}\n {showListArrow && (\n <button\n type=\"button\"\n className=\"spreadsheet-list-arrow\"\n aria-label=\"Show allowed values\"\n aria-haspopup=\"listbox\"\n tabIndex={-1}\n style={{ position: 'absolute', right: 1, top: 1, bottom: 1, width: 16, zIndex: 24, fontSize: 10, lineHeight: 1, background: 'var(--muted, #f4f4f5)', border: '1px solid var(--border, #e4e4e7)', borderRadius: 2, cursor: 'pointer', padding: 0 }}\n onMouseDown={(e) => e.stopPropagation()}\n onClick={(e) => {\n e.stopPropagation();\n if (listMenu) setListMenu(null);\n else openListMenu(rIdx, cIdx, e.currentTarget.parentElement);\n }}\n >\n ▾\n </button>\n )}\n {activeSpill && rangeContains(activeSpill.range, rIdx, cIdx) && (\n <span aria-hidden=\"true\" className=\"spreadsheet-spill-border\" style={spillBorderStyle(activeSpill.range, rIdx, cIdx)} />\n )}\n {showFillHandle && (\n <div\n className=\"spreadsheet-fill-handle\"\n aria-label=\"Fill handle\"\n onMouseDown={startFill}\n onClick={(e) => e.stopPropagation()}\n style={{ position: 'absolute', right: 0, bottom: 0, width: 7, height: 7, background: 'var(--primary, #6366f1)', cursor: 'crosshair', zIndex: 25 }}\n />\n )}\n </td>\n );\n })}\n {onAddColumnClick && <td className=\"w-10 min-w-[2.5rem] bg-muted/10 border-r border-border\" />}\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n {menu && (\n <SpreadsheetContextMenu\n items={menu.items}\n x={menu.x}\n y={menu.y}\n onClose={() => {\n setMenu(null);\n gridRef.current?.focus();\n }}\n onOpenPanel={setPanel}\n />\n )}\n {panel === 'conditionalFormatting' && <SpreadsheetConditionalFormatPanel state={state} onClose={() => setPanel(null)} />}\n {panel === 'dataValidation' && <SpreadsheetDataValidationPanel state={state} onClose={() => setPanel(null)} />}\n {listMenu && (\n <div\n role=\"listbox\"\n aria-label=\"Allowed values\"\n className=\"fixed z-50 max-h-60 min-w-[8rem] overflow-y-auto rounded-md border border-border bg-popover py-1 text-xs text-popover-foreground shadow-lg\"\n style={{ left: listMenu.x, top: listMenu.y, background: 'var(--popover, var(--background, #fff))' }}\n onKeyDown={(e) => {\n e.stopPropagation();\n if (e.key === 'Escape') {\n setListMenu(null);\n gridRef.current?.focus();\n }\n }}\n >\n {listMenu.values.length === 0 && <div className=\"px-3 py-1 text-muted-foreground\">No values</div>}\n {listMenu.values.map((value, i) => (\n <button\n key={`${i}:${value}`}\n type=\"button\"\n role=\"option\"\n aria-selected={false}\n className=\"block w-full px-3 py-1 text-left hover:bg-muted\"\n onClick={() => chooseListValue(value)}\n >\n {value}\n </button>\n ))}\n </div>\n )}\n {state.validationPrompt && <SpreadsheetValidationDialog prompt={state.validationPrompt} onResolve={resolveValidation} />}\n <style>{`\n .col-resize-handle:hover .col-resize-handle-line {\n background-color: var(--primary, #6366f1);\n opacity: 0.75;\n }\n .col-resize-handle.active .col-resize-handle-line {\n background-color: var(--primary, #6366f1);\n opacity: 1;\n }\n table.table-fixed th {\n overflow: hidden;\n }\n table.table-fixed td {\n max-width: 0;\n overflow: hidden;\n }\n `}</style>\n </div>\n );\n\n if (!showSheetTabs) return grid;\n return (\n <div className=\"flex h-full w-full flex-col\">\n <div className=\"min-h-0 flex-1\">{grid}</div>\n <SheetTabs state={state} readOnly={readOnly} />\n </div>\n );\n};\n","import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { clampMenuPosition, runSpreadsheetMenuItem, type SpreadsheetMenuItem, type SpreadsheetPanelId } from '@pixerate/editor/spreadsheet';\n\n// Gap kept between the menu and the viewport edges.\nconst VIEWPORT_MARGIN = 4;\n\nexport interface SpreadsheetContextMenuProps {\n items: SpreadsheetMenuItem[];\n x: number;\n y: number;\n onClose: () => void;\n /** Accessible name of the menu (default \"Table actions\"). */\n ariaLabel?: string;\n /** Opens a panel for items with `panel` (conditional formatting, data validation). */\n onOpenPanel?: (panel: SpreadsheetPanelId) => void;\n}\n\n/** The table context menu (sort, filter, freeze, hide, merge, categories, transpose). */\nexport const SpreadsheetContextMenu: React.FC<SpreadsheetContextMenuProps> = ({ items, x, y, onClose, onOpenPanel, ariaLabel = 'Table actions' }) => {\n const menuRef = useRef<HTMLDivElement>(null);\n const onCloseRef = useRef(onClose);\n onCloseRef.current = onClose;\n const [position, setPosition] = useState({ x, y });\n\n // Keep the (fixed) menu inside the viewport: near the right or bottom edge\n // it opens to the left of / above the pointer instead of being cut off.\n useLayoutEffect(() => {\n const menu = menuRef.current;\n if (!menu || typeof window === 'undefined') return;\n const { width, height } = menu.getBoundingClientRect();\n const next = clampMenuPosition(\n { x, y },\n { width, height },\n { width: window.innerWidth, height: window.innerHeight },\n VIEWPORT_MARGIN\n );\n setPosition((prev) => (prev.x === next.x && prev.y === next.y ? prev : next));\n }, [x, y, items]);\n\n useEffect(() => {\n const handlePointer = (e: MouseEvent) => {\n if (!menuRef.current?.contains(e.target as Node)) onCloseRef.current();\n };\n const handleKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onCloseRef.current();\n };\n window.addEventListener('mousedown', handlePointer);\n window.addEventListener('keydown', handleKey);\n return () => {\n window.removeEventListener('mousedown', handlePointer);\n window.removeEventListener('keydown', handleKey);\n };\n }, []);\n\n return (\n <div\n ref={menuRef}\n role=\"menu\"\n aria-label={ariaLabel}\n className=\"fixed z-50 min-w-[14rem] rounded-md border border-border bg-popover py-1 text-xs text-popover-foreground shadow-lg\"\n style={{\n left: position.x,\n top: position.y,\n maxHeight: `calc(100vh - ${VIEWPORT_MARGIN * 2}px)`,\n overflowY: 'auto',\n background: 'var(--popover, var(--background, #fff))'\n }}\n onContextMenu={(e) => e.preventDefault()}\n onKeyDown={(e) => e.stopPropagation()}\n >\n {items.map((item) => (\n <React.Fragment key={item.id}>\n {item.separatorBefore && <div role=\"separator\" className=\"my-1 h-px bg-border\" />}\n <button\n type=\"button\"\n role=\"menuitem\"\n data-action={item.id}\n data-checked={item.checked ? '' : undefined}\n disabled={item.disabled}\n className={`block w-full px-3 py-1 text-left hover:bg-muted disabled:cursor-default disabled:opacity-40 disabled:hover:bg-transparent ${\n item.checked ? 'font-semibold' : ''\n }`}\n onClick={() => {\n onClose();\n if (item.panel) onOpenPanel?.(item.panel);\n else runSpreadsheetMenuItem(item);\n }}\n >\n {item.label}\n </button>\n </React.Fragment>\n ))}\n </div>\n );\n};\n","import React from 'react';\nimport type { SpreadsheetRowGroup, SpreadsheetViewColumn } from '@pixerate/editor/spreadsheet';\n\nexport interface SpreadsheetGroupRowProps {\n group: SpreadsheetRowGroup;\n columns: SpreadsheetViewColumn[];\n /** Column the rows are grouped by: shows the group label and toggle. */\n groupColId: string;\n onToggle: (key: string) => void;\n /** Render a trailing cell for the \"add column\" column. */\n trailingCell?: boolean;\n /** Every displayed column, when `columns` is a virtualised window of them (picks the label column). */\n labelColumns?: SpreadsheetViewColumn[];\n /** Virtualised: columns before the left spacer (the frozen ones), and the spacers' widths. */\n leadingColumns?: number;\n leftSpace?: number;\n rightSpace?: number;\n}\n\nconst formatSummary = (value: number | null) => (value === null ? '–' : String(value));\n\n/** A category header row: collapse toggle, label, row count and per-column summaries. */\nexport const SpreadsheetGroupRow: React.FC<SpreadsheetGroupRowProps> = ({\n group,\n columns,\n groupColId,\n onToggle,\n trailingCell,\n labelColumns = columns,\n leadingColumns,\n leftSpace = 0,\n rightSpace = 0\n}) => {\n // The label goes in the grouping column, or the first column when that one is hidden.\n const labelColId = labelColumns.some((c) => c.column.id === groupColId) ? groupColId : labelColumns[0]?.column.id;\n const spacer = (key: string) => <td key={key} aria-hidden=\"true\" data-spacer=\"\" style={{ padding: 0 }} />;\n return (\n <tr className=\"border-b border-border bg-muted/40 font-semibold\" data-group-key={group.key} style={{ height: 28 }}>\n <td className=\"w-12 min-w-[3rem] sticky left-0 z-10 bg-muted border-r border-border text-center\">\n <button\n type=\"button\"\n aria-label={`${group.collapsed ? 'Expand' : 'Collapse'} group ${group.label}`}\n aria-expanded={!group.collapsed}\n className=\"h-5 w-5 rounded text-[10px] text-muted-foreground hover:bg-muted\"\n onClick={(e) => {\n e.stopPropagation();\n onToggle(group.key);\n }}\n >\n {group.collapsed ? '▸' : '▾'}\n </button>\n </td>\n {columns.map(({ column }, i) => {\n const summary = group.summaries[column.id];\n const before = leadingColumns !== undefined && i === leadingColumns && leftSpace > 0 ? spacer('space:left') : null;\n return (\n <React.Fragment key={column.id}>\n {before}\n <td className=\"border-r border-border px-2 py-1 truncate max-w-0 text-foreground\" style={{ maxWidth: 0, overflow: 'hidden' }}>\n {column.id === labelColId ? (\n <span className=\"truncate\">\n {group.label} <span className=\"font-normal text-muted-foreground\">({group.rowIndices.length})</span>\n </span>\n ) : summary !== undefined ? (\n <span className=\"truncate\" data-summary={column.id}>{formatSummary(summary)}</span>\n ) : null}\n </td>\n </React.Fragment>\n );\n })}\n {leadingColumns !== undefined && leadingColumns >= columns.length && leftSpace > 0 && spacer('space:left')}\n {rightSpace > 0 && spacer('space:right')}\n {trailingCell && <td className=\"w-10 min-w-[2.5rem] bg-muted/10 border-r border-border\" />}\n </tr>\n );\n};\n","import { useCallback, useEffect, useRef, useState, type RefObject } from 'react';\nimport {\n computeFillTarget,\n normalizeRange,\n type CellRange\n} from '@pixerate/editor/spreadsheet';\nimport type { useSpreadsheetEditor } from './useSpreadsheetEditor';\n\ntype SpreadsheetState = ReturnType<typeof useSpreadsheetEditor>;\n\n/** True when focus is in the grid itself, not in a text input (cell editor, formula bar). */\nfunction gridHasFocus(grid: HTMLElement | null): boolean {\n if (!grid || typeof document === 'undefined') return false;\n const active = document.activeElement;\n if (!active || !grid.contains(active)) return false;\n return !(active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement);\n}\n\n/**\n * Copy and paste for the grid. Copy writes TSV, an HTML table and the\n * lossless `application/x.pixerate.spreadsheet+json` format; paste prefers\n * that format, then HTML, then TSV.\n *\n * The listeners are on `document`: with no text selection the browser fires\n * `copy`/`paste` at `<body>`, not at the focused grid. Text inputs inside the\n * grid keep native copy/paste.\n */\nexport function useSpreadsheetClipboard(\n gridRef: RefObject<HTMLElement | null>,\n state: SpreadsheetState,\n readOnly: boolean\n) {\n const stateRef = useRef(state);\n stateRef.current = state;\n const readOnlyRef = useRef(readOnly);\n readOnlyRef.current = readOnly;\n // Set when a copy event wrote the selection, so the keyboard fallback is skipped.\n const copiedRef = useRef(false);\n\n useEffect(() => {\n if (typeof document === 'undefined') return;\n const handleCopy = (e: ClipboardEvent) => {\n const s = stateRef.current;\n if (!gridHasFocus(gridRef.current) || s.editingCell || !e.clipboardData || !s.selectedRange) return;\n for (const [type, data] of Object.entries(s.copyToClipboardData(s.selectedRange))) {\n e.clipboardData.setData(type, data);\n }\n copiedRef.current = true;\n e.preventDefault();\n };\n const handlePaste = (e: ClipboardEvent) => {\n const s = stateRef.current;\n if (readOnlyRef.current || !gridHasFocus(gridRef.current) || s.editingCell || !e.clipboardData) return;\n if (s.pasteClipboardData(e.clipboardData)) e.preventDefault();\n };\n document.addEventListener('copy', handleCopy);\n document.addEventListener('paste', handlePaste);\n return () => {\n document.removeEventListener('copy', handleCopy);\n document.removeEventListener('paste', handlePaste);\n };\n }, [gridRef]);\n\n /**\n * Call on Mod+C (without preventing default). The browser normally follows\n * with a `copy` event; where it doesn't (no selection in some browsers),\n * the selection is written as plain TSV instead.\n */\n const copyShortcutFallback = useCallback(() => {\n copiedRef.current = false;\n setTimeout(() => {\n if (copiedRef.current) return;\n const s = stateRef.current;\n // Rejected when clipboard access is denied; nothing else to fall back to.\n Promise.resolve(navigator.clipboard?.writeText(s.exportToTsv(s.selectedRange))).catch(() => {});\n }, 0);\n }, []);\n\n return { copyShortcutFallback };\n}\n\n/**\n * Fill handle dragging: press on the handle, move over cells, release to\n * autofill from the selection into the dragged range (one undo step).\n */\nexport function useFillHandle(state: SpreadsheetState) {\n const [drag, setDrag] = useState<{ source: CellRange; target: CellRange | null } | null>(null);\n const dragRef = useRef(drag);\n dragRef.current = drag;\n const stateRef = useRef(state);\n stateRef.current = state;\n const dragging = drag !== null;\n\n useEffect(() => {\n if (!dragging) return;\n const handleMouseUp = () => {\n const current = dragRef.current;\n setDrag(null);\n if (current?.target) stateRef.current.autofill(current.source, current.target);\n };\n window.addEventListener('mouseup', handleMouseUp);\n return () => window.removeEventListener('mouseup', handleMouseUp);\n }, [dragging]);\n\n const startFill = useCallback((e: { preventDefault(): void; stopPropagation(): void }) => {\n e.preventDefault();\n e.stopPropagation();\n const range = stateRef.current.selectedRange;\n if (range) setDrag({ source: normalizeRange(range), target: null });\n }, []);\n\n const extendFill = useCallback((row: number, col: number) => {\n const current = dragRef.current;\n if (!current) return;\n setDrag({ source: current.source, target: computeFillTarget(current.source, { row, col }) });\n }, []);\n\n return { fillTarget: drag?.target ?? null, isFilling: dragging, startFill, extendFill };\n}\n","import React, { useEffect, useRef } from 'react';\nimport type { SpreadsheetValidationAction, SpreadsheetValidationPrompt } from '@pixerate/editor/spreadsheet';\n\nexport interface SpreadsheetValidationDialogProps {\n prompt: SpreadsheetValidationPrompt;\n onResolve: (action: SpreadsheetValidationAction) => void;\n}\n\n/**\n * The data validation alert: Stop (Retry / Cancel), Warning (\"Continue?\"\n * Yes / No / Cancel) or Information (OK / Cancel), as in Excel.\n */\nexport const SpreadsheetValidationDialog: React.FC<SpreadsheetValidationDialogProps> = ({ prompt, onResolve }) => {\n const style = prompt.result.errorStyle ?? 'stop';\n const firstButton = useRef<HTMLButtonElement>(null);\n useEffect(() => {\n firstButton.current?.focus();\n }, [prompt]);\n\n const buttons: Array<{ label: string; action: SpreadsheetValidationAction }> =\n style === 'stop'\n ? [\n { label: 'Retry', action: 'retry' },\n { label: 'Cancel', action: 'cancel' }\n ]\n : style === 'warning'\n ? [\n { label: 'Yes', action: 'accept' },\n { label: 'No', action: 'retry' },\n { label: 'Cancel', action: 'cancel' }\n ]\n : [\n { label: 'OK', action: 'accept' },\n { label: 'Cancel', action: 'cancel' }\n ];\n const icon = style === 'stop' ? '⛔' : style === 'warning' ? '⚠' : 'ℹ';\n\n return (\n <div\n className=\"fixed inset-0 z-[60] flex items-center justify-center bg-black/30\"\n onMouseDown={(e) => e.preventDefault()}\n onKeyDown={(e) => {\n e.stopPropagation();\n if (e.key === 'Escape') {\n e.preventDefault();\n onResolve('cancel');\n }\n }}\n >\n <div\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-labelledby=\"spreadsheet-validation-title\"\n aria-describedby=\"spreadsheet-validation-message\"\n data-error-style={style}\n className=\"w-[22rem] max-w-[calc(100vw-2rem)] rounded-md border border-border bg-popover p-4 text-xs text-popover-foreground shadow-xl\"\n style={{ background: 'var(--popover, var(--background, #fff))' }}\n >\n <div className=\"flex items-start gap-3\">\n <span aria-hidden=\"true\" className=\"text-lg leading-none\">{icon}</span>\n <div className=\"min-w-0 flex-1\">\n <h2 id=\"spreadsheet-validation-title\" className=\"mb-1 text-sm font-semibold\">\n {prompt.result.title}\n </h2>\n <p id=\"spreadsheet-validation-message\" className=\"whitespace-pre-wrap\">\n {prompt.result.message}\n </p>\n {style === 'warning' && <p className=\"mt-2\">Continue?</p>}\n </div>\n </div>\n <div className=\"mt-4 flex justify-end gap-2\">\n {buttons.map((button, i) => (\n <button\n key={button.action}\n ref={i === 0 ? firstButton : undefined}\n type=\"button\"\n data-action={button.action}\n className={`rounded border border-border px-3 py-1 ${i === 0 ? 'bg-primary text-primary-foreground' : 'hover:bg-muted'}`}\n onClick={() => onResolve(button.action)}\n >\n {button.label}\n </button>\n ))}\n </div>\n </div>\n </div>\n );\n};\n","import React, { useMemo, useState } from 'react';\nimport {\n CONDITIONAL_FORMAT_ICON_SETS,\n CONDITIONAL_FORMAT_PRESETS,\n CONDITIONAL_FORMAT_STYLE_PRESETS,\n CONDITIONAL_FORMAT_TIME_PERIODS,\n DATA_VALIDATION_ERROR_STYLE_OPTIONS,\n DATA_VALIDATION_OPERATOR_OPTIONS,\n DATA_VALIDATION_TYPE_OPTIONS,\n createConditionalFormatRule,\n describeConditionalFormat,\n describeDataValidation,\n formatRuleRanges,\n getConditionalFormatCss,\n parseRuleRanges,\n type CellRange,\n type ConditionalFormatIconSet,\n type ConditionalFormatPresetKind,\n type ConditionalFormatRule,\n type ConditionalFormatTimePeriod,\n type DataValidationErrorStyle,\n type DataValidationOperator,\n type DataValidationType\n} from '@pixerate/editor/spreadsheet';\nimport type { useSpreadsheetEditor } from './useSpreadsheetEditor';\n\ntype SpreadsheetState = ReturnType<typeof useSpreadsheetEditor>;\n\nexport interface SpreadsheetRulePanelProps {\n state: SpreadsheetState;\n onClose: () => void;\n}\n\nconst inputClass = 'w-full rounded border border-border bg-background px-1.5 py-0.5 text-xs text-foreground';\nconst buttonClass = 'rounded border border-border px-2 py-0.5 hover:bg-muted disabled:opacity-40';\n\nfunction selectionText(range: CellRange | null): string {\n return range ? formatRuleRanges([range]) : 'A1';\n}\n\n/** Frame shared by both managers: a compact side panel that keeps keys away from the grid. */\nconst PanelFrame: React.FC<{ title: string; label: string; onClose: () => void; children: React.ReactNode }> = ({\n title,\n label,\n onClose,\n children\n}) => (\n <div\n role=\"dialog\"\n aria-label={label}\n className=\"fixed right-4 top-16 z-40 flex max-h-[calc(100vh-5rem)] w-80 flex-col overflow-y-auto rounded-md border border-border bg-popover p-3 text-xs text-popover-foreground shadow-lg\"\n style={{ background: 'var(--popover, var(--background, #fff))' }}\n onKeyDown={(e) => {\n e.stopPropagation();\n if (e.key === 'Escape') onClose();\n }}\n onContextMenu={(e) => e.stopPropagation()}\n >\n <div className=\"mb-2 flex items-center justify-between\">\n <h2 className=\"text-sm font-semibold\">{title}</h2>\n <button type=\"button\" aria-label=\"Close\" className=\"px-1 text-muted-foreground hover:text-foreground\" onClick={onClose}>\n ✕\n </button>\n </div>\n {children}\n </div>\n);\n\n/** Swatch showing a rule's look (fill, font colour, bold) or its kind. */\nfunction RuleSwatch({ rule }: { rule: ConditionalFormatRule }) {\n if (rule.type === 'colorScale') {\n return (\n <span\n aria-hidden=\"true\"\n className=\"inline-block h-3 w-6 shrink-0 rounded-sm border border-border\"\n style={{ background: `linear-gradient(90deg, ${rule.stops.map((s) => s.color).join(', ')})` }}\n />\n );\n }\n if (rule.type === 'dataBar') {\n return <span aria-hidden=\"true\" className=\"inline-block h-3 w-6 shrink-0 rounded-sm\" style={{ background: rule.color ?? '#638ec6' }} />;\n }\n if (rule.type === 'iconSet') return <span aria-hidden=\"true\" className=\"shrink-0\">●</span>;\n const css = getConditionalFormatCss(rule.style);\n return (\n <span aria-hidden=\"true\" className=\"inline-flex h-4 w-6 shrink-0 items-center justify-center rounded-sm border border-border\" style={css}>\n Aa\n </span>\n );\n}\n\n/**\n * Conditional formatting manager: the sheet's rules in priority order (move,\n * stop if true, delete) and a form to add a rule to a range.\n */\nexport const SpreadsheetConditionalFormatPanel: React.FC<SpreadsheetRulePanelProps> = ({ state, onClose }) => {\n const rules = state.document.table?.conditionalFormats ?? [];\n const [kind, setKind] = useState<ConditionalFormatPresetKind>('greaterThan');\n const [appliesTo, setAppliesTo] = useState(() => selectionText(state.selectedRange));\n const [value, setValue] = useState('');\n const [value2, setValue2] = useState('');\n const [text, setText] = useState('');\n const [formula, setFormula] = useState('=');\n const [rank, setRank] = useState('10');\n const [period, setPeriod] = useState<ConditionalFormatTimePeriod>('today');\n const [iconSet, setIconSet] = useState<ConditionalFormatIconSet>('3TrafficLights1');\n const [color, setColor] = useState('#638ec6');\n const [styleId, setStyleId] = useState(CONDITIONAL_FORMAT_STYLE_PRESETS[0].id);\n const preset = useMemo(() => CONDITIONAL_FORMAT_PRESETS.find((p) => p.kind === kind)!, [kind]);\n const ranges = parseRuleRanges(appliesTo);\n\n const add = () => {\n if (!ranges) return;\n state.addConditionalFormat(\n createConditionalFormatRule({\n kind,\n ranges,\n value,\n value2,\n text,\n formula,\n rank: Number(rank) || 10,\n period,\n iconSet,\n color,\n style: CONDITIONAL_FORMAT_STYLE_PRESETS.find((s) => s.id === styleId)?.style\n })\n );\n };\n\n return (\n <PanelFrame title=\"Conditional formatting\" label=\"Conditional formatting rules\" onClose={onClose}>\n <ol className=\"mb-3 flex flex-col gap-1\" aria-label=\"Rules in priority order\">\n {rules.length === 0 && <li className=\"text-muted-foreground\">No rules on this sheet.</li>}\n {rules.map((rule, i) => (\n <li key={rule.id} data-rule-id={rule.id} className=\"flex items-center gap-1.5 rounded border border-border px-1.5 py-1\">\n <RuleSwatch rule={rule} />\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate\" title={describeConditionalFormat(rule)}>\n {describeConditionalFormat(rule)}\n </div>\n <div className=\"truncate font-mono text-[10px] text-muted-foreground\">{formatRuleRanges(rule.ranges)}</div>\n </div>\n <label className=\"flex items-center gap-0.5 text-[10px]\" title=\"Stop if true\">\n <input\n type=\"checkbox\"\n aria-label=\"Stop if true\"\n checked={!!rule.stopIfTrue}\n onChange={(e) => state.updateConditionalFormat(rule.id, { stopIfTrue: e.target.checked })}\n />\n Stop\n </label>\n <button type=\"button\" aria-label=\"Move up\" className={buttonClass} disabled={i === 0} onClick={() => state.moveConditionalFormat(rule.id, { by: -1 })}>\n ▲\n </button>\n <button\n type=\"button\"\n aria-label=\"Move down\"\n className={buttonClass}\n disabled={i === rules.length - 1}\n onClick={() => state.moveConditionalFormat(rule.id, { by: 1 })}\n >\n ▼\n </button>\n <button type=\"button\" aria-label=\"Delete rule\" className={buttonClass} onClick={() => state.deleteConditionalFormat(rule.id)}>\n ✕\n </button>\n </li>\n ))}\n </ol>\n\n <fieldset className=\"flex flex-col gap-1.5 border-t border-border pt-2\">\n <legend className=\"sr-only\">New rule</legend>\n <label className=\"flex flex-col gap-0.5\">\n Format cells\n <select aria-label=\"Rule type\" className={inputClass} value={kind} onChange={(e) => setKind(e.target.value as ConditionalFormatPresetKind)}>\n {CONDITIONAL_FORMAT_PRESETS.map((p) => (\n <option key={p.kind} value={p.kind}>\n {p.label}\n </option>\n ))}\n </select>\n </label>\n {preset.fields.includes('value') && (\n <input aria-label=\"Value\" placeholder=\"Value or =formula\" className={inputClass} value={value} onChange={(e) => setValue(e.target.value)} />\n )}\n {preset.fields.includes('value2') && (\n <input aria-label=\"Second value\" placeholder=\"and\" className={inputClass} value={value2} onChange={(e) => setValue2(e.target.value)} />\n )}\n {preset.fields.includes('text') && (\n <input aria-label=\"Text\" placeholder=\"Text\" className={inputClass} value={text} onChange={(e) => setText(e.target.value)} />\n )}\n {preset.fields.includes('formula') && (\n <input aria-label=\"Formula\" placeholder=\"=$A1>10\" className={inputClass} value={formula} onChange={(e) => setFormula(e.target.value)} />\n )}\n {preset.fields.includes('rank') && (\n <input aria-label=\"Rank\" type=\"number\" min={1} className={inputClass} value={rank} onChange={(e) => setRank(e.target.value)} />\n )}\n {preset.fields.includes('period') && (\n <select aria-label=\"Period\" className={inputClass} value={period} onChange={(e) => setPeriod(e.target.value as ConditionalFormatTimePeriod)}>\n {CONDITIONAL_FORMAT_TIME_PERIODS.map((p) => (\n <option key={p.period} value={p.period}>\n {p.label}\n </option>\n ))}\n </select>\n )}\n {preset.fields.includes('iconSet') && (\n <select aria-label=\"Icon set\" className={inputClass} value={iconSet} onChange={(e) => setIconSet(e.target.value as ConditionalFormatIconSet)}>\n {CONDITIONAL_FORMAT_ICON_SETS.map((set) => (\n <option key={set} value={set}>\n {set}\n </option>\n ))}\n </select>\n )}\n {preset.fields.includes('color') && (\n <input aria-label=\"Bar colour\" type=\"color\" className=\"h-6 w-12\" value={color} onChange={(e) => setColor(e.target.value)} />\n )}\n {preset.usesStyle && (\n <select aria-label=\"Style\" className={inputClass} value={styleId} onChange={(e) => setStyleId(e.target.value)}>\n {CONDITIONAL_FORMAT_STYLE_PRESETS.map((s) => (\n <option key={s.id} value={s.id}>\n {s.label}\n </option>\n ))}\n </select>\n )}\n <label className=\"flex flex-col gap-0.5\">\n Applies to\n <input aria-label=\"Applies to\" className={`${inputClass} font-mono`} value={appliesTo} onChange={(e) => setAppliesTo(e.target.value)} />\n </label>\n <div className=\"flex justify-between gap-2\">\n <button type=\"button\" className={buttonClass} onClick={() => setAppliesTo(selectionText(state.selectedRange))}>\n Use selection\n </button>\n <button type=\"button\" className={buttonClass} disabled={!ranges} onClick={add}>\n Add rule\n </button>\n </div>\n </fieldset>\n </PanelFrame>\n );\n};\n\n/**\n * Data validation manager: the sheet's rules (delete), a form to validate a\n * range, and \"circle invalid data\".\n */\nexport const SpreadsheetDataValidationPanel: React.FC<SpreadsheetRulePanelProps> = ({ state, onClose }) => {\n const rules = state.document.table?.dataValidations ?? [];\n const [type, setType] = useState<DataValidationType>('list');\n const [operator, setOperator] = useState<DataValidationOperator>('between');\n const [formula1, setFormula1] = useState('');\n const [formula2, setFormula2] = useState('');\n const [errorStyle, setErrorStyle] = useState<DataValidationErrorStyle>('stop');\n const [errorMessage, setErrorMessage] = useState('');\n const [inputMessage, setInputMessage] = useState('');\n const [ignoreBlank, setIgnoreBlank] = useState(true);\n const [appliesTo, setAppliesTo] = useState(() => selectionText(state.selectedRange));\n const ranges = parseRuleRanges(appliesTo);\n const usesOperator = type === 'whole' || type === 'decimal' || type === 'date' || type === 'time' || type === 'textLength';\n const needsTwo = usesOperator && (operator === 'between' || operator === 'notBetween');\n const circles = state.controller.getInvalidDataCircles();\n\n const apply = () => {\n if (!ranges) return;\n state.addDataValidation({\n ranges,\n type,\n ...(usesOperator ? { operator } : {}),\n ...(formula1 ? { formula1 } : {}),\n ...(needsTwo && formula2 ? { formula2 } : {}),\n errorStyle,\n ...(errorMessage ? { errorMessage } : {}),\n ...(inputMessage ? { inputMessage } : {}),\n ignoreBlank\n });\n };\n\n return (\n <PanelFrame title=\"Data validation\" label=\"Data validation rules\" onClose={onClose}>\n <ul className=\"mb-3 flex flex-col gap-1\" aria-label=\"Validation rules\">\n {rules.length === 0 && <li className=\"text-muted-foreground\">No validation on this sheet.</li>}\n {rules.map((rule) => (\n <li key={rule.id} data-rule-id={rule.id} className=\"flex items-center gap-1.5 rounded border border-border px-1.5 py-1\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate\" title={describeDataValidation(rule)}>\n {describeDataValidation(rule)}\n </div>\n <div className=\"truncate font-mono text-[10px] text-muted-foreground\">\n {formatRuleRanges(rule.ranges)} · {rule.errorStyle ?? 'stop'}\n </div>\n </div>\n <button type=\"button\" aria-label=\"Delete rule\" className={buttonClass} onClick={() => state.deleteDataValidation(rule.id)}>\n ✕\n </button>\n </li>\n ))}\n </ul>\n\n <fieldset className=\"flex flex-col gap-1.5 border-t border-border pt-2\">\n <legend className=\"sr-only\">New validation</legend>\n <label className=\"flex flex-col gap-0.5\">\n Allow\n <select aria-label=\"Allow\" className={inputClass} value={type} onChange={(e) => setType(e.target.value as DataValidationType)}>\n {DATA_VALIDATION_TYPE_OPTIONS.map((o) => (\n <option key={o.type} value={o.type}>\n {o.label}\n </option>\n ))}\n </select>\n </label>\n {usesOperator && (\n <select aria-label=\"Operator\" className={inputClass} value={operator} onChange={(e) => setOperator(e.target.value as DataValidationOperator)}>\n {DATA_VALIDATION_OPERATOR_OPTIONS.map((o) => (\n <option key={o.operator} value={o.operator}>\n {o.label}\n </option>\n ))}\n </select>\n )}\n {type !== 'any' && (\n <input\n aria-label={type === 'list' ? 'Source' : type === 'custom' ? 'Formula' : needsTwo ? 'Minimum' : 'Value'}\n placeholder={type === 'list' ? 'Low,Medium,High or =$H$1:$H$5' : type === 'custom' ? '=A1>0' : 'Value or =formula'}\n className={inputClass}\n value={formula1}\n onChange={(e) => setFormula1(e.target.value)}\n />\n )}\n {needsTwo && <input aria-label=\"Maximum\" placeholder=\"Maximum\" className={inputClass} value={formula2} onChange={(e) => setFormula2(e.target.value)} />}\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" checked={ignoreBlank} onChange={(e) => setIgnoreBlank(e.target.checked)} /> Ignore blank\n </label>\n <input aria-label=\"Input message\" placeholder=\"Input message (optional)\" className={inputClass} value={inputMessage} onChange={(e) => setInputMessage(e.target.value)} />\n <div className=\"flex gap-1\">\n <select aria-label=\"Error style\" className={inputClass} value={errorStyle} onChange={(e) => setErrorStyle(e.target.value as DataValidationErrorStyle)}>\n {DATA_VALIDATION_ERROR_STYLE_OPTIONS.map((o) => (\n <option key={o.style} value={o.style}>\n {o.label}\n </option>\n ))}\n </select>\n </div>\n <input aria-label=\"Error message\" placeholder=\"Error message (optional)\" className={inputClass} value={errorMessage} onChange={(e) => setErrorMessage(e.target.value)} />\n <label className=\"flex flex-col gap-0.5\">\n Applies to\n <input aria-label=\"Applies to\" className={`${inputClass} font-mono`} value={appliesTo} onChange={(e) => setAppliesTo(e.target.value)} />\n </label>\n <div className=\"flex flex-wrap justify-between gap-2\">\n <button type=\"button\" className={buttonClass} onClick={() => setAppliesTo(selectionText(state.selectedRange))}>\n Use selection\n </button>\n <button type=\"button\" className={buttonClass} disabled={!ranges} onClick={() => ranges && ranges.forEach((r) => state.clearDataValidation(r))}>\n Clear\n </button>\n <button type=\"button\" className={buttonClass} disabled={!ranges} onClick={apply}>\n Apply\n </button>\n </div>\n <button type=\"button\" className={buttonClass} aria-pressed={circles} onClick={() => state.setInvalidDataCircles(!circles)}>\n {circles ? 'Clear validation circles' : 'Circle invalid data'}\n </button>\n </fieldset>\n </PanelFrame>\n );\n};\n","import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, type RefObject } from 'react';\nimport {\n fullSpreadsheetViewWindow,\n getSpreadsheetScrollToCell,\n getSpreadsheetViewWindow,\n measureSpreadsheetView,\n sameSpreadsheetViewWindow,\n shouldVirtualizeSpreadsheet,\n type CellCoordinate,\n type CellRange,\n type SpreadsheetViewMetrics,\n type SpreadsheetViewModel,\n type SpreadsheetViewport,\n type SpreadsheetViewWindow\n} from '@pixerate/editor/spreadsheet';\n\n// Browsers without layout effects on the server: fall back to useEffect there.\nconst useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;\n\nexport interface SpreadsheetViewportOptions {\n /** `'auto'` (default): virtualise large views only; `true` / `false` force it. */\n virtualize?: boolean | 'auto';\n /** Merged ranges, rendered whole when they cross the window's edge. */\n merges?: readonly CellRange[];\n /** Scrolled into view when it changes (virtualised views only). */\n activeCell?: CellCoordinate | null;\n overscanRows?: number;\n overscanColumns?: number;\n}\n\nexport interface SpreadsheetViewportState {\n metrics: SpreadsheetViewMetrics;\n /** What to render; `virtual: false` renders every row and column. */\n window: SpreadsheetViewWindow;\n /** Attach to the scroll container's `onScroll`. */\n onScroll: () => void;\n}\n\n/**\n * Virtualised rendering for `SpreadsheetEditor`: tracks the scroll\n * container (`scrollRef`), works out the window of rows and columns to\n * render, and scrolls the active cell into view.\n */\nexport function useSpreadsheetViewport(\n scrollRef: RefObject<HTMLElement | null>,\n view: SpreadsheetViewModel,\n options: SpreadsheetViewportOptions = {}\n): SpreadsheetViewportState {\n const metrics = useMemo(() => measureSpreadsheetView(view), [view]);\n const virtual = shouldVirtualizeSpreadsheet(view, options.virtualize ?? 'auto');\n const [viewport, setViewport] = useState<SpreadsheetViewport>({ scrollTop: 0, scrollLeft: 0, width: 0, height: 0 });\n const windowOptions = useMemo(\n () => ({ merges: options.merges, overscanRows: options.overscanRows, overscanColumns: options.overscanColumns }),\n [options.merges, options.overscanRows, options.overscanColumns]\n );\n\n const win = useMemo(\n () => (virtual ? getSpreadsheetViewWindow(metrics, viewport, windowOptions) : fullSpreadsheetViewWindow(metrics)),\n [virtual, metrics, viewport, windowOptions]\n );\n\n // Read by the scroll handler, which must not change identity.\n const latest = useRef({ metrics, viewport, virtual, windowOptions });\n latest.current = { metrics, viewport, virtual, windowOptions };\n\n const readViewport = useCallback((): SpreadsheetViewport | null => {\n const el = scrollRef.current;\n if (!el) return null;\n return { scrollTop: el.scrollTop, scrollLeft: el.scrollLeft, width: el.clientWidth, height: el.clientHeight };\n }, [scrollRef]);\n\n /** Stores a new viewport, re-rendering only when the window it gives changes. */\n const updateViewport = useCallback((next: SpreadsheetViewport) => {\n setViewport((prev) => {\n const { metrics: m, virtual: v, windowOptions: o } = latest.current;\n if (!v) return prev;\n const same =\n prev.width === next.width &&\n prev.height === next.height &&\n sameSpreadsheetViewWindow(getSpreadsheetViewWindow(m, prev, o), getSpreadsheetViewWindow(m, next, o));\n return same ? prev : next;\n });\n }, []);\n\n const onScroll = useCallback(() => {\n const next = readViewport();\n if (next) updateViewport(next);\n }, [readViewport, updateViewport]);\n\n // Measure the container, and again whenever it is resized.\n useIsomorphicLayoutEffect(() => {\n if (!virtual) return;\n onScroll();\n const el = scrollRef.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => onScroll());\n observer.observe(el);\n return () => observer.disconnect();\n }, [virtual, onScroll, scrollRef]);\n\n // Keyboard navigation and selection: bring the active cell into view.\n const activeRow = options.activeCell?.row;\n const activeCol = options.activeCell?.col;\n useIsomorphicLayoutEffect(() => {\n if (!virtual || activeRow === undefined || activeCol === undefined) return;\n const el = scrollRef.current;\n const current = latest.current.viewport;\n const measured = readViewport();\n const base: SpreadsheetViewport = measured\n ? { ...measured, scrollTop: Math.max(measured.scrollTop, 0), scrollLeft: Math.max(measured.scrollLeft, 0) }\n : current;\n const target = getSpreadsheetScrollToCell(latest.current.metrics, base, { row: activeRow, col: activeCol });\n if (!target) return;\n const next = { ...base, ...target };\n if (el) {\n if (target.scrollTop !== undefined) el.scrollTop = target.scrollTop;\n if (target.scrollLeft !== undefined) el.scrollLeft = target.scrollLeft;\n }\n // Some environments (jsdom) never fire the scroll event.\n updateViewport(next);\n // Only the active cell and the mode: scrolling away from the active cell\n // (or an edit elsewhere) must not snap back.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [virtual, activeRow, activeCol]);\n\n return { metrics, window: win, onScroll };\n}\n","import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { applyFormulaSuggestion, getFormulaHints, type FormulaNameSuggestionSource } from '@pixerate/editor/spreadsheet';\n\nexport interface FormulaHintsProps {\n /** The input being edited (a cell editor or the formula bar). */\n inputRef: React.RefObject<HTMLInputElement | null>;\n /** The input's current value. */\n value: string;\n /** Called with the new value when a suggestion is accepted. */\n onAccept: (value: string) => void;\n /** Maximum number of function suggestions (default 8). */\n limit?: number;\n /** Defined names to suggest too (e.g. `controller.getNameSuggestions()`). */\n names?: readonly FormulaNameSuggestionSource[];\n}\n\n/**\n * Formula autocomplete for an input: while the value starts with `=`, lists\n * functions matching the name at the caret (name, signature, description) and,\n * inside a call, shows the signature with the current argument highlighted.\n *\n * Keys are handled on the input itself, before the grid sees them: ArrowUp /\n * ArrowDown move the selection, Tab accepts it, Escape closes the list.\n * Enter is left alone so it still commits the cell.\n */\nexport const FormulaHints: React.FC<FormulaHintsProps> = ({ inputRef, value, onAccept, limit = 8, names }) => {\n const [caret, setCaret] = useState<number | null>(null);\n const [focused, setFocused] = useState(false);\n const [selected, setSelected] = useState(0);\n const [dismissed, setDismissed] = useState(false);\n const [position, setPosition] = useState<{ top: number; left: number; width: number } | null>(null);\n const pendingCaret = useRef<number | null>(null);\n\n const hints = useMemo(\n () => getFormulaHints(value, caret ?? value.length, { limit, names }),\n [value, caret, limit, names],\n );\n const suggestions = dismissed ? [] : hints.suggestions;\n const selectedIndex = Math.max(0, Math.min(selected, suggestions.length - 1));\n const visible = focused && value.trimStart().startsWith('=') && (suggestions.length > 0 || !!hints.activeCall);\n\n // The key listener reads the latest state through a ref.\n const latest = useRef({ suggestions, selected: selectedIndex, value, caret, onAccept });\n latest.current = { suggestions, selected: selectedIndex, value, caret, onAccept };\n\n const accept = (index: number) => {\n const { suggestions: list, value: current, caret: at, onAccept: commit } = latest.current;\n const suggestion = list[index];\n if (!suggestion) return;\n const next = applyFormulaSuggestion(current, at ?? current.length, suggestion);\n pendingCaret.current = next.caret;\n commit(next.value);\n };\n\n useEffect(() => {\n const input = inputRef.current;\n if (!input) return;\n const syncCaret = () => setCaret(input.selectionStart ?? input.value.length);\n const onInput = () => {\n setDismissed(false);\n setSelected(0);\n syncCaret();\n };\n const onFocus = () => {\n setFocused(true);\n syncCaret();\n };\n const onBlur = () => setFocused(false);\n // A native listener on the input runs before React's delegated handlers,\n // so stopping propagation keeps these keys away from the grid.\n const onKeyDown = (e: KeyboardEvent) => {\n const { suggestions: list } = latest.current;\n if (list.length === 0) return;\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n e.preventDefault();\n e.stopPropagation();\n const step = e.key === 'ArrowDown' ? 1 : -1;\n setSelected((i) => (i + step + list.length) % list.length);\n } else if (e.key === 'Tab' && !e.shiftKey) {\n e.preventDefault();\n e.stopPropagation();\n accept(latest.current.selected);\n } else if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n setDismissed(true);\n }\n };\n\n input.addEventListener('input', onInput);\n input.addEventListener('keyup', syncCaret);\n input.addEventListener('click', syncCaret);\n input.addEventListener('select', syncCaret);\n input.addEventListener('focus', onFocus);\n input.addEventListener('blur', onBlur);\n input.addEventListener('keydown', onKeyDown);\n // Inputs focused on mount (autoFocus) fired `focus` before this effect ran.\n if (typeof document !== 'undefined' && document.activeElement === input) onFocus();\n return () => {\n input.removeEventListener('input', onInput);\n input.removeEventListener('keyup', syncCaret);\n input.removeEventListener('click', syncCaret);\n input.removeEventListener('select', syncCaret);\n input.removeEventListener('focus', onFocus);\n input.removeEventListener('blur', onBlur);\n input.removeEventListener('keydown', onKeyDown);\n };\n }, [inputRef]);\n\n // After accepting, put the caret inside the inserted parenthesis.\n useLayoutEffect(() => {\n const input = inputRef.current;\n const at = pendingCaret.current;\n if (!input || at === null || input.value !== value) return;\n pendingCaret.current = null;\n input.setSelectionRange(at, at);\n setCaret(at);\n setSelected(0);\n }, [value, inputRef]);\n\n useLayoutEffect(() => {\n const input = inputRef.current;\n if (!visible || !input) return;\n const rect = input.getBoundingClientRect();\n setPosition({ top: rect.bottom + 2, left: rect.left, width: rect.width });\n }, [visible, value, inputRef]);\n\n if (!visible) return null;\n\n const { activeCall } = hints;\n return (\n <div\n data-formula-hints=\"\"\n className=\"rounded-md border border-border bg-popover text-popover-foreground shadow-md text-xs font-sans overflow-hidden\"\n style={{\n position: 'fixed',\n top: position?.top ?? 0,\n left: position?.left ?? 0,\n minWidth: Math.max(260, position?.width ?? 0),\n maxWidth: 440,\n zIndex: 50,\n visibility: position ? 'visible' : 'hidden'\n }}\n onMouseDown={(e) => e.preventDefault()}\n >\n {activeCall && (\n <div data-formula-signature=\"\" className=\"px-2 py-1.5 border-b border-border bg-muted/30\">\n <div className=\"font-mono\">\n {activeCall.parts.map((part, i) => (\n <span\n key={i}\n data-active={part.active ? '' : undefined}\n className={part.active ? 'font-bold text-primary underline' : ''}\n >\n {part.text}\n </span>\n ))}\n </div>\n <div className=\"mt-0.5 text-muted-foreground\">\n {activeCall.argument ? (\n <>\n <span className=\"font-semibold\">{activeCall.argument.name}</span>: {activeCall.argument.description}\n </>\n ) : (\n activeCall.description\n )}\n </div>\n </div>\n )}\n {suggestions.length > 0 && (\n <ul role=\"listbox\" aria-label=\"Formula suggestions\" className=\"max-h-64 overflow-auto py-1 m-0 list-none p-0\">\n {suggestions.map((s, i) => (\n <li\n key={`${s.kind ?? 'fn'}:${s.name}`}\n role=\"option\"\n aria-selected={i === selectedIndex}\n className={`cursor-pointer px-2 py-1 ${i === selectedIndex ? 'bg-primary/10' : 'hover:bg-muted/50'}`}\n onMouseEnter={() => setSelected(i)}\n onMouseDown={(e) => {\n // Keep focus in the input so the edit isn't committed by blur.\n e.preventDefault();\n accept(i);\n }}\n >\n <div className=\"font-mono font-semibold text-foreground\">{s.signature}</div>\n <div className=\"text-muted-foreground truncate\">{s.description}</div>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n};\n","import React, { useRef, useState } from 'react';\nimport { getSheetTabMenuItems, sheetDropIndex, type SpreadsheetMenuItem } from '@pixerate/editor/spreadsheet';\nimport type { useSpreadsheetEditor } from './useSpreadsheetEditor';\nimport { SpreadsheetContextMenu } from './SpreadsheetContextMenu';\n\nexport interface SheetTabsProps {\n state: ReturnType<typeof useSpreadsheetEditor>;\n readOnly?: boolean;\n className?: string;\n}\n\n/**\n * The workbook's sheet tabs: click to switch, double-click to rename, drag\n * to reorder, right-click for insert / rename / duplicate / move / delete\n * (delete asks to confirm), and a `+` button to add a sheet.\n */\nexport const SheetTabs: React.FC<SheetTabsProps> = ({ state, readOnly = false, className = '' }) => {\n const { controller, sheets } = state;\n const [renaming, setRenaming] = useState<{ id: string; draft: string } | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [menu, setMenu] = useState<{ x: number; y: number; items: SpreadsheetMenuItem[] } | null>(null);\n const dragFrom = useRef<number | null>(null);\n const [dropTarget, setDropTarget] = useState<{ index: number; after: boolean } | null>(null);\n\n const commitRename = (cancelOnError: boolean) => {\n if (!renaming) return;\n const sheet = sheets.find((s) => s.id === renaming.id);\n const name = renaming.draft.trim();\n if (!sheet || !name || name === sheet.name) {\n setRenaming(null);\n setError(null);\n return;\n }\n try {\n state.renameSheet(renaming.id, name);\n setRenaming(null);\n setError(null);\n } catch (err: any) {\n setError(err?.message ?? String(err));\n if (cancelOnError) setRenaming(null);\n }\n };\n\n const dropAfter = (e: React.DragEvent<HTMLElement>) => {\n const rect = e.currentTarget.getBoundingClientRect();\n return e.clientX > rect.left + rect.width / 2;\n };\n\n return (\n <div className={`flex flex-col ${className}`} data-sheet-tabs=\"\">\n <div\n role=\"tablist\"\n aria-label=\"Sheets\"\n className=\"flex items-center gap-0.5 overflow-x-auto border-t border-border bg-muted px-1 py-1 text-xs\"\n >\n {sheets.map((sheet, index) =>\n renaming?.id === sheet.id ? (\n <input\n key={sheet.id}\n aria-label=\"Sheet name\"\n autoFocus\n className=\"w-32 rounded border border-primary bg-background px-2 py-0.5 text-xs outline-none\"\n value={renaming.draft}\n onChange={(e) => setRenaming({ id: sheet.id, draft: e.target.value })}\n onFocus={(e) => e.currentTarget.select()}\n onKeyDown={(e) => {\n e.stopPropagation();\n if (e.key === 'Enter') commitRename(false);\n else if (e.key === 'Escape') {\n setRenaming(null);\n setError(null);\n }\n }}\n onBlur={() => commitRename(true)}\n />\n ) : (\n <button\n key={sheet.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={sheet.active}\n data-sheet-id={sheet.id}\n draggable={!readOnly}\n title={readOnly ? sheet.name : `${sheet.name} — double-click to rename, drag to move`}\n className={`whitespace-nowrap rounded px-3 py-0.5 ${\n sheet.active ? 'bg-background font-semibold text-foreground shadow-sm' : 'text-muted-foreground hover:bg-background/60'\n } ${dropTarget?.index === index ? (dropTarget.after ? 'border-r-2 border-primary' : 'border-l-2 border-primary') : ''}`}\n onClick={() => state.setActiveSheet(sheet.id)}\n onDoubleClick={() => {\n if (readOnly) return;\n setError(null);\n setRenaming({ id: sheet.id, draft: sheet.name });\n }}\n onContextMenu={(e) => {\n if (readOnly) return;\n e.preventDefault();\n setMenu({ x: e.clientX, y: e.clientY, items: getSheetTabMenuItems(controller, sheet.id, { onError: setError }) });\n }}\n onDragStart={(e) => {\n dragFrom.current = index;\n e.dataTransfer?.setData('text/plain', sheet.id);\n if (e.dataTransfer) e.dataTransfer.effectAllowed = 'move';\n }}\n onDragOver={(e) => {\n if (dragFrom.current === null) return;\n e.preventDefault();\n const after = dropAfter(e);\n setDropTarget((prev) => (prev?.index === index && prev.after === after ? prev : { index, after }));\n }}\n onDragLeave={() => setDropTarget(null)}\n onDrop={(e) => {\n e.preventDefault();\n const from = dragFrom.current;\n dragFrom.current = null;\n setDropTarget(null);\n if (from === null) return;\n state.moveSheet(sheets[from].id, sheetDropIndex(from, index, dropAfter(e)));\n }}\n onDragEnd={() => {\n dragFrom.current = null;\n setDropTarget(null);\n }}\n >\n {sheet.name}\n </button>\n ),\n )}\n {!readOnly && (\n <button\n type=\"button\"\n aria-label=\"Add sheet\"\n title=\"Add sheet\"\n className=\"rounded px-2 py-0.5 text-muted-foreground hover:bg-background/60\"\n onClick={() => {\n setError(null);\n state.addSheet();\n }}\n >\n +\n </button>\n )}\n </div>\n {error && (\n <div role=\"alert\" className=\"px-2 py-1 text-xs text-destructive\">\n {error}\n </div>\n )}\n {menu && (\n <SpreadsheetContextMenu\n items={menu.items}\n x={menu.x}\n y={menu.y}\n ariaLabel=\"Sheet actions\"\n onClose={() => setMenu(null)}\n />\n )}\n </div>\n );\n};\n","import React, { useMemo, useState } from 'react';\nimport { getNameManagerRows, parseFormula, type SpreadsheetNameRow } from '@pixerate/editor/spreadsheet';\nimport type { useSpreadsheetEditor } from './useSpreadsheetEditor';\n\nexport interface NameManagerProps {\n state: ReturnType<typeof useSpreadsheetEditor>;\n readOnly?: boolean;\n onClose?: () => void;\n className?: string;\n}\n\ninterface Draft {\n /** The name being edited (null for a new one). */\n original: { name: string; sheetId?: string } | null;\n name: string;\n refersTo: string;\n /** Sheet id, or '' for workbook scope. */\n scope: string;\n comment: string;\n}\n\nconst EMPTY_DRAFT: Draft = { original: null, name: '', refersTo: '=', scope: '', comment: '' };\n\n/**\n * A simple Name Manager: lists defined names (name, current value, formula,\n * scope) and adds, edits, renames and deletes them. Renaming a name rewrites\n * the formulas that use it; deleting one leaves them showing `#NAME?`.\n */\nexport const NameManager: React.FC<NameManagerProps> = ({ state, readOnly = false, onClose, className = '' }) => {\n const { controller, sheets } = state;\n const rows = useMemo(\n () => getNameManagerRows(controller),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [controller, state.document, state.names],\n );\n const [draft, setDraft] = useState<Draft>(EMPTY_DRAFT);\n const [error, setError] = useState<string | null>(null);\n\n const edit = (row: SpreadsheetNameRow) => {\n setError(null);\n setDraft({\n original: { name: row.name, sheetId: row.sheetId },\n name: row.name,\n refersTo: row.refersTo,\n scope: row.sheetId ?? '',\n comment: row.comment ?? '',\n });\n };\n\n const save = (e: React.FormEvent) => {\n e.preventDefault();\n const scope = draft.scope ? { sheet: draft.scope } : {};\n try {\n // Check before changing anything, so a failed edit keeps the old name.\n const invalid = controller.validateDefinedName(draft.name.trim());\n if (invalid) throw new Error(invalid);\n try {\n parseFormula(draft.refersTo.trim().startsWith('=') ? draft.refersTo.trim() : `=${draft.refersTo.trim()}`);\n } catch (err: any) {\n throw new Error(`There's a problem with this formula: ${err?.message ?? draft.refersTo}`);\n }\n const original = draft.original;\n if (original) {\n const originalScope = original.sheetId ? { sheet: original.sheetId } : {};\n if ((original.sheetId ?? '') !== draft.scope) {\n state.deleteName(original.name, originalScope);\n } else if (original.name !== draft.name) {\n state.renameName(original.name, draft.name.trim(), originalScope);\n }\n }\n state.defineName(draft.name.trim(), draft.refersTo, { ...scope, comment: draft.comment || undefined });\n setDraft(EMPTY_DRAFT);\n setError(null);\n } catch (err: any) {\n setError(err?.message ?? String(err));\n }\n };\n\n return (\n <section aria-label=\"Name Manager\" className={`flex flex-col gap-2 text-xs ${className}`} data-name-manager=\"\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"m-0 text-sm font-semibold\">Name Manager</h3>\n {onClose && (\n <button type=\"button\" aria-label=\"Close Name Manager\" className=\"rounded px-2 hover:bg-muted\" onClick={onClose}>\n ×\n </button>\n )}\n </div>\n <table className=\"w-full border-collapse\">\n <thead>\n <tr className=\"text-left text-muted-foreground\">\n <th className=\"px-1 font-medium\">Name</th>\n <th className=\"px-1 font-medium\">Value</th>\n <th className=\"px-1 font-medium\">Refers to</th>\n <th className=\"px-1 font-medium\">Scope</th>\n {!readOnly && <th className=\"px-1\" />}\n </tr>\n </thead>\n <tbody>\n {rows.length === 0 && (\n <tr>\n <td colSpan={5} className=\"px-1 py-2 text-muted-foreground\">\n No names yet.\n </td>\n </tr>\n )}\n {rows.map((row) => (\n <tr key={`${row.sheetId ?? ''}!${row.name}`} data-name={row.name} className=\"border-t border-border\" title={row.comment}>\n <td className=\"px-1 py-0.5 font-mono font-semibold\">{row.name}</td>\n <td className=\"px-1 py-0.5\">{row.value}</td>\n <td className=\"px-1 py-0.5 font-mono\">{row.refersTo}</td>\n <td className=\"px-1 py-0.5\">{row.scopeLabel}</td>\n {!readOnly && (\n <td className=\"whitespace-nowrap px-1 py-0.5 text-right\">\n <button type=\"button\" aria-label={`Edit ${row.name}`} className=\"rounded px-1 hover:bg-muted\" onClick={() => edit(row)}>\n Edit\n </button>\n <button\n type=\"button\"\n aria-label={`Delete ${row.name}`}\n className=\"rounded px-1 text-destructive hover:bg-muted\"\n onClick={() => {\n state.deleteName(row.name, row.sheetId ? { sheet: row.sheetId } : {});\n if (draft.original?.name === row.name && (draft.original.sheetId ?? '') === (row.sheetId ?? '')) setDraft(EMPTY_DRAFT);\n }}\n >\n Delete\n </button>\n </td>\n )}\n </tr>\n ))}\n </tbody>\n </table>\n {!readOnly && (\n <form className=\"grid grid-cols-[auto_1fr] items-center gap-x-2 gap-y-1\" onSubmit={save} aria-label={draft.original ? `Edit name ${draft.original.name}` : 'New name'}>\n <label htmlFor=\"pixerate-name-manager-name\">Name</label>\n <input\n id=\"pixerate-name-manager-name\"\n className=\"rounded border border-border bg-background px-1 py-0.5\"\n value={draft.name}\n onChange={(e) => setDraft({ ...draft, name: e.target.value })}\n />\n <label htmlFor=\"pixerate-name-manager-refers\">Refers to</label>\n <input\n id=\"pixerate-name-manager-refers\"\n className=\"rounded border border-border bg-background px-1 py-0.5 font-mono\"\n value={draft.refersTo}\n onChange={(e) => setDraft({ ...draft, refersTo: e.target.value })}\n />\n <label htmlFor=\"pixerate-name-manager-scope\">Scope</label>\n <select\n id=\"pixerate-name-manager-scope\"\n className=\"rounded border border-border bg-background px-1 py-0.5\"\n value={draft.scope}\n onChange={(e) => setDraft({ ...draft, scope: e.target.value })}\n >\n <option value=\"\">Workbook</option>\n {sheets.map((sheet) => (\n <option key={sheet.id} value={sheet.id}>\n {sheet.name}\n </option>\n ))}\n </select>\n <label htmlFor=\"pixerate-name-manager-comment\">Comment</label>\n <input\n id=\"pixerate-name-manager-comment\"\n className=\"rounded border border-border bg-background px-1 py-0.5\"\n value={draft.comment}\n onChange={(e) => setDraft({ ...draft, comment: e.target.value })}\n />\n <div className=\"col-span-2 flex gap-2\">\n <button type=\"submit\" className=\"rounded bg-primary px-2 py-0.5 text-primary-foreground\">\n {draft.original ? 'Save' : 'Add name'}\n </button>\n {draft.original && (\n <button\n type=\"button\"\n className=\"rounded px-2 py-0.5 hover:bg-muted\"\n onClick={() => {\n setDraft(EMPTY_DRAFT);\n setError(null);\n }}\n >\n Cancel\n </button>\n )}\n </div>\n </form>\n )}\n {error && (\n <div role=\"alert\" className=\"text-destructive\">\n {error}\n </div>\n )}\n </section>\n );\n};\n","import React, { createContext, useContext, useMemo } from 'react';\nimport type {\n\tButtonSlotProps,\n\tEditorSlotsMap,\n\tNodeHeaderSlotProps,\n\tTooltipSlotProps\n} from '@pixerate/editor';\n\nconst defaultSlots: EditorSlotsMap = {\n\tButton: (props: ButtonSlotProps) => (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclassName={`pixerate-btn ${props.className || ''}`}\n\t\t\tonClick={props.onClick}\n\t\t\tdisabled={props.disabled}\n\t\t>\n\t\t\t{props.children}\n\t\t</button>\n\t),\n\tTooltip: (props: TooltipSlotProps) => (\n\t\t<div className={`pixerate-tooltip-container ${props.className || ''}`} title={String(props.content)}>\n\t\t\t{props.children}\n\t\t</div>\n\t),\n\tNodeHeader: (props: NodeHeaderSlotProps) => (\n\t\t<div className={`pixerate-node-header flex items-center justify-between ${props.className || ''}`}>\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t{props.icon}\n\t\t\t\t<span className=\"font-semibold\">{props.title}</span>\n\t\t\t</div>\n\t\t\t{props.onClose && (\n\t\t\t\t<button type=\"button\" onClick={props.onClose} className=\"opacity-70 hover:opacity-100\">\n\t\t\t\t\t×\n\t\t\t\t</button>\n\t\t\t)}\n\t\t</div>\n\t)\n};\n\nconst EditorSlotsContext = createContext<EditorSlotsMap>(defaultSlots);\n\nexport interface EditorSlotsProviderProps {\n\tslots?: Partial<EditorSlotsMap>;\n\tchildren: React.ReactNode;\n}\n\n/**\n * Context provider allowing consumers to inject custom design system components into the editor.\n */\nexport function EditorSlotsProvider({ slots, children }: EditorSlotsProviderProps) {\n\tconst mergedSlots = useMemo(() => ({ ...defaultSlots, ...slots }), [slots]);\n\n\treturn (\n\t\t<EditorSlotsContext.Provider value={mergedSlots}>\n\t\t\t{children}\n\t\t</EditorSlotsContext.Provider>\n\t);\n}\n\n/**\n * Hook to access injected design system slots.\n */\nexport function useEditorSlots(): EditorSlotsMap {\n\treturn useContext(EditorSlotsContext);\n}\n","import { useRef, useState, useEffect, useCallback, useMemo } from 'react';\nimport type { ToolRegistry } from '@pixerate/editor/tools';\nimport {\n ImageEditorController,\n createImageEffectsToolProvider,\n type ImageEffectsToolProviderOptions,\n type ImageEditorOptions,\n type ImageEditorState,\n type ImageEditorTool,\n type CropBox,\n type AspectRatio,\n type ImageAdjustments,\n type DepthMaskOptions,\n type Annotation,\n type CreateAnnotationPayload,\n type ExportOptions,\n type SerializedImageEditorState,\n type AIResultOptions,\n type ImagePoint,\n type AdjustmentKind,\n type AdjustmentLayerInit,\n type AdjustmentLayerUpdate,\n type ImageHistogram,\n} from '@pixerate/editor/image-editor';\n\nexport interface UseImageEditorReturn {\n controller: ImageEditorController;\n state: ImageEditorState;\n canUndo: boolean;\n canRedo: boolean;\n setTool: (tool: ImageEditorTool) => void;\n setCrop: (crop: CropBox | null, addToHistory?: boolean) => void;\n applyCropPreset: (ratio: AspectRatio) => void;\n resetCrop: () => void;\n rotate: (degrees: number) => void;\n setRotation: (degrees: number) => void;\n flipHorizontal: () => void;\n flipVertical: () => void;\n setAdjustments: (partial: Partial<ImageAdjustments>, commitToHistory?: boolean) => void;\n resetAdjustments: () => void;\n /** Update to Current Process: re-render the adjustments with the latest process (one undo step). */\n upgradeProcess: () => boolean;\n /** Adds an adjustment layer (one undo step) and returns its id. */\n addAdjustmentLayer: (init: AdjustmentKind | AdjustmentLayerInit, index?: number) => string;\n updateAdjustmentLayer: (id: string, update: AdjustmentLayerUpdate, commitToHistory?: boolean) => boolean;\n removeAdjustmentLayer: (id: string) => boolean;\n moveAdjustmentLayer: (id: string, toIndex: number) => boolean;\n toggleAdjustmentLayer: (id: string, enabled?: boolean) => boolean;\n /** Histogram of the last rendered preview (after adjustments and layers); null before a render. */\n histogram: ImageHistogram | null;\n setDepthMask: (partial: Partial<DepthMaskOptions>) => void;\n resetDepthMask: () => void;\n addAnnotation: (annotation: CreateAnnotationPayload) => string;\n updateAnnotation: (id: string, partial: Partial<Annotation>, commitToHistory?: boolean) => void;\n removeAnnotation: (id: string) => void;\n clearAnnotations: () => void;\n selectAnnotation: (id: string | null) => void;\n undo: () => boolean;\n redo: () => boolean;\n reset: () => void;\n zoomIn: (factor?: number) => void;\n zoomOut: (factor?: number) => void;\n resetZoom: () => void;\n setZoom: (zoom: number) => void;\n setPan: (pan: ImagePoint) => void;\n setComparing: (comparing: boolean) => void;\n loadImage: (src: string | HTMLImageElement) => Promise<void>;\n toDataURL: (options?: ExportOptions) => Promise<string>;\n toBlob: (options?: ExportOptions) => Promise<Blob>;\n toJSON: () => SerializedImageEditorState;\n loadJSON: (data: SerializedImageEditorState) => void;\n renderMask: (options?: { useAnnotations?: boolean; useCrop?: boolean }) => Promise<HTMLCanvasElement>;\n toMaskDataURL: (options?: { useAnnotations?: boolean; useCrop?: boolean }) => Promise<string>;\n toSourceDataURL: (options?: Pick<ExportOptions, 'format' | 'quality'>) => Promise<string>;\n /** In documents with several layers (or `target: 'new-layer'`) the result goes to a new layer. */\n applyInpaintedImage: (newDataUrl: string, options?: AIResultOptions) => Promise<string | void>;\n /** In documents with several layers (or `target: 'new-layer'`) the result's alpha masks the active layer. */\n applyBackgroundRemovedImage: (newDataUrl: string, options?: AIResultOptions) => Promise<string | void>;\n}\n\nexport function useImageEditor(options: ImageEditorOptions = {}): UseImageEditorReturn {\n const controllerRef = useRef<ImageEditorController | null>(null);\n\n if (!controllerRef.current) {\n controllerRef.current = new ImageEditorController(options);\n }\n\n const controller = controllerRef.current;\n const [state, setState] = useState<ImageEditorState>(() => controller.getState());\n const [historyTicks, setHistoryTicks] = useState(0);\n const [histogram, setHistogram] = useState<ImageHistogram | null>(() => controller.getHistogram());\n\n useEffect(() => controller.subscribeHistogram(setHistogram), [controller]);\n\n useEffect(() => {\n const unsub = controller.subscribe((next) => {\n setState(next);\n setHistoryTicks((t) => t + 1);\n });\n return unsub;\n }, [controller]);\n\n // The constructor loads the initial image. Reload only when the `image`\n // option itself changes, not whenever the controller's source differs from\n // it (AI edits replace the source with a data URL and must not be reverted).\n const loadedImageRef = useRef(options.image);\n useEffect(() => {\n if (options.image === loadedImageRef.current) return;\n loadedImageRef.current = options.image;\n if (options.image) {\n controller.loadImage(options.image);\n }\n }, [options.image, controller]);\n\n const setTool = useCallback((tool: ImageEditorTool) => controller.setTool(tool), [controller]);\n const setCrop = useCallback(\n (crop: CropBox | null, addToHistory = true) => controller.setCrop(crop, addToHistory),\n [controller]\n );\n const applyCropPreset = useCallback((ratio: AspectRatio) => controller.applyCropPreset(ratio), [controller]);\n const resetCrop = useCallback(() => controller.resetCrop(), [controller]);\n const rotate = useCallback((deg: number) => controller.rotate(deg), [controller]);\n const setRotation = useCallback((deg: number) => controller.setRotation(deg), [controller]);\n const flipHorizontal = useCallback(() => controller.flipHorizontal(), [controller]);\n const flipVertical = useCallback(() => controller.flipVertical(), [controller]);\n const setAdjustments = useCallback(\n (partial: Partial<ImageAdjustments>, commitToHistory = true) =>\n controller.setAdjustments(partial, commitToHistory),\n [controller]\n );\n const resetAdjustments = useCallback(() => controller.resetAdjustments(), [controller]);\n const upgradeProcess = useCallback(() => controller.upgradeProcess(), [controller]);\n const addAdjustmentLayer = useCallback(\n (init: AdjustmentKind | AdjustmentLayerInit, index?: number) => controller.addAdjustmentLayer(init, index),\n [controller]\n );\n const updateAdjustmentLayer = useCallback(\n (id: string, update: AdjustmentLayerUpdate, commitToHistory = true) =>\n controller.updateAdjustmentLayer(id, update, commitToHistory),\n [controller]\n );\n const removeAdjustmentLayer = useCallback((id: string) => controller.removeAdjustmentLayer(id), [controller]);\n const moveAdjustmentLayer = useCallback((id: string, to: number) => controller.moveAdjustmentLayer(id, to), [controller]);\n const toggleAdjustmentLayer = useCallback(\n (id: string, enabled?: boolean) => controller.toggleAdjustmentLayer(id, enabled),\n [controller]\n );\n const setDepthMask = useCallback((partial: Partial<DepthMaskOptions>) => controller.setDepthMask(partial), [controller]);\n const resetDepthMask = useCallback(() => controller.resetDepthMask(), [controller]);\n const addAnnotation = useCallback((ann: CreateAnnotationPayload) => controller.addAnnotation(ann), [controller]);\n const updateAnnotation = useCallback(\n (id: string, partial: Partial<Annotation>, commitToHistory = true) =>\n controller.updateAnnotation(id, partial, commitToHistory),\n [controller]\n );\n const removeAnnotation = useCallback((id: string) => controller.removeAnnotation(id), [controller]);\n const clearAnnotations = useCallback(() => controller.clearAnnotations(), [controller]);\n const selectAnnotation = useCallback((id: string | null) => controller.selectAnnotation(id), [controller]);\n const undo = useCallback(() => controller.undo(), [controller]);\n const redo = useCallback(() => controller.redo(), [controller]);\n const reset = useCallback(() => controller.reset(), [controller]);\n const zoomIn = useCallback((factor?: number) => controller.zoomIn(factor), [controller]);\n const zoomOut = useCallback((factor?: number) => controller.zoomOut(factor), [controller]);\n const resetZoom = useCallback(() => controller.resetZoom(), [controller]);\n const setZoom = useCallback((zoom: number) => controller.setZoom(zoom), [controller]);\n const setPan = useCallback((pan: ImagePoint) => controller.setPan(pan), [controller]);\n const setComparing = useCallback((comp: boolean) => controller.setComparing(comp), [controller]);\n const loadImage = useCallback((src: string | HTMLImageElement) => controller.loadImage(src), [controller]);\n const toDataURL = useCallback((opts?: ExportOptions) => controller.toDataURL(opts), [controller]);\n const toBlob = useCallback((opts?: ExportOptions) => controller.toBlob(opts), [controller]);\n const toJSON = useCallback(() => controller.toJSON(), [controller]);\n const loadJSON = useCallback((data: SerializedImageEditorState) => controller.loadJSON(data), [controller]);\n const renderMask = useCallback(\n (opts?: { useAnnotations?: boolean; useCrop?: boolean }) => controller.renderMask(opts),\n [controller]\n );\n const toMaskDataURL = useCallback(\n (opts?: { useAnnotations?: boolean; useCrop?: boolean }) => controller.toMaskDataURL(opts),\n [controller]\n );\n const toSourceDataURL = useCallback(\n (opts?: Pick<ExportOptions, 'format' | 'quality'>) => controller.toSourceDataURL(opts),\n [controller]\n );\n const applyInpaintedImage = useCallback(\n (newDataUrl: string, options?: AIResultOptions) => controller.applyInpaintedImage(newDataUrl, options),\n [controller]\n );\n const applyBackgroundRemovedImage = useCallback(\n (newDataUrl: string, options?: AIResultOptions) => controller.applyBackgroundRemovedImage(newDataUrl, options),\n [controller]\n );\n\n return useMemo(\n () => ({\n controller,\n state,\n canUndo: controller.canUndo,\n canRedo: controller.canRedo,\n setTool,\n setCrop,\n applyCropPreset,\n resetCrop,\n rotate,\n setRotation,\n flipHorizontal,\n flipVertical,\n setAdjustments,\n resetAdjustments,\n upgradeProcess,\n addAdjustmentLayer,\n updateAdjustmentLayer,\n removeAdjustmentLayer,\n moveAdjustmentLayer,\n toggleAdjustmentLayer,\n histogram,\n setDepthMask,\n resetDepthMask,\n addAnnotation,\n updateAnnotation,\n removeAnnotation,\n clearAnnotations,\n selectAnnotation,\n undo,\n redo,\n reset,\n zoomIn,\n zoomOut,\n resetZoom,\n setZoom,\n setPan,\n setComparing,\n loadImage,\n toDataURL,\n toBlob,\n toJSON,\n loadJSON,\n renderMask,\n toMaskDataURL,\n toSourceDataURL,\n applyInpaintedImage,\n applyBackgroundRemovedImage,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [controller, state, historyTicks, histogram]\n );\n}\n\n/**\n * Registers the image editor's provider-effect tools (`search_effects`, `describe_effect`,\n * `apply_effect`, `add_effect_layer`, …) in `registry` while mounted. They work once an effects\n * provider is registered (see `useEffects`); before that the read tools say so and the write tools\n * refuse.\n */\nexport function useImageEffectsTools(\n registry: ToolRegistry | null | undefined,\n controller: ImageEditorController,\n options: ImageEffectsToolProviderOptions = {},\n): void {\n const { id, namespace, readOnly } = options;\n useEffect(() => {\n if (!registry) return;\n return registry.register(createImageEffectsToolProvider(controller, { id, namespace, readOnly }));\n }, [registry, controller, id, namespace, readOnly]);\n}\n","import React, { useRef, useEffect, useState, useCallback } from 'react';\nimport type {\n Annotation,\n CropBox,\n CropHandle,\n ExportOptions,\n ImageEditorTool,\n ImagePoint,\n InpaintHook,\n RemoveBackgroundHook,\n ImageEditorAIHooks,\n} from '@pixerate/editor/image-editor';\nimport {\n canvasToImagePoint,\n hitTestCrop,\n getCropCursor,\n calculateCropDrag,\n hitTestAnnotation,\n normalizeProcessVersion,\n LATEST_PROCESS_VERSION,\n IMAGE_ADJUSTMENT_CONTROLS,\n readAdjustmentControls,\n DEFAULT_SELECTION_TOOL_OPTIONS,\n SelectionGesture,\n PaintGesture,\n handlePaintShortcut,\n pointerPressure,\n FreeTransformTool,\n getViewportProjection,\n ShapeDrawGesture,\n TypeToolGesture,\n DEFAULT_SHAPE_TOOL_OPTIONS,\n DEFAULT_TYPE_TOOL_OPTIONS,\n type SelectionToolOptions,\n type ShapeToolOptions,\n type TypeToolOptions,\n type TransformHandle,\n} from '@pixerate/editor/image-editor';\nimport { useImageEditor, type UseImageEditorReturn } from './useImageEditor';\nimport { ControlSlider } from './ControlSlider';\nimport { Histogram } from './Histogram';\nimport { AdjustmentLayersPanel } from './AdjustmentLayersPanel';\nimport { LayersPanel } from './LayersPanel';\nimport { ImageProviderEffectsPanel } from './ImageProviderEffectsPanel';\nimport type { EffectProvider } from '@pixerate/editor/effects';\nimport { useEffects } from '../effects';\nimport { BrushOptionsBar } from './BrushOptionsBar';\nimport { ColorProfilePanel } from './ColorProfilePanel';\nimport { SelectionOptionsBar } from './SelectionOptionsBar';\nimport { RefineEdgePanel } from './RefineEdgePanel';\nimport { FreeTransformOptionsBar } from './FreeTransformOptionsBar';\nimport { ShapeOptionsBar } from './ShapeOptionsBar';\nimport { TypeOptionsBar } from './TypeOptionsBar';\n\nexport interface ImageEditorProps {\n editor?: UseImageEditorReturn;\n src?: string;\n className?: string;\n style?: React.CSSProperties;\n onSave?: (dataUrl: string) => void;\n exportOptions?: ExportOptions;\n onInpaint?: InpaintHook;\n onRemoveBackground?: RemoveBackgroundHook;\n aiHooks?: ImageEditorAIHooks;\n /**\n * An effects provider (see `@pixerate/editor/effects`), registered with the controller while\n * mounted: filter effects as smart filters and generator or overlay effects as effect layers,\n * with an Effects section in the Layers tab. Optional: without one the editor is as before.\n */\n effects?: EffectProvider | null;\n}\n\ntype TabType = 'crop' | 'adjust' | 'layers' | 'paint' | 'select' | 'annotate' | 'depth' | 'ai';\n\nexport const ImageEditor: React.FC<ImageEditorProps> = ({\n editor: externalEditor,\n src,\n className = '',\n style,\n onSave,\n exportOptions,\n onInpaint,\n onRemoveBackground,\n aiHooks,\n effects,\n}) => {\n const internalEditor = useImageEditor({ image: src });\n const editor = externalEditor || internalEditor;\n const { state, controller } = editor;\n useEffects(controller, effects);\n const effectsShown = !!controller.effectsProvider || state.layers.some(function has(l): boolean {\n return (l.type === 'pixel' && !!l.generator) || (l.type === 'smart' && !!l.smartFilters?.filters.some((f) => f.kind === 'effect')) || (l.type === 'group' && l.children.some(has));\n });\n const legacyProcess = normalizeProcessVersion(state.adjustments.process) < LATEST_PROCESS_VERSION;\n\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const [activeTab, setActiveTab] = useState<TabType>('crop');\n const [activeCropRatio, setActiveCropRatio] = useState<number | null>(null);\n\n // Selection tools (magic wand, marquees, lasso): options bar state and the pointer gesture.\n const [selectionOptions, setSelectionOptions] = useState<SelectionToolOptions>(DEFAULT_SELECTION_TOOL_OPTIONS);\n const selectionOptionsRef = useRef(selectionOptions);\n selectionOptionsRef.current = selectionOptions;\n const selectionGestureRef = useRef<SelectionGesture | null>(null);\n if (!selectionGestureRef.current || selectionGestureRef.current.controller !== controller) {\n selectionGestureRef.current = new SelectionGesture(controller, () => selectionOptionsRef.current);\n }\n const selectionDraftRef = useRef<ImagePoint[] | null>(null);\n const [selectionError, setSelectionError] = useState<string | null>(null);\n\n // Paint tools (Move, Brush, Eraser): the pointer gesture and the brush cursor.\n const paintGestureRef = useRef<PaintGesture | null>(null);\n const paintControllerRef = useRef(controller);\n if (!paintGestureRef.current || paintControllerRef.current !== controller) {\n paintGestureRef.current = new PaintGesture(controller);\n paintControllerRef.current = controller;\n }\n const brushCursorRef = useRef<ImagePoint | null>(null);\n const [paintError, setPaintError] = useState<string | null>(null);\n\n // Free Transform (Ctrl/Cmd+T): the shared tool drives a session; its overlay is drawn by the renderer.\n const transformToolRef = useRef<FreeTransformTool | null>(null);\n const transformControllerRef = useRef(controller);\n if (!transformToolRef.current || transformControllerRef.current !== controller) {\n transformToolRef.current?.cancel();\n transformToolRef.current = new FreeTransformTool(controller, {\n schedule: (run) => (typeof requestAnimationFrame !== 'undefined' ? requestAnimationFrame(run) : run()),\n });\n transformControllerRef.current = controller;\n }\n const transformTool = transformToolRef.current;\n const [, setTransformTick] = useState(0);\n const [transformCursor, setTransformCursor] = useState('default');\n\n // Shape and type tools: their options and gestures; type is edited on the canvas through a hidden textarea.\n const [shapeOptions, setShapeOptions] = useState<ShapeToolOptions>(DEFAULT_SHAPE_TOOL_OPTIONS);\n const shapeOptionsRef = useRef(shapeOptions);\n shapeOptionsRef.current = shapeOptions;\n const [typeOptions, setTypeOptions] = useState<TypeToolOptions>(DEFAULT_TYPE_TOOL_OPTIONS);\n const typeOptionsRef = useRef(typeOptions);\n typeOptionsRef.current = typeOptions;\n const shapeGestureRef = useRef<ShapeDrawGesture | null>(null);\n const typeToolRef = useRef<TypeToolGesture | null>(null);\n const shapeTypeControllerRef = useRef(controller);\n if (!shapeGestureRef.current || !typeToolRef.current || shapeTypeControllerRef.current !== controller) {\n typeToolRef.current?.finish();\n shapeGestureRef.current = new ShapeDrawGesture(controller, () => shapeOptionsRef.current);\n typeToolRef.current = new TypeToolGesture(controller, () => typeOptionsRef.current);\n shapeTypeControllerRef.current = controller;\n }\n const typeInputRef = useRef<HTMLTextAreaElement>(null);\n const [typeSession, setTypeSession] = useState(typeToolRef.current.session);\n const [shapeTypeError, setShapeTypeError] = useState<string | null>(null);\n\n // AI Tools state\n const [inpaintPrompt, setInpaintPrompt] = useState('');\n const [inpaintMaskMode, setInpaintMaskMode] = useState<'annotations' | 'crop'>('annotations');\n const [isRemovingBg, setIsRemovingBg] = useState(false);\n const [isInpainting, setIsInpainting] = useState(false);\n const [aiError, setAiError] = useState<string | null>(null);\n const [aiSuccess, setAiSuccess] = useState<string | null>(null);\n /** Where AI results go: by layer count (auto), a new layer / mask, or replacing the Background. */\n const [aiTarget, setAiTarget] = useState<'auto' | 'new-layer' | 'replace'>('auto');\n const aiOptions = aiTarget === 'auto' ? {} : { target: aiTarget };\n\n const effectiveOnInpaint = onInpaint || aiHooks?.onInpaint;\n const effectiveOnRemoveBg = onRemoveBackground || aiHooks?.onRemoveBackground;\n\n const handleRemoveBackground = async () => {\n if (!effectiveOnRemoveBg) {\n setAiError('No background removal hook is configured.');\n return;\n }\n setAiError(null);\n setAiSuccess(null);\n setIsRemovingBg(true);\n try {\n // AI hooks work in natural pixels (no crop or rotation): the source when the result replaces\n // it, the composite of the layers when the result becomes a layer or mask.\n const imageDataUrl = await controller.toAIInputDataURL(aiOptions);\n const result = await effectiveOnRemoveBg({ imageDataUrl });\n if (typeof result === 'string') {\n await editor.applyBackgroundRemovedImage(result, aiOptions);\n setAiSuccess('Background removed successfully!');\n } else {\n setAiSuccess('Background removal complete.');\n }\n } catch (err: any) {\n setAiError(err?.message || 'Failed to remove background.');\n } finally {\n setIsRemovingBg(false);\n }\n };\n\n const handleInpaint = async () => {\n if (!effectiveOnInpaint) {\n setAiError('No inpainting hook is configured.');\n return;\n }\n if (!inpaintPrompt.trim()) {\n setAiError('Please enter an inpainting prompt.');\n return;\n }\n setAiError(null);\n setAiSuccess(null);\n setIsInpainting(true);\n try {\n // Source image and mask share natural image space so they line up exactly.\n const imageDataUrl = await controller.toAIInputDataURL(aiOptions);\n const maskDataUrl = await editor.toMaskDataURL({\n useAnnotations: inpaintMaskMode === 'annotations',\n useCrop: inpaintMaskMode === 'crop',\n });\n const result = await effectiveOnInpaint({\n prompt: inpaintPrompt.trim(),\n imageDataUrl,\n maskDataUrl,\n cropBox: inpaintMaskMode === 'crop' ? editor.state.crop : null,\n });\n if (typeof result === 'string') {\n await editor.applyInpaintedImage(result, aiOptions);\n setAiSuccess('Inpainting applied successfully!');\n } else {\n setAiSuccess('Inpainting complete.');\n }\n } catch (err: any) {\n setAiError(err?.message || 'Failed to apply inpainting.');\n } finally {\n setIsInpainting(false);\n }\n };\n\n // Annotation drafting state\n const [activeColor, setActiveColor] = useState('#ef4444');\n const [strokeWidth, setStrokeWidth] = useState(3);\n const [fontSize, setFontSize] = useState(24);\n const [textInput, setTextInput] = useState('');\n\n // Live draft and drag references\n const draftAnnotationRef = useRef<Annotation | null>(null);\n const draftCropRef = useRef<CropBox | null>(null);\n const cropDragInfoRef = useRef<{\n handle: CropHandle | 'new';\n startCanvasPt: ImagePoint;\n startImgPt: ImagePoint;\n startCrop: CropBox;\n } | null>(null);\n const annotationDragInfoRef = useRef<{\n annId: string;\n startImgPt: ImagePoint;\n initialAnn: Annotation;\n } | null>(null);\n const isDrawingRef = useRef(false);\n const currentPathRef = useRef<ImagePoint[]>([]);\n const dragStartPointRef = useRef<ImagePoint | null>(null);\n\n // Canvas viewport sizing and re-render\n const renderCanvas = useCallback(\n async (draftAnnotation?: Annotation | null, draftCrop?: CropBox | null) => {\n const canvas = canvasRef.current;\n const container = containerRef.current;\n if (!canvas || !container) return;\n\n const vpWidth = container.clientWidth || 800;\n const vpHeight = container.clientHeight || 500;\n\n await controller.render(canvas, {\n viewportWidth: vpWidth,\n viewportHeight: vpHeight,\n showCropOverlay: activeTab === 'crop',\n showSelectionOverlay: true,\n interactive: true,\n draftAnnotation: draftAnnotation !== undefined ? draftAnnotation : draftAnnotationRef.current,\n draftCrop: draftCrop !== undefined ? draftCrop : draftCropRef.current,\n draftSelectionPath: selectionDraftRef.current,\n brushCursor:\n activeTab === 'paint' && brushCursorRef.current && controller.getState().activeTool !== 'move' && !transformTool.active\n ? { ...brushCursorRef.current, diameter: controller.getState().paint.brush.size }\n : null,\n freeTransform: transformTool.overlay(),\n textEdit: typeToolRef.current?.session?.alive ? typeToolRef.current.session.overlay() : null,\n });\n },\n [controller, activeTab, transformTool]\n );\n\n // The text being edited: re-render on every change, and end it when the tool or tab changes.\n useEffect(() => typeSession?.subscribe(() => void renderCanvas()), [typeSession, renderCanvas]);\n useEffect(() => {\n if (activeTab === 'annotate' && state.activeTool === 'type') return;\n if (typeToolRef.current?.session) {\n typeToolRef.current.finish();\n setTypeSession(null);\n void renderCanvas();\n }\n }, [activeTab, state.activeTool, renderCanvas]);\n const finishTyping = () => {\n typeToolRef.current?.finish();\n setTypeSession(null);\n void renderCanvas();\n };\n const handleTypeKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n const session = typeToolRef.current?.session;\n if (!session || e.nativeEvent.isComposing) return;\n if (e.key === 'Escape') {\n e.preventDefault();\n finishTyping();\n return;\n }\n if ((e.metaKey || e.ctrlKey) && ['z', 'y', 'c', 'x', 'v'].includes(e.key.toLowerCase())) return;\n if (session.handleKey(e)) {\n e.preventDefault();\n setShapeTypeError(session.error);\n }\n };\n const handleTypeInput = (e: React.FormEvent<HTMLTextAreaElement>) => {\n // Composed (IME) and pasted text arrives here; plain keys were handled on keydown.\n const el = e.currentTarget;\n const session = typeToolRef.current?.session;\n if (session && el.value && !(e.nativeEvent as InputEvent).isComposing) {\n session.insert(el.value);\n el.value = '';\n }\n };\n\n useEffect(() => transformTool.subscribe(() => {\n setTransformTick((n) => n + 1);\n void renderCanvas();\n }), [transformTool, renderCanvas]);\n\n /** The canvas point of a pointer event, its document point, and the screen scale. */\n const transformPoint = (e: React.PointerEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current!;\n const rect = canvas.getBoundingClientRect();\n const sx = rect.width > 0 ? canvas.width / rect.width : 1;\n const sy = rect.height > 0 ? canvas.height / rect.height : 1;\n const s = controller.getState();\n const cropping = activeTab === 'crop';\n const projection = getViewportProjection(s, canvas.width, canvas.height, cropping);\n const pt = canvasToImagePoint({ x: (e.clientX - rect.left) * sx, y: (e.clientY - rect.top) * sy }, s, canvas.width, canvas.height, cropping);\n transformTool.setView(projection.scale);\n return { pt, tolerance: 6 / (projection.scale || 1) };\n };\n const handleTransformPointerDown = (e: React.PointerEvent<HTMLCanvasElement>): boolean => {\n if (!transformTool.active) return false;\n if (e.button !== 0) return true;\n e.preventDefault();\n try {\n e.currentTarget.setPointerCapture?.(e.pointerId);\n } catch {\n // Synthetic events have no active pointer to capture.\n }\n const { pt, tolerance } = transformPoint(e);\n transformTool.down(pt, tolerance);\n return true;\n };\n const handleTransformPointerMove = (e: React.PointerEvent<HTMLCanvasElement>): boolean => {\n if (!transformTool.active) return false;\n const { pt, tolerance } = transformPoint(e);\n if (e.buttons & 1) transformTool.move(pt, e);\n else {\n const over: TransformHandle | null = transformTool.hit(pt, tolerance);\n setTransformCursor(transformTool.cursor(over));\n }\n return true;\n };\n const handleTransformPointerUp = (): boolean => {\n if (!transformTool.active) return false;\n transformTool.up();\n return true;\n };\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n const onKey = (e: KeyboardEvent) => {\n if (transformTool.key(e)) e.preventDefault();\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [transformTool]);\n\n\n useEffect(() => {\n const raf =\n typeof requestAnimationFrame !== 'undefined'\n ? requestAnimationFrame\n : (cb: () => void) => setTimeout(cb, 0) as unknown as number;\n const caf =\n typeof cancelAnimationFrame !== 'undefined'\n ? cancelAnimationFrame\n : (id: number) => clearTimeout(id);\n\n const animId = raf(() => {\n renderCanvas();\n });\n return () => caf(animId);\n }, [renderCanvas, state]);\n\n // Synchronize initial tool with activeTab\n useEffect(() => {\n if (activeTab === 'crop' && editor.state.activeTool !== 'crop') {\n editor.setTool('crop');\n }\n }, [activeTab, editor]);\n\n // Container resize observer to safely adapt viewport without feedback loops\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n if (typeof ResizeObserver !== 'undefined') {\n const observer = new ResizeObserver(() => {\n renderCanvas();\n });\n observer.observe(container);\n return () => observer.disconnect();\n } else {\n const handleResize = () => renderCanvas();\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }\n }, [renderCanvas]);\n\n // Convert mouse event coordinates to internal canvas pixel space\n const getCanvasEventPoint = (e: React.MouseEvent<HTMLCanvasElement>): ImagePoint => {\n const canvas = canvasRef.current;\n if (!canvas) return { x: 0, y: 0 };\n const rect = canvas.getBoundingClientRect();\n const scaleX = rect.width > 0 ? canvas.width / rect.width : 1;\n const scaleY = rect.height > 0 ? canvas.height / rect.height : 1;\n return {\n x: (e.clientX - rect.left) * scaleX,\n y: (e.clientY - rect.top) * scaleY,\n };\n };\n\n // Paint tools: pointer events (coalesced samples, pointer capture) into strokes and moves.\n const paintSamples = (e: React.PointerEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current!;\n const native = e.nativeEvent as PointerEvent;\n const events = typeof native.getCoalescedEvents === 'function' ? native.getCoalescedEvents() : [];\n const list = events.length ? events : [native];\n const rect = canvas.getBoundingClientRect();\n const sx = rect.width > 0 ? canvas.width / rect.width : 1;\n const sy = rect.height > 0 ? canvas.height / rect.height : 1;\n const s = controller.getState();\n return list.map((ev) => ({\n ...canvasToImagePoint({ x: (ev.clientX - rect.left) * sx, y: (ev.clientY - rect.top) * sy }, s, canvas.width, canvas.height, false),\n pressure: pointerPressure(ev),\n }));\n };\n const handlePaintPointerDown = (e: React.PointerEvent<HTMLCanvasElement>) => {\n if (handleTransformPointerDown(e)) return;\n if (activeTab !== 'paint' || e.button !== 0) return;\n e.preventDefault();\n try {\n e.currentTarget.setPointerCapture?.(e.pointerId);\n } catch {\n // Synthetic events have no active pointer to capture.\n }\n const [first] = paintSamples(e);\n setPaintError(paintGestureRef.current!.down({ ...first, altKey: e.altKey }));\n };\n const handlePaintPointerMove = (e: React.PointerEvent<HTMLCanvasElement>) => {\n if (handleTransformPointerMove(e)) return;\n if (activeTab !== 'paint') return;\n const samples = paintSamples(e);\n brushCursorRef.current = samples[samples.length - 1] ?? null;\n if (paintGestureRef.current!.active) paintGestureRef.current!.moveTo(samples);\n else void renderCanvas();\n };\n const handlePaintPointerUp = () => {\n if (handleTransformPointerUp()) return;\n if (activeTab !== 'paint') return;\n const g = paintGestureRef.current!;\n if (g.active) {\n g.up();\n if (g.error) setPaintError(g.error);\n }\n };\n\n useEffect(() => {\n if (activeTab !== 'paint' || typeof window === 'undefined') return;\n const onKey = (e: KeyboardEvent) => {\n if (handlePaintShortcut(controller, e)) e.preventDefault();\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [activeTab, controller]);\n\n // Pointer event handlers for drawing and annotations\n const handleMouseDown = (e: React.MouseEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current;\n if (!canvas || transformTool.active) return;\n const canvasPt = getCanvasEventPoint(e);\n\n if (activeTab === 'select') {\n const gesture = selectionGestureRef.current!;\n const imgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false);\n void gesture.begin(imgPt, e).then(() => setSelectionError(gesture.error));\n return;\n }\n\n if (activeTab === 'crop') {\n const activeCrop = draftCropRef.current || state.crop || {\n x: 0,\n y: 0,\n width: state.imageDimensions.width,\n height: state.imageDimensions.height,\n };\n const handle = hitTestCrop(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);\n const startImgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, true);\n\n if (handle) {\n cropDragInfoRef.current = {\n handle,\n startCanvasPt: canvasPt,\n startImgPt,\n startCrop: activeCrop,\n };\n } else {\n // Clicked outside crop box: start new crop selection\n cropDragInfoRef.current = {\n handle: 'new',\n startCanvasPt: canvasPt,\n startImgPt,\n startCrop: { x: startImgPt.x, y: startImgPt.y, width: 0, height: 0 },\n };\n }\n return;\n }\n\n if (activeTab === 'annotate' && (state.activeTool === 'shape' || state.activeTool === 'type')) {\n const imgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false);\n setShapeTypeError(null);\n if (state.activeTool === 'shape') shapeGestureRef.current!.down(imgPt);\n else {\n typeToolRef.current!.down(imgPt, { shift: e.shiftKey });\n setTypeSession(typeToolRef.current!.session);\n void renderCanvas();\n }\n return;\n }\n\n if (activeTab === 'annotate') {\n const imgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false);\n dragStartPointRef.current = imgPt;\n\n if (state.activeTool === 'select') {\n for (let i = state.annotations.length - 1; i >= 0; i--) {\n const ann = state.annotations[i];\n if (hitTestAnnotation(imgPt, ann)) {\n editor.selectAnnotation(ann.id);\n annotationDragInfoRef.current = {\n annId: ann.id,\n startImgPt: imgPt,\n initialAnn: { ...ann },\n };\n return;\n }\n }\n editor.selectAnnotation(null);\n return;\n }\n\n if (state.activeTool === 'pen') {\n isDrawingRef.current = true;\n currentPathRef.current = [imgPt];\n const draft: Annotation = {\n id: 'draft',\n type: 'pen',\n x: 0,\n y: 0,\n points: [imgPt],\n strokeColor: activeColor,\n strokeWidth,\n };\n draftAnnotationRef.current = draft;\n renderCanvas(draft);\n }\n }\n };\n\n const handleMouseMove = (e: React.MouseEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current;\n if (!canvas || transformTool.active) return;\n const canvasPt = getCanvasEventPoint(e);\n\n if (activeTab === 'select') {\n const gesture = selectionGestureRef.current!;\n if (gesture.active && gesture.move(canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false))) {\n selectionDraftRef.current = gesture.draftPath;\n renderCanvas();\n }\n return;\n }\n\n if (activeTab === 'crop') {\n const drag = cropDragInfoRef.current;\n if (drag) {\n const currentImgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, true);\n let newCrop: CropBox;\n\n if (drag.handle === 'new') {\n const minX = Math.max(0, Math.min(drag.startImgPt.x, currentImgPt.x));\n const minY = Math.max(0, Math.min(drag.startImgPt.y, currentImgPt.y));\n const maxX = Math.min(state.imageDimensions.width, Math.max(drag.startImgPt.x, currentImgPt.x));\n const maxY = Math.min(state.imageDimensions.height, Math.max(drag.startImgPt.y, currentImgPt.y));\n newCrop = {\n x: Math.round(minX),\n y: Math.round(minY),\n width: Math.round(Math.max(20, maxX - minX)),\n height: Math.round(Math.max(20, maxY - minY)),\n };\n } else {\n newCrop = calculateCropDrag(\n drag.startCrop,\n drag.handle,\n drag.startImgPt,\n currentImgPt,\n state.imageDimensions.width,\n state.imageDimensions.height,\n activeCropRatio,\n state.transform\n );\n }\n\n draftCropRef.current = newCrop;\n renderCanvas(null, newCrop);\n } else {\n const activeCrop = draftCropRef.current || state.crop || {\n x: 0,\n y: 0,\n width: state.imageDimensions.width,\n height: state.imageDimensions.height,\n };\n const handle = hitTestCrop(canvasPt, state, canvas.width, canvas.height, 14, activeCrop);\n canvas.style.cursor = getCropCursor(handle, state.transform);\n }\n return;\n }\n\n if (activeTab === 'annotate' && state.activeTool === 'shape') {\n const g = shapeGestureRef.current!;\n if (g.active) {\n g.move(canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false), { shift: e.shiftKey, alt: e.altKey });\n if (g.error) setShapeTypeError(g.error);\n }\n return;\n }\n\n if (activeTab === 'annotate') {\n // If moving selected annotation\n if (annotationDragInfoRef.current) {\n const drag = annotationDragInfoRef.current;\n const currentImgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false);\n const dx = currentImgPt.x - drag.startImgPt.x;\n const dy = currentImgPt.y - drag.startImgPt.y;\n editor.updateAnnotation(drag.annId, {\n x: Math.round(drag.initialAnn.x + dx),\n y: Math.round(drag.initialAnn.y + dy),\n });\n return;\n }\n\n const startPt = dragStartPointRef.current;\n if (!startPt) {\n // Update cursor for hover on select tool\n if (state.activeTool === 'select') {\n const imgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false);\n let hovered = false;\n for (let i = state.annotations.length - 1; i >= 0; i--) {\n if (hitTestAnnotation(imgPt, state.annotations[i])) {\n hovered = true;\n break;\n }\n }\n canvas.style.cursor = hovered ? 'move' : 'default';\n } else {\n canvas.style.cursor = 'crosshair';\n }\n return;\n }\n\n const currentImgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false);\n\n if (state.activeTool === 'pen' && isDrawingRef.current) {\n currentPathRef.current.push(currentImgPt);\n const draft: Annotation = {\n id: 'draft',\n type: 'pen',\n x: 0,\n y: 0,\n points: [...currentPathRef.current],\n strokeColor: activeColor,\n strokeWidth,\n };\n draftAnnotationRef.current = draft;\n renderCanvas(draft);\n } else if (state.activeTool === 'rect') {\n const w = currentImgPt.x - startPt.x;\n const h = currentImgPt.y - startPt.y;\n const draft: Annotation = {\n id: 'draft',\n type: 'rect',\n x: Math.min(startPt.x, currentImgPt.x),\n y: Math.min(startPt.y, currentImgPt.y),\n width: Math.abs(w),\n height: Math.abs(h),\n strokeColor: activeColor,\n strokeWidth,\n };\n draftAnnotationRef.current = draft;\n renderCanvas(draft);\n } else if (state.activeTool === 'circle') {\n const rx = Math.abs(currentImgPt.x - startPt.x) / 2;\n const ry = Math.abs(currentImgPt.y - startPt.y) / 2;\n const draft: Annotation = {\n id: 'draft',\n type: 'circle',\n x: Math.min(startPt.x, currentImgPt.x) + rx,\n y: Math.min(startPt.y, currentImgPt.y) + ry,\n radiusX: rx,\n radiusY: ry,\n strokeColor: activeColor,\n strokeWidth,\n };\n draftAnnotationRef.current = draft;\n renderCanvas(draft);\n } else if (state.activeTool === 'arrow') {\n const draft: Annotation = {\n id: 'draft',\n type: 'arrow',\n x: startPt.x,\n y: startPt.y,\n endX: currentImgPt.x,\n endY: currentImgPt.y,\n strokeColor: activeColor,\n strokeWidth,\n };\n draftAnnotationRef.current = draft;\n renderCanvas(draft);\n } else if (state.activeTool === 'line') {\n const draft: Annotation = {\n id: 'draft',\n type: 'line',\n x: startPt.x,\n y: startPt.y,\n endX: currentImgPt.x,\n endY: currentImgPt.y,\n strokeColor: activeColor,\n strokeWidth,\n };\n draftAnnotationRef.current = draft;\n renderCanvas(draft);\n }\n }\n };\n\n const handleMouseUp = (e: React.MouseEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current;\n if (!canvas || transformTool.active) return;\n const canvasPt = getCanvasEventPoint(e);\n\n if (activeTab === 'select') {\n const gesture = selectionGestureRef.current!;\n if (gesture.active) {\n gesture.end(canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false), e);\n selectionDraftRef.current = null;\n renderCanvas();\n }\n return;\n }\n\n if (activeTab === 'crop') {\n if (cropDragInfoRef.current) {\n if (\n draftCropRef.current &&\n draftCropRef.current.width >= 20 &&\n draftCropRef.current.height >= 20\n ) {\n editor.setCrop(draftCropRef.current, true);\n }\n cropDragInfoRef.current = null;\n draftCropRef.current = null;\n renderCanvas();\n }\n return;\n }\n\n if (activeTab === 'annotate' && state.activeTool === 'shape') {\n shapeGestureRef.current!.up();\n return;\n }\n if (activeTab === 'annotate' && state.activeTool === 'type') {\n const tool = typeToolRef.current!;\n tool.up(canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false));\n setTypeSession(tool.session);\n if (tool.error) setShapeTypeError(tool.error);\n void renderCanvas();\n // Keystrokes go to the hidden textarea while text is being edited.\n if (tool.session) setTimeout(() => typeInputRef.current?.focus(), 0);\n return;\n }\n\n if (activeTab === 'annotate') {\n if (annotationDragInfoRef.current) {\n annotationDragInfoRef.current = null;\n return;\n }\n\n const startPt = dragStartPointRef.current;\n if (startPt) {\n const currentImgPt = canvasToImagePoint(canvasPt, state, canvas.width, canvas.height, false);\n\n if (state.activeTool === 'pen' && isDrawingRef.current) {\n if (currentPathRef.current.length > 1) {\n editor.addAnnotation({\n type: 'pen',\n x: 0,\n y: 0,\n points: [...currentPathRef.current],\n strokeColor: activeColor,\n strokeWidth,\n });\n }\n isDrawingRef.current = false;\n currentPathRef.current = [];\n } else if (state.activeTool === 'rect') {\n const w = Math.abs(currentImgPt.x - startPt.x);\n const h = Math.abs(currentImgPt.y - startPt.y);\n if (w > 4 && h > 4) {\n editor.addAnnotation({\n type: 'rect',\n x: Math.min(startPt.x, currentImgPt.x),\n y: Math.min(startPt.y, currentImgPt.y),\n width: w,\n height: h,\n strokeColor: activeColor,\n strokeWidth,\n });\n }\n } else if (state.activeTool === 'circle') {\n const rx = Math.abs(currentImgPt.x - startPt.x) / 2;\n const ry = Math.abs(currentImgPt.y - startPt.y) / 2;\n if (rx > 4 && ry > 4) {\n editor.addAnnotation({\n type: 'circle',\n x: Math.min(startPt.x, currentImgPt.x) + rx,\n y: Math.min(startPt.y, currentImgPt.y) + ry,\n radiusX: rx,\n radiusY: ry,\n strokeColor: activeColor,\n strokeWidth,\n });\n }\n } else if (state.activeTool === 'arrow') {\n if (Math.hypot(currentImgPt.x - startPt.x, currentImgPt.y - startPt.y) > 4) {\n editor.addAnnotation({\n type: 'arrow',\n x: startPt.x,\n y: startPt.y,\n endX: currentImgPt.x,\n endY: currentImgPt.y,\n strokeColor: activeColor,\n strokeWidth,\n });\n }\n } else if (state.activeTool === 'line') {\n if (Math.hypot(currentImgPt.x - startPt.x, currentImgPt.y - startPt.y) > 4) {\n editor.addAnnotation({\n type: 'line',\n x: startPt.x,\n y: startPt.y,\n endX: currentImgPt.x,\n endY: currentImgPt.y,\n strokeColor: activeColor,\n strokeWidth,\n });\n }\n }\n\n draftAnnotationRef.current = null;\n dragStartPointRef.current = null;\n renderCanvas();\n }\n }\n };\n\n const handleAddText = () => {\n if (!textInput.trim()) return;\n editor.addAnnotation({\n type: 'text',\n x: 50,\n y: 50,\n text: textInput.trim(),\n fontSize,\n color: activeColor,\n });\n setTextInput('');\n };\n\n const handleExport = async () => {\n const dataUrl = await editor.toDataURL(exportOptions);\n if (onSave) {\n onSave(dataUrl);\n } else {\n // Default download trigger\n const link = document.createElement('a');\n link.download = `edited-image-${Date.now()}.png`;\n link.href = dataUrl;\n link.click();\n }\n };\n\n return (\n <div\n className={`flex flex-col bg-slate-900 border border-slate-800 rounded-xl overflow-hidden shadow-2xl text-slate-100 ${className}`}\n style={style}\n >\n {/* Top Action Header */}\n <div className=\"flex flex-wrap items-center justify-between px-4 py-3 bg-slate-950/80 border-b border-slate-800 gap-3\">\n {/* Navigation Tabs */}\n <div className=\"flex items-center gap-1 bg-slate-900 p-1 rounded-lg border border-slate-800 text-xs\">\n <button\n type=\"button\"\n onClick={() => {\n setActiveTab('crop');\n editor.setTool('crop');\n }}\n className={`px-3 py-1.5 rounded-md font-medium transition-colors ${\n activeTab === 'crop' ? 'bg-indigo-600 text-white shadow' : 'text-slate-400 hover:text-slate-200'\n }`}\n >\n Transform & Crop\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveTab('adjust');\n editor.setTool('select');\n }}\n className={`px-3 py-1.5 rounded-md font-medium transition-colors ${\n activeTab === 'adjust' ? 'bg-indigo-600 text-white shadow' : 'text-slate-400 hover:text-slate-200'\n }`}\n >\n Adjustments\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveTab('layers');\n editor.setTool('select');\n }}\n className={`px-3 py-1.5 rounded-md font-medium transition-colors ${\n activeTab === 'layers' ? 'bg-indigo-600 text-white shadow' : 'text-slate-400 hover:text-slate-200'\n }`}\n >\n Layers\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveTab('paint');\n editor.setTool('brush');\n }}\n className={`px-3 py-1.5 rounded-md font-medium transition-colors ${\n activeTab === 'paint' ? 'bg-indigo-600 text-white shadow' : 'text-slate-400 hover:text-slate-200'\n }`}\n >\n Paint\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveTab('select');\n editor.setTool('select');\n }}\n className={`px-3 py-1.5 rounded-md font-medium transition-colors ${\n activeTab === 'select' ? 'bg-indigo-600 text-white shadow' : 'text-slate-400 hover:text-slate-200'\n }`}\n >\n Select & Mask\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveTab('annotate');\n editor.setTool('pen');\n }}\n className={`px-3 py-1.5 rounded-md font-medium transition-colors ${\n activeTab === 'annotate' ? 'bg-indigo-600 text-white shadow' : 'text-slate-400 hover:text-slate-200'\n }`}\n >\n Annotations\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveTab('depth');\n editor.setTool('select');\n }}\n className={`px-3 py-1.5 rounded-md font-medium transition-colors ${\n activeTab === 'depth' ? 'bg-indigo-600 text-white shadow' : 'text-slate-400 hover:text-slate-200'\n }`}\n >\n Depth Mask\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveTab('ai');\n editor.setTool('select');\n }}\n className={`px-3 py-1.5 rounded-md font-medium transition-colors flex items-center gap-1.5 ${\n activeTab === 'ai' ? 'bg-indigo-600 text-white shadow' : 'text-slate-400 hover:text-slate-200'\n }`}\n >\n <svg className=\"w-3.5 h-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83\" />\n </svg>\n AI Tools\n </button>\n </div>\n\n {/* Global Action Tools (Undo/Redo, Zoom, Compare, Save) */}\n <div className=\"flex items-center gap-2 text-xs\">\n <button\n type=\"button\"\n disabled={!editor.canUndo}\n onClick={() => editor.undo()}\n className=\"p-1.5 rounded-lg border border-slate-800 bg-slate-900 text-slate-300 disabled:opacity-40 disabled:cursor-not-allowed hover:bg-slate-800\"\n title=\"Undo\"\n >\n ↩\n </button>\n <button\n type=\"button\"\n disabled={!editor.canRedo}\n onClick={() => editor.redo()}\n className=\"p-1.5 rounded-lg border border-slate-800 bg-slate-900 text-slate-300 disabled:opacity-40 disabled:cursor-not-allowed hover:bg-slate-800\"\n title=\"Redo\"\n >\n ↪\n </button>\n <button\n type=\"button\"\n onClick={() => editor.reset()}\n className=\"px-2 py-1.5 rounded-lg border border-slate-800 bg-slate-900 text-slate-400 hover:text-slate-200 hover:bg-slate-800\"\n >\n Reset\n </button>\n\n <div className=\"h-4 w-px bg-slate-800 mx-1\" />\n\n {/* Zoom */}\n <button\n type=\"button\"\n onClick={() => editor.zoomOut()}\n className=\"p-1.5 rounded-lg border border-slate-800 bg-slate-900 text-slate-300 hover:bg-slate-800\"\n title=\"Zoom Out\"\n >\n -\n </button>\n <span className=\"font-mono text-slate-400 w-10 text-center\">{Math.round(state.zoom * 100)}%</span>\n <button\n type=\"button\"\n onClick={() => editor.zoomIn()}\n className=\"p-1.5 rounded-lg border border-slate-800 bg-slate-900 text-slate-300 hover:bg-slate-800\"\n title=\"Zoom In\"\n >\n +\n </button>\n\n <div className=\"h-4 w-px bg-slate-800 mx-1\" />\n\n {/* Live Compare */}\n <button\n type=\"button\"\n onMouseDown={() => editor.setComparing(true)}\n onMouseUp={() => editor.setComparing(false)}\n onMouseLeave={() => editor.setComparing(false)}\n className=\"px-2.5 py-1.5 rounded-lg border border-slate-800 bg-slate-900 text-amber-400 hover:bg-slate-800 select-none active:bg-amber-950/40\"\n >\n Hold Compare\n </button>\n\n {/* Save / Export */}\n <button\n type=\"button\"\n onClick={handleExport}\n className=\"px-4 py-1.5 rounded-lg bg-emerald-600 hover:bg-emerald-500 text-white font-medium shadow-md shadow-emerald-900/30 transition-colors\"\n >\n Export Image\n </button>\n </div>\n </div>\n\n {/* Free Transform options bar (Ctrl/Cmd+T), above the viewport while a transform is open */}\n {transformTool.active && <FreeTransformOptionsBar tool={transformTool} className=\"border-b border-slate-800 bg-slate-900/95 px-4 py-2\" />}\n {!transformTool.active && transformTool.error && (\n <div role=\"alert\" className=\"border-b border-rose-900 bg-rose-950/80 px-4 py-1.5 text-xs text-rose-200\">\n {transformTool.error}\n </div>\n )}\n\n {/* Main Viewport + Sidebar Layout */}\n <div className=\"flex flex-col md:flex-row flex-1 min-h-[520px] md:h-[560px]\">\n {/* Canvas Area */}\n <div\n ref={containerRef}\n className=\"relative flex-1 h-[360px] md:h-full min-h-[320px] bg-slate-950 overflow-hidden select-none\"\n >\n <canvas\n ref={canvasRef}\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n onPointerDown={handlePaintPointerDown}\n onPointerMove={handlePaintPointerMove}\n onPointerUp={handlePaintPointerUp}\n onPointerCancel={() => paintGestureRef.current?.cancel()}\n data-testid=\"image-editor-canvas\"\n style={transformTool.active ? { cursor: transformCursor } : undefined}\n className={`absolute inset-0 w-full h-full block ${transformTool.active ? 'touch-none' : activeTab === 'paint' ? 'touch-none cursor-crosshair' : activeTab === 'annotate' && state.activeTool === 'type' ? 'cursor-text' : activeTab === 'annotate' && state.activeTool === 'shape' ? 'cursor-crosshair' : ''}`}\n />\n {typeSession && (\n <textarea\n ref={typeInputRef}\n aria-label=\"Edit text\"\n data-testid=\"type-input\"\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n onKeyDown={handleTypeKeyDown}\n onInput={handleTypeInput}\n onCompositionEnd={(e) => {\n const session = typeToolRef.current?.session;\n if (session && e.data) session.insert(e.data);\n e.currentTarget.value = '';\n }}\n className=\"absolute left-0 top-0 h-px w-px opacity-0\"\n />\n )}\n\n </div>\n\n {/* Tab Controls Sidebar */}\n <div className=\"w-full md:w-80 bg-slate-900/90 border-t md:border-t-0 md:border-l border-slate-800 p-4 overflow-y-auto h-auto md:h-full md:max-h-[560px]\">\n {/* TAB 1: CROP & TRANSFORM */}\n {activeTab === 'crop' && (\n <div className=\"flex flex-col gap-4 text-xs\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">\n Aspect Ratio Presets\n </span>\n <div className=\"grid grid-cols-3 gap-2\">\n <button\n type=\"button\"\n onClick={() => {\n setActiveCropRatio(null);\n editor.applyCropPreset(null);\n }}\n className={`px-2.5 py-2 rounded-lg border font-medium ${\n activeCropRatio === null && state.crop\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 hover:bg-slate-700 text-slate-200 border-slate-700'\n }`}\n >\n Freeform\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveCropRatio(1);\n editor.applyCropPreset(1);\n }}\n className={`px-2.5 py-2 rounded-lg border font-medium ${\n activeCropRatio === 1\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 hover:bg-slate-700 text-slate-200 border-slate-700'\n }`}\n >\n 1:1 Square\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveCropRatio(4 / 3);\n editor.applyCropPreset(4 / 3);\n }}\n className={`px-2.5 py-2 rounded-lg border font-medium ${\n activeCropRatio === 4 / 3\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 hover:bg-slate-700 text-slate-200 border-slate-700'\n }`}\n >\n 4:3 Standard\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveCropRatio(16 / 9);\n editor.applyCropPreset(16 / 9);\n }}\n className={`px-2.5 py-2 rounded-lg border font-medium ${\n activeCropRatio === 16 / 9\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 hover:bg-slate-700 text-slate-200 border-slate-700'\n }`}\n >\n 16:9 Wide\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveCropRatio(3 / 2);\n editor.applyCropPreset(3 / 2);\n }}\n className={`px-2.5 py-2 rounded-lg border font-medium ${\n activeCropRatio === 3 / 2\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 hover:bg-slate-700 text-slate-200 border-slate-700'\n }`}\n >\n 3:2 Photo\n </button>\n <button\n type=\"button\"\n onClick={() => {\n setActiveCropRatio(null);\n editor.resetCrop();\n }}\n className=\"px-2.5 py-2 rounded-lg bg-rose-950/40 hover:bg-rose-900/60 text-rose-300 border border-rose-800/40 font-medium\"\n >\n Clear Crop\n </button>\n </div>\n\n <div className=\"h-px bg-slate-800 my-1\" />\n\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">\n Orientation & Flips\n </span>\n <div className=\"grid grid-cols-2 gap-2\">\n <button\n type=\"button\"\n onClick={() => editor.rotate(-90)}\n className=\"px-3 py-2 rounded-lg bg-slate-800 hover:bg-slate-700 text-slate-200 border border-slate-700\"\n >\n Rotate -90°\n </button>\n <button\n type=\"button\"\n onClick={() => editor.rotate(90)}\n className=\"px-3 py-2 rounded-lg bg-slate-800 hover:bg-slate-700 text-slate-200 border border-slate-700\"\n >\n Rotate +90°\n </button>\n <button\n type=\"button\"\n onClick={() => editor.flipHorizontal()}\n className={`px-3 py-2 rounded-lg border transition-colors ${\n state.transform.flipH\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 border-slate-700 text-slate-200 hover:bg-slate-700'\n }`}\n >\n Flip Horizontal\n </button>\n <button\n type=\"button\"\n onClick={() => editor.flipVertical()}\n className={`px-3 py-2 rounded-lg border transition-colors ${\n state.transform.flipV\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 border-slate-700 text-slate-200 hover:bg-slate-700'\n }`}\n >\n Flip Vertical\n </button>\n </div>\n </div>\n )}\n\n {/* TAB 2: ADJUSTMENTS */}\n {activeTab === 'adjust' && (\n <div className=\"flex flex-col gap-3 text-xs\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">\n Color Adjustments\n </span>\n <button\n type=\"button\"\n onClick={() => editor.resetAdjustments()}\n className=\"text-[10px] text-rose-400 hover:underline\"\n >\n Reset Sliders\n </button>\n </div>\n\n <Histogram histogram={editor.histogram} />\n\n {IMAGE_ADJUSTMENT_CONTROLS.map((spec) => (\n <React.Fragment key={spec.id}>\n <ControlSlider\n spec={spec}\n value={readAdjustmentControls(state.adjustments)[spec.id]}\n disabled={spec.requiresProcess !== undefined && legacyProcess}\n onChange={(v) => editor.setAdjustments({ [spec.id]: v })}\n />\n {spec.id === 'tint' && legacyProcess && (\n <div\n className=\"flex items-center justify-between gap-2 rounded border border-amber-500/30 bg-amber-500/10 px-2 py-1.5 text-[10px] text-amber-200\"\n data-testid=\"image-editor-process-notice\"\n >\n <span>Legacy rendering (process 1). Tint needs the current process.</span>\n <button\n type=\"button\"\n onClick={() => editor.upgradeProcess()}\n className=\"shrink-0 rounded bg-amber-500/20 px-2 py-0.5 hover:bg-amber-500/30\"\n >\n Update\n </button>\n </div>\n )}\n </React.Fragment>\n ))}\n\n <div className=\"border-t border-slate-700/60 pt-3\">\n <AdjustmentLayersPanel\n controller={controller}\n layers={state.adjustments.layers}\n histogram={editor.histogram}\n />\n </div>\n </div>\n )}\n\n {/* TAB: LAYERS */}\n {activeTab === 'layers' && (\n <div className=\"flex flex-col gap-3 text-xs\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">Layers</span>\n <button\n type=\"button\"\n title=\"Edit › Free Transform (Ctrl/Cmd+T): the selected pixels, or the whole active layer\"\n className=\"px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40\"\n disabled={transformTool.active}\n onClick={() => transformTool.begin()}\n >\n Free Transform\n </button>\n <LayersPanel controller={controller} />\n {effectsShown && <ImageProviderEffectsPanel controller={controller} className=\"border-t border-slate-700/60 pt-3\" />}\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">Colour</span>\n <ColorProfilePanel controller={controller} />\n </div>\n )}\n\n {/* TAB: PAINT */}\n {activeTab === 'paint' && (\n <div className=\"flex flex-col gap-3 text-xs\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">Paint</span>\n <BrushOptionsBar controller={controller} />\n <button\n type=\"button\"\n title=\"Edit › Free Transform (Ctrl/Cmd+T): the selected pixels, or the whole active layer\"\n className=\"px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start\"\n disabled={transformTool.active}\n onClick={() => transformTool.begin()}\n >\n Free Transform\n </button>\n {paintError && (\n <p role=\"alert\" className=\"text-rose-400\" data-testid=\"paint-error\">\n {paintError}\n </p>\n )}\n <div className=\"border-t border-slate-700/60 pt-3\">\n <LayersPanel controller={controller} />\n </div>\n </div>\n )}\n\n {/* TAB 3: ANNOTATIONS */}\n {activeTab === 'annotate' && (\n <div className=\"flex flex-col gap-3 text-xs\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">Shape & Type Layers</span>\n <div className=\"grid grid-cols-2 gap-1.5\">\n {(['shape', 'type'] as ImageEditorTool[]).map((t) => (\n <button\n key={t}\n type=\"button\"\n aria-pressed={state.activeTool === t}\n onClick={() => editor.setTool(t)}\n className={`py-1.5 px-2 rounded-lg font-medium border transition-colors ${\n state.activeTool === t ? 'bg-indigo-600 border-indigo-500 text-white' : 'bg-slate-800 border-slate-700 text-slate-300 hover:bg-slate-700'\n }`}\n >\n {t === 'shape' ? 'Shape' : 'Type'}\n </button>\n ))}\n </div>\n {state.activeTool === 'shape' && <ShapeOptionsBar controller={controller} options={shapeOptions} onChange={setShapeOptions} />}\n {state.activeTool === 'type' && (\n <TypeOptionsBar controller={controller} options={typeOptions} onChange={setTypeOptions} session={typeSession} />\n )}\n {state.activeTool === 'type' && typeSession && (\n <button type=\"button\" onClick={finishTyping} className=\"self-start rounded bg-slate-800 px-2 py-1 text-[11px] text-slate-200 hover:bg-slate-700\">\n Done editing text\n </button>\n )}\n {shapeTypeError && (\n <p role=\"alert\" className=\"text-rose-400\" data-testid=\"shape-type-error\">\n {shapeTypeError}\n </p>\n )}\n <div className=\"h-px bg-slate-800 my-1\" />\n\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">\n Draw & Annotate\n </span>\n\n {/* Tool Picker */}\n <div className=\"grid grid-cols-3 gap-1.5\">\n {(['pen', 'rect', 'circle', 'arrow', 'line'] as ImageEditorTool[]).map((t) => (\n <button\n key={t}\n type=\"button\"\n onClick={() => editor.setTool(t)}\n className={`py-1.5 px-2 rounded-lg font-medium capitalize border transition-colors ${\n state.activeTool === t\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 border-slate-700 text-slate-300 hover:bg-slate-700'\n }`}\n >\n {t}\n </button>\n ))}\n </div>\n\n {/* Color & Size */}\n <div className=\"flex items-center gap-2 mt-2\">\n <label className=\"text-slate-400\">Color:</label>\n <input\n type=\"color\"\n value={activeColor}\n onChange={(e) => setActiveColor(e.target.value)}\n className=\"w-8 h-8 rounded border border-slate-700 cursor-pointer bg-transparent\"\n />\n <div className=\"flex-1 ml-2\">\n <div className=\"flex justify-between text-slate-400 mb-0.5\">\n <span>Width:</span>\n <span className=\"font-mono\">{strokeWidth}px</span>\n </div>\n <input\n type=\"range\"\n min=\"1\"\n max=\"20\"\n value={strokeWidth}\n onChange={(e) => setStrokeWidth(Number(e.target.value))}\n className=\"w-full accent-indigo-500\"\n />\n </div>\n </div>\n\n <div className=\"h-px bg-slate-800 my-1\" />\n\n {/* Text Tool */}\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">Add Text</span>\n <div className=\"flex gap-2\">\n <input\n type=\"text\"\n placeholder=\"Type watermark or label...\"\n value={textInput}\n onChange={(e) => setTextInput(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && handleAddText()}\n className=\"flex-1 bg-slate-950 border border-slate-700 rounded-lg px-2.5 py-1.5 text-xs text-slate-100 placeholder-slate-500 focus:outline-none focus:border-indigo-500\"\n />\n <button\n type=\"button\"\n onClick={handleAddText}\n className=\"px-3 py-1.5 rounded-lg bg-indigo-600 hover:bg-indigo-500 text-white font-medium shadow\"\n >\n Add\n </button>\n </div>\n <div className=\"flex items-center justify-between text-slate-400\">\n <span>Font Size:</span>\n <span className=\"font-mono\">{fontSize}px</span>\n </div>\n <input\n type=\"range\"\n min=\"12\"\n max=\"72\"\n value={fontSize}\n onChange={(e) => setFontSize(Number(e.target.value))}\n className=\"w-full accent-indigo-500\"\n />\n\n {/* Layers & Selected Annotation */}\n <div className=\"h-px bg-slate-800 my-1\" />\n <div className=\"flex items-center justify-between\">\n <span className=\"text-slate-400\">Layers ({state.annotations.length})</span>\n {state.selectedAnnotationId && (\n <button\n type=\"button\"\n onClick={() => editor.removeAnnotation(state.selectedAnnotationId!)}\n className=\"text-rose-400 hover:underline text-[11px]\"\n >\n Delete Selected\n </button>\n )}\n {state.annotations.length > 0 && (\n <button\n type=\"button\"\n onClick={() => editor.clearAnnotations()}\n className=\"text-slate-400 hover:text-slate-200 text-[11px]\"\n >\n Clear All\n </button>\n )}\n </div>\n </div>\n )}\n\n {/* TAB 4: GLEAMFORGE DEPTH MASKING */}\n {activeTab === 'depth' && (\n <div className=\"flex flex-col gap-3 text-xs\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">\n Depth Masking\n </span>\n <button\n type=\"button\"\n onClick={() => editor.resetDepthMask()}\n className=\"text-[10px] text-rose-400 hover:underline\"\n >\n Reset Mask\n </button>\n </div>\n\n <label className=\"flex items-center gap-2 cursor-pointer text-slate-300\">\n <input\n type=\"checkbox\"\n checked={state.depthMask.enabled}\n onChange={(e) => editor.setDepthMask({ enabled: e.target.checked })}\n className=\"rounded accent-indigo-500\"\n />\n <span>Enable Depth / Alpha Mask</span>\n </label>\n\n {state.depthMask.enabled && (\n <>\n <div>\n <label className=\"text-slate-400 block mb-1\">Mask Image URL:</label>\n <input\n type=\"text\"\n placeholder=\"https://.../depthmap.png\"\n value={state.depthMask.maskSource || ''}\n onChange={(e) => editor.setDepthMask({ maskSource: e.target.value || null })}\n className=\"w-full bg-slate-950 border border-slate-700 rounded-lg px-2.5 py-1.5 text-xs text-slate-100 placeholder-slate-500\"\n />\n </div>\n\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={() => editor.setDepthMask({ mode: 'threshold' })}\n className={`flex-1 py-1.5 rounded-lg border text-xs font-medium ${\n state.depthMask.mode === 'threshold'\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 border-slate-700 text-slate-300'\n }`}\n >\n Threshold Mode\n </button>\n <button\n type=\"button\"\n onClick={() => editor.setDepthMask({ mode: 'brightness' })}\n className={`flex-1 py-1.5 rounded-lg border text-xs font-medium ${\n state.depthMask.mode === 'brightness'\n ? 'bg-indigo-600 border-indigo-500 text-white'\n : 'bg-slate-800 border-slate-700 text-slate-300'\n }`}\n >\n Brightness Mode\n </button>\n </div>\n\n <div>\n <div className=\"flex justify-between text-slate-400 mb-1\">\n <span>Depth Start (Lower):</span>\n <span className=\"font-mono\">{state.depthMask.depthRange[0]}</span>\n </div>\n <input\n type=\"range\"\n min=\"0\"\n max=\"255\"\n value={state.depthMask.depthRange[0]}\n onChange={(e) =>\n editor.setDepthMask({\n depthRange: [Number(e.target.value), state.depthMask.depthRange[1]],\n })\n }\n className=\"w-full accent-indigo-500\"\n />\n </div>\n\n <div>\n <div className=\"flex justify-between text-slate-400 mb-1\">\n <span>Depth Stop (Upper):</span>\n <span className=\"font-mono\">{state.depthMask.depthRange[1]}</span>\n </div>\n <input\n type=\"range\"\n min=\"0\"\n max=\"255\"\n value={state.depthMask.depthRange[1]}\n onChange={(e) =>\n editor.setDepthMask({\n depthRange: [state.depthMask.depthRange[0], Number(e.target.value)],\n })\n }\n className=\"w-full accent-indigo-500\"\n />\n </div>\n\n <div>\n <div className=\"flex justify-between text-slate-400 mb-1\">\n <span>Softness:</span>\n <span className=\"font-mono\">{state.depthMask.softness}</span>\n </div>\n <input\n type=\"range\"\n min=\"1\"\n max=\"50\"\n value={state.depthMask.softness}\n onChange={(e) => editor.setDepthMask({ softness: Number(e.target.value) })}\n className=\"w-full accent-indigo-500\"\n />\n </div>\n\n <label className=\"flex items-center gap-2 cursor-pointer text-slate-300 mt-1\">\n <input\n type=\"checkbox\"\n checked={state.depthMask.invert}\n onChange={(e) => editor.setDepthMask({ invert: e.target.checked })}\n className=\"rounded accent-indigo-500\"\n />\n <span>Invert Mask</span>\n </label>\n </>\n )}\n </div>\n )}\n\n {/* SELECT & MASK: selection tools, refine edge, layer masks */}\n {activeTab === 'select' && (\n <div className=\"flex flex-col gap-4 text-xs\">\n <SelectionOptionsBar\n controller={controller}\n options={selectionOptions}\n onOptionsChange={setSelectionOptions}\n selection={state.selection ?? null}\n quickMask={Boolean(state.quickMask)}\n />\n {selectionError && (\n <p role=\"alert\" className=\"text-rose-400\">\n {selectionError}\n </p>\n )}\n <div className=\"flex gap-1\">\n <button\n type=\"button\"\n title=\"Select › Transform Selection: the outline only\"\n className=\"px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40\"\n disabled={transformTool.active}\n onClick={() => transformTool.begin({ content: 'selection-outline' })}\n >\n Transform Selection\n </button>\n <button\n type=\"button\"\n title=\"Edit › Free Transform: the selected pixels of the active layer\"\n className=\"px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white self-start disabled:opacity-40\"\n disabled={transformTool.active}\n onClick={() => transformTool.begin({ content: 'selection' })}\n >\n Free Transform Pixels\n </button>\n </div>\n <RefineEdgePanel controller={controller} selection={state.selection ?? null} layers={state.adjustments.layers} />\n </div>\n )}\n\n {/* TAB 5: AI TOOLS / INPAINTING & BACKGROUND REMOVAL */}\n {activeTab === 'ai' && (\n <div className=\"flex flex-col gap-4 text-xs\">\n <label className=\"flex items-center justify-between gap-2 text-slate-300\">\n <span>Results go to</span>\n <select\n aria-label=\"AI result target\"\n value={aiTarget}\n onChange={(e) => setAiTarget(e.target.value as typeof aiTarget)}\n className=\"bg-slate-800 border border-slate-700 rounded px-1.5 py-1\"\n >\n <option value=\"auto\">{controller.isMultiLayer ? 'Auto (new layer)' : 'Auto (replace image)'}</option>\n <option value=\"new-layer\">New layer / mask</option>\n <option value=\"replace\">Replace image</option>\n </select>\n </label>\n {/* Background Removal Section */}\n <div className=\"p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5\">\n <svg className=\"w-3.5 h-3.5 text-indigo-400\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M6 3v12M18 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6z\" />\n </svg>\n Background Removal\n </span>\n {isRemovingBg && (\n <span className=\"inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-indigo-900/60 text-indigo-300 animate-pulse\">\n Removing...\n </span>\n )}\n </div>\n\n <p className=\"text-slate-400 text-[11px] leading-relaxed\">\n Isolate foreground subject with AI alpha transparency segmentation.\n </p>\n\n <button\n type=\"button\"\n onClick={handleRemoveBackground}\n disabled={isRemovingBg || isInpainting}\n className=\"mt-1 px-3 py-2 rounded-lg bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 text-white font-medium shadow transition-colors flex items-center justify-center gap-2\"\n >\n {isRemovingBg ? (\n <>\n <div className=\"w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin\" />\n Removing Background...\n </>\n ) : (\n <>\n <svg className=\"w-3.5 h-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83\" />\n </svg>\n Remove Background\n </>\n )}\n </button>\n </div>\n\n {/* AI Inpainting / Generative Fill Section */}\n <div className=\"p-3 rounded-lg bg-slate-950/60 border border-slate-800 flex flex-col gap-2.5\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px] flex items-center gap-1.5\">\n <svg className=\"w-3.5 h-3.5 text-purple-400\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"m21.64 3.64-1.28-1.28a1.2 1.2 0 0 0-1.7 0l-9.72 9.72-1.94 4.86 4.86-1.94 9.72-9.72a1.2 1.2 0 0 0 .06-1.64z\" />\n <path d=\"m14 7 3 3\" />\n </svg>\n Generative Inpainting\n </span>\n {isInpainting && (\n <span className=\"inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-purple-900/60 text-purple-300 animate-pulse\">\n Inpainting...\n </span>\n )}\n </div>\n\n <p className=\"text-slate-400 text-[11px] leading-relaxed\">\n Replace, modify, or fill selected regions using prompt-guided generative inpainting.\n </p>\n\n <div className=\"flex flex-col gap-1\">\n <label htmlFor=\"ai-inpaint-prompt-react\" className=\"text-slate-300 text-[11px] font-medium\">Prompt</label>\n <textarea\n id=\"ai-inpaint-prompt-react\"\n value={inpaintPrompt}\n onChange={(e) => setInpaintPrompt(e.target.value)}\n placeholder=\"e.g. replace sunglasses with steampunk goggles, remove person in background...\"\n rows={3}\n className=\"w-full bg-slate-900 border border-slate-700 rounded-lg p-2 text-xs text-slate-100 placeholder-slate-500 focus:outline-none focus:border-indigo-500 resize-none\"\n />\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-slate-300 text-[11px] font-medium\">Target Mask Region</span>\n <div className=\"grid grid-cols-2 gap-1.5\">\n <button\n type=\"button\"\n onClick={() => setInpaintMaskMode('annotations')}\n className={`px-2 py-1.5 rounded border text-[11px] font-medium text-left transition-colors ${\n inpaintMaskMode === 'annotations'\n ? 'bg-purple-600/30 border-purple-500 text-purple-200'\n : 'bg-slate-900 border-slate-700 text-slate-400 hover:text-slate-200'\n }`}\n >\n Drawn Shapes ({state.annotations.length})\n </button>\n <button\n type=\"button\"\n onClick={() => setInpaintMaskMode('crop')}\n className={`px-2 py-1.5 rounded border text-[11px] font-medium text-left transition-colors ${\n inpaintMaskMode === 'crop'\n ? 'bg-purple-600/30 border-purple-500 text-purple-200'\n : 'bg-slate-900 border-slate-700 text-slate-400 hover:text-slate-200'\n }`}\n >\n Crop Box ({state.crop ? 'Selected' : 'Full'})\n </button>\n </div>\n </div>\n\n <button\n type=\"button\"\n onClick={handleInpaint}\n disabled={isInpainting || isRemovingBg || !inpaintPrompt.trim()}\n className=\"mt-1 px-3 py-2 rounded-lg bg-purple-600 hover:bg-purple-500 disabled:opacity-50 text-white font-medium shadow transition-colors flex items-center justify-center gap-2\"\n >\n {isInpainting ? (\n <>\n <div className=\"w-3.5 h-3.5 border-2 border-white/30 border-t-white rounded-full animate-spin\" />\n Generating Inpaint...\n </>\n ) : (\n <>\n <svg className=\"w-3.5 h-3.5\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83\" />\n </svg>\n Apply Inpainting\n </>\n )}\n </button>\n </div>\n\n {aiError && (\n <div className=\"p-2.5 rounded-lg bg-rose-950/60 border border-rose-800 text-rose-300 text-[11px]\">\n {aiError}\n </div>\n )}\n\n {aiSuccess && (\n <div className=\"p-2.5 rounded-lg bg-emerald-950/60 border border-emerald-800 text-emerald-300 text-[11px]\">\n {aiSuccess}\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n};\n","import React from 'react';\nimport type { ControlSpec } from '@pixerate/editor/image-editor';\nimport { controlTrackBackground, formatControlValue } from '@pixerate/editor/image-editor';\n\nexport interface ControlSliderProps {\n spec: ControlSpec;\n value: number;\n onChange: (value: number) => void;\n disabled?: boolean;\n /** Overrides `spec.label` (also the accessible name). */\n label?: string;\n}\n\n/** A labelled range input described by a control-table entry. */\nexport const ControlSlider: React.FC<ControlSliderProps> = ({ spec, value, onChange, disabled, label }) => {\n const name = label ?? spec.label;\n const track = controlTrackBackground(spec);\n return (\n <div data-control-id={spec.id}>\n <div className=\"flex justify-between text-slate-400 mb-1\">\n <span>{name}</span>\n <span className=\"font-mono\">{formatControlValue(spec, value)}</span>\n </div>\n <input\n type=\"range\"\n min={spec.min}\n max={spec.max}\n step={spec.step}\n aria-label={name}\n disabled={disabled}\n value={value}\n onChange={(e) => onChange(Number(e.target.value))}\n className=\"w-full accent-indigo-500 disabled:opacity-40\"\n />\n {track && <div className=\"h-0.5 rounded-full opacity-70\" style={{ background: track }} />}\n </div>\n );\n};\n","import React, { useEffect, useMemo, useState } from 'react';\nimport type { ImageEditorController, ImageHistogram } from '@pixerate/editor/image-editor';\nimport { histogramPath } from '@pixerate/editor/image-editor';\n\nexport interface HistogramProps {\n histogram: ImageHistogram | null;\n /** `rgb` overlays the three channels on the luminance; a single channel draws just that one. */\n channel?: 'rgb' | 'luminance' | 'red' | 'green' | 'blue';\n height?: number;\n className?: string;\n style?: React.CSSProperties;\n}\n\nconst FILL: Record<'luminance' | 'red' | 'green' | 'blue', string> = {\n luminance: 'rgba(148, 163, 184, 0.45)',\n red: 'rgba(239, 68, 68, 0.45)',\n green: 'rgba(34, 197, 94, 0.45)',\n blue: 'rgba(59, 130, 246, 0.45)',\n};\n\nconst W = 256;\n\n/** SVG histogram of an image (see `computeHistogram` / `controller.subscribeHistogram`). */\nexport const Histogram: React.FC<HistogramProps> = ({ histogram, channel = 'rgb', height = 64, className = '', style }) => {\n const channels = channel === 'rgb' ? (['luminance', 'red', 'green', 'blue'] as const) : ([channel] as const);\n const paths = useMemo(\n () => (histogram && histogram.samples > 0 ? channels.map((c) => ({ c, d: histogramPath(histogram, c, W, height) })) : []),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [histogram, channel, height]\n );\n const clipLow = histogram && histogram.samples ? Math.max(...histogram.shadows) / histogram.samples : 0;\n const clipHigh = histogram && histogram.samples ? Math.max(...histogram.highlights) / histogram.samples : 0;\n return (\n <svg\n viewBox={`0 0 ${W} ${height}`}\n preserveAspectRatio=\"none\"\n role=\"img\"\n aria-label={histogram ? `Histogram of ${histogram.samples} pixels` : 'Histogram (no data)'}\n data-testid=\"image-editor-histogram\"\n className={`w-full rounded bg-slate-950/60 ${className}`}\n style={{ height, ...style }}\n >\n {paths.map(({ c, d }) => (\n <path key={c} d={d} fill={FILL[c]} stroke=\"none\" />\n ))}\n {clipLow > 0.005 && <rect x={0} y={0} width={3} height={height} fill=\"#3b82f6\" data-testid=\"histogram-clip-shadows\" />}\n {clipHigh > 0.005 && <rect x={W - 3} y={0} width={3} height={height} fill=\"#ef4444\" data-testid=\"histogram-clip-highlights\" />}\n </svg>\n );\n};\n\n/** The preview histogram of an image editor, updated after every render. */\nexport function useImageHistogram(controller: ImageEditorController): ImageHistogram | null {\n const [histogram, setHistogram] = useState<ImageHistogram | null>(() => controller.getHistogram());\n useEffect(() => controller.subscribeHistogram(setHistogram), [controller]);\n return histogram;\n}\n","import React, { useEffect, useState } from 'react';\nimport type {\n AdjustmentKind,\n AdjustmentLayer,\n BlendMode,\n ControlSpec,\n CurvePoint,\n ImageEditorController,\n ImageHistogram,\n} from '@pixerate/editor/image-editor';\nimport {\n ADJUSTMENT_KINDS,\n ADJUSTMENT_LAYER_CONTROLS,\n ADJUSTMENT_LAYER_OPACITY_CONTROL,\n BLEND_MODES,\n HUE_RANGE_LABELS,\n adjustmentKindLabel,\n getControlPath,\n hueRangeWeight,\n setControlPath,\n} from '@pixerate/editor/image-editor';\nimport { ControlSlider } from './ControlSlider';\nimport { CurvesEditor } from './CurvesEditor';\n\nexport interface AdjustmentLayersPanelProps {\n controller: ImageEditorController;\n /** The current layers (`state.adjustments.layers`), bottom to top. Omit to follow the controller. */\n layers?: AdjustmentLayer[];\n histogram?: ImageHistogram | null;\n}\n\ntype Channel = 'master' | 'red' | 'green' | 'blue';\nconst CHANNELS: { id: Channel; label: string }[] = [\n { id: 'master', label: 'RGB' },\n { id: 'red', label: 'Red' },\n { id: 'green', label: 'Green' },\n { id: 'blue', label: 'Blue' },\n];\nconst TONES = [\n { id: 'shadows', label: 'Shadows' },\n { id: 'midtones', label: 'Midtones' },\n { id: 'highlights', label: 'Highlights' },\n] as const;\n\nconst selectClass = 'bg-slate-800 border border-slate-700 rounded px-1.5 py-1 text-slate-200';\nconst chipClass = (on: boolean) =>\n `px-2 py-0.5 rounded text-[10px] ${on ? 'bg-indigo-600 text-white' : 'bg-slate-800 text-slate-400 hover:text-slate-200'}`;\n\n/** Hue strip with the weight of one Hue/Saturation range drawn over it. */\nconst HueRangeStrip: React.FC<{ bounds: [number, number, number, number] }> = ({ bounds }) => {\n const pts = Array.from({ length: 73 }, (_, i) => `${(i / 72) * 360},${20 - hueRangeWeight({ bounds }, i * 5) * 18}`).join(' ');\n return (\n <svg viewBox=\"0 0 360 20\" preserveAspectRatio=\"none\" className=\"w-full h-4 rounded\" data-testid=\"hue-range-strip\">\n <defs>\n <linearGradient id=\"pixerate-hue-strip\">\n {[0, 60, 120, 180, 240, 300, 360].map((h) => (\n <stop key={h} offset={`${(h / 360) * 100}%`} stopColor={`hsl(${h}, 90%, 50%)`} />\n ))}\n </linearGradient>\n </defs>\n <rect width={360} height={20} fill=\"url(#pixerate-hue-strip)\" opacity={0.6} />\n <polyline points={pts} fill=\"none\" stroke=\"#fff\" strokeWidth={1.5} />\n </svg>\n );\n};\n\n/**\n * Adjustment-layer stack: add, reorder, show / hide and remove layers, and edit the selected\n * one (curves over the histogram, levels, hue/saturation ranges, colour balance, …).\n */\nexport const AdjustmentLayersPanel: React.FC<AdjustmentLayersPanelProps> = ({ controller, layers: layersProp, histogram }) => {\n // Follows the controller when no `layers` prop is given.\n const follow = layersProp === undefined;\n const [, setTick] = useState(0);\n useEffect(() => (follow ? controller.subscribe(() => setTick((n) => n + 1)) : undefined), [controller, follow]);\n const layers = layersProp ?? controller.getAdjustmentLayers();\n const [newKind, setNewKind] = useState<AdjustmentKind>('curves');\n const [selectedId, setSelectedId] = useState<string | null>(null);\n const [channel, setChannel] = useState<Channel>('master');\n const [range, setRange] = useState<number>(-1);\n const [tone, setTone] = useState<(typeof TONES)[number]['id']>('midtones');\n\n const selected = layers.find((l) => l.id === selectedId) ?? null;\n const topFirst = [...layers].reverse();\n\n const setParam = (layer: AdjustmentLayer, path: string, value: unknown, commit = true) =>\n controller.updateAdjustmentLayer(layer.id, { params: setControlPath(layer.params, path, value) as never }, commit);\n\n const slider = (layer: AdjustmentLayer, spec: ControlSpec, label?: string) => (\n <ControlSlider\n key={spec.id}\n spec={spec}\n label={label}\n value={Number(getControlPath(layer.params, spec.id) ?? spec.default)}\n onChange={(v) => setParam(layer, spec.id, v)}\n />\n );\n const controlsOf = (layer: AdjustmentLayer, filter: (spec: ControlSpec) => boolean = () => true) =>\n ADJUSTMENT_LAYER_CONTROLS[layer.kind].filter(filter);\n const checkbox = (layer: AdjustmentLayer, path: string, label: string) => (\n <label className=\"flex items-center gap-2 text-slate-300\">\n <input\n type=\"checkbox\"\n checked={Boolean(getControlPath(layer.params, path))}\n onChange={(e) => setParam(layer, path, e.target.checked)}\n className=\"accent-indigo-500\"\n />\n {label}\n </label>\n );\n\n const editor = (layer: AdjustmentLayer) => {\n switch (layer.kind) {\n case 'curves':\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex gap-1\" role=\"group\" aria-label=\"Curve channel\">\n {CHANNELS.map((c) => (\n <button key={c.id} type=\"button\" className={chipClass(channel === c.id)} onClick={() => setChannel(c.id)}>\n {c.label}\n </button>\n ))}\n </div>\n <CurvesEditor\n points={layer.params[channel]}\n channel={channel}\n histogram={histogram}\n onChange={(points: CurvePoint[], commit) => setParam(layer, channel, points, commit)}\n />\n </div>\n );\n case 'levels':\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex gap-1\" role=\"group\" aria-label=\"Levels channel\">\n {CHANNELS.map((c) => (\n <button key={c.id} type=\"button\" className={chipClass(channel === c.id)} onClick={() => setChannel(c.id)}>\n {c.label}\n </button>\n ))}\n </div>\n {controlsOf(layer, (s) => s.id.startsWith(`${channel}.`)).map((s) => slider(layer, s))}\n </div>\n );\n case 'hueSaturation':\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex flex-wrap gap-1\" role=\"group\" aria-label=\"Hue range\">\n <button type=\"button\" className={chipClass(range === -1)} onClick={() => setRange(-1)}>\n Master\n </button>\n {HUE_RANGE_LABELS.map((name, i) => (\n <button key={name} type=\"button\" className={chipClass(range === i)} onClick={() => setRange(i)} disabled={layer.params.colorize}>\n {name}\n </button>\n ))}\n </div>\n {range >= 0 && !layer.params.colorize && <HueRangeStrip bounds={layer.params.ranges[range].bounds} />}\n {controlsOf(layer, (s) => (range === -1 || layer.params.colorize ? !s.id.startsWith('ranges.') : s.id.startsWith(`ranges.${range}.`))).map((s) =>\n slider(layer, s)\n )}\n {range === -1 && checkbox(layer, 'colorize', 'Colorize')}\n </div>\n );\n case 'colorBalance':\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex gap-1\" role=\"group\" aria-label=\"Tone\">\n {TONES.map((t) => (\n <button key={t.id} type=\"button\" className={chipClass(tone === t.id)} onClick={() => setTone(t.id)}>\n {t.label}\n </button>\n ))}\n </div>\n {controlsOf(layer, (s) => s.id.startsWith(`${tone}.`)).map((s) => slider(layer, s))}\n {checkbox(layer, 'preserveLuminosity', 'Preserve luminosity')}\n </div>\n );\n case 'blackWhite':\n return (\n <div className=\"flex flex-col gap-2\">\n {controlsOf(layer).map((s) => slider(layer, s))}\n <label className=\"flex items-center gap-2 text-slate-300\">\n <input\n type=\"checkbox\"\n checked={layer.params.tint !== null}\n onChange={(e) => setParam(layer, 'tint', e.target.checked ? '#e1d3b3' : null)}\n className=\"accent-indigo-500\"\n />\n Tint\n {layer.params.tint && (\n <input\n type=\"color\"\n aria-label=\"Tint colour\"\n value={layer.params.tint}\n onChange={(e) => setParam(layer, 'tint', e.target.value)}\n className=\"h-5 w-8 bg-transparent\"\n />\n )}\n </label>\n </div>\n );\n case 'photoFilter':\n return (\n <div className=\"flex flex-col gap-2\">\n <label className=\"flex items-center gap-2 text-slate-300\">\n Filter colour\n <input\n type=\"color\"\n aria-label=\"Filter colour\"\n value={layer.params.color}\n onChange={(e) => setParam(layer, 'color', e.target.value)}\n className=\"h-5 w-8 bg-transparent\"\n />\n </label>\n {controlsOf(layer).map((s) => slider(layer, s))}\n {checkbox(layer, 'preserveLuminosity', 'Preserve luminosity')}\n </div>\n );\n case 'invert':\n return <p className=\"text-slate-500 text-[11px]\">Invert has no settings.</p>;\n default:\n return <div className=\"flex flex-col gap-2\">{controlsOf(layer).map((s) => slider(layer, s))}</div>;\n }\n };\n\n return (\n <div className=\"flex flex-col gap-2 text-xs\" data-testid=\"adjustment-layers-panel\">\n <div className=\"flex items-center justify-between\">\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">Adjustment Layers</span>\n </div>\n <div className=\"flex gap-1.5\">\n <select\n aria-label=\"New adjustment layer kind\"\n className={`${selectClass} flex-1`}\n value={newKind}\n onChange={(e) => setNewKind(e.target.value as AdjustmentKind)}\n >\n {ADJUSTMENT_KINDS.map((k) => (\n <option key={k.kind} value={k.kind}>\n {k.label}\n </option>\n ))}\n </select>\n <button\n type=\"button\"\n className=\"px-2 py-1 rounded bg-indigo-600 text-white hover:bg-indigo-500\"\n onClick={() => {\n setSelectedId(controller.addAdjustmentLayer(newKind));\n setChannel('master');\n setRange(-1);\n }}\n >\n Add Layer\n </button>\n </div>\n\n {topFirst.length > 0 && (\n <ul className=\"flex flex-col gap-1\" aria-label=\"Adjustment layers\">\n {topFirst.map((layer) => {\n const index = layers.indexOf(layer);\n const label = layer.name || adjustmentKindLabel(layer.kind);\n return (\n <li\n key={layer.id}\n className={`flex items-center gap-1.5 rounded px-1.5 py-1 ${layer.id === selectedId ? 'bg-indigo-600/20 ring-1 ring-indigo-500/50' : 'bg-slate-800/60'}`}\n >\n <input\n type=\"checkbox\"\n aria-label={`Show ${label}`}\n checked={layer.enabled}\n onChange={() => controller.toggleAdjustmentLayer(layer.id)}\n className=\"accent-indigo-500\"\n />\n <button\n type=\"button\"\n className={`flex-1 text-left truncate ${layer.enabled ? 'text-slate-200' : 'text-slate-500 line-through'}`}\n onClick={() => setSelectedId(layer.id === selectedId ? null : layer.id)}\n aria-pressed={layer.id === selectedId}\n >\n {label}\n </button>\n <button\n type=\"button\"\n aria-label={`Move ${label} up`}\n disabled={index === layers.length - 1}\n onClick={() => controller.moveAdjustmentLayer(layer.id, index + 1)}\n className=\"px-1 text-slate-400 hover:text-slate-200 disabled:opacity-30\"\n >\n ↑\n </button>\n <button\n type=\"button\"\n aria-label={`Move ${label} down`}\n disabled={index === 0}\n onClick={() => controller.moveAdjustmentLayer(layer.id, index - 1)}\n className=\"px-1 text-slate-400 hover:text-slate-200 disabled:opacity-30\"\n >\n ↓\n </button>\n <button\n type=\"button\"\n aria-label={`Remove ${label}`}\n onClick={() => {\n controller.removeAdjustmentLayer(layer.id);\n if (selectedId === layer.id) setSelectedId(null);\n }}\n className=\"px-1 text-rose-400 hover:text-rose-300\"\n >\n ✕\n </button>\n </li>\n );\n })}\n </ul>\n )}\n\n {selected && (\n <div className=\"flex flex-col gap-2 rounded border border-slate-700/60 p-2\" data-testid=\"adjustment-layer-editor\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-slate-400\">Blend</span>\n <select\n aria-label=\"Blend mode\"\n className={`${selectClass} flex-1`}\n value={selected.blend}\n onChange={(e) => controller.updateAdjustmentLayer(selected.id, { blend: e.target.value as BlendMode })}\n >\n {BLEND_MODES.map((m) => (\n <option key={m.id} value={m.id}>\n {m.label}\n </option>\n ))}\n </select>\n </div>\n <ControlSlider\n spec={ADJUSTMENT_LAYER_OPACITY_CONTROL}\n label=\"Layer opacity\"\n value={selected.opacity}\n onChange={(v) => controller.updateAdjustmentLayer(selected.id, { opacity: v })}\n />\n {editor(selected)}\n </div>\n )}\n </div>\n );\n};\n","import React, { useRef, useState } from 'react';\nimport type { CurvePoint, ImageHistogram } from '@pixerate/editor/image-editor';\nimport {\n boxToCurvePoint,\n curvePointToBox,\n curveSvgPath,\n hitTestCurvePoint,\n histogramPath,\n insertCurvePoint,\n moveCurvePoint,\n removeCurvePoint,\n} from '@pixerate/editor/image-editor';\n\nexport interface CurvesEditorProps {\n points: CurvePoint[];\n /** `commit` is true for the first change of a gesture (one undo step), false for the drag moves. */\n onChange: (points: CurvePoint[], commit: boolean) => void;\n histogram?: ImageHistogram | null;\n channel?: 'master' | 'red' | 'green' | 'blue';\n size?: number;\n}\n\nconst BOX = 256;\nconst STROKE = { master: '#e2e8f0', red: '#ef4444', green: '#22c55e', blue: '#3b82f6' };\n\n/**\n * Curves editor over the histogram: click to add a point, drag to move it, double-click to\n * remove it.\n */\nexport const CurvesEditor: React.FC<CurvesEditorProps> = ({ points, onChange, histogram, channel = 'master', size = 200 }) => {\n const svgRef = useRef<SVGSVGElement>(null);\n const [drag, setDrag] = useState<number | null>(null);\n\n const toBox = (e: React.PointerEvent | React.MouseEvent) => {\n const rect = svgRef.current?.getBoundingClientRect();\n if (!rect || !rect.width || !rect.height) return { x: 0, y: 0 };\n return { x: ((e.clientX - rect.left) / rect.width) * BOX, y: ((e.clientY - rect.top) / rect.height) * BOX };\n };\n\n const onPointerDown = (e: React.PointerEvent) => {\n const { x, y } = toBox(e);\n let index = hitTestCurvePoint(points, x, y, BOX, BOX, 10);\n if (index === -1) {\n const inserted = insertCurvePoint(points, boxToCurvePoint(x, y, BOX, BOX));\n onChange(inserted.points, true);\n index = inserted.index;\n } else {\n onChange(points, true);\n }\n setDrag(index);\n (e.target as Element).setPointerCapture?.(e.pointerId);\n };\n\n const onPointerMove = (e: React.PointerEvent) => {\n if (drag === null) return;\n onChange(moveCurvePoint(points, drag, boxToCurvePoint(toBox(e).x, toBox(e).y, BOX, BOX)), false);\n };\n\n const onDoubleClick = (e: React.MouseEvent) => {\n const { x, y } = toBox(e);\n const index = hitTestCurvePoint(points, x, y, BOX, BOX, 10);\n if (index !== -1 && points.length > 2) onChange(removeCurvePoint(points, index), true);\n };\n\n const histChannel = channel === 'master' ? 'luminance' : channel;\n return (\n <svg\n ref={svgRef}\n viewBox={`0 0 ${BOX} ${BOX}`}\n width={size}\n height={size}\n role=\"application\"\n aria-label={`${channel} curve`}\n data-testid=\"curves-editor\"\n className=\"rounded bg-slate-950/70 touch-none select-none cursor-crosshair\"\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={() => setDrag(null)}\n onPointerCancel={() => setDrag(null)}\n onDoubleClick={onDoubleClick}\n >\n {histogram && histogram.samples > 0 && (\n <path d={histogramPath(histogram, histChannel, BOX, BOX)} fill=\"rgba(148, 163, 184, 0.25)\" />\n )}\n {[64, 128, 192].map((v) => (\n <g key={v} stroke=\"rgba(148, 163, 184, 0.2)\" strokeWidth={1}>\n <line x1={v} y1={0} x2={v} y2={BOX} />\n <line x1={0} y1={v} x2={BOX} y2={v} />\n </g>\n ))}\n <line x1={0} y1={BOX} x2={BOX} y2={0} stroke=\"rgba(148, 163, 184, 0.35)\" strokeDasharray=\"4 4\" />\n <path d={curveSvgPath(points, BOX, BOX)} fill=\"none\" stroke={STROKE[channel]} strokeWidth={2} />\n {points.map((p, i) => {\n const b = curvePointToBox(p, BOX, BOX);\n return (\n <circle\n key={i}\n cx={b.x}\n cy={b.y}\n r={5}\n fill={drag === i ? STROKE[channel] : '#0f172a'}\n stroke={STROKE[channel]}\n strokeWidth={2}\n aria-label={`Point ${p.input} to ${p.output}`}\n />\n );\n })}\n </svg>\n );\n};\n","import React, { useEffect, useRef, useState } from 'react';\nimport type { ImageEditorController, ImageLayer, LayerMenuAction, LayerPanelRow, PixelBuffer } from '@pixerate/editor/image-editor';\nimport { LayerEffectsPanel } from './LayerEffectsPanel';\nimport {\n BIT_DEPTH_OPTIONS,\n BLEND_MODES,\n PSD_FILE_ACCEPT,\n downloadPsd,\n dropPlacement,\n dropZone,\n openPsdFile,\n layerBadge,\n layerHasThumbnail,\n layerWarning,\n layerEffectsBadge,\n layerMenu,\n layerPanelRows,\n runLayerMenuAction,\n} from '@pixerate/editor/image-editor';\n\nexport interface LayersPanelProps {\n controller: ImageEditorController;\n /** Thumbnail size in px (default 32). */\n thumbnailSize?: number;\n /** Show Open PSD / Export PSD (default true). */\n psd?: boolean;\n /** Base name of exported PSD files (default `image`). */\n psdFileName?: string;\n /** Show the active layer's effects section (default true). */\n effects?: boolean;\n className?: string;\n}\n\nconst iconButton = 'px-1.5 py-0.5 rounded text-[10px] bg-slate-800 text-slate-300 hover:text-white disabled:opacity-40';\nconst rowClass = (active: boolean) =>\n `flex items-center gap-1.5 px-1.5 py-1 rounded cursor-pointer select-none ${active ? 'bg-indigo-600/30 ring-1 ring-indigo-500' : 'hover:bg-slate-800'}`;\n\n/** Draws a thumbnail (RGBA pixels) into a small canvas; nothing without a 2D context. */\nconst Thumbnail: React.FC<{ pixels: PixelBuffer | null; size: number; label: string; onClick?: (e: React.MouseEvent) => void; selected?: boolean; testId?: string }> = ({\n pixels,\n size,\n label,\n onClick,\n selected,\n testId,\n}) => {\n const ref = useRef<HTMLCanvasElement>(null);\n useEffect(() => {\n const canvas = ref.current;\n const ctx = canvas?.getContext('2d');\n if (!canvas || !ctx || !pixels || typeof ctx.createImageData !== 'function') return;\n canvas.width = pixels.width;\n canvas.height = pixels.height;\n const img = ctx.createImageData(pixels.width, pixels.height);\n img.data.set(pixels.data as ArrayLike<number>);\n ctx.putImageData(img, 0, 0);\n }, [pixels]);\n return (\n <canvas\n ref={ref}\n role={onClick ? 'button' : 'img'}\n aria-label={label}\n data-testid={testId}\n onClick={onClick}\n style={{ width: size, height: size }}\n className={`shrink-0 rounded bg-[repeating-conic-gradient(#334155_0%_25%,#1e293b_0%_50%)] [background-size:8px_8px] object-contain ${selected ? 'ring-2 ring-white' : 'ring-1 ring-slate-700'}`}\n />\n );\n};\n\n/**\n * The layer stack, top first: visibility, thumbnails, names (double-click to rename), locks,\n * mask thumbnails (click to paint the mask, Shift-click to disable it), drag to reorder or drop\n * into a group, opacity / fill / blend / clipping for the active layer, and the layer menu\n * (right-click a row, or the ⋯ button), an fx badge on rows with effects (click to switch them\n * on or off) and the active layer's effects. Every action is one undo step on the controller.\n */\nexport const LayersPanel: React.FC<LayersPanelProps> = ({ controller, thumbnailSize = 32, psd = true, psdFileName = 'image', effects = true, className }) => {\n const [, setTick] = useState(0);\n useEffect(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);\n const [error, setError] = useState<string | null>(null);\n const [renaming, setRenaming] = useState<string | null>(null);\n const [menu, setMenu] = useState<{ x: number; y: number } | null>(null);\n const [drag, setDrag] = useState<string | null>(null);\n /** Warnings of the last PSD open or export. */\n const [psdNotes, setPsdNotes] = useState<string[]>([]);\n const fileInput = useRef<HTMLInputElement>(null);\n const psdTask = async (fn: () => Promise<string[]>) => {\n try {\n setError(null);\n setPsdNotes(await fn());\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n }\n };\n /** Whether the next slider change records an undo step (the first of a drag does, the rest replace it). */\n const commitNext = useRef(true);\n\n const state = controller.getState();\n const rows = layerPanelRows(state.layers, state.activeLayerId);\n const active = controller.getActiveLayer();\n\n const attempt = (fn: () => unknown) => {\n try {\n setError(null);\n fn();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n }\n };\n const run = async (action: LayerMenuAction) => {\n setMenu(null);\n setError(await runLayerMenuAction(controller, action));\n };\n const prop = (key: 'opacity' | 'fillOpacity', value: number) =>\n attempt(() => {\n controller.setLayerProperties(active!.id, { [key]: value }, commitNext.current);\n commitNext.current = false;\n });\n const sliderEvents = {\n onPointerDown: () => (commitNext.current = true),\n onPointerUp: () => (commitNext.current = true),\n onKeyDown: () => (commitNext.current = true),\n };\n\n const onDrop = (e: React.DragEvent, row: LayerPanelRow) => {\n e.preventDefault();\n const id = e.dataTransfer.getData('text/x-pixerate-layer') || drag;\n setDrag(null);\n if (!id) return;\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n const fraction = rect.height ? (e.clientY - rect.top) / rect.height : 0.5;\n const placement = dropPlacement(state.layers, id, row.layer.id, dropZone(fraction, row.layer.type === 'group'));\n if (placement) attempt(() => controller.moveLayer(id, placement));\n };\n\n const thumb = (layer: ImageLayer) => (layerHasThumbnail(layer) ? controller.getLayerThumbnail(layer.id, { maxSide: 64 }) : null);\n const maskThumb = (layer: ImageLayer) => (layer.mask && !layer.mask.source ? controller.getLayerThumbnail(layer.id, { maxSide: 64, mask: true }) : null);\n\n const locked = (layer: ImageLayer) => Boolean(layer.locks?.all || layer.locks?.pixels || layer.locks?.position || layer.locks?.transparency);\n\n return (\n <div className={`flex flex-col gap-2 text-xs text-slate-200 ${className ?? ''}`} data-testid=\"layers-panel\" onClick={() => menu && setMenu(null)}>\n <div className=\"flex flex-wrap items-center gap-1\" role=\"toolbar\" aria-label=\"Layer actions\">\n <button type=\"button\" className={iconButton} onClick={() => run('new-layer')}>New Layer</button>\n <button type=\"button\" className={iconButton} onClick={() => run('new-group')}>New Group</button>\n <button type=\"button\" className={iconButton} disabled={!active} onClick={() => run('duplicate')}>Duplicate</button>\n <button type=\"button\" className={iconButton} disabled={!active} onClick={() => run('add-mask')}>Add Mask</button>\n <button type=\"button\" className={iconButton} disabled={!active} onClick={() => run('delete')}>Delete</button>\n <button\n type=\"button\"\n className={iconButton}\n aria-label=\"Layer menu\"\n aria-haspopup=\"menu\"\n onClick={(e) => {\n e.stopPropagation();\n const r = (e.currentTarget as HTMLElement).getBoundingClientRect();\n setMenu(menu ? null : { x: r.left, y: r.bottom });\n }}\n >\n ⋯\n </button>\n <select\n aria-label=\"Bits per channel\"\n title=\"Image › Mode: bits per channel\"\n className=\"rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200\"\n value={controller.bitDepth}\n onChange={(e) => attempt(() => controller.setBitDepth(Number(e.target.value) as 8 | 16 | 32))}\n >\n {BIT_DEPTH_OPTIONS.map((o) => (\n <option key={o.depth} value={o.depth} title={o.title}>\n {o.label}\n </option>\n ))}\n </select>\n {psd && (\n <>\n <button type=\"button\" className={iconButton} onClick={() => fileInput.current?.click()}>Open PSD…</button>\n <button type=\"button\" className={iconButton} onClick={() => psdTask(async () => (await downloadPsd(controller, psdFileName)).warnings)}>Export PSD</button>\n <input\n ref={fileInput}\n type=\"file\"\n accept={PSD_FILE_ACCEPT}\n className=\"hidden\"\n data-testid=\"psd-file-input\"\n aria-label=\"Open a PSD file\"\n onChange={(e) => {\n const file = e.currentTarget.files?.[0];\n e.currentTarget.value = '';\n if (file) psdTask(() => openPsdFile(controller, file));\n }}\n />\n </>\n )}\n </div>\n {psdNotes.length > 0 && (\n <ul className=\"rounded bg-amber-900/30 text-amber-200 px-2 py-1 space-y-0.5\" data-testid=\"psd-warnings\" aria-label=\"PSD warnings\">\n {psdNotes.map((n) => (\n <li key={n}>{n}</li>\n ))}\n <li>\n <button type=\"button\" className=\"underline\" onClick={() => setPsdNotes([])}>Dismiss</button>\n </li>\n </ul>\n )}\n\n {active && (\n <div className=\"grid grid-cols-2 gap-x-2 gap-y-1 items-center\" data-testid=\"layer-properties\">\n <label className=\"flex flex-col gap-0.5\">\n <span className=\"text-slate-400\">Opacity {Math.round(active.opacity * 100)}%</span>\n <input\n type=\"range\"\n min={0}\n max={100}\n aria-label=\"Layer opacity\"\n value={Math.round(active.opacity * 100)}\n {...sliderEvents}\n onChange={(e) => prop('opacity', Number(e.target.value) / 100)}\n className=\"accent-indigo-500\"\n />\n </label>\n <label className=\"flex flex-col gap-0.5\">\n <span className=\"text-slate-400\">Fill {Math.round(((active.type === 'pixel' ? active.fillOpacity : undefined) ?? 1) * 100)}%</span>\n <input\n type=\"range\"\n min={0}\n max={100}\n aria-label=\"Layer fill\"\n disabled={active.type !== 'pixel'}\n value={Math.round(((active.type === 'pixel' ? active.fillOpacity : undefined) ?? 1) * 100)}\n {...sliderEvents}\n onChange={(e) => prop('fillOpacity', Number(e.target.value) / 100)}\n className=\"accent-indigo-500 disabled:opacity-40\"\n />\n </label>\n <select\n aria-label=\"Layer blend mode\"\n className=\"bg-slate-800 border border-slate-700 rounded px-1.5 py-1\"\n value={active.blend}\n onChange={(e) => attempt(() => controller.setLayerProperties(active.id, { blend: e.target.value as never }))}\n >\n {active.type === 'group' && <option value=\"pass-through\">Pass Through</option>}\n {BLEND_MODES.map((m) => (\n <option key={m.id} value={m.id}>{m.label}</option>\n ))}\n </select>\n <label className=\"flex items-center gap-1.5 text-slate-300\">\n <input\n type=\"checkbox\"\n aria-label=\"Clip to layer below\"\n checked={Boolean(active.clipped)}\n onChange={(e) => attempt(() => controller.setLayerProperties(active.id, { clipped: e.target.checked }))}\n className=\"accent-indigo-500\"\n />\n Clip to below\n </label>\n <div className=\"col-span-2 flex flex-wrap gap-2 text-slate-400\" role=\"group\" aria-label=\"Layer locks\">\n {(['pixels', 'transparency', 'position', 'all'] as const).map((k) => (\n <label key={k} className=\"flex items-center gap-1\">\n <input\n type=\"checkbox\"\n aria-label={`Lock ${k}`}\n checked={Boolean(active.locks?.[k])}\n onChange={(e) => attempt(() => controller.setLayerProperties(active.id, { locks: { ...active.locks, [k]: e.target.checked } }))}\n className=\"accent-indigo-500\"\n />\n {k}\n </label>\n ))}\n </div>\n </div>\n )}\n\n {effects && active && active.type !== 'adjustment' && <LayerEffectsPanel controller={controller} className=\"border-t border-slate-800 pt-1.5\" />}\n\n <ul className=\"flex flex-col gap-0.5\" role=\"tree\" aria-label=\"Layers\">\n {rows.map((row) => {\n const { layer } = row;\n return (\n <li\n key={layer.id}\n role=\"treeitem\"\n aria-selected={row.active}\n aria-level={row.depth + 1}\n data-layer-id={layer.id}\n draggable={!layer.locks?.all}\n onDragStart={(e) => {\n e.dataTransfer.setData('text/x-pixerate-layer', layer.id);\n setDrag(layer.id);\n }}\n onDragOver={(e) => e.preventDefault()}\n onDrop={(e) => onDrop(e, row)}\n tabIndex={0}\n onClick={() => attempt(() => controller.setActiveLayer(layer.id, 'pixels'))}\n onKeyDown={(e) => {\n if (e.target === e.currentTarget && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n attempt(() => controller.setActiveLayer(layer.id, 'pixels'));\n }\n }}\n onContextMenu={(e) => {\n e.preventDefault();\n controller.setActiveLayer(layer.id, state.activeLayerId === layer.id ? state.activeTarget : 'pixels');\n setMenu({ x: e.clientX, y: e.clientY });\n }}\n className={rowClass(row.active)}\n style={{ paddingLeft: 6 + row.depth * 14 }}\n >\n <button\n type=\"button\"\n aria-label={layer.visible ? `Hide ${row.label}` : `Show ${row.label}`}\n aria-pressed={layer.visible}\n className=\"w-4 text-center text-slate-300\"\n onClick={(e) => {\n e.stopPropagation();\n attempt(() => controller.setLayerProperties(layer.id, { visible: !layer.visible }));\n }}\n >\n {layer.visible ? '●' : '○'}\n </button>\n {layer.type === 'group' && (\n <button\n type=\"button\"\n aria-label={layer.collapsed ? `Expand ${row.label}` : `Collapse ${row.label}`}\n className=\"w-3 text-slate-400\"\n onClick={(e) => {\n e.stopPropagation();\n attempt(() => controller.setLayerProperties(layer.id, { collapsed: !layer.collapsed }));\n }}\n >\n {layer.collapsed ? '▸' : '▾'}\n </button>\n )}\n {row.clipped && <span className=\"text-slate-500\" aria-label=\"Clipped\">↳</span>}\n {layerHasThumbnail(layer) ? (\n <span className=\"relative shrink-0\">\n <Thumbnail\n pixels={thumb(layer)}\n size={thumbnailSize}\n label={`${row.label} pixels`}\n selected={row.active && state.activeTarget === 'pixels' && Boolean(layer.mask)}\n />\n {layer.type !== 'pixel' && (\n <span\n data-testid=\"layer-kind-badge\"\n className=\"absolute -bottom-1 -right-1 rounded bg-slate-700 px-0.5 text-[8px] font-bold leading-tight text-slate-100 ring-1 ring-slate-900\"\n >\n {layerBadge(layer)}\n </span>\n )}\n </span>\n ) : (\n <span\n className=\"shrink-0 grid place-items-center rounded bg-slate-800 text-[9px] text-slate-400 ring-1 ring-slate-700\"\n style={{ width: thumbnailSize, height: thumbnailSize }}\n >\n {layerBadge(layer)}\n </span>\n )}\n {layer.mask && !layer.mask.source && layer.type === 'pixel' && (\n <button\n type=\"button\"\n aria-label={`${layer.mask.linked === false ? 'Link' : 'Unlink'} ${row.label} mask`}\n aria-pressed={layer.mask.linked !== false}\n title={layer.mask.linked === false ? 'Mask unlinked: it stays put when the layer moves or transforms. Click to link.' : 'Mask linked: it moves with the layer. Click to unlink.'}\n data-testid=\"layer-mask-link\"\n className={`shrink-0 text-[10px] leading-none ${layer.mask.linked === false ? 'text-slate-600' : 'text-slate-300'}`}\n onClick={(e) => {\n e.stopPropagation();\n attempt(() => controller.setLayerMaskProps(layer.id, { linked: layer.mask!.linked === false }));\n }}\n >\n {layer.mask.linked === false ? '⛓︎̸' : '⛓︎'}\n </button>\n )}\n {layer.mask && (\n <Thumbnail\n pixels={maskThumb(layer)}\n size={thumbnailSize}\n label={`${row.label} mask${layer.mask.enabled === false ? ' (disabled)' : ''}`}\n testId=\"layer-mask-thumbnail\"\n selected={row.active && state.activeTarget === 'mask'}\n onClick={(e) => {\n e.stopPropagation();\n if (e.shiftKey) attempt(() => controller.setLayerMaskProps(layer.id, { enabled: layer.mask!.enabled === false }));\n else attempt(() => controller.setActiveLayer(layer.id, 'mask'));\n }}\n />\n )}\n {renaming === layer.id ? (\n <input\n autoFocus\n aria-label=\"Layer name\"\n defaultValue={layer.name || row.label}\n className=\"flex-1 min-w-0 bg-slate-900 border border-slate-600 rounded px-1\"\n onClick={(e) => e.stopPropagation()}\n onBlur={(e) => {\n setRenaming(null);\n if (e.target.value.trim() && e.target.value !== layer.name) attempt(() => controller.setLayerProperties(layer.id, { name: e.target.value }));\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') (e.target as HTMLInputElement).blur();\n if (e.key === 'Escape') setRenaming(null);\n }}\n />\n ) : (\n <span\n className={`flex-1 min-w-0 truncate ${layer.visible ? '' : 'text-slate-500'}`}\n onDoubleClick={(e) => {\n e.stopPropagation();\n setRenaming(layer.id);\n }}\n >\n {row.label}\n </span>\n )}\n {layerWarning(layer) && (\n <span role=\"img\" data-testid=\"layer-warning\" aria-label={layerWarning(layer)!} title={layerWarning(layer)!} className=\"text-[10px] text-amber-400\">\n ⚠\n </span>\n )}\n {layerEffectsBadge(layer) && (\n <button\n type=\"button\"\n data-testid=\"layer-fx-badge\"\n aria-label={layerEffectsBadge(layer) === 'on' ? `Turn effects off for ${row.label}` : `Turn effects on for ${row.label}`}\n aria-pressed={layerEffectsBadge(layer) === 'on'}\n className={`text-[9px] italic font-semibold ${layerEffectsBadge(layer) === 'on' ? 'text-indigo-300' : 'text-slate-600 line-through'}`}\n onClick={(e) => {\n e.stopPropagation();\n attempt(() => controller.setLayerEffectsEnabled(layer.id, layerEffectsBadge(layer) !== 'on'));\n }}\n >\n fx\n </button>\n )}\n {locked(layer) && <span aria-label=\"Locked\" className=\"text-slate-400\">🔒</span>}\n {layer.blend !== 'normal' && layer.blend !== 'pass-through' && <span className=\"text-[9px] text-slate-500\">{layer.blend}</span>}\n </li>\n );\n })}\n </ul>\n\n {error && (\n <p role=\"alert\" className=\"text-rose-400\">\n {error}\n </p>\n )}\n\n {menu && (\n <div\n role=\"menu\"\n aria-label=\"Layer menu\"\n className=\"fixed z-50 min-w-44 rounded border border-slate-700 bg-slate-900 py-1 shadow-xl\"\n style={{ left: menu.x, top: menu.y }}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.key === 'Escape' && setMenu(null)}\n >\n {layerMenu(controller).map((item) => (\n <button\n key={item.action}\n type=\"button\"\n role=\"menuitem\"\n disabled={!item.enabled}\n className=\"block w-full px-3 py-1 text-left hover:bg-slate-800 disabled:opacity-40\"\n onClick={() => run(item.action)}\n >\n {item.label}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n};\n","import React, { useEffect, useRef, useState } from 'react';\nimport type { EffectControl, ImageEditorController, LayerEffectKind } from '@pixerate/editor/image-editor';\nimport { LAYER_EFFECT_MENU, effectControlChange, layerEffectControls, layerEffectsPanel } from '@pixerate/editor/image-editor';\n\nexport interface LayerEffectsPanelProps {\n controller: ImageEditorController;\n /** The layer whose effects to show (default: the active layer). */\n layerId?: string | null;\n className?: string;\n}\n\nconst button = 'px-1.5 py-0.5 rounded text-[10px] bg-slate-800 text-slate-300 hover:text-white disabled:opacity-40';\n\n/**\n * A layer's effects (Photoshop's layer styles): the master switch, Scale Effects, an \"Add effect\"\n * menu, and each effect with its enabled toggle, remove button and, when expanded, its settings.\n * Every change is one undo step (a slider drag is one step too).\n */\nexport const LayerEffectsPanel: React.FC<LayerEffectsPanelProps> = ({ controller, layerId, className }) => {\n const [, setTick] = useState(0);\n useEffect(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);\n const [open, setOpen] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n /** Whether the next slider change records an undo step (the first of a drag does, the rest replace it). */\n const commitNext = useRef(true);\n\n const layer = layerId ? controller.getLayer(layerId) : controller.getActiveLayer();\n const model = layerEffectsPanel(layer);\n const id = layer?.id;\n const attempt = (fn: () => unknown) => {\n try {\n setError(null);\n fn();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n }\n };\n const sliderEvents = {\n onPointerDown: () => (commitNext.current = true),\n onPointerUp: () => (commitNext.current = true),\n onKeyDown: () => (commitNext.current = true),\n };\n\n if (!model.available || !id) {\n return (\n <div className={`text-xs text-slate-500 ${className ?? ''}`} data-testid=\"layer-effects\">\n {model.reason}\n </div>\n );\n }\n const effects = controller.getLayerEffects(id);\n const patterns = controller.getDocumentPatterns();\n const change = (effectId: string, control: EffectControl, value: unknown, drag = false) =>\n attempt(() => {\n const effect = controller.getLayerEffects(id).items.find((e) => e.id === effectId)!;\n controller.updateLayerEffect(id, effectId, effectControlChange(effect, control.key, value, patterns), drag ? commitNext.current : true);\n if (drag) commitNext.current = false;\n });\n\n const renderControl = (effectId: string, c: EffectControl) => {\n const label = `${c.label}`;\n switch (c.type) {\n case 'range': {\n const k = c.percent ? 100 : 1;\n const shown = Math.round(c.value * k * 100) / 100;\n return (\n <label key={c.key} className=\"flex flex-col gap-0.5\">\n <span className=\"text-slate-400\">\n {label} {shown}\n {c.unit}\n </span>\n <input\n type=\"range\"\n aria-label={label}\n min={c.min * k}\n max={c.max * k}\n step={c.step * k}\n value={shown}\n disabled={model.readOnly}\n {...sliderEvents}\n onChange={(e) => change(effectId, c, Number(e.target.value) / k, true)}\n className=\"accent-indigo-500\"\n />\n </label>\n );\n }\n case 'color':\n return (\n <label key={c.key} className=\"flex items-center gap-1.5 text-slate-300\">\n <input type=\"color\" aria-label={label} value={c.value} disabled={model.readOnly} onChange={(e) => change(effectId, c, e.target.value)} />\n {label}\n </label>\n );\n case 'checkbox':\n return (\n <label key={c.key} className=\"flex items-center gap-1.5 text-slate-300\">\n <input type=\"checkbox\" aria-label={label} checked={c.value} disabled={model.readOnly} onChange={(e) => change(effectId, c, e.target.checked)} className=\"accent-indigo-500\" />\n {label}\n </label>\n );\n case 'select':\n return (\n <label key={c.key} className=\"flex flex-col gap-0.5\">\n <span className=\"text-slate-400\">{label}</span>\n <select\n aria-label={label}\n value={c.value}\n disabled={model.readOnly}\n onChange={(e) => change(effectId, c, e.target.value)}\n className=\"bg-slate-800 border border-slate-700 rounded px-1.5 py-1\"\n >\n {c.options.map((o) => (\n <option key={o.value} value={o.value}>\n {o.label}\n </option>\n ))}\n </select>\n </label>\n );\n }\n };\n\n return (\n <div className={`flex flex-col gap-1.5 text-xs text-slate-200 ${className ?? ''}`} data-testid=\"layer-effects\" aria-label=\"Layer effects\" role=\"group\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"font-semibold text-slate-300\">fx Effects</span>\n <label className=\"flex items-center gap-1 text-slate-300\">\n <input\n type=\"checkbox\"\n aria-label=\"Effects on\"\n checked={model.enabled}\n disabled={model.readOnly}\n onChange={(e) => attempt(() => controller.setLayerEffectsEnabled(id, e.target.checked))}\n className=\"accent-indigo-500\"\n />\n On\n </label>\n <label className=\"flex items-center gap-1 text-slate-400\">\n Scale\n <input\n type=\"number\"\n aria-label=\"Scale effects\"\n min={1}\n max={1000}\n step={1}\n value={Math.round(model.scale * 100)}\n disabled={model.readOnly}\n onChange={(e) => {\n const v = Number(e.target.value);\n if (v >= 1 && v <= 1000) attempt(() => controller.setLayerEffectsEnabled(id, model.enabled, v / 100));\n }}\n className=\"w-14 bg-slate-800 border border-slate-700 rounded px-1\"\n />\n %\n </label>\n <select\n aria-label=\"Add effect\"\n value=\"\"\n disabled={model.readOnly}\n onChange={(e) => {\n const kind = e.target.value as LayerEffectKind;\n if (!kind) return;\n attempt(() => setOpen(controller.addLayerEffect(id, kind).effect.id));\n }}\n className=\"bg-slate-800 border border-slate-700 rounded px-1.5 py-1\"\n >\n <option value=\"\">Add effect…</option>\n {LAYER_EFFECT_MENU.map((m) => (\n <option key={m.kind} value={m.kind}>\n {m.label}\n </option>\n ))}\n </select>\n </div>\n {model.readOnly && model.reason && <p className=\"text-slate-500\">{model.reason}</p>}\n <ul className=\"flex flex-col gap-1\" aria-label=\"Effects\">\n {model.rows.map((row) => {\n const effect = effects.items.find((e) => e.id === row.id)!;\n const expanded = open === row.id;\n return (\n <li key={row.id} data-effect-id={row.id} className=\"rounded bg-slate-900/60 ring-1 ring-slate-800\">\n <div className=\"flex items-center gap-1.5 px-1.5 py-1\">\n <input\n type=\"checkbox\"\n aria-label={`${row.label} on`}\n checked={row.enabled}\n disabled={model.readOnly}\n onChange={(e) => attempt(() => controller.updateLayerEffect(id, row.id, { enabled: e.target.checked }))}\n className=\"accent-indigo-500\"\n />\n <button\n type=\"button\"\n aria-expanded={expanded}\n className={`flex-1 text-left ${row.enabled && model.enabled ? '' : 'text-slate-500'}`}\n onClick={() => setOpen(expanded ? null : row.id)}\n >\n {row.label}\n </button>\n <button type=\"button\" className={button} aria-label={`Remove ${row.label}`} disabled={model.readOnly} onClick={() => attempt(() => controller.removeLayerEffect(id, row.id))}>\n ✕\n </button>\n </div>\n {expanded && (\n <div className=\"grid grid-cols-2 gap-x-2 gap-y-1 px-1.5 pb-1.5\" data-testid=\"effect-settings\">\n {layerEffectControls(effect, patterns).map((c) => renderControl(row.id, c))}\n </div>\n )}\n </li>\n );\n })}\n </ul>\n {error && (\n <p role=\"alert\" className=\"text-rose-400\">\n {error}\n </p>\n )}\n </div>\n );\n};\n","import React, { useEffect, useState } from 'react';\nimport { findLayer, type ImageEditorController, type ImageLayer, type SmartObjectLayer } from '@pixerate/editor/image-editor';\nimport type { EffectProvider } from '@pixerate/editor/effects';\nimport { EffectParameters, EffectsBrowser, useEffectDescription } from '../effects';\n\nexport interface ImageProviderEffectsPanelProps {\n controller: ImageEditorController;\n className?: string;\n}\n\nconst btn = 'rounded border border-slate-700 px-1.5 py-0.5 text-[11px] text-slate-300 hover:text-white disabled:opacity-40';\n\n/** One effect's controls, loaded from the provider; a note when it does not have the effect. */\nfunction Controls({\n provider,\n effect,\n name,\n values,\n onChange,\n onPreset,\n}: {\n provider: EffectProvider | null;\n effect: string;\n name?: string;\n values: Readonly<Record<string, unknown>>;\n onChange: (control: string, value: unknown, gesture: string | null) => void;\n onPreset: (values: Readonly<Record<string, unknown>>) => void;\n}) {\n const { description, error } = useEffectDescription(provider, effect);\n if (!provider) return <p className=\"text-[11px] text-slate-400\">No effects provider: \"{name ?? effect}\" is kept but not drawn.</p>;\n if (error) return <p className=\"text-[11px] text-amber-400\">{error}</p>;\n if (!description) return <p className=\"text-[11px] text-slate-400\">Loading…</p>;\n return <EffectParameters description={description} values={values} onChange={onChange} onReset={(k) => onChange(k, description.defaults[k], null)} onPreset={onPreset} />;\n}\n\n/**\n * Provider effects in the image editor, for the active layer: its effect smart filters (apply,\n * turn on and off, opacity, reorder, change controls, remove) and, for an effect layer, its own\n * controls; plus adding effect layers. Applying a filter effect to a pixel layer converts it to a\n * smart object in the same undo step. Without a provider it says why nothing can be added.\n */\nexport function ImageProviderEffectsPanel({ controller, className = '' }: ImageProviderEffectsPanelProps) {\n const [, setTick] = useState(0);\n useEffect(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);\n const [browse, setBrowse] = useState<null | 'filter' | 'layer'>(null);\n const [message, setMessage] = useState<string | null>(null);\n const [open, setOpen] = useState<string | null>(null);\n const provider = controller.effectsProvider;\n const state = controller.getState();\n const layer: ImageLayer | null = state.activeLayerId ? (findLayer(state.layers, state.activeLayerId)?.layer ?? null) : null;\n const run = (work: () => unknown) => {\n setMessage(null);\n Promise.resolve()\n .then(work)\n .catch((e: unknown) => setMessage(e instanceof Error ? e.message : String(e)));\n };\n const drags = React.useRef(new Set<string>());\n /** Changes during a drag skip the undo stack; the last one (gesture ended) records one step. */\n const commit = (gesture: string | null) => {\n if (gesture) {\n if (!drags.current.has(gesture)) {\n drags.current.add(gesture);\n return true;\n }\n return false;\n }\n return true;\n };\n const filters = layer?.type === 'smart' ? ((layer as SmartObjectLayer).smartFilters?.filters ?? []).filter((f) => f.kind === 'effect') : [];\n const generator = layer?.type === 'pixel' ? layer.generator : undefined;\n const canFilter = !!layer && layer.type !== 'adjustment' && layer.type !== 'annotation';\n\n return (\n <section className={`flex flex-col gap-2 text-xs ${className}`} aria-label=\"Provider effects\" data-image-provider-effects=\"\">\n <div className=\"flex items-center gap-1\">\n <span className=\"flex-1 font-semibold uppercase tracking-wider text-[11px] text-slate-200\">Effects</span>\n <button type=\"button\" className={btn} disabled={!provider || !canFilter} aria-pressed={browse === 'filter'} onClick={() => setBrowse(browse === 'filter' ? null : 'filter')}>\n Apply effect…\n </button>\n <button type=\"button\" className={btn} disabled={!provider} aria-pressed={browse === 'layer'} onClick={() => setBrowse(browse === 'layer' ? null : 'layer')}>\n Effect layer…\n </button>\n </div>\n {!provider && <p className=\"text-[11px] text-slate-400\">No effects provider is registered. Effects in the document are kept.</p>}\n {browse === 'filter' && layer && (\n <EffectsBrowser provider={provider} uses={['filter']} title=\"Filters\" onPick={(e) => (setBrowse(null), run(() => controller.applyEffectFilter(layer.id, e.id)))} />\n )}\n {browse === 'layer' && (\n <EffectsBrowser provider={provider} uses={['generator', 'overlay', 'title']} title=\"Generators and overlays\" onPick={(e) => (setBrowse(null), run(() => controller.addEffectLayer(e.id)))} />\n )}\n {generator && layer && (\n <div className=\"space-y-1\" data-effect-part=\"generator\">\n <div className=\"flex items-center gap-1\">\n <span className=\"flex-1 font-medium text-slate-200\">{generator.name ?? generator.effect}</span>\n <button type=\"button\" className={btn} title=\"Keep the pixels as a plain layer\" onClick={() => run(() => controller.rasterizeEffectLayer(layer.id))}>\n Rasterize\n </button>\n </div>\n <Controls\n provider={provider}\n effect={generator.effect}\n name={generator.name}\n values={generator.values}\n onChange={(k, v, gesture) => run(() => controller.updateEffectLayer(layer.id, { values: { [k]: v as never } }, commit(gesture)))}\n onPreset={(values) => run(() => controller.updateEffectLayer(layer.id, { values: values as never }))}\n />\n </div>\n )}\n {filters.length > 0 && layer && (\n <ol className=\"space-y-1\" data-effect-part=\"filters\">\n {filters.map((f) => {\n const label = f.kind === 'effect' ? (f.name ?? f.effect) : f.kind;\n const all = (layer as SmartObjectLayer).smartFilters!.filters;\n const index = all.indexOf(f);\n if (f.kind !== 'effect') return null;\n return (\n <li key={f.id} className=\"rounded border border-slate-700 p-1\" data-smart-effect={f.id}>\n <div className=\"flex items-center gap-1\">\n <input type=\"checkbox\" checked={f.enabled} aria-label={`${label} on`} onChange={(e) => {\n const enabled = e.currentTarget.checked;\n run(() => controller.updateEffectFilter(layer.id, f.id, { enabled }));\n }} />\n <button type=\"button\" className=\"min-w-0 flex-1 truncate text-left text-slate-200\" aria-expanded={open === f.id} onClick={() => setOpen(open === f.id ? null : f.id)}>\n {label}\n </button>\n <button type=\"button\" className={btn} disabled={index === all.length - 1} aria-label=\"Move up\" onClick={() => run(() => controller.updateEffectFilter(layer.id, f.id, { index: index + 1 }))}>\n ↑\n </button>\n <button type=\"button\" className={btn} disabled={index === 0} aria-label=\"Move down\" onClick={() => run(() => controller.updateEffectFilter(layer.id, f.id, { index: index - 1 }))}>\n ↓\n </button>\n <button type=\"button\" className={btn} aria-label={`Remove ${label}`} onClick={() => run(() => controller.removeSmartFilter(layer.id, f.id))}>\n ✕\n </button>\n </div>\n {open === f.id && (\n <div className=\"mt-1 space-y-2\">\n <label className=\"flex items-center gap-1\">\n <span className=\"w-14 text-[11px] text-slate-300\">Opacity</span>\n <input\n type=\"range\"\n min={0}\n max={1}\n step={0.01}\n className=\"flex-1\"\n value={f.opacity}\n aria-label={`${label} opacity`}\n onChange={(e) => {\n const opacity = Number(e.currentTarget.value);\n run(() => controller.updateEffectFilter(layer.id, f.id, { opacity }));\n }}\n />\n </label>\n <Controls\n provider={provider}\n effect={f.effect}\n name={f.name}\n values={f.values}\n onChange={(k, v, gesture) => run(() => controller.updateEffectFilter(layer.id, f.id, { values: { [k]: v as never } }, commit(gesture)))}\n onPreset={(values) => run(() => controller.updateEffectFilter(layer.id, f.id, { values: values as never }))}\n />\n </div>\n )}\n </li>\n );\n })}\n </ol>\n )}\n {!layer && <p className=\"text-[11px] text-slate-400\">Select a layer to apply effects to it.</p>}\n {message && (\n <p role=\"alert\" className=\"text-[11px] text-rose-400\">\n {message}\n </p>\n )}\n </section>\n );\n}\n","import { useEffect, useState } from 'react';\nimport type { EffectDescription, EffectProvider } from '@pixerate/editor/effects';\n\n/** Anything that takes an effects provider: every editor controller with effects support. */\nexport interface EffectsHost {\n useEffects(provider: EffectProvider): () => void;\n}\n\n/**\n * Registers `provider` with an editor while mounted (or while it is the one passed), and removes it\n * again on unmount. Pass `null` or `undefined` for no provider: the editor then behaves as without\n * effects support.\n */\nexport function useEffects(host: EffectsHost | null | undefined, provider: EffectProvider | null | undefined): void {\n useEffect(() => {\n if (!host || !provider) return;\n return host.useEffects(provider);\n }, [host, provider]);\n}\n\n/** An effect's description from the provider, loaded when `effect` changes (`null` while loading or on error). */\nexport function useEffectDescription(provider: EffectProvider | null | undefined, effect: string | null | undefined): { description: EffectDescription | null; error: string | null } {\n const [state, setState] = useState<{ key: string; description: EffectDescription | null; error: string | null }>({ key: '', description: null, error: null });\n const key = provider && effect ? `${provider.id}:${effect}` : '';\n useEffect(() => {\n if (!provider || !effect) return;\n let live = true;\n Promise.resolve()\n .then(() => provider.describe(effect))\n .then(\n (description) => live && setState({ key, description, error: null }),\n (e: unknown) => live && setState({ key, description: null, error: e instanceof Error ? e.message : String(e) }),\n );\n return () => {\n live = false;\n };\n }, [provider, effect, key]);\n return state.key === key ? { description: state.description, error: state.error } : { description: null, error: null };\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { renderEffectThumbnail, type EffectProvider, type EffectSummary } from '@pixerate/editor/effects';\n\nexport interface EffectThumbnailProps {\n provider: EffectProvider;\n effect: EffectSummary;\n /** Pixel size of the preview (default 96 × 54). */\n width?: number;\n height?: number;\n className?: string;\n}\n\n/**\n * A preview of an effect drawn by the provider's own renderer (filters on a sample picture,\n * transitions half way, generators mid-way through). Motion effects and failures show a label.\n */\nexport function EffectThumbnail({ provider, effect, width = 96, height = 54, className = '' }: EffectThumbnailProps) {\n const ref = useRef<HTMLCanvasElement>(null);\n const [failed, setFailed] = useState(effect.kind === 'motion');\n useEffect(() => {\n if (effect.kind === 'motion') return;\n let live = true;\n renderEffectThumbnail(provider, effect, { width, height }).then(\n (pixels) => {\n const ctx = live ? ref.current?.getContext('2d') : null;\n if (!ctx || typeof ImageData === 'undefined') return;\n ctx.putImageData(new ImageData(new Uint8ClampedArray(pixels.data), pixels.width, pixels.height), 0, 0);\n },\n () => live && setFailed(true),\n );\n return () => {\n live = false;\n };\n }, [provider, effect, width, height]);\n return (\n <div\n className={`relative overflow-hidden rounded border border-border bg-[repeating-conic-gradient(#8884_0_25%,transparent_0_50%)] bg-[length:12px_12px] ${className}`}\n style={{ aspectRatio: `${width} / ${height}` }}\n data-effect-thumbnail={effect.id}\n >\n {failed ? (\n <span className=\"absolute inset-0 flex items-center justify-center text-[10px] text-muted-foreground\">{effect.kind === 'motion' ? 'Motion' : 'No preview'}</span>\n ) : (\n <canvas ref={ref} width={width} height={height} className=\"h-full w-full\" aria-hidden=\"true\" />\n )}\n </div>\n );\n}\n","import React, { useEffect, useMemo, useState } from 'react';\nimport { EFFECT_USE_LABELS, type EffectKind, type EffectProvider, type EffectSummary, type EffectUse } from '@pixerate/editor/effects';\nimport { EffectThumbnail } from './EffectThumbnail';\n\nexport interface EffectsBrowserProps {\n /** The editor's provider; without one the browser says effects are unavailable. */\n provider: EffectProvider | null | undefined;\n /** Only effects with one of these uses (default: all but motion). */\n uses?: readonly EffectUse[];\n /** Only effects of these kinds (default: any). */\n kinds?: readonly EffectKind[];\n /** Called with the effect the user picks. */\n onPick: (effect: EffectSummary) => void;\n /** Draw previews with the provider's renderer (default true). */\n thumbnails?: boolean;\n /** Heading (default \"Effects\"). */\n title?: React.ReactNode;\n className?: string;\n}\n\n/**\n * Browses a provider's effects: a search box, a category filter (and a use filter when more than\n * one use is allowed), and a grid of effects with previews. Picking one calls `onPick`.\n */\nexport function EffectsBrowser({ provider, uses, kinds, onPick, thumbnails = true, title = 'Effects', className = '' }: EffectsBrowserProps) {\n const [all, setAll] = useState<readonly EffectSummary[]>([]);\n const [query, setQuery] = useState('');\n const [category, setCategory] = useState('');\n const [use, setUse] = useState<EffectUse | ''>('');\n const [error, setError] = useState<string | null>(null);\n useEffect(() => {\n if (!provider) return setAll([]);\n let live = true;\n Promise.resolve()\n .then(() => provider.list())\n .then(\n (list) => live && (setAll(list), setError(null)),\n (e: unknown) => live && setError(e instanceof Error ? e.message : String(e)),\n );\n return () => {\n live = false;\n };\n }, [provider]);\n const [found, setFound] = useState<readonly EffectSummary[]>([]);\n useEffect(() => {\n if (!provider) return setFound([]);\n let live = true;\n Promise.resolve()\n .then(() => provider.search(query, { ...(category ? { category } : {}), ...(use ? { use } : {}) }))\n .then((list) => live && setFound(list), () => live && setFound([]));\n return () => {\n live = false;\n };\n }, [provider, query, category, use]);\n const allowed = (e: EffectSummary) => (!kinds || kinds.includes(e.kind)) && (uses ? e.kind !== 'motion' || uses.includes('motion') : e.kind !== 'motion') && (!uses || e.uses.some((u) => uses.includes(u)));\n const categories = useMemo(() => [...new Set(all.filter(allowed).map((e) => e.category))], [all, uses, kinds]);\n const shown = found.filter(allowed);\n if (!provider)\n return (\n <div className={`rounded-md border border-dashed border-border p-3 text-xs text-muted-foreground ${className}`} data-effects-browser=\"\" data-effects-unavailable=\"\">\n No effects provider is registered, so effects cannot be added. Effects already in the document are kept.\n </div>\n );\n return (\n <section className={`flex flex-col gap-2 ${className}`} data-effects-browser=\"\" aria-label=\"Effects browser\">\n {title && <h3 className=\"text-xs font-semibold\">{title}</h3>}\n <div className=\"flex flex-wrap gap-1\">\n <input\n type=\"search\"\n className=\"min-w-0 flex-1 rounded border border-border bg-transparent px-1.5 py-0.5 text-xs\"\n placeholder=\"Search effects\"\n aria-label=\"Search effects\"\n value={query}\n onChange={(e) => setQuery(e.currentTarget.value)}\n />\n <select className=\"rounded border border-border bg-transparent px-1 py-0.5 text-xs\" aria-label=\"Category\" value={category} onChange={(e) => setCategory(e.currentTarget.value)}>\n <option value=\"\">All categories</option>\n {categories.map((c) => (\n <option key={c} value={c}>\n {c}\n </option>\n ))}\n </select>\n {uses && uses.length > 1 && (\n <select className=\"rounded border border-border bg-transparent px-1 py-0.5 text-xs\" aria-label=\"Use\" value={use} onChange={(e) => setUse(e.currentTarget.value as EffectUse | '')}>\n <option value=\"\">Any use</option>\n {uses.map((u) => (\n <option key={u} value={u}>\n {EFFECT_USE_LABELS[u]}\n </option>\n ))}\n </select>\n )}\n </div>\n {error && <p role=\"alert\" className=\"text-[11px] text-destructive\">{error}</p>}\n <ul className=\"grid max-h-96 grid-cols-[repeat(auto-fill,minmax(6.5rem,1fr))] gap-1.5 overflow-y-auto\" role=\"list\">\n {shown.map((e) => (\n <li key={e.id}>\n <button\n type=\"button\"\n className=\"flex w-full flex-col gap-1 rounded border border-transparent p-1 text-left hover:border-border focus-visible:border-border\"\n title={e.description ?? e.name}\n data-effect-id={e.id}\n onClick={() => onPick(e)}\n >\n {thumbnails && <EffectThumbnail provider={provider} effect={e} />}\n <span className=\"truncate text-[11px] font-medium\">{e.name}</span>\n <span className=\"truncate text-[10px] text-muted-foreground\">{e.uses.map((u) => EFFECT_USE_LABELS[u]).join(' · ')}</span>\n </button>\n </li>\n ))}\n </ul>\n {!shown.length && !error && <p className=\"text-[11px] text-muted-foreground\">No effects match.</p>}\n </section>\n );\n}\n","import React, { useId, useMemo } from 'react';\nimport { effectFieldValue, effectParameterFields, type EffectDescription } from '@pixerate/editor/effects';\nimport { parameterLabel, parameterValuesEqual, type ParameterValue } from '@pixerate/editor/parameters';\nimport { ParameterFieldControl } from '../parameters/fields';\n\nexport interface EffectParametersProps {\n /** The effect's description (`describe`). */\n description: EffectDescription;\n /** Its saved values; controls left out show their defaults. */\n values: Readonly<Record<string, unknown>>;\n /**\n * A control changed. While a slider or colour drag is under way `gesture` is a key unique to\n * that drag, so the host can fold its changes into one undo step; otherwise `null`.\n */\n onChange: (control: string, value: ParameterValue, gesture: string | null) => void;\n /** Resets one control to its default. */\n onReset?: (control: string) => void;\n /** Controls that are keyframed: shown read-only with a note (edit them as keyframes). */\n keyframed?: ReadonlySet<string>;\n /** Applies a preset's values. */\n onPreset?: (values: Readonly<Record<string, unknown>>) => void;\n disabled?: boolean;\n className?: string;\n}\n\n/**\n * The parameter panel of an effect, generated from its JSON Schema controls: sliders for bounded\n * numbers, switches, choices, colour pickers, vectors and text, with each control's description,\n * per-control reset and the effect's presets.\n */\nexport function EffectParameters({ description, values, onChange, onReset, keyframed, onPreset, disabled = false, className = '' }: EffectParametersProps) {\n const fields = useMemo(() => effectParameterFields(description), [description]);\n const idBase = useId();\n const gesture = React.useRef<string | null>(null);\n const count = React.useRef(0);\n return (\n <div className={`space-y-2 ${className}`} data-effect-parameters={description.id}>\n {onPreset && description.presets.length > 0 && (\n <select\n className=\"w-full rounded border border-border bg-transparent px-1 py-0.5 text-xs\"\n aria-label={`${description.name} presets`}\n value=\"\"\n disabled={disabled}\n onChange={(e) => {\n const preset = description.presets.find((p) => p.name === e.currentTarget.value);\n if (preset) onPreset({ ...description.defaults, ...preset.values });\n }}\n >\n <option value=\"\">Presets…</option>\n {description.presets.map((p) => (\n <option key={p.name} value={p.name}>\n {p.name}\n </option>\n ))}\n </select>\n )}\n {fields.map((field) => {\n const label = parameterLabel(field);\n const inputId = `${idBase}-${field.id}`;\n const keyed = keyframed?.has(field.id) ?? false;\n const value = effectFieldValue(field, values[field.id]);\n const changed = !keyed && !parameterValuesEqual(value, field.default);\n return (\n <div key={field.id} className=\"space-y-1\" data-effect-control={field.id}>\n <div className=\"flex items-center gap-1.5\">\n <label htmlFor={inputId} className=\"min-w-0 flex-1 truncate text-xs font-medium\" title={field.description}>\n {label}\n </label>\n {keyed && <span className=\"text-[10px] text-muted-foreground\">keyframed</span>}\n {onReset && changed && !disabled && (\n <button type=\"button\" className=\"rounded px-1 text-[11px] text-muted-foreground hover:text-foreground\" aria-label={`Reset ${label}`} onClick={() => onReset(field.id)}>\n ↺\n </button>\n )}\n </div>\n <ParameterFieldControl\n field={field}\n value={value}\n id={inputId}\n disabled={disabled || keyed}\n onChange={(v) => onChange(field.id, v, gesture.current)}\n onGestureStart={() => (gesture.current = `${idBase}:${field.id}:${++count.current}`)}\n onGestureEnd={() => (gesture.current = null)}\n />\n </div>\n );\n })}\n {!fields.length && <p className=\"text-[11px] text-muted-foreground\">No controls.</p>}\n </div>\n );\n}\n","import React, { useRef } from 'react';\nimport {\n choiceOptionLabel,\n formatParameterNumber,\n getChoiceOptions,\n isSliderField,\n normalizeHexColor,\n parameterLabel,\n parameterStep,\n parseParameterNumberInput,\n clampParameterNumber,\n vectorComponentField,\n vectorSize,\n type BooleanParameterField,\n type ChoiceParameterField,\n type ColorParameterField,\n type ImageParameterField,\n type NumberParameterField,\n type ParameterField,\n type ParameterKeyState,\n type ParameterValue,\n type TextParameterField,\n type VectorParameterField,\n} from '@pixerate/editor/parameters';\n\n/** Props every field control takes. Controls are controller-free: wire them to anything. */\nexport interface ParameterControlProps<F extends ParameterField, V extends ParameterValue> {\n field: F;\n value: V;\n onChange: (value: V) => void;\n /** A continuous edit (slider drag, colour pick) started: merge changes into one undo step. */\n onGestureStart?: () => void;\n onGestureEnd?: () => void;\n disabled?: boolean;\n /** DOM id of the main input (for a `<label htmlFor>`). */\n id?: string;\n}\n\nexport const parameterInputClass =\n 'h-7 w-full min-w-0 rounded-md border border-input bg-background px-2 text-xs text-foreground tabular-nums focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:cursor-not-allowed disabled:opacity-50';\nexport const parameterButtonClass =\n 'inline-flex h-7 items-center justify-center gap-1 rounded-md border border-input bg-background px-2 text-xs text-foreground hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-50';\nconst rangeClass = 'h-4 w-full min-w-0 flex-1 cursor-pointer accent-primary disabled:cursor-not-allowed disabled:opacity-50';\n\ntype CommitInputProps = {\n value: string;\n /** Called with the text and the element (e.g. to show the stored value again after a refused edit). */\n onCommit: (value: string, input: HTMLInputElement | HTMLTextAreaElement) => void;\n multiline?: boolean;\n} & Omit<React.InputHTMLAttributes<HTMLInputElement> & React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'value' | 'onChange' | 'defaultValue'>;\n\n/** A text box that commits on blur or Enter (Mod+Enter when multiline) and resets on Escape. */\nexport function ParameterCommitInput({ value, onCommit, multiline, className, onKeyDown, ...rest }: CommitInputProps) {\n const commit = (el: HTMLInputElement | HTMLTextAreaElement) => {\n if (el.value !== value) onCommit(el.value, el);\n };\n const keyDown = (e: React.KeyboardEvent<HTMLInputElement & HTMLTextAreaElement>) => {\n onKeyDown?.(e);\n if (e.defaultPrevented) return;\n if (e.key === 'Enter' && (!multiline || e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n commit(e.currentTarget);\n }\n if (e.key === 'Escape') e.currentTarget.value = value;\n };\n const props = {\n defaultValue: value,\n className: className ?? parameterInputClass,\n onBlur: (e: React.FocusEvent<HTMLInputElement & HTMLTextAreaElement>) => commit(e.currentTarget),\n onKeyDown: keyDown,\n ...rest,\n };\n // `key` remounts the box when the value changes from outside.\n return multiline ? (\n <textarea key={value} {...props} className={`${props.className} h-auto min-h-[3.5rem] py-1`} />\n ) : (\n <input key={value} type=\"text\" {...props} />\n );\n}\n\nconst plainNumber = (field: NumberParameterField, value: number) => formatParameterNumber({ ...field, unit: undefined }, value);\n\n/** A number box: type a value (units allowed), or step with the arrow keys (Shift ×10). */\nexport function ParameterNumberInput({\n field,\n value,\n onChange,\n disabled,\n id,\n 'aria-label': ariaLabel,\n}: ParameterControlProps<NumberParameterField, number> & { 'aria-label'?: string }) {\n return (\n <div className=\"relative min-w-0 flex-1\">\n <ParameterCommitInput\n id={id}\n inputMode=\"decimal\"\n aria-label={ariaLabel ?? parameterLabel(field)}\n value={plainNumber(field, value)}\n disabled={disabled || field.readOnly}\n className={`${parameterInputClass} ${field.unit ? 'pr-6' : ''}`}\n onCommit={(text, input) => {\n const n = parseParameterNumberInput(field, text);\n // Show the stored value again when the text was not a number or clamps to it.\n if (n === null || n === value) input.value = plainNumber(field, value);\n else onChange(n);\n }}\n onKeyDown={(e) => {\n if (e.key !== 'ArrowUp' && e.key !== 'ArrowDown') return;\n e.preventDefault();\n const step = parameterStep(field) * (e.shiftKey ? 10 : 1);\n onChange(clampParameterNumber(field, value + (e.key === 'ArrowUp' ? step : -step)));\n }}\n />\n {field.unit && (\n <span className=\"pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 text-[10px] text-muted-foreground\">{field.unit}</span>\n )}\n </div>\n );\n}\n\n/** A slider plus number box for `number` / `int` fields (number box only for `control: 'input'` or unbounded fields). */\nexport function ParameterSlider(props: ParameterControlProps<NumberParameterField, number>) {\n const { field, value, onChange, onGestureStart, onGestureEnd, disabled } = props;\n const dragging = useRef(false);\n const end = () => {\n if (!dragging.current) return;\n dragging.current = false;\n onGestureEnd?.();\n };\n if (!isSliderField(field)) return <ParameterNumberInput {...props} />;\n const step = parameterStep(field);\n return (\n <div className=\"flex items-center gap-2\">\n <input\n type=\"range\"\n aria-label={parameterLabel(field)}\n aria-valuetext={formatParameterNumber(field, value)}\n min={field.min}\n max={field.max}\n step={step}\n value={value}\n disabled={disabled || field.readOnly}\n className={rangeClass}\n onPointerDown={() => {\n if (dragging.current) return;\n dragging.current = true;\n onGestureStart?.();\n }}\n onPointerUp={end}\n onPointerCancel={end}\n onBlur={end}\n onChange={(e) => onChange(clampParameterNumber(field, Number(e.target.value)))}\n />\n <div className=\"w-20 shrink-0\">\n <ParameterNumberInput {...props} id={props.id} aria-label={`${parameterLabel(field)} value`} />\n </div>\n </div>\n );\n}\n\n/** An on/off switch for `boolean` fields. */\nexport function ParameterToggle({ field, value, onChange, disabled, id }: ParameterControlProps<BooleanParameterField, boolean>) {\n return (\n <button\n type=\"button\"\n role=\"switch\"\n id={id}\n aria-checked={value}\n aria-label={parameterLabel(field)}\n disabled={disabled || field.readOnly}\n onClick={() => onChange(!value)}\n className={`relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-transparent transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:opacity-50 ${\n value ? 'bg-primary' : 'bg-muted'\n }`}\n >\n <span\n className={`pointer-events-none block h-4 w-4 rounded-full bg-background shadow transition-transform ${value ? 'translate-x-4' : 'translate-x-0.5'}`}\n />\n </button>\n );\n}\n\n/** A dropdown (or segmented buttons with `control: 'segmented'`) for `choice` fields. */\nexport function ParameterSelect({ field, value, onChange, disabled, id }: ParameterControlProps<ChoiceParameterField, string | number>) {\n const options = getChoiceOptions(field);\n const off = disabled || field.readOnly;\n if (field.control === 'segmented') {\n return (\n <div role=\"radiogroup\" aria-label={parameterLabel(field)} className=\"inline-flex flex-wrap rounded-md border border-input bg-muted p-0.5\">\n {options.map((o) => (\n <button\n key={String(o.value)}\n type=\"button\"\n role=\"radio\"\n aria-checked={o.value === value}\n title={o.description}\n disabled={off}\n onClick={() => onChange(o.value)}\n className={`rounded px-2 py-0.5 text-xs disabled:opacity-50 ${\n o.value === value ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'\n }`}\n >\n {choiceOptionLabel(o)}\n </button>\n ))}\n </div>\n );\n }\n const index = options.findIndex((o) => o.value === value);\n return (\n <select\n id={id}\n aria-label={parameterLabel(field)}\n value={String(index)}\n disabled={off}\n onChange={(e) => {\n const option = options[Number(e.target.value)];\n if (option) onChange(option.value);\n }}\n className={parameterInputClass}\n >\n {options.map((o, i) => (\n <option key={String(o.value)} value={String(i)} title={o.description}>\n {choiceOptionLabel(o)}\n </option>\n ))}\n </select>\n );\n}\n\n/** A colour picker with a hex box, an alpha slider (with `alpha`) and swatches. */\nexport function ParameterColor({ field, value, onChange, onGestureStart, onGestureEnd, disabled, id }: ParameterControlProps<ColorParameterField, string>) {\n const picking = useRef(false);\n const alpha = !!field.alpha;\n const hex = normalizeHexColor(value, true) ?? '#000000ff';\n const rgb = hex.slice(0, 7);\n const a = hex.slice(7);\n const off = disabled || field.readOnly;\n const start = () => {\n if (picking.current) return;\n picking.current = true;\n onGestureStart?.();\n };\n const end = () => {\n if (!picking.current) return;\n picking.current = false;\n onGestureEnd?.();\n };\n return (\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-2\">\n <span className=\"relative h-7 w-9 shrink-0 overflow-hidden rounded-md border border-input bg-[repeating-conic-gradient(#d4d4d8_0_25%,#fff_0_50%)] bg-[length:8px_8px]\">\n <span className=\"absolute inset-0\" style={{ background: alpha ? hex : rgb }} />\n <input\n type=\"color\"\n aria-label={parameterLabel(field)}\n value={rgb}\n disabled={off}\n className=\"absolute inset-0 h-full w-full cursor-pointer opacity-0 disabled:cursor-not-allowed\"\n onChange={(e) => {\n start();\n onChange(alpha ? `${e.target.value}${a}` : e.target.value);\n }}\n onBlur={end}\n />\n </span>\n <ParameterCommitInput\n id={id}\n aria-label={`${parameterLabel(field)} hex`}\n value={alpha ? hex : rgb}\n disabled={off}\n spellCheck={false}\n className={`${parameterInputClass} font-mono`}\n onCommit={(text) => {\n const next = normalizeHexColor(text, alpha);\n if (next) onChange(next);\n }}\n />\n </div>\n {alpha && (\n <input\n type=\"range\"\n aria-label={`${parameterLabel(field)} opacity`}\n min={0}\n max={255}\n step={1}\n value={parseInt(a, 16)}\n disabled={off}\n className={rangeClass}\n onPointerDown={start}\n onPointerUp={end}\n onPointerCancel={end}\n onBlur={end}\n onChange={(e) => onChange(`${rgb}${Number(e.target.value).toString(16).padStart(2, '0')}`)}\n />\n )}\n {field.swatches && field.swatches.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {field.swatches.map((s) => {\n const swatch = normalizeHexColor(s, alpha);\n if (!swatch) return null;\n return (\n <button\n key={s}\n type=\"button\"\n title={swatch}\n aria-label={`${parameterLabel(field)} ${swatch}`}\n aria-pressed={swatch === (alpha ? hex : rgb)}\n disabled={off}\n onClick={() => onChange(swatch)}\n className=\"h-5 w-5 rounded border border-input aria-pressed:ring-1 aria-pressed:ring-primary\"\n style={{ background: swatch }}\n />\n );\n })}\n </div>\n )}\n </div>\n );\n}\n\n/** One number box per component for `vector` fields. */\nexport function ParameterVector({ field, value, onChange, disabled, id }: ParameterControlProps<VectorParameterField, number[]>) {\n const size = vectorSize(field);\n return (\n <div className=\"grid gap-1.5\" style={{ gridTemplateColumns: `repeat(${size}, minmax(0, 1fr))` }}>\n {Array.from({ length: size }, (_, i) => {\n const component = vectorComponentField(field, i);\n return (\n <label key={i} className=\"flex min-w-0 items-center gap-1\">\n <span className=\"w-3 shrink-0 text-[10px] uppercase text-muted-foreground\">{component.label}</span>\n <ParameterNumberInput\n field={component}\n value={value[i] ?? 0}\n id={i === 0 ? id : undefined}\n aria-label={`${parameterLabel(field)} ${component.label}`}\n disabled={disabled || field.readOnly}\n onChange={(n) => onChange(Array.from({ length: size }, (_, j) => (j === i ? n : (value[j] ?? 0))))}\n />\n </label>\n );\n })}\n </div>\n );\n}\n\nexport interface ParameterImageProps extends ParameterControlProps<ImageParameterField, string> {\n /** Turns a picked file into a URL (upload it, or `URL.createObjectURL`). Without it there is no file button. */\n resolveFile?: (file: File) => string | Promise<string>;\n}\n\n/** An image picker: suggested thumbnails, a URL box, an optional file button and a clear button. */\nexport function ParameterImage({ field, value, onChange, disabled, id, resolveFile }: ParameterImageProps) {\n const off = disabled || field.readOnly;\n const name = parameterLabel(field);\n return (\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-2\">\n <div className=\"flex h-12 w-16 shrink-0 items-center justify-center overflow-hidden rounded-md border border-input bg-muted\">\n {value ? (\n <img src={value} alt={name} className=\"h-full w-full object-cover\" />\n ) : (\n <span className=\"text-[10px] text-muted-foreground\">None</span>\n )}\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n <ParameterCommitInput\n id={id}\n aria-label={`${name} URL`}\n placeholder=\"Image URL\"\n value={value.startsWith('data:') ? '' : value}\n disabled={off}\n onCommit={(text) => onChange(text.trim())}\n />\n <div className=\"flex gap-1\">\n {resolveFile && (\n <label className={`${parameterButtonClass} cursor-pointer ${off ? 'pointer-events-none opacity-50' : ''}`}>\n Choose file…\n <input\n type=\"file\"\n className=\"sr-only\"\n accept={field.accept ?? 'image/*'}\n disabled={off}\n aria-label={`${name} file`}\n onChange={async (e) => {\n const file = e.target.files?.[0];\n e.target.value = '';\n if (file) onChange(await resolveFile(file));\n }}\n />\n </label>\n )}\n {value && (\n <button type=\"button\" className={parameterButtonClass} disabled={off} onClick={() => onChange('')} aria-label={`Clear ${name}`}>\n Clear\n </button>\n )}\n </div>\n </div>\n </div>\n {field.options && field.options.length > 0 && (\n <div className=\"flex flex-wrap gap-1\">\n {field.options.map((o) => (\n <button\n key={o.url}\n type=\"button\"\n title={o.label ?? o.url}\n aria-label={o.label ?? o.url}\n aria-pressed={o.url === value}\n disabled={off}\n onClick={() => onChange(o.url)}\n className=\"h-9 w-12 overflow-hidden rounded border border-input aria-pressed:ring-2 aria-pressed:ring-primary\"\n >\n <img src={o.url} alt=\"\" className=\"h-full w-full object-cover\" />\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n/** A text box (or textarea with `multiline`) that commits on blur or Enter. */\nexport function ParameterText({ field, value, onChange, disabled, id }: ParameterControlProps<TextParameterField, string>) {\n return (\n <ParameterCommitInput\n id={id}\n aria-label={parameterLabel(field)}\n multiline={field.multiline}\n placeholder={field.placeholder}\n maxLength={field.maxLength}\n value={value}\n disabled={disabled || field.readOnly}\n onCommit={onChange}\n />\n );\n}\n\nexport interface KeyframeDiamondProps {\n state: ParameterKeyState;\n onToggle: () => void;\n /** The parameter's label (for the accessible name). */\n label: string;\n disabled?: boolean;\n className?: string;\n}\n\n/** A keyframe toggle: filled when a key sits at the playhead, tinted when the value is animated. */\nexport function KeyframeDiamond({ state, onToggle, label, disabled, className = '' }: KeyframeDiamondProps) {\n const keyed = state === 'keyed';\n return (\n <button\n type=\"button\"\n data-key-state={state}\n aria-pressed={keyed}\n aria-label={`${keyed ? 'Remove' : 'Add'} keyframe for ${label}`}\n title={keyed ? 'Remove keyframe here' : 'Add keyframe at the playhead'}\n disabled={disabled}\n onClick={onToggle}\n className={`inline-flex h-4 w-4 shrink-0 items-center justify-center rounded-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:opacity-40 ${\n state === 'none' ? 'text-muted-foreground hover:text-foreground' : 'text-amber-500'\n } ${className}`}\n >\n <svg viewBox=\"0 0 10 10\" className=\"h-2.5 w-2.5\" aria-hidden=\"true\">\n <path\n d=\"M5 0.8 9.2 5 5 9.2 0.8 5Z\"\n fill={keyed ? 'currentColor' : 'none'}\n stroke=\"currentColor\"\n strokeWidth=\"1.3\"\n opacity={state === 'animated' ? 0.7 : 1}\n />\n </svg>\n </button>\n );\n}\n\nexport interface ParameterFieldControlProps extends ParameterControlProps<ParameterField, ParameterValue> {\n resolveFile?: ParameterImageProps['resolveFile'];\n}\n\n/** The control for any field type. */\nexport function ParameterFieldControl({ field, value, onChange, resolveFile, ...rest }: ParameterFieldControlProps) {\n const set = onChange as (value: any) => void;\n switch (field.type) {\n case 'number':\n case 'int':\n return <ParameterSlider field={field} value={value as number} onChange={set} {...rest} />;\n case 'boolean':\n return <ParameterToggle field={field} value={value as boolean} onChange={set} {...rest} />;\n case 'choice':\n return <ParameterSelect field={field} value={value as string | number} onChange={set} {...rest} />;\n case 'color':\n return <ParameterColor field={field} value={value as string} onChange={set} {...rest} />;\n case 'vector':\n return <ParameterVector field={field} value={value as number[]} onChange={set} {...rest} />;\n case 'image':\n return <ParameterImage field={field} value={value as string} onChange={set} resolveFile={resolveFile} {...rest} />;\n case 'text':\n return <ParameterText field={field} value={value as string} onChange={set} {...rest} />;\n }\n}\n\n","import React, { useEffect, useState } from 'react';\nimport type { ImageEditorController } from '@pixerate/editor/image-editor';\nimport {\n BRUSH_OPTION_CONTROLS,\n MIXER_MIXING_OPTIONS,\n MIXER_OPTION_CONTROLS,\n PAINT_TOOLS,\n RETOUCH_CHOICES,\n RETOUCH_OPTION_CONTROLS,\n RETOUCH_TOGGLES,\n cloneSourceLabel,\n isRetouchPaintTool,\n rgbUnitToHex,\n setRetouchChoice,\n} from '@pixerate/editor/image-editor';\nimport { DEFAULT_PAINT_GRADIENT } from '@pixerate/editor/image-editor';\nimport { PaintGradientEditor } from './PaintGradientEditor';\nimport { ControlSlider } from './ControlSlider';\n\nexport interface BrushOptionsBarProps {\n controller: ImageEditorController;\n className?: string;\n}\n\nconst chip = (on: boolean) => `px-2 py-1 rounded text-[11px] ${on ? 'bg-indigo-600 text-white' : 'bg-slate-800 text-slate-300 hover:text-white'}`;\n\n/**\n * The paint tools: Move / Brush / Mixer / Eraser, the brush's size, hardness, opacity, flow and\n * smoothing, pressure toggles, the foreground and background colours (D resets, X swaps) and\n * Edit › Fill / Clear on the active layer, and gradient paint for the brush (the colour changes as\n * the stroke goes; `PaintGradientEditor`). With the Mixer Brush: its load (Load brush / Clean\n * brush), Wet / Load / Mix, load and clean each stroke, and the RGB / Pigment mixing toggle.\n * With a retouching tool: the clone source (Alt-click the canvas to set it), Sample, the Spot\n * Healing type, the tone Range, Exposure / Strength and the Aligned / Protect tones / Vibrance\n * toggles that tool uses.\n * Shortcuts are handled by `handlePaintShortcut` in the editor.\n */\nexport const BrushOptionsBar: React.FC<BrushOptionsBarProps> = ({ controller, className }) => {\n const [, setTick] = useState(0);\n useEffect(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);\n const [error, setError] = useState<string | null>(null);\n const state = controller.getState();\n const { brush, foreground, background, mixer, mixerLoad, retouch, cloneSource, paint } = state.paint;\n const tool = state.activeTool as (typeof PAINT_TOOLS)[number]['id'];\n const attempt = (fn: () => unknown) => {\n try {\n setError(null);\n fn();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n }\n };\n\n return (\n <div className={`flex flex-col gap-2 text-xs text-slate-200 ${className ?? ''}`} data-testid=\"brush-options\">\n <div className=\"flex flex-wrap gap-1\" role=\"toolbar\" aria-label=\"Paint tools\">\n {PAINT_TOOLS.map((t) => (\n <button\n key={t.id}\n type=\"button\"\n aria-pressed={state.activeTool === t.id}\n title={t.shortcut ? `${t.label} (${t.shortcut})` : t.label}\n className={chip(state.activeTool === t.id)}\n onClick={() => controller.setTool(t.id)}\n >\n {t.label}\n </button>\n ))}\n </div>\n\n <div className=\"flex items-center gap-2\" role=\"group\" aria-label=\"Colours\">\n <label className=\"flex items-center gap-1\">\n <input\n type=\"color\"\n aria-label=\"Foreground colour\"\n value={foreground}\n onChange={(e) => controller.setPaintOptions({ foreground: e.target.value })}\n className=\"h-6 w-8 rounded border border-slate-700 bg-transparent\"\n />\n <span className=\"text-slate-400\">FG</span>\n </label>\n <label className=\"flex items-center gap-1\">\n <input\n type=\"color\"\n aria-label=\"Background colour\"\n value={background}\n onChange={(e) => controller.setPaintOptions({ background: e.target.value })}\n className=\"h-6 w-8 rounded border border-slate-700 bg-transparent\"\n />\n <span className=\"text-slate-400\">BG</span>\n </label>\n <button type=\"button\" title=\"Swap colours (X)\" className={chip(false)} onClick={() => controller.swapPaintColors()}>\n Swap\n </button>\n <button type=\"button\" title=\"Default colours (D)\" className={chip(false)} onClick={() => controller.resetPaintColors()}>\n Default\n </button>\n {state.activeTool === 'brush' && (\n <button\n type=\"button\"\n aria-pressed={paint.type === 'gradient'}\n title=\"Gradient paint: the brush changes colour as the stroke goes\"\n className={chip(paint.type === 'gradient')}\n onClick={() => attempt(() => controller.setPaintOptions(paint.type === 'gradient' ? { foreground } : { paint: DEFAULT_PAINT_GRADIENT }))}\n >\n Gradient\n </button>\n )}\n </div>\n {state.activeTool === 'brush' && paint.type === 'gradient' && (\n <PaintGradientEditor value={paint} colors={{ paint: foreground, secondary: background }} onChange={(g) => attempt(() => controller.setPaintOptions({ paint: g }))} />\n )}\n\n {BRUSH_OPTION_CONTROLS.map((spec) => (\n <ControlSlider\n key={spec.id}\n spec={spec}\n value={brush[spec.id]}\n onChange={(v) => controller.setPaintOptions({ brush: { [spec.id]: v } })}\n />\n ))}\n\n {state.activeTool === 'mixer' && (\n <div className=\"flex flex-col gap-2 border-t border-slate-800 pt-2\" role=\"group\" aria-label=\"Mixer Brush\" data-testid=\"mixer-options\">\n <div className=\"flex items-center gap-2\">\n <span\n aria-label=\"Brush load\"\n title={mixerLoad.reservoir ? `Loaded ${rgbUnitToHex(mixerLoad.reservoir)}, ${Math.round(mixerLoad.amount * 100)}% left` : 'Unloaded'}\n className=\"h-6 w-6 rounded border border-slate-700\"\n style={{ background: mixerLoad.reservoir ? rgbUnitToHex(mixerLoad.reservoir) : 'transparent' }}\n />\n <button type=\"button\" title=\"Fill the reservoir with the foreground colour\" className={chip(false)} onClick={() => controller.loadMixerBrush()}>\n Load brush\n </button>\n <button type=\"button\" title=\"Empty the picked-up colour\" className={chip(false)} onClick={() => controller.cleanMixerBrush()}>\n Clean brush\n </button>\n </div>\n <div className=\"flex gap-1\" role=\"group\" aria-label=\"Mixing\">\n {MIXER_MIXING_OPTIONS.map((m) => (\n <button\n key={m.id}\n type=\"button\"\n aria-pressed={mixer.mixing === m.id}\n title={m.title}\n className={chip(mixer.mixing === m.id)}\n onClick={() => controller.setPaintOptions({ mixer: { mixing: m.id } })}\n >\n {m.label}\n </button>\n ))}\n </div>\n {MIXER_OPTION_CONTROLS.map((spec) => (\n <ControlSlider key={spec.id} spec={spec} value={mixer[spec.id]} onChange={(v) => controller.setPaintOptions({ mixer: { [spec.id]: v } })} />\n ))}\n <div className=\"flex flex-wrap gap-3 text-slate-300\">\n <label className=\"flex items-center gap-1.5\">\n <input\n type=\"checkbox\"\n aria-label=\"Load the brush after each stroke\"\n checked={mixer.loadEachStroke}\n onChange={(e) => controller.setPaintOptions({ mixer: { loadEachStroke: e.target.checked } })}\n className=\"accent-indigo-500\"\n />\n Load each stroke\n </label>\n <label className=\"flex items-center gap-1.5\">\n <input\n type=\"checkbox\"\n aria-label=\"Clean the brush after each stroke\"\n checked={mixer.cleanEachStroke}\n onChange={(e) => controller.setPaintOptions({ mixer: { cleanEachStroke: e.target.checked } })}\n className=\"accent-indigo-500\"\n />\n Clean each stroke\n </label>\n </div>\n </div>\n )}\n\n {isRetouchPaintTool(tool) && (\n <div className=\"flex flex-col gap-2 border-t border-slate-800 pt-2\" role=\"group\" aria-label=\"Retouch options\" data-testid=\"retouch-options\">\n {(tool === 'clone' || tool === 'heal') && (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-slate-400\" data-testid=\"clone-source\">\n {cloneSourceLabel(controller)}\n </span>\n {cloneSource && (\n <button type=\"button\" title=\"Forget the source point\" className={chip(false)} onClick={() => controller.setCloneSource(null)}>\n Clear source\n </button>\n )}\n </div>\n )}\n {RETOUCH_CHOICES.filter((c) => c.tools.includes(tool)).map((choice) => (\n <div key={choice.id} className=\"flex flex-wrap items-center gap-1\" role=\"group\" aria-label={choice.label}>\n <span className=\"text-slate-400\">{choice.label}</span>\n {choice.options.map((o) => (\n <button\n key={o.id}\n type=\"button\"\n aria-pressed={retouch[choice.id] === o.id}\n title={o.title}\n className={chip(retouch[choice.id] === o.id)}\n onClick={() => setRetouchChoice(controller, choice.id, o.id)}\n >\n {o.label}\n </button>\n ))}\n </div>\n ))}\n {RETOUCH_OPTION_CONTROLS.filter((c) => c.tools.includes(tool)).map((spec) => (\n <ControlSlider key={spec.id} spec={spec} value={retouch[spec.id]} onChange={(v) => controller.setPaintOptions({ retouch: { [spec.id]: v } })} />\n ))}\n <div className=\"flex flex-wrap gap-3 text-slate-300\">\n {RETOUCH_TOGGLES.filter((t) => t.tools.includes(tool)).map((t) => (\n <label key={t.id} className=\"flex items-center gap-1.5\">\n <input\n type=\"checkbox\"\n aria-label={t.label}\n checked={retouch[t.id]}\n onChange={(e) => controller.setPaintOptions({ retouch: { [t.id]: e.target.checked } })}\n className=\"accent-indigo-500\"\n />\n {t.label}\n </label>\n ))}\n </div>\n </div>\n )}\n\n <div className=\"flex flex-wrap gap-3 text-slate-300\" role=\"group\" aria-label=\"Pressure\">\n <label className=\"flex items-center gap-1.5\">\n <input\n type=\"checkbox\"\n aria-label=\"Pressure controls size\"\n checked={brush.pressureSize}\n onChange={(e) => controller.setPaintOptions({ brush: { pressureSize: e.target.checked } })}\n className=\"accent-indigo-500\"\n />\n Pressure size\n </label>\n <label className=\"flex items-center gap-1.5\">\n <input\n type=\"checkbox\"\n aria-label=\"Pressure controls opacity\"\n checked={brush.pressureOpacity}\n onChange={(e) => controller.setPaintOptions({ brush: { pressureOpacity: e.target.checked } })}\n className=\"accent-indigo-500\"\n />\n Pressure opacity\n </label>\n </div>\n\n <div className=\"flex gap-1\">\n <button type=\"button\" className={chip(false)} onClick={() => attempt(() => controller.fillPixels())}>\n Fill\n </button>\n <button type=\"button\" className={chip(false)} onClick={() => attempt(() => controller.clearPixels())}>\n Clear\n </button>\n </div>\n {error && (\n <p role=\"alert\" className=\"text-rose-400\">\n {error}\n </p>\n )}\n </div>\n );\n};\n","import React from 'react';\nimport { PAINT_GRADIENT_KIT } from '@pixerate/editor/image-editor';\nimport { PaintGradientEditorView, type PaintGradientEditorProps } from '../paint-editor/PaintGradientEditorView';\n\nexport type { PaintGradientEditorProps } from '../paint-editor/PaintGradientEditorView';\n\n/** The gradient paint editor for the image editor's brush (see `PaintGradientEditorView`). */\nexport const PaintGradientEditor: React.FC<PaintGradientEditorProps> = (props) => <PaintGradientEditorView {...props} kit={PAINT_GRADIENT_KIT} />;\n","import React, { useState } from 'react';\nimport type { PaintGradientKit, PaintGradientMappingKind, PaintGradientRepeat, PaintGradientSource, PaintGradientSpace } from '@pixerate/editor/paint-editor';\n\nexport interface PaintGradientEditorProps {\n value: PaintGradientSource;\n onChange: (paint: PaintGradientSource) => void;\n /** What `paint` / `secondary` stops show as (the editor's two colours). */\n colors: { paint: string; secondary: string };\n className?: string;\n}\n\nexport interface PaintGradientEditorViewProps extends PaintGradientEditorProps {\n /** The gradient helpers (`PAINT_GRADIENT_KIT`, from the editor's own entry). */\n kit: PaintGradientKit;\n}\n\nconst button = 'px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-200 hover:bg-slate-700 disabled:opacity-40';\nconst select = 'rounded bg-slate-800 px-1 py-0.5 text-[11px]';\nconst number = 'w-16 rounded bg-slate-800 px-1 py-0.5 text-[11px]';\nconst pct = (v: number) => Math.round(v * 1000) / 10;\n\n/**\n * Gradient paint editor (the vector editor's stop ramp, for paint): click the ramp to add a stop,\n * pick a stop to edit its colour (or the paint / second colour), opacity, position and midpoint;\n * the mixing space, what moves the stroke along it (distance with length and repeat, pressure,\n * tilt, speed, direction, time, across the tip, random), softness, reverse, and starting presets.\n */\nexport const PaintGradientEditorView: React.FC<PaintGradientEditorViewProps> = ({ value, onChange, colors, className, kit }) => {\n const {\n PAINT_GRADIENT_MAPPINGS,\n PAINT_GRADIENT_MAPPING_LABELS,\n PAINT_GRADIENT_PRESETS,\n PAINT_GRADIENT_REPEATS,\n PAINT_GRADIENT_REPEAT_LABELS,\n PAINT_GRADIENT_SPACES,\n PAINT_GRADIENT_SPACE_LABELS,\n addPaintGradientStop,\n paintGradientMappingFor,\n paintSourceCss,\n removePaintGradientStop,\n reversePaintGradient,\n updatePaintGradientStop,\n } = kit;\n const [selected, setSelected] = useState(0);\n const sel = Math.min(selected, value.stops.length - 1);\n const stop = value.stops[sel];\n const map = value.map;\n const stopHex = (c: string) => (c === 'paint' ? colors.paint : c === 'secondary' ? colors.secondary : c);\n const patchStop = (patch: Parameters<PaintGradientKit['updatePaintGradientStop']>[2]) => {\n const r = updatePaintGradientStop(value, sel, patch);\n setSelected(r.index);\n onChange(r.paint);\n };\n return (\n <div className={`flex flex-col gap-1.5 text-xs text-slate-200 ${className ?? ''}`} data-testid=\"paint-gradient-editor\" aria-label=\"Gradient paint\">\n <div className=\"flex items-center gap-1\">\n <select aria-label=\"Gradient preset\" className={select} value=\"\" onChange={(e) => e.target.value && (setSelected(0), onChange(PAINT_GRADIENT_PRESETS[Number(e.target.value)].paint))}>\n <option value=\"\">Presets…</option>\n {PAINT_GRADIENT_PRESETS.map((p, i) => (\n <option key={p.name} value={i}>\n {p.name}\n </option>\n ))}\n </select>\n <button type=\"button\" className={button} onClick={() => onChange(reversePaintGradient(value))}>\n Reverse\n </button>\n </div>\n <div\n role=\"slider\"\n tabIndex={0}\n aria-label=\"Gradient ramp: click to add a stop\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={pct(stop.offset)}\n data-testid=\"paint-gradient-ramp\"\n className=\"relative h-6 cursor-copy rounded ring-1 ring-slate-700\"\n style={{ background: paintSourceCss(value, colors) }}\n onClick={(e) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const r = addPaintGradientStop(value, rect.width ? (e.clientX - rect.left) / rect.width : 0.5, colors);\n if (r.index >= 0) {\n setSelected(r.index);\n onChange(r.paint);\n }\n }}\n />\n <div className=\"relative h-4\" aria-label=\"Stops\">\n {value.stops.map((s, i) => (\n <button\n key={i}\n type=\"button\"\n aria-label={`Stop ${i + 1} at ${pct(s.offset)}%`}\n aria-pressed={i === sel}\n className={`absolute top-0 h-4 w-3 -translate-x-1/2 rounded-sm ring-1 ${i === sel ? 'ring-white' : 'ring-slate-600'}`}\n style={{ left: `${s.offset * 100}%`, background: stopHex(s.color) }}\n onClick={() => setSelected(i)}\n />\n ))}\n </div>\n <div className=\"flex flex-wrap items-center gap-1\" data-testid=\"paint-gradient-stop\">\n <select aria-label=\"Stop colour source\" className={select} value={stop.color === 'paint' || stop.color === 'secondary' ? stop.color : 'color'} onChange={(e) => patchStop({ color: e.target.value === 'color' ? stopHex(stop.color) : e.target.value })}>\n <option value=\"color\">Colour</option>\n <option value=\"paint\">Paint colour</option>\n <option value=\"secondary\">Second colour</option>\n </select>\n {stop.color !== 'paint' && stop.color !== 'secondary' && <input type=\"color\" aria-label=\"Stop colour\" value={stop.color} onChange={(e) => patchStop({ color: e.target.value })} className=\"h-6 w-8 rounded bg-transparent\" />}\n <label className=\"flex items-center gap-1\">\n At\n <input type=\"number\" aria-label=\"Stop position\" min={0} max={100} step={1} value={pct(stop.offset)} onChange={(e) => patchStop({ offset: Number(e.target.value) / 100 })} className={number} />%\n </label>\n <label className=\"flex items-center gap-1\">\n Opacity\n <input type=\"number\" aria-label=\"Stop opacity\" min={0} max={100} step={5} value={pct(stop.opacity ?? 1)} onChange={(e) => patchStop({ opacity: Number(e.target.value) / 100 })} className={number} />%\n </label>\n {sel < value.stops.length - 1 && (\n <label className=\"flex items-center gap-1\">\n Midpoint\n <input type=\"number\" aria-label=\"Stop midpoint\" min={5} max={95} step={1} value={pct(stop.midpoint ?? 0.5)} onChange={(e) => patchStop({ midpoint: Number(e.target.value) / 100 })} className={number} />%\n </label>\n )}\n <button type=\"button\" className={button} disabled={value.stops.length <= 2} onClick={() => (setSelected(Math.max(0, sel - 1)), onChange(removePaintGradientStop(value, sel)))}>\n Remove stop\n </button>\n </div>\n <div className=\"flex flex-wrap items-center gap-1\" data-testid=\"paint-gradient-mapping\">\n <select aria-label=\"Gradient follows\" className={select} value={map.by} onChange={(e) => onChange({ ...value, map: paintGradientMappingFor(e.target.value as PaintGradientMappingKind, map) })}>\n {PAINT_GRADIENT_MAPPINGS.map((m) => (\n <option key={m} value={m}>\n {PAINT_GRADIENT_MAPPING_LABELS[m]}\n </option>\n ))}\n </select>\n {map.by === 'distance' && (\n <>\n <input type=\"number\" aria-label=\"Gradient length\" min={1} max={100000} value={map.length} onChange={(e) => onChange({ ...value, map: { ...map, length: Math.max(1, Number(e.target.value) || 1) } })} className={number} />\n <select aria-label=\"Gradient length unit\" className={select} value={map.unit ?? 'px'} onChange={(e) => onChange({ ...value, map: { ...map, unit: e.target.value as 'px' | 'dabs' } })}>\n <option value=\"px\">px</option>\n <option value=\"dabs\">dabs</option>\n </select>\n </>\n )}\n {map.by === 'time' && <input type=\"number\" aria-label=\"Gradient duration\" min={1} max={600000} value={map.duration} onChange={(e) => onChange({ ...value, map: { ...map, duration: Math.max(1, Number(e.target.value) || 1) } })} className={number} />}\n {map.by === 'random' && <input type=\"number\" aria-label=\"Dabs per pick\" min={1} max={500} value={map.every ?? 1} onChange={(e) => onChange({ ...value, map: { ...map, every: Math.max(1, Math.round(Number(e.target.value) || 1)) } })} className={number} />}\n {(map.by === 'distance' || map.by === 'time') && (\n <select aria-label=\"Gradient repeat\" className={select} value={map.repeat ?? 'clamp'} onChange={(e) => onChange({ ...value, map: { ...map, repeat: e.target.value as PaintGradientRepeat } })}>\n {PAINT_GRADIENT_REPEATS.map((r) => (\n <option key={r} value={r}>\n {PAINT_GRADIENT_REPEAT_LABELS[r]}\n </option>\n ))}\n </select>\n )}\n </div>\n <div className=\"flex items-center gap-1\">\n <select aria-label=\"Gradient mixing\" className={select} value={value.space} onChange={(e) => onChange({ ...value, space: e.target.value as PaintGradientSpace })}>\n {PAINT_GRADIENT_SPACES.map((s) => (\n <option key={s} value={s}>\n {PAINT_GRADIENT_SPACE_LABELS[s]}\n </option>\n ))}\n </select>\n <label className=\"flex flex-1 items-center gap-1\">\n Softness\n <input type=\"range\" aria-label=\"Gradient softness\" min={0} max={1} step={0.05} value={value.softness ?? 1} onChange={(e) => onChange({ ...value, softness: Number(e.target.value) })} className=\"flex-1 accent-indigo-500\" />\n </label>\n </div>\n </div>\n );\n};\n","import React, { useEffect, useState } from 'react';\nimport type { ImageEditorController, Intent } from '@pixerate/editor/image-editor';\nimport { COLOR_MODE_OPTIONS, INTENT_OPTIONS, PROOF_PROFILE_OPTIONS, WORKING_SPACE_OPTIONS, colorPanelView } from '@pixerate/editor/image-editor';\n\nexport interface ColorProfilePanelProps {\n controller: ImageEditorController;\n className?: string;\n}\n\nconst chip = 'px-2 py-1 rounded text-[11px] bg-slate-800 text-slate-300 hover:text-white';\nconst select = 'rounded bg-slate-800 px-1 py-0.5 text-[11px] text-slate-200';\n\n/**\n * Colour management: the document's profile (working space) with Assign Profile and Convert to\n * Profile (intent, black point compensation), Image › Mode (RGB, CMYK, Lab), and View › Proof\n * Setup (profile, intent, simulate paper, gamut warning).\n */\nexport const ColorProfilePanel: React.FC<ColorProfilePanelProps> = ({ controller, className }) => {\n const [, setTick] = useState(0);\n useEffect(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);\n const [target, setTarget] = useState<string>('display-p3');\n const [intent, setIntent] = useState<Intent>('relative');\n const [bpc, setBpc] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const view = colorPanelView(controller);\n const attempt = (fn: () => unknown) => {\n try {\n setError(null);\n fn();\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n }\n };\n const proofWith = (patch: Partial<{ id: string; intent: Intent; simulatePaper: boolean; gamutWarning: boolean }>) => {\n const cur = view.proof;\n const id = patch.id ?? cur?.id ?? 'coated-cmyk';\n attempt(() =>\n controller.setProofSetup({\n profile: id,\n intent: patch.intent ?? cur?.intent ?? 'relative',\n simulatePaper: patch.simulatePaper ?? cur?.simulatePaper ?? false,\n gamutWarning: patch.gamutWarning ?? cur?.gamutWarning ?? false,\n })\n );\n };\n\n return (\n <div className={`flex flex-col gap-2 text-xs text-slate-200 ${className ?? ''}`} data-testid=\"color-profile-panel\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-slate-400\">Profile</span>\n <span data-testid=\"color-profile-name\">{view.profileName}</span>\n </div>\n <div className=\"flex flex-wrap items-center gap-1\" role=\"group\" aria-label=\"Colour mode\">\n <span className=\"text-slate-400\">Mode</span>\n <select aria-label=\"Colour mode\" className={select} value={view.mode} onChange={(e) => attempt(() => controller.setColorMode(e.target.value as 'rgb' | 'cmyk' | 'lab'))}>\n {COLOR_MODE_OPTIONS.map((o) => (\n <option key={o.id} value={o.id} title={o.title}>\n {o.label}\n </option>\n ))}\n </select>\n {view.cmykProfileName && <span className=\"text-slate-400\">{view.cmykProfileName}</span>}\n </div>\n <div className=\"flex flex-wrap items-center gap-1\" role=\"group\" aria-label=\"Assign or convert\">\n <select aria-label=\"Target profile\" className={select} value={target} onChange={(e) => setTarget(e.target.value)}>\n {WORKING_SPACE_OPTIONS.map((o) => (\n <option key={o.id} value={o.id}>\n {o.label}\n </option>\n ))}\n </select>\n <select aria-label=\"Rendering intent\" className={select} value={intent} onChange={(e) => setIntent(e.target.value as Intent)}>\n {INTENT_OPTIONS.map((o) => (\n <option key={o.id} value={o.id} title={o.title}>\n {o.label}\n </option>\n ))}\n </select>\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" aria-label=\"Black point compensation\" checked={bpc} onChange={(e) => setBpc(e.target.checked)} className=\"accent-indigo-500\" />\n BPC\n </label>\n <button type=\"button\" className={chip} title=\"Edit › Assign Profile: keep the numbers\" onClick={() => attempt(() => controller.assignProfile(target))}>\n Assign\n </button>\n <button type=\"button\" className={chip} title=\"Edit › Convert to Profile: keep the look\" onClick={() => attempt(() => controller.convertToProfile(target, { intent, bpc }))}>\n Convert\n </button>\n </div>\n <div className=\"flex flex-wrap items-center gap-1\" role=\"group\" aria-label=\"Proof setup\">\n <span className=\"text-slate-400\">Proof</span>\n <select\n aria-label=\"Proof profile\"\n className={select}\n value={view.proof?.id ?? ''}\n onChange={(e) => (e.target.value ? proofWith({ id: e.target.value }) : attempt(() => controller.setProofSetup(null)))}\n >\n <option value=\"\">Off</option>\n {PROOF_PROFILE_OPTIONS.map((o) => (\n <option key={o.id} value={o.id}>\n {o.label}\n </option>\n ))}\n </select>\n {view.proof && (\n <>\n <select aria-label=\"Proof intent\" className={select} value={view.proof.intent} onChange={(e) => proofWith({ intent: e.target.value as Intent })}>\n {INTENT_OPTIONS.map((o) => (\n <option key={o.id} value={o.id}>\n {o.label}\n </option>\n ))}\n </select>\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" aria-label=\"Simulate paper colour\" checked={view.proof.simulatePaper} onChange={(e) => proofWith({ simulatePaper: e.target.checked })} className=\"accent-indigo-500\" />\n Paper\n </label>\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" aria-label=\"Gamut warning\" checked={view.proof.gamutWarning} onChange={(e) => proofWith({ gamutWarning: e.target.checked })} className=\"accent-indigo-500\" />\n Gamut warning\n </label>\n </>\n )}\n </div>\n {error && (\n <p role=\"alert\" className=\"text-rose-400\">\n {error}\n </p>\n )}\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport type { ImageEditorController, SelectionMask, SelectionModifyOp, SelectionToolOptions } from '@pixerate/editor/image-editor';\nimport {\n SELECTION_MODES,\n SELECTION_MODE_LABELS,\n SELECTION_TOOLS,\n describeSelection,\n} from '@pixerate/editor/image-editor';\n\nexport interface SelectionOptionsBarProps {\n controller: ImageEditorController;\n options: SelectionToolOptions;\n onOptionsChange: (next: SelectionToolOptions) => void;\n /** The current selection (pass `state.selection` so the bar re-renders with it). */\n selection?: SelectionMask | null;\n /** The current Quick Mask view flag (`state.quickMask`). */\n quickMask?: boolean;\n className?: string;\n}\n\nconst MODIFY_OPS: { op: SelectionModifyOp; label: string }[] = [\n { op: 'grow', label: 'Grow' },\n { op: 'shrink', label: 'Shrink' },\n { op: 'feather', label: 'Feather' },\n { op: 'border', label: 'Border' },\n { op: 'smooth', label: 'Smooth' },\n];\n\nconst btn = (on: boolean) =>\n `px-2 py-1 rounded-md border text-[11px] transition-colors ${\n on ? 'bg-indigo-600 border-indigo-500 text-white' : 'bg-slate-950 border-slate-800 text-slate-300 hover:text-white'\n }`;\n\n/**\n * Options bar of the selection tools: tool, mode (new / add / subtract / intersect), magic wand\n * tolerance and contiguous, anti-alias, sample merged, Select › All / Deselect / Inverse,\n * Modify (grow, shrink, feather, border, smooth) and the Quick Mask toggle.\n */\nexport const SelectionOptionsBar: React.FC<SelectionOptionsBarProps> = ({\n controller,\n options,\n onOptionsChange,\n selection,\n quickMask,\n className = '',\n}) => {\n const [radius, setRadius] = useState(2);\n const set = (patch: Partial<SelectionToolOptions>) => onOptionsChange({ ...options, ...patch });\n const sel = selection === undefined ? controller.getSelection() : selection;\n const qm = quickMask ?? Boolean(controller.getState().quickMask);\n return (\n <div data-testid=\"selection-options-bar\" className={`flex flex-col gap-3 text-xs ${className}`}>\n <div role=\"group\" aria-label=\"Selection tool\" className=\"flex flex-wrap gap-1\">\n {SELECTION_TOOLS.map((t) => (\n <button key={t.id} type=\"button\" aria-pressed={options.tool === t.id} className={btn(options.tool === t.id)} onClick={() => set({ tool: t.id })}>\n {t.label}\n </button>\n ))}\n </div>\n <div role=\"group\" aria-label=\"Selection mode\" className=\"flex flex-wrap gap-1\">\n {SELECTION_MODES.map((m) => (\n <button key={m} type=\"button\" aria-pressed={options.mode === m} className={btn(options.mode === m)} onClick={() => set({ mode: m })}>\n {SELECTION_MODE_LABELS[m]}\n </button>\n ))}\n </div>\n {options.tool === 'wand' && (\n <div className=\"flex flex-col gap-2\">\n <label className=\"flex flex-col gap-1\">\n <span className=\"flex justify-between text-slate-400\">\n <span>Tolerance</span>\n <span className=\"font-mono\">{options.tolerance}</span>\n </span>\n <input\n type=\"range\"\n min={0}\n max={255}\n step={1}\n aria-label=\"Tolerance\"\n value={options.tolerance}\n onChange={(e) => set({ tolerance: Number(e.target.value) })}\n className=\"w-full accent-indigo-500\"\n />\n </label>\n <label className=\"flex items-center gap-2 text-slate-300\">\n <input type=\"checkbox\" checked={options.contiguous} onChange={(e) => set({ contiguous: e.target.checked })} />\n Contiguous\n </label>\n <label className=\"flex items-center gap-2 text-slate-300\">\n <input type=\"checkbox\" checked={options.sampleMerged} onChange={(e) => set({ sampleMerged: e.target.checked })} />\n Sample adjusted image\n </label>\n <label className=\"flex items-center gap-2 text-slate-300\">\n Sample\n <select\n aria-label=\"Sample from\"\n value={options.sample ?? 'composite'}\n onChange={(e) => set({ sample: e.target.value as 'composite' | 'active-layer' })}\n className=\"bg-slate-800 border border-slate-700 rounded px-1 py-0.5\"\n >\n <option value=\"composite\">All layers</option>\n <option value=\"active-layer\">Active layer</option>\n </select>\n </label>\n </div>\n )}\n <label className=\"flex items-center gap-2 text-slate-300\">\n <input type=\"checkbox\" checked={options.antiAlias} onChange={(e) => set({ antiAlias: e.target.checked })} />\n Anti-alias\n </label>\n <div className=\"flex flex-wrap gap-1\">\n <button type=\"button\" className={btn(false)} onClick={() => controller.selectAll()}>\n Select All\n </button>\n <button type=\"button\" className={btn(false)} disabled={!sel} onClick={() => controller.deselect()}>\n Deselect\n </button>\n <button type=\"button\" className={btn(false)} onClick={() => controller.invertSelection()}>\n Inverse\n </button>\n <button type=\"button\" aria-pressed={qm} className={btn(qm)} onClick={() => controller.setQuickMask(!qm)}>\n Quick Mask\n </button>\n </div>\n <div className=\"flex flex-wrap items-center gap-1\">\n <label className=\"flex items-center gap-1 text-slate-400\">\n Radius\n <input\n type=\"number\"\n min={0}\n max={500}\n step={1}\n aria-label=\"Modify radius\"\n value={radius}\n onChange={(e) => setRadius(Math.max(0, Number(e.target.value) || 0))}\n className=\"w-14 bg-slate-950 border border-slate-800 rounded px-1 py-0.5 text-slate-200\"\n />\n </label>\n {MODIFY_OPS.map(({ op, label }) => (\n <button key={op} type=\"button\" className={btn(false)} disabled={!sel} onClick={() => controller.modifySelection(op, radius)}>\n {label}\n </button>\n ))}\n </div>\n <p data-testid=\"selection-status\" className=\"text-slate-400\">\n {describeSelection(sel)}\n </p>\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport type { AdjustmentKind, AdjustmentLayer, ImageEditorController, RefineEdgeParams, SelectionMask } from '@pixerate/editor/image-editor';\nimport {\n ADJUSTMENT_KINDS,\n REFINE_EDGE_CONTROLS,\n adjustmentKindLabel,\n layerMaskFromSelection,\n} from '@pixerate/editor/image-editor';\n\nexport interface RefineEdgePanelProps {\n controller: ImageEditorController;\n /** The current selection (`state.selection`), so the panel re-renders with it. */\n selection?: SelectionMask | null;\n /** The adjustment layers (`state.adjustments.layers`), for the mask actions. */\n layers?: AdjustmentLayer[];\n className?: string;\n}\n\nconst DEFAULT_PARAMS: Required<RefineEdgeParams> = { radius: 8, smartRadius: false, smooth: 0, feather: 0, contrast: 0, shiftEdge: 0 };\n\nconst button =\n 'px-2 py-1 rounded-md border border-slate-800 bg-slate-950 text-[11px] text-slate-200 hover:text-white disabled:opacity-40';\n\n/**\n * Refine Edge (snap the selection, e.g. a coarse AI mask, to the image's edges) and layer masks:\n * use the selection as an adjustment layer's mask, edit mask density and feather, load a mask\n * back as a selection.\n */\nexport const RefineEdgePanel: React.FC<RefineEdgePanelProps> = ({ controller, selection, layers, className = '' }) => {\n const [params, setParams] = useState<Required<RefineEdgeParams>>(DEFAULT_PARAMS);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [layerId, setLayerId] = useState('');\n const [newKind, setNewKind] = useState<AdjustmentKind>('hueSaturation');\n const sel = selection === undefined ? controller.getSelection() : selection;\n const list = layers ?? controller.getAdjustmentLayers();\n const target = list.find((l) => l.id === layerId) ?? list[list.length - 1];\n\n const refine = async () => {\n setBusy(true);\n setError(null);\n try {\n await controller.refineSelection(params);\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <div data-testid=\"refine-edge-panel\" className={`flex flex-col gap-3 text-xs ${className}`}>\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px]\">Refine Edge</span>\n {REFINE_EDGE_CONTROLS.map((c) => (\n <label key={c.id} className=\"flex flex-col gap-1\">\n <span className=\"flex justify-between text-slate-400\">\n <span>{c.label}</span>\n <span className=\"font-mono\">\n {params[c.id]}\n {c.unit}\n </span>\n </span>\n <input\n type=\"range\"\n min={c.min}\n max={c.max}\n step={c.step}\n aria-label={c.label}\n value={params[c.id]}\n onChange={(e) => setParams({ ...params, [c.id]: Number(e.target.value) })}\n className=\"w-full accent-indigo-500\"\n />\n </label>\n ))}\n <label className=\"flex items-center gap-2 text-slate-300\">\n <input type=\"checkbox\" checked={params.smartRadius} onChange={(e) => setParams({ ...params, smartRadius: e.target.checked })} />\n Smart Radius\n </label>\n <div className=\"flex gap-1\">\n <button type=\"button\" className={button} disabled={!sel || busy} onClick={refine}>\n Refine Edge\n </button>\n <button type=\"button\" className={button} onClick={() => setParams(DEFAULT_PARAMS)}>\n Reset\n </button>\n </div>\n {error && (\n <p role=\"alert\" className=\"text-rose-400\">\n {error}\n </p>\n )}\n\n <span className=\"font-semibold text-slate-200 uppercase tracking-wider text-[11px] mt-2\">Layer Mask</span>\n <div className=\"flex gap-1 items-center\">\n <select\n aria-label=\"New masked layer kind\"\n value={newKind}\n onChange={(e) => setNewKind(e.target.value as AdjustmentKind)}\n className=\"flex-1 bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200\"\n >\n {ADJUSTMENT_KINDS.map((k) => (\n <option key={k.kind} value={k.kind}>\n {k.label}\n </option>\n ))}\n </select>\n <button\n type=\"button\"\n className={button}\n disabled={!sel}\n onClick={() => sel && setLayerId(controller.addAdjustmentLayer({ kind: newKind, mask: layerMaskFromSelection(sel) }))}\n >\n New Masked Layer\n </button>\n </div>\n {list.length > 0 && target && (\n <div className=\"flex flex-col gap-2\">\n <select\n aria-label=\"Mask layer\"\n value={target.id}\n onChange={(e) => setLayerId(e.target.value)}\n className=\"bg-slate-950 border border-slate-800 rounded px-1 py-1 text-slate-200\"\n >\n {list.map((l) => (\n <option key={l.id} value={l.id}>\n {l.name || adjustmentKindLabel(l.kind)}\n {l.mask ? ' (masked)' : ''}\n </option>\n ))}\n </select>\n <div className=\"flex flex-wrap gap-1\">\n <button type=\"button\" className={button} disabled={!sel} onClick={() => controller.applySelectionAsLayerMask(target.id)}>\n Mask with Selection\n </button>\n <button type=\"button\" className={button} disabled={!target.mask} onClick={() => controller.selectionFromLayerMask(target.id)}>\n Load as Selection\n </button>\n <button type=\"button\" className={button} disabled={!target.mask} onClick={() => controller.setAdjustmentLayerMask(target.id, null)}>\n Remove Mask\n </button>\n </div>\n {target.mask && (\n <>\n <label className=\"flex flex-col gap-1\">\n <span className=\"flex justify-between text-slate-400\">\n <span>Density</span>\n <span className=\"font-mono\">{Math.round((target.mask.density ?? 1) * 100)}%</span>\n </span>\n <input\n type=\"range\"\n min={0}\n max={100}\n step={1}\n aria-label=\"Mask density\"\n value={Math.round((target.mask.density ?? 1) * 100)}\n onChange={(e) => controller.setAdjustmentLayerMaskProps(target.id, { density: Number(e.target.value) / 100 })}\n className=\"w-full accent-indigo-500\"\n />\n </label>\n <label className=\"flex flex-col gap-1\">\n <span className=\"flex justify-between text-slate-400\">\n <span>Mask Feather</span>\n <span className=\"font-mono\">{target.mask.feather ?? 0}px</span>\n </span>\n <input\n type=\"range\"\n min={0}\n max={50}\n step={0.5}\n aria-label=\"Mask feather\"\n value={target.mask.feather ?? 0}\n onChange={(e) => controller.setAdjustmentLayerMaskProps(target.id, { feather: Number(e.target.value) })}\n className=\"w-full accent-indigo-500\"\n />\n </label>\n </>\n )}\n </div>\n )}\n </div>\n );\n};\n","import React, { useEffect, useState } from 'react';\nimport type { FreeTransformField, FreeTransformTool, Interpolation, TransformAnchor, WarpBar } from '@pixerate/editor/image-editor';\nimport { FREE_TRANSFORM_FIELDS, FREE_TRANSFORM_MODE_OPTIONS, INTERPOLATIONS, TRANSFORM_ANCHORS, WARP_GRID_OPTIONS, WARP_STYLE_OPTIONS } from '@pixerate/editor/image-editor';\n\nexport interface FreeTransformOptionsBarProps {\n tool: FreeTransformTool;\n className?: string;\n}\n\nconst chip = (on: boolean) => `px-2 py-1 rounded text-[11px] ${on ? 'bg-indigo-600 text-white' : 'bg-slate-800 text-slate-300 hover:text-white'}`;\nconst round = (v: number, unit: string) => (unit === 'px' ? Math.round(v * 10) / 10 : Math.round(v * 100) / 100);\n\n/**\n * Free Transform's options bar (Photoshop's): the mode switch (Free, Rotate, Skew, Distort,\n * Perspective, Warp), the reference-point locator, X / Y of the reference point, W / H in percent\n * with the proportional chain, the angle and skews, the interpolation, and Commit (Enter) / Cancel\n * (Esc). In Warp mode the numbers give way to the warp style, bend, horizontal and vertical\n * distortion, orientation and grid. Typed values apply on Enter or when the field loses focus.\n */\nexport const FreeTransformOptionsBar: React.FC<FreeTransformOptionsBarProps> = ({ tool, className }) => {\n const [, setTick] = useState(0);\n useEffect(() => tool.subscribe(() => setTick((n) => n + 1)), [tool]);\n const bar = tool.bar();\n if (!tool.active || !bar) return null;\n const warp = tool.warpBar();\n const warpNumber = (key: 'bend' | 'horizontal' | 'vertical', raw: string) => {\n const v = Number(raw);\n if (raw.trim() !== '' && Number.isFinite(v) && v !== warp[key]) tool.setWarp({ [key]: Math.max(-100, Math.min(100, v)) } as Partial<WarpBar>);\n };\n const apply = (field: FreeTransformField, raw: string) => {\n const v = Number(raw);\n if (raw.trim() !== '' && Number.isFinite(v) && Math.abs(v - bar[field]) > 1e-9) tool.setField(field, v);\n };\n\n return (\n <div className={`flex flex-wrap items-center gap-2 text-xs text-slate-200 ${className ?? ''}`} data-testid=\"free-transform-options\" role=\"toolbar\" aria-label=\"Free Transform options\">\n <div className=\"flex gap-1\" role=\"group\" aria-label=\"Transform mode\">\n {FREE_TRANSFORM_MODE_OPTIONS.map((m) => (\n <button key={m.id} type=\"button\" title={m.title} aria-pressed={tool.mode === m.id} className={chip(tool.mode === m.id)} onClick={() => tool.setMode(m.id)}>\n {m.label}\n </button>\n ))}\n </div>\n <div className=\"grid grid-cols-3 gap-px\" role=\"group\" aria-label=\"Reference point\">\n {TRANSFORM_ANCHORS.map((a: TransformAnchor) => (\n <button key={a} type=\"button\" aria-label={`Reference point ${a}`} title={`Reference point: ${a}`} className=\"h-2.5 w-2.5 rounded-sm bg-slate-700 hover:bg-indigo-500\" onClick={() => tool.setReference(a)} />\n ))}\n </div>\n {tool.mode === 'warp' && (\n <div className=\"flex flex-wrap items-center gap-2\" role=\"group\" aria-label=\"Warp options\">\n <label className=\"flex items-center gap-1\">\n <span className=\"text-slate-400\">Warp</span>\n <select aria-label=\"Warp style\" value={warp.style} onChange={(e) => tool.setWarp({ style: e.target.value as WarpBar['style'] })} className=\"rounded border border-slate-700 bg-slate-900 px-1 py-0.5\">\n {WARP_STYLE_OPTIONS.map((o) => (\n <option key={o.id} value={o.id}>\n {o.label}\n </option>\n ))}\n </select>\n </label>\n {(['bend', 'horizontal', 'vertical'] as const).map((k) => (\n <label key={k} className=\"flex items-center gap-1\">\n <span className=\"text-slate-400\">{k === 'bend' ? 'Bend' : k === 'horizontal' ? 'H' : 'V'}</span>\n <input\n key={`${k}:${warp[k]}`}\n type=\"number\"\n aria-label={k === 'bend' ? 'Warp bend in percent' : `Warp ${k} distortion in percent`}\n defaultValue={warp[k]}\n min={-100}\n max={100}\n disabled={warp.style === 'custom'}\n className=\"w-14 rounded border border-slate-700 bg-slate-900 px-1 py-0.5 text-right disabled:opacity-40\"\n onBlur={(e) => warpNumber(k, e.currentTarget.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n e.stopPropagation();\n warpNumber(k, e.currentTarget.value);\n }\n }}\n />\n <span className=\"text-slate-500\">%</span>\n </label>\n ))}\n <button\n type=\"button\"\n title=\"Bend along the vertical axis\"\n aria-pressed={warp.orientation === 'vertical'}\n disabled={warp.style === 'custom'}\n className={chip(warp.orientation === 'vertical')}\n onClick={() => tool.setWarp({ orientation: warp.orientation === 'vertical' ? 'horizontal' : 'vertical' })}\n >\n Vertical\n </button>\n <label className=\"flex items-center gap-1\">\n <span className=\"text-slate-400\">Grid</span>\n <select\n aria-label=\"Warp grid\"\n value={WARP_GRID_OPTIONS.find((g) => g.columns === warp.columns && g.rows === warp.rows)?.id ?? '1x1'}\n onChange={(e) => {\n const g = WARP_GRID_OPTIONS.find((o) => o.id === e.target.value)!;\n tool.setWarp({ columns: g.columns, rows: g.rows });\n }}\n className=\"rounded border border-slate-700 bg-slate-900 px-1 py-0.5\"\n >\n {WARP_GRID_OPTIONS.map((g) => (\n <option key={g.id} value={g.id}>\n {g.label}\n </option>\n ))}\n </select>\n </label>\n </div>\n )}\n {tool.mode !== 'warp' && FREE_TRANSFORM_FIELDS.map((f) => (\n <label key={f.id} className=\"flex items-center gap-1\" title={f.title}>\n <span className=\"text-slate-400\">{f.label}</span>\n <input\n key={`${f.id}:${round(bar[f.id], f.unit)}`}\n type=\"number\"\n aria-label={f.title}\n defaultValue={round(bar[f.id], f.unit)}\n disabled={!bar.affine}\n step={f.unit === 'px' ? 1 : 0.1}\n className=\"w-16 rounded border border-slate-700 bg-slate-900 px-1 py-0.5 text-right disabled:opacity-40\"\n onBlur={(e) => apply(f.id, e.currentTarget.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n e.stopPropagation();\n apply(f.id, e.currentTarget.value);\n }\n }}\n />\n <span className=\"text-slate-500\">{f.unit}</span>\n {f.id === 'scaleX' && (\n <button\n type=\"button\"\n aria-label=\"Keep width and height proportional\"\n aria-pressed={tool.proportional}\n className={chip(tool.proportional)}\n onClick={() => {\n tool.proportional = !tool.proportional;\n setTick((n) => n + 1);\n }}\n >\n ⛓︎\n </button>\n )}\n </label>\n ))}\n <label className=\"flex items-center gap-1\">\n <span className=\"text-slate-400\">Interpolation</span>\n <select\n aria-label=\"Interpolation\"\n value={tool.interpolation}\n onChange={(e) => tool.setInterpolation(e.target.value as Interpolation)}\n className=\"rounded border border-slate-700 bg-slate-900 px-1 py-0.5\"\n >\n {INTERPOLATIONS.map((i) => (\n <option key={i} value={i}>\n {i[0].toUpperCase() + i.slice(1)}\n </option>\n ))}\n </select>\n </label>\n <button type=\"button\" title=\"Commit (Enter)\" className=\"px-2 py-1 rounded bg-emerald-600 text-white hover:bg-emerald-500\" onClick={() => tool.commit()}>\n Commit\n </button>\n <button type=\"button\" title=\"Cancel (Esc)\" className={chip(false)} onClick={() => tool.cancel()}>\n Cancel\n </button>\n {tool.error && (\n <span role=\"alert\" className=\"text-rose-400\">\n {tool.error}\n </span>\n )}\n </div>\n );\n};\n","import React, { useEffect, useState } from 'react';\nimport type { ImageEditorController, LiveShapeKind, ShapeToolOptions } from '@pixerate/editor/image-editor';\nimport { LIVE_SHAPE_KINDS, SHAPE_KIND_LABELS, applyShapeOptions } from '@pixerate/editor/image-editor';\n\nexport interface ShapeOptionsBarProps {\n controller: ImageEditorController;\n options: ShapeToolOptions;\n onChange: (options: ShapeToolOptions) => void;\n className?: string;\n}\n\nconst chip = (on: boolean) => `px-2 py-1 rounded text-[11px] ${on ? 'bg-indigo-600 text-white' : 'bg-slate-800 text-slate-300 hover:text-white'}`;\n\n/**\n * The shape tool's options: the kind to draw, fill and stroke (colour or none), stroke width and\n * the kind's own settings (corner radius, sides, points, line weight and arrowhead). Changes also\n * apply to the active shape layer, as one undo step each.\n */\nexport const ShapeOptionsBar: React.FC<ShapeOptionsBarProps> = ({ controller, options, onChange, className }) => {\n const [, setTick] = useState(0);\n useEffect(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);\n const [error, setError] = useState<string | null>(null);\n const active = controller.getActiveLayer();\n const shapeId = active?.type === 'shape' ? active.id : null;\n const set = (change: Partial<ShapeToolOptions>) => {\n onChange({ ...options, ...change });\n if (!shapeId) return;\n try {\n setError(null);\n applyShapeOptions(controller, shapeId, change);\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n };\n const num = (v: string, min: number, max: number) => Math.max(min, Math.min(max, Number(v) || min));\n\n return (\n <div className={`flex flex-col gap-2 text-xs text-slate-200 ${className ?? ''}`} data-testid=\"shape-options\">\n <div className=\"flex flex-wrap gap-1\" role=\"toolbar\" aria-label=\"Shape kind\">\n {LIVE_SHAPE_KINDS.map((k: LiveShapeKind) => (\n <button key={k} type=\"button\" aria-pressed={options.kind === k} className={chip(options.kind === k)} onClick={() => onChange({ ...options, kind: k })}>\n {SHAPE_KIND_LABELS[k]}\n </button>\n ))}\n </div>\n <div className=\"flex flex-wrap items-center gap-3\">\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" aria-label=\"Fill\" checked={options.fill !== null} onChange={(e) => set({ fill: e.target.checked ? '#4f46e5' : null })} />\n Fill\n <input\n type=\"color\"\n aria-label=\"Fill colour\"\n disabled={options.fill === null}\n value={options.fill ?? '#4f46e5'}\n onChange={(e) => set({ fill: e.target.value })}\n className=\"h-6 w-8 rounded border border-slate-700 bg-transparent\"\n />\n </label>\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" aria-label=\"Stroke\" checked={options.stroke !== null} onChange={(e) => set({ stroke: e.target.checked ? '#000000' : null })} />\n Stroke\n <input\n type=\"color\"\n aria-label=\"Stroke colour\"\n disabled={options.stroke === null}\n value={options.stroke ?? '#000000'}\n onChange={(e) => set({ stroke: e.target.value })}\n className=\"h-6 w-8 rounded border border-slate-700 bg-transparent\"\n />\n </label>\n <label className=\"flex items-center gap-1\">\n Width\n <input\n type=\"number\"\n aria-label=\"Stroke width\"\n min={0}\n max={200}\n value={options.strokeWidth}\n onChange={(e) => set({ strokeWidth: num(e.target.value, 0, 200) })}\n className=\"w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5\"\n />\n </label>\n </div>\n <div className=\"flex flex-wrap items-center gap-3\">\n {options.kind === 'rect' && (\n <label className=\"flex items-center gap-1\">\n Radius\n <input type=\"number\" aria-label=\"Corner radius\" min={0} max={1000} value={options.radius} onChange={(e) => set({ radius: num(e.target.value, 0, 1000) })} className=\"w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5\" />\n </label>\n )}\n {options.kind === 'polygon' && (\n <label className=\"flex items-center gap-1\">\n Sides\n <input type=\"number\" aria-label=\"Sides\" min={3} max={100} value={options.sides} onChange={(e) => set({ sides: num(e.target.value, 3, 100) })} className=\"w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5\" />\n </label>\n )}\n {options.kind === 'star' && (\n <>\n <label className=\"flex items-center gap-1\">\n Points\n <input type=\"number\" aria-label=\"Points\" min={3} max={100} value={options.points} onChange={(e) => set({ points: num(e.target.value, 3, 100) })} className=\"w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5\" />\n </label>\n <label className=\"flex items-center gap-1\">\n Inner\n <input\n type=\"range\"\n aria-label=\"Inner radius\"\n min={0.05}\n max={1}\n step={0.05}\n value={options.innerRatio}\n onChange={(e) => set({ innerRatio: Number(e.target.value) })}\n className=\"accent-indigo-500\"\n />\n </label>\n </>\n )}\n {options.kind === 'line' && (\n <>\n <label className=\"flex items-center gap-1\">\n Weight\n <input type=\"number\" aria-label=\"Line weight\" min={1} max={200} value={options.weight} onChange={(e) => set({ weight: num(e.target.value, 1, 200) })} className=\"w-14 rounded border border-slate-700 bg-slate-950 px-1 py-0.5\" />\n </label>\n <label className=\"flex items-center gap-1\">\n <input type=\"checkbox\" aria-label=\"Arrowhead\" checked={options.arrow} onChange={(e) => set({ arrow: e.target.checked })} />\n Arrowhead\n </label>\n </>\n )}\n </div>\n <p className=\"text-[10px] text-slate-500\">Drag on the image to draw. Shift: square, circle or 45° line. Alt: from the centre.</p>\n {error && (\n <p role=\"alert\" className=\"text-rose-400\">\n {error}\n </p>\n )}\n </div>\n );\n};\n","import React, { useEffect, useState } from 'react';\nimport type { ImageEditorController, TextAlign, TextEditSession, TextStyle, TypeToolOptions } from '@pixerate/editor/image-editor';\nimport { TEXT_ALIGNS } from '@pixerate/editor/image-editor';\n\nexport interface TypeOptionsBarProps {\n controller: ImageEditorController;\n options: TypeToolOptions;\n onChange: (options: TypeToolOptions) => void;\n /** The text being edited on the canvas: changes style its selection (or all of it). */\n session?: TextEditSession | null;\n className?: string;\n}\n\nconst chip = (on: boolean) => `px-2 py-1 rounded text-[11px] ${on ? 'bg-indigo-600 text-white' : 'bg-slate-800 text-slate-300 hover:text-white'}`;\nconst ALIGN_LABELS: Record<TextAlign, string> = { left: 'Left', center: 'Centre', right: 'Right', justify: 'Justify' };\n\n/**\n * The type tool's options: font family (from the editor's fonts), size, bold, italic, colour and\n * alignment. While text is being edited they style the selection (or the whole text); with a\n * type layer active they style all of it; otherwise they set what the next text uses.\n */\nexport const TypeOptionsBar: React.FC<TypeOptionsBarProps> = ({ controller, options, onChange, session, className }) => {\n const [, setTick] = useState(0);\n useEffect(() => controller.subscribe(() => setTick((n) => n + 1)), [controller]);\n useEffect(() => session?.subscribe(() => setTick((n) => n + 1)), [session]);\n const [error, setError] = useState<string | null>(null);\n const active = controller.getActiveLayer();\n const typeId = !session && active?.type === 'type' ? active.id : null;\n const here: Partial<TextStyle> = session?.alive ? session.styleHere() : {};\n const shown: TypeToolOptions = {\n ...options,\n ...(here.fontFamily ? { fontFamily: here.fontFamily } : {}),\n ...(here.fontSize ? { fontSize: here.fontSize } : {}),\n ...(here.fontWeight ? { fontWeight: here.fontWeight } : {}),\n ...(session?.alive ? { italic: Boolean(here.italic), color: here.color ?? options.color } : {}),\n };\n const fonts = controller.listFonts();\n const missing = active?.type === 'type' ? active.missingFonts ?? [] : [];\n\n const style = (change: Partial<TypeToolOptions>) => {\n onChange({ ...options, ...change });\n const s: Record<string, unknown> = {};\n for (const k of ['fontFamily', 'fontSize', 'fontWeight', 'italic', 'color'] as const) if (k in change) s[k] = change[k];\n const p = change.align ? { align: change.align } : null;\n try {\n setError(null);\n if (session?.alive) {\n if (Object.keys(s).length) session.setStyle(s as Partial<TextStyle>);\n if (p) session.setParagraph(p);\n if (session.error) setError(session.error);\n } else if (typeId) {\n if (Object.keys(s).length) controller.setTextStyle(typeId, s);\n if (p) controller.setParagraphStyle(typeId, p);\n }\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n }\n };\n\n return (\n <div className={`flex flex-col gap-2 text-xs text-slate-200 ${className ?? ''}`} data-testid=\"type-options\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <label className=\"flex items-center gap-1\">\n Font\n <input\n list=\"pixerate-type-fonts\"\n aria-label=\"Font family\"\n value={shown.fontFamily}\n onChange={(e) => e.target.value.trim() && style({ fontFamily: e.target.value })}\n className=\"w-32 rounded border border-slate-700 bg-slate-950 px-1 py-0.5\"\n />\n <datalist id=\"pixerate-type-fonts\">\n {fonts.map((f) => (\n <option key={f} value={f} />\n ))}\n </datalist>\n </label>\n <label className=\"flex items-center gap-1\">\n Size\n <input\n type=\"number\"\n aria-label=\"Font size\"\n min={1}\n max={2000}\n value={Math.round(shown.fontSize * 10) / 10}\n onChange={(e) => Number(e.target.value) > 0 && style({ fontSize: Number(e.target.value) })}\n className=\"w-16 rounded border border-slate-700 bg-slate-950 px-1 py-0.5\"\n />\n </label>\n <button type=\"button\" aria-pressed={shown.fontWeight >= 600} className={`${chip(shown.fontWeight >= 600)} font-bold`} onClick={() => style({ fontWeight: shown.fontWeight >= 600 ? 400 : 700 })}>\n B\n </button>\n <button type=\"button\" aria-pressed={shown.italic} className={`${chip(shown.italic)} italic`} onClick={() => style({ italic: !shown.italic })}>\n I\n </button>\n <input type=\"color\" aria-label=\"Text colour\" value={shown.color} onChange={(e) => style({ color: e.target.value })} className=\"h-6 w-8 rounded border border-slate-700 bg-transparent\" />\n </div>\n <div className=\"flex gap-1\" role=\"toolbar\" aria-label=\"Alignment\">\n {TEXT_ALIGNS.map((a) => (\n <button key={a} type=\"button\" aria-pressed={options.align === a} className={chip(options.align === a)} onClick={() => style({ align: a })}>\n {ALIGN_LABELS[a]}\n </button>\n ))}\n </div>\n <p className=\"text-[10px] text-slate-500\">Click to type point text, drag for a paragraph box, click text to edit it. Esc finishes.</p>\n {missing.length > 0 && (\n <p role=\"status\" className=\"text-amber-400\" data-testid=\"type-missing-fonts\">\n Missing {missing.length === 1 ? 'font' : 'fonts'}: {missing.join(', ')}\n </p>\n )}\n {error && (\n <p role=\"alert\" className=\"text-rose-400\">\n {error}\n </p>\n )}\n </div>\n );\n};\n","import { useCallback, useMemo, useSyncExternalStore } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n getCommentStore,\n getTrackChangesStore,\n type CommentStore,\n type CommentStoreSnapshot,\n type TrackChangesSnapshot,\n type TrackedChange,\n} from \"@pixerate/editor\";\n\nconst EMPTY_COMMENTS: CommentStoreSnapshot = Object.freeze({\n threads: [],\n activeThreadId: null,\n}) as CommentStoreSnapshot;\n\nconst EMPTY_TRACK_CHANGES: TrackChangesSnapshot = Object.freeze({\n enabled: false,\n author: { id: \"anonymous\", name: \"Anonymous\" },\n changes: [],\n currentChangeId: null,\n}) as TrackChangesSnapshot;\n\nconst noopUnsubscribe = () => {};\n\nfunction isCommentStore(value: unknown): value is CommentStore {\n return (\n !!value &&\n typeof (value as CommentStore).getSnapshot === \"function\" &&\n typeof (value as CommentStore).createThread === \"function\"\n );\n}\n\nexport interface UseCommentsResult extends CommentStoreSnapshot {\n store: CommentStore | null;\n}\n\n/**\n * Subscribes to a comment store: pass the store itself, or an editor using\n * the `Comments` extension (`null` while the editor is being created).\n */\nexport function useComments(\n source: Editor | CommentStore | null | undefined,\n): UseCommentsResult {\n const store = isCommentStore(source) ? source : getCommentStore(source as Editor | null);\n const subscribe = useCallback(\n (onChange: () => void) => (store ? store.subscribe(() => onChange()) : noopUnsubscribe),\n [store],\n );\n const getSnapshot = () => store?.getSnapshot() ?? EMPTY_COMMENTS;\n const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n return useMemo(() => ({ ...snapshot, store }), [snapshot, store]);\n}\n\nexport interface UseTrackChangesResult extends TrackChangesSnapshot {\n currentChange: TrackedChange | null;\n setEnabled: (enabled: boolean) => void;\n toggle: () => void;\n accept: (id: string) => void;\n reject: (id: string) => void;\n acceptAll: () => void;\n rejectAll: () => void;\n next: () => void;\n previous: () => void;\n /** Selects a change in the editor. */\n select: (id: string) => void;\n /** Accepts a tracked move (both ends). */\n acceptMove: (id: string) => void;\n /** Rejects a tracked move (both ends). */\n rejectMove: (id: string) => void;\n}\n\n/**\n * Subscribes to the tracked-change state of an editor using the\n * `TrackChanges` extension and exposes its commands.\n */\nexport function useTrackChanges(editor: Editor | null | undefined): UseTrackChangesResult {\n const store = getTrackChangesStore(editor ?? null);\n const subscribe = useCallback(\n (onChange: () => void) => (store ? store.subscribe(() => onChange()) : noopUnsubscribe),\n [store],\n );\n const getSnapshot = () => store?.getSnapshot() ?? EMPTY_TRACK_CHANGES;\n const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n return useMemo(() => {\n const run = (fn: (e: Editor) => void) => () => {\n if (editor && !editor.isDestroyed) fn(editor);\n };\n return {\n ...snapshot,\n currentChange:\n snapshot.changes.find((c) => c.id === snapshot.currentChangeId) ?? null,\n setEnabled: (enabled: boolean) => run((e) => e.commands.setTrackChanges(enabled))(),\n toggle: run((e) => e.commands.toggleTrackChanges()),\n accept: (id: string) => run((e) => e.commands.acceptChange(id))(),\n reject: (id: string) => run((e) => e.commands.rejectChange(id))(),\n acceptAll: run((e) => e.commands.acceptAllChanges()),\n rejectAll: run((e) => e.commands.rejectAllChanges()),\n next: run((e) => e.chain().focus().selectNextChange().run()),\n previous: run((e) => e.chain().focus().selectPreviousChange().run()),\n select: (id: string) => run((e) => e.chain().focus().selectChange(id).run())(),\n acceptMove: (id: string) => run((e) => e.commands.acceptMove(id))(),\n rejectMove: (id: string) => run((e) => e.commands.rejectMove(id))(),\n };\n }, [snapshot, editor]);\n}\n","import React, { useState } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n formatReviewTime,\n getCommentAuthor,\n type CommentStore,\n type CommentThread,\n type ReviewAuthor,\n} from \"@pixerate/editor\";\nimport { useComments } from \"./useReview\";\n\nexport interface CommentsPanelProps {\n editor: Editor | null;\n /** Defaults to the store of the editor's `Comments` extension. */\n store?: CommentStore;\n /** Author of replies. Defaults to the `Comments` extension's author. */\n author?: ReviewAuthor;\n /** Initially show resolved threads. */\n showResolved?: boolean;\n className?: string;\n formatTime?: (timestamp: number) => string;\n emptyMessage?: string;\n}\n\nconst buttonClass =\n \"rounded px-2 py-1 text-xs text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-50\";\nconst primaryButtonClass =\n \"rounded px-2 py-1 text-xs bg-primary/10 text-primary hover:bg-primary/20 disabled:opacity-50\";\nconst textareaClass =\n \"w-full resize-y rounded-md border border-input bg-background p-2 text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-primary\";\n\n/**\n * Lists comment threads with reply, resolve and delete actions. Clicking a\n * thread selects its text in the editor. Threads with an empty body are\n * drafts (e.g. created by `CommentButton`) and show a compose box.\n */\nexport const CommentsPanel: React.FC<CommentsPanelProps> = ({\n editor,\n store: storeProp,\n author: authorProp,\n showResolved: showResolvedInitial = false,\n className = \"flex flex-col gap-2 text-sm text-foreground\",\n formatTime = (t) => formatReviewTime(t),\n emptyMessage = \"No comments yet. Select text and add a comment.\",\n}) => {\n const { threads, activeThreadId, store } = useComments(storeProp ?? editor);\n const [showResolved, setShowResolved] = useState(showResolvedInitial);\n const author = authorProp ?? getCommentAuthor(editor) ?? { id: \"anonymous\", name: \"Anonymous\" };\n\n const visible = threads.filter((t) => showResolved || !t.resolved);\n const resolvedCount = threads.filter((t) => t.resolved).length;\n\n return (\n <aside className={className} aria-label=\"Comments\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n {threads.length - resolvedCount} open\n {resolvedCount > 0 ? ` · ${resolvedCount} resolved` : \"\"}\n </span>\n {resolvedCount > 0 && (\n <button\n type=\"button\"\n className={buttonClass}\n aria-pressed={showResolved}\n onClick={() => setShowResolved((v) => !v)}\n >\n {showResolved ? \"Hide resolved\" : \"Show resolved\"}\n </button>\n )}\n </div>\n {visible.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">{emptyMessage}</p>\n ) : (\n <ul className=\"flex flex-col gap-2\" role=\"list\">\n {visible.map((thread) => (\n <CommentThreadCard\n key={thread.id}\n thread={thread}\n active={thread.id === activeThreadId}\n editor={editor}\n store={store}\n author={author}\n formatTime={formatTime}\n />\n ))}\n </ul>\n )}\n </aside>\n );\n};\n\ninterface CommentThreadCardProps {\n thread: CommentThread;\n active: boolean;\n editor: Editor | null;\n store: CommentStore | null;\n author: ReviewAuthor;\n formatTime: (timestamp: number) => string;\n}\n\nconst CommentThreadCard: React.FC<CommentThreadCardProps> = ({\n thread,\n active,\n editor,\n store,\n author,\n formatTime,\n}) => {\n const [draft, setDraft] = useState(\"\");\n const isDraft = thread.body === \"\";\n const quote = thread.anchor?.quote ?? thread.lastQuote ?? \"\";\n const live = editor && !editor.isDestroyed ? editor : null;\n\n const focus = () => {\n if (!active) {\n if (live && !thread.orphaned) live.commands.focusComment(thread.id);\n else store?.setActiveThread(thread.id);\n }\n };\n const remove = () => {\n if (live) live.commands.deleteComment(thread.id);\n else store?.deleteThread(thread.id);\n };\n const setResolved = (resolved: boolean) => {\n if (live) live.commands.resolveComment(thread.id, resolved);\n else store?.resolveThread(thread.id, resolved, author);\n };\n const submit = () => {\n const body = draft.trim();\n if (!body || !store) return;\n if (isDraft) store.editComment(thread.id, body);\n else store.addReply(thread.id, { body, author });\n setDraft(\"\");\n };\n const stop = (e: React.SyntheticEvent) => e.stopPropagation();\n\n return (\n <li\n className={`flex flex-col gap-2 rounded-md border bg-background p-3 cursor-pointer ${\n active ? \"border-primary ring-1 ring-primary\" : \"border-border\"\n } ${thread.resolved ? \"opacity-70\" : \"\"}`}\n data-thread-id={thread.id}\n data-active={active || undefined}\n aria-current={active || undefined}\n tabIndex={0}\n onClick={focus}\n onKeyDown={(e) => {\n if (e.target === e.currentTarget && (e.key === \"Enter\" || e.key === \" \")) {\n e.preventDefault();\n focus();\n }\n }}\n >\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"font-medium\">{thread.author.name}</span>\n <span className=\"text-xs text-muted-foreground\">{formatTime(thread.createdAt)}</span>\n </div>\n {quote && (\n <blockquote className=\"border-l-2 border-border pl-2 text-xs text-muted-foreground line-clamp-2\">\n {quote}\n </blockquote>\n )}\n {thread.orphaned && (\n <span className=\"text-xs text-destructive\">The commented text was deleted.</span>\n )}\n {thread.resolved && <span className=\"text-xs text-muted-foreground\">Resolved</span>}\n {!isDraft && <p className=\"whitespace-pre-wrap break-words\">{thread.body}</p>}\n {thread.replies.length > 0 && (\n <ul className=\"flex flex-col gap-2 border-l border-border pl-3\" role=\"list\">\n {thread.replies.map((reply) => (\n <li key={reply.id} className=\"flex flex-col gap-0.5\" data-reply-id={reply.id}>\n <span className=\"text-xs\">\n <span className=\"font-medium\">{reply.author.name}</span>{\" \"}\n <span className=\"text-muted-foreground\">{formatTime(reply.createdAt)}</span>\n </span>\n <p className=\"whitespace-pre-wrap break-words\">{reply.body}</p>\n </li>\n ))}\n </ul>\n )}\n {(active || isDraft) && !thread.resolved && (\n <div className=\"flex flex-col gap-1\" onClick={stop}>\n <textarea\n className={textareaClass}\n rows={2}\n value={draft}\n aria-label={isDraft ? \"Comment\" : \"Reply\"}\n placeholder={isDraft ? \"Add a comment…\" : \"Reply…\"}\n autoFocus={isDraft}\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n submit();\n }\n }}\n />\n <div className=\"flex justify-end gap-1\">\n {isDraft && (\n <button type=\"button\" className={buttonClass} onClick={remove}>\n Cancel\n </button>\n )}\n <button\n type=\"button\"\n className={primaryButtonClass}\n disabled={!draft.trim()}\n onClick={submit}\n >\n {isDraft ? \"Comment\" : \"Reply\"}\n </button>\n </div>\n </div>\n )}\n {!isDraft && (\n <div className=\"flex justify-end gap-1\" onClick={stop}>\n <button type=\"button\" className={buttonClass} onClick={() => setResolved(!thread.resolved)}>\n {thread.resolved ? \"Reopen\" : \"Resolve\"}\n </button>\n <button\n type=\"button\"\n className={`${buttonClass} hover:text-destructive`}\n onClick={remove}\n >\n Delete\n </button>\n </div>\n )}\n </li>\n );\n};\n","import React from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { useTrackChanges } from \"./useReview\";\n\nexport interface ReviewToolbarProps {\n editor: Editor | null;\n className?: string;\n /**\n * Show the current change's author and description (e.g. \"Alice: Formatted:\n * Bold\"). Defaults to `true`.\n */\n showDescription?: boolean;\n /** Class of the description label. */\n descriptionClassName?: string;\n}\n\nconst defaultDescriptionClass = \"max-w-[16rem] truncate px-1 text-xs text-muted-foreground\";\n\nconst buttonClass =\n \"rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent\";\n\n/**\n * Toolbar for tracked changes: toggle tracking, step through changes\n * (insertions, deletions, formatting and block changes, with a description\n * of the current one), and accept or reject the current change or all\n * changes.\n */\nexport const ReviewToolbar: React.FC<ReviewToolbarProps> = ({\n editor,\n className = \"flex flex-wrap items-center gap-1 rounded-md border border-border bg-background p-1 text-sm\",\n showDescription = true,\n descriptionClassName = defaultDescriptionClass,\n}) => {\n const review = useTrackChanges(editor);\n const count = review.changes.length;\n const current = review.currentChange;\n const index = current ? review.changes.findIndex((c) => c.id === current.id) + 1 : 0;\n\n return (\n <div className={className} role=\"toolbar\" aria-label=\"Review\">\n <button\n type=\"button\"\n className={`${buttonClass} ${review.enabled ? \"bg-primary/10 text-primary\" : \"\"}`}\n aria-pressed={review.enabled}\n disabled={!editor}\n onClick={review.toggle}\n >\n {review.enabled ? \"Tracking on\" : \"Track changes\"}\n </button>\n <span className=\"mx-1 h-4 w-px bg-border\" aria-hidden=\"true\" />\n <button\n type=\"button\"\n className={buttonClass}\n aria-label=\"Previous change\"\n disabled={count === 0}\n onClick={review.previous}\n >\n ‹\n </button>\n <span className=\"min-w-[4rem] text-center text-xs text-muted-foreground\" aria-live=\"polite\">\n {count === 0 ? \"No changes\" : current ? `${index} of ${count}` : `${count} changes`}\n </span>\n <button\n type=\"button\"\n className={buttonClass}\n aria-label=\"Next change\"\n disabled={count === 0}\n onClick={review.next}\n >\n ›\n </button>\n {showDescription && current && (\n <span\n className={descriptionClassName}\n data-change-type={current.type}\n title={`${current.author.name}: ${current.description}`}\n >\n {current.author.name ? `${current.author.name}: ` : \"\"}\n {current.description}\n </span>\n )}\n <span className=\"mx-1 h-4 w-px bg-border\" aria-hidden=\"true\" />\n <button\n type=\"button\"\n className={buttonClass}\n disabled={!current}\n onClick={() => current && review.accept(current.id)}\n >\n Accept\n </button>\n <button\n type=\"button\"\n className={buttonClass}\n disabled={!current}\n onClick={() => current && review.reject(current.id)}\n >\n Reject\n </button>\n <button type=\"button\" className={buttonClass} disabled={count === 0} onClick={review.acceptAll}>\n Accept all\n </button>\n <button type=\"button\" className={buttonClass} disabled={count === 0} onClick={review.rejectAll}>\n Reject all\n </button>\n </div>\n );\n};\n","import React from \"react\";\nimport type { Editor } from \"@tiptap/core\";\n\nexport interface CommentButtonProps {\n editor: Editor | null;\n className?: string;\n children?: React.ReactNode;\n}\n\n/**\n * Adds a draft comment on the selection; drop it into a `BubbleMenu`. The\n * draft is completed in `CommentsPanel`.\n */\nexport const CommentButton: React.FC<CommentButtonProps> = ({\n editor,\n className = \"rounded px-2 py-1 text-xs text-popover-foreground hover:bg-muted\",\n children = \"Comment\",\n}) => (\n <button\n type=\"button\"\n className={className}\n disabled={!editor}\n onClick={() => editor?.chain().focus().addComment().run()}\n >\n {children}\n </button>\n);\n","import { useCallback, useMemo, useRef, useState } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n applyDocumentComparison,\n type CompareSource,\n type CompareSummary,\n type EditorCompareOptions,\n} from \"@pixerate/editor\";\n\nexport type { CompareSource, CompareSummary, EditorCompareOptions } from \"@pixerate/editor\";\n\nexport interface UseDocumentCompareResult {\n /** Summary of the last comparison, or `null`. */\n summary: CompareSummary | null;\n /**\n * Replaces the editor content with the comparison of two versions (nodes,\n * JSON or HTML) as tracked changes, ready to review with `ReviewToolbar`.\n * Returns the summary, or `null` without an editor.\n */\n compare: (\n original: CompareSource,\n revised: CompareSource,\n options?: EditorCompareOptions,\n ) => CompareSummary | null;\n /** Forgets the last summary. */\n clear: () => void;\n}\n\n/**\n * Compare two document versions into an editor using `TrackChanges`.\n * `options` are defaults for every comparison.\n */\nexport function useDocumentCompare(\n editor: Editor | null | undefined,\n options?: EditorCompareOptions,\n): UseDocumentCompareResult {\n const [summary, setSummary] = useState<CompareSummary | null>(null);\n const defaults = useRef(options);\n defaults.current = options;\n const compare = useCallback(\n (original: CompareSource, revised: CompareSource, overrides?: EditorCompareOptions) => {\n if (!editor || editor.isDestroyed) return null;\n const result = applyDocumentComparison(editor, original, revised, {\n ...defaults.current,\n ...overrides,\n });\n setSummary(result.summary);\n return result.summary;\n },\n [editor],\n );\n const clear = useCallback(() => setSummary(null), []);\n return useMemo(() => ({ summary, compare, clear }), [summary, compare, clear]);\n}\n","import React from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { trackedChangeLabel } from \"@pixerate/editor\";\nimport { useTrackChanges } from \"./useReview\";\n\nexport interface TrackedChangesListProps {\n editor: Editor | null;\n className?: string;\n itemClassName?: string;\n activeItemClassName?: string;\n /** Content shown when there are no changes. */\n emptyState?: React.ReactNode;\n}\n\nconst buttonClass =\n \"rounded px-1.5 py-0.5 text-xs text-foreground hover:bg-muted disabled:opacity-40\";\n\n/**\n * Lists the document's tracked changes (insertions, deletions, moves,\n * formatting and block changes) with their author and description, and\n * accepts or rejects each one. A move is one entry: accepting or rejecting\n * it resolves both its source and its destination. Clicking an entry\n * selects the change in the editor.\n */\nexport const TrackedChangesList: React.FC<TrackedChangesListProps> = ({\n editor,\n className = \"flex flex-col gap-1 text-sm\",\n itemClassName = \"flex items-center gap-2 rounded px-2 py-1 hover:bg-muted/50\",\n activeItemClassName = \"bg-primary/10\",\n emptyState = \"No tracked changes.\",\n}) => {\n const review = useTrackChanges(editor);\n\n if (review.changes.length === 0) {\n return (\n <div className={className} data-tracked-changes-list=\"\">\n <div className=\"pixerate-changes-empty text-xs text-muted-foreground\">{emptyState}</div>\n </div>\n );\n }\n\n return (\n <ul className={className} role=\"list\" aria-label=\"Tracked changes\" data-tracked-changes-list=\"\">\n {review.changes.map((change) => {\n const active = change.id === review.currentChangeId;\n return (\n <li\n key={`${change.type}:${change.id}`}\n className={active ? `${itemClassName} ${activeItemClassName}` : itemClassName}\n data-change-type={change.type}\n data-change-id={change.id}\n >\n <button\n type=\"button\"\n className=\"min-w-0 flex-1 truncate text-left text-xs\"\n title={`${change.author.name}: ${change.description}`}\n onClick={() => review.select(change.id)}\n >\n <span className=\"font-medium\">{trackedChangeLabel(change)}</span>\n {change.author.name ? ` · ${change.author.name}` : \"\"}\n <span className=\"block truncate text-muted-foreground\">{change.description}</span>\n </button>\n <button type=\"button\" className={buttonClass} onClick={() => review.accept(change.id)}>\n Accept\n </button>\n <button type=\"button\" className={buttonClass} onClick={() => review.reject(change.id)}>\n Reject\n </button>\n </li>\n );\n })}\n </ul>\n );\n};\n","import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport {\n createCommandPaletteController,\n matchPaletteHotkey,\n type CommandPaletteController,\n type CommandPaletteOptions,\n type CommandPaletteState,\n type CommandRegistry,\n} from '@pixerate/editor/commands';\n\nexport interface UseCommandPaletteOptions<TContext = any> extends CommandPaletteOptions<TContext> {\n /** Chord that toggles the palette from anywhere, also while typing (e.g. `Mod+K`). */\n hotkey?: string;\n /** Element or window the hotkey listens on (default: `window`). */\n hotkeyTarget?: Window | HTMLElement | null;\n}\n\nexport interface UseCommandPaletteResult extends CommandPaletteState {\n controller: CommandPaletteController;\n setOpen: (open: boolean) => void;\n toggle: () => void;\n setQuery: (query: string) => void;\n setActiveIndex: (index: number) => void;\n move: (delta: number) => void;\n run: CommandPaletteController['run'];\n runActive: CommandPaletteController['runActive'];\n handleKeyDown: CommandPaletteController['handleKeyDown'];\n}\n\n/**\n * Command palette state over a `CommandRegistry` (ranked rows with shortcuts and\n * disabled reasons, active row, recents). Render it with `<CommandPalette palette={…} />`\n * or your own UI. Options are read live; the registry identity is the dependency.\n */\nexport function useCommandPalette<TContext = any>(\n registry: CommandRegistry<TContext>,\n options: UseCommandPaletteOptions<TContext> = {},\n): UseCommandPaletteResult {\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const controller = useMemo(\n () =>\n createCommandPaletteController(registry, {\n context: () => {\n const c = optionsRef.current.context;\n if (c === undefined) return registry.context;\n return (typeof c === 'function' ? (c as () => TContext)() : c) as TContext;\n },\n scope: () => {\n const s = optionsRef.current.scope;\n return typeof s === 'function' ? s() : s;\n },\n recents: options.recents,\n recentLimit: options.recentLimit,\n limit: options.limit,\n platform: options.platform,\n onRecentsChange: (recents) => optionsRef.current.onRecentsChange?.(recents),\n onRun: (result) => optionsRef.current.onRun?.(result),\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [registry],\n );\n\n const state = useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n\n const { hotkey, hotkeyTarget } = options;\n useEffect(() => {\n if (!hotkey) return;\n const target = hotkeyTarget ?? (typeof window !== 'undefined' ? window : null);\n if (!target) return;\n const onKeyDown = (event: Event) => {\n const e = event as KeyboardEvent;\n if (e.defaultPrevented || !matchPaletteHotkey(e, hotkey, optionsRef.current.platform)) return;\n e.preventDefault();\n controller.toggle();\n };\n target.addEventListener('keydown', onKeyDown);\n return () => target.removeEventListener('keydown', onKeyDown);\n }, [controller, hotkey, hotkeyTarget]);\n\n return {\n ...state,\n controller,\n setOpen: controller.setOpen,\n toggle: controller.toggle,\n setQuery: controller.setQuery,\n setActiveIndex: controller.setActiveIndex,\n move: controller.move,\n run: controller.run,\n runActive: controller.runActive,\n handleKeyDown: controller.handleKeyDown,\n };\n}\n","import React, { useEffect, useId, useRef } from 'react';\nimport type { CommandPaletteItem } from '@pixerate/editor/commands';\nimport type { UseCommandPaletteResult } from './useCommandPalette';\n\nexport interface CommandPaletteProps {\n /** State from `useCommandPalette`. */\n palette: UseCommandPaletteResult;\n placeholder?: string;\n emptyMessage?: string;\n /** Extra classes for the dialog panel. */\n className?: string;\n}\n\n/** Label with the fuzzy-matched characters emphasised. */\nfunction HighlightedLabel({ item }: { item: CommandPaletteItem }) {\n if (item.labelIndices.length === 0) return <>{item.label}</>;\n const marked = new Set(item.labelIndices);\n return (\n <>\n {Array.from(item.label).map((ch, i) =>\n marked.has(i) ? (\n <span key={i} className=\"font-semibold text-foreground\" data-match=\"\">\n {ch}\n </span>\n ) : (\n <React.Fragment key={i}>{ch}</React.Fragment>\n ),\n )}\n </>\n );\n}\n\n/**\n * Headless-styled command palette (Tailwind + theme tokens): a search box over the\n * registry's commands showing each command's group, shortcut and, for disabled\n * commands, the reason. Arrow keys move, Enter runs, Escape or a backdrop click closes.\n */\nexport const CommandPalette: React.FC<CommandPaletteProps> = ({\n palette,\n placeholder = 'Type a command…',\n emptyMessage = 'No matching commands',\n className = '',\n}) => {\n const inputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLUListElement>(null);\n const baseId = useId();\n const listId = `${baseId}-list`;\n const optionId = (index: number) => `${baseId}-option-${index}`;\n const { open, query, items, activeIndex } = palette;\n\n useEffect(() => {\n if (open) inputRef.current?.focus();\n }, [open]);\n\n useEffect(() => {\n if (!open) return;\n const active = listRef.current?.querySelector<HTMLElement>('[aria-selected=\"true\"]');\n active?.scrollIntoView?.({ block: 'nearest' });\n }, [open, activeIndex]);\n\n if (!open) return null;\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-start justify-center bg-black/30 px-4 pt-[15vh]\"\n data-command-palette-backdrop=\"\"\n onMouseDown={(e) => {\n if (e.target === e.currentTarget) palette.setOpen(false);\n }}\n >\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Command palette\"\n className={`w-full max-w-lg overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-xl ${className}`}\n style={{ background: 'var(--popover, var(--background, #fff))' }}\n >\n <input\n ref={inputRef}\n type=\"text\"\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={listId}\n aria-autocomplete=\"list\"\n aria-activedescendant={items.length ? optionId(activeIndex) : undefined}\n aria-label=\"Search commands\"\n placeholder={placeholder}\n value={query}\n onChange={(e) => palette.setQuery(e.target.value)}\n onKeyDown={(e) => {\n if (palette.handleKeyDown(e.nativeEvent)) e.stopPropagation();\n }}\n className=\"w-full border-b border-border bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground\"\n />\n {items.length === 0 ? (\n <div className=\"px-3 py-6 text-center text-sm text-muted-foreground\">{emptyMessage}</div>\n ) : (\n <ul ref={listRef} id={listId} role=\"listbox\" aria-label=\"Commands\" className=\"max-h-80 overflow-y-auto py-1\">\n {items.map((item, index) => (\n <li\n key={item.id}\n id={optionId(index)}\n role=\"option\"\n aria-selected={index === activeIndex}\n aria-disabled={!item.enabled || undefined}\n data-command-id={item.id}\n data-recent={item.recent ? '' : undefined}\n title={item.disabledReason}\n onMouseMove={() => index !== activeIndex && palette.setActiveIndex(index)}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => palette.run(item.id)}\n className={`flex cursor-pointer items-center gap-2 px-3 py-1.5 text-sm ${\n index === activeIndex ? 'bg-muted' : ''\n } ${item.enabled ? '' : 'cursor-default opacity-50'}`}\n >\n <span className=\"min-w-0 flex-1 truncate\">\n <HighlightedLabel item={item} />\n {item.disabledReason && (\n <span className=\"ml-2 text-xs text-muted-foreground\" data-disabled-reason=\"\">\n {item.disabledReason}\n </span>\n )}\n </span>\n {item.group && <span className=\"shrink-0 text-xs text-muted-foreground\">{item.group}</span>}\n {item.shortcut && (\n <kbd className=\"shrink-0 rounded border border-border px-1.5 font-mono text-[10px] text-muted-foreground\">\n {item.shortcut}\n </kbd>\n )}\n </li>\n ))}\n </ul>\n )}\n </div>\n </div>\n );\n};\n","import { useEffect, useRef } from 'react';\nimport type { CommandRegistry, CommandResult, CommandSpec } from '@pixerate/editor/commands';\n\nexport interface UseCommandShortcutsOptions<TContext = any> {\n /** Default `true`. */\n enabled?: boolean;\n /** Element or window to listen on (default: `window`). */\n target?: Window | HTMLElement | null;\n /** Active scopes, most specific first (e.g. `'canvas'` while the canvas has focus). */\n scopes?: string | readonly string[];\n /** Context for the commands (default: the registry's). */\n context?: TContext;\n /** Fire even while typing in inputs / contenteditable (default: per binding). */\n allowInEditable?: boolean;\n /** Called after a shortcut ran a command. */\n onRun?: (result: CommandResult) => void;\n}\n\n/**\n * Runs the registry's commands from their keyboard shortcuts (`registry.handleKeyDown`).\n * Typing in inputs and editors is never hijacked, and disabled commands leave the\n * event alone. Options are read live.\n */\nexport function useCommandShortcuts<TContext = any>(\n registry: CommandRegistry<TContext> | null | undefined,\n options: UseCommandShortcutsOptions<TContext> = {},\n): void {\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const { enabled = true, target } = options;\n\n useEffect(() => {\n if (!registry || !enabled) return;\n const eventTarget = target ?? (typeof window !== 'undefined' ? window : null);\n if (!eventTarget) return;\n const onKeyDown = (event: Event) => {\n const { scopes, context, allowInEditable, onRun } = optionsRef.current;\n const result = registry.handleKeyDown(event as KeyboardEvent, {\n scopes,\n ...(allowInEditable !== undefined ? { allowInEditable } : {}),\n ...(context !== undefined ? { context } : {}),\n });\n if (result) onRun?.(result);\n };\n eventTarget.addEventListener('keydown', onKeyDown);\n return () => eventTarget.removeEventListener('keydown', onKeyDown);\n }, [registry, enabled, target]);\n}\n\n/**\n * Registers commands while the component is mounted. Memoize `specs` (e.g. with\n * `useMemo(() => createHistoryCommands(manager), [manager])`): a new array re-registers.\n */\nexport function useRegisterCommands<TContext = any>(\n registry: CommandRegistry<TContext> | null | undefined,\n specs: readonly CommandSpec<TContext>[] | null | undefined,\n): void {\n useEffect(() => {\n if (!registry || !specs || specs.length === 0) return;\n return registry.register(specs);\n }, [registry, specs]);\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n createAutosaveController,\n createRevisionTracker,\n type AutosaveController,\n type AutosaveRecovery,\n type AutosaveStatusInfo,\n type DirtyFlagSource,\n type RevisionChangeSource,\n type RevisionTracker,\n type StorageAdapter,\n} from '@pixerate/editor/persistence';\n\nexport interface UseAutosaveOptions<T> {\n storage: StorageAdapter;\n /** Snapshot key (the meta lives at `<key>:meta`). */\n key: string;\n /** Reads the current document (the latest function is always used). */\n getSnapshot: () => T;\n serialize?: (snapshot: T) => string;\n deserialize?: (text: string) => T;\n /** Document name stored with the snapshot. */\n name?: string;\n /** Change notifications, e.g. a `HistoryManager`. */\n history?: RevisionChangeSource;\n /** Saved-vs-current flag, e.g. `useHistoryDirty().tracker` or a `bindDirtyToHistory` binding. */\n dirty?: DirtyFlagSource;\n interval?: number;\n debounceMs?: number;\n retryBaseMs?: number;\n retryMaxMs?: number;\n /**\n * Whether the document has finished loading (default `true`). Snapshots start\n * once this is true and any recovered snapshot was restored or discarded.\n */\n ready?: boolean;\n /** Look for an earlier session's snapshot on mount (default `true`). */\n recover?: boolean;\n /** Write pending changes on `pagehide` and when the tab is hidden (default `true`). */\n flushOnHide?: boolean;\n}\n\nexport interface UseAutosaveResult<T> {\n status: AutosaveStatusInfo;\n /** An earlier session's unsaved snapshot, until restored or discarded. */\n recovery: AutosaveRecovery<T> | null;\n /** True while the recovery check runs or a recovered snapshot awaits a decision. */\n pendingRecovery: boolean;\n /** Takes the recovered snapshot (apply it to the editor) and starts autosaving. */\n restore: () => T | undefined;\n /** Deletes the recovered snapshot and starts autosaving. */\n discard: () => Promise<void>;\n /** Writes pending changes now. */\n flushNow: () => Promise<void>;\n /** Call after an explicit save: marks the current revision saved and retires this session's snapshot. */\n markClean: () => Promise<void>;\n /** Records a change made outside `history`. */\n notifyChange: () => void;\n controller: AutosaveController<T> | null;\n}\n\nconst IDLE: AutosaveStatusInfo = {\n status: 'idle',\n error: null,\n failures: 0,\n nextAttemptAt: null,\n lastSavedAt: null,\n ready: false,\n};\n\n/**\n * Crash-recovery autosave bound to a history and dirty flag, with page\n * lifecycle flushing and a recovery check on mount (see\n * `createAutosaveController` in `@pixerate/editor/persistence`). Render\n * `<RecoveryPrompt>` with `recovery`, `restore` and `discard`.\n */\nexport function useAutosave<T>(options: UseAutosaveOptions<T>): UseAutosaveResult<T> {\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const { storage, key, history, dirty } = options;\n const recover = options.recover !== false;\n const flushOnHide = options.flushOnHide !== false;\n const ready = options.ready !== false;\n\n const [controller, setController] = useState<AutosaveController<T> | null>(null);\n const [status, setStatus] = useState<AutosaveStatusInfo>(IDLE);\n const [recovery, setRecovery] = useState<AutosaveRecovery<T> | null>(null);\n const [pendingRecovery, setPendingRecovery] = useState(recover);\n const revisionsRef = useRef<RevisionTracker | null>(null);\n\n useEffect(() => {\n const revisions = createRevisionTracker({ history, dirty });\n const o = optionsRef.current;\n const instance = createAutosaveController<T>({\n storage,\n key,\n getSnapshot: () => optionsRef.current.getSnapshot(),\n serialize: o.serialize,\n deserialize: o.deserialize,\n name: () => optionsRef.current.name,\n revision: revisions.revision,\n savedRevision: revisions.savedRevision,\n interval: o.interval,\n debounceMs: o.debounceMs,\n retryBaseMs: o.retryBaseMs,\n retryMaxMs: o.retryMaxMs,\n });\n const unsubscribeStatus = instance.subscribe(setStatus);\n const unsubscribeRevisions = revisions.subscribe(() => instance.notify());\n revisionsRef.current = revisions;\n setController(instance);\n setStatus(instance.getStatus());\n\n let active = true;\n if (recover) {\n setPendingRecovery(true);\n instance\n .checkRecovery()\n .catch(() => null)\n .then((found) => {\n if (!active) return;\n setRecovery(found);\n setPendingRecovery(found !== null);\n });\n } else {\n setRecovery(null);\n setPendingRecovery(false);\n }\n\n return () => {\n active = false;\n unsubscribeStatus();\n unsubscribeRevisions();\n revisions.destroy();\n instance.destroy();\n if (revisionsRef.current === revisions) revisionsRef.current = null;\n };\n }, [storage, key, history, dirty, recover]);\n\n useEffect(() => {\n if (controller && ready && !pendingRecovery) controller.ready();\n }, [controller, ready, pendingRecovery]);\n\n useEffect(() => {\n if (!controller || !flushOnHide || typeof window === 'undefined') return;\n const flush = () => void controller.flushNow();\n const onVisibility = () => {\n if (document.visibilityState === 'hidden') flush();\n };\n window.addEventListener('pagehide', flush);\n document.addEventListener('visibilitychange', onVisibility);\n return () => {\n window.removeEventListener('pagehide', flush);\n document.removeEventListener('visibilitychange', onVisibility);\n };\n }, [controller, flushOnHide]);\n\n const restore = useCallback(() => {\n const snapshot = recovery?.snapshot;\n setRecovery(null);\n setPendingRecovery(false);\n return snapshot;\n }, [recovery]);\n\n const discard = useCallback(async () => {\n if (controller) await controller.discardRecovery();\n setRecovery(null);\n setPendingRecovery(false);\n }, [controller]);\n\n const flushNow = useCallback(async () => {\n await controller?.flushNow();\n }, [controller]);\n\n const markClean = useCallback(async () => {\n revisionsRef.current?.markSaved();\n await controller?.markClean();\n }, [controller]);\n\n const notifyChange = useCallback(() => revisionsRef.current?.bump(), []);\n\n return { status, recovery, pendingRecovery, restore, discard, flushNow, markClean, notifyChange, controller };\n}\n","import React from 'react';\nimport { formatRecoveryMessage, type RecoveryMeta } from '@pixerate/editor/persistence';\n\nexport interface RecoveryPromptProps {\n /** `useAutosave().recovery`; nothing renders while it is `null`. */\n recovery: { meta: RecoveryMeta } | null;\n onRestore: () => void;\n onDiscard: () => void;\n /** Formats the snapshot time (default `toLocaleString`). */\n formatTime?: (time: number) => string;\n restoreLabel?: string;\n discardLabel?: string;\n className?: string;\n}\n\n/**\n * \"Restore unsaved changes from <time>?\" banner with Restore / Discard buttons\n * (Tailwind + theme tokens).\n */\nexport const RecoveryPrompt: React.FC<RecoveryPromptProps> = ({\n recovery,\n onRestore,\n onDiscard,\n formatTime,\n restoreLabel = 'Restore',\n discardLabel = 'Discard',\n className = '',\n}) => {\n if (!recovery) return null;\n const { name } = recovery.meta;\n return (\n <div\n role=\"alertdialog\"\n aria-label=\"Unsaved changes found\"\n data-recovery-prompt=\"\"\n className={`flex flex-wrap items-center gap-3 rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground shadow-sm ${className}`}\n >\n <span className=\"min-w-0 flex-1\">\n {formatRecoveryMessage(recovery.meta, formatTime)}\n {name ? <span className=\"ml-1 text-xs text-muted-foreground\">({name})</span> : null}\n </span>\n <button\n type=\"button\"\n data-recovery-restore=\"\"\n onClick={onRestore}\n className=\"rounded-md bg-primary px-3 py-1 text-xs font-medium text-primary-foreground hover:opacity-90\"\n >\n {restoreLabel}\n </button>\n <button\n type=\"button\"\n data-recovery-discard=\"\"\n onClick={onDiscard}\n className=\"rounded-md border border-border px-3 py-1 text-xs font-medium hover:bg-muted\"\n >\n {discardLabel}\n </button>\n </div>\n );\n};\n","import { useEffect, useMemo, useState } from 'react';\nimport {\n estimateJobProgress,\n planGenerationRequest,\n type GenerationPlan,\n type GenerationRequest,\n type JobProgressEstimate,\n type ModelCapabilities,\n type PlanOptions,\n} from '@pixerate/editor/generation';\n\n/**\n * Plans `request` against `capabilities` (see `planGenerationRequest`) and\n * returns the adjusted request, adjustments and errors. Recomputed only when\n * the request, capabilities or options change by value, so inline objects are fine.\n */\nexport function useGenerationPlan(\n request: GenerationRequest,\n capabilities: ModelCapabilities,\n options: PlanOptions = {},\n): GenerationPlan {\n const key = JSON.stringify([request, capabilities, options]);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useMemo(() => planGenerationRequest(request, capabilities, options), [key]);\n}\n\nexport interface UseJobProgressOptions {\n startedAt: number | Date | string;\n expectedMs?: number;\n done?: boolean;\n /** Fixed current time (disables ticking; useful for SSR and tests). */\n now?: number | Date | string;\n /** Re-render interval while running in ms (default 1000). */\n intervalMs?: number;\n}\n\n/** Ticking `estimateJobProgress` for a running job; stops ticking when `done`. */\nexport function useJobProgress(options: UseJobProgressOptions): JobProgressEstimate {\n const { startedAt, expectedMs, done, now, intervalMs = 1000 } = options;\n const [tick, setTick] = useState(() => Date.now());\n const ticking = !done && now === undefined;\n useEffect(() => {\n if (!ticking) return;\n setTick(Date.now());\n const id = setInterval(() => setTick(Date.now()), Math.max(16, intervalMs));\n return () => clearInterval(id);\n }, [ticking, intervalMs]);\n return estimateJobProgress({ startedAt, expectedMs, done, now: now ?? tick });\n}\n","import React, { useId, useMemo } from 'react';\nimport {\n getGenerationControls,\n getReferenceSlots,\n getRequestValue,\n parseControlValue,\n removeReference,\n setRequestValue,\n type GenerationControl,\n type GenerationPlan,\n type GenerationReference,\n type GenerationRequest,\n type ModelCapabilities,\n type PlanStrategy,\n type ReferenceRole,\n} from '@pixerate/editor/generation';\nimport { useGenerationPlan } from './useGenerationPlan';\n\nexport interface GenerationSettingsProps {\n capabilities: ModelCapabilities;\n /** The request being edited (controlled). */\n value: GenerationRequest;\n onChange: (next: GenerationRequest) => void;\n /** A plan computed elsewhere; otherwise one is computed with `strategy`. */\n plan?: GenerationPlan;\n /** Strategy for the built-in plan (default `nearest`). */\n strategy?: PlanStrategy;\n /** List plan adjustments and errors under the controls (default `true`). */\n showAdjustments?: boolean;\n /** Shows an \"Add\" button per reference role; you pick the asset and call `onChange`. */\n onAddReference?: (role: ReferenceRole) => void;\n /** Custom rendering of a reference chip (default: its id). */\n renderReference?: (reference: GenerationReference) => React.ReactNode;\n className?: string;\n}\n\nconst inputClass =\n 'w-full rounded-md border border-border bg-background px-2 py-1 text-sm outline-none focus:ring-1 focus:ring-ring';\n\nfunction Control({\n control,\n value,\n id,\n onValue,\n}: {\n control: GenerationControl;\n value: unknown;\n id: string;\n onValue: (value: unknown) => void;\n}) {\n const shown = value ?? control.defaultValue;\n if (control.kind === 'checkbox') {\n return (\n <input\n id={id}\n type=\"checkbox\"\n data-field={control.key}\n checked={Boolean(shown)}\n onChange={(e) => onValue(parseControlValue(control, e.target.checked))}\n />\n );\n }\n if (control.kind === 'select') {\n return (\n <select\n id={id}\n data-field={control.key}\n className={inputClass}\n value={shown === undefined ? '' : String(shown)}\n onChange={(e) => onValue(parseControlValue(control, e.target.value))}\n >\n {shown === undefined && <option value=\"\">Default</option>}\n {control.options!.map((option) => (\n <option key={String(option.value)} value={String(option.value)}>\n {option.label}\n </option>\n ))}\n </select>\n );\n }\n if (control.kind === 'textarea') {\n return (\n <textarea\n id={id}\n data-field={control.key}\n className={inputClass}\n rows={2}\n maxLength={control.maxLength}\n value={typeof value === 'string' ? value : ''}\n onChange={(e) => onValue(parseControlValue(control, e.target.value))}\n />\n );\n }\n const numeric = typeof shown === 'number' ? shown : undefined;\n return (\n <div className=\"flex items-center gap-2\">\n <input\n id={id}\n type={control.kind === 'range' ? 'range' : 'number'}\n data-field={control.key}\n className={control.kind === 'range' ? 'flex-1' : inputClass}\n min={control.min}\n max={control.max}\n step={control.step ?? 'any'}\n value={numeric ?? (control.kind === 'range' ? (control.min ?? 0) : '')}\n onChange={(e) => onValue(parseControlValue(control, e.target.value))}\n />\n {control.kind === 'range' && (\n <span className=\"w-10 text-right tabular-nums text-muted-foreground\" data-field-value=\"\">\n {numeric ?? '–'}\n </span>\n )}\n </div>\n );\n}\n\n/**\n * Headless-styled settings form generated from a model's capabilities:\n * selects for choices, sliders/number inputs for ranges, text areas for\n * negative/system prompts, checkboxes for boolean params, reference slots by\n * role, and the plan's adjustments and errors. Controlled via `value` / `onChange`.\n */\nexport const GenerationSettings: React.FC<GenerationSettingsProps> = ({\n capabilities,\n value,\n onChange,\n plan: planProp,\n strategy,\n showAdjustments = true,\n onAddReference,\n renderReference,\n className = '',\n}) => {\n const baseId = useId();\n const controls = useMemo(() => getGenerationControls(capabilities), [capabilities]);\n const computed = useGenerationPlan(value, capabilities, { strategy });\n const plan = planProp ?? computed;\n const slots = getReferenceSlots(capabilities, value);\n\n return (\n <div className={`flex flex-col gap-3 text-sm ${className}`} data-generation-settings=\"\" data-model={capabilities.id}>\n {controls.map((control) => {\n const id = `${baseId}-${control.key}`;\n return (\n <div key={control.key} className=\"flex flex-col gap-1\" data-control={control.key}>\n <label htmlFor={id} className=\"text-xs font-medium text-muted-foreground\" title={control.description}>\n {control.label}\n </label>\n <Control\n control={control}\n id={id}\n value={getRequestValue(value, control.key)}\n onValue={(next) => onChange(setRequestValue(value, control.key, next))}\n />\n </div>\n );\n })}\n\n {slots.map((slot) => (\n <fieldset key={slot.role} className=\"flex flex-col gap-1\" data-reference-role={slot.role}>\n <legend className=\"text-xs font-medium text-muted-foreground\" title={slot.description}>\n {slot.label}{' '}\n <span className=\"tabular-nums\" data-reference-count=\"\">\n ({slot.references.length}/{slot.max})\n </span>\n {slot.min > 0 && <span className=\"text-destructive\"> *</span>}\n </legend>\n <ul className=\"flex flex-wrap gap-1\">\n {slot.references.map((ref) => (\n <li key={ref.id} className=\"flex items-center gap-1 rounded border border-border px-1.5 py-0.5\" data-reference-id={ref.id}>\n {renderReference ? renderReference(ref) : <span className=\"max-w-[10rem] truncate\">{ref.id}</span>}\n <button\n type=\"button\"\n aria-label={`Remove ${slot.label} ${ref.id}`}\n className=\"text-muted-foreground hover:text-foreground\"\n onClick={() => onChange(removeReference(value, slot.role, ref.id))}\n >\n ×\n </button>\n </li>\n ))}\n {onAddReference && slot.canAdd && (\n <li>\n <button\n type=\"button\"\n className=\"rounded border border-dashed border-border px-1.5 py-0.5 text-muted-foreground hover:text-foreground\"\n onClick={() => onAddReference(slot.role)}\n >\n Add\n </button>\n </li>\n )}\n </ul>\n </fieldset>\n ))}\n\n {showAdjustments && plan.adjustments.length > 0 && (\n <ul role=\"status\" className=\"flex flex-col gap-0.5 text-xs text-muted-foreground\" data-generation-adjustments=\"\">\n {plan.adjustments.map((adjustment, index) => (\n <li key={index} data-adjustment-field={adjustment.field} data-adjustment-kind={adjustment.kind}>\n {adjustment.reason}\n </li>\n ))}\n </ul>\n )}\n {showAdjustments && plan.errors.length > 0 && (\n <ul role=\"alert\" className=\"flex flex-col gap-0.5 text-xs text-destructive\" data-generation-errors=\"\">\n {plan.errors.map((error, index) => (\n <li key={index} data-error-field={error.field}>\n {error.message}\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n};\n","import React from 'react';\nimport { useJobProgress, type UseJobProgressOptions } from './useGenerationPlan';\n\nexport interface JobProgressProps extends UseJobProgressOptions {\n /** Text shown before the time label, e.g. the model name. */\n title?: string;\n /** Extra classes for the root. */\n className?: string;\n}\n\n/**\n * Headless-styled progress bar for a generation job that reports no progress\n * of its own: time-based percent (held at 95% until `done`) with a\n * \"~2m left\" / \"Almost done…\" label. Exposes `role=\"progressbar\"`.\n */\nexport const JobProgress: React.FC<JobProgressProps> = ({ title, className = '', ...options }) => {\n const progress = useJobProgress(options);\n return (\n <div className={`flex flex-col gap-1 text-sm ${className}`} data-job-progress=\"\" data-done={options.done ? '' : undefined}>\n <div className=\"flex items-center justify-between gap-2 text-muted-foreground\">\n {title && <span className=\"truncate text-foreground\">{title}</span>}\n <span data-job-progress-label=\"\" aria-live=\"polite\">\n {progress.label}\n </span>\n </div>\n <div\n role=\"progressbar\"\n aria-label={title ?? 'Generation progress'}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={progress.percent}\n aria-valuetext={`${progress.percent}%, ${progress.label}`}\n className=\"h-1.5 w-full overflow-hidden rounded-full bg-muted\"\n >\n <div\n className=\"h-full rounded-full bg-primary transition-[width] duration-500\"\n style={{ width: `${progress.percent}%`, background: 'var(--primary, currentColor)' }}\n />\n </div>\n </div>\n );\n};\n","import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n defaultAssetRoleOptions,\n describeAssetMentions,\n findTextMentions,\n getAssetRoleOptions,\n setMentionRoleInText,\n type AssetInfo,\n type AssetMentionChip,\n type AssetRoleOption,\n type ModelCapabilities,\n} from '@pixerate/editor/generation';\n\nexport interface AssetMentionChipsProps {\n /** Prompt text containing `@asset` / `@asset:role` mentions. */\n content: string;\n /** Called with the text after a role is picked (`@fox` → `@fox:style_ref`). */\n onChange: (next: string) => void;\n /** Mentionable assets; mentions that match none (by id or label) are not shown. */\n assets: readonly AssetInfo[];\n /** The selected model: its roles are offered and mentions are checked against it. */\n capabilities?: ModelCapabilities;\n /** Role options (default: the model's roles, else the built-in roles). */\n roles?: readonly AssetRoleOption[];\n /** Custom chip content (default: the asset label). */\n renderAsset?: (chip: AssetMentionChip) => React.ReactNode;\n className?: string;\n}\n\n/**\n * The asset mentions of a prompt as chips with role badges. Clicking a chip\n * opens a role picker popover; picking a role rewrites the mention's `:role`\n * suffix in the text. Chips with problems for the model (unsupported role,\n * wrong media type, too many for the role) are flagged.\n */\nexport const AssetMentionChips: React.FC<AssetMentionChipsProps> = ({\n content,\n onChange,\n assets,\n capabilities,\n roles,\n renderAsset,\n className = '',\n}) => {\n const [open, setOpen] = useState<number | null>(null);\n const rootRef = useRef<HTMLDivElement>(null);\n const chips = useMemo(\n () => describeAssetMentions(findTextMentions(content), assets, capabilities),\n [content, assets, capabilities],\n );\n const options = roles ?? (capabilities ? getAssetRoleOptions(capabilities) : defaultAssetRoleOptions());\n\n useEffect(() => {\n if (open === null) return;\n const onPointer = (event: MouseEvent) => {\n if (!rootRef.current?.contains(event.target as Node)) setOpen(null);\n };\n document.addEventListener('mousedown', onPointer);\n return () => document.removeEventListener('mousedown', onPointer);\n }, [open]);\n\n const pick = (chip: AssetMentionChip, role: string | null) => {\n setOpen(null);\n if (chip.start === undefined) return;\n onChange(setMentionRoleInText(content, chip.start, role));\n };\n\n if (chips.length === 0) return null;\n return (\n <div ref={rootRef} className={`flex flex-wrap gap-1.5 ${className}`} data-asset-mention-chips=\"\">\n {chips.map((chip) => {\n const error = chip.issues.find((issue) => issue.severity === 'error');\n const warning = chip.issues.find((issue) => issue.severity === 'warning');\n const problem = error ?? warning;\n const isOpen = open === chip.index;\n return (\n <span key={`${chip.start}-${chip.index}`} className=\"relative inline-flex\" data-asset-chip={chip.asset.id}>\n <button\n type=\"button\"\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n title={problem?.message}\n data-issue={problem?.code}\n onClick={() => setOpen(isOpen ? null : chip.index)}\n onKeyDown={(e) => {\n if (e.key === 'Escape') setOpen(null);\n }}\n className={`inline-flex items-center gap-1 rounded-full border px-2 py-0.5 text-xs ${\n error ? 'border-red-500/60' : warning ? 'border-amber-500/60' : 'border-border'\n } bg-muted/40 hover:bg-muted`}\n >\n <span>{renderAsset ? renderAsset(chip) : `@${chip.asset.label ?? chip.handle}`}</span>\n <span\n className={`rounded px-1 text-[10px] uppercase tracking-wide ${chip.role ? 'bg-primary/15' : 'opacity-60'}`}\n data-role-badge={chip.role ?? ''}\n >\n {chip.roleLabel ?? 'No role'}\n </span>\n </button>\n {isOpen && (\n <div\n role=\"listbox\"\n aria-label={`Role for ${chip.asset.label ?? chip.handle}`}\n className=\"absolute left-0 top-full z-50 mt-1 flex min-w-[12rem] flex-col rounded-md border border-border bg-background p-1 text-xs shadow-lg\"\n data-role-picker=\"\"\n onKeyDown={(e) => {\n if (e.key === 'Escape') setOpen(null);\n }}\n >\n {options.map((option) => (\n <button\n key={option.role}\n type=\"button\"\n role=\"option\"\n aria-selected={chip.role === option.role}\n data-role-option={option.role}\n title={option.description}\n onClick={() => pick(chip, option.role)}\n className=\"flex items-center justify-between gap-2 rounded px-2 py-1 text-left hover:bg-muted\"\n >\n <span>{option.label}</span>\n {option.accepts?.length ? (\n <span className=\"text-[10px] opacity-60\">{option.accepts.join(', ')}</span>\n ) : null}\n </button>\n ))}\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={!chip.role}\n data-role-option=\"\"\n onClick={() => pick(chip, null)}\n className=\"rounded px-2 py-1 text-left opacity-70 hover:bg-muted\"\n >\n No role\n </button>\n {chip.issues.length > 0 && (\n <ul className=\"mt-1 border-t border-border px-2 pt-1 text-[10px]\" data-chip-issues=\"\">\n {chip.issues.map((issue, i) => (\n <li key={i} className={issue.severity === 'error' ? 'text-red-500' : 'text-amber-500'}>\n {issue.message}\n </li>\n ))}\n </ul>\n )}\n </div>\n )}\n </span>\n );\n })}\n </div>\n );\n};\n","import React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n DRIFT_TYPE_LABELS,\n recreateRequest,\n referenceRoleLabel,\n stableStringify,\n variationRequest,\n type AssetLookup,\n type GenerationRecord,\n type GenerationRecordFilter,\n type GenerationRecordStore,\n type ModelCapabilities,\n type RecreateMode,\n type RecreateOptions,\n type RecreateResult,\n} from '@pixerate/editor/generation';\n\ntype Template = NonNullable<RecreateOptions['templates']>[number];\n\nexport interface UseGenerationRecordsResult {\n records: GenerationRecord[];\n loading: boolean;\n error: unknown;\n refresh: () => Promise<void>;\n}\n\n/**\n * Loads records from a `GenerationRecordStore` (newest first) and reloads\n * whenever the store changes. `filter` is compared by value.\n */\nexport function useGenerationRecords(\n store: GenerationRecordStore | null | undefined,\n filter?: GenerationRecordFilter,\n): UseGenerationRecordsResult {\n const [records, setRecords] = useState<GenerationRecord[]>([]);\n const [loading, setLoading] = useState(!!store);\n const [error, setError] = useState<unknown>(null);\n const filterKey = stableStringify(filter ?? {});\n\n const refresh = useCallback(async () => {\n if (!store) {\n setRecords([]);\n setLoading(false);\n return;\n }\n setLoading(true);\n try {\n const next = await store.list(filter);\n setRecords(next);\n setError(null);\n } catch (err) {\n setError(err);\n } finally {\n setLoading(false);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [store, filterKey]);\n\n useEffect(() => {\n void refresh();\n if (!store) return;\n return store.subscribe(() => void refresh());\n }, [store, refresh]);\n\n return { records, loading, error, refresh };\n}\n\nexport interface GenerationHistoryProps {\n records: readonly GenerationRecord[];\n /** Current templates (drift detection, and resolution in `latest` mode). */\n templates?: readonly Template[];\n /** Current models (capability drift and re-planning). */\n capabilities?: ModelCapabilities | readonly ModelCapabilities[];\n /** Current assets (missing / changed asset drift). */\n assets?: AssetLookup;\n /** Recreate mode (controlled); otherwise a toggle starting at `exact`. */\n mode?: RecreateMode;\n onModeChange?: (mode: RecreateMode) => void;\n /** \"Recreate\": receives the rebuilt request and drift report. */\n onRecreate?: (result: RecreateResult, record: GenerationRecord) => void;\n /** \"Variation\": same request with a new seed. */\n onVariation?: (result: RecreateResult, record: GenerationRecord) => void;\n onRemove?: (record: GenerationRecord) => void;\n /** Extra content per record (e.g. output thumbnails). */\n renderPreview?: (record: GenerationRecord) => React.ReactNode;\n emptyText?: string;\n className?: string;\n}\n\nconst severityClass = {\n info: 'text-sky-600 dark:text-sky-300',\n warning: 'text-amber-600 dark:text-amber-300',\n error: 'text-red-600 dark:text-red-400',\n} as const;\n\n/**\n * Generation history: one entry per record with its model, prompt, asset\n * role badges and the drift since it was made (templates edited, model\n * capabilities changed, settings no longer supported, assets missing), plus\n * Recreate and Variation buttons. Recreate is disabled when drift blocks it.\n */\nexport const GenerationHistory: React.FC<GenerationHistoryProps> = ({\n records,\n templates,\n capabilities,\n assets,\n mode: modeProp,\n onModeChange,\n onRecreate,\n onVariation,\n onRemove,\n renderPreview,\n emptyText = 'No generations yet.',\n className = '',\n}) => {\n const [innerMode, setInnerMode] = useState<RecreateMode>('exact');\n const mode = modeProp ?? innerMode;\n const setMode = (next: RecreateMode) => {\n if (modeProp === undefined) setInnerMode(next);\n onModeChange?.(next);\n };\n const options = useMemo(() => ({ templates, capabilities, assets, mode }), [templates, capabilities, assets, mode]);\n const results = useMemo(() => records.map((record) => recreateRequest(record, options)), [records, options]);\n const models = useMemo(\n () => (capabilities ? (Array.isArray(capabilities) ? capabilities : [capabilities as ModelCapabilities]) : []),\n [capabilities],\n );\n\n return (\n <div className={`flex flex-col gap-2 text-sm ${className}`} data-generation-history=\"\">\n <div className=\"flex items-center gap-2 text-xs\" role=\"radiogroup\" aria-label=\"Recreate mode\">\n {(['exact', 'latest'] as const).map((value) => (\n <label key={value} className=\"inline-flex items-center gap-1\">\n <input\n type=\"radio\"\n name=\"generation-history-mode\"\n value={value}\n checked={mode === value}\n onChange={() => setMode(value)}\n data-mode={value}\n />\n {value === 'exact' ? 'Exact (recorded versions)' : 'Latest templates & settings'}\n </label>\n ))}\n </div>\n {records.length === 0 && <p className=\"text-xs text-muted-foreground\">{emptyText}</p>}\n <ul className=\"flex flex-col gap-2\">\n {records.map((record, i) => {\n const result = results[i];\n const model = models.find((m) => m.id === record.provenance.modelId);\n const blocked = !result.ok;\n return (\n <li\n key={record.id}\n className=\"rounded-md border border-border p-2\"\n data-record={record.id}\n data-drift={result.drift.length}\n >\n <div className=\"flex flex-wrap items-center justify-between gap-2 text-xs\">\n <span className=\"font-medium\">{model?.name ?? record.provenance.modelId}</span>\n <span className=\"text-muted-foreground\">\n {record.kind !== 'generate' && <span data-kind=\"\">{record.kind} · </span>}\n <time dateTime={record.createdAt}>{record.createdAt.replace('T', ' ').slice(0, 16)}</time>\n {record.seed !== undefined && <> · seed {record.seed}</>}\n </span>\n </div>\n <p className=\"mt-1 line-clamp-3 break-words text-xs\" data-record-prompt=\"\">\n {record.provenance.resolvedPrompt}\n </p>\n {record.assets.length > 0 && (\n <div className=\"mt-1 flex flex-wrap gap-1\">\n {record.assets.map((asset) => (\n <span\n key={`${asset.role}:${asset.id}`}\n className=\"rounded-full bg-muted px-2 py-0.5 text-[10px]\"\n data-asset-role={asset.role}\n >\n {asset.id} · {referenceRoleLabel(asset.role, model)}\n </span>\n ))}\n </div>\n )}\n {renderPreview?.(record)}\n {result.drift.length > 0 && (\n <ul className=\"mt-1 flex flex-col gap-0.5 text-[11px]\" data-drift-report=\"\">\n {result.drift.map((item, j) => (\n <li key={j} className={severityClass[item.severity]} data-drift-type={item.type}>\n <strong>{DRIFT_TYPE_LABELS[item.type]}:</strong> {item.message}\n </li>\n ))}\n </ul>\n )}\n <div className=\"mt-2 flex gap-2\">\n {onRecreate && (\n <button\n type=\"button\"\n disabled={blocked}\n title={blocked ? 'This generation cannot be recreated as recorded.' : undefined}\n onClick={() => onRecreate(result, record)}\n className=\"rounded border border-border px-2 py-0.5 text-xs hover:bg-muted disabled:opacity-50\"\n data-action=\"recreate\"\n >\n Recreate\n </button>\n )}\n {onVariation && (\n <button\n type=\"button\"\n onClick={() => onVariation(variationRequest(record, {}, options), record)}\n className=\"rounded border border-border px-2 py-0.5 text-xs hover:bg-muted\"\n data-action=\"variation\"\n >\n Variation\n </button>\n )}\n {onRemove && (\n <button\n type=\"button\"\n onClick={() => onRemove(record)}\n className=\"ml-auto rounded px-2 py-0.5 text-xs text-muted-foreground hover:bg-muted\"\n data-action=\"remove\"\n >\n Remove\n </button>\n )}\n </div>\n </li>\n );\n })}\n </ul>\n </div>\n );\n};\n","import { useCallback, useMemo, useSyncExternalStore } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n EMPTY_FIND_REPLACE_SNAPSHOT,\n getFindReplaceStore,\n type FindOptions,\n type FindReplaceMode,\n type FindReplaceSnapshot,\n} from \"@pixerate/editor\";\n\nexport interface UseFindReplaceResult extends FindReplaceSnapshot {\n /** Whether the editor has the `FindReplace` extension. */\n available: boolean;\n matchCount: number;\n open: boolean;\n show: (mode?: FindReplaceMode) => void;\n close: () => void;\n setQuery: (query: string) => void;\n setReplacement: (replacement: string) => void;\n setOptions: (options: Partial<FindOptions>) => void;\n toggleOption: (option: keyof FindOptions) => void;\n next: () => void;\n previous: () => void;\n replace: () => void;\n replaceAll: () => void;\n clear: () => void;\n}\n\nconst noopUnsubscribe = () => {};\n\n/**\n * Subscribes to an editor's Find and Replace state (`FindReplace` extension)\n * and exposes its commands.\n */\nexport function useFindReplace(editor: Editor | null | undefined): UseFindReplaceResult {\n const store = getFindReplaceStore(editor ?? null);\n const subscribe = useCallback(\n (onChange: () => void) => (store ? store.subscribe(() => onChange()) : noopUnsubscribe),\n [store],\n );\n const getSnapshot = () => store?.getSnapshot() ?? EMPTY_FIND_REPLACE_SNAPSHOT;\n const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n return useMemo(() => {\n const run = (fn: (e: Editor) => void) => {\n if (editor && !editor.isDestroyed && store) fn(editor);\n };\n return {\n ...snapshot,\n available: !!store,\n matchCount: snapshot.matches.length,\n show: (mode: FindReplaceMode = \"find\") =>\n run((e) => e.commands.openFindReplace({ mode })),\n close: () => run((e) => e.commands.closeFindReplace()),\n setQuery: (query: string) => run((e) => e.commands.setSearch({ query })),\n setReplacement: (replacement: string) => run((e) => e.commands.setSearch({ replacement })),\n setOptions: (options: Partial<FindOptions>) => run((e) => e.commands.setSearch({ options })),\n toggleOption: (option: keyof FindOptions) =>\n run((e) => e.commands.setSearch({ options: { [option]: !snapshot.options[option] } })),\n next: () => run((e) => e.commands.findNext()),\n previous: () => run((e) => e.commands.findPrevious()),\n replace: () => run((e) => e.commands.replaceCurrent()),\n replaceAll: () => run((e) => e.commands.replaceAll()),\n clear: () => run((e) => e.commands.clearSearch()),\n };\n }, [snapshot, editor, store]);\n}\n","import React, { useEffect, useRef, useState } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { FIND_OPTION_TOGGLES, formatFindStatus } from \"@pixerate/editor\";\nimport { useFindReplace } from \"./useFindReplace\";\n\nexport interface FindReplaceBarProps {\n editor: Editor | null;\n className?: string;\n /** Render even while the find state is closed (default: only after Mod+F / Mod+H / `openFindReplace`). */\n alwaysOpen?: boolean;\n /** Show the \"More options\" toggle (prefix, suffix, ignore punctuation/white space, literal). Default `true`. */\n showMoreOptions?: boolean;\n /** Called after the bar closes (Escape or the close button). */\n onClose?: () => void;\n}\n\nconst inputClass =\n \"min-w-0 flex-1 rounded border border-input bg-background px-2 py-1 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-ring\";\nconst buttonClass =\n \"rounded px-2 py-1 text-xs text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent\";\nconst toggleClass = (on: boolean) =>\n `${buttonClass} font-mono ${on ? \"bg-primary/10 text-primary\" : \"text-muted-foreground\"}`;\n\nconst isMod = (e: React.KeyboardEvent) => e.metaKey || e.ctrlKey;\n\n/**\n * Word-style find bar for an editor using the `FindReplace` extension: find\n * and replace fields, option toggles, \"3 of 12\" counter, previous/next,\n * Replace and Replace All. Enter / Shift+Enter step through matches, Enter in\n * the replace field replaces, Mod+Enter replaces all, Escape closes.\n */\nexport const FindReplaceBar: React.FC<FindReplaceBarProps> = ({\n editor,\n className = \"flex flex-col gap-1 rounded-md border border-border bg-background p-1 text-sm shadow-sm\",\n alwaysOpen = false,\n showMoreOptions = true,\n onClose,\n}) => {\n const find = useFindReplace(editor);\n const findInput = useRef<HTMLInputElement>(null);\n const [moreOpen, setMoreOpen] = useState(false);\n const visible = find.available && (alwaysOpen || find.open);\n\n // Mod+F / Mod+H (in the editor or the bar) focus and select the find field.\n useEffect(() => {\n if (!visible || find.focusRequest === 0) return;\n findInput.current?.focus();\n findInput.current?.select();\n }, [visible, find.focusRequest]);\n\n if (!visible) return null;\n\n const showReplace = find.mode === \"replace\";\n const status = formatFindStatus(find);\n const hasMatches = find.matchCount > 0;\n\n const close = () => {\n find.close();\n editor?.commands.focus();\n onClose?.();\n };\n\n const onBarKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n close();\n } else if (isMod(e) && (e.key === \"f\" || e.key === \"F\")) {\n e.preventDefault();\n find.show(\"find\");\n } else if (isMod(e) && (e.key === \"h\" || e.key === \"H\")) {\n e.preventDefault();\n find.show(\"replace\");\n }\n };\n\n const onFindKeyDown = (e: React.KeyboardEvent) => {\n if (e.key !== \"Enter\") return;\n e.preventDefault();\n if (e.shiftKey) find.previous();\n else find.next();\n };\n\n const onReplaceKeyDown = (e: React.KeyboardEvent) => {\n if (e.key !== \"Enter\") return;\n e.preventDefault();\n if (isMod(e)) find.replaceAll();\n else find.replace();\n };\n\n return (\n <div className={className} role=\"search\" aria-label=\"Find and replace\" onKeyDown={onBarKeyDown}>\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n className={buttonClass}\n aria-label=\"Toggle replace\"\n aria-expanded={showReplace}\n onClick={() => find.show(showReplace ? \"find\" : \"replace\")}\n >\n {showReplace ? \"▾\" : \"▸\"}\n </button>\n <input\n ref={findInput}\n type=\"text\"\n className={inputClass}\n placeholder=\"Find\"\n aria-label=\"Find\"\n aria-invalid={!!find.error}\n value={find.query}\n onChange={(e) => find.setQuery(e.target.value)}\n onKeyDown={onFindKeyDown}\n />\n {FIND_OPTION_TOGGLES.filter((t) => !t.advanced).map((t) => (\n <button\n key={t.key}\n type=\"button\"\n className={toggleClass(!!find.options[t.key])}\n aria-label={t.label}\n title={t.label}\n aria-pressed={!!find.options[t.key]}\n onClick={() => find.toggleOption(t.key)}\n >\n {t.short}\n </button>\n ))}\n <span\n className={`min-w-[5rem] px-1 text-center text-xs ${find.error ? \"text-destructive\" : \"text-muted-foreground\"}`}\n aria-live=\"polite\"\n role={find.error ? \"alert\" : \"status\"}\n data-testid=\"find-status\"\n >\n {status}\n </span>\n <button type=\"button\" className={buttonClass} aria-label=\"Previous match\" disabled={!hasMatches} onClick={find.previous}>\n ↑\n </button>\n <button type=\"button\" className={buttonClass} aria-label=\"Next match\" disabled={!hasMatches} onClick={find.next}>\n ↓\n </button>\n {showMoreOptions && (\n <button\n type=\"button\"\n className={buttonClass}\n aria-label=\"More options\"\n aria-expanded={moreOpen}\n onClick={() => setMoreOpen((v) => !v)}\n >\n …\n </button>\n )}\n <button type=\"button\" className={buttonClass} aria-label=\"Close find\" onClick={close}>\n ×\n </button>\n </div>\n {showReplace && (\n <div className=\"flex items-center gap-1 pl-7\">\n <input\n type=\"text\"\n className={inputClass}\n placeholder=\"Replace\"\n aria-label=\"Replace\"\n value={find.replacement}\n onChange={(e) => find.setReplacement(e.target.value)}\n onKeyDown={onReplaceKeyDown}\n />\n <button\n type=\"button\"\n className={buttonClass}\n disabled={!hasMatches || find.currentIndex < 0}\n onClick={find.replace}\n >\n Replace\n </button>\n <button type=\"button\" className={buttonClass} disabled={!hasMatches} onClick={find.replaceAll}>\n Replace all\n </button>\n {find.lastReplaceCount !== null && (\n <span className=\"px-1 text-xs text-muted-foreground\" aria-live=\"polite\">\n {find.lastReplaceCount === 1 ? \"1 replaced\" : `${find.lastReplaceCount} replaced`}\n </span>\n )}\n </div>\n )}\n {showMoreOptions && moreOpen && (\n <div className=\"flex flex-wrap items-center gap-x-3 gap-y-1 pl-7 text-xs text-muted-foreground\">\n {FIND_OPTION_TOGGLES.filter((t) => t.advanced).map((t) => (\n <label key={t.key} className=\"flex items-center gap-1\">\n <input\n type=\"checkbox\"\n checked={!!find.options[t.key]}\n onChange={() => find.toggleOption(t.key)}\n />\n {t.label}\n </label>\n ))}\n </div>\n )}\n </div>\n );\n};\n","import { useMemo, useSyncExternalStore } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport {\n createTableStore,\n getTableActionState,\n runTableAction,\n type TableAction,\n type TableActionParams,\n type TableState,\n} from \"@pixerate/editor\";\n\nexport type { TableAction, TableActionParams, TableState } from \"@pixerate/editor\";\n\nexport interface UseTableMenuResult extends TableState {\n /** Runs a table action (focusing the editor); `false` when it cannot run. */\n run: (action: TableAction, params?: TableActionParams) => boolean;\n /** `true`, or why the action cannot run with these params. */\n check: (action: TableAction, params?: TableActionParams) => true | string;\n}\n\n/**\n * Subscribes to the table at the editor's selection: whether the selection\n * is in a table, its size, header state, the cell's alignment and\n * background, and the enablement (with reasons) of every table action.\n * Re-renders only when that state changes. The Svelte counterpart is\n * `createTableMenu`.\n */\nexport function useTableMenu(editor: Editor | null | undefined): UseTableMenuResult {\n // The store only listens to the editor while subscribed (StrictMode-safe).\n const store = useMemo(() => createTableStore(editor), [editor]);\n const snapshot = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n return useMemo(\n () => ({\n ...snapshot,\n run: (action, params) => runTableAction(editor, action, params, { focus: true }),\n check: (action, params) => getTableActionState(editor, action, params),\n }),\n [snapshot, editor],\n );\n}\n","import React from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { DEFAULT_TABLE_TOOLBAR, type TableToolbarItem } from \"@pixerate/editor\";\nimport { useTableMenu } from \"./useTableMenu\";\n\nexport interface TableToolbarProps {\n editor: Editor | null;\n /** Buttons to show (default `DEFAULT_TABLE_TOOLBAR`). */\n items?: readonly TableToolbarItem[];\n /** Render (with disabled buttons) when the selection is not in a table. Default `false`. */\n showWhenOutside?: boolean;\n className?: string;\n buttonClassName?: string;\n activeButtonClassName?: string;\n separatorClassName?: string;\n /** Called after a button ran its action. */\n onAction?: (item: TableToolbarItem) => void;\n}\n\nconst keepSelection = (event: React.MouseEvent) => event.preventDefault();\n\n/**\n * Table toolbar: insert/delete rows and columns, merge/split cells, header\n * toggles, cell alignment and delete table. Rendered only while the\n * selection is in a table (unless `showWhenOutside`); disabled buttons say\n * why in their tooltip. Use it inline, or inside `TableBubbleMenu`.\n */\nexport const TableToolbar: React.FC<TableToolbarProps> = ({\n editor,\n items = DEFAULT_TABLE_TOOLBAR,\n showWhenOutside = false,\n className = \"flex flex-wrap items-center gap-1 text-xs\",\n buttonClassName = \"rounded px-2 py-1 text-foreground hover:bg-muted disabled:opacity-40 disabled:hover:bg-transparent\",\n activeButtonClassName = \"bg-primary/10 text-primary\",\n separatorClassName = \"mx-1 h-4 w-px bg-border\",\n onAction,\n}) => {\n const table = useTableMenu(editor);\n if (!editor || (!table.inTable && !showWhenOutside)) return null;\n\n return (\n <div className={className} role=\"toolbar\" aria-label=\"Table\" data-table-toolbar=\"\">\n {items.map((item, index) => {\n const status = table.check(item.action, item.params);\n const enabled = status === true;\n const active = item.active?.(table);\n const separator = index > 0 && items[index - 1].group !== item.group;\n return (\n <React.Fragment key={item.id}>\n {separator && <span className={separatorClassName} aria-hidden=\"true\" />}\n <button\n type=\"button\"\n data-action={item.id}\n aria-label={item.title}\n title={enabled ? item.title : `${item.title}: ${status}`}\n {...(item.active ? { \"aria-pressed\": !!active } : {})}\n disabled={!enabled}\n className={active ? `${buttonClassName} ${activeButtonClassName}` : buttonClassName}\n onMouseDown={keepSelection}\n onClick={() => {\n if (table.run(item.action, item.params)) onAction?.(item);\n }}\n >\n {item.label}\n </button>\n </React.Fragment>\n );\n })}\n </div>\n );\n};\n","import React, { useState } from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { useTableMenu } from \"./useTableMenu\";\n\nexport interface InsertTableGridProps {\n editor: Editor | null;\n /** Grid size offered (default 8 × 8). */\n rows?: number;\n cols?: number;\n /** Insert with a header row (default `true`). */\n withHeaderRow?: boolean;\n className?: string;\n cellClassName?: string;\n activeCellClassName?: string;\n /** Called after a table was inserted. */\n onInsert?: (size: { rows: number; cols: number }) => void;\n}\n\nconst keepSelection = (event: React.MouseEvent) => event.preventDefault();\n\n/**\n * Word-style insert-table picker: hover (or focus) a cell of the grid to\n * choose the size, click to insert a table of that size at the cursor. The\n * grid is disabled (with the reason as its title) where a table cannot be\n * inserted, e.g. inside another table.\n */\nexport const InsertTableGrid: React.FC<InsertTableGridProps> = ({\n editor,\n rows = 8,\n cols = 8,\n withHeaderRow = true,\n className = \"inline-flex flex-col gap-1 rounded-md border border-border bg-background p-2 text-xs shadow-md\",\n cellClassName = \"h-4 w-4 rounded-sm border border-border bg-background disabled:opacity-40\",\n activeCellClassName = \"border-primary bg-primary/20\",\n onInsert,\n}) => {\n const table = useTableMenu(editor);\n const [hover, setHover] = useState<{ rows: number; cols: number } | null>(null);\n const status = table.actions.insertTable;\n const disabled = !editor || !status.enabled;\n\n const insert = (size: { rows: number; cols: number }) => {\n if (table.run(\"insertTable\", { ...size, withHeaderRow })) onInsert?.(size);\n setHover(null);\n };\n\n return (\n <div\n className={className}\n role=\"group\"\n aria-label=\"Insert table\"\n title={disabled ? status.reason : undefined}\n data-insert-table-grid=\"\"\n onMouseLeave={() => setHover(null)}\n >\n <div\n role=\"grid\"\n aria-label=\"Table size\"\n style={{ display: \"grid\", gridTemplateColumns: `repeat(${cols}, max-content)`, gap: 2 }}\n >\n {Array.from({ length: rows * cols }, (_, i) => {\n const size = { rows: Math.floor(i / cols) + 1, cols: (i % cols) + 1 };\n const active = !!hover && size.rows <= hover.rows && size.cols <= hover.cols;\n return (\n <button\n key={i}\n type=\"button\"\n data-rows={size.rows}\n data-cols={size.cols}\n data-active={active}\n aria-label={`${size.rows} × ${size.cols} table`}\n disabled={disabled}\n className={active ? `${cellClassName} ${activeCellClassName}` : cellClassName}\n onMouseDown={keepSelection}\n onMouseEnter={() => setHover(size)}\n onFocus={() => setHover(size)}\n onClick={() => insert(size)}\n />\n );\n })}\n </div>\n <div aria-live=\"polite\" data-testid=\"insert-table-size\">\n {disabled ? status.reason : hover ? `${hover.rows} × ${hover.cols}` : \"Insert table\"}\n </div>\n </div>\n );\n};\n","import React from \"react\";\nimport type { Editor } from \"@tiptap/core\";\nimport { shouldShowTableBubbleMenu } from \"@pixerate/editor\";\nimport { BubbleMenu, type BubbleMenuProps } from \"../components/BubbleMenu\";\nimport { TableToolbar, type TableToolbarProps } from \"./TableToolbar\";\n\nexport interface TableBubbleMenuProps\n extends Omit<BubbleMenuProps, \"editor\" | \"children\" | \"shouldShow\"> {\n editor: Editor | null;\n /** Custom content (default: a `TableToolbar`). */\n children?: React.ReactNode;\n /** Props for the default `TableToolbar`. */\n toolbarProps?: Omit<TableToolbarProps, \"editor\">;\n}\n\n/**\n * A bubble menu that follows the selection while it is in a table (even a\n * collapsed cursor), with the table toolbar or your own `children`. It uses\n * its own plugin key (`tableBubbleMenu`), so it can be combined with the\n * formatting `BubbleMenu`.\n */\nexport const TableBubbleMenu: React.FC<TableBubbleMenuProps> = ({\n editor,\n children,\n toolbarProps,\n pluginKey = \"tableBubbleMenu\",\n ...rest\n}) => (\n <BubbleMenu editor={editor} pluginKey={pluginKey} shouldShow={shouldShowTableBubbleMenu as BubbleMenuProps[\"shouldShow\"]} {...rest}>\n {children ?? <TableToolbar editor={editor} {...toolbarProps} />}\n </BubbleMenu>\n);\n","import React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport type { ChartNodeViewMount, ChartNodeViewState } from '@pixerate/editor';\nimport type { ChartTheme } from '@pixerate/editor/chart';\nimport { ChartCanvas } from '../chart/ChartCanvas';\nimport { ChartDataGrid } from '../chart/ChartDataGrid';\nimport { ChartInspector } from '../chart/ChartInspector';\nimport { chartButtonClass } from '../chart/styles';\n\nexport interface ChartNodeViewProps {\n /** What the editor's `chart` node passes (see `ChartNodeViewState`). */\n state: ChartNodeViewState;\n /** Chart colours (default: the CSS-variable theme). */\n theme?: Partial<ChartTheme>;\n /** Show the data grid under the chart while editing (default `true`). */\n showDataGrid?: boolean;\n}\n\n/**\n * A chart inside a rich-text document: read-only until clicked, then editable on the canvas\n * with the data grid and the inspector in a panel below (side by side when there is room). \"Done\", Escape or moving the\n * selection away closes it. Edits are written back to the document as undo steps.\n */\nexport function ChartNodeView({ state, theme, showDataGrid = true }: ChartNodeViewProps) {\n const { controller, editing, editable, selected, width, height, setEditing } = state;\n const open = () => {\n if (editable && !editing) setEditing(true);\n };\n return (\n <div\n className={`not-prose my-2 rounded-md border bg-background p-1 ${selected ? 'border-primary ring-1 ring-primary' : 'border-border'}`}\n data-chart-node-view=\"\"\n data-editing={editing ? '' : undefined}\n onKeyDown={(e) => {\n if (editing && e.key === 'Escape') {\n e.stopPropagation();\n setEditing(false);\n }\n }}\n >\n {editing && (\n <div className=\"mb-1 flex items-center justify-between gap-2 px-1\" data-chart-node-toolbar=\"\">\n <span className=\"text-xs text-muted-foreground\">Editing chart</span>\n <button type=\"button\" className={chartButtonClass} data-action=\"done\" onClick={() => setEditing(false)}>\n Done\n </button>\n </div>\n )}\n <div\n className={editable && !editing ? 'cursor-pointer' : undefined}\n onClick={open}\n title={editable && !editing ? 'Click to edit the chart' : undefined}\n data-chart-node-canvas=\"\"\n >\n <ChartCanvas controller={controller} width={width ?? 640} height={height} responsive={width === null} editable={editing} theme={theme} />\n </div>\n {editing && (\n // Wraps by the document's width, not the viewport's: side by side when there is room.\n <div className=\"mt-2 flex flex-wrap items-start gap-2\" data-chart-node-panel=\"\">\n {showDataGrid && (\n <div className=\"min-w-0 flex-[1_1_20rem] overflow-x-auto\">\n <ChartDataGrid controller={controller} />\n </div>\n )}\n <ChartInspector controller={controller} className=\"max-h-96 min-w-0 flex-[1_1_16rem] overflow-y-auto rounded-md border border-border p-3\" />\n </div>\n )}\n </div>\n );\n}\n\nexport interface ReactChartNodeViewOptions extends Omit<ChartNodeViewProps, 'state'> {\n /** Draw something else for each chart (default `ChartNodeView`). */\n component?: React.ComponentType<ChartNodeViewProps>;\n}\n\n/**\n * The `nodeView` for the core `chart` node, drawing `ChartNodeView` in its own React root:\n * `createRichTextPreset({ chart: { nodeView: createReactChartNodeView() } })`. Works with any\n * TipTap editor (it does not need `EditorContent`); app context does not reach the chart.\n */\nexport function createReactChartNodeView(options: ReactChartNodeViewOptions = {}): ChartNodeViewMount {\n const { component: Component = ChartNodeView, ...props } = options;\n return (dom, state) => {\n const root = createRoot(dom);\n let latest = state;\n let scheduled = false;\n let destroyed = false;\n // ProseMirror creates and updates node views inside other renders (e.g. while\n // `EditorContent` mounts), where rendering another root is an error: render in a microtask.\n const schedule = () => {\n if (scheduled) return;\n scheduled = true;\n queueMicrotask(() => {\n scheduled = false;\n if (!destroyed) root.render(<Component {...props} state={latest} />);\n });\n };\n schedule();\n return {\n update: (next) => {\n latest = next;\n schedule();\n },\n destroy: () => {\n destroyed = true;\n queueMicrotask(() => root.unmount());\n },\n };\n };\n}\n","import React, { useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';\nimport {\n CSS_VARIABLE_CHART_THEME,\n chartClientToScene,\n chartTextBaseline,\n chartTextTransform,\n describeChartSelection,\n handleChartKey,\n layoutChart,\n startChartPointDrag,\n type ChartController,\n type ChartMark,\n type ChartPointDrag,\n type ChartPresence,\n type ChartScene,\n type ChartTextMeasure,\n type ChartTheme,\n} from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\n\nexport interface ChartCanvasProps {\n controller: ChartController;\n /** Scene width; with `responsive` this is only the fallback before the container is measured (default 640). */\n width?: number;\n /** Scene height in pixels (default 400). */\n height?: number;\n /** Follow the container's width (default `true`). */\n responsive?: boolean;\n /** Colours and type (default: shadcn-style CSS variables). */\n theme?: Partial<ChartTheme>;\n /** Click to select, drag bars and points, keyboard editing (default `true`). */\n editable?: boolean;\n /** Text width for layout (default: an estimate). */\n measureText?: ChartTextMeasure;\n emptyMessage?: string;\n className?: string;\n /** Agent cursors to draw over the chart (see `ChartDirector`). */\n presence?: ChartPresence;\n /** Receives the scene as drawn (e.g. for `ChartDirector`'s `scene`). */\n sceneRef?: { current: ChartScene | null };\n}\n\n/** SVG attributes for one mark (colours go in `style` so CSS variables work). */\nexport function renderChartMark(mark: ChartMark, fontFamily: string, interactive: boolean): React.ReactNode {\n const common = {\n 'data-role': mark.role,\n 'data-chart-key': mark.target ? mark.key : undefined,\n 'data-selected': mark.selected ? '' : undefined,\n opacity: mark.opacity,\n pointerEvents: mark.role === 'selection' || mark.role === 'drag-readout' || (!mark.target && mark.role !== 'background') ? ('none' as const) : undefined,\n cursor: interactive && mark.target && mark.role !== 'background' ? 'pointer' : undefined,\n };\n switch (mark.kind) {\n case 'rect':\n return <rect key={mark.key} {...common} x={mark.x} y={mark.y} width={mark.width} height={mark.height} rx={mark.radius} style={{ fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'path':\n return (\n <path\n key={mark.key}\n {...common}\n d={mark.d}\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n strokeDasharray={mark.dash}\n style={{ fill: mark.fill ?? 'none', stroke: mark.stroke, strokeWidth: mark.strokeWidth }}\n />\n );\n case 'circle':\n return <circle key={mark.key} {...common} cx={mark.cx} cy={mark.cy} r={mark.r} style={{ fill: mark.fill, stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'line':\n return <line key={mark.key} {...common} x1={mark.x1} y1={mark.y1} x2={mark.x2} y2={mark.y2} strokeDasharray={mark.dash} style={{ stroke: mark.stroke, strokeWidth: mark.strokeWidth }} />;\n case 'text':\n return (\n <text\n key={mark.key}\n {...common}\n x={mark.x}\n y={mark.y}\n textAnchor={mark.anchor}\n dominantBaseline={chartTextBaseline(mark.baseline)}\n transform={chartTextTransform(mark)}\n style={{ fill: mark.fill, fontSize: mark.size, fontWeight: mark.weight, fontFamily, userSelect: 'none' }}\n >\n {mark.text}\n </text>\n );\n }\n}\n\n/** Agent cursors and notes, drawn in scene coordinates inside the chart's SVG. */\nexport function ChartPresenceLayer({ presence }: { presence: ChartPresence }) {\n const { actors } = useSyncExternalStore(presence.subscribe, presence.getState, presence.getState);\n return (\n <g data-chart-presence=\"\" pointerEvents=\"none\">\n {actors.map((a) => (\n <g key={a.id} transform={`translate(${a.x} ${a.y})`} data-actor={a.id}>\n <path d=\"M0,0 L0,14 L4,10.5 L7,17 L9.5,16 L6.5,9.5 L11.5,9.5 Z\" style={{ fill: a.color, stroke: '#ffffff', strokeWidth: 1 }} transform={a.pressed ? 'scale(0.9)' : undefined} />\n <g transform=\"translate(13 16)\">\n <rect x={0} y={0} rx={4} height={18} width={Math.max(28, (a.message ?? a.name).length * 6.4 + 12)} style={{ fill: a.color }} />\n <text x={6} y={9} dominantBaseline=\"central\" style={{ fill: '#ffffff', fontSize: 11, fontWeight: 600, fontFamily: 'inherit' }}>\n {a.message ?? a.name}\n </text>\n </g>\n </g>\n ))}\n </g>\n );\n}\n\n/** A laid-out scene as an SVG (no interaction): for read-only views, streaming and exports. */\nexport function ChartSceneSvg({ scene, label, className }: { scene: ChartScene; label?: string; className?: string }) {\n return (\n <svg width={scene.width} height={scene.height} viewBox={`0 0 ${scene.width} ${scene.height}`} role=\"img\" aria-label={label} className={`block max-w-full ${className ?? ''}`}>\n {scene.marks.map((m) => renderChartMark(m, scene.theme.fontFamily, false))}\n </svg>\n );\n}\n\ninterface Frozen {\n valueDomain: ChartPointDrag['valueDomain'];\n valueDomain2: ChartPointDrag['valueDomain2'] | null;\n xDomain: ChartPointDrag['xDomain'] | null;\n readout: ChartPointDrag['target'];\n}\n\n/**\n * Draws a chart controller's spec as SVG. Click a mark to select it, drag a bar or point to\n * change its value (one undo step; Alt for fine steps, Shift to keep one axis on scatter\n * charts, Ctrl / ⌘ to skip snapping, Escape to cancel), and with the chart focused use\n * ← → ↑ ↓, Delete and Escape (see `handleChartKey`).\n */\nexport function ChartCanvas({ controller, width = 640, height = 400, responsive = true, theme, editable = true, measureText, emptyMessage, className, presence, sceneRef }: ChartCanvasProps) {\n const state = useChartState(controller);\n const wrapper = useRef<HTMLDivElement>(null);\n const svg = useRef<SVGSVGElement>(null);\n const drag = useRef<ChartPointDrag | null>(null);\n const [measured, setMeasured] = useState<number | null>(null);\n // Frozen while a point is dragged so the axes do not rescale under the pointer.\n const [frozen, setFrozen] = useState<Frozen | null>(null);\n\n useEffect(() => {\n const el = wrapper.current;\n if (!responsive || !el || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(([entry]) => {\n const w = Math.round(entry.contentRect.width);\n if (w > 0) setMeasured(w);\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, [responsive]);\n\n const sceneWidth = (responsive && measured) || width;\n const fullTheme = useMemo(() => ({ ...CSS_VARIABLE_CHART_THEME, ...theme }), [theme]);\n const scene = useMemo(\n () =>\n layoutChart(state.spec, {\n width: sceneWidth,\n height,\n theme: fullTheme,\n selection: editable ? state.selection : null,\n measureText,\n emptyMessage,\n valueDomain: frozen?.valueDomain,\n valueDomain2: frozen?.valueDomain2,\n xDomain: frozen?.xDomain,\n readout: frozen?.readout,\n }),\n [state.spec, state.selection, sceneWidth, height, fullTheme, editable, measureText, emptyMessage, frozen],\n );\n if (sceneRef) sceneRef.current = scene;\n const byKey = useMemo(() => new Map(scene.marks.map((m) => [m.key, m])), [scene]);\n\n useEffect(() => () => drag.current?.end(), []);\n\n const scenePoint = (e: React.PointerEvent) => chartClientToScene(scene, svg.current!.getBoundingClientRect(), e.clientX, e.clientY);\n\n const onPointerDown = (e: React.PointerEvent<SVGSVGElement>) => {\n if (!editable || e.button !== 0) return;\n const key = (e.target as Element).closest?.('[data-chart-key]')?.getAttribute('data-chart-key');\n const target = key ? byKey.get(key)?.target : undefined;\n controller.select(target ?? null);\n drag.current = startChartPointDrag(controller, scene, target, scenePoint(e));\n if (drag.current) {\n const d = drag.current;\n setFrozen({ valueDomain: d.valueDomain, valueDomain2: d.valueDomain2 ?? null, xDomain: d.xDomain ?? null, readout: d.target });\n svg.current?.setPointerCapture?.(e.pointerId);\n }\n };\n const onPointerMove = (e: React.PointerEvent<SVGSVGElement>) => {\n if (drag.current) drag.current.move(scenePoint(e), { fine: e.altKey, lockAxis: e.shiftKey, noSnap: e.ctrlKey || e.metaKey });\n };\n const endDrag = () => {\n drag.current?.end();\n drag.current = null;\n setFrozen(null);\n };\n const onKeyDown = (e: React.KeyboardEvent<SVGSVGElement>) => {\n if (drag.current && e.key === 'Escape') {\n drag.current.cancel();\n drag.current = null;\n setFrozen(null);\n e.preventDefault();\n return;\n }\n if (editable && handleChartKey(controller, scene, e)) e.preventDefault();\n };\n\n const label = state.spec.title || 'Chart';\n return (\n <div ref={wrapper} className={`w-full ${className ?? ''}`} data-chart-canvas=\"\">\n <svg\n ref={svg}\n width={sceneWidth}\n height={height}\n viewBox={`0 0 ${scene.width} ${scene.height}`}\n role=\"img\"\n aria-label={editable ? `${label}. ${describeChartSelection(controller, state.selection)}` : label}\n tabIndex={editable ? 0 : undefined}\n className=\"block max-w-full touch-none select-none rounded-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary\"\n onPointerDown={onPointerDown}\n onPointerMove={onPointerMove}\n onPointerUp={endDrag}\n onPointerCancel={endDrag}\n onKeyDown={onKeyDown}\n >\n {scene.marks.map((m) => renderChartMark(m, scene.theme.fontFamily, editable))}\n {presence && <ChartPresenceLayer presence={presence} />}\n </svg>\n </div>\n );\n}\n","import { useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\nimport type { ToolRegistry } from '@pixerate/editor/tools';\nimport {\n ChartController,\n ChartDirector,\n ChartPresence,\n createChartCommands,\n createChartRasterizer,\n createChartToolProvider,\n createOfficeChartToolProvider,\n type OfficeChartToolProviderOptions,\n layoutChart,\n type ChartScene,\n type ChartToolProviderOptions,\n type ChartActionResult,\n type ChartCommandOptions,\n type ChartControllerOptions,\n type ChartSelection,\n type ChartSpecPatch,\n type ChartState,\n type ChartType,\n} from '@pixerate/editor/chart';\n\n/** A `ChartController` created once for the component's lifetime. */\nexport function useChartController(options: ChartControllerOptions = {}): ChartController {\n const ref = useRef<ChartController | null>(null);\n if (!ref.current) ref.current = new ChartController(options);\n return ref.current;\n}\n\n/** The controller's state (re-renders on every change). */\nexport function useChartState(controller: ChartController): ChartState {\n return useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);\n}\n\nexport interface UseChartEditorResult {\n controller: ChartController;\n state: ChartState;\n spec: ChartState['spec'];\n selection: ChartSelection | null;\n update: (patch: ChartSpecPatch) => ChartActionResult;\n setType: (type: ChartType) => ChartActionResult;\n setValue: (seriesId: string, index: number, value: unknown) => ChartActionResult;\n select: (selection: ChartSelection | null) => void;\n undo: () => void;\n redo: () => void;\n}\n\n/**\n * Subscribes to a chart controller and exposes its state with bound actions. Pass options\n * instead of a controller to create one for the component's lifetime.\n */\nexport function useChartEditor(controllerOrOptions: ChartController | ChartControllerOptions = {}): UseChartEditorResult {\n const own = useRef<ChartController | null>(null);\n let controller: ChartController;\n if (controllerOrOptions instanceof ChartController) controller = controllerOrOptions;\n else {\n if (!own.current) own.current = new ChartController(controllerOrOptions);\n controller = own.current;\n }\n const state = useChartState(controller);\n const actions = useMemo(\n () => ({\n update: (patch: ChartSpecPatch) => controller.update(patch),\n setType: (type: ChartType) => controller.setType(type),\n setValue: (seriesId: string, index: number, value: unknown) => controller.setValue(seriesId, index, value),\n select: (selection: ChartSelection | null) => controller.select(selection),\n undo: () => void controller.undo(),\n redo: () => void controller.redo(),\n }),\n [controller],\n );\n return { controller, state, spec: state.spec, selection: state.selection, ...actions };\n}\n\n/** Anything with `register(specs) → unregister` (a `CommandRegistry`). */\nexport interface ChartCommandTarget {\n register(specs: any): () => void;\n}\n\n/**\n * Registers the controller's palette / agent commands (`chart.describe`, `chart.update`,\n * `chart.setValues`, …) in `registry` while mounted.\n */\nexport function useChartCommands(registry: ChartCommandTarget | null | undefined, controller: ChartController, options: ChartCommandOptions = {}): void {\n const { prefix, group, scope } = options;\n useEffect(() => {\n if (!registry) return;\n return registry.register(createChartCommands(controller, { prefix, group, scope }));\n }, [registry, controller, prefix, group, scope]);\n}\n\n/** `useChartToolProvider` options: `rasterize` defaults to a canvas rasterizer in the browser (`false` turns PNG off). */\nexport type ChartToolProviderHookOptions = Omit<ChartToolProviderOptions, 'rasterize'> & { rasterize?: ChartToolProviderOptions['rasterize'] | false };\n\n/**\n * Registers the chart's agent tools (`createChartToolProvider`) with a `ToolRegistry` while\n * mounted. Options are read when the controller or registry changes. In the browser,\n * `render_chart { format: \"png\" }` works out of the box (`createChartRasterizer`).\n */\nexport function useChartToolProvider(registry: ToolRegistry | null | undefined, controller: ChartController, options: ChartToolProviderHookOptions = {}): void {\n const latest = useRef(options);\n latest.current = options;\n const { id, namespace } = options;\n useEffect(() => {\n if (!registry) return;\n const { rasterize, ...rest } = latest.current;\n return registry.register(createChartToolProvider(controller, { ...rest, id, namespace, rasterize: rasterize === false ? undefined : (rasterize ?? createChartRasterizer()) }));\n }, [registry, controller, id, namespace]);\n}\n\n/**\n * Registers the Office-file chart tools (`createOfficeChartToolProvider`: `list_file_charts`,\n * `get_file_chart`, and `load_file_chart` with a `controller`) while mounted. `files` and\n * `readOnly` are read on every call, so they can change without re-registering.\n */\nexport function useOfficeChartToolProvider(registry: ToolRegistry | null | undefined, options: OfficeChartToolProviderOptions = {}): void {\n const latest = useRef(options);\n latest.current = options;\n const { id, namespace, controller } = options;\n const hasFiles = !!options.files;\n useEffect(() => {\n if (!registry) return;\n const current = latest.current;\n return registry.register(\n createOfficeChartToolProvider({\n ...current,\n id,\n namespace,\n controller,\n files: hasFiles ? () => latest.current.files?.() ?? [] : undefined,\n readOnly: () => {\n const r = latest.current.readOnly;\n return (typeof r === 'function' ? r() : r) ?? false;\n },\n }),\n );\n }, [registry, id, namespace, controller, hasFiles]);\n}\n\n/**\n * A `ChartPresence` and `ChartDirector` for a chart: pass `presence` and `sceneRef` to\n * `ChartCanvas`, and `director` to `useChartToolProvider` so agent edits are acted out with a\n * cursor.\n */\nexport function useChartDirector(controller: ChartController, options: { speed?: number; size?: { width: number; height: number } } = {}) {\n const sceneRef = useRef<ChartScene | null>(null);\n const ref = useRef<{ presence: ChartPresence; director: ChartDirector } | null>(null);\n if (!ref.current) {\n const presence = new ChartPresence();\n const size = options.size ?? { width: 640, height: 400 };\n const director = new ChartDirector(controller, presence, { scene: () => sceneRef.current ?? layoutChart(controller.getSpec(), size), speed: options.speed });\n ref.current = { presence, director };\n }\n return { ...ref.current, sceneRef };\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { chartColorInputValue, chartSeriesColor, formatChartNumber, type ChartController } from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\nimport { chartButtonClass, chartCellClass, chartIconButtonClass, chartInputClass } from './styles';\n\ntype CommitInputProps = {\n value: string;\n /** Called with the typed text. Return `false` to show the stored value again (a refused edit). */\n onCommit: (value: string) => boolean | void;\n} & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange' | 'defaultValue'>;\n\n/** A text box that commits on blur or Enter and resets on Escape. Follows `value` unless the user is typing. */\nexport function ChartCommitInput({ value, onCommit, onKeyDown, onBlur, ...rest }: CommitInputProps) {\n const [draft, setDraft] = useState(value);\n const typing = useRef(false);\n useEffect(() => {\n if (!typing.current) setDraft(value);\n }, [value]);\n const commit = () => {\n if (!typing.current) return;\n typing.current = false;\n if (draft === value) return;\n if (onCommit(draft) === false) setDraft(value);\n };\n return (\n <input\n {...rest}\n value={draft}\n onChange={(e) => {\n typing.current = true;\n setDraft(e.currentTarget.value);\n }}\n onBlur={(e) => {\n onBlur?.(e);\n commit();\n }}\n onKeyDown={(e) => {\n onKeyDown?.(e);\n if (e.defaultPrevented) return;\n if (e.key === 'Enter') {\n e.preventDefault();\n commit();\n } else if (e.key === 'Escape') {\n typing.current = false;\n setDraft(value);\n }\n }}\n />\n );\n}\n\nexport interface ChartDataGridProps {\n controller: ChartController;\n /** Header of the category column (default \"Category\"). */\n categoryHeader?: string;\n /** Hide the add / delete buttons. */\n readOnly?: boolean;\n className?: string;\n}\n\n/**\n * The chart's data as an editable grid: categories down the side, one column per series\n * (name, colour, show / hide, delete). Cells take numbers as people type them (`1,200`,\n * `12%`, blank for a gap); pasting TSV or CSV fills and grows the grid from the cell.\n */\nexport function ChartDataGrid({ controller, categoryHeader = 'Category', readOnly = false, className }: ChartDataGridProps) {\n const { spec, selection } = useChartState(controller);\n const paste = (row: number, column: number) => (e: React.ClipboardEvent<HTMLInputElement>) => {\n const text = e.clipboardData?.getData('text/plain') ?? '';\n if (!/[\\t\\n]/.test(text.replace(/\\n$/, ''))) return;\n e.preventDefault();\n controller.pasteCells(row, column, text);\n };\n return (\n <div className={`overflow-auto rounded-md border border-border ${className ?? ''}`} data-chart-grid=\"\">\n <table className=\"w-full border-collapse text-xs\">\n <thead className=\"bg-muted/50\">\n <tr>\n <th className=\"border-b border-r border-border px-2 py-1 text-left font-medium text-muted-foreground\">{categoryHeader}</th>\n {spec.series.map((s, si) => {\n const color = chartSeriesColor(spec, si);\n const selected = selection?.kind === 'series' && selection.seriesId === s.id;\n return (\n <th key={s.id} data-series-id={s.id} className={`border-b border-r border-border px-1 py-1 font-medium ${selected ? 'bg-primary/10' : ''}`}>\n <div className=\"flex items-center gap-1\">\n <input\n type=\"color\"\n aria-label={`${s.name} colour`}\n value={chartColorInputValue(color)}\n disabled={readOnly}\n onPointerDown={() => controller.beginGesture(`color:${s.id}`)}\n onChange={(e) => controller.updateSeries(s.id, { color: e.currentTarget.value })}\n onBlur={() => controller.endGesture()}\n className=\"h-5 w-5 shrink-0 cursor-pointer rounded border-0 bg-transparent p-0\"\n />\n <ChartCommitInput\n value={s.name}\n aria-label=\"Series name\"\n onFocus={() => controller.select({ kind: 'series', seriesId: s.id })}\n onCommit={(name) => void controller.updateSeries(s.id, { name })}\n className={`${chartInputClass} h-6 min-w-[5rem] border-transparent bg-transparent font-medium ${s.hidden ? 'text-muted-foreground line-through' : ''}`}\n />\n {!readOnly && (\n <>\n <button\n type=\"button\"\n className={chartIconButtonClass}\n title={s.hidden ? 'Show series' : 'Hide series'}\n aria-label={s.hidden ? `Show ${s.name}` : `Hide ${s.name}`}\n aria-pressed={!s.hidden}\n data-action=\"toggle-series\"\n onClick={() => controller.toggleSeries(s.id)}\n >\n {s.hidden ? '○' : '●'}\n </button>\n <button type=\"button\" className={chartIconButtonClass} title=\"Delete series\" aria-label={`Delete ${s.name}`} data-action=\"remove-series\" onClick={() => controller.removeSeries(s.id)}>\n ×\n </button>\n </>\n )}\n </div>\n </th>\n );\n })}\n {!readOnly && (\n <th className=\"w-8 border-b border-border px-1\">\n <button type=\"button\" className={chartIconButtonClass} title=\"Add series\" aria-label=\"Add series\" data-action=\"add-series\" onClick={() => controller.addSeries()}>\n +\n </button>\n </th>\n )}\n </tr>\n </thead>\n <tbody>\n {spec.categories.map((category, i) => {\n const rowSelected = selection?.kind === 'category' && selection.index === i;\n return (\n <tr key={i} data-category-index={i} className={rowSelected ? 'bg-primary/10' : undefined}>\n <th className=\"border-b border-r border-border p-0 text-left font-normal\">\n <ChartCommitInput\n value={category}\n aria-label={`Category ${i + 1}`}\n onFocus={() => controller.select({ kind: 'category', index: i })}\n onPaste={paste(i, -1)}\n onCommit={(label) => void controller.renameCategory(i, label)}\n className={`${chartCellClass} text-left`}\n />\n </th>\n {spec.series.map((s) => {\n const value = s.values[i];\n const selected = selection?.kind === 'point' && selection.seriesId === s.id && selection.index === i;\n return (\n <td key={s.id} className={`border-b border-r border-border p-0 ${selected ? 'bg-primary/10' : ''}`}>\n <ChartCommitInput\n value={value === null || value === undefined ? '' : String(value)}\n inputMode=\"decimal\"\n aria-label={`${s.name}, ${category}`}\n title={value === null ? undefined : formatChartNumber(value, spec.yAxis.format)}\n data-cell={`${s.id}:${i}`}\n onFocus={() => controller.select({ kind: 'point', seriesId: s.id, index: i })}\n onPaste={paste(i, spec.series.indexOf(s))}\n onCommit={(text) => controller.setValue(s.id, i, text).ok}\n className={chartCellClass}\n />\n </td>\n );\n })}\n {!readOnly && (\n <td className=\"border-b border-border px-1\">\n <button type=\"button\" className={chartIconButtonClass} title=\"Delete category\" aria-label={`Delete ${category}`} data-action=\"remove-category\" onClick={() => controller.removeCategory(i)}>\n ×\n </button>\n </td>\n )}\n </tr>\n );\n })}\n </tbody>\n </table>\n {!readOnly && (\n <div className=\"p-1\">\n <button type=\"button\" className={`${chartButtonClass} h-6 border-dashed`} data-action=\"add-category\" onClick={() => controller.addCategory()}>\n + Add category\n </button>\n </div>\n )}\n </div>\n );\n}\n","// Class names shared by the chart components (the same as the Svelte package's).\nexport const chartInputClass =\n 'h-7 w-full min-w-0 rounded-md border border-input bg-background px-2 text-xs text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:cursor-not-allowed disabled:opacity-50';\nexport const chartButtonClass =\n 'inline-flex h-7 items-center justify-center gap-1 rounded-md border border-input bg-background px-2 text-xs text-foreground hover:bg-muted focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-50';\nexport const chartIconButtonClass =\n 'inline-flex h-6 w-6 shrink-0 items-center justify-center rounded text-xs text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary disabled:pointer-events-none disabled:opacity-40';\nexport const chartSegmentClass = (active: boolean) =>\n `inline-flex h-7 flex-1 items-center justify-center rounded px-2 text-xs focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary ${\n active ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground'\n }`;\nexport const chartLabelClass = 'text-[11px] font-medium text-muted-foreground';\nexport const chartSectionClass = 'space-y-2 border-b border-border pb-3 last:border-b-0';\nexport const chartCellClass =\n 'h-7 w-full min-w-[4.5rem] bg-transparent px-2 text-right text-xs tabular-nums text-foreground focus-visible:bg-background focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-primary';\n","import React, { useId } from 'react';\nimport {\n CHART_COLOR_SCHEMES,\n CHART_ERROR_BAR_DIRECTIONS,\n CHART_ERROR_BAR_LABELS,\n CHART_ERROR_BAR_TYPES,\n CHART_LABEL_POSITIONS,\n CHART_LAYOUT_PRESETS,\n CHART_MARKERS,\n CHART_TRENDLINE_TYPES,\n checkChartColors,\n chartFamily,\n chartSupportsTrendlines,\n chartTrendlineName,\n CHART_CURVES,\n CHART_LEGEND_POSITIONS,\n CHART_NUMBER_STYLES,\n CHART_SERIES_TYPES,\n CHART_STACKINGS,\n CHART_TYPE_LABELS,\n CHART_TYPES,\n chartColorInputValue,\n chartErrorBarsOfType,\n chartSeriesColor,\n defaultChartErrorBarValue,\n formatChartAmountList,\n parseChartAmountList,\n chartSeriesType,\n isCartesianChart,\n type ChartAxis,\n type ChartController,\n type ChartErrorBars,\n type ChartErrorBarType,\n type ChartNumberFormat,\n type ChartSeries,\n} from '@pixerate/editor/chart';\nimport { useChartState } from './useChartEditor';\nimport { ChartCommitInput } from './ChartDataGrid';\nimport { chartButtonClass, chartInputClass, chartLabelClass, chartSectionClass, chartSegmentClass } from './styles';\n\nexport interface ChartInspectorProps {\n controller: ChartController;\n /** Which sections to show (default: all that apply to the chart). */\n sections?: readonly ChartInspectorSection[];\n className?: string;\n}\n\nexport type ChartInspectorSection = 'type' | 'style' | 'titles' | 'options' | 'legend' | 'axes' | 'series';\n\nconst cap = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);\n\nfunction Field({ label, htmlFor, children }: { label: string; htmlFor?: string; children: React.ReactNode }) {\n return (\n <div className=\"flex items-center gap-2\">\n <label htmlFor={htmlFor} className={`${chartLabelClass} w-20 shrink-0`}>\n {label}\n </label>\n <div className=\"min-w-0 flex-1\">{children}</div>\n </div>\n );\n}\n\nfunction Toggle({ label, checked, onChange, name }: { label: string; checked: boolean; onChange: (checked: boolean) => void; name: string }) {\n return (\n <label className=\"flex cursor-pointer items-center gap-2 text-xs text-foreground\">\n <input type=\"checkbox\" className=\"h-3.5 w-3.5 accent-primary\" checked={checked} data-option={name} onChange={(e) => onChange(e.currentTarget.checked)} />\n {label}\n </label>\n );\n}\n\nfunction Select<T extends string>({ id, value, options, onChange, name, labels }: { id?: string; value: T; options: readonly T[]; onChange: (value: T) => void; name: string; labels?: Partial<Record<T, string>> }) {\n return (\n <select id={id} className={chartInputClass} value={value} data-option={name} onChange={(e) => onChange(e.currentTarget.value as T)}>\n {options.map((o) => (\n <option key={o} value={o}>\n {labels?.[o] ?? cap(o)}\n </option>\n ))}\n </select>\n );\n}\n\nfunction AxisSection({ controller, axis, value, idBase, horizontal, numeric = false, scales = false }: { controller: ChartController; axis: 'x' | 'y' | 'y2'; value: ChartAxis; idBase: string; horizontal: boolean; numeric?: boolean; scales?: boolean }) {\n const set = (patch: Partial<ChartAxis>) => controller.setAxis(axis, patch);\n const setFormat = (patch: Partial<ChartNumberFormat>) => set({ format: { ...value.format, ...patch } });\n const bound = (key: 'min' | 'max') => (\n <ChartCommitInput\n id={`${idBase}-${axis}-${key}`}\n value={value[key] === null ? '' : String(value[key])}\n placeholder=\"Auto\"\n inputMode=\"decimal\"\n data-option={`${axis}Axis.${key}`}\n className={chartInputClass}\n onCommit={(text) => set({ [key]: text.trim() === '' ? null : Number(text) }).ok}\n />\n );\n const name = axis === 'x' ? (numeric ? 'X axis' : 'Category axis') : axis === 'y' ? 'Value axis' : 'Secondary axis';\n const valueAxis = axis !== 'x' || numeric;\n const key = axis === 'y2' ? 'yAxis2' : `${axis}Axis`;\n return (\n <div className={chartSectionClass} data-section={`axis-${axis}`}>\n <div className=\"flex items-center justify-between\">\n <h4 className=\"text-xs font-semibold text-foreground\">\n {name}\n <span className=\"ml-1 font-normal text-muted-foreground\">({axis === 'x' ? (horizontal ? 'left' : 'bottom') : axis === 'y2' ? (horizontal ? 'top' : 'right') : horizontal ? 'bottom' : 'left'})</span>\n </h4>\n <Toggle label=\"Show\" name={`${axis}Axis.show`} checked={value.show} onChange={(show) => set({ show })} />\n </div>\n <Field label=\"Title\" htmlFor={`${idBase}-${axis}-title`}>\n <ChartCommitInput id={`${idBase}-${axis}-title`} value={value.title} data-option={`${axis}Axis.title`} className={chartInputClass} onCommit={(title) => void set({ title })} />\n </Field>\n <div className=\"flex flex-wrap gap-x-4 gap-y-1\">\n <Toggle label=\"Grid lines\" name={`${key}.gridlines`} checked={value.gridlines} onChange={(gridlines) => set({ gridlines })} />\n {axis === 'x' && !numeric && <Toggle label=\"Dates\" name=\"xAxis.kind\" checked={value.kind === 'date'} onChange={(dates) => set({ kind: dates ? 'date' : undefined } as Partial<ChartAxis>)} />}\n {scales && <Toggle label=\"Reverse\" name={`${key}.reverse`} checked={!!value.reverse} onChange={(reverse) => set({ reverse })} />}\n {scales && valueAxis && <Toggle label=\"Log scale\" name={`${key}.scale`} checked={value.scale === 'log'} onChange={(log) => set({ scale: log ? 'log' : 'linear' })} />}\n </div>\n {scales && valueAxis && value.scale === 'log' && (\n <Field label=\"Log base\" htmlFor={`${idBase}-${axis}-log-base`}>\n <ChartCommitInput\n id={`${idBase}-${axis}-log-base`}\n value={String(value.logBase ?? 10)}\n inputMode=\"decimal\"\n data-option={`${key}.logBase`}\n className={chartInputClass}\n onCommit={(text) => set({ logBase: text.trim() === '' ? undefined : Number(text) }).ok}\n />\n </Field>\n )}\n {valueAxis && value.scale !== 'log' && (\n <Field label=\"Step\" htmlFor={`${idBase}-${axis}-step`}>\n <ChartCommitInput\n id={`${idBase}-${axis}-step`}\n value={value.step === null ? '' : String(value.step)}\n placeholder=\"Auto\"\n inputMode=\"decimal\"\n data-option={`${key}.step`}\n className={chartInputClass}\n onCommit={(text) => set({ step: text.trim() === '' ? null : Number(text) }).ok}\n />\n </Field>\n )}\n {valueAxis && (\n <>\n <Field label=\"Min / max\">\n <div className=\"flex gap-1\">\n {bound('min')}\n {bound('max')}\n </div>\n </Field>\n <Field label=\"Format\" htmlFor={`${idBase}-${axis}-format`}>\n <div className=\"flex gap-1\">\n <Select id={`${idBase}-${axis}-format`} name={`${key}.format.style`} value={value.format.style ?? 'number'} options={CHART_NUMBER_STYLES} onChange={(style) => setFormat({ style })} />\n <ChartCommitInput\n value={value.format.decimals === undefined ? '' : String(value.format.decimals)}\n placeholder=\"Auto\"\n aria-label=\"Decimals\"\n title=\"Decimals\"\n inputMode=\"numeric\"\n data-option={`${key}.format.decimals`}\n className={`${chartInputClass} w-14 shrink-0`}\n onCommit={(text) => {\n const format = { ...value.format };\n if (text.trim() === '') delete format.decimals;\n else format.decimals = Number(text);\n return set({ format }).ok;\n }}\n />\n </div>\n </Field>\n {value.format.style === 'currency' && (\n <Field label=\"Currency\" htmlFor={`${idBase}-${axis}-currency`}>\n <ChartCommitInput id={`${idBase}-${axis}-currency`} value={value.format.currency ?? 'USD'} data-option={`${key}.format.currency`} className={chartInputClass} onCommit={(currency) => void setFormat({ currency: currency.toUpperCase() })} />\n </Field>\n )}\n <Field label=\"Code\" htmlFor={`${idBase}-${axis}-code`}>\n <ChartCommitInput\n id={`${idBase}-${axis}-code`}\n value={value.format.code ?? ''}\n placeholder={'e.g. #,##0.0,,\"M\"'}\n data-option={`${key}.format.code`}\n className={chartInputClass}\n onCommit={(code) => {\n const format = { ...value.format };\n if (code.trim()) format.code = code.trim();\n else delete format.code;\n return set({ format }).ok;\n }}\n />\n </Field>\n </>\n )}\n </div>\n );\n}\n\n/** Error bar type, amount, direction and caps for one series (`which`: y or x error bars). */\nfunction ErrorBarFields({ controller, series, which, idBase }: { controller: ChartController; series: ChartSeries; which: 'errorBars' | 'xErrorBars'; idBase: string }) {\n const bars = series[which];\n const key = `series.${which}`;\n const id = `${idBase}-${which}`;\n const values = which === 'xErrorBars' ? (series.x ?? []) : series.values;\n const set = (next: ChartErrorBars | null) => controller.updateSeries(series.id, { [which]: next });\n const patch = (p: Partial<ChartErrorBars>) => bars && set({ ...bars, ...p });\n return (\n <div className=\"space-y-1.5\" data-section={which === 'errorBars' ? 'error-bars' : 'x-error-bars'}>\n <Field label={which === 'errorBars' ? 'Error bars' : 'X error bars'} htmlFor={`${id}-type`}>\n <select id={`${id}-type`} className={chartInputClass} value={bars?.type ?? ''} data-option={`${key}.type`} onChange={(e) => set(chartErrorBarsOfType(e.currentTarget.value as ChartErrorBarType | '', bars, values))}>\n <option value=\"\">None</option>\n {CHART_ERROR_BAR_TYPES.map((t) => (\n <option key={t} value={t}>\n {CHART_ERROR_BAR_LABELS[t]}\n </option>\n ))}\n </select>\n </Field>\n {bars && (bars.type === 'fixed' || bars.type === 'percent' || bars.type === 'stddev') && (\n <Field label={bars.type === 'percent' ? 'Percent' : bars.type === 'stddev' ? 'Deviations' : 'Amount'} htmlFor={`${id}-value`}>\n <ChartCommitInput id={`${id}-value`} value={String(bars.value ?? defaultChartErrorBarValue(bars.type))} inputMode=\"decimal\" data-option={`${key}.value`} className={chartInputClass} onCommit={(text) => !!patch({ value: text.trim() === '' ? undefined : Number(text) })?.ok} />\n </Field>\n )}\n {bars?.type === 'custom' && (\n <>\n <Field label=\"Plus\" htmlFor={`${id}-plus`}>\n <ChartCommitInput id={`${id}-plus`} value={formatChartAmountList(bars.plus)} placeholder=\"1, 2, -, 0.5\" data-option={`${key}.plus`} className={chartInputClass} onCommit={(text) => !!patch({ plus: parseChartAmountList(text) as ChartErrorBars['plus'] })?.ok} />\n </Field>\n <Field label=\"Minus\" htmlFor={`${id}-minus`}>\n <ChartCommitInput\n id={`${id}-minus`}\n value={formatChartAmountList(bars.minus)}\n placeholder=\"Same as plus\"\n data-option={`${key}.minus`}\n className={chartInputClass}\n onCommit={(text) => {\n const next = { ...bars };\n if (text.trim()) next.minus = parseChartAmountList(text) as ChartErrorBars['minus'];\n else delete next.minus;\n return set(next).ok;\n }}\n />\n </Field>\n </>\n )}\n {bars && (\n <div className=\"flex items-center gap-2\">\n <select className={`${chartInputClass} flex-1`} aria-label=\"Error bar direction\" value={bars.direction ?? 'both'} data-option={`${key}.direction`} onChange={(e) => patch({ direction: e.currentTarget.value as ChartErrorBars['direction'] })}>\n {CHART_ERROR_BAR_DIRECTIONS.map((d) => (\n <option key={d} value={d}>\n {d === 'both' ? 'Both ways' : d === 'plus' ? 'Plus only' : 'Minus only'}\n </option>\n ))}\n </select>\n <Toggle label=\"Caps\" name={`${key}.cap`} checked={bars.cap !== false} onChange={(cap) => patch({ cap })} />\n </div>\n )}\n </div>\n );\n}\n\n/**\n * Settings for a chart controller: type, titles, stacking and line options, legend, both\n * axes and the selected series. Every change is one undo step.\n */\nexport function ChartInspector({ controller, sections, className }: ChartInspectorProps) {\n const { spec, selectedSeries } = useChartState(controller);\n const idBase = useId();\n const show = (section: ChartInspectorSection) => !sections || sections.includes(section);\n const cartesian = isCartesianChart(spec.type);\n const family = chartFamily(spec);\n const hasAxes = family === 'cartesian' || family === 'xy' || family === 'waterfall' || family === 'histogram' || family === 'box';\n const types = spec.series.map((s) => chartSeriesType(spec, s));\n const usesSecondary = family === 'cartesian' && spec.series.some((s) => s.axis === 'secondary' && !s.hidden);\n const colorCheck = checkChartColors(spec.series.filter((s) => !s.hidden).map((s) => chartSeriesColor(spec, spec.series.indexOf(s))));\n const hasBars = cartesian && types.includes('bar');\n const hasLines = cartesian && types.some((t) => t === 'line' || t === 'area');\n const seriesIndex = selectedSeries ? spec.series.findIndex((s) => s.id === selectedSeries.id) : -1;\n // Log and reversed axes and error bars are drawn by the bar / line / area / scatter layouts.\n const scales = family === 'cartesian' || family === 'xy';\n\n return (\n <div className={`space-y-3 text-xs ${className ?? ''}`} data-chart-inspector=\"\">\n {show('type') && (\n <div className={chartSectionClass} data-section=\"type\">\n <div className=\"grid grid-cols-3 gap-0.5 rounded-md bg-muted p-0.5\" role=\"radiogroup\" aria-label=\"Chart type\">\n {CHART_TYPES.map((type) => (\n <button key={type} type=\"button\" role=\"radio\" aria-checked={spec.type === type} data-chart-type={type} className={chartSegmentClass(spec.type === type)} onClick={() => controller.setType(type)}>\n {CHART_TYPE_LABELS[type]}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {show('style') && (\n <div className={chartSectionClass} data-section=\"style\">\n <Field label=\"Layout\" htmlFor={`${idBase}-layout`}>\n <select id={`${idBase}-layout`} className={chartInputClass} value=\"\" data-option=\"preset.layout\" onChange={(e) => e.currentTarget.value && controller.applyPreset({ layout: e.currentTarget.value })}>\n <option value=\"\">Quick layout…</option>\n {CHART_LAYOUT_PRESETS.map((p) => (\n <option key={p.id} value={p.id} title={p.description}>\n {p.label}\n </option>\n ))}\n </select>\n </Field>\n <Field label=\"Colours\" htmlFor={`${idBase}-colors`}>\n <select id={`${idBase}-colors`} className={chartInputClass} value={CHART_COLOR_SCHEMES.find((c) => c.palette.join() === spec.palette.join())?.id ?? ''} data-option=\"preset.colors\" onChange={(e) => e.currentTarget.value && controller.applyPreset({ colors: e.currentTarget.value })}>\n <option value=\"\">Custom</option>\n {CHART_COLOR_SCHEMES.map((c) => (\n <option key={c.id} value={c.id} title={c.description}>\n {c.label}\n </option>\n ))}\n </select>\n </Field>\n {!colorCheck.ok && (\n <p className=\"text-[11px] leading-snug text-amber-600 dark:text-amber-400\" data-chart-color-warning=\"\">\n {colorCheck.issues[0]}\n </p>\n )}\n <button type=\"button\" className={chartButtonClass} data-action=\"transpose\" onClick={() => controller.transpose()}>\n Switch rows and columns\n </button>\n </div>\n )}\n\n {show('titles') && (\n <div className={chartSectionClass} data-section=\"titles\">\n <Field label=\"Title\" htmlFor={`${idBase}-title`}>\n <ChartCommitInput id={`${idBase}-title`} value={spec.title} data-option=\"title\" className={chartInputClass} onCommit={(title) => void controller.setTitle(title)} />\n </Field>\n <Field label=\"Subtitle\" htmlFor={`${idBase}-subtitle`}>\n <ChartCommitInput id={`${idBase}-subtitle`} value={spec.subtitle} data-option=\"subtitle\" className={chartInputClass} onCommit={(subtitle) => void controller.setSubtitle(subtitle)} />\n </Field>\n </div>\n )}\n\n {show('options') && (\n <div className={chartSectionClass} data-section=\"options\">\n {cartesian && (\n <Field label=\"Stacking\" htmlFor={`${idBase}-stacking`}>\n <Select id={`${idBase}-stacking`} name=\"stacking\" value={spec.stacking} options={CHART_STACKINGS} labels={{ none: 'None', stacked: 'Stacked', percent: '100%' }} onChange={(stacking) => controller.update({ stacking })} />\n </Field>\n )}\n {hasBars && (\n <Field label=\"Bars\">\n <div className=\"flex gap-0.5 rounded-md bg-muted p-0.5\">\n {(['vertical', 'horizontal'] as const).map((o) => (\n <button key={o} type=\"button\" aria-pressed={spec.orientation === o} data-option={`orientation.${o}`} className={chartSegmentClass(spec.orientation === o)} onClick={() => controller.update({ orientation: o })}>\n {cap(o)}\n </button>\n ))}\n </div>\n </Field>\n )}\n {hasLines && (\n <Field label=\"Lines\" htmlFor={`${idBase}-curve`}>\n <Select id={`${idBase}-curve`} name=\"curve\" value={spec.curve} options={CHART_CURVES} onChange={(curve) => controller.update({ curve })} />\n </Field>\n )}\n {spec.type === 'donut' && (\n <Field label=\"Hole\" htmlFor={`${idBase}-hole`}>\n <input\n id={`${idBase}-hole`}\n type=\"range\"\n min={0}\n max={0.9}\n step={0.05}\n value={spec.innerRadius}\n data-option=\"innerRadius\"\n className=\"w-full accent-primary\"\n onPointerDown={() => controller.beginGesture('innerRadius')}\n onPointerUp={() => controller.endGesture()}\n onChange={(e) => controller.update({ innerRadius: Number(e.currentTarget.value) })}\n />\n </Field>\n )}\n {hasBars && (\n <Field label=\"Spacing\" htmlFor={`${idBase}-gap`}>\n <input\n id={`${idBase}-gap`}\n type=\"range\"\n min={0}\n max={0.9}\n step={0.02}\n value={spec.gapWidth}\n data-option=\"gapWidth\"\n className=\"w-full accent-primary\"\n onPointerDown={() => controller.beginGesture('gapWidth')}\n onPointerUp={() => controller.endGesture()}\n onChange={(e) => controller.update({ gapWidth: Number(e.currentTarget.value) })}\n />\n </Field>\n )}\n {spec.dataLabels && hasBars && (\n <Field label=\"Labels\" htmlFor={`${idBase}-label-position`}>\n <Select id={`${idBase}-label-position`} name=\"labelPosition\" value={spec.labelPosition} options={CHART_LABEL_POSITIONS} onChange={(labelPosition) => controller.update({ labelPosition })} />\n </Field>\n )}\n {spec.type === 'histogram' && (\n <Field label=\"Bins\" htmlFor={`${idBase}-bins`}>\n <ChartCommitInput id={`${idBase}-bins`} value={spec.bins === null ? '' : String(spec.bins)} placeholder=\"Auto\" inputMode=\"numeric\" data-option=\"bins\" className={chartInputClass} onCommit={(text) => controller.update({ bins: text.trim() === '' ? null : Number(text) }).ok} />\n </Field>\n )}\n <div className=\"flex flex-wrap gap-x-4 gap-y-1\">\n {spec.type === 'waterfall' && <Toggle label=\"Total bar\" name=\"showTotal\" checked={spec.showTotal} onChange={(showTotal) => controller.update({ showTotal })} />}\n {hasLines && <Toggle label=\"Points\" name=\"points\" checked={spec.points} onChange={(points) => controller.update({ points })} />}\n <Toggle label=\"Data labels\" name=\"dataLabels\" checked={spec.dataLabels} onChange={(dataLabels) => controller.update({ dataLabels })} />\n </div>\n </div>\n )}\n\n {show('legend') && (\n <div className={chartSectionClass} data-section=\"legend\">\n <div className=\"flex items-center justify-between\">\n <h4 className=\"text-xs font-semibold text-foreground\">Legend</h4>\n <Toggle label=\"Show\" name=\"legend.show\" checked={spec.legend.show} onChange={(v) => controller.setLegend({ show: v })} />\n </div>\n {spec.legend.show && (\n <div className=\"flex gap-0.5 rounded-md bg-muted p-0.5\">\n {CHART_LEGEND_POSITIONS.map((p) => (\n <button key={p} type=\"button\" aria-pressed={spec.legend.position === p} data-option={`legend.${p}`} className={chartSegmentClass(spec.legend.position === p)} onClick={() => controller.setLegend({ position: p })}>\n {cap(p)}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n\n {show('axes') && hasAxes && (\n <>\n {family !== 'box' && family !== 'histogram' && <AxisSection controller={controller} axis=\"x\" value={spec.xAxis} idBase={idBase} horizontal={spec.orientation === 'horizontal'} numeric={family === 'xy'} scales={scales} />}\n <AxisSection controller={controller} axis=\"y\" value={spec.yAxis} idBase={idBase} horizontal={spec.orientation === 'horizontal'} scales={scales} />\n {usesSecondary && <AxisSection controller={controller} axis=\"y2\" value={spec.yAxis2} idBase={idBase} horizontal={spec.orientation === 'horizontal'} scales={scales} />}\n </>\n )}\n\n {show('series') && selectedSeries && (\n <div className={chartSectionClass} data-section=\"series\" data-series-id={selectedSeries.id}>\n <h4 className=\"text-xs font-semibold text-foreground\">Series</h4>\n <Field label=\"Name\" htmlFor={`${idBase}-series-name`}>\n <ChartCommitInput id={`${idBase}-series-name`} value={selectedSeries.name} data-option=\"series.name\" className={chartInputClass} onCommit={(name) => void controller.updateSeries(selectedSeries.id, { name })} />\n </Field>\n <Field label=\"Colour\" htmlFor={`${idBase}-series-color`}>\n <div className=\"flex items-center gap-1\">\n <input\n id={`${idBase}-series-color`}\n type=\"color\"\n value={chartColorInputValue(chartSeriesColor(spec, seriesIndex))}\n data-option=\"series.color\"\n className=\"h-7 w-9 shrink-0 cursor-pointer rounded border border-input bg-background p-0.5\"\n onPointerDown={() => controller.beginGesture(`color:${selectedSeries.id}`)}\n onBlur={() => controller.endGesture()}\n onChange={(e) => controller.updateSeries(selectedSeries.id, { color: e.currentTarget.value })}\n />\n {selectedSeries.color && (\n <button type=\"button\" className={chartButtonClass} data-action=\"reset-color\" onClick={() => controller.updateSeries(selectedSeries.id, { color: null })}>\n Palette\n </button>\n )}\n </div>\n </Field>\n {cartesian && (\n <Field label=\"Draw as\" htmlFor={`${idBase}-series-type`}>\n <select\n id={`${idBase}-series-type`}\n className={chartInputClass}\n value={selectedSeries.type ?? ''}\n data-option=\"series.type\"\n onChange={(e) => controller.updateSeries(selectedSeries.id, { type: (e.currentTarget.value || null) as any })}\n >\n <option value=\"\">Chart type</option>\n {CHART_SERIES_TYPES.map((t) => (\n <option key={t} value={t}>\n {CHART_TYPE_LABELS[t]}\n </option>\n ))}\n </select>\n </Field>\n )}\n {(cartesian || family === 'xy') && ['line', 'area', 'scatter'].includes(chartSeriesType(spec, selectedSeries)) && (\n <Field label=\"Marker\" htmlFor={`${idBase}-series-marker`}>\n <select\n id={`${idBase}-series-marker`}\n className={chartInputClass}\n value={selectedSeries.marker ?? ''}\n data-option=\"series.marker\"\n onChange={(e) => controller.updateSeries(selectedSeries.id, { marker: (e.currentTarget.value || null) as any })}\n >\n <option value=\"\">Default</option>\n {CHART_MARKERS.map((m) => (\n <option key={m} value={m}>\n {cap(m)}\n </option>\n ))}\n </select>\n </Field>\n )}\n {scales && <ErrorBarFields controller={controller} series={selectedSeries} which=\"errorBars\" idBase={idBase} />}\n {family === 'xy' && <ErrorBarFields controller={controller} series={selectedSeries} which=\"xErrorBars\" idBase={idBase} />}\n {chartSupportsTrendlines(spec.type, spec.stacking) && (\n <div className=\"space-y-1\" data-section=\"trendlines\">\n {(selectedSeries.trendlines ?? []).map((t, i) => (\n <div key={i} className=\"flex items-center gap-1\" data-trendline={i}>\n <span className=\"flex-1 truncate text-muted-foreground\">{chartTrendlineName(t, selectedSeries.name)}</span>\n <Toggle label=\"R²\" name={`trendline.${i}.showR2`} checked={!!t.showR2} onChange={(showR2) => controller.updateTrendline(selectedSeries.id, i, { showR2 })} />\n <button type=\"button\" className={chartButtonClass} aria-label=\"Delete trendline\" data-action=\"trendline-delete\" onClick={() => controller.removeTrendline(selectedSeries.id, i)}>\n ×\n </button>\n </div>\n ))}\n <select\n className={chartInputClass}\n value=\"\"\n aria-label=\"Add trendline\"\n data-option=\"trendline.add\"\n onChange={(e) => e.currentTarget.value && controller.addTrendline(selectedSeries.id, { type: e.currentTarget.value as any })}\n >\n <option value=\"\">Add trendline…</option>\n {CHART_TRENDLINE_TYPES.map((t) => (\n <option key={t} value={t}>\n {cap(t.replace('-', ' '))}\n </option>\n ))}\n </select>\n </div>\n )}\n <div className=\"flex flex-wrap items-center gap-1\">\n <Toggle label=\"Hidden\" name=\"series.hidden\" checked={!!selectedSeries.hidden} onChange={(hidden) => controller.updateSeries(selectedSeries.id, { hidden })} />\n {family === 'cartesian' && <Toggle label=\"Secondary axis\" name=\"series.axis\" checked={selectedSeries.axis === 'secondary'} onChange={(secondary) => controller.updateSeries(selectedSeries.id, { axis: secondary ? 'secondary' : null })} />}\n <span className=\"flex-1\" />\n <button type=\"button\" className={chartButtonClass} disabled={seriesIndex <= 0} aria-label=\"Move series earlier\" data-action=\"series-up\" onClick={() => controller.moveSeries(selectedSeries.id, seriesIndex - 1)}>\n ↑\n </button>\n <button type=\"button\" className={chartButtonClass} disabled={seriesIndex >= spec.series.length - 1} aria-label=\"Move series later\" data-action=\"series-down\" onClick={() => controller.moveSeries(selectedSeries.id, seriesIndex + 1)}>\n ↓\n </button>\n <button type=\"button\" className={`${chartButtonClass} text-destructive`} data-action=\"series-delete\" onClick={() => controller.removeSeries(selectedSeries.id)}>\n Delete\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["useEditor","import_react","StarterKit","Placeholder","import_react","import_editor","useEditor","useTipTapEditor","import_react","import_react","import_react","import_editor","import_react","import_editor","import_react","import_react","import_editor","import_react","import_react","import_react","import_react","import_jsx_runtime","TipTapEditorContent","import_react","import_react","import_editor","import_jsx_runtime","import_react","import_editor","import_jsx_runtime","import_react","import_react","import_editor","import_jsx_runtime","import_react","import_editor","import_editor","import_jsx_runtime","import_react","import_editor","import_react","import_jsx_runtime","import_editor","import_react","options","document","import_react","import_spreadsheet","import_react","import_spreadsheet","import_jsx_runtime","React","import_react","import_jsx_runtime","React","import_react","import_spreadsheet","import_react","import_jsx_runtime","button","import_react","import_spreadsheet","import_jsx_runtime","import_react","import_spreadsheet","import_react","import_spreadsheet","import_jsx_runtime","import_react","import_spreadsheet","import_jsx_runtime","import_jsx_runtime","import_react","import_spreadsheet","import_jsx_runtime","import_react","import_jsx_runtime","import_react","options","import_react","import_image_editor","import_image_editor","import_jsx_runtime","import_react","import_image_editor","import_jsx_runtime","import_react","import_image_editor","import_react","import_image_editor","import_jsx_runtime","import_jsx_runtime","import_react","import_react","import_image_editor","import_jsx_runtime","import_image_editor","import_jsx_runtime","import_react","import_image_editor","import_react","import_react","import_jsx_runtime","import_react","import_effects","import_jsx_runtime","import_react","import_effects","import_parameters","import_react","import_jsx_runtime","_","import_jsx_runtime","React","import_jsx_runtime","React","import_react","import_image_editor","import_image_editor","import_react","import_jsx_runtime","button","import_jsx_runtime","import_jsx_runtime","import_react","import_image_editor","import_jsx_runtime","chip","select","import_react","import_image_editor","import_jsx_runtime","btn","import_react","import_image_editor","import_jsx_runtime","button","import_react","import_image_editor","import_jsx_runtime","chip","import_react","import_image_editor","import_jsx_runtime","chip","import_react","import_image_editor","import_jsx_runtime","chip","import_jsx_runtime","currentImgPt","React","import_react","import_editor","import_react","import_editor","import_jsx_runtime","buttonClass","import_jsx_runtime","buttonClass","import_jsx_runtime","import_react","import_editor","import_editor","import_jsx_runtime","buttonClass","import_react","import_commands","import_react","import_jsx_runtime","React","import_react","import_react","import_persistence","import_jsx_runtime","import_react","import_react","import_generation","import_jsx_runtime","inputClass","import_jsx_runtime","import_react","import_generation","import_jsx_runtime","chip","import_react","import_generation","import_jsx_runtime","import_react","import_editor","noopUnsubscribe","import_react","import_editor","import_jsx_runtime","inputClass","buttonClass","import_react","import_editor","import_react","import_editor","import_jsx_runtime","keepSelection","React","import_react","import_jsx_runtime","keepSelection","import_editor","import_jsx_runtime","import_react","import_chart","import_react","import_jsx_runtime","import_react","import_chart","import_jsx_runtime","import_react","import_chart","import_jsx_runtime","key","cap","import_jsx_runtime"]}
|