quoin-editor 0.4.0 → 0.4.1

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/canvas/BlockCanvas.tsx","../src/context.tsx","../src/registry.ts","../src/blocks/core.ts","../src/blocks/MarkdownBlockEditor.tsx","../src/upload/FilePickerButton.tsx","../src/ui/button.tsx","../src/ui/cn.ts","../src/ui/touch-target.ts","../src/markdown/edit.ts","../src/markdown/line-at.ts","../src/markdown/insert-command.ts","../src/markdown/shortcut-label.ts","../src/ui/dialog.tsx","../src/markdown/ShortcutsReference.tsx","../src/markdown/SlashPalette.tsx","../src/markdown/commands.ts","../src/ui/command.tsx","../src/ui/popover.tsx","../src/markdown/useMarkdownKeymap.ts","../src/markdown/list-continuation.ts","../src/markdown/indent-list.ts","../src/markdown/line-toggles.ts","../src/markdown/slash-trigger.ts","../src/markdown/wrap-selection.ts","../src/markdown/useSlashPalette.ts","../src/markdown/caret-coordinates.ts","../src/hooks/useAutoGrow.ts","../src/blocks/str.ts","../src/ui/select.tsx","../src/ui/textarea.tsx","../src/blocks/CalloutBlockEditor.tsx","../src/ui/input.tsx","../src/blocks/CodeBlockEditor.tsx","../src/blocks/ImageBlockEditor.tsx","../src/upload/UploadField.tsx","../src/blocks/intrinsic-size.ts","../src/blocks/FileBlockEditor.tsx","../src/blocks/previews.tsx","../src/hooks/useBlockList.ts","../src/hooks/new-block-id.ts","../src/canvas/announcements.ts","../src/canvas/BlockActionsMenu.tsx","../src/ui/dropdown-menu.tsx","../src/canvas/BlockCard.tsx","../src/canvas/BlockEditor.tsx","../src/canvas/source-offset.ts","../src/dev-warn.ts","../src/canvas/BlockInserter.tsx","../src/canvas/DocumentStarter.tsx","../src/canvas/ReadOnlyCanvas.tsx","../src/canvas/reorder-indices.ts","../src/canvas/same-blocks.ts","../src/canvas/SortableBlock.tsx","../src/canvas/unacknowledged.ts","../src/hooks/useAutosave.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport {\n DndContext,\n KeyboardSensor,\n PointerSensor,\n closestCenter,\n useSensor,\n useSensors,\n type DragEndEvent,\n} from '@dnd-kit/core';\nimport { restrictToVerticalAxis } from '@dnd-kit/modifiers';\nimport { SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy } from '@dnd-kit/sortable';\nimport { QuoinProvider } from '../context';\nimport { blockByType, type AnyBlockDefinition } from '../registry';\nimport { coreBlocks } from '../blocks/core';\nimport type { QuoinBlock, UploadFn } from '../types';\nimport { useBlockList } from '../hooks/useBlockList';\nimport { cn } from '../ui/cn';\nimport { buildAnnouncements } from './announcements';\nimport { BlockActionsMenu } from './BlockActionsMenu';\nimport { BlockCard } from './BlockCard';\nimport { BlockInserter } from './BlockInserter';\nimport { DocumentStarter } from './DocumentStarter';\nimport { ReadOnlyCanvas } from './ReadOnlyCanvas';\nimport { reorderIndices } from './reorder-indices';\nimport { sameBlocks } from './same-blocks';\nimport { SortableBlock } from './SortableBlock';\nimport { remember } from './unacknowledged';\n\n/** Props for `BlockCanvas`; `blocks` and `onChange` are the whole document contract. */\nexport type BlockCanvasProps = {\n /**\n * The document. Update it synchronously from `onChange`, as with a controlled `<input value onChange>`.\n * Applying the edit late is tolerated as long as what comes back is one of the arrays the canvas emitted:\n * it recognises its own output even several keystrokes behind, so a transition or a debounced setter is safe.\n * A store that rebuilds the document on the way through hands back a structural copy instead, which arrives\n * behind the canvas's own state and reads as a foreign document. That does not revert the edit cleanly: the\n * characters the copy predates are dropped and the ones typed after them are kept.\n * A new array that differs from the last one you supplied replaces what the canvas shows, which is how a host\n * loads, undoes or merges. An array structurally equal to the last one you supplied is ignored, so a \"discard\n * changes\" button that hands back the original document does nothing; remount the canvas with a React `key` to\n * force a reset. The comparison is shallow over each block's `data`: a host whose block `data` holds nested\n * objects rebuilt on every render, and which does not echo `onChange` back, can still lose an edit. The core\n * block types all have flat data, so this only affects custom blocks.\n */\n blocks: QuoinBlock[];\n onChange: (blocks: QuoinBlock[]) => void;\n /**\n * Called when a block is removed through its actions menu, with the block and the index it held.\n * It runs just after the `onChange` that reports the document without it, so a host acting on the\n * deletion is already looking at the new array. Restore the block by supplying a `blocks` array\n * with it spliced back at that index, the same way any other document arrives.\n *\n * Restore it on a later tick or a later interaction, such as the click of an Undo toast. A\n * restore applied synchronously inside this callback batches with the echo of the deletion, so\n * what arrives is structurally equal to the document last supplied and is ignored.\n */\n onDelete?: (block: QuoinBlock, index: number) => void;\n /** Defaults to the five core block types. Pass `[...coreBlocks, yours]` to extend them. */\n blockTypes?: AnyBlockDefinition[];\n upload?: UploadFn;\n resolveAssetUrl?: (storageKey: string) => string;\n onError?: (error: Error) => void;\n /** Renders the document with no inserters, menus, drag handles or editors. */\n readOnly?: boolean;\n /** Added to the root element's own classes rather than replacing them. */\n className?: string;\n id?: string;\n /** Names the document for assistive technology; the root then becomes a labelled group. */\n 'aria-label'?: string;\n};\n\ntype Selection = { start: number; end: number };\n\nfunction Canvas({\n blocks,\n onChange,\n onDelete,\n blockTypes,\n readOnly,\n className,\n id,\n 'aria-label': ariaLabel,\n}: Pick<\n BlockCanvasProps,\n 'blocks' | 'onChange' | 'onDelete' | 'readOnly' | 'className' | 'id' | 'aria-label'\n> & {\n blockTypes: AnyBlockDefinition[];\n}) {\n const list = useBlockList(blocks);\n const { insertAt, update, remove, move, reorder, reset } = list;\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 4 } }),\n useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),\n );\n const dndId = React.useId();\n const [newBlockId, setNewBlockId] = React.useState<string | null>(null);\n const [seedSelection, setSeedSelection] = React.useState<Selection | null>(null);\n const listRef = React.useRef<HTMLDivElement>(null);\n const pendingDeleteIndexRef = React.useRef<number | null>(null);\n const removedRef = React.useRef<{ block: QuoinBlock; index: number } | null>(null);\n const announcements = React.useMemo(\n () => buildAnnouncements(list.blocks, blockTypes),\n [list.blocks, blockTypes],\n );\n\n // The reducer reads `blocks` once, so the two effects below carry the document\n // across the boundary in both directions. An array this canvas emitted is\n // recognised when the host hands it back and is not reset; an array the host\n // supplies is foreign and is. Seeding the refs with the first `blocks` keeps\n // mounting from reporting a change nobody made.\n const lastEmitted = React.useRef<QuoinBlock[]>(blocks);\n const lastSupplied = React.useRef<QuoinBlock[]>(blocks);\n // Every emission still waiting to come back, not just the newest: a host that applies\n // edits late hands back an array from several keystrokes ago, and recognising only the\n // newest would read that as a foreign document and overwrite live text with it.\n const unacknowledged = React.useRef<Set<QuoinBlock[]>>(new Set());\n\n React.useEffect(() => {\n if (list.blocks === lastEmitted.current) return;\n lastEmitted.current = list.blocks;\n remember(unacknowledged.current, list.blocks);\n onChange(list.blocks);\n const removed = removedRef.current;\n removedRef.current = null;\n if (removed) onDelete?.(removed.block, removed.index);\n }, [list.blocks, onChange, onDelete]);\n\n React.useEffect(() => {\n const previous = lastSupplied.current;\n lastSupplied.current = blocks;\n if (unacknowledged.current.has(blocks)) {\n // Caught up: anything older than this emission has been echoed or coalesced away.\n // Everything before then is forgotten, so a host replaying one of these arrays from\n // its own undo stack later is a document the canvas accepts rather than ignores.\n if (blocks === lastEmitted.current) unacknowledged.current.clear();\n return;\n }\n // A host that builds a fresh array on every render, without echoing edits, would\n // otherwise wipe them on any unrelated re-render. An undo replays a different array.\n // The cost of the `previous` half is that a restore applied synchronously inside\n // `onDelete` batches with the echo, arrives structurally equal to the last document\n // supplied, and is read as one of those re-renders. That is why `onDelete` documents\n // restoring on a later tick. Dropping this comparison to accept the synchronous case\n // would hand back the edit-wiping bug, which is the worse of the two.\n if (sameBlocks(blocks, previous) || sameBlocks(blocks, list.blocks)) return;\n unacknowledged.current.clear();\n lastEmitted.current = blocks;\n reset(blocks);\n }, [blocks, reset]);\n\n const insertPlain = React.useCallback(\n (index: number, type: string, data?: Record<string, unknown>) => {\n setSeedSelection(null);\n const seed = data ?? blockByType(blockTypes, type)?.initialData?.() ?? {};\n setNewBlockId(insertAt(index, type, seed));\n },\n [insertAt, blockTypes],\n );\n\n function handleDelete(index: number, id: string) {\n const block = list.blocks[index];\n pendingDeleteIndexRef.current = index;\n if (block) removedRef.current = { block, index };\n // Otherwise a block inserted, deleted and then restored by the host would come\n // back in edit mode and take the focus from whatever the person is doing.\n setNewBlockId((current) => (current === id ? null : current));\n remove(id);\n }\n\n React.useEffect(() => {\n const index = pendingDeleteIndexRef.current;\n pendingDeleteIndexRef.current = null;\n if (index === null || !listRef.current) return;\n const landingIndex = Math.min(index, list.blocks.length - 1);\n const card =\n landingIndex >= 0 ? listRef.current.querySelector<HTMLElement>(`[data-block-index=\"${landingIndex}\"]`) : null;\n (card?.querySelector<HTMLElement>('button') ?? listRef.current.querySelector<HTMLElement>('button'))?.focus();\n }, [list.blocks]);\n\n function handleDragEnd(event: DragEndEvent) {\n const { active, over } = event;\n const result = reorderIndices(\n list.blocks.map((b) => b.id),\n String(active.id),\n over ? String(over.id) : null,\n );\n if (result) reorder(result.from, result.to);\n }\n\n const rootProps = {\n ref: listRef,\n id,\n className: cn('quoin flex flex-col', className),\n role: ariaLabel ? 'group' : undefined,\n 'aria-label': ariaLabel,\n };\n\n if (readOnly) return <ReadOnlyCanvas blocks={list.blocks} onUpdate={update} root={rootProps} />;\n\n return (\n <div {...rootProps}>\n <BlockInserter index={0} onInsert={insertPlain} label=\"Insert a block at the start\" />\n <DndContext\n id={dndId}\n sensors={sensors}\n collisionDetection={closestCenter}\n modifiers={[restrictToVerticalAxis]}\n accessibility={{ announcements }}\n onDragEnd={handleDragEnd}\n >\n <SortableContext items={list.blocks.map((b) => b.id)} strategy={verticalListSortingStrategy}>\n <ul className=\"flex flex-col\">\n {list.blocks.map((b, i) => (\n <li key={b.id}>\n <SortableBlock\n id={b.id}\n index={i}\n actions={\n <BlockActionsMenu\n index={i}\n count={list.blocks.length}\n label={blockByType(blockTypes, b.type)?.label ?? b.type}\n onMove={move}\n onDelete={() => handleDelete(i, b.id)}\n />\n }\n >\n <BlockCard\n block={b}\n index={i}\n editingByDefault={b.id === newBlockId}\n initialSelection={b.id === newBlockId ? seedSelection : null}\n onUpdate={update}\n onInsertBlock={insertPlain}\n />\n </SortableBlock>\n <BlockInserter\n index={i + 1}\n onInsert={insertPlain}\n label={`Insert a block after block ${i + 1}`}\n />\n </li>\n ))}\n </ul>\n </SortableContext>\n </DndContext>\n <DocumentStarter\n autoFocus={list.blocks.length === 0}\n onStart={(markdown, selection) => {\n setSeedSelection(selection ?? null);\n setNewBlockId(insertAt(list.blocks.length, 'MARKDOWN', { markdown }));\n }}\n onInsertBlock={(type) => insertPlain(list.blocks.length, type)}\n />\n </div>\n );\n}\n\n/** The editor: renders `blocks`, reports every edit through `onChange`, and accepts a new `blocks` array from outside at any time. */\nexport function BlockCanvas({\n blocks,\n onChange,\n onDelete,\n blockTypes = coreBlocks,\n upload,\n resolveAssetUrl,\n onError,\n readOnly = false,\n className,\n id,\n 'aria-label': ariaLabel,\n}: BlockCanvasProps) {\n const config = React.useMemo(\n () => ({ blockTypes, upload, resolveAssetUrl, onError }),\n [blockTypes, upload, resolveAssetUrl, onError],\n );\n return (\n <QuoinProvider value={config}>\n <Canvas\n blocks={blocks}\n onChange={onChange}\n onDelete={onDelete}\n blockTypes={blockTypes}\n readOnly={readOnly}\n className={className}\n id={id}\n aria-label={ariaLabel}\n />\n </QuoinProvider>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport type { AnyBlockDefinition } from './registry';\nimport type { UploadFn } from './types';\n\n/** The resolved canvas configuration every block editor reads through `useQuoin`. */\nexport type QuoinConfig = {\n blockTypes: AnyBlockDefinition[];\n /** Absent when the host has not wired uploads; upload fields then render disabled. */\n upload?: UploadFn;\n resolveAssetUrl: (storageKey: string) => string;\n onError: (error: Error) => void;\n};\n\n/** What a host passes to `QuoinProvider`: only the block types are required. */\nexport type QuoinConfigInput = Partial<QuoinConfig> & {\n blockTypes: AnyBlockDefinition[];\n};\n\nconst QuoinContext = React.createContext<QuoinConfig | null>(null);\n\n/** Supplies the block registry and the host couplings (upload, asset URLs, error reporting) to every block below it. */\nexport function QuoinProvider({\n value,\n children,\n}: {\n value: QuoinConfigInput;\n children: React.ReactNode;\n}) {\n const { blockTypes, upload, resolveAssetUrl, onError } = value;\n const config = React.useMemo<QuoinConfig>(\n () => ({\n blockTypes,\n upload,\n // Identity default: an empty key resolves to an empty string, which stays falsy\n // wherever a resolved URL is tested for \"no asset chosen yet\".\n resolveAssetUrl: resolveAssetUrl ?? ((key: string) => key),\n onError: onError ?? ((error: Error) => console.error(error)),\n }),\n [blockTypes, upload, resolveAssetUrl, onError],\n );\n return <QuoinContext.Provider value={config}>{children}</QuoinContext.Provider>;\n}\n\n/** Reads the canvas configuration. Throws outside a QuoinProvider rather than returning a silent default. */\nexport function useQuoin(): QuoinConfig {\n const config = React.useContext(QuoinContext);\n if (!config) throw new Error('useQuoin must be used inside a QuoinProvider.');\n return config;\n}\n","import type { ComponentType } from 'react';\nimport type { LucideIcon } from 'lucide-react';\nimport type { BlockEditorProps, BlockPreviewProps } from './types';\n\n/** The fields every block definition carries, whatever it can do with its data. */\ntype BlockDefinitionCommon<D extends object> = {\n type: string;\n label: string;\n icon: LucideIcon;\n /**\n * Called when a new block of this type is inserted, to seed its data.\n * `NoInfer` keeps `D` inferred from `editor` and `preview` alone, so the seed is checked\n * against the editor's data type instead of widening it.\n */\n initialData?: () => NoInfer<D>;\n /** Whether the block is offered in the slash palette and inserter; defaults to true. */\n inSlashPalette?: boolean;\n /**\n * Renders this block's editor permanently instead of a preview you click to edit.\n * Also supply a `preview`: a read-only canvas draws the preview rather than the editor,\n * so without one the block's content is invisible there.\n */\n alwaysEditing?: boolean;\n};\n\n/**\n * Describes one block type: how to label it, how to draw it at rest, how to edit it.\n *\n * Supply `editor`, `preview`, or both, and the canvas does the rest. A definition with no\n * `preview` is edit-only: a read-only canvas has nothing to draw for it but its label.\n * A definition with no `editor` can never be edited in the canvas, which is what a block\n * whose content belongs to a server-side record wants; the card offers no edit affordance\n * for it and a click goes through to whatever the preview itself renders.\n *\n * Omitting both is a type error, because such a block would only ever draw its own label.\n */\nexport type BlockDefinition<D extends object = Record<string, unknown>> =\n | (BlockDefinitionCommon<D> & {\n editor: ComponentType<BlockEditorProps<D>>;\n /**\n * What the block shows when it is not being edited. Optional so a host can register an\n * edit-only block type, and overridable so a host can supply rich rendering (a full\n * markdown pipeline, a chart) without Quoin depending on one.\n */\n preview?: ComponentType<BlockPreviewProps<D>>;\n })\n | (BlockDefinitionCommon<D> & {\n /** Omitted: this block is never editable in the canvas. */\n editor?: undefined;\n /** Required here, because it is the only thing that can draw the block. */\n preview: ComponentType<BlockPreviewProps<D>>;\n });\n\n/** A definition with its data type erased, so definitions of different shapes compose in one array. */\nexport type AnyBlockDefinition = BlockDefinition<Record<string, unknown>>;\n\n/**\n * Types `data` inside your editor component, then erases the generic on the way out.\n * The erasure is deliberate: `D` appears in both covariant and contravariant positions\n * on `editor`, so without it an array of differently-shaped definitions will not typecheck.\n * `initialData` is checked against the editor's data type. That relies on `NoInfer`, so\n * TypeScript 5.4 or later is required.\n *\n * `D` defaults to `Record<string, unknown>`, so a definition whose components take no\n * annotation still gets a usable `data` rather than a bare `object`.\n */\nexport function defineBlock<D extends object = Record<string, unknown>>(\n definition: BlockDefinition<D>,\n): AnyBlockDefinition {\n return definition as unknown as AnyBlockDefinition;\n}\n\n/** The definition for a type, or undefined; the last registration of a type wins, so a host can override a core block. */\nexport function blockByType(\n definitions: AnyBlockDefinition[],\n type: string,\n): AnyBlockDefinition | undefined {\n for (let i = definitions.length - 1; i >= 0; i -= 1) {\n if (definitions[i].type === type) return definitions[i];\n }\n return undefined;\n}\n\n/** The definitions offered in the slash palette, in registration order, one per type, with the last registration of a type winning. */\nexport function paletteBlocks(definitions: AnyBlockDefinition[]): AnyBlockDefinition[] {\n const seen = new Set<string>();\n const out: AnyBlockDefinition[] = [];\n for (let i = definitions.length - 1; i >= 0; i -= 1) {\n const d = definitions[i];\n if (seen.has(d.type)) continue;\n // Claim the type BEFORE honouring the opt-out, so a hidden override suppresses the\n // definition it replaces instead of letting the earlier one reappear. Without this,\n // the palette can offer a block that `blockByType` resolves to a different definition.\n seen.add(d.type);\n if (d.inSlashPalette === false) continue;\n out.push(d);\n }\n return out.reverse();\n}\n","import { Code, FileText, MessageSquare, Image, Paperclip } from 'lucide-react';\nimport { defineBlock, type AnyBlockDefinition } from '../registry';\nimport { MarkdownBlockEditor } from './MarkdownBlockEditor';\nimport { CalloutBlockEditor } from './CalloutBlockEditor';\nimport { CodeBlockEditor } from './CodeBlockEditor';\nimport { ImageBlockEditor } from './ImageBlockEditor';\nimport { FileBlockEditor } from './FileBlockEditor';\nimport {\n MarkdownPreview,\n CalloutPreview,\n CodePreview,\n ImagePreview,\n FilePreview,\n} from './previews';\n\n/** The block types Quoin ships with. Spread them alongside your own definitions. */\nexport const coreBlocks: AnyBlockDefinition[] = [\n defineBlock({\n type: 'MARKDOWN',\n label: 'Markdown',\n icon: FileText,\n editor: MarkdownBlockEditor,\n preview: MarkdownPreview,\n initialData: () => ({ markdown: '' }),\n }),\n defineBlock({\n type: 'CALLOUT',\n label: 'Callout',\n icon: MessageSquare,\n editor: CalloutBlockEditor,\n preview: CalloutPreview,\n initialData: () => ({ tone: 'info', body: '' }),\n }),\n defineBlock({\n type: 'CODE',\n label: 'Code',\n icon: Code,\n editor: CodeBlockEditor,\n preview: CodePreview,\n initialData: () => ({ language: '', code: '' }),\n }),\n defineBlock({\n type: 'IMAGE',\n label: 'Image',\n icon: Image,\n editor: ImageBlockEditor,\n preview: ImagePreview,\n initialData: () => ({ storageKey: '', alt: '' }),\n }),\n defineBlock({\n type: 'FILE',\n label: 'File',\n icon: Paperclip,\n editor: FileBlockEditor,\n preview: FilePreview,\n initialData: () => ({ storageKey: '', filename: '' }),\n }),\n];\n","'use client';\n\nimport * as React from 'react';\nimport { useQuoin } from '../context';\nimport { FilePickerButton } from '../upload/FilePickerButton';\nimport { applyEdit } from '../markdown/edit';\nimport { insertCommand } from '../markdown/insert-command';\nimport { ShortcutsReference } from '../markdown/ShortcutsReference';\nimport { SlashPalette } from '../markdown/SlashPalette';\nimport { useMarkdownKeymap } from '../markdown/useMarkdownKeymap';\nimport { useSlashPalette } from '../markdown/useSlashPalette';\nimport type { TextCommand } from '../markdown/commands';\nimport { useAutoGrow } from '../hooks/useAutoGrow';\nimport type { BlockEditorProps } from '../types';\nimport { str } from './str';\n\nconst BOX = [\n '-mx-2 min-h-7 w-[calc(100%+1rem)] resize-none rounded-md border-0 bg-transparent px-2 py-0',\n 'text-base leading-7 outline-none placeholder:text-muted-foreground',\n 'transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:ring-ring/50',\n].join(' ');\n\nexport function MarkdownBlockEditor({ data, onChange, onInsertBlock, onDone }: BlockEditorProps) {\n const { onError } = useQuoin();\n const markdown = str(data.markdown);\n const ref = useAutoGrow<HTMLTextAreaElement>(markdown);\n const palette = useSlashPalette(ref);\n const [shortcutsOpen, setShortcutsOpen] = React.useState(false);\n\n const set = (patch: Record<string, unknown>) => onChange({ ...data, ...patch });\n // The keymap memoises its handlers on this, so a fresh closure every render would\n // rebuild them on every render too, including the ones a palette or dialog causes.\n const commit = React.useCallback(\n (next: string) => onChange({ ...data, markdown: next }),\n [data, onChange],\n );\n\n const keymap = useMarkdownKeymap({ commit, onOpenPalette: palette.openAtCaret });\n\n function reopenBox(): HTMLTextAreaElement | null {\n const el = ref.current;\n el?.focus({ preventScroll: true });\n return el ?? null;\n }\n\n function runTextCommand(command: TextCommand) {\n palette.setOpen(false);\n const el = reopenBox();\n if (!el) return;\n applyEdit(el, insertCommand(command, el.value, palette.offsetRef.current), commit);\n }\n\n function writeLiteralSlash() {\n palette.setOpen(false);\n const el = reopenBox();\n if (!el) return;\n const at = palette.offsetRef.current;\n applyEdit(\n el,\n { value: `${el.value.slice(0, at)}/${el.value.slice(at)}`, selectionStart: at + 1, selectionEnd: at + 1 },\n commit,\n );\n }\n\n function readMarkdownFile(file: File) {\n const reader = new FileReader();\n reader.onload = () => {\n const text = typeof reader.result === 'string' ? reader.result : '';\n if (text.trim() === '') {\n onError(new Error(`${file.name} is empty.`));\n return;\n }\n set({ markdown: text });\n onDone?.();\n };\n reader.onerror = () => onError(new Error(`Could not read ${file.name}.`));\n reader.readAsText(file);\n }\n\n return (\n <div className=\"relative flex flex-col gap-3\">\n <textarea\n ref={ref}\n aria-label=\"Markdown\"\n value={markdown}\n rows={1}\n placeholder=\"Write, or press / for commands\"\n onChange={(e) => set({ markdown: e.target.value })}\n onKeyDown={keymap.onKeyDown}\n onPaste={keymap.onPaste}\n className={BOX}\n />\n <SlashPalette\n open={palette.open}\n caret={palette.caret}\n onOpenChange={palette.setOpen}\n onTextCommand={runTextCommand}\n onBlockCommand={(type) => {\n palette.setOpen(false);\n onInsertBlock?.(type);\n }}\n onShortcuts={() => {\n palette.setOpen(false);\n setShortcutsOpen(true);\n }}\n onDismiss={writeLiteralSlash}\n />\n <ShortcutsReference open={shortcutsOpen} onOpenChange={setShortcutsOpen} />\n {markdown.trim() === '' && (\n <FilePickerButton\n label=\"Upload .md\"\n accept=\".md,text/markdown,text/plain\"\n onPick={readMarkdownFile}\n />\n )}\n </div>\n );\n}\n","'use client';\n\nimport { Upload } from 'lucide-react';\nimport { Button } from '../ui/button';\n\n/** Props for `FilePickerButton`. */\nexport type FilePickerButtonProps = {\n /** Labels the button and the file input behind it. */\n label: string;\n /** An `accept` attribute for the file input, such as `'image/*'` or `'.pdf'`. */\n accept?: string;\n /** Greys the button out and disables the input behind it. */\n disabled?: boolean;\n /** Called with the chosen file, and again if the same file is picked after a failure. */\n onPick: (file: File) => void;\n};\n\n/** A button that opens the file picker and hands back the chosen file, performing no upload of its own. */\n// The input itself stays focusable and labelled, laid transparently over the\n// button, so the keyboard and the pointer both land on the real control. The\n// wrapper paints the focus ring the invisible input cannot show.\nexport function FilePickerButton({ label, accept, disabled, onPick }: FilePickerButtonProps) {\n return (\n <span className=\"relative inline-flex rounded-md has-[:focus-visible]:ring-[3px] has-[:focus-visible]:ring-ring/50\">\n <Button asChild variant=\"outline\" size=\"sm\">\n <span aria-hidden=\"true\" className={disabled ? 'pointer-events-none opacity-50' : undefined}>\n <Upload aria-hidden=\"true\" />\n {label}\n </span>\n </Button>\n <input\n type=\"file\"\n accept={accept}\n aria-label={label}\n disabled={disabled}\n className=\"absolute inset-0 cursor-pointer opacity-0 disabled:cursor-not-allowed\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n // Clear so picking the same file again still fires `change`, which is what makes retry after a failed upload work.\n e.target.value = '';\n if (file) onPick(file);\n }}\n />\n </span>\n );\n}\n","import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"./cn\";\nimport { SQUARE_TAP_TARGET_FLOOR, TAP_TARGET_FLOOR } from \"./touch-target\";\n\n/** Class variants for the button primitive, reusable on other elements. */\nconst buttonVariants = cva(\n \"inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,background-color,border-color,box-shadow,opacity] disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 shrink-0 outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50\",\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white shadow-xs hover:bg-destructive/90 dark:bg-destructive/60 dark:hover:bg-destructive/75\",\n outline:\n \"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: `h-9 px-4 py-2 has-[>svg]:px-3 ${TAP_TARGET_FLOOR}`,\n xs: `h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3 ${TAP_TARGET_FLOOR}`,\n sm: `h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5 ${TAP_TARGET_FLOOR}`,\n lg: `h-10 rounded-md px-6 has-[>svg]:px-4 ${TAP_TARGET_FLOOR}`,\n icon: `size-9 ${SQUARE_TAP_TARGET_FLOOR}`,\n \"icon-xs\": `size-6 rounded-md [&_svg:not([class*='size-'])]:size-3 ${SQUARE_TAP_TARGET_FLOOR}`,\n \"icon-sm\": `size-8 ${SQUARE_TAP_TARGET_FLOOR}`,\n \"icon-lg\": `size-10 ${SQUARE_TAP_TARGET_FLOOR}`,\n },\n },\n defaultVariants: { variant: \"default\", size: \"default\" },\n },\n);\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/** Merges class names, with later Tailwind utilities overriding earlier conflicting ones. */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","/** 44px is the platform minimum for a finger. It is applied as a floor rather than\n * a height so a control keeps its own pointer-precise size, and only where the\n * primary pointer is coarse so mouse-driven layouts keep their density. */\nexport const TAP_TARGET_FLOOR = 'pointer-coarse:min-h-11';\n\n/** The pointer-coarse sizing floor on both axes, for square icon controls. */\nexport const SQUARE_TAP_TARGET_FLOOR = `${TAP_TARGET_FLOOR} pointer-coarse:min-w-11`;\n\n/** For an icon control pinned to a corner, where growing the box would drag the icon\n * inward. The target is a centred, transparent pseudo-element instead, so the hit\n * area reaches 44px while the icon keeps its own size and position. Requires the\n * control to be positioned, which a pinned one already is. */\nexport const ICON_TAP_TARGET_FLOOR = [\n \"pointer-coarse:before:absolute pointer-coarse:before:top-1/2 pointer-coarse:before:left-1/2\",\n 'pointer-coarse:before:size-11 pointer-coarse:before:-translate-x-1/2 pointer-coarse:before:-translate-y-1/2',\n \"pointer-coarse:before:content-['']\",\n].join(' ');\n","/** A text transform result: the next value and where the selection should land. */\nexport type Edit = { value: string; selectionStart: number; selectionEnd: number };\n\nfunction changedSpan(before: string, after: string) {\n let start = 0;\n const shortest = Math.min(before.length, after.length);\n while (start < shortest && before[start] === after[start]) start += 1;\n\n let endBefore = before.length;\n let endAfter = after.length;\n while (endBefore > start && endAfter > start && before[endBefore - 1] === after[endAfter - 1]) {\n endBefore -= 1;\n endAfter -= 1;\n }\n\n return { start, endBefore, replacement: after.slice(start, endAfter) };\n}\n\n// Writing through execCommand keeps the transform as one entry on the browser's\n// own undo stack. Either path commits el.value rather than the edit's intended\n// value: a browser is trusted to write what it was asked, and if it ever\n// wrote something else, committing our own intent instead would silently\n// diverge React's state from the DOM.\nfunction writeNatively(el: HTMLTextAreaElement, replacement: string): boolean {\n if (typeof document.execCommand !== 'function') return false;\n try {\n return replacement === ''\n ? document.execCommand('delete')\n : document.execCommand('insertText', false, replacement);\n } catch {\n return false;\n }\n}\n\n/** Applies an edit to a textarea through the native undo stack when the browser allows it, so Ctrl+Z still works. */\nexport function applyEdit(\n el: HTMLTextAreaElement,\n edit: Edit,\n commit: (value: string) => void,\n): void {\n if (el.value !== edit.value) {\n const { start, endBefore, replacement } = changedSpan(el.value, edit.value);\n el.setSelectionRange(start, endBefore);\n if (!writeNatively(el, replacement)) {\n el.value = edit.value;\n }\n commit(el.value);\n }\n el.setSelectionRange(edit.selectionStart, edit.selectionEnd);\n}\n","const FENCE = /^ {0,3}(```|~~~)/;\n\nexport type Line = { start: number; end: number; text: string };\n\n/** The line containing the offset, with its start and end offsets and its text (no trailing newline). */\nexport function lineAt(value: string, offset: number): Line {\n const start = value.lastIndexOf('\\n', offset - 1) + 1;\n const next = value.indexOf('\\n', offset);\n const end = next === -1 ? value.length : next;\n return { start, end, text: value.slice(start, end) };\n}\n\nexport function isFenceDelimiter(text: string): boolean {\n return FENCE.test(text);\n}\n\nexport function insideFence(value: string, offset: number): boolean {\n const lines = value.slice(0, offset).split('\\n');\n if (isFenceDelimiter(lines[lines.length - 1])) return true;\n\n let open = false;\n for (let i = 0; i < lines.length - 1; i += 1) {\n if (isFenceDelimiter(lines[i])) open = !open;\n }\n return open;\n}\n","import type { Edit } from './edit';\nimport { lineAt } from './line-at';\n\n/** The fields `insertCommand` needs. `TextCommand` satisfies this structurally. */\nexport type InsertableCommand = {\n insert: string;\n caretOffset: number;\n selectLength?: number;\n separate: boolean;\n};\n\n/** Inserts a command's markdown at the caret, starting a new line (or a blank line if it asks) when the caret is mid-line. */\nexport function insertCommand(command: InsertableCommand, value: string, caret: number): Edit {\n const line = lineAt(value, caret);\n const before = value.slice(line.start, caret).replace(/[ \\t]+$/, '');\n const cut = line.start + before.length;\n const prefix = before.trim() === '' ? '' : command.separate ? '\\n\\n' : '\\n';\n const at = cut + prefix.length + command.caretOffset;\n\n return {\n value: value.slice(0, cut) + prefix + command.insert + value.slice(caret),\n selectionStart: at,\n selectionEnd: at + (command.selectLength ?? 0),\n };\n}\n","const MAC_LABEL: Record<string, string> = { mod: '⌘', alt: '⌥', shift: '⇧' };\nconst OTHER_LABEL: Record<string, string> = { mod: 'Ctrl', alt: 'Alt', shift: 'Shift' };\n\nfunction onMac(): boolean {\n if (typeof navigator === 'undefined') return false;\n return /Mac|iPhone|iPad/.test(navigator.userAgent);\n}\n\n/** Renders a \"mod+shift+b\" style hint as the platform's own label, such as ⌘⇧B on a Mac and Ctrl+Shift+B elsewhere. */\nexport function formatShortcut(hint: string): string {\n const mac = onMac();\n const labels = mac ? MAC_LABEL : OTHER_LABEL;\n const parts = hint.split('+').map((part) => labels[part] ?? part.toUpperCase());\n return parts.join(mac ? '' : '+');\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { XIcon } from \"lucide-react\";\nimport { cn } from \"./cn\";\nimport { ICON_TAP_TARGET_FLOOR } from \"./touch-target\";\n\nfunction Dialog(props: React.ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />;\n}\n\nfunction DialogTrigger(\n props: React.ComponentProps<typeof DialogPrimitive.Trigger>,\n) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nfunction DialogPortal(\n props: React.ComponentProps<typeof DialogPrimitive.Portal>,\n) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\nfunction DialogClose(\n props: React.ComponentProps<typeof DialogPrimitive.Close>,\n) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n \"quoin fixed inset-0 z-50 bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content>) {\n return (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n \"quoin bg-popover fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className,\n )}\n {...props}\n >\n {children}\n <DialogPrimitive.Close\n className={cn(\n \"ring-offset-background focus:ring-ring absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-none\",\n ICON_TAP_TARGET_FLOOR,\n )}\n >\n <XIcon />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n );\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-lg leading-none font-semibold\", className)}\n {...props}\n />\n );\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n};\n","'use client';\n\nimport { formatShortcut } from './shortcut-label';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '../ui/dialog';\n\nconst ROWS: Array<{ label: string; keys: string }> = [\n { label: 'Open the command palette', keys: '/' },\n { label: 'Bold', keys: formatShortcut('mod+b') },\n { label: 'Italic', keys: formatShortcut('mod+i') },\n { label: 'Inline code', keys: formatShortcut('mod+e') },\n { label: 'Link', keys: formatShortcut('mod+k') },\n { label: 'Heading', keys: formatShortcut('mod+alt+1') },\n { label: 'Subtitle', keys: formatShortcut('mod+alt+2') },\n { label: 'Sub-subtitle', keys: formatShortcut('mod+alt+3') },\n { label: 'Bullet list', keys: formatShortcut('mod+shift+8') },\n { label: 'Numbered list', keys: formatShortcut('mod+shift+7') },\n { label: 'Continue a list, or leave it when the item is empty', keys: 'Enter' },\n { label: 'Indent item', keys: 'Tab' },\n { label: 'Outdent item', keys: formatShortcut('shift') + '+Tab' },\n];\n\nexport function ShortcutsReference({\n open,\n onOpenChange,\n}: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}) {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>Keyboard shortcuts</DialogTitle>\n <DialogDescription>Formatting without leaving the keyboard.</DialogDescription>\n </DialogHeader>\n <dl className=\"grid grid-cols-[1fr_auto] gap-x-4 gap-y-2 text-sm\">\n {ROWS.map((row) => (\n <div key={row.label} className=\"col-span-2 grid grid-cols-subgrid items-baseline\">\n <dt className=\"text-muted-foreground\">{row.label}</dt>\n <dd>\n <kbd className=\"rounded border bg-muted px-1.5 py-0.5 font-mono text-xs\">{row.keys}</kbd>\n </dd>\n </div>\n ))}\n </dl>\n </DialogContent>\n </Dialog>\n );\n}\n","'use client';\n\nimport { Keyboard } from 'lucide-react';\nimport { useQuoin } from '../context';\nimport { paletteBlocks } from '../registry';\nimport type { CaretRect } from './caret-coordinates';\nimport { TEXT_COMMANDS, type TextCommand } from './commands';\nimport { formatShortcut } from './shortcut-label';\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandShortcut,\n} from '../ui/command';\nimport { Popover, PopoverAnchor, PopoverContent } from '../ui/popover';\n\nexport function SlashPalette({\n open,\n caret,\n onOpenChange,\n onTextCommand,\n onBlockCommand,\n onShortcuts,\n onDismiss,\n}: {\n open: boolean;\n caret: CaretRect | null;\n onOpenChange: (open: boolean) => void;\n onTextCommand: (command: TextCommand) => void;\n onBlockCommand: (type: string) => void;\n onShortcuts: () => void;\n onDismiss: () => void;\n}) {\n const { blockTypes } = useQuoin();\n const blockOptions = paletteBlocks(blockTypes);\n return (\n <Popover open={open} onOpenChange={onOpenChange}>\n <PopoverAnchor asChild>\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute\"\n style={caret ? { top: caret.top, left: caret.left, height: caret.height } : { top: 0, left: 0 }}\n />\n </PopoverAnchor>\n <PopoverContent\n aria-label=\"Command palette\"\n align=\"start\"\n side=\"bottom\"\n sideOffset={4}\n className=\"w-72 p-0\"\n onEscapeKeyDown={(event) => {\n event.preventDefault();\n onDismiss();\n }}\n // Radix restores focus to the trigger on close, and this palette has an\n // aria-hidden anchor that cannot hold it, so the restore would drop focus\n // to the body. Both callers refocus the textarea before applying the edit.\n onCloseAutoFocus={(event) => event.preventDefault()}\n >\n <Command label=\"Search commands\">\n <CommandInput placeholder=\"Search commands\" />\n <CommandList>\n <CommandEmpty>No command found.</CommandEmpty>\n <CommandGroup heading=\"Text\">\n {TEXT_COMMANDS.map((command) => (\n <CommandItem\n key={command.id}\n value={`${command.label} ${command.keywords.join(' ')}`}\n onSelect={() => onTextCommand(command)}\n >\n <command.icon aria-hidden=\"true\" />\n <span>{command.label}</span>\n {command.hint ? <CommandShortcut>{formatShortcut(command.hint)}</CommandShortcut> : null}\n </CommandItem>\n ))}\n </CommandGroup>\n <CommandGroup heading=\"Blocks\">\n {blockOptions.map((option) => (\n <CommandItem key={option.type} value={option.label} onSelect={() => onBlockCommand(option.type)}>\n <option.icon aria-hidden=\"true\" />\n <span>{option.label}</span>\n </CommandItem>\n ))}\n </CommandGroup>\n <CommandGroup>\n <CommandItem value=\"keyboard shortcuts help\" onSelect={onShortcuts}>\n <Keyboard aria-hidden=\"true\" />\n <span>Keyboard shortcuts</span>\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n );\n}\n","import {\n Code,\n Heading1,\n Heading2,\n Heading3,\n List,\n ListOrdered,\n ListTodo,\n Minus,\n Quote,\n Table,\n type LucideIcon,\n} from 'lucide-react';\n\n/** A slash-palette entry: how it is shown and searched, and the markdown it inserts. */\nexport type TextCommand = {\n id: string;\n label: string;\n keywords: string[];\n icon: LucideIcon;\n hint?: string;\n insert: string;\n caretOffset: number;\n selectLength?: number;\n /** Needs a blank line above it: a divider after a paragraph line parses as a\n * setext heading, and a GFM table cannot interrupt a paragraph at all. */\n separate: boolean;\n};\n\nconst TABLE = ['| Column | Column |', '| --- | --- |', '| | |'].join('\\n');\n\n/** The built-in slash-palette commands, in display order. */\nexport const TEXT_COMMANDS: TextCommand[] = [\n {\n id: 'heading',\n label: 'Heading',\n keywords: ['h1', 'title', 'heading', 'big'],\n icon: Heading1,\n hint: 'mod+alt+1',\n insert: '# ',\n caretOffset: 2,\n separate: false,\n },\n {\n id: 'subtitle',\n label: 'Subtitle',\n keywords: ['h2', 'subtitle', 'section', 'subheading'],\n icon: Heading2,\n hint: 'mod+alt+2',\n insert: '## ',\n caretOffset: 3,\n separate: false,\n },\n {\n id: 'subsubtitle',\n label: 'Sub-subtitle',\n keywords: ['h3', 'subsubtitle', 'minor'],\n icon: Heading3,\n hint: 'mod+alt+3',\n insert: '### ',\n caretOffset: 4,\n separate: false,\n },\n {\n id: 'bullet',\n label: 'Bullet list',\n keywords: ['bullet', 'unordered', 'ul', 'list', 'point'],\n icon: List,\n hint: 'mod+shift+8',\n insert: '- ',\n caretOffset: 2,\n separate: false,\n },\n {\n id: 'numbered',\n label: 'Numbered list',\n keywords: ['numbered', 'ordered', 'ol', 'steps'],\n icon: ListOrdered,\n hint: 'mod+shift+7',\n insert: '1. ',\n caretOffset: 3,\n separate: false,\n },\n {\n id: 'task',\n label: 'Task list',\n keywords: ['task', 'todo', 'checkbox', 'checklist'],\n icon: ListTodo,\n insert: '- [ ] ',\n caretOffset: 6,\n separate: false,\n },\n {\n id: 'quote',\n label: 'Quote',\n keywords: ['quote', 'blockquote', 'citation'],\n icon: Quote,\n insert: '> ',\n caretOffset: 2,\n separate: false,\n },\n {\n id: 'code',\n label: 'Code block',\n keywords: ['code', 'snippet', 'fence', 'pre'],\n icon: Code,\n insert: '```\\n\\n```',\n caretOffset: 3,\n separate: true,\n },\n {\n id: 'divider',\n label: 'Divider',\n keywords: ['divider', 'rule', 'hr', 'separator', 'break'],\n icon: Minus,\n insert: '---\\n',\n caretOffset: 4,\n separate: true,\n },\n {\n id: 'table',\n label: 'Table',\n keywords: ['table', 'grid', 'rows', 'columns'],\n icon: Table,\n insert: TABLE,\n caretOffset: 2,\n selectLength: 6,\n separate: true,\n },\n];\n","\"use client\"\n\nimport * as React from \"react\"\nimport { Command as CommandPrimitive } from \"cmdk\"\nimport { SearchIcon } from \"lucide-react\"\n\nimport { cn } from \"./cn\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"./dialog\"\n\nfunction Command({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n return (\n <CommandPrimitive\n data-slot=\"command\"\n className={cn(\n \"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandDialog({\n title = \"Command Palette\",\n description = \"Search for a command to run...\",\n children,\n className,\n ...props\n}: React.ComponentProps<typeof Dialog> & {\n title?: string\n description?: string\n className?: string\n}) {\n return (\n <Dialog {...props}>\n <DialogHeader className=\"sr-only\">\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n <DialogContent className={cn(\"overflow-hidden p-0\", className)}>\n <Command className=\"**:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n {children}\n </Command>\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction CommandInput({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n return (\n <div\n data-slot=\"command-input-wrapper\"\n className=\"flex h-9 items-center gap-2 border-b px-3\"\n >\n <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n <CommandPrimitive.Input\n data-slot=\"command-input\"\n className={cn(\n \"flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n />\n </div>\n )\n}\n\nfunction CommandList({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n return (\n <CommandPrimitive.List\n data-slot=\"command-list\"\n className={cn(\n \"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandEmpty({\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n return (\n <CommandPrimitive.Empty\n data-slot=\"command-empty\"\n className=\"py-6 text-center text-sm\"\n {...props}\n />\n )\n}\n\nfunction CommandGroup({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return (\n <CommandPrimitive.Group\n data-slot=\"command-group\"\n className={cn(\n \"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n return (\n <CommandPrimitive.Separator\n data-slot=\"command-separator\"\n className={cn(\"-mx-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction CommandItem({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return (\n <CommandPrimitive.Item\n data-slot=\"command-item\"\n className={cn(\n \"relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"command-shortcut\"\n className={cn(\n \"ml-auto text-xs tracking-widest text-muted-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n}\n","import * as React from \"react\";\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport { cn } from \"./cn\";\n\nfunction Popover(props: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />;\n}\nfunction PopoverTrigger(props: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />;\n}\nfunction PopoverAnchor(props: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {\n return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />;\n}\nfunction PopoverContent({ className, align = \"center\", sideOffset = 4, ...props }: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n data-slot=\"popover-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"quoin bg-popover text-popover-foreground z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden\",\n className,\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n );\n}\nexport { Popover, PopoverAnchor, PopoverTrigger, PopoverContent };\n","import * as React from 'react';\nimport { applyEdit, type Edit } from './edit';\nimport { indentList } from './indent-list';\nimport { toggleLinePrefix, type LinePrefix } from './line-toggles';\nimport { continueList } from './list-continuation';\nimport { shouldOpenPalette } from './slash-trigger';\nimport { linkPaste, wrapSelection, type WrapKind } from './wrap-selection';\n\nconst WRAP: Record<string, WrapKind> = { b: 'bold', i: 'italic', e: 'code', k: 'link' };\n\n// Shift turns the 8 key into \"*\", so the physical code is the only stable match.\nconst HEADING: Record<string, LinePrefix> = { Digit1: 'h1', Digit2: 'h2', Digit3: 'h3' };\nconst LIST: Record<string, LinePrefix> = { Digit7: 'ordered', Digit8: 'bullet' };\n\n/** Keyboard and paste handlers that give a plain textarea markdown shortcuts, list continuation, Tab indent and the slash palette trigger. */\nexport function useMarkdownKeymap({\n commit,\n onOpenPalette,\n}: {\n commit: (markdown: string) => void;\n onOpenPalette: () => void;\n}) {\n const onKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n const el = event.currentTarget;\n const { value, selectionStart, selectionEnd } = el;\n const mod = event.metaKey || event.ctrlKey;\n\n const run = (edit: Edit | null) => {\n if (!edit) return;\n event.preventDefault();\n applyEdit(el, edit, commit);\n };\n\n if (mod && event.altKey) {\n const kind = HEADING[event.code];\n if (kind) run(toggleLinePrefix(kind, value, selectionStart, selectionEnd));\n return;\n }\n\n if (mod && event.shiftKey) {\n const kind = LIST[event.code];\n if (kind) run(toggleLinePrefix(kind, value, selectionStart, selectionEnd));\n return;\n }\n\n if (mod) {\n const kind = WRAP[event.key.toLowerCase()];\n if (kind) run(wrapSelection(kind, value, selectionStart, selectionEnd));\n return;\n }\n\n if (event.key === '/') {\n if (!shouldOpenPalette(value, selectionStart, selectionEnd)) return;\n event.preventDefault();\n onOpenPalette();\n return;\n }\n\n if (event.key === 'Enter' && !event.shiftKey) {\n run(continueList(value, selectionStart, 'Enter'));\n return;\n }\n\n if (event.key === 'Backspace' && selectionStart === selectionEnd) {\n run(continueList(value, selectionStart, 'Backspace'));\n return;\n }\n\n if (event.key === 'Tab') {\n run(indentList(value, selectionStart, selectionEnd, event.shiftKey ? -1 : 1));\n }\n },\n [commit, onOpenPalette],\n );\n\n const onPaste = React.useCallback(\n (event: React.ClipboardEvent<HTMLTextAreaElement>) => {\n const el = event.currentTarget;\n const edit = linkPaste(\n el.value,\n el.selectionStart,\n el.selectionEnd,\n event.clipboardData.getData('text/plain'),\n );\n if (!edit) return;\n event.preventDefault();\n applyEdit(el, edit, commit);\n },\n [commit],\n );\n\n return { onKeyDown, onPaste };\n}\n","import type { Edit } from './edit';\nimport { insideFence, lineAt, type Line } from './line-at';\n\nexport const LIST_MARKER = /^(\\s*)((?:[-*+] \\[[ xX]\\] )|(?:[-*+] )|(?:\\d+[.)] )|(?:> ))(.*)$/;\n\nconst INDENT = ' ';\n\nfunction nextMarker(marker: string): string {\n const ordered = /^(\\d+)([.)] )$/.exec(marker);\n if (ordered) return `${Number(ordered[1]) + 1}${ordered[2]}`;\n const task = /^([-*+]) \\[[ xX]\\] $/.exec(marker);\n if (task) return `${task[1]} [ ] `;\n return marker;\n}\n\n// Both the dead item on Enter and the caret at the content start on Backspace\n// mean the same thing: climb out one level, or drop the marker at the top.\nfunction climbOut(value: string, line: Line, indent: string, marker: string, content: string): Edit {\n const outdent = indent.length >= INDENT.length;\n\n if (outdent) {\n const text = indent.slice(INDENT.length) + marker + content;\n const at = line.start + indent.length - INDENT.length + marker.length;\n return {\n value: value.slice(0, line.start) + text + value.slice(line.end),\n selectionStart: at,\n selectionEnd: at,\n };\n }\n\n // A stripped marker with only a single newline above it reads to CommonMark\n // as a lazy continuation of the previous list item's paragraph, not a new\n // block, so a blank line is needed whenever that previous line is a list item.\n const leavesList = line.start > 0 && LIST_MARKER.test(lineAt(value, line.start - 1).text);\n const text = leavesList ? `\\n${content}` : content;\n const at = leavesList ? line.start + 1 : line.start;\n\n return {\n value: value.slice(0, line.start) + text + value.slice(line.end),\n selectionStart: at,\n selectionEnd: at,\n };\n}\n\n/** Continues a list item on Enter, or climbs out of the list on an empty item or Backspace at the marker; returns null when the caret is not in a list item or is inside a code fence, so the default key behaviour runs. */\nexport function continueList(\n value: string,\n caret: number,\n key: 'Enter' | 'Backspace',\n): Edit | null {\n if (insideFence(value, caret)) return null;\n\n const line = lineAt(value, caret);\n const match = LIST_MARKER.exec(line.text);\n if (!match) return null;\n\n const [, indent, marker, content] = match;\n\n if (key === 'Backspace') {\n if (caret !== line.start + indent.length + marker.length) return null;\n return climbOut(value, line, indent, marker, content);\n }\n\n if (content.trim() === '') return climbOut(value, line, indent, marker, content);\n\n const inserted = `\\n${indent}${nextMarker(marker)}`;\n const at = caret + inserted.length;\n return {\n value: value.slice(0, caret) + inserted + value.slice(caret),\n selectionStart: at,\n selectionEnd: at,\n };\n}\n","import type { Edit } from './edit';\nimport { insideFence, lineAt } from './line-at';\nimport { LIST_MARKER } from './list-continuation';\n\nconst INDENT = ' ';\n\nfunction indentOf(text: string): number {\n return /^\\s*/.exec(text)?.[0].length ?? 0;\n}\n\n// Indenting more than one level past the line above turns a list item into an\n// indented code block, so the first line of the range is capped against it.\nfunction shift(text: string, direction: 1 | -1, cap: number | undefined): string {\n const current = indentOf(text);\n if (direction === -1) return text.slice(Math.min(current, INDENT.length));\n if (cap !== undefined && current >= cap + INDENT.length) return text;\n return INDENT + text;\n}\n\n/** Indents or outdents the selected list items; returns null when the selection is not entirely list items, is inside a code fence, or cannot move further, so Tab keeps its default behaviour. */\nexport function indentList(\n value: string,\n selectionStart: number,\n selectionEnd: number,\n direction: 1 | -1,\n): Edit | null {\n if (insideFence(value, selectionStart)) return null;\n\n const first = lineAt(value, selectionStart);\n const last = lineAt(value, selectionEnd);\n const block = value.slice(first.start, last.end);\n const lines = block.split('\\n');\n if (!lines.every((text) => LIST_MARKER.test(text))) return null;\n\n const cap = first.start === 0 ? 0 : indentOf(lineAt(value, first.start - 1).text);\n const shifted = lines.map((text, i) => shift(text, direction, i === 0 ? cap : undefined));\n if (shifted.every((text, i) => text === lines[i])) return null;\n\n const joined = shifted.join('\\n');\n return {\n value: value.slice(0, first.start) + joined + value.slice(last.end),\n selectionStart: selectionStart + (shifted[0].length - lines[0].length),\n selectionEnd: selectionEnd + (joined.length - block.length),\n };\n}\n","import type { Edit } from './edit';\nimport { insideFence, isFenceDelimiter, lineAt } from './line-at';\n\n/** A line-level markdown prefix: a heading level, a bullet or a numbered item. */\nexport type LinePrefix = 'h1' | 'h2' | 'h3' | 'bullet' | 'ordered';\n\nconst EXISTING = /^(\\s*)(?:#{1,6} |[-*+] \\[[ xX]\\] |[-*+] |\\d+[.)] )?/;\n\nconst PREFIX: Record<LinePrefix, (index: number) => string> = {\n h1: () => '# ',\n h2: () => '## ',\n h3: () => '### ',\n bullet: () => '- ',\n ordered: (index) => `${index + 1}. `,\n};\n\nconst CARRIES: Record<LinePrefix, RegExp> = {\n h1: /^\\s*# /,\n h2: /^\\s*## /,\n h3: /^\\s*### /,\n bullet: /^\\s*[-*+] /,\n ordered: /^\\s*\\d+[.)] /,\n};\n\n/** Adds the prefix to every line in the selection, or removes it when every line already carries it; fenced code is left alone. */\nexport function toggleLinePrefix(\n kind: LinePrefix,\n value: string,\n selectionStart: number,\n selectionEnd: number,\n): Edit {\n const first = lineAt(value, selectionStart);\n const last = lineAt(value, selectionEnd);\n const block = value.slice(first.start, last.end);\n const lines = block.split('\\n');\n\n let offset = first.start;\n const eligible = lines.map((text) => {\n const at = offset;\n offset += text.length + 1;\n return !insideFence(value, at) && !isFenceDelimiter(text);\n });\n\n const carried = lines.every((text, i) => !eligible[i] || CARRIES[kind].test(text));\n\n const rewritten = lines.map((text, i) => {\n if (!eligible[i]) return text;\n const match = EXISTING.exec(text);\n const indent = match?.[1] ?? '';\n const body = text.slice(match?.[0].length ?? 0);\n return carried ? indent + body : indent + PREFIX[kind](i) + body;\n });\n\n const joined = rewritten.join('\\n');\n const next = value.slice(0, first.start) + joined + value.slice(last.end);\n\n if (selectionStart !== selectionEnd) {\n return { value: next, selectionStart: first.start, selectionEnd: first.start + joined.length };\n }\n\n const caret = Math.max(first.start, selectionStart + (rewritten[0].length - lines[0].length));\n return { value: next, selectionStart: caret, selectionEnd: caret };\n}\n","import { insideFence } from './line-at';\n\n/** Whether typing \"/\" here should open the command palette: only at a word start, with no selection and outside a code fence. */\nexport function shouldOpenPalette(\n value: string,\n selectionStart: number,\n selectionEnd: number,\n): boolean {\n if (selectionStart !== selectionEnd) return false;\n if (insideFence(value, selectionStart)) return false;\n if (selectionStart === 0) return true;\n\n const previous = value[selectionStart - 1];\n return previous === '\\n' || previous === ' ' || previous === '\\t';\n}\n","import type { Edit } from './edit';\n\n/** An inline markdown wrapper: bold, italic, code or a link. */\nexport type WrapKind = 'bold' | 'italic' | 'code' | 'link';\n\nconst DELIMITER: Record<Exclude<WrapKind, 'link'>, string> = {\n bold: '**',\n italic: '_',\n code: '`',\n};\n\nconst WHOLE_LINK = /^\\[([^\\]]*)\\]\\(([^)]*)\\)$/;\nconst BARE_URL = /^https?:\\/\\/[^\\s]+$/;\n\nfunction unwrap(value: string, start: number, end: number, delimiter: string): Edit | null {\n const selected = value.slice(start, end);\n const width = delimiter.length;\n\n if (selected.length >= 2 * width && selected.startsWith(delimiter) && selected.endsWith(delimiter)) {\n const inner = selected.slice(width, selected.length - width);\n return {\n value: value.slice(0, start) + inner + value.slice(end),\n selectionStart: start,\n selectionEnd: start + inner.length,\n };\n }\n\n const outside =\n start >= width &&\n value.slice(start - width, start) === delimiter &&\n value.slice(end, end + width) === delimiter;\n\n if (!outside) return null;\n\n return {\n value: value.slice(0, start - width) + selected + value.slice(end + width),\n selectionStart: start - width,\n selectionEnd: start - width + selected.length,\n };\n}\n\nfunction link(value: string, start: number, end: number): Edit {\n const selected = value.slice(start, end);\n const whole = WHOLE_LINK.exec(selected);\n\n if (whole) {\n const text = whole[1];\n return {\n value: value.slice(0, start) + text + value.slice(end),\n selectionStart: start,\n selectionEnd: start + text.length,\n };\n }\n\n const opened = `[${selected}](`;\n const at = selected === '' ? start + 1 : start + opened.length;\n return {\n value: value.slice(0, start) + opened + ')' + value.slice(end),\n selectionStart: at,\n selectionEnd: at,\n };\n}\n\n/** Wraps the selection in the markers for the kind, or removes them when it is already wrapped. */\nexport function wrapSelection(\n kind: WrapKind,\n value: string,\n selectionStart: number,\n selectionEnd: number,\n): Edit {\n if (kind === 'link') return link(value, selectionStart, selectionEnd);\n\n const delimiter = DELIMITER[kind];\n const stripped = unwrap(value, selectionStart, selectionEnd, delimiter);\n if (stripped) return stripped;\n\n const selected = value.slice(selectionStart, selectionEnd);\n\n if (kind === 'code' && selected.includes('\\n')) {\n const at = selectionStart + 4;\n return {\n value: value.slice(0, selectionStart) + '```\\n' + selected + '\\n```' + value.slice(selectionEnd),\n selectionStart: at,\n selectionEnd: at + selected.length,\n };\n }\n\n const at = selectionStart + delimiter.length;\n return {\n value: value.slice(0, selectionStart) + delimiter + selected + delimiter + value.slice(selectionEnd),\n selectionStart: at,\n selectionEnd: at + selected.length,\n };\n}\n\n/** Turns a pasted URL over a selection into a markdown link; returns null when nothing is selected or the paste is not a bare URL, so the paste goes through unchanged. */\nexport function linkPaste(\n value: string,\n selectionStart: number,\n selectionEnd: number,\n pasted: string,\n): Edit | null {\n if (selectionStart === selectionEnd) return null;\n\n const url = pasted.trim();\n if (!BARE_URL.test(url)) return null;\n\n const inserted = `[${value.slice(selectionStart, selectionEnd)}](${url})`;\n const at = selectionStart + inserted.length;\n return {\n value: value.slice(0, selectionStart) + inserted + value.slice(selectionEnd),\n selectionStart: at,\n selectionEnd: at,\n };\n}\n","import * as React from 'react';\nimport { caretRect, type CaretRect } from './caret-coordinates';\n\nexport function useSlashPalette(ref: React.RefObject<HTMLTextAreaElement | null>) {\n const [open, setOpen] = React.useState(false);\n const [caret, setCaret] = React.useState<CaretRect | null>(null);\n const offsetRef = React.useRef(0);\n\n const openAtCaret = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n offsetRef.current = el.selectionStart;\n setCaret(caretRect(el));\n setOpen(true);\n }, [ref]);\n\n return { open, setOpen, caret, offsetRef, openAtCaret };\n}\n","type CopiedProperty =\n | 'boxSizing'\n | 'fontFamily'\n | 'fontSize'\n | 'fontStyle'\n | 'fontWeight'\n | 'letterSpacing'\n | 'lineHeight'\n | 'paddingBottom'\n | 'paddingLeft'\n | 'paddingRight'\n | 'paddingTop'\n | 'textIndent'\n | 'textTransform'\n | 'wordBreak'\n | 'wordSpacing'\n | 'borderBottomWidth'\n | 'borderLeftWidth'\n | 'borderRightWidth'\n | 'borderTopWidth';\n\nconst COPIED: CopiedProperty[] = [\n 'boxSizing',\n 'fontFamily',\n 'fontSize',\n 'fontStyle',\n 'fontWeight',\n 'letterSpacing',\n 'lineHeight',\n 'paddingBottom',\n 'paddingLeft',\n 'paddingRight',\n 'paddingTop',\n 'textIndent',\n 'textTransform',\n 'wordBreak',\n 'wordSpacing',\n 'borderBottomWidth',\n 'borderLeftWidth',\n 'borderRightWidth',\n 'borderTopWidth',\n];\n\n/** The caret's position and line height, in pixels relative to the textarea's top left corner. */\nexport type CaretRect = { top: number; left: number; height: number };\n\n/** A textarea exposes no caret geometry, so the text before the caret is laid\n * out again in a hidden div that copies the box's own metrics, and a marker at\n * the end of it is measured. Returns null when the textarea is not laid out\n * (hidden or detached), because there is nothing to measure. */\nexport function caretRect(el: HTMLTextAreaElement): CaretRect | null {\n if (el.offsetWidth === 0) return null;\n\n const style = window.getComputedStyle(el);\n const mirror = document.createElement('div');\n for (const property of COPIED) mirror.style[property] = style[property];\n mirror.style.position = 'absolute';\n mirror.style.top = '0';\n mirror.style.left = '-9999px';\n mirror.style.visibility = 'hidden';\n mirror.style.whiteSpace = 'pre-wrap';\n mirror.style.overflowWrap = 'break-word';\n mirror.style.width = `${el.clientWidth}px`;\n mirror.textContent = el.value.slice(0, el.selectionStart);\n\n const marker = document.createElement('span');\n marker.textContent = '\\u200b';\n mirror.appendChild(marker);\n document.body.appendChild(mirror);\n\n const top = marker.offsetTop;\n const left = marker.offsetLeft;\n const height = marker.offsetHeight || Number.parseFloat(style.lineHeight) || 0;\n mirror.remove();\n\n if (height === 0) return null;\n return { top: top - el.scrollTop, left, height };\n}\n","import * as React from 'react';\n\n/** Height follows the content, and is recomputed when the box gets narrower or\n * wider, because a re-wrap changes the line count without changing the value.\n * Only a width change refits: reacting to the height this hook just set would\n * feed the observer its own output. */\nexport function useAutoGrow<T extends HTMLTextAreaElement>(value: string) {\n const ref = React.useRef<T>(null);\n const lastWidth = React.useRef<number | null>(null);\n\n // Measuring means collapsing to \"auto\" first, which shrinks the page enough that\n // the browser clamps the scroll position, and growing back does not undo that.\n // Both steps run before paint, so restoring the scroll here is not visible.\n const fit = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n const scroller = document.scrollingElement ?? document.documentElement;\n const scrollTop = scroller.scrollTop;\n el.style.height = 'auto';\n if (el.scrollHeight > 0) el.style.height = `${el.scrollHeight}px`;\n if (scroller.scrollTop !== scrollTop) scroller.scrollTop = scrollTop;\n }, []);\n\n React.useLayoutEffect(fit, [fit, value]);\n\n React.useEffect(() => {\n const el = ref.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(([entry]) => {\n const width = entry.contentRect.width;\n if (width === lastWidth.current) return;\n lastWidth.current = width;\n fit();\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, [fit]);\n\n return ref;\n}\n","export const str = (v: unknown) => (typeof v === 'string' ? v : '');\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\";\nimport { cn } from \"./cn\";\nimport { TAP_TARGET_FLOOR } from \"./touch-target\";\n\nfunction Select(props: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\nfunction SelectValue(props: React.ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />;\n}\nfunction SelectTrigger({ className, children, ...props }: React.ComponentProps<typeof SelectPrimitive.Trigger>) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n className={cn(\n \"border-input data-[placeholder]:text-muted-foreground flex h-9 w-full cursor-pointer items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm shadow-xs outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n TAP_TARGET_FLOOR,\n className,\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"size-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n );\n}\nfunction SelectContent({ className, children, position = \"popper\", ...props }: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n className={cn(\n \"quoin bg-popover text-popover-foreground relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border shadow-md\",\n position === \"popper\" && \"data-[side=bottom]:translate-y-1\",\n className,\n )}\n position={position}\n {...props}\n >\n <SelectPrimitive.ScrollUpButton className=\"flex cursor-default items-center justify-center py-1\">\n <ChevronUpIcon className=\"size-4\" />\n </SelectPrimitive.ScrollUpButton>\n <SelectPrimitive.Viewport className={cn(\"p-1\", position === \"popper\" && \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]\")}>\n {children}\n </SelectPrimitive.Viewport>\n <SelectPrimitive.ScrollDownButton className=\"flex cursor-default items-center justify-center py-1\">\n <ChevronDownIcon className=\"size-4\" />\n </SelectPrimitive.ScrollDownButton>\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n );\n}\nfunction SelectItem({ className, children, ...props }: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n TAP_TARGET_FLOOR,\n className,\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n );\n}\nexport { Select, SelectValue, SelectTrigger, SelectContent, SelectItem };\n","import * as React from \"react\";\nimport { cn } from \"./cn\";\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n return (\n <textarea\n data-slot=\"textarea\"\n className={cn(\n \"border-input placeholder:text-muted-foreground flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none disabled:pointer-events-none disabled:opacity-50 md:text-sm\",\n \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n \"aria-invalid:ring-destructive/20 aria-invalid:border-destructive\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Textarea };\n","'use client';\n\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select';\nimport { Textarea } from '../ui/textarea';\nimport type { BlockEditorProps } from '../types';\nimport { str } from './str';\n\nconst CALLOUT_TONES = ['info', 'tip', 'warning', 'success', 'danger'] as const;\n\nexport function CalloutBlockEditor({ data, onChange }: BlockEditorProps) {\n const set = (patch: Record<string, unknown>) => onChange({ ...data, ...patch });\n\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-sm font-medium leading-none\">Tone</span>\n <Select value={str(data.tone) || 'info'} onValueChange={(v) => set({ tone: v })}>\n <SelectTrigger aria-label=\"Callout tone\" className=\"w-40 capitalize\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {CALLOUT_TONES.map((t) => (\n <SelectItem key={t} value={t} className=\"capitalize\">\n {t}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-sm font-medium leading-none\">Callout text</span>\n <Textarea value={str(data.body)} onChange={(e) => set({ body: e.target.value })} className=\"text-sm\" />\n </label>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"./cn\";\nimport { TAP_TARGET_FLOOR } from \"./touch-target\";\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <input\n type={type}\n data-slot=\"input\"\n className={cn(\n \"border-input placeholder:text-muted-foreground flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:opacity-50 md:text-sm\",\n \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n \"aria-invalid:ring-destructive/20 aria-invalid:border-destructive\",\n TAP_TARGET_FLOOR,\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Input };\n","'use client';\n\nimport { Input } from '../ui/input';\nimport { Textarea } from '../ui/textarea';\nimport type { BlockEditorProps } from '../types';\nimport { str } from './str';\n\nexport function CodeBlockEditor({ data, onChange }: BlockEditorProps) {\n const set = (patch: Record<string, unknown>) => onChange({ ...data, ...patch });\n\n return (\n <div className=\"flex flex-col gap-2\">\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-sm font-medium leading-none\">Language</span>\n <Input\n aria-label=\"Language\"\n value={str(data.language)}\n onChange={(e) => set({ language: e.target.value })}\n className=\"text-sm\"\n />\n </label>\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-sm font-medium leading-none\">Code</span>\n <Textarea\n aria-label=\"Code\"\n value={str(data.code)}\n onChange={(e) => set({ code: e.target.value })}\n className=\"min-h-32 font-mono text-sm\"\n />\n </label>\n </div>\n );\n}\n","'use client';\n\nimport { useEffect, useRef } from 'react';\nimport { useQuoin } from '../context';\nimport { Input } from '../ui/input';\nimport { UploadField } from '../upload/UploadField';\nimport type { BlockEditorProps } from '../types';\nimport { str } from './str';\nimport { intrinsicSize } from './intrinsic-size';\n\nexport function ImageBlockEditor({ data, onChange }: BlockEditorProps) {\n const { resolveAssetUrl } = useQuoin();\n // Read through a ref: measuring the upload is async, and the alt/caption fields\n // stay editable while it runs.\n const latest = useRef(data);\n useEffect(() => {\n latest.current = data;\n });\n const set = (patch: Record<string, unknown>) => onChange({ ...latest.current, ...patch });\n\n const onUploaded = async (r: { storageKey: string }) => {\n const src = resolveAssetUrl(r.storageKey);\n const size = src ? await intrinsicSize(src) : null;\n set({ storageKey: r.storageKey, ...size });\n };\n\n return (\n <div className=\"flex flex-col gap-2\">\n <UploadField category=\"image\" label=\"Upload image\" onUploaded={onUploaded} />\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-sm font-medium leading-none\">Alt text</span>\n <Input\n aria-label=\"Image alt text\"\n value={str(data.alt)}\n onChange={(e) => set({ alt: e.target.value })}\n className=\"text-sm\"\n />\n </label>\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-sm font-medium leading-none\">Caption (optional)</span>\n <Input\n aria-label=\"Image caption\"\n value={str(data.caption)}\n onChange={(e) => set({ caption: e.target.value })}\n className=\"text-sm\"\n />\n </label>\n {str(data.storageKey) && <span className=\"text-xs text-muted-foreground\">Image attached ✓</span>}\n </div>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport { useQuoin } from '../context';\nimport type { UploadResult } from '../types';\nimport { FilePickerButton } from './FilePickerButton';\n\n/** Props for `UploadField`; the upload function itself comes from the canvas, not from here. */\nexport type UploadFieldProps = {\n /** Names what the file is for, and is passed to the host's `upload` as its second argument. */\n category: string;\n /** Labels the control for both the pointer and assistive technology. */\n label: string;\n /** An `accept` attribute for the file input, such as `'image/*'` or `'.pdf'`. */\n accept?: string;\n /** Called once the upload resolves. Throwing from it is reported through the canvas `onError`. */\n onUploaded: (result: UploadResult) => void;\n};\n\n/** A file picker wired to the canvas `upload` function, with its own busy state and inline error. */\nexport function UploadField({ category, label, accept, onUploaded }: UploadFieldProps) {\n const { upload, onError } = useQuoin();\n const [busy, setBusy] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n\n async function run(file: File) {\n if (!upload) return;\n setBusy(true);\n setError(null);\n let result: UploadResult;\n try {\n result = await upload(file, category);\n } catch (cause) {\n setError((cause instanceof Error && cause.message) || 'Upload failed.');\n setBusy(false);\n return;\n }\n setBusy(false);\n try {\n onUploaded(result);\n } catch (cause) {\n onError(cause instanceof Error ? cause : new Error(String(cause)));\n }\n }\n\n return (\n <div className=\"flex flex-col items-start gap-1.5\">\n <FilePickerButton\n label={label}\n accept={accept}\n disabled={busy || !upload}\n onPick={(file) => void run(file)}\n />\n {!upload && (\n <span role=\"note\" className=\"text-xs text-muted-foreground\">\n Uploads are not configured for this editor.\n </span>\n )}\n {busy && <span role=\"status\" className=\"text-xs text-muted-foreground\">Uploading...</span>}\n {error && (\n <span role=\"alert\" className=\"text-xs text-destructive\">\n {error}\n </span>\n )}\n </div>\n );\n}\n","export type IntrinsicSize = { width: number; height: number };\n\n/** Persisted onto the block so the reader can reserve the box before the bytes\n * arrive. Resolves null rather than rejecting: a drop without them still renders,\n * it just reflows. */\nexport function intrinsicSize(src: string): Promise<IntrinsicSize | null> {\n return new Promise((resolve) => {\n if (typeof window === 'undefined') return resolve(null);\n const img = new window.Image();\n img.onload = () => resolve({ width: img.naturalWidth, height: img.naturalHeight });\n img.onerror = () => resolve(null);\n img.src = src;\n });\n}\n","'use client';\n\nimport { UploadField } from '../upload/UploadField';\nimport type { BlockEditorProps } from '../types';\nimport { str } from './str';\n\nexport function FileBlockEditor({ data, onChange }: BlockEditorProps) {\n const set = (patch: Record<string, unknown>) => onChange({ ...data, ...patch });\n\n return (\n <div className=\"flex flex-col gap-2\">\n <UploadField\n category=\"file\"\n label=\"Upload file\"\n onUploaded={(r) => set({ storageKey: r.storageKey, filename: r.filename, size: r.size })}\n />\n {str(data.filename) && <span className=\"text-xs text-muted-foreground\">{str(data.filename)} ✓</span>}\n </div>\n );\n}\n","'use client';\n\nimport { useQuoin } from '../context';\nimport type { BlockPreviewProps } from '../types';\nimport { str } from './str';\n\nconst HINT = 'text-sm text-muted-foreground';\n\n/**\n * One colour per tone, carrying both the rule and the wash behind it. Until 0.4.0 the\n * five tones were mapped onto whatever this palette already had, which gave info, tip\n * and success the same near-black rule and all five the same grey fill: the editor\n * offered five choices that rendered as three, and the choice a writer made was lost.\n *\n * The wash is 15% of a mid-lightness colour, which is light enough to keep body copy\n * on it and saturated enough to read as the tone rather than as grey.\n */\nexport const TONE: Record<string, string> = {\n info: 'border-info bg-info/15',\n tip: 'border-primary bg-primary/15',\n warning: 'border-warning bg-warning/15',\n success: 'border-success bg-success/15',\n danger: 'border-destructive bg-destructive/15',\n};\n\nexport function MarkdownPreview({ data }: BlockPreviewProps) {\n const markdown = str(data.markdown);\n if (markdown.trim() === '') return <p className={HINT}>Empty markdown block</p>;\n return <div className=\"whitespace-pre-wrap text-base leading-7\">{markdown}</div>;\n}\n\nexport function CodePreview({ data }: BlockPreviewProps) {\n const code = str(data.code);\n if (code.trim() === '') return <p className={HINT}>Empty code block</p>;\n return (\n <pre className=\"overflow-x-auto rounded-md bg-muted p-3 text-sm\">\n <code>{code}</code>\n </pre>\n );\n}\n\nexport function ImagePreview({ data }: BlockPreviewProps) {\n const { resolveAssetUrl } = useQuoin();\n const key = str(data.storageKey);\n // Guard on the key, not the resolved URL: a prefixing resolver turns an empty key into a truthy, dead address.\n if (key === '') return <p className={HINT}>No image chosen</p>;\n return <img src={resolveAssetUrl(key)} alt={str(data.alt)} className=\"max-w-full rounded-md\" />;\n}\n\nexport function FilePreview({ data }: BlockPreviewProps) {\n const name = str(data.filename);\n if (name === '') return <p className={HINT}>No file chosen</p>;\n return <p className=\"text-sm\">{name}</p>;\n}\n\nexport function CalloutPreview({ data }: BlockPreviewProps) {\n const body = str(data.body);\n if (body.trim() === '') return <p className={HINT}>Empty callout</p>;\n const tone = str(data.tone) || 'info';\n const paint = TONE[tone] ?? 'border-border bg-muted/50';\n return (\n <div data-tone={tone} className={`rounded-md border-l-4 ${paint} p-3 text-sm`}>\n {body}\n </div>\n );\n}\n","import * as React from 'react';\nimport type { QuoinBlock } from '../types';\nimport { newBlockId } from './new-block-id';\n\n/** Handed back by `remove` and accepted by `undo` to restore that one block. */\nexport type UndoToken = number;\n\ntype Removed = { block: QuoinBlock; index: number };\n\ntype State = {\n blocks: QuoinBlock[];\n removals: Map<UndoToken, Removed>;\n};\n\ntype Action =\n | { type: 'insertAt'; index: number; block: QuoinBlock }\n | { type: 'update'; id: string; data: Record<string, unknown> }\n | { type: 'remove'; id: string; token: UndoToken }\n | { type: 'undo'; token: UndoToken }\n | { type: 'move'; index: number; dir: -1 | 1 }\n | { type: 'reorder'; from: number; to: number }\n | { type: 'reset'; blocks: QuoinBlock[] };\n\nlet removalSeq = 0;\n\n/** A canvas may never call `undo`, so the oldest removals are dropped rather than kept\n * for the lifetime of the document. The cap is far past any run of deletes a person\n * would undo one by one. */\nconst UNDO_DEPTH = 20;\n\nfunction reducer(state: State, action: Action): State {\n switch (action.type) {\n case 'insertAt': {\n const next = [...state.blocks];\n next.splice(Math.max(0, Math.min(action.index, state.blocks.length)), 0, action.block);\n return { ...state, blocks: next };\n }\n case 'update': {\n return {\n ...state,\n blocks: state.blocks.map((b) => (b.id === action.id ? { ...b, data: action.data } : b)),\n };\n }\n case 'remove': {\n const index = state.blocks.findIndex((b) => b.id === action.id);\n if (index === -1) return state;\n const removals = new Map(state.removals);\n removals.set(action.token, { block: state.blocks[index], index });\n while (removals.size > UNDO_DEPTH) {\n const oldest = removals.keys().next();\n if (oldest.done) break;\n removals.delete(oldest.value);\n }\n return { blocks: state.blocks.filter((b) => b.id !== action.id), removals };\n }\n case 'undo': {\n const removal = state.removals.get(action.token);\n if (!removal) return state;\n const next = [...state.blocks];\n next.splice(Math.min(removal.index, state.blocks.length), 0, removal.block);\n const removals = new Map(state.removals);\n removals.delete(action.token);\n return { blocks: next, removals };\n }\n case 'move': {\n const j = action.index + action.dir;\n if (j < 0 || j >= state.blocks.length) return state;\n const next = [...state.blocks];\n [next[action.index], next[j]] = [next[j], next[action.index]];\n return { ...state, blocks: next };\n }\n case 'reorder': {\n const { from, to } = action;\n if (from < 0 || to < 0 || from >= state.blocks.length || to >= state.blocks.length) return state;\n const next = [...state.blocks];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved);\n return { ...state, blocks: next };\n }\n case 'reset':\n return { blocks: action.blocks, removals: new Map() };\n }\n}\n\n/** The document plus every way to change it; `reset` replaces the whole document and voids outstanding undo tokens. */\nexport type BlockList = {\n blocks: QuoinBlock[];\n insertAt: (index: number, type: string, data?: Record<string, unknown>) => string;\n update: (id: string, data: Record<string, unknown>) => void;\n /** Returns a token `undo` restores that block with; only the last 20 removals stay restorable. */\n remove: (id: string) => UndoToken;\n undo: (token: UndoToken) => void;\n move: (index: number, dir: -1 | 1) => void;\n reorder: (from: number, to: number) => void;\n reset: (blocks: QuoinBlock[]) => void;\n};\n\n/** Holds a document in a reducer and returns its blocks with insert, update, remove, undo, move, reorder and reset. Reads `initial` once. */\nexport function useBlockList(initial: QuoinBlock[]): BlockList {\n const [state, dispatch] = React.useReducer(reducer, { blocks: initial, removals: new Map() });\n\n const insertAt = React.useCallback(\n (index: number, type: string, data: Record<string, unknown> = {}): string => {\n const id = newBlockId();\n dispatch({ type: 'insertAt', index, block: { id, type, data } });\n return id;\n },\n [],\n );\n\n const update = React.useCallback((id: string, data: Record<string, unknown>) => {\n dispatch({ type: 'update', id, data });\n }, []);\n\n const remove = React.useCallback((id: string): UndoToken => {\n removalSeq += 1;\n const token = removalSeq;\n dispatch({ type: 'remove', id, token });\n return token;\n }, []);\n\n const undo = React.useCallback((token: UndoToken) => {\n dispatch({ type: 'undo', token });\n }, []);\n\n const move = React.useCallback((index: number, dir: -1 | 1) => {\n dispatch({ type: 'move', index, dir });\n }, []);\n\n const reorder = React.useCallback((from: number, to: number) => {\n dispatch({ type: 'reorder', from, to });\n }, []);\n\n const reset = React.useCallback((blocks: QuoinBlock[]) => {\n dispatch({ type: 'reset', blocks });\n }, []);\n\n return { blocks: state.blocks, insertAt, update, remove, undo, move, reorder, reset };\n}\n","/**\n * A fresh block id that cannot collide with one already in a persisted document.\n * It holds no counter, because a counter restarts on every page load and would\n * re-mint ids a host has stored.\n */\nexport function newBlockId(): string {\n const webCrypto = globalThis.crypto;\n if (webCrypto && typeof webCrypto.randomUUID === 'function') return webCrypto.randomUUID();\n // randomUUID is absent in insecure contexts and older runtimes.\n const random = () => Math.random().toString(36).slice(2, 10);\n return `blk-${Date.now().toString(36)}-${random()}${random()}`;\n}\n","import type { Announcements } from '@dnd-kit/core';\nimport { blockByType, type AnyBlockDefinition } from '../registry';\nimport type { QuoinBlock } from '../types';\n\nfunction describeBlock(blocks: QuoinBlock[], blockTypes: AnyBlockDefinition[], id: string): string {\n const index = blocks.findIndex((b) => b.id === id);\n if (index === -1) return 'block';\n const { type } = blocks[index];\n const label = blockByType(blockTypes, type)?.label ?? type;\n return `${label} block, position ${index + 1} of ${blocks.length}`;\n}\n\n/** The screen reader sentences a drag speaks, naming each block by its registered label and position. */\nexport function buildAnnouncements(blocks: QuoinBlock[], blockTypes: AnyBlockDefinition[]): Announcements {\n const describe = (id: string | number) => describeBlock(blocks, blockTypes, String(id));\n return {\n onDragStart({ active }) {\n return `Picked up ${describe(active.id)}.`;\n },\n onDragOver({ active, over }) {\n if (!over) return `${describe(active.id)} is no longer over a drop position.`;\n return `${describe(active.id)} was moved over ${describe(over.id)}.`;\n },\n onDragEnd({ active, over }) {\n if (!over) return `${describe(active.id)} was dropped.`;\n return `${describe(active.id)} was dropped over ${describe(over.id)}.`;\n },\n onDragCancel({ active }) {\n return `Dragging was cancelled. ${describe(active.id)} was dropped.`;\n },\n };\n}\n","'use client';\n\nimport { ArrowDown, ArrowUp, MoreHorizontal, Trash2 } from 'lucide-react';\nimport { Button } from '../ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../ui/dropdown-menu';\n\nexport function BlockActionsMenu({\n index,\n count,\n label,\n onMove,\n onDelete,\n}: {\n index: number;\n count: number;\n label: string;\n onMove: (index: number, dir: 1 | -1) => void;\n onDelete: () => void;\n}) {\n const position = index + 1;\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button type=\"button\" variant=\"ghost\" size=\"icon-sm\" aria-label={`${label} block ${position} options`}>\n <MoreHorizontal aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-48\">\n <DropdownMenuItem\n aria-label={`Move block ${position} up`}\n disabled={index === 0}\n onSelect={() => onMove(index, -1)}\n >\n <ArrowUp aria-hidden=\"true\" />\n <span>Move up</span>\n </DropdownMenuItem>\n <DropdownMenuItem\n aria-label={`Move block ${position} down`}\n disabled={index === count - 1}\n onSelect={() => onMove(index, 1)}\n >\n <ArrowDown aria-hidden=\"true\" />\n <span>Move down</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n aria-label={`Delete block ${position}`}\n className=\"text-destructive focus:text-destructive\"\n onSelect={onDelete}\n >\n <Trash2 aria-hidden=\"true\" />\n <span>Delete</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\nimport { cn } from \"./cn\";\nimport { TAP_TARGET_FLOOR } from \"./touch-target\";\n\nfunction DropdownMenu(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Root>,\n) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuTrigger(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>,\n) {\n return (\n <DropdownMenuPrimitive.Trigger\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n \"quoin bg-popover text-popover-foreground z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className,\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nfunction DropdownMenuGroup(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Group>,\n) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n );\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[inset]:pl-8 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4\",\n TAP_TARGET_FLOOR,\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-none select-none\",\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction DropdownMenuRadioGroup(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>,\n) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-none select-none\",\n className,\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"text-muted-foreground ml-auto text-xs tracking-widest\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSub(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>,\n) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent data-[state=open]:bg-accent flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[inset]:pl-8\",\n className,\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"quoin bg-popover text-popover-foreground z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-lg\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n};\n","'use client';\n\nimport * as React from 'react';\nimport { Pencil } from 'lucide-react';\nimport { BlockEditor } from './BlockEditor';\nimport { renderedOffsetAt, sourceOffsetFor, type ClickProbe } from './source-offset';\nimport { useQuoin } from '../context';\nimport { blockByType } from '../registry';\nimport { devWarn } from '../dev-warn';\nimport type { QuoinBlock } from '../types';\nimport { Button } from '../ui/button';\n\nconst INTERACTIVE_SELECTOR = 'a, button, input, textarea, select, [role=\"button\"], [tabindex], iframe';\n\n/** Radix renders Select, dropdown and popover content in a portal, so focus moving\n * into one leaves this block's DOM subtree while the author is still editing it. */\nconst PORTALLED_OVERLAY = '[data-radix-popper-content-wrapper], [role=\"dialog\"]';\n\n// A drag-select ends in a click on mouseup; bailing here keeps that click from\n// flipping the block into edit mode and wiping out the selection it just made.\nfunction hasSelectionWithin(container: HTMLElement): boolean {\n const selection = window.getSelection();\n if (!selection || selection.isCollapsed || selection.rangeCount === 0) return false;\n return container.contains(selection.getRangeAt(0).commonAncestorContainer);\n}\n\nfunction BlockCardImpl({\n block,\n index,\n editingByDefault = false,\n readOnly = false,\n initialSelection = null,\n onUpdate,\n onInsertBlock,\n}: {\n block: QuoinBlock;\n index: number;\n editingByDefault?: boolean;\n /** Draws the block at rest and never opens an editor, for a canvas that is only being read. */\n readOnly?: boolean;\n initialSelection?: { start: number; end: number } | null;\n onUpdate: (id: string, data: Record<string, unknown>) => void;\n onInsertBlock?: (index: number, type: string) => void;\n}) {\n const { blockTypes, onError } = useQuoin();\n const definition = blockByType(blockTypes, block.type);\n const Preview = definition?.preview;\n // A definition with no `editor` can never be edited here, so the card offers no way in:\n // no click target, no Edit button, and nothing that could set `editing`.\n const editable = Boolean(definition?.editor) && !readOnly;\n const [editing, setEditing] = React.useState(editingByDefault && editable);\n const editButtonRef = React.useRef<HTMLButtonElement>(null);\n const editorContainerRef = React.useRef<HTMLDivElement>(null);\n const returnFocusOnClose = React.useRef(false);\n const clickedRef = React.useRef<ClickProbe | null>(null);\n const scrollTopRef = React.useRef<number | null>(null);\n\n const handleInsertBlock = React.useCallback(\n (type: string) => onInsertBlock?.(index + 1, type),\n [onInsertBlock, index],\n );\n\n const leaveEditing = React.useCallback(() => {\n returnFocusOnClose.current = true;\n setEditing(false);\n }, []);\n\n const settleRef = React.useRef<number | null>(null);\n\n const clearSettle = () => {\n if (settleRef.current === null) return;\n window.clearTimeout(settleRef.current);\n settleRef.current = null;\n };\n\n React.useEffect(() => clearSettle, []);\n\n function stillInside(node: Element | null): boolean {\n if (!node) return false;\n return Boolean(editorContainerRef.current?.contains(node)) || Boolean(node.closest(PORTALLED_OVERLAY));\n }\n\n // Editing ends when the author's attention goes elsewhere, so a block left\n // behind renders instead of stranding them on its markdown source. A pointer\n // event is read directly rather than through focus, which Radix moves around\n // asynchronously while an overlay or a freshly inserted block settles.\n React.useEffect(() => {\n if (!editing) return;\n function onPointerDown(e: PointerEvent) {\n if (stillInside(e.target as Element | null)) return;\n setEditing(false);\n }\n document.addEventListener('pointerdown', onPointerDown, true);\n return () => document.removeEventListener('pointerdown', onPointerDown, true);\n }, [editing]);\n\n function closeIfTabbedAway() {\n clearSettle();\n settleRef.current = window.setTimeout(() => {\n settleRef.current = null;\n if (stillInside(document.activeElement)) return;\n setEditing(false);\n }, 0);\n }\n\n // Focus on the click path must not scroll: the caret is placed after focus, so the\n // browser would otherwise drag the viewport to wherever the box's selection starts\n // out, away from the line the author actually aimed at.\n React.useEffect(() => {\n if (!editing) return;\n const field = editorContainerRef.current?.querySelector<HTMLElement>(\n 'textarea, input, [role=\"combobox\"]',\n );\n if (!field) return;\n\n const clicked = clickedRef.current;\n clickedRef.current = null;\n\n if (clicked === null || !(field instanceof HTMLTextAreaElement)) {\n field.focus();\n if (field instanceof HTMLTextAreaElement) {\n const at = initialSelection ?? { start: field.value.length, end: field.value.length };\n field.setSelectionRange(at.start, at.end);\n }\n return;\n }\n\n const offset = sourceOffsetFor(field.value, clicked);\n field.focus({ preventScroll: true });\n field.setSelectionRange(offset, offset);\n }, [editing, initialSelection]);\n\n // Replacing a tall rendered block with a one-row textarea shrinks the page, so\n // the browser clamps the scroll before the box can grow back. The position is\n // taken at the click and put back here, after the box has been sized.\n React.useLayoutEffect(() => {\n const scrollTop = scrollTopRef.current;\n scrollTopRef.current = null;\n if (!editing || scrollTop === null) return;\n const scroller = document.scrollingElement ?? document.documentElement;\n if (scroller.scrollTop !== scrollTop) scroller.scrollTop = scrollTop;\n }, [editing]);\n\n React.useEffect(() => {\n if (editing || !returnFocusOnClose.current) return;\n returnFocusOnClose.current = false;\n editButtonRef.current?.focus();\n }, [editing]);\n\n // A block whose type no host registered draws its type rather than nothing, so a\n // document authored with a plugin block does not look empty, and the host is told\n // once per type instead of on every render.\n const reportedType = React.useRef<string | null>(null);\n React.useEffect(() => {\n if (definition || reportedType.current === block.type) return;\n reportedType.current = block.type;\n onError(new Error(`No block type is registered for \"${block.type}\".`));\n }, [definition, block.type, onError]);\n\n // A read-only canvas draws previews and never editors, so an edit-only definition has\n // nothing here but its label. That is a registration mistake rather than a document\n // one, which is why it goes to the developer's console and not to `onError`.\n React.useEffect(() => {\n if (!readOnly || !definition || definition.preview) return;\n devWarn(\n `the block type \"${block.type}\" has no \\`preview\\`, so a read-only canvas can draw ` +\n 'only its label. Give its definition a `preview` to render the block itself.',\n );\n }, [readOnly, definition, block.type]);\n\n if (definition?.alwaysEditing && editable) {\n return (\n <BlockEditor\n type={block.type}\n data={block.data}\n onChange={(data) => onUpdate(block.id, data)}\n onInsertBlock={handleInsertBlock}\n />\n );\n }\n\n if (editing) {\n return (\n <div\n ref={editorContainerRef}\n onKeyDown={(e) => {\n if (e.key === 'Tab') {\n closeIfTabbedAway();\n return;\n }\n if (e.key !== 'Escape') return;\n // Radix's DismissableLayer (Select, dropdowns, etc.) closes on a document\n // capture listener and never stops propagation, so this handler still\n // sees the Escape that already dismissed a nested overlay. Only collapse\n // when the key genuinely landed inside this editor's own DOM subtree, not\n // in a portalled overlay that merely propagates through the React tree.\n if (!editorContainerRef.current?.contains(e.target as Node)) return;\n returnFocusOnClose.current = true;\n setEditing(false);\n }}\n >\n <BlockEditor\n type={block.type}\n data={block.data}\n onChange={(data) => onUpdate(block.id, data)}\n onInsertBlock={handleInsertBlock}\n onDone={leaveEditing}\n />\n </div>\n );\n }\n\n const rest = Preview ? (\n <Preview data={block.data} blockId={block.id} />\n ) : (\n <p className=\"py-1 text-sm text-muted-foreground\">{definition?.label ?? block.type}</p>\n );\n\n // No way into an editor, because the canvas is read-only or this type has none.\n if (!editable) return <div>{rest}</div>;\n\n return (\n <div className=\"group/card relative\">\n <div\n onClick={(e) => {\n const target = e.target as HTMLElement;\n if (target.closest(INTERACTIVE_SELECTOR)) return;\n if (hasSelectionWithin(e.currentTarget)) return;\n clickedRef.current = {\n rendered: e.currentTarget.textContent ?? '',\n clickedText: target.textContent ?? '',\n renderedOffset: renderedOffsetAt(e.currentTarget, e.clientX, e.clientY),\n };\n scrollTopRef.current = (document.scrollingElement ?? document.documentElement).scrollTop;\n setEditing(true);\n }}\n >\n {rest}\n </div>\n <Button\n ref={editButtonRef}\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={`Edit block ${index + 1}`}\n onClick={() => setEditing(true)}\n className=\"absolute right-0 top-0 bg-background/90 opacity-0 transition-opacity group-hover/card:opacity-100 group-focus-within/card:opacity-100 focus-visible:opacity-100\"\n >\n <Pencil aria-hidden=\"true\" />\n </Button>\n </div>\n );\n}\n\nexport const BlockCard = React.memo(BlockCardImpl);\n","'use client';\n\nimport { useQuoin } from '../context';\nimport { blockByType } from '../registry';\nimport type { BlockEditorProps } from '../types';\n\nexport function BlockEditor({\n type,\n data,\n onChange,\n onInsertBlock,\n onDone,\n}: BlockEditorProps & { type: string }) {\n const { blockTypes } = useQuoin();\n const Editor = blockByType(blockTypes, type)?.editor;\n if (!Editor) return null;\n return <Editor data={data} onChange={onChange} onInsertBlock={onInsertBlock} onDone={onDone} />;\n}\n","/** What a click on a block's rendered body says about where the caret belongs. */\nexport type ClickProbe = {\n /** The whole text the preview drew for the block. */\n rendered: string;\n /** The text of the element the click actually landed on. */\n clickedText: string;\n /** Character offset of the click within `rendered`, or null when the browser places no caret there. */\n renderedOffset: number | null;\n};\n\ntype CaretPosition = { offsetNode: Node; offset: number };\n\ntype CaretDocument = Document & {\n caretPositionFromPoint?: (x: number, y: number) => CaretPosition | null;\n caretRangeFromPoint?: (x: number, y: number) => Range | null;\n};\n\nfunction caretPositionAt(x: number, y: number): CaretPosition | null {\n const doc = document as CaretDocument;\n const position = doc.caretPositionFromPoint?.(x, y);\n if (position) return position;\n const range = doc.caretRangeFromPoint?.(x, y);\n return range ? { offsetNode: range.startContainer, offset: range.startOffset } : null;\n}\n\n/** Character offset of the point within `container`'s text, or null when no caret can be placed there. */\nexport function renderedOffsetAt(container: HTMLElement, x: number, y: number): number | null {\n const position = caretPositionAt(x, y);\n if (!position || position.offsetNode.nodeType !== Node.TEXT_NODE) return null;\n if (!container.contains(position.offsetNode)) return null;\n\n const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT);\n let before = 0;\n while (walker.nextNode()) {\n if (walker.currentNode === position.offsetNode) return before + position.offset;\n before += walker.currentNode.textContent?.length ?? 0;\n }\n return null;\n}\n\nconst PROBE_LENGTHS = [40, 20, 8];\n\n/** A custom preview draws something other than the source, so the clicked text is looked\n * back up in it. Collapsing runs of whitespace is what lets a wrapped rendering match a\n * single source line, but it also makes a multi-line clicked string unfindable, so the\n * literal text is tried first and the collapsed form only after it. */\nfunction search(source: string, probe: ClickProbe): number {\n const literal = probe.clickedText.trim();\n // Clicking the block rather than a line inside it locates nothing. The end is where an\n // author can carry on writing; the top is the one place they certainly did not aim at.\n if (literal === '' || literal === probe.rendered.trim()) return source.length;\n\n const candidates = [literal, literal.replace(/\\s+/g, ' ')];\n for (const text of candidates) {\n const whole = source.indexOf(text);\n if (whole !== -1) return whole;\n }\n for (const length of PROBE_LENGTHS) {\n for (const text of candidates) {\n if (text.length < length) continue;\n const at = source.indexOf(text.slice(0, length));\n if (at !== -1) return at;\n }\n }\n return source.length;\n}\n\n/** Where in `source` the caret belongs for a click the preview reported through `probe`. */\nexport function sourceOffsetFor(source: string, probe: ClickProbe): number {\n // The stock previews draw the source verbatim, so the browser's own caret position is\n // the answer, with no searching and no ambiguity between repeated lines.\n if (probe.renderedOffset !== null && probe.rendered === source) {\n return Math.max(0, Math.min(probe.renderedOffset, source.length));\n }\n return search(source, probe);\n}\n","// Bundlers replace `process.env.NODE_ENV` at build time. Declared locally rather than\n// pulled in from @types/node, because nothing else here needs a Node environment, and\n// guarded with `typeof` so a runtime that defines no `process` still works.\ndeclare const process: { env?: { NODE_ENV?: string } } | undefined;\n\nconst seen = new Set<string>();\n\n/** Warns the developer once per distinct message, and never in a production build. */\nexport function devWarn(message: string): void {\n if (typeof process !== 'undefined' && process?.env?.NODE_ENV === 'production') return;\n if (seen.has(message)) return;\n seen.add(message);\n console.warn(`Quoin: ${message}`);\n}\n\n/** Lets a test observe the warning again; nothing in the package calls it. */\nexport function resetDevWarnings(): void {\n seen.clear();\n}\n","'use client';\n\nimport * as React from 'react';\nimport { Plus } from 'lucide-react';\nimport { useQuoin } from '../context';\nimport { paletteBlocks } from '../registry';\nimport { Button } from '../ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../ui/dropdown-menu';\n\nexport function BlockInserter({\n index,\n onInsert,\n label,\n}: {\n index: number;\n onInsert: (index: number, type: string, data?: Record<string, unknown>) => void;\n label: string;\n}) {\n const { blockTypes } = useQuoin();\n const options = paletteBlocks(blockTypes);\n const insertedAtRef = React.useRef<number | null>(null);\n\n function handleSelect(type: string) {\n insertedAtRef.current = index;\n onInsert(index, type);\n }\n\n function handleCloseAutoFocus(event: Event) {\n const insertedAt = insertedAtRef.current;\n insertedAtRef.current = null;\n if (insertedAt === null) return;\n\n event.preventDefault();\n const card = document.querySelector<HTMLElement>(`[data-block-index=\"${insertedAt}\"]`);\n if (!card) return;\n if (typeof card.scrollIntoView === 'function') {\n card.scrollIntoView({ block: 'center', behavior: 'smooth' });\n }\n card.querySelector<HTMLElement>('textarea, input, [role=\"combobox\"]')?.focus();\n }\n\n return (\n <div className=\"group/inserter relative flex h-6 items-center justify-center pointer-coarse:h-11\">\n <span\n aria-hidden=\"true\"\n className=\"absolute inset-x-0 top-1/2 h-px bg-border opacity-0 transition-opacity group-hover/inserter:opacity-100 group-focus-within/inserter:opacity-100\"\n />\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon-xs\"\n aria-label={label}\n className=\"relative z-10 rounded-full bg-background opacity-0 transition-opacity group-hover/inserter:opacity-100 group-focus-within/inserter:opacity-100 focus-visible:opacity-100 pointer-coarse:opacity-100\"\n >\n <Plus aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"center\" className=\"w-56\" onCloseAutoFocus={handleCloseAutoFocus}>\n {options.map((opt) => (\n <DropdownMenuItem key={opt.type} onSelect={() => handleSelect(opt.type)}>\n <opt.icon aria-hidden=\"true\" />\n <span>{opt.label}</span>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport type { ChangeEvent } from 'react';\nimport type { TextCommand } from '../markdown/commands';\nimport { insertCommand } from '../markdown/insert-command';\nimport { ShortcutsReference } from '../markdown/ShortcutsReference';\nimport { SlashPalette } from '../markdown/SlashPalette';\nimport { useSlashPalette } from '../markdown/useSlashPalette';\n\nconst LINE = [\n 'w-full resize-none rounded-md border-0 bg-transparent px-2 py-1 outline-none',\n 'text-base leading-7 placeholder:text-muted-foreground',\n 'transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:ring-ring/50',\n].join(' ');\n\nexport function DocumentStarter({\n autoFocus = false,\n onStart,\n onInsertBlock,\n}: {\n autoFocus?: boolean;\n onStart: (markdown: string, selection?: { start: number; end: number }) => void;\n onInsertBlock: (type: string) => void;\n}) {\n const ref = React.useRef<HTMLTextAreaElement>(null);\n const palette = useSlashPalette(ref);\n const [shortcutsOpen, setShortcutsOpen] = React.useState(false);\n\n // The line never keeps what is typed into it: the first character becomes a\n // block instead. Clearing the node directly rather than through state keeps\n // that true even when the handler causes no re-render of this component.\n function handleChange(e: ChangeEvent<HTMLTextAreaElement>) {\n const value = e.target.value;\n e.target.value = '';\n if (value === '') return;\n // A virtual keyboard, an IME or a paste delivers \"/\" with no keydown to\n // intercept, so the shortcut is recognised from the value as well.\n if (value === '/') palette.openAtCaret();\n else onStart(value);\n }\n\n function startWith(command: TextCommand) {\n palette.setOpen(false);\n const edit = insertCommand(command, '', 0);\n onStart(edit.value, { start: edit.selectionStart, end: edit.selectionEnd });\n }\n\n return (\n <div className=\"relative\">\n <textarea\n ref={ref}\n aria-label=\"Write something\"\n defaultValue=\"\"\n onChange={handleChange}\n onKeyDown={(e) => {\n if (e.key !== '/') return;\n e.preventDefault();\n palette.openAtCaret();\n }}\n autoFocus={autoFocus}\n rows={1}\n placeholder=\"Write, or press / for commands\"\n className={LINE}\n />\n <SlashPalette\n open={palette.open}\n caret={palette.caret}\n onOpenChange={palette.setOpen}\n onTextCommand={startWith}\n onBlockCommand={(type) => {\n palette.setOpen(false);\n onInsertBlock(type);\n }}\n onShortcuts={() => {\n palette.setOpen(false);\n setShortcutsOpen(true);\n }}\n onDismiss={() => palette.setOpen(false)}\n />\n <ShortcutsReference open={shortcutsOpen} onOpenChange={setShortcutsOpen} />\n </div>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport { BlockCard } from './BlockCard';\nimport type { QuoinBlock } from '../types';\n\n/** Draws the document at rest: every block's preview, with no inserters, menus, drag handles or editors. */\nexport function ReadOnlyCanvas({\n blocks,\n onUpdate,\n root,\n}: {\n blocks: QuoinBlock[];\n onUpdate: (id: string, data: Record<string, unknown>) => void;\n root: React.ComponentPropsWithRef<'div'>;\n}) {\n return (\n <div {...root}>\n <ul className=\"flex flex-col\">\n {blocks.map((b, i) => (\n <li key={b.id}>\n <div data-block-index={i} className=\"rounded-lg px-2 py-1\">\n <BlockCard block={b} index={i} editingByDefault={false} readOnly onUpdate={onUpdate} />\n </div>\n </li>\n ))}\n </ul>\n </div>\n );\n}\n","export function reorderIndices(\n ids: string[],\n activeId: string,\n overId: string | null,\n): { from: number; to: number } | null {\n if (overId === null || activeId === overId) return null;\n const from = ids.indexOf(activeId);\n const to = ids.indexOf(overId);\n if (from === -1 || to === -1) return null;\n return { from, to };\n}\n","import type { QuoinBlock } from '../types';\n\nfunction sameData(a: Record<string, unknown>, b: Record<string, unknown>): boolean {\n if (a === b) return true;\n const keys = Object.keys(a);\n if (keys.length !== Object.keys(b).length) return false;\n return keys.every((key) => Object.hasOwn(b, key) && Object.is(a[key], b[key]));\n}\n\n/** Whether two documents hold the same blocks in the same order, comparing each block's data one level deep. */\nexport function sameBlocks(a: QuoinBlock[], b: QuoinBlock[]): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n return a.every((block, i) => {\n const other = b[i];\n return block.id === other.id && block.type === other.type && sameData(block.data, other.data);\n });\n}\n","'use client';\n\nimport { useSortable } from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\nimport { GripVertical } from 'lucide-react';\nimport type { ReactNode } from 'react';\nimport { Button } from '../ui/button';\nimport { cn } from '../ui/cn';\n\n/** The gutter only leaves the text column once the viewport is wide enough to\n * hold it beside a 68ch measure, which is past `lg`. Below that it stacks above\n * the block, where it also has to stay visible: hover is not available there. */\nconst GUTTER = [\n 'flex items-center justify-end gap-0.5 pb-1',\n 'lg:absolute lg:right-full lg:top-1 lg:justify-start lg:pb-0 lg:pr-1',\n 'lg:opacity-0 lg:transition-opacity',\n 'lg:group-hover/block:opacity-100 lg:group-focus-within/block:opacity-100',\n].join(' ');\n\nexport function SortableBlock({\n id,\n index,\n actions,\n children,\n}: {\n id: string;\n index: number;\n actions?: ReactNode;\n children: ReactNode;\n}) {\n const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } =\n useSortable({ id });\n\n return (\n <div\n ref={setNodeRef}\n style={{ transform: CSS.Transform.toString(transform), transition }}\n className={cn('group/block relative', isDragging && 'z-10 opacity-80')}\n >\n <div className={GUTTER}>\n {actions}\n <Button\n type=\"button\"\n ref={setActivatorNodeRef}\n variant=\"ghost\"\n size=\"icon-sm\"\n className=\"cursor-grab text-muted-foreground active:cursor-grabbing\"\n aria-label={`Reorder block ${index + 1}`}\n {...attributes}\n {...listeners}\n >\n <GripVertical aria-hidden=\"true\" />\n </Button>\n </div>\n <div\n data-block-index={index}\n className={cn(\n 'rounded-lg px-2 py-1 transition-colors',\n isDragging ? 'bg-popover shadow-md' : 'group-hover/block:bg-muted/40',\n )}\n >\n {children}\n </div>\n </div>\n );\n}\n","import type { QuoinBlock } from '../types';\n\n/** A host may coalesce or drop echoes, so the outstanding set is capped instead of trusted to drain. */\nconst UNACKNOWLEDGED_LIMIT = 64;\n\n/** Records an emitted document as awaiting its echo, dropping the oldest once the cap is reached. */\nexport function remember(outstanding: Set<QuoinBlock[]>, blocks: QuoinBlock[]) {\n outstanding.add(blocks);\n while (outstanding.size > UNACKNOWLEDGED_LIMIT) {\n const oldest = outstanding.values().next();\n if (oldest.done) return;\n outstanding.delete(oldest.value);\n }\n}\n","import * as React from 'react';\n\n/** Where a debounced save stands, for a \"Saving...\" or \"Saved\" indicator. */\nexport type AutosaveStatus = 'idle' | 'saving' | 'saved' | 'retrying';\n\n/**\n * Whether a resolved save reported failure. Only an explicit `{ ok: false }` counts, so a\n * `save` that resolves to a response body, a mutation result or nothing at all is a success\n * and needs no wrapper to discard its value. Rejecting is still the other way to fail.\n */\nfunction reportedFailure(result: unknown): boolean {\n return (\n typeof result === 'object' &&\n result !== null &&\n 'ok' in result &&\n (result as { ok?: unknown }).ok === false\n );\n}\n\n/** What `useAutosave` tracks, how to build the payload, and how to persist it. */\nexport type UseAutosaveInput<T> = {\n /** The tracked fields. An edit to any of them marks dirty and restarts the debounce. */\n deps: React.DependencyList;\n build: () => T;\n /**\n * Persists the payload. Return anything: a mutation or a `fetch` that resolves to a body\n * can be passed straight in. A save fails by rejecting, or by resolving to `{ ok: false }`.\n */\n save: (payload: T) => unknown;\n debounceMs?: number;\n maxBackoffMs?: number;\n};\n\n/** The current save status and a way to retry a failed save immediately. */\nexport type UseAutosaveResult = {\n status: AutosaveStatus;\n retry: () => void;\n};\n\n/**\n * Debounced last-write-wins autosave. Nothing fires on mount, only after the first\n * real edit, and a rejected save backs off exponentially until it lands. `save` and\n * `build` are read at fire time, so passing fresh closures each render is safe.\n */\nexport function useAutosave<T>({\n deps,\n build,\n save,\n debounceMs = 2000,\n maxBackoffMs = 30000,\n}: UseAutosaveInput<T>): UseAutosaveResult {\n // The effect order below is load-bearing: the dirty flag must be set before the\n // scheduling effect reads it within the same commit, and the \"latest closure\" refs\n // must be assigned after commit rather than during render.\n const [status, setStatus] = React.useState<AutosaveStatus>('idle');\n const dirtyRef = React.useRef(false);\n const retryRef = React.useRef(0);\n const backoffRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n const buildRef = React.useRef(build);\n const saveRef = React.useRef(save);\n const runRef = React.useRef<() => void>(() => {});\n\n React.useEffect(() => {\n buildRef.current = build;\n saveRef.current = save;\n runRef.current = () => {\n void (async () => {\n setStatus('saving');\n try {\n const res = await saveRef.current(buildRef.current());\n if (reportedFailure(res)) throw new Error('save rejected');\n retryRef.current = 0;\n dirtyRef.current = false;\n setStatus('saved');\n } catch {\n setStatus('retrying');\n retryRef.current += 1;\n const delay = Math.min(debounceMs * 2 ** retryRef.current, maxBackoffMs);\n if (backoffRef.current) clearTimeout(backoffRef.current);\n backoffRef.current = setTimeout(() => runRef.current(), delay);\n }\n })();\n };\n });\n\n // Compares values rather than counting mounts: React's development remount\n // re-runs this effect with identical deps, and a \"have I mounted\" flag survives\n // that remount, so a flag marks an untouched editor dirty and autosaves it.\n const seenRef = React.useRef<React.DependencyList | null>(null);\n React.useEffect(() => {\n const seen = seenRef.current;\n seenRef.current = deps;\n if (seen === null) return;\n const unchanged = seen.length === deps.length && seen.every((v, i) => v === deps[i]);\n if (!unchanged) dirtyRef.current = true;\n // eslint-disable-next-line react-hooks/exhaustive-deps -- the caller owns the tracked fields\n }, deps);\n\n React.useEffect(() => {\n if (!dirtyRef.current) return;\n const handle = setTimeout(() => runRef.current(), debounceMs);\n return () => clearTimeout(handle);\n // eslint-disable-next-line react-hooks/exhaustive-deps -- the caller owns the tracked fields\n }, deps);\n\n React.useEffect(\n () => () => {\n if (backoffRef.current) clearTimeout(backoffRef.current);\n },\n [],\n );\n\n const retry = React.useCallback(() => {\n if (backoffRef.current) clearTimeout(backoffRef.current);\n runRef.current();\n }, []);\n\n return { status, retry };\n}\n"],"mappings":"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","names":["React","seen","Code","React","jsx","jsx","jsx","jsxs","jsx","jsx","jsxs","jsx","jsx","jsxs","jsx","jsxs","jsxs","jsx","jsx","jsx","jsx","jsx","jsxs","React","text","at","INDENT","at","React","React","jsx","jsxs","jsx","jsxs","jsx","jsx","jsxs","jsx","jsx","jsxs","useEffect","useRef","React","jsx","jsxs","jsx","jsxs","useRef","useEffect","jsx","jsxs","jsx","Code","React","CheckIcon","jsx","jsxs","jsx","jsx","jsx","jsxs","React","jsx","jsx","jsxs","React","jsx","jsxs","React","jsx","jsxs","jsx","jsx","jsxs","jsx","jsxs","newBlockId","id","React","seen"]}
1
+ {"version":3,"sources":["../src/canvas/BlockCanvas.tsx","../src/context.tsx","../src/registry.ts","../src/blocks/core.ts","../src/blocks/MarkdownBlockEditor.tsx","../src/upload/FilePickerButton.tsx","../src/ui/button.tsx","../src/ui/cn.ts","../src/ui/focus.ts","../src/ui/touch-target.ts","../src/markdown/edit.ts","../src/markdown/line-at.ts","../src/markdown/insert-command.ts","../src/markdown/platform.ts","../src/markdown/shortcut-label.ts","../src/ui/dialog.tsx","../src/markdown/ShortcutsReference.tsx","../src/markdown/SlashPalette.tsx","../src/markdown/commands.ts","../src/ui/command.tsx","../src/ui/popover.tsx","../src/markdown/useMarkdownKeymap.ts","../src/markdown/list-continuation.ts","../src/markdown/indent-list.ts","../src/markdown/line-toggles.ts","../src/markdown/slash-trigger.ts","../src/markdown/wrap-selection.ts","../src/markdown/useSlashPalette.ts","../src/markdown/caret-coordinates.ts","../src/hooks/useAutoGrow.ts","../src/hooks/use-isomorphic-layout-effect.ts","../src/blocks/str.ts","../src/ui/select.tsx","../src/ui/textarea.tsx","../src/blocks/CalloutBlockEditor.tsx","../src/ui/input.tsx","../src/blocks/CodeBlockEditor.tsx","../src/blocks/ImageBlockEditor.tsx","../src/upload/UploadField.tsx","../src/blocks/intrinsic-size.ts","../src/blocks/FileBlockEditor.tsx","../src/blocks/previews.tsx","../src/hooks/useBlockList.ts","../src/hooks/new-block-id.ts","../src/canvas/announcements.ts","../src/canvas/BlockActionsMenu.tsx","../src/ui/dropdown-menu.tsx","../src/canvas/BlockCard.tsx","../src/canvas/BlockEditor.tsx","../src/canvas/source-offset.ts","../src/dev-warn.ts","../src/canvas/BlockInserter.tsx","../src/canvas/DocumentStarter.tsx","../src/canvas/ReadOnlyCanvas.tsx","../src/canvas/reorder-indices.ts","../src/canvas/same-blocks.ts","../src/canvas/SortableBlock.tsx","../src/canvas/unacknowledged.ts","../src/hooks/useAutosave.ts","../src/hooks/autosave-backoff.ts"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport {\n DndContext,\n KeyboardSensor,\n PointerSensor,\n closestCenter,\n useSensor,\n useSensors,\n type DragEndEvent,\n} from '@dnd-kit/core';\nimport { restrictToVerticalAxis } from '@dnd-kit/modifiers';\nimport { SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy } from '@dnd-kit/sortable';\nimport { QuoinProvider } from '../context';\nimport { blockByType, type AnyBlockDefinition } from '../registry';\nimport { coreBlocks } from '../blocks/core';\nimport type { QuoinBlock, UploadFn } from '../types';\nimport { useBlockList } from '../hooks/useBlockList';\nimport { cn } from '../ui/cn';\nimport { buildAnnouncements } from './announcements';\nimport { BlockActionsMenu } from './BlockActionsMenu';\nimport { BlockCard } from './BlockCard';\nimport { BlockInserter } from './BlockInserter';\nimport { DocumentStarter } from './DocumentStarter';\nimport { ReadOnlyCanvas } from './ReadOnlyCanvas';\nimport { reorderIndices } from './reorder-indices';\nimport { sameBlocks } from './same-blocks';\nimport { SortableBlock } from './SortableBlock';\nimport { acknowledge, createUnacknowledged, forgetAll, remember } from './unacknowledged';\n\n/** Props for `BlockCanvas`; `blocks` and `onChange` are the whole document contract. */\nexport type BlockCanvasProps = {\n /**\n * The document. Update it synchronously from `onChange`, as with a controlled `<input value onChange>`.\n * Applying the edit late is tolerated: the canvas recognises an array it emitted however late it comes back, and\n * a structural copy of one within 64 edits, so a transition, a debounced setter or a store that clones the\n * document on the way through is safe.\n * A new array that differs from the last one you supplied replaces what the canvas shows, which is how a host\n * loads, undoes or merges. An array structurally equal to the last one you supplied is ignored, so a \"discard\n * changes\" button that hands back the original document does nothing. A host that does not echo `onChange` back\n * meets the same when it restores a copy of a state from the last 64 edits, which reads as a late echo. Remount\n * the canvas with a React `key` to force a reset in either case. The comparison is shallow over each block's\n * `data`: a host whose block `data` holds nested objects rebuilt on every render, and which does not echo\n * `onChange` back, can still lose an edit. The core block types all have flat data, so this only affects custom\n * blocks.\n */\n blocks: QuoinBlock[];\n onChange: (blocks: QuoinBlock[]) => void;\n /**\n * Called when a block is removed through its actions menu, with the block and the index it held.\n * It runs just after the `onChange` that reports the document without it, so a host acting on the\n * deletion is already looking at the new array. Restore the block by supplying a `blocks` array\n * with it spliced back at that index, the same way any other document arrives.\n *\n * Restore it on a later tick or a later interaction, such as the click of an Undo toast. A\n * restore applied synchronously inside this callback batches with the echo of the deletion, so\n * what arrives is structurally equal to the document last supplied and is ignored.\n */\n onDelete?: (block: QuoinBlock, index: number) => void;\n /** Defaults to the five core block types. Pass `[...coreBlocks, yours]` to extend them. */\n blockTypes?: AnyBlockDefinition[];\n upload?: UploadFn;\n resolveAssetUrl?: (storageKey: string) => string;\n onError?: (error: Error) => void;\n /** Renders the document with no inserters, menus, drag handles or editors. */\n readOnly?: boolean;\n /** Added to the root element's own classes rather than replacing them. */\n className?: string;\n id?: string;\n /** Names the document for assistive technology; the root then becomes a labelled group. */\n 'aria-label'?: string;\n};\n\ntype Selection = { start: number; end: number };\n\nfunction Canvas({\n blocks,\n onChange,\n onDelete,\n blockTypes,\n readOnly,\n className,\n id,\n 'aria-label': ariaLabel,\n}: Pick<\n BlockCanvasProps,\n 'blocks' | 'onChange' | 'onDelete' | 'readOnly' | 'className' | 'id' | 'aria-label'\n> & {\n blockTypes: AnyBlockDefinition[];\n}) {\n const list = useBlockList(blocks);\n const { insertAt, update, remove, move, reorder, reset } = list;\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 4 } }),\n useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),\n );\n const dndId = React.useId();\n const [newBlockId, setNewBlockId] = React.useState<string | null>(null);\n const [seedSelection, setSeedSelection] = React.useState<Selection | null>(null);\n const listRef = React.useRef<HTMLDivElement>(null);\n const pendingDeleteIndexRef = React.useRef<number | null>(null);\n const removedRef = React.useRef<{ block: QuoinBlock; index: number } | null>(null);\n const announcements = React.useMemo(\n () => buildAnnouncements(list.blocks, blockTypes),\n [list.blocks, blockTypes],\n );\n\n // The reducer reads `blocks` once, so the two effects below carry the document\n // across the boundary in both directions. An array this canvas emitted, or a\n // structural copy of a recent one, is recognised when the host hands it back\n // and is not reset; any other array the host supplies is foreign and is.\n // Seeding the refs with the first `blocks` keeps mounting from reporting a\n // change nobody made.\n const lastEmitted = React.useRef<QuoinBlock[]>(blocks);\n const lastSupplied = React.useRef<QuoinBlock[]>(blocks);\n // Every emission still waiting to come back, not just the newest: a host that applies\n // edits late hands back an array from several keystrokes ago, and recognising only the\n // newest would read that as a foreign document and overwrite live text with it.\n const unacknowledged = React.useRef(createUnacknowledged());\n\n React.useEffect(() => {\n if (list.blocks === lastEmitted.current) return;\n lastEmitted.current = list.blocks;\n remember(unacknowledged.current, list.blocks);\n onChange(list.blocks);\n const removed = removedRef.current;\n removedRef.current = null;\n if (removed) onDelete?.(removed.block, removed.index);\n }, [list.blocks, onChange, onDelete]);\n\n React.useEffect(() => {\n const previous = lastSupplied.current;\n lastSupplied.current = blocks;\n if (acknowledge(unacknowledged.current, blocks)) return;\n // A host that builds a fresh array on every render, without echoing edits, would\n // otherwise wipe them on any unrelated re-render. An undo replays a different array.\n // The cost of the `previous` half is that a restore applied synchronously inside\n // `onDelete` batches with the echo, arrives structurally equal to the last document\n // supplied, and is read as one of those re-renders. That is why `onDelete` documents\n // restoring on a later tick. Dropping this comparison to accept the synchronous case\n // would hand back the edit-wiping bug, which is the worse of the two.\n if (sameBlocks(blocks, previous) || sameBlocks(blocks, list.blocks)) return;\n forgetAll(unacknowledged.current);\n lastEmitted.current = blocks;\n reset(blocks);\n }, [blocks, reset]);\n\n // The new card reads these as it mounts. Kept any longer they would reopen it\n // on a later remount, such as a read-only round trip or a host undo.\n React.useEffect(() => {\n if (newBlockId === null) return;\n setNewBlockId(null);\n setSeedSelection(null);\n }, [newBlockId]);\n\n const insertPlain = React.useCallback(\n (index: number, type: string, data?: Record<string, unknown>) => {\n const seed = data ?? blockByType(blockTypes, type)?.initialData?.() ?? {};\n setNewBlockId(insertAt(index, type, seed));\n },\n [insertAt, blockTypes],\n );\n\n function handleDelete(index: number, id: string) {\n const block = list.blocks[index];\n pendingDeleteIndexRef.current = index;\n if (block) removedRef.current = { block, index };\n remove(id);\n }\n\n React.useEffect(() => {\n const index = pendingDeleteIndexRef.current;\n pendingDeleteIndexRef.current = null;\n if (index === null || !listRef.current) return;\n const landingIndex = Math.min(index, list.blocks.length - 1);\n const card =\n landingIndex >= 0 ? listRef.current.querySelector<HTMLElement>(`[data-block-index=\"${landingIndex}\"]`) : null;\n (card?.querySelector<HTMLElement>('button') ?? listRef.current.querySelector<HTMLElement>('button'))?.focus();\n }, [list.blocks]);\n\n function handleDragEnd(event: DragEndEvent) {\n const { active, over } = event;\n const result = reorderIndices(\n list.blocks.map((b) => b.id),\n String(active.id),\n over ? String(over.id) : null,\n );\n if (result) reorder(result.from, result.to);\n }\n\n const rootProps = {\n ref: listRef,\n id,\n className: cn('quoin flex flex-col', className),\n role: ariaLabel ? 'group' : undefined,\n 'aria-label': ariaLabel,\n };\n\n if (readOnly) return <ReadOnlyCanvas blocks={list.blocks} onUpdate={update} root={rootProps} />;\n\n return (\n <div {...rootProps}>\n <BlockInserter index={0} onInsert={insertPlain} label=\"Insert a block at the start\" canvasRef={listRef} />\n <DndContext\n id={dndId}\n sensors={sensors}\n collisionDetection={closestCenter}\n modifiers={[restrictToVerticalAxis]}\n accessibility={{ announcements }}\n onDragEnd={handleDragEnd}\n >\n <SortableContext items={list.blocks.map((b) => b.id)} strategy={verticalListSortingStrategy}>\n <ul className=\"flex flex-col\">\n {list.blocks.map((b, i) => (\n <li key={b.id}>\n <SortableBlock\n id={b.id}\n index={i}\n actions={\n <BlockActionsMenu\n index={i}\n count={list.blocks.length}\n label={blockByType(blockTypes, b.type)?.label ?? b.type}\n onMove={move}\n onDelete={() => handleDelete(i, b.id)}\n />\n }\n >\n <BlockCard\n block={b}\n index={i}\n editingByDefault={b.id === newBlockId}\n initialSelection={b.id === newBlockId ? seedSelection : null}\n onUpdate={update}\n onInsertBlock={insertPlain}\n />\n </SortableBlock>\n <BlockInserter\n index={i + 1}\n onInsert={insertPlain}\n label={`Insert a block after block ${i + 1}`}\n canvasRef={listRef}\n />\n </li>\n ))}\n </ul>\n </SortableContext>\n </DndContext>\n <DocumentStarter\n autoFocus={list.blocks.length === 0}\n onStart={(markdown, selection) => {\n setSeedSelection(selection ?? null);\n setNewBlockId(insertAt(list.blocks.length, 'MARKDOWN', { markdown }));\n }}\n onInsertBlock={(type) => insertPlain(list.blocks.length, type)}\n />\n </div>\n );\n}\n\n/** The editor: renders `blocks`, reports every edit through `onChange`, and accepts a new `blocks` array from outside at any time. */\nexport function BlockCanvas({\n blocks,\n onChange,\n onDelete,\n blockTypes = coreBlocks,\n upload,\n resolveAssetUrl,\n onError,\n readOnly = false,\n className,\n id,\n 'aria-label': ariaLabel,\n}: BlockCanvasProps) {\n const config = React.useMemo(\n () => ({ blockTypes, upload, resolveAssetUrl, onError }),\n [blockTypes, upload, resolveAssetUrl, onError],\n );\n return (\n <QuoinProvider value={config}>\n <Canvas\n blocks={blocks}\n onChange={onChange}\n onDelete={onDelete}\n blockTypes={blockTypes}\n readOnly={readOnly}\n className={className}\n id={id}\n aria-label={ariaLabel}\n />\n </QuoinProvider>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport type { AnyBlockDefinition } from './registry';\nimport type { UploadFn } from './types';\n\n/** The resolved canvas configuration every block editor reads through `useQuoin`. */\nexport type QuoinConfig = {\n blockTypes: AnyBlockDefinition[];\n /** Absent when the host has not wired uploads; upload fields then render disabled. */\n upload?: UploadFn;\n resolveAssetUrl: (storageKey: string) => string;\n onError: (error: Error) => void;\n};\n\n/** What a host passes to `QuoinProvider`: only the block types are required. */\nexport type QuoinConfigInput = Partial<QuoinConfig> & {\n blockTypes: AnyBlockDefinition[];\n};\n\nconst QuoinContext = React.createContext<QuoinConfig | null>(null);\n\n/** Supplies the block registry and the host couplings (upload, asset URLs, error reporting) to every block below it. */\nexport function QuoinProvider({\n value,\n children,\n}: {\n value: QuoinConfigInput;\n children: React.ReactNode;\n}) {\n const { blockTypes, upload, resolveAssetUrl, onError } = value;\n const config = React.useMemo<QuoinConfig>(\n () => ({\n blockTypes,\n upload,\n // Identity default: an empty key resolves to an empty string, which stays falsy\n // wherever a resolved URL is tested for \"no asset chosen yet\".\n resolveAssetUrl: resolveAssetUrl ?? ((key: string) => key),\n onError: onError ?? ((error: Error) => console.error(error)),\n }),\n [blockTypes, upload, resolveAssetUrl, onError],\n );\n return <QuoinContext.Provider value={config}>{children}</QuoinContext.Provider>;\n}\n\n/** Reads the canvas configuration. Throws outside a QuoinProvider rather than returning a silent default. */\nexport function useQuoin(): QuoinConfig {\n const config = React.useContext(QuoinContext);\n if (!config) throw new Error('useQuoin must be used inside a QuoinProvider.');\n return config;\n}\n","import type { ComponentType } from 'react';\nimport type { LucideIcon } from 'lucide-react';\nimport type { BlockEditorProps, BlockPreviewProps } from './types';\n\n/** The fields every block definition carries, whatever it can do with its data. */\ntype BlockDefinitionCommon<D extends object> = {\n type: string;\n label: string;\n icon: LucideIcon;\n /**\n * Called when a new block of this type is inserted, to seed its data.\n * `NoInfer` keeps `D` inferred from `editor` and `preview` alone, so the seed is checked\n * against the editor's data type instead of widening it.\n */\n initialData?: () => NoInfer<D>;\n /** Whether the block is offered in the slash palette and inserter; defaults to true. */\n inSlashPalette?: boolean;\n /**\n * Renders this block's editor permanently instead of a preview you click to edit.\n * Also supply a `preview`: a read-only canvas draws the preview rather than the editor,\n * so without one the block's content is invisible there.\n */\n alwaysEditing?: boolean;\n};\n\n/**\n * Describes one block type: how to label it, how to draw it at rest, how to edit it.\n *\n * Supply `editor`, `preview`, or both, and the canvas does the rest. A definition with no\n * `preview` is edit-only: a read-only canvas has nothing to draw for it but its label.\n * A definition with no `editor` can never be edited in the canvas, which is what a block\n * whose content belongs to a server-side record wants; the card offers no edit affordance\n * for it and a click goes through to whatever the preview itself renders.\n *\n * Omitting both is a type error, because such a block would only ever draw its own label.\n */\nexport type BlockDefinition<D extends object = Record<string, unknown>> =\n | (BlockDefinitionCommon<D> & {\n editor: ComponentType<BlockEditorProps<D>>;\n /**\n * What the block shows when it is not being edited. Optional so a host can register an\n * edit-only block type, and overridable so a host can supply rich rendering (a full\n * markdown pipeline, a chart) without Quoin depending on one.\n */\n preview?: ComponentType<BlockPreviewProps<D>>;\n })\n | (BlockDefinitionCommon<D> & {\n /** Omitted: this block is never editable in the canvas. */\n editor?: undefined;\n /** Required here, because it is the only thing that can draw the block. */\n preview: ComponentType<BlockPreviewProps<D>>;\n });\n\n/** A definition with its data type erased, so definitions of different shapes compose in one array. */\nexport type AnyBlockDefinition = BlockDefinition<Record<string, unknown>>;\n\n/**\n * Types `data` inside your editor component, then erases the generic on the way out.\n * The erasure is deliberate: `D` appears in both covariant and contravariant positions\n * on `editor`, so without it an array of differently-shaped definitions will not typecheck.\n * `initialData` is checked against the editor's data type. That relies on `NoInfer`, so\n * TypeScript 5.4 or later is required.\n *\n * `D` defaults to `Record<string, unknown>`, so a definition whose components take no\n * annotation still gets a usable `data` rather than a bare `object`.\n */\nexport function defineBlock<D extends object = Record<string, unknown>>(\n definition: BlockDefinition<D>,\n): AnyBlockDefinition {\n return definition as unknown as AnyBlockDefinition;\n}\n\n/** The definition for a type, or undefined; the last registration of a type wins, so a host can override a core block. */\nexport function blockByType(\n definitions: AnyBlockDefinition[],\n type: string,\n): AnyBlockDefinition | undefined {\n for (let i = definitions.length - 1; i >= 0; i -= 1) {\n if (definitions[i].type === type) return definitions[i];\n }\n return undefined;\n}\n\n/** The definitions offered in the slash palette, in registration order, one per type, with the last registration of a type winning. */\nexport function paletteBlocks(definitions: AnyBlockDefinition[]): AnyBlockDefinition[] {\n const seen = new Set<string>();\n const out: AnyBlockDefinition[] = [];\n for (let i = definitions.length - 1; i >= 0; i -= 1) {\n const d = definitions[i];\n if (seen.has(d.type)) continue;\n // Claim the type BEFORE honouring the opt-out, so a hidden override suppresses the\n // definition it replaces instead of letting the earlier one reappear. Without this,\n // the palette can offer a block that `blockByType` resolves to a different definition.\n seen.add(d.type);\n if (d.inSlashPalette === false) continue;\n out.push(d);\n }\n return out.reverse();\n}\n","import { Code, FileText, MessageSquare, Image, Paperclip } from 'lucide-react';\nimport { defineBlock, type AnyBlockDefinition } from '../registry';\nimport { MarkdownBlockEditor } from './MarkdownBlockEditor';\nimport { CalloutBlockEditor } from './CalloutBlockEditor';\nimport { CodeBlockEditor } from './CodeBlockEditor';\nimport { ImageBlockEditor } from './ImageBlockEditor';\nimport { FileBlockEditor } from './FileBlockEditor';\nimport {\n MarkdownPreview,\n CalloutPreview,\n CodePreview,\n ImagePreview,\n FilePreview,\n} from './previews';\n\n/** The block types Quoin ships with. Spread them alongside your own definitions. */\nexport const coreBlocks: AnyBlockDefinition[] = [\n defineBlock({\n type: 'MARKDOWN',\n label: 'Markdown',\n icon: FileText,\n editor: MarkdownBlockEditor,\n preview: MarkdownPreview,\n initialData: () => ({ markdown: '' }),\n }),\n defineBlock({\n type: 'CALLOUT',\n label: 'Callout',\n icon: MessageSquare,\n editor: CalloutBlockEditor,\n preview: CalloutPreview,\n initialData: () => ({ tone: 'info', body: '' }),\n }),\n defineBlock({\n type: 'CODE',\n label: 'Code',\n icon: Code,\n editor: CodeBlockEditor,\n preview: CodePreview,\n initialData: () => ({ language: '', code: '' }),\n }),\n defineBlock({\n type: 'IMAGE',\n label: 'Image',\n icon: Image,\n editor: ImageBlockEditor,\n preview: ImagePreview,\n initialData: () => ({ storageKey: '', alt: '' }),\n }),\n defineBlock({\n type: 'FILE',\n label: 'File',\n icon: Paperclip,\n editor: FileBlockEditor,\n preview: FilePreview,\n initialData: () => ({ storageKey: '', filename: '' }),\n }),\n];\n","'use client';\n\nimport * as React from 'react';\nimport { useQuoin } from '../context';\nimport { FilePickerButton } from '../upload/FilePickerButton';\nimport { applyEdit } from '../markdown/edit';\nimport { insertCommand } from '../markdown/insert-command';\nimport { ShortcutsReference } from '../markdown/ShortcutsReference';\nimport { SlashPalette } from '../markdown/SlashPalette';\nimport { useMarkdownKeymap } from '../markdown/useMarkdownKeymap';\nimport { useSlashPalette } from '../markdown/useSlashPalette';\nimport type { TextCommand } from '../markdown/commands';\nimport { useAutoGrow } from '../hooks/useAutoGrow';\nimport type { BlockEditorProps } from '../types';\nimport { FOCUS_RING } from '../ui/focus';\nimport { str } from './str';\n\nconst BOX = [\n '-mx-2 min-h-7 w-[calc(100%+1rem)] resize-none rounded-md border-0 bg-transparent px-2 py-0',\n 'text-base leading-7 placeholder:text-muted-foreground',\n 'transition-[color,box-shadow]',\n FOCUS_RING,\n].join(' ');\n\nexport function MarkdownBlockEditor({ data, onChange, onInsertBlock, onDone }: BlockEditorProps) {\n const { onError } = useQuoin();\n const markdown = str(data.markdown);\n const ref = useAutoGrow<HTMLTextAreaElement>(markdown);\n const palette = useSlashPalette(ref);\n const [shortcutsOpen, setShortcutsOpen] = React.useState(false);\n\n const set = (patch: Record<string, unknown>) => onChange({ ...data, ...patch });\n // The keymap memoises its handlers on this, so a fresh closure every render would\n // rebuild them on every render too, including the ones a palette or dialog causes.\n const commit = React.useCallback(\n (next: string) => onChange({ ...data, markdown: next }),\n [data, onChange],\n );\n\n const keymap = useMarkdownKeymap({ commit, onOpenPalette: palette.openAtCaret });\n\n function reopenBox(): HTMLTextAreaElement | null {\n const el = ref.current;\n el?.focus({ preventScroll: true });\n return el ?? null;\n }\n\n function runTextCommand(command: TextCommand) {\n palette.setOpen(false);\n const el = reopenBox();\n if (!el) return;\n applyEdit(el, insertCommand(command, el.value, palette.offsetRef.current), commit);\n }\n\n function writeLiteralSlash() {\n palette.setOpen(false);\n const el = reopenBox();\n if (!el) return;\n const at = palette.offsetRef.current;\n applyEdit(\n el,\n { value: `${el.value.slice(0, at)}/${el.value.slice(at)}`, selectionStart: at + 1, selectionEnd: at + 1 },\n commit,\n );\n }\n\n function readMarkdownFile(file: File) {\n const reader = new FileReader();\n reader.onload = () => {\n const text = typeof reader.result === 'string' ? reader.result : '';\n if (text.trim() === '') {\n onError(new Error(`${file.name} is empty.`));\n return;\n }\n set({ markdown: text });\n onDone?.();\n };\n reader.onerror = () => onError(new Error(`Could not read ${file.name}.`));\n reader.readAsText(file);\n }\n\n return (\n <div className=\"relative flex flex-col gap-3\">\n <textarea\n ref={ref}\n aria-label=\"Markdown\"\n value={markdown}\n rows={1}\n placeholder=\"Write, or press / for commands\"\n onChange={(e) => set({ markdown: e.target.value })}\n onKeyDown={keymap.onKeyDown}\n onPaste={keymap.onPaste}\n className={BOX}\n />\n <SlashPalette\n open={palette.open}\n caret={palette.caret}\n onOpenChange={palette.setOpen}\n onTextCommand={runTextCommand}\n onBlockCommand={(type) => {\n palette.setOpen(false);\n onInsertBlock?.(type);\n onDone?.();\n }}\n onShortcuts={() => {\n palette.setOpen(false);\n setShortcutsOpen(true);\n }}\n onDismiss={writeLiteralSlash}\n />\n <ShortcutsReference open={shortcutsOpen} onOpenChange={setShortcutsOpen} />\n {markdown.trim() === '' && (\n <FilePickerButton\n label=\"Upload .md\"\n accept=\".md,text/markdown,text/plain\"\n onPick={readMarkdownFile}\n />\n )}\n </div>\n );\n}\n","'use client';\n\nimport { Upload } from 'lucide-react';\nimport { Button } from '../ui/button';\n\n/** Props for `FilePickerButton`. */\nexport type FilePickerButtonProps = {\n /** Labels the button and the file input behind it. */\n label: string;\n /** An `accept` attribute for the file input, such as `'image/*'` or `'.pdf'`. */\n accept?: string;\n /** Greys the button out and disables the input behind it. */\n disabled?: boolean;\n /** Called with the chosen file, and again if the same file is picked after a failure. */\n onPick: (file: File) => void;\n};\n\n/** A button that opens the file picker and hands back the chosen file, performing no upload of its own. */\n// The input itself stays focusable and labelled, laid transparently over the\n// button, so the keyboard and the pointer both land on the real control. The\n// wrapper paints the focus ring the invisible input cannot show.\nexport function FilePickerButton({ label, accept, disabled, onPick }: FilePickerButtonProps) {\n return (\n <span className=\"relative inline-flex rounded-md has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-2 has-[:focus-visible]:outline-[var(--quoin-ring)]\">\n <Button asChild variant=\"outline\" size=\"sm\">\n <span aria-hidden=\"true\" className={disabled ? 'pointer-events-none opacity-50' : undefined}>\n <Upload aria-hidden=\"true\" />\n {label}\n </span>\n </Button>\n <input\n type=\"file\"\n accept={accept}\n aria-label={label}\n disabled={disabled}\n className=\"absolute inset-0 cursor-pointer opacity-0 disabled:cursor-not-allowed\"\n onChange={(e) => {\n const file = e.target.files?.[0];\n // Clear so picking the same file again still fires `change`, which is what makes retry after a failed upload work.\n e.target.value = '';\n if (file) onPick(file);\n }}\n />\n </span>\n );\n}\n","import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"./cn\";\nimport { FOCUS_RING } from \"./focus\";\nimport { SQUARE_TAP_TARGET_FLOOR, TAP_TARGET_FLOOR } from \"./touch-target\";\n\n/** Class variants for the button primitive, reusable on other elements. */\nconst buttonVariants = cva(\n [\n \"inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,background-color,border-color,box-shadow,opacity] disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 shrink-0\",\n FOCUS_RING,\n ],\n {\n variants: {\n variant: {\n default:\n \"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white shadow-xs hover:bg-destructive/90 dark:bg-destructive/60 dark:hover:bg-destructive/75\",\n outline:\n \"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n ghost: \"hover:bg-accent hover:text-accent-foreground\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: `h-9 px-4 py-2 has-[>svg]:px-3 ${TAP_TARGET_FLOOR}`,\n xs: `h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3 ${TAP_TARGET_FLOOR}`,\n sm: `h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5 ${TAP_TARGET_FLOOR}`,\n lg: `h-10 rounded-md px-6 has-[>svg]:px-4 ${TAP_TARGET_FLOOR}`,\n icon: `size-9 ${SQUARE_TAP_TARGET_FLOOR}`,\n \"icon-xs\": `size-6 rounded-md [&_svg:not([class*='size-'])]:size-3 ${SQUARE_TAP_TARGET_FLOOR}`,\n \"icon-sm\": `size-8 ${SQUARE_TAP_TARGET_FLOOR}`,\n \"icon-lg\": `size-10 ${SQUARE_TAP_TARGET_FLOOR}`,\n },\n },\n defaultVariants: { variant: \"default\", size: \"default\" },\n },\n);\n\ntype ButtonProps = React.ComponentPropsWithoutRef<\"button\"> &\n VariantProps<typeof buttonVariants> & { asChild?: boolean };\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n { className, variant = \"default\", size = \"default\", asChild = false, ...props },\n ref,\n) {\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n ref={ref}\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n});\n\nexport { Button, buttonVariants };\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/** Merges class names, with later Tailwind utilities overriding earlier conflicting ones. */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","/** A solid 2px keyboard focus outline in --quoin-ring. An outline rather than a ring, because\n * forced-colors mode drops box-shadow. The explicit solid style is load-bearing: the hidden\n * outline utility sets the style to none, and the width utility reads that style back. */\nexport const FOCUS_RING = [\n 'outline-hidden',\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-solid',\n 'focus-visible:outline-[var(--quoin-ring)]',\n].join(' ');\n\n/** An inset bar that marks the highlighted row of a Radix menu or select, so the row is not\n * told apart from its neighbours by background colour alone. */\nexport const HIGHLIGHT_BAR = 'data-[highlighted]:shadow-[inset_2px_0_0_var(--quoin-foreground)]';\n\n/** The same bar for a cmdk row, which reports its highlight as data-selected. */\nexport const SELECTED_BAR = 'data-[selected=true]:shadow-[inset_2px_0_0_var(--quoin-foreground)]';\n","/** 44px is the platform minimum for a finger. It is applied as a floor rather than\n * a height so a control keeps its own pointer-precise size, and only where the\n * primary pointer is coarse so mouse-driven layouts keep their density. */\nexport const TAP_TARGET_FLOOR = 'pointer-coarse:min-h-11';\n\n/** The pointer-coarse sizing floor on both axes, for square icon controls. */\nexport const SQUARE_TAP_TARGET_FLOOR = `${TAP_TARGET_FLOOR} pointer-coarse:min-w-11`;\n\n/** For an icon control pinned to a corner, where growing the box would drag the icon\n * inward. The target is a centred, transparent pseudo-element instead, so the hit\n * area reaches 44px while the icon keeps its own size and position. Requires the\n * control to be positioned, which a pinned one already is. */\nexport const ICON_TAP_TARGET_FLOOR = [\n \"pointer-coarse:before:absolute pointer-coarse:before:top-1/2 pointer-coarse:before:left-1/2\",\n 'pointer-coarse:before:size-11 pointer-coarse:before:-translate-x-1/2 pointer-coarse:before:-translate-y-1/2',\n \"pointer-coarse:before:content-['']\",\n].join(' ');\n","/** A text transform result: the next value and where the selection should land. */\nexport type Edit = { value: string; selectionStart: number; selectionEnd: number };\n\nfunction changedSpan(before: string, after: string) {\n let start = 0;\n const shortest = Math.min(before.length, after.length);\n while (start < shortest && before[start] === after[start]) start += 1;\n\n let endBefore = before.length;\n let endAfter = after.length;\n while (endBefore > start && endAfter > start && before[endBefore - 1] === after[endAfter - 1]) {\n endBefore -= 1;\n endAfter -= 1;\n }\n\n return { start, endBefore, replacement: after.slice(start, endAfter) };\n}\n\n// Writing through execCommand keeps the transform as one entry on the browser's\n// own undo stack. Either path commits el.value rather than the edit's intended\n// value: a browser is trusted to write what it was asked, and if it ever\n// wrote something else, committing our own intent instead would silently\n// diverge React's state from the DOM.\nfunction writeNatively(el: HTMLTextAreaElement, replacement: string): boolean {\n if (typeof document.execCommand !== 'function') return false;\n try {\n return replacement === ''\n ? document.execCommand('delete')\n : document.execCommand('insertText', false, replacement);\n } catch {\n return false;\n }\n}\n\n/** Applies an edit to a textarea through the native undo stack when the browser allows it, so Ctrl+Z still works. */\nexport function applyEdit(\n el: HTMLTextAreaElement,\n edit: Edit,\n commit: (value: string) => void,\n): void {\n if (el.value !== edit.value) {\n const { start, endBefore, replacement } = changedSpan(el.value, edit.value);\n el.setSelectionRange(start, endBefore);\n if (!writeNatively(el, replacement)) {\n el.value = edit.value;\n }\n commit(el.value);\n }\n el.setSelectionRange(edit.selectionStart, edit.selectionEnd);\n}\n","const FENCE = /^ {0,3}(```|~~~)/;\n\nexport type Line = { start: number; end: number; text: string };\n\n/** The line containing the offset, with its start and end offsets and its text (no trailing newline). */\nexport function lineAt(value: string, offset: number): Line {\n const start = value.lastIndexOf('\\n', offset - 1) + 1;\n const next = value.indexOf('\\n', offset);\n const end = next === -1 ? value.length : next;\n return { start, end, text: value.slice(start, end) };\n}\n\nexport function isFenceDelimiter(text: string): boolean {\n return FENCE.test(text);\n}\n\nexport function insideFence(value: string, offset: number): boolean {\n const lines = value.slice(0, offset).split('\\n');\n if (isFenceDelimiter(lines[lines.length - 1])) return true;\n\n let open = false;\n for (let i = 0; i < lines.length - 1; i += 1) {\n if (isFenceDelimiter(lines[i])) open = !open;\n }\n return open;\n}\n","import type { Edit } from './edit';\nimport { lineAt } from './line-at';\n\n/** The fields `insertCommand` needs. `TextCommand` satisfies this structurally. */\nexport type InsertableCommand = {\n insert: string;\n caretOffset: number;\n selectLength?: number;\n separate: boolean;\n};\n\n/** Inserts a command's markdown at the caret, starting a new line (or a blank line if it asks) when the caret is mid-line. */\nexport function insertCommand(command: InsertableCommand, value: string, caret: number): Edit {\n const line = lineAt(value, caret);\n const before = value.slice(line.start, caret).replace(/[ \\t]+$/, '');\n const cut = line.start + before.length;\n const prefix = before.trim() === '' ? '' : command.separate ? '\\n\\n' : '\\n';\n const at = cut + prefix.length + command.caretOffset;\n\n return {\n value: value.slice(0, cut) + prefix + command.insert + value.slice(caret),\n selectionStart: at,\n selectionEnd: at + (command.selectLength ?? 0),\n };\n}\n","type NavigatorWithData = Navigator & { userAgentData?: { platform?: string } };\n\n/** True on macOS and iOS, where the shortcut modifier is Command rather than Ctrl. Read on each call so a stubbed navigator is honoured. */\nexport function isMac(): boolean {\n if (typeof navigator === 'undefined') return false;\n const { userAgentData, platform } = navigator as NavigatorWithData;\n return /mac|iphone|ipad/i.test(userAgentData?.platform || platform || '');\n}\n","import { isMac } from './platform';\n\nconst MAC_LABEL: Record<string, string> = { mod: '⌘', alt: '⌥', shift: '⇧' };\nconst OTHER_LABEL: Record<string, string> = { mod: 'Ctrl', alt: 'Alt', shift: 'Shift' };\n\n/** Renders a \"mod+shift+b\" style hint as the platform's own label, such as ⌘⇧B on a Mac and Ctrl+Shift+B elsewhere. */\nexport function formatShortcut(hint: string): string {\n const mac = isMac();\n const labels = mac ? MAC_LABEL : OTHER_LABEL;\n const parts = hint.split('+').map((part) => labels[part] ?? part.toUpperCase());\n return parts.join(mac ? '' : '+');\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { XIcon } from \"lucide-react\";\nimport { cn } from \"./cn\";\nimport { FOCUS_RING } from \"./focus\";\nimport { ICON_TAP_TARGET_FLOOR } from \"./touch-target\";\n\nfunction Dialog(props: React.ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />;\n}\n\nfunction DialogTrigger(\n props: React.ComponentProps<typeof DialogPrimitive.Trigger>,\n) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\n}\n\nfunction DialogPortal(\n props: React.ComponentProps<typeof DialogPrimitive.Portal>,\n) {\n return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\n}\n\nfunction DialogClose(\n props: React.ComponentProps<typeof DialogPrimitive.Close>,\n) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\n}\n\nfunction DialogOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n return (\n <DialogPrimitive.Overlay\n data-slot=\"dialog-overlay\"\n className={cn(\n \"quoin fixed inset-0 z-50 bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content>) {\n return (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n data-slot=\"dialog-content\"\n className={cn(\n \"quoin bg-popover fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className,\n )}\n {...props}\n >\n {children}\n <DialogPrimitive.Close\n className={cn(\n \"absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100\",\n FOCUS_RING,\n ICON_TAP_TARGET_FLOOR,\n )}\n >\n <XIcon />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n );\n}\n\nfunction DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\"text-lg leading-none font-semibold\", className)}\n {...props}\n />\n );\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n};\n","'use client';\n\nimport { formatShortcut } from './shortcut-label';\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from '../ui/dialog';\n\nconst ROWS: Array<{ label: string; keys: string }> = [\n { label: 'Open the command palette', keys: '/' },\n { label: 'Bold', keys: formatShortcut('mod+b') },\n { label: 'Italic', keys: formatShortcut('mod+i') },\n { label: 'Inline code', keys: formatShortcut('mod+e') },\n { label: 'Link', keys: formatShortcut('mod+k') },\n { label: 'Heading', keys: formatShortcut('mod+alt+1') },\n { label: 'Subtitle', keys: formatShortcut('mod+alt+2') },\n { label: 'Sub-subtitle', keys: formatShortcut('mod+alt+3') },\n { label: 'Bullet list', keys: formatShortcut('mod+shift+8') },\n { label: 'Numbered list', keys: formatShortcut('mod+shift+7') },\n { label: 'Continue a list, or leave it when the item is empty', keys: 'Enter' },\n { label: 'Indent item', keys: 'Tab' },\n { label: 'Outdent item', keys: formatShortcut('shift') + '+Tab' },\n];\n\nexport function ShortcutsReference({\n open,\n onOpenChange,\n}: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}) {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>Keyboard shortcuts</DialogTitle>\n <DialogDescription>Formatting without leaving the keyboard.</DialogDescription>\n </DialogHeader>\n <dl className=\"grid grid-cols-[1fr_auto] gap-x-4 gap-y-2 text-sm\">\n {ROWS.map((row) => (\n <div key={row.label} className=\"col-span-2 grid grid-cols-subgrid items-baseline\">\n <dt className=\"text-muted-foreground\">{row.label}</dt>\n <dd>\n <kbd className=\"rounded border bg-muted px-1.5 py-0.5 font-mono text-xs\">{row.keys}</kbd>\n </dd>\n </div>\n ))}\n </dl>\n </DialogContent>\n </Dialog>\n );\n}\n","'use client';\n\nimport { Keyboard } from 'lucide-react';\nimport { useQuoin } from '../context';\nimport { paletteBlocks } from '../registry';\nimport type { CaretRect } from './caret-coordinates';\nimport { TEXT_COMMANDS, type TextCommand } from './commands';\nimport { formatShortcut } from './shortcut-label';\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandShortcut,\n} from '../ui/command';\nimport { Popover, PopoverAnchor, PopoverContent } from '../ui/popover';\n\nexport function SlashPalette({\n open,\n caret,\n onOpenChange,\n onTextCommand,\n onBlockCommand,\n onShortcuts,\n onDismiss,\n}: {\n open: boolean;\n caret: CaretRect | null;\n onOpenChange: (open: boolean) => void;\n onTextCommand: (command: TextCommand) => void;\n onBlockCommand: (type: string) => void;\n onShortcuts: () => void;\n onDismiss: () => void;\n}) {\n const { blockTypes } = useQuoin();\n const blockOptions = paletteBlocks(blockTypes);\n return (\n <Popover open={open} onOpenChange={onOpenChange}>\n <PopoverAnchor asChild>\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute\"\n style={caret ? { top: caret.top, left: caret.left, height: caret.height } : { top: 0, left: 0 }}\n />\n </PopoverAnchor>\n <PopoverContent\n aria-label=\"Command palette\"\n align=\"start\"\n side=\"bottom\"\n sideOffset={4}\n className=\"w-72 p-0\"\n onEscapeKeyDown={(event) => {\n event.preventDefault();\n onDismiss();\n }}\n // Radix restores focus to the trigger on close, and this palette has an\n // aria-hidden anchor that cannot hold it, so the restore would drop focus\n // to the body. Both callers refocus the textarea before applying the edit.\n onCloseAutoFocus={(event) => event.preventDefault()}\n >\n <Command label=\"Search commands\">\n <CommandInput placeholder=\"Search commands\" />\n <CommandList>\n <CommandEmpty>No command found.</CommandEmpty>\n <CommandGroup heading=\"Text\">\n {TEXT_COMMANDS.map((command) => (\n <CommandItem\n key={command.id}\n value={`${command.label} ${command.keywords.join(' ')}`}\n onSelect={() => onTextCommand(command)}\n >\n <command.icon aria-hidden=\"true\" />\n <span>{command.label}</span>\n {command.hint ? <CommandShortcut>{formatShortcut(command.hint)}</CommandShortcut> : null}\n </CommandItem>\n ))}\n </CommandGroup>\n <CommandGroup heading=\"Blocks\">\n {blockOptions.map((option) => (\n <CommandItem key={option.type} value={option.label} onSelect={() => onBlockCommand(option.type)}>\n <option.icon aria-hidden=\"true\" />\n <span>{option.label}</span>\n </CommandItem>\n ))}\n </CommandGroup>\n <CommandGroup>\n <CommandItem value=\"keyboard shortcuts help\" onSelect={onShortcuts}>\n <Keyboard aria-hidden=\"true\" />\n <span>Keyboard shortcuts</span>\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n );\n}\n","import {\n Code,\n Heading1,\n Heading2,\n Heading3,\n List,\n ListOrdered,\n ListTodo,\n Minus,\n Quote,\n Table,\n type LucideIcon,\n} from 'lucide-react';\n\n/** A slash-palette entry: how it is shown and searched, and the markdown it inserts. */\nexport type TextCommand = {\n id: string;\n label: string;\n keywords: string[];\n icon: LucideIcon;\n hint?: string;\n insert: string;\n caretOffset: number;\n selectLength?: number;\n /** Needs a blank line above it: a divider after a paragraph line parses as a\n * setext heading, and a GFM table cannot interrupt a paragraph at all. */\n separate: boolean;\n};\n\nconst TABLE = ['| Column | Column |', '| --- | --- |', '| | |'].join('\\n');\n\n/** The built-in slash-palette commands, in display order. */\nexport const TEXT_COMMANDS: TextCommand[] = [\n {\n id: 'heading',\n label: 'Heading',\n keywords: ['h1', 'title', 'heading', 'big'],\n icon: Heading1,\n hint: 'mod+alt+1',\n insert: '# ',\n caretOffset: 2,\n separate: false,\n },\n {\n id: 'subtitle',\n label: 'Subtitle',\n keywords: ['h2', 'subtitle', 'section', 'subheading'],\n icon: Heading2,\n hint: 'mod+alt+2',\n insert: '## ',\n caretOffset: 3,\n separate: false,\n },\n {\n id: 'subsubtitle',\n label: 'Sub-subtitle',\n keywords: ['h3', 'subsubtitle', 'minor'],\n icon: Heading3,\n hint: 'mod+alt+3',\n insert: '### ',\n caretOffset: 4,\n separate: false,\n },\n {\n id: 'bullet',\n label: 'Bullet list',\n keywords: ['bullet', 'unordered', 'ul', 'list', 'point'],\n icon: List,\n hint: 'mod+shift+8',\n insert: '- ',\n caretOffset: 2,\n separate: false,\n },\n {\n id: 'numbered',\n label: 'Numbered list',\n keywords: ['numbered', 'ordered', 'ol', 'steps'],\n icon: ListOrdered,\n hint: 'mod+shift+7',\n insert: '1. ',\n caretOffset: 3,\n separate: false,\n },\n {\n id: 'task',\n label: 'Task list',\n keywords: ['task', 'todo', 'checkbox', 'checklist'],\n icon: ListTodo,\n insert: '- [ ] ',\n caretOffset: 6,\n separate: false,\n },\n {\n id: 'quote',\n label: 'Quote',\n keywords: ['quote', 'blockquote', 'citation'],\n icon: Quote,\n insert: '> ',\n caretOffset: 2,\n separate: false,\n },\n {\n id: 'code',\n label: 'Code block',\n keywords: ['code', 'snippet', 'fence', 'pre'],\n icon: Code,\n insert: '```\\n\\n```',\n caretOffset: 3,\n separate: true,\n },\n {\n id: 'divider',\n label: 'Divider',\n keywords: ['divider', 'rule', 'hr', 'separator', 'break'],\n icon: Minus,\n insert: '---\\n',\n caretOffset: 4,\n separate: true,\n },\n {\n id: 'table',\n label: 'Table',\n keywords: ['table', 'grid', 'rows', 'columns'],\n icon: Table,\n insert: TABLE,\n caretOffset: 2,\n selectLength: 6,\n separate: true,\n },\n];\n","\"use client\"\n\nimport * as React from \"react\"\nimport { Command as CommandPrimitive } from \"cmdk\"\nimport { SearchIcon } from \"lucide-react\"\n\nimport { cn } from \"./cn\"\nimport { SELECTED_BAR } from \"./focus\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"./dialog\"\n\nfunction Command({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n return (\n <CommandPrimitive\n data-slot=\"command\"\n className={cn(\n \"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandDialog({\n title = \"Command Palette\",\n description = \"Search for a command to run...\",\n children,\n className,\n ...props\n}: React.ComponentProps<typeof Dialog> & {\n title?: string\n description?: string\n className?: string\n}) {\n return (\n <Dialog {...props}>\n <DialogHeader className=\"sr-only\">\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </DialogHeader>\n <DialogContent className={cn(\"overflow-hidden p-0\", className)}>\n <Command className=\"**:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n {children}\n </Command>\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction CommandInput({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n return (\n <div\n data-slot=\"command-input-wrapper\"\n className=\"flex h-9 items-center gap-2 border-b px-3\"\n >\n <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n <CommandPrimitive.Input\n data-slot=\"command-input\"\n className={cn(\n \"flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n {...props}\n />\n </div>\n )\n}\n\nfunction CommandList({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n return (\n <CommandPrimitive.List\n data-slot=\"command-list\"\n className={cn(\n \"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandEmpty({\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n return (\n <CommandPrimitive.Empty\n data-slot=\"command-empty\"\n className=\"py-6 text-center text-sm\"\n {...props}\n />\n )\n}\n\nfunction CommandGroup({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n return (\n <CommandPrimitive.Group\n data-slot=\"command-group\"\n className={cn(\n \"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n return (\n <CommandPrimitive.Separator\n data-slot=\"command-separator\"\n className={cn(\"-mx-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction CommandItem({\n className,\n ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n return (\n <CommandPrimitive.Item\n data-slot=\"command-item\"\n className={cn(\n \"relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n SELECTED_BAR,\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CommandShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"command-shortcut\"\n className={cn(\n \"ml-auto text-xs tracking-widest text-muted-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n}\n","import * as React from \"react\";\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\";\nimport { cn } from \"./cn\";\n\nfunction Popover(props: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />;\n}\nfunction PopoverTrigger(props: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />;\n}\nfunction PopoverAnchor(props: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {\n return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />;\n}\nfunction PopoverContent({ className, align = \"center\", sideOffset = 4, ...props }: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n data-slot=\"popover-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"quoin bg-popover text-popover-foreground z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden\",\n className,\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n );\n}\nexport { Popover, PopoverAnchor, PopoverTrigger, PopoverContent };\n","import * as React from 'react';\nimport { applyEdit, type Edit } from './edit';\nimport { indentList } from './indent-list';\nimport { toggleLinePrefix, type LinePrefix } from './line-toggles';\nimport { continueList } from './list-continuation';\nimport { isMac } from './platform';\nimport { shouldOpenPalette } from './slash-trigger';\nimport { linkPaste, wrapSelection, type WrapKind } from './wrap-selection';\n\nconst WRAP: Record<string, WrapKind> = { b: 'bold', i: 'italic', e: 'code', k: 'link' };\n\n// Shift turns the 8 key into \"*\", so the physical code is the only stable match.\nconst HEADING: Record<string, LinePrefix> = { Digit1: 'h1', Digit2: 'h2', Digit3: 'h3' };\nconst LIST: Record<string, LinePrefix> = { Digit7: 'ordered', Digit8: 'bullet' };\n\n/** Keyboard and paste handlers that give a plain textarea markdown shortcuts, list continuation, Tab indent and the slash palette trigger. */\nexport function useMarkdownKeymap({\n commit,\n onOpenPalette,\n}: {\n commit: (markdown: string) => void;\n onOpenPalette: () => void;\n}) {\n const onKeyDown = React.useCallback(\n (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n // Safari reports keyCode 229 for the keydown that follows compositionend.\n if (event.nativeEvent.isComposing || event.keyCode === 229) return;\n\n const el = event.currentTarget;\n const { value, selectionStart, selectionEnd } = el;\n const mod = isMac() ? event.metaKey : event.ctrlKey;\n\n const run = (edit: Edit | null) => {\n if (!edit) return;\n event.preventDefault();\n applyEdit(el, edit, commit);\n };\n\n if (mod && event.altKey) {\n const kind = HEADING[event.code];\n if (kind) run(toggleLinePrefix(kind, value, selectionStart, selectionEnd));\n return;\n }\n\n if (mod && event.shiftKey) {\n const kind = LIST[event.code];\n if (kind) run(toggleLinePrefix(kind, value, selectionStart, selectionEnd));\n return;\n }\n\n if (mod) {\n const kind = WRAP[event.key.toLowerCase()];\n if (kind) run(wrapSelection(kind, value, selectionStart, selectionEnd));\n return;\n }\n\n if (event.key === '/') {\n if (!shouldOpenPalette(value, selectionStart, selectionEnd)) return;\n event.preventDefault();\n onOpenPalette();\n return;\n }\n\n if (event.key === 'Enter' && !event.shiftKey) {\n run(continueList(value, selectionStart, 'Enter'));\n return;\n }\n\n if (event.key === 'Backspace' && selectionStart === selectionEnd) {\n run(continueList(value, selectionStart, 'Backspace'));\n return;\n }\n\n if (event.key === 'Tab') {\n run(indentList(value, selectionStart, selectionEnd, event.shiftKey ? -1 : 1));\n }\n },\n [commit, onOpenPalette],\n );\n\n const onPaste = React.useCallback(\n (event: React.ClipboardEvent<HTMLTextAreaElement>) => {\n const el = event.currentTarget;\n const edit = linkPaste(\n el.value,\n el.selectionStart,\n el.selectionEnd,\n event.clipboardData.getData('text/plain'),\n );\n if (!edit) return;\n event.preventDefault();\n applyEdit(el, edit, commit);\n },\n [commit],\n );\n\n return { onKeyDown, onPaste };\n}\n","import type { Edit } from './edit';\nimport { insideFence, lineAt, type Line } from './line-at';\n\nexport const LIST_MARKER = /^(\\s*)((?:[-*+] \\[[ xX]\\] )|(?:[-*+] )|(?:\\d+[.)] )|(?:> ))(.*)$/;\n\nconst INDENT = ' ';\n\nfunction nextMarker(marker: string): string {\n const ordered = /^(\\d+)([.)] )$/.exec(marker);\n if (ordered) return `${Number(ordered[1]) + 1}${ordered[2]}`;\n const task = /^([-*+]) \\[[ xX]\\] $/.exec(marker);\n if (task) return `${task[1]} [ ] `;\n return marker;\n}\n\n// Both the dead item on Enter and the caret at the content start on Backspace\n// mean the same thing: climb out one level, or drop the marker at the top.\nfunction climbOut(value: string, line: Line, indent: string, marker: string, content: string): Edit {\n const outdent = indent.length >= INDENT.length;\n\n if (outdent) {\n const text = indent.slice(INDENT.length) + marker + content;\n const at = line.start + indent.length - INDENT.length + marker.length;\n return {\n value: value.slice(0, line.start) + text + value.slice(line.end),\n selectionStart: at,\n selectionEnd: at,\n };\n }\n\n // A stripped marker with only a single newline above it reads to CommonMark\n // as a lazy continuation of the previous list item's paragraph, not a new\n // block, so a blank line is needed whenever that previous line is a list item.\n const leavesList = line.start > 0 && LIST_MARKER.test(lineAt(value, line.start - 1).text);\n const text = leavesList ? `\\n${content}` : content;\n const at = leavesList ? line.start + 1 : line.start;\n\n return {\n value: value.slice(0, line.start) + text + value.slice(line.end),\n selectionStart: at,\n selectionEnd: at,\n };\n}\n\n/** Continues a list item on Enter, or climbs out of the list on an empty item or Backspace at the marker; returns null when the caret is not in a list item or is inside a code fence, so the default key behaviour runs. */\nexport function continueList(\n value: string,\n caret: number,\n key: 'Enter' | 'Backspace',\n): Edit | null {\n if (insideFence(value, caret)) return null;\n\n const line = lineAt(value, caret);\n const match = LIST_MARKER.exec(line.text);\n if (!match) return null;\n\n const [, indent, marker, content] = match;\n\n if (key === 'Backspace') {\n if (caret !== line.start + indent.length + marker.length) return null;\n return climbOut(value, line, indent, marker, content);\n }\n\n if (content.trim() === '') return climbOut(value, line, indent, marker, content);\n\n const inserted = `\\n${indent}${nextMarker(marker)}`;\n const at = caret + inserted.length;\n return {\n value: value.slice(0, caret) + inserted + value.slice(caret),\n selectionStart: at,\n selectionEnd: at,\n };\n}\n","import type { Edit } from './edit';\nimport { insideFence, lineAt } from './line-at';\nimport { LIST_MARKER } from './list-continuation';\n\nconst INDENT = ' ';\n\nfunction indentOf(text: string): number {\n return /^\\s*/.exec(text)?.[0].length ?? 0;\n}\n\n// Indenting more than one level past the line above turns a list item into an\n// indented code block, so the first line of the range is capped against it.\nfunction shift(text: string, direction: 1 | -1, cap: number | undefined): string {\n const current = indentOf(text);\n if (direction === -1) return text.slice(Math.min(current, INDENT.length));\n if (cap !== undefined && current >= cap + INDENT.length) return text;\n return INDENT + text;\n}\n\n/** Indents or outdents the selected list items; returns null when the selection is not entirely list items, is inside a code fence, or cannot move further, so Tab keeps its default behaviour. */\nexport function indentList(\n value: string,\n selectionStart: number,\n selectionEnd: number,\n direction: 1 | -1,\n): Edit | null {\n if (insideFence(value, selectionStart)) return null;\n\n const first = lineAt(value, selectionStart);\n const last = lineAt(value, selectionEnd);\n const block = value.slice(first.start, last.end);\n const lines = block.split('\\n');\n if (!lines.every((text) => LIST_MARKER.test(text))) return null;\n\n const cap = first.start === 0 ? 0 : indentOf(lineAt(value, first.start - 1).text);\n const shifted = lines.map((text, i) => shift(text, direction, i === 0 ? cap : undefined));\n if (shifted.every((text, i) => text === lines[i])) return null;\n\n const joined = shifted.join('\\n');\n return {\n value: value.slice(0, first.start) + joined + value.slice(last.end),\n selectionStart: selectionStart + (shifted[0].length - lines[0].length),\n selectionEnd: selectionEnd + (joined.length - block.length),\n };\n}\n","import type { Edit } from './edit';\nimport { insideFence, isFenceDelimiter, lineAt } from './line-at';\n\n/** A line-level markdown prefix: a heading level, a bullet or a numbered item. */\nexport type LinePrefix = 'h1' | 'h2' | 'h3' | 'bullet' | 'ordered';\n\nconst EXISTING = /^(\\s*)(?:#{1,6} |[-*+] \\[[ xX]\\] |[-*+] |\\d+[.)] )?/;\n\nconst PREFIX: Record<LinePrefix, (index: number) => string> = {\n h1: () => '# ',\n h2: () => '## ',\n h3: () => '### ',\n bullet: () => '- ',\n ordered: (index) => `${index + 1}. `,\n};\n\nconst CARRIES: Record<LinePrefix, RegExp> = {\n h1: /^\\s*# /,\n h2: /^\\s*## /,\n h3: /^\\s*### /,\n bullet: /^\\s*[-*+] /,\n ordered: /^\\s*\\d+[.)] /,\n};\n\n/** Adds the prefix to every line in the selection, or removes it when every line already carries it; fenced code is left alone. */\nexport function toggleLinePrefix(\n kind: LinePrefix,\n value: string,\n selectionStart: number,\n selectionEnd: number,\n): Edit {\n const first = lineAt(value, selectionStart);\n const last = lineAt(value, selectionEnd);\n const block = value.slice(first.start, last.end);\n const lines = block.split('\\n');\n\n let offset = first.start;\n const eligible = lines.map((text) => {\n const at = offset;\n offset += text.length + 1;\n return !insideFence(value, at) && !isFenceDelimiter(text);\n });\n\n const carried = lines.every((text, i) => !eligible[i] || CARRIES[kind].test(text));\n\n const rewritten = lines.map((text, i) => {\n if (!eligible[i]) return text;\n const match = EXISTING.exec(text);\n const indent = match?.[1] ?? '';\n const body = text.slice(match?.[0].length ?? 0);\n return carried ? indent + body : indent + PREFIX[kind](i) + body;\n });\n\n const joined = rewritten.join('\\n');\n const next = value.slice(0, first.start) + joined + value.slice(last.end);\n\n if (selectionStart !== selectionEnd) {\n return { value: next, selectionStart: first.start, selectionEnd: first.start + joined.length };\n }\n\n const caret = Math.max(first.start, selectionStart + (rewritten[0].length - lines[0].length));\n return { value: next, selectionStart: caret, selectionEnd: caret };\n}\n","import { insideFence } from './line-at';\n\n/** Whether typing \"/\" here should open the command palette: only at a word start, with no selection and outside a code fence. */\nexport function shouldOpenPalette(\n value: string,\n selectionStart: number,\n selectionEnd: number,\n): boolean {\n if (selectionStart !== selectionEnd) return false;\n if (insideFence(value, selectionStart)) return false;\n if (selectionStart === 0) return true;\n\n const previous = value[selectionStart - 1];\n return previous === '\\n' || previous === ' ' || previous === '\\t';\n}\n","import type { Edit } from './edit';\n\n/** An inline markdown wrapper: bold, italic, code or a link. */\nexport type WrapKind = 'bold' | 'italic' | 'code' | 'link';\n\nconst DELIMITER: Record<Exclude<WrapKind, 'link'>, string> = {\n bold: '**',\n italic: '_',\n code: '`',\n};\n\nconst WHOLE_LINK = /^\\[([^\\]]*)\\]\\(([^)]*)\\)$/;\nconst BARE_URL = /^https?:\\/\\/[^\\s]+$/;\n\nfunction unwrap(value: string, start: number, end: number, delimiter: string): Edit | null {\n const selected = value.slice(start, end);\n const width = delimiter.length;\n\n if (selected.length >= 2 * width && selected.startsWith(delimiter) && selected.endsWith(delimiter)) {\n const inner = selected.slice(width, selected.length - width);\n return {\n value: value.slice(0, start) + inner + value.slice(end),\n selectionStart: start,\n selectionEnd: start + inner.length,\n };\n }\n\n const outside =\n start >= width &&\n value.slice(start - width, start) === delimiter &&\n value.slice(end, end + width) === delimiter;\n\n if (!outside) return null;\n\n return {\n value: value.slice(0, start - width) + selected + value.slice(end + width),\n selectionStart: start - width,\n selectionEnd: start - width + selected.length,\n };\n}\n\nfunction link(value: string, start: number, end: number): Edit {\n const selected = value.slice(start, end);\n const whole = WHOLE_LINK.exec(selected);\n\n if (whole) {\n const text = whole[1];\n return {\n value: value.slice(0, start) + text + value.slice(end),\n selectionStart: start,\n selectionEnd: start + text.length,\n };\n }\n\n const opened = `[${selected}](`;\n const at = selected === '' ? start + 1 : start + opened.length;\n return {\n value: value.slice(0, start) + opened + ')' + value.slice(end),\n selectionStart: at,\n selectionEnd: at,\n };\n}\n\n/** Wraps the selection in the markers for the kind, or removes them when it is already wrapped. */\nexport function wrapSelection(\n kind: WrapKind,\n value: string,\n selectionStart: number,\n selectionEnd: number,\n): Edit {\n if (kind === 'link') return link(value, selectionStart, selectionEnd);\n\n const delimiter = DELIMITER[kind];\n const stripped = unwrap(value, selectionStart, selectionEnd, delimiter);\n if (stripped) return stripped;\n\n const selected = value.slice(selectionStart, selectionEnd);\n\n if (kind === 'code' && selected.includes('\\n')) {\n const at = selectionStart + 4;\n return {\n value: value.slice(0, selectionStart) + '```\\n' + selected + '\\n```' + value.slice(selectionEnd),\n selectionStart: at,\n selectionEnd: at + selected.length,\n };\n }\n\n const at = selectionStart + delimiter.length;\n return {\n value: value.slice(0, selectionStart) + delimiter + selected + delimiter + value.slice(selectionEnd),\n selectionStart: at,\n selectionEnd: at + selected.length,\n };\n}\n\n/** Turns a pasted URL over a selection into a markdown link; returns null when nothing is selected or the paste is not a bare URL, so the paste goes through unchanged. */\nexport function linkPaste(\n value: string,\n selectionStart: number,\n selectionEnd: number,\n pasted: string,\n): Edit | null {\n if (selectionStart === selectionEnd) return null;\n\n const url = pasted.trim();\n if (!BARE_URL.test(url)) return null;\n\n const inserted = `[${value.slice(selectionStart, selectionEnd)}](${url})`;\n const at = selectionStart + inserted.length;\n return {\n value: value.slice(0, selectionStart) + inserted + value.slice(selectionEnd),\n selectionStart: at,\n selectionEnd: at,\n };\n}\n","import * as React from 'react';\nimport { caretRect, type CaretRect } from './caret-coordinates';\n\nexport function useSlashPalette(ref: React.RefObject<HTMLTextAreaElement | null>) {\n const [open, setOpen] = React.useState(false);\n const [caret, setCaret] = React.useState<CaretRect | null>(null);\n const offsetRef = React.useRef(0);\n\n const openAtCaret = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n offsetRef.current = el.selectionStart;\n setCaret(caretRect(el));\n setOpen(true);\n }, [ref]);\n\n return { open, setOpen, caret, offsetRef, openAtCaret };\n}\n","type CopiedProperty =\n | 'boxSizing'\n | 'fontFamily'\n | 'fontSize'\n | 'fontStyle'\n | 'fontWeight'\n | 'letterSpacing'\n | 'lineHeight'\n | 'paddingBottom'\n | 'paddingLeft'\n | 'paddingRight'\n | 'paddingTop'\n | 'textIndent'\n | 'textTransform'\n | 'wordBreak'\n | 'wordSpacing'\n | 'borderBottomWidth'\n | 'borderLeftWidth'\n | 'borderRightWidth'\n | 'borderTopWidth';\n\nconst COPIED: CopiedProperty[] = [\n 'boxSizing',\n 'fontFamily',\n 'fontSize',\n 'fontStyle',\n 'fontWeight',\n 'letterSpacing',\n 'lineHeight',\n 'paddingBottom',\n 'paddingLeft',\n 'paddingRight',\n 'paddingTop',\n 'textIndent',\n 'textTransform',\n 'wordBreak',\n 'wordSpacing',\n 'borderBottomWidth',\n 'borderLeftWidth',\n 'borderRightWidth',\n 'borderTopWidth',\n];\n\n/** The caret's position and line height, in pixels relative to the textarea's top left corner. */\nexport type CaretRect = { top: number; left: number; height: number };\n\n/** A textarea exposes no caret geometry, so the text before the caret is laid\n * out again in a hidden div that copies the box's own metrics, and a marker at\n * the end of it is measured. Returns null when the textarea is not laid out\n * (hidden or detached), because there is nothing to measure. */\nexport function caretRect(el: HTMLTextAreaElement): CaretRect | null {\n if (el.offsetWidth === 0) return null;\n\n const style = window.getComputedStyle(el);\n const mirror = document.createElement('div');\n for (const property of COPIED) mirror.style[property] = style[property];\n mirror.style.position = 'absolute';\n mirror.style.top = '0';\n mirror.style.left = '-9999px';\n mirror.style.visibility = 'hidden';\n mirror.style.whiteSpace = 'pre-wrap';\n mirror.style.overflowWrap = 'break-word';\n mirror.style.width = `${el.clientWidth}px`;\n mirror.textContent = el.value.slice(0, el.selectionStart);\n\n const marker = document.createElement('span');\n marker.textContent = '\\u200b';\n mirror.appendChild(marker);\n document.body.appendChild(mirror);\n\n const top = marker.offsetTop;\n const left = marker.offsetLeft;\n const height = marker.offsetHeight || Number.parseFloat(style.lineHeight) || 0;\n mirror.remove();\n\n if (height === 0) return null;\n return { top: top - el.scrollTop, left, height };\n}\n","import * as React from 'react';\nimport { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect';\n\n/** Height follows the content, and is recomputed when the box gets narrower or\n * wider, because a re-wrap changes the line count without changing the value.\n * Only a width change refits: reacting to the height this hook just set would\n * feed the observer its own output. */\nexport function useAutoGrow<T extends HTMLTextAreaElement>(value: string): React.RefObject<T> {\n const ref = React.useRef<T>(null);\n const lastWidth = React.useRef<number | null>(null);\n\n // Measuring means collapsing to \"auto\" first, which shrinks the page enough that\n // the browser clamps the scroll position, and growing back does not undo that.\n // Both steps run before paint, so restoring the scroll here is not visible.\n const fit = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n const scroller = document.scrollingElement ?? document.documentElement;\n const scrollTop = scroller.scrollTop;\n el.style.height = 'auto';\n if (el.scrollHeight > 0) el.style.height = `${el.scrollHeight}px`;\n if (scroller.scrollTop !== scrollTop) scroller.scrollTop = scrollTop;\n }, []);\n\n useIsomorphicLayoutEffect(fit, [fit, value]);\n\n React.useEffect(() => {\n const el = ref.current;\n if (!el || typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(([entry]) => {\n const width = entry.contentRect.width;\n if (width === lastWidth.current) return;\n lastWidth.current = width;\n fit();\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, [fit]);\n\n // React 18's types refuse `RefObject<T | null>` on a `ref` prop, and `RefObject<T>` fits both majors.\n return ref as React.RefObject<T>;\n}\n","import * as React from 'react';\n\nexport const useIsomorphicLayoutEffect = typeof document === 'undefined' ? React.useEffect : React.useLayoutEffect;\n","export const str = (v: unknown) => (typeof v === 'string' ? v : '');\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\";\nimport { cn } from \"./cn\";\nimport { FOCUS_RING, HIGHLIGHT_BAR } from \"./focus\";\nimport { TAP_TARGET_FLOOR } from \"./touch-target\";\n\nfunction Select(props: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\nfunction SelectValue(props: React.ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />;\n}\nfunction SelectTrigger({ className, children, ...props }: React.ComponentProps<typeof SelectPrimitive.Trigger>) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n className={cn(\n \"border-input data-[placeholder]:text-muted-foreground flex h-9 w-full cursor-pointer items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm shadow-xs disabled:cursor-not-allowed disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\",\n FOCUS_RING,\n TAP_TARGET_FLOOR,\n className,\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"size-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n );\n}\nfunction SelectContent({ className, children, position = \"popper\", ...props }: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n className={cn(\n \"quoin bg-popover text-popover-foreground relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border shadow-md\",\n position === \"popper\" && \"data-[side=bottom]:translate-y-1\",\n className,\n )}\n position={position}\n {...props}\n >\n <SelectPrimitive.ScrollUpButton className=\"flex cursor-default items-center justify-center py-1\">\n <ChevronUpIcon className=\"size-4\" />\n </SelectPrimitive.ScrollUpButton>\n <SelectPrimitive.Viewport className={cn(\"p-1\", position === \"popper\" && \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]\")}>\n {children}\n </SelectPrimitive.Viewport>\n <SelectPrimitive.ScrollDownButton className=\"flex cursor-default items-center justify-center py-1\">\n <ChevronDownIcon className=\"size-4\" />\n </SelectPrimitive.ScrollDownButton>\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n );\n}\nfunction SelectItem({ className, children, ...props }: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n HIGHLIGHT_BAR,\n TAP_TARGET_FLOOR,\n className,\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n );\n}\nexport { Select, SelectValue, SelectTrigger, SelectContent, SelectItem };\n","import * as React from \"react\";\nimport { cn } from \"./cn\";\nimport { FOCUS_RING } from \"./focus\";\n\nconst Textarea = React.forwardRef<HTMLTextAreaElement, React.ComponentPropsWithoutRef<\"textarea\">>(function Textarea(\n { className, ...props },\n ref,\n) {\n return (\n <textarea\n ref={ref}\n data-slot=\"textarea\"\n className={cn(\n \"border-input placeholder:text-muted-foreground flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 md:text-sm\",\n FOCUS_RING,\n \"focus-visible:border-ring\",\n \"aria-invalid:border-destructive\",\n className,\n )}\n {...props}\n />\n );\n});\n\nexport { Textarea };\n","'use client';\n\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select';\nimport { Textarea } from '../ui/textarea';\nimport type { BlockEditorProps } from '../types';\nimport { str } from './str';\n\nconst CALLOUT_TONES = ['info', 'tip', 'warning', 'success', 'danger'] as const;\n\nexport function CalloutBlockEditor({ data, onChange }: BlockEditorProps) {\n const set = (patch: Record<string, unknown>) => onChange({ ...data, ...patch });\n\n return (\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-sm font-medium leading-none\">Tone</span>\n <Select value={str(data.tone) || 'info'} onValueChange={(v) => set({ tone: v })}>\n <SelectTrigger aria-label=\"Callout tone\" className=\"w-40 capitalize\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {CALLOUT_TONES.map((t) => (\n <SelectItem key={t} value={t} className=\"capitalize\">\n {t}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-sm font-medium leading-none\">Callout text</span>\n <Textarea value={str(data.body)} onChange={(e) => set({ body: e.target.value })} className=\"text-sm\" />\n </label>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"./cn\";\nimport { FOCUS_RING } from \"./focus\";\nimport { TAP_TARGET_FLOOR } from \"./touch-target\";\n\nconst Input = React.forwardRef<HTMLInputElement, React.ComponentPropsWithoutRef<\"input\">>(function Input(\n { className, type, ...props },\n ref,\n) {\n return (\n <input\n ref={ref}\n type={type}\n data-slot=\"input\"\n className={cn(\n \"border-input placeholder:text-muted-foreground flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:opacity-50 md:text-sm\",\n FOCUS_RING,\n \"focus-visible:border-ring\",\n \"aria-invalid:border-destructive\",\n TAP_TARGET_FLOOR,\n className,\n )}\n {...props}\n />\n );\n});\n\nexport { Input };\n","'use client';\n\nimport { Input } from '../ui/input';\nimport { Textarea } from '../ui/textarea';\nimport type { BlockEditorProps } from '../types';\nimport { str } from './str';\n\nexport function CodeBlockEditor({ data, onChange }: BlockEditorProps) {\n const set = (patch: Record<string, unknown>) => onChange({ ...data, ...patch });\n\n return (\n <div className=\"flex flex-col gap-2\">\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-sm font-medium leading-none\">Language</span>\n <Input\n aria-label=\"Language\"\n value={str(data.language)}\n onChange={(e) => set({ language: e.target.value })}\n className=\"text-sm\"\n />\n </label>\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-sm font-medium leading-none\">Code</span>\n <Textarea\n aria-label=\"Code\"\n value={str(data.code)}\n onChange={(e) => set({ code: e.target.value })}\n className=\"min-h-32 font-mono text-sm\"\n />\n </label>\n </div>\n );\n}\n","'use client';\n\nimport { useEffect, useRef } from 'react';\nimport { useQuoin } from '../context';\nimport { Input } from '../ui/input';\nimport { UploadField } from '../upload/UploadField';\nimport type { BlockEditorProps, UploadResult } from '../types';\nimport { str } from './str';\nimport { intrinsicSize } from './intrinsic-size';\n\nexport function ImageBlockEditor({ data, onChange }: BlockEditorProps) {\n const { resolveAssetUrl } = useQuoin();\n // Read through a ref: measuring the upload is async, and the alt/caption fields\n // stay editable while it runs.\n const latest = useRef(data);\n useEffect(() => {\n latest.current = data;\n });\n const set = (patch: Record<string, unknown>) => onChange({ ...latest.current, ...patch });\n\n const newestKey = useRef('');\n\n const onUploaded = async ({ storageKey }: UploadResult) => {\n newestKey.current = storageKey;\n const { width: _width, height: _height, ...unsized } = latest.current;\n onChange({ ...unsized, storageKey });\n const src = resolveAssetUrl(storageKey);\n const size = src ? await intrinsicSize(src) : null;\n if (size && newestKey.current === storageKey) set({ storageKey, ...size });\n };\n\n return (\n <div className=\"flex flex-col gap-2\">\n <UploadField category=\"image\" label=\"Upload image\" onUploaded={onUploaded} />\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-sm font-medium leading-none\">Alt text</span>\n <Input\n aria-label=\"Image alt text\"\n value={str(data.alt)}\n onChange={(e) => set({ alt: e.target.value })}\n className=\"text-sm\"\n />\n </label>\n <label className=\"flex flex-col gap-1\">\n <span className=\"text-sm font-medium leading-none\">Caption (optional)</span>\n <Input\n aria-label=\"Image caption\"\n value={str(data.caption)}\n onChange={(e) => set({ caption: e.target.value })}\n className=\"text-sm\"\n />\n </label>\n {str(data.storageKey) && <span className=\"text-xs text-muted-foreground\">Image attached</span>}\n </div>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport { useQuoin } from '../context';\nimport type { UploadResult } from '../types';\nimport { FilePickerButton } from './FilePickerButton';\n\n/** Props for `UploadField`; the upload function itself comes from the canvas, not from here. */\nexport type UploadFieldProps = {\n /** Names what the file is for, and is passed to the host's `upload` as its second argument. */\n category: string;\n /** Labels the control for both the pointer and assistive technology. */\n label: string;\n /** An `accept` attribute for the file input, such as `'image/*'` or `'.pdf'`. */\n accept?: string;\n /** Called once the upload resolves. The field stays busy until a returned promise settles, and throwing or rejecting is reported through the canvas `onError`. */\n onUploaded: (result: UploadResult) => void | Promise<void>;\n};\n\n/** A file picker wired to the canvas `upload` function, with its own busy state and inline error. */\nexport function UploadField({ category, label, accept, onUploaded }: UploadFieldProps) {\n const { upload, onError } = useQuoin();\n const [busy, setBusy] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n\n async function run(file: File) {\n if (!upload) return;\n setBusy(true);\n setError(null);\n let result: UploadResult;\n try {\n result = await upload(file, category);\n } catch (cause) {\n setError((cause instanceof Error && cause.message) || 'Upload failed.');\n setBusy(false);\n return;\n }\n try {\n await onUploaded(result);\n } catch (cause) {\n onError(cause instanceof Error ? cause : new Error(String(cause)));\n } finally {\n setBusy(false);\n }\n }\n\n return (\n <div className=\"flex flex-col items-start gap-1.5\">\n <FilePickerButton\n label={label}\n accept={accept}\n disabled={busy || !upload}\n onPick={(file) => void run(file)}\n />\n {!upload && (\n <span role=\"note\" className=\"text-xs text-muted-foreground\">\n Uploads are not configured for this editor.\n </span>\n )}\n {busy && <span role=\"status\" className=\"text-xs text-muted-foreground\">Uploading...</span>}\n {error && (\n <span role=\"alert\" className=\"text-xs text-destructive\">\n {error}\n </span>\n )}\n </div>\n );\n}\n","export type IntrinsicSize = { width: number; height: number };\n\n/** Persisted onto the block so the reader can reserve the box before the bytes\n * arrive. Resolves null rather than rejecting: a drop without them still renders,\n * it just reflows. */\nexport function intrinsicSize(src: string): Promise<IntrinsicSize | null> {\n return new Promise((resolve) => {\n if (typeof window === 'undefined') return resolve(null);\n const img = new window.Image();\n img.onload = () => resolve({ width: img.naturalWidth, height: img.naturalHeight });\n img.onerror = () => resolve(null);\n img.src = src;\n });\n}\n","'use client';\n\nimport { UploadField } from '../upload/UploadField';\nimport type { BlockEditorProps } from '../types';\nimport { str } from './str';\n\nexport function FileBlockEditor({ data, onChange }: BlockEditorProps) {\n const set = (patch: Record<string, unknown>) => onChange({ ...data, ...patch });\n\n return (\n <div className=\"flex flex-col gap-2\">\n <UploadField\n category=\"file\"\n label=\"Upload file\"\n onUploaded={(r) => set({ storageKey: r.storageKey, filename: r.filename, size: r.size })}\n />\n {str(data.filename) && <span className=\"text-xs text-muted-foreground\">{str(data.filename)} ✓</span>}\n </div>\n );\n}\n","'use client';\n\nimport { useQuoin } from '../context';\nimport type { BlockPreviewProps } from '../types';\nimport { str } from './str';\n\nconst HINT = 'text-sm text-muted-foreground';\n\n/**\n * One colour per tone, carrying both the rule and the wash behind it. Until 0.4.0 the\n * five tones were mapped onto whatever this palette already had, which gave info, tip\n * and success the same near-black rule and all five the same grey fill: the editor\n * offered five choices that rendered as three, and the choice a writer made was lost.\n *\n * The wash is 15% of a mid-lightness colour, which is light enough to keep body copy\n * on it and saturated enough to read as the tone rather than as grey.\n */\nexport const TONE: Record<string, string> = {\n info: 'border-info bg-info/15',\n tip: 'border-primary bg-primary/15',\n warning: 'border-warning bg-warning/15',\n success: 'border-success bg-success/15',\n danger: 'border-destructive bg-destructive/15',\n};\n\nexport function MarkdownPreview({ data }: BlockPreviewProps) {\n const markdown = str(data.markdown);\n if (markdown.trim() === '') return <p className={HINT}>Empty markdown block</p>;\n return <div className=\"whitespace-pre-wrap text-base leading-7\">{markdown}</div>;\n}\n\nexport function CodePreview({ data }: BlockPreviewProps) {\n const code = str(data.code);\n if (code.trim() === '') return <p className={HINT}>Empty code block</p>;\n return (\n <pre className=\"overflow-x-auto rounded-md bg-muted p-3 text-sm\">\n <code>{code}</code>\n </pre>\n );\n}\n\nexport function ImagePreview({ data }: BlockPreviewProps) {\n const { resolveAssetUrl } = useQuoin();\n const key = str(data.storageKey);\n // Guard on the key, not the resolved URL: a prefixing resolver turns an empty key into a truthy, dead address.\n if (key === '') return <p className={HINT}>No image chosen</p>;\n return <img src={resolveAssetUrl(key)} alt={str(data.alt)} className=\"max-w-full rounded-md\" />;\n}\n\nexport function FilePreview({ data }: BlockPreviewProps) {\n const name = str(data.filename);\n if (name === '') return <p className={HINT}>No file chosen</p>;\n return <p className=\"text-sm\">{name}</p>;\n}\n\nexport function CalloutPreview({ data }: BlockPreviewProps) {\n const body = str(data.body);\n if (body.trim() === '') return <p className={HINT}>Empty callout</p>;\n const tone = str(data.tone) || 'info';\n const paint = TONE[tone] ?? 'border-border bg-muted/50';\n return (\n <div data-tone={tone} className={`rounded-md border-l-4 ${paint} p-3 text-sm`}>\n {body}\n </div>\n );\n}\n","import * as React from 'react';\nimport type { QuoinBlock } from '../types';\nimport { newBlockId } from './new-block-id';\n\n/** Handed back by `remove` and accepted by `undo` to restore that one block. */\nexport type UndoToken = number;\n\ntype Removed = { block: QuoinBlock; index: number };\n\ntype State = {\n blocks: QuoinBlock[];\n removals: Map<UndoToken, Removed>;\n};\n\ntype Action =\n | { type: 'insertAt'; index: number; block: QuoinBlock }\n | { type: 'update'; id: string; data: Record<string, unknown> }\n | { type: 'remove'; id: string; token: UndoToken }\n | { type: 'undo'; token: UndoToken }\n | { type: 'move'; index: number; dir: -1 | 1 }\n | { type: 'reorder'; from: number; to: number }\n | { type: 'reset'; blocks: QuoinBlock[] };\n\nlet removalSeq = 0;\n\n/** A canvas may never call `undo`, so the oldest removals are dropped rather than kept\n * for the lifetime of the document. The cap is far past any run of deletes a person\n * would undo one by one. */\nconst UNDO_DEPTH = 20;\n\nfunction reducer(state: State, action: Action): State {\n switch (action.type) {\n case 'insertAt': {\n const next = [...state.blocks];\n next.splice(Math.max(0, Math.min(action.index, state.blocks.length)), 0, action.block);\n return { ...state, blocks: next };\n }\n case 'update': {\n return {\n ...state,\n blocks: state.blocks.map((b) => (b.id === action.id ? { ...b, data: action.data } : b)),\n };\n }\n case 'remove': {\n const index = state.blocks.findIndex((b) => b.id === action.id);\n if (index === -1) return state;\n const removals = new Map(state.removals);\n removals.set(action.token, { block: state.blocks[index], index });\n while (removals.size > UNDO_DEPTH) {\n const oldest = removals.keys().next();\n if (oldest.done) break;\n removals.delete(oldest.value);\n }\n return { blocks: state.blocks.filter((b) => b.id !== action.id), removals };\n }\n case 'undo': {\n const removal = state.removals.get(action.token);\n if (!removal) return state;\n const next = [...state.blocks];\n next.splice(Math.min(removal.index, state.blocks.length), 0, removal.block);\n const removals = new Map(state.removals);\n removals.delete(action.token);\n return { blocks: next, removals };\n }\n case 'move': {\n const j = action.index + action.dir;\n if (j < 0 || j >= state.blocks.length) return state;\n const next = [...state.blocks];\n [next[action.index], next[j]] = [next[j], next[action.index]];\n return { ...state, blocks: next };\n }\n case 'reorder': {\n const { from, to } = action;\n if (from < 0 || to < 0 || from >= state.blocks.length || to >= state.blocks.length) return state;\n const next = [...state.blocks];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved);\n return { ...state, blocks: next };\n }\n case 'reset':\n return { blocks: action.blocks, removals: new Map() };\n }\n}\n\n/** The document plus every way to change it; `reset` replaces the whole document and voids outstanding undo tokens. */\nexport type BlockList = {\n blocks: QuoinBlock[];\n insertAt: (index: number, type: string, data?: Record<string, unknown>) => string;\n update: (id: string, data: Record<string, unknown>) => void;\n /** Returns a token `undo` restores that block with; only the last 20 removals stay restorable. */\n remove: (id: string) => UndoToken;\n undo: (token: UndoToken) => void;\n move: (index: number, dir: -1 | 1) => void;\n reorder: (from: number, to: number) => void;\n reset: (blocks: QuoinBlock[]) => void;\n};\n\n/** Holds a document in a reducer and returns its blocks with insert, update, remove, undo, move, reorder and reset. Reads `initial` once. */\nexport function useBlockList(initial: QuoinBlock[]): BlockList {\n const [state, dispatch] = React.useReducer(reducer, { blocks: initial, removals: new Map() });\n\n const insertAt = React.useCallback(\n (index: number, type: string, data: Record<string, unknown> = {}): string => {\n const id = newBlockId();\n dispatch({ type: 'insertAt', index, block: { id, type, data } });\n return id;\n },\n [],\n );\n\n const update = React.useCallback((id: string, data: Record<string, unknown>) => {\n dispatch({ type: 'update', id, data });\n }, []);\n\n const remove = React.useCallback((id: string): UndoToken => {\n removalSeq += 1;\n const token = removalSeq;\n dispatch({ type: 'remove', id, token });\n return token;\n }, []);\n\n const undo = React.useCallback((token: UndoToken) => {\n dispatch({ type: 'undo', token });\n }, []);\n\n const move = React.useCallback((index: number, dir: -1 | 1) => {\n dispatch({ type: 'move', index, dir });\n }, []);\n\n const reorder = React.useCallback((from: number, to: number) => {\n dispatch({ type: 'reorder', from, to });\n }, []);\n\n const reset = React.useCallback((blocks: QuoinBlock[]) => {\n dispatch({ type: 'reset', blocks });\n }, []);\n\n return { blocks: state.blocks, insertAt, update, remove, undo, move, reorder, reset };\n}\n","/**\n * A fresh block id that cannot collide with one already in a persisted document.\n * It holds no counter, because a counter restarts on every page load and would\n * re-mint ids a host has stored.\n */\nexport function newBlockId(): string {\n const webCrypto = globalThis.crypto;\n if (webCrypto && typeof webCrypto.randomUUID === 'function') return webCrypto.randomUUID();\n // randomUUID is absent in insecure contexts and older runtimes.\n const random = () => Math.random().toString(36).slice(2, 10);\n return `blk-${Date.now().toString(36)}-${random()}${random()}`;\n}\n","import type { Announcements } from '@dnd-kit/core';\nimport { blockByType, type AnyBlockDefinition } from '../registry';\nimport type { QuoinBlock } from '../types';\n\nfunction describeBlock(blocks: QuoinBlock[], blockTypes: AnyBlockDefinition[], id: string): string {\n const index = blocks.findIndex((b) => b.id === id);\n if (index === -1) return 'block';\n const { type } = blocks[index];\n const label = blockByType(blockTypes, type)?.label ?? type;\n return `${label} block, position ${index + 1} of ${blocks.length}`;\n}\n\n/** The screen reader sentences a drag speaks, naming each block by its registered label and position. */\nexport function buildAnnouncements(blocks: QuoinBlock[], blockTypes: AnyBlockDefinition[]): Announcements {\n const describe = (id: string | number) => describeBlock(blocks, blockTypes, String(id));\n return {\n onDragStart({ active }) {\n return `Picked up ${describe(active.id)}.`;\n },\n onDragOver({ active, over }) {\n if (!over) return `${describe(active.id)} is no longer over a drop position.`;\n return `${describe(active.id)} was moved over ${describe(over.id)}.`;\n },\n onDragEnd({ active, over }) {\n if (!over) return `${describe(active.id)} was dropped.`;\n return `${describe(active.id)} was dropped over ${describe(over.id)}.`;\n },\n onDragCancel({ active }) {\n return `Dragging was cancelled. ${describe(active.id)} was dropped.`;\n },\n };\n}\n","'use client';\n\nimport { ArrowDown, ArrowUp, MoreHorizontal, Trash2 } from 'lucide-react';\nimport { Button } from '../ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../ui/dropdown-menu';\n\nexport function BlockActionsMenu({\n index,\n count,\n label,\n onMove,\n onDelete,\n}: {\n index: number;\n count: number;\n label: string;\n onMove: (index: number, dir: 1 | -1) => void;\n onDelete: () => void;\n}) {\n const position = index + 1;\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button type=\"button\" variant=\"ghost\" size=\"icon-sm\" aria-label={`${label} block ${position} options`}>\n <MoreHorizontal aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-48\">\n <DropdownMenuItem\n aria-label={`Move block ${position} up`}\n disabled={index === 0}\n onSelect={() => onMove(index, -1)}\n >\n <ArrowUp aria-hidden=\"true\" />\n <span>Move up</span>\n </DropdownMenuItem>\n <DropdownMenuItem\n aria-label={`Move block ${position} down`}\n disabled={index === count - 1}\n onSelect={() => onMove(index, 1)}\n >\n <ArrowDown aria-hidden=\"true\" />\n <span>Move down</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n aria-label={`Delete block ${position}`}\n className=\"text-destructive focus:text-destructive\"\n onSelect={onDelete}\n >\n <Trash2 aria-hidden=\"true\" />\n <span>Delete</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\nimport { CheckIcon, ChevronRightIcon, CircleIcon } from \"lucide-react\";\nimport { cn } from \"./cn\";\nimport { HIGHLIGHT_BAR } from \"./focus\";\nimport { TAP_TARGET_FLOOR } from \"./touch-target\";\n\nfunction DropdownMenu(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Root>,\n) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuTrigger(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>,\n) {\n return (\n <DropdownMenuPrimitive.Trigger\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuContent({\n className,\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n className={cn(\n \"quoin bg-popover text-popover-foreground z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className,\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n );\n}\n\nfunction DropdownMenuGroup(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Group>,\n) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n );\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4\",\n HIGHLIGHT_BAR,\n TAP_TARGET_FLOOR,\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none\",\n HIGHLIGHT_BAR,\n className,\n )}\n checked={checked}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n );\n}\n\nfunction DropdownMenuRadioGroup(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>,\n) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n );\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n className={cn(\n \"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none\",\n HIGHLIGHT_BAR,\n className,\n )}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <CircleIcon className=\"size-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n );\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"px-2 py-1.5 text-sm font-medium data-[inset]:pl-8\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"text-muted-foreground ml-auto text-xs tracking-widest\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction DropdownMenuSub(\n props: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>,\n) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean;\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"focus:bg-accent data-[state=open]:bg-accent flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8\",\n HIGHLIGHT_BAR,\n className,\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto size-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n );\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"quoin bg-popover text-popover-foreground z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-lg\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n};\n","'use client';\n\nimport * as React from 'react';\nimport { Pencil } from 'lucide-react';\nimport { BlockEditor } from './BlockEditor';\nimport { renderedOffsetAt, sourceOffsetFor, type ClickProbe } from './source-offset';\nimport { useQuoin } from '../context';\nimport { blockByType } from '../registry';\nimport { devWarn } from '../dev-warn';\nimport { useIsomorphicLayoutEffect } from '../hooks/use-isomorphic-layout-effect';\nimport type { QuoinBlock } from '../types';\nimport { Button } from '../ui/button';\n\nconst INTERACTIVE_SELECTOR = 'a, button, input, textarea, select, [role=\"button\"], [tabindex], iframe';\n\n/** Radix renders Select, dropdown and popover content in a portal, so focus moving\n * into one leaves this block's DOM subtree while the author is still editing it. */\nconst PORTALLED_OVERLAY = '[data-radix-popper-content-wrapper], [role=\"dialog\"]';\n\n// A drag-select ends in a click on mouseup; bailing here keeps that click from\n// flipping the block into edit mode and wiping out the selection it just made.\nfunction hasSelectionWithin(container: HTMLElement): boolean {\n const selection = window.getSelection();\n if (!selection || selection.isCollapsed || selection.rangeCount === 0) return false;\n return container.contains(selection.getRangeAt(0).commonAncestorContainer);\n}\n\nfunction BlockCardImpl({\n block,\n index,\n editingByDefault = false,\n readOnly = false,\n initialSelection = null,\n onUpdate,\n onInsertBlock,\n}: {\n block: QuoinBlock;\n index: number;\n editingByDefault?: boolean;\n /** Draws the block at rest and never opens an editor, for a canvas that is only being read. */\n readOnly?: boolean;\n initialSelection?: { start: number; end: number } | null;\n onUpdate: (id: string, data: Record<string, unknown>) => void;\n onInsertBlock?: (index: number, type: string) => void;\n}) {\n const { blockTypes, onError } = useQuoin();\n const definition = blockByType(blockTypes, block.type);\n const Preview = definition?.preview;\n // A definition with no `editor` can never be edited here, so the card offers no way in:\n // no click target, no Edit button, and nothing that could set `editing`.\n const editable = Boolean(definition?.editor) && !readOnly;\n const [editing, setEditing] = React.useState(editingByDefault && editable);\n const editButtonRef = React.useRef<HTMLButtonElement>(null);\n const editorContainerRef = React.useRef<HTMLDivElement>(null);\n const returnFocusOnClose = React.useRef(false);\n const clickedRef = React.useRef<ClickProbe | null>(null);\n const scrollTopRef = React.useRef<number | null>(null);\n // Read through a ref so the canvas clearing a one-shot seed does not re-run the\n // focus effect and move the caret the author has already placed.\n const seedRef = React.useRef(initialSelection);\n React.useEffect(() => {\n seedRef.current = initialSelection;\n });\n\n const handleInsertBlock = React.useCallback(\n (type: string) => onInsertBlock?.(index + 1, type),\n [onInsertBlock, index],\n );\n\n const leaveEditing = React.useCallback(() => {\n returnFocusOnClose.current = true;\n setEditing(false);\n }, []);\n\n const settleRef = React.useRef<number | null>(null);\n\n const clearSettle = () => {\n if (settleRef.current === null) return;\n window.clearTimeout(settleRef.current);\n settleRef.current = null;\n };\n\n React.useEffect(() => clearSettle, []);\n\n function stillInside(node: Element | null): boolean {\n if (!node) return false;\n return Boolean(editorContainerRef.current?.contains(node)) || Boolean(node.closest(PORTALLED_OVERLAY));\n }\n\n // Editing ends when the author's attention goes elsewhere, so a block left\n // behind renders instead of stranding them on its markdown source. A pointer\n // event is read directly rather than through focus, which Radix moves around\n // asynchronously while an overlay or a freshly inserted block settles.\n React.useEffect(() => {\n if (!editing) return;\n function onPointerDown(e: PointerEvent) {\n if (stillInside(e.target as Element | null)) return;\n setEditing(false);\n }\n document.addEventListener('pointerdown', onPointerDown, true);\n return () => document.removeEventListener('pointerdown', onPointerDown, true);\n }, [editing]);\n\n function closeIfTabbedAway() {\n clearSettle();\n settleRef.current = window.setTimeout(() => {\n settleRef.current = null;\n if (stillInside(document.activeElement)) return;\n setEditing(false);\n }, 0);\n }\n\n // Focus on the click path must not scroll: the caret is placed after focus, so the\n // browser would otherwise drag the viewport to wherever the box's selection starts\n // out, away from the line the author actually aimed at.\n React.useEffect(() => {\n if (!editing) return;\n const field = editorContainerRef.current?.querySelector<HTMLElement>(\n 'textarea, input, [role=\"combobox\"]',\n );\n if (!field) return;\n\n const clicked = clickedRef.current;\n clickedRef.current = null;\n\n if (clicked === null || !(field instanceof HTMLTextAreaElement)) {\n field.focus();\n if (field instanceof HTMLTextAreaElement) {\n const at = seedRef.current ?? { start: field.value.length, end: field.value.length };\n field.setSelectionRange(at.start, at.end);\n }\n return;\n }\n\n const offset = sourceOffsetFor(field.value, clicked);\n field.focus({ preventScroll: true });\n field.setSelectionRange(offset, offset);\n }, [editing]);\n\n // Replacing a tall rendered block with a one-row textarea shrinks the page, so\n // the browser clamps the scroll before the box can grow back. The position is\n // taken at the click and put back here, after the box has been sized.\n useIsomorphicLayoutEffect(() => {\n const scrollTop = scrollTopRef.current;\n scrollTopRef.current = null;\n if (!editing || scrollTop === null) return;\n const scroller = document.scrollingElement ?? document.documentElement;\n if (scroller.scrollTop !== scrollTop) scroller.scrollTop = scrollTop;\n }, [editing]);\n\n React.useEffect(() => {\n if (editing || !returnFocusOnClose.current) return;\n returnFocusOnClose.current = false;\n editButtonRef.current?.focus();\n }, [editing]);\n\n // A block whose type no host registered draws its type rather than nothing, so a\n // document authored with a plugin block does not look empty, and the host is told\n // once per type instead of on every render.\n const reportedType = React.useRef<string | null>(null);\n React.useEffect(() => {\n if (definition || reportedType.current === block.type) return;\n reportedType.current = block.type;\n onError(new Error(`No block type is registered for \"${block.type}\".`));\n }, [definition, block.type, onError]);\n\n // A read-only canvas draws previews and never editors, so an edit-only definition has\n // nothing here but its label. That is a registration mistake rather than a document\n // one, which is why it goes to the developer's console and not to `onError`.\n React.useEffect(() => {\n if (!readOnly || !definition || definition.preview) return;\n devWarn(\n `the block type \"${block.type}\" has no \\`preview\\`, so a read-only canvas can draw ` +\n 'only its label. Give its definition a `preview` to render the block itself.',\n );\n }, [readOnly, definition, block.type]);\n\n if (definition?.alwaysEditing && editable) {\n return (\n <BlockEditor\n type={block.type}\n data={block.data}\n onChange={(data) => onUpdate(block.id, data)}\n onInsertBlock={handleInsertBlock}\n />\n );\n }\n\n if (editing) {\n return (\n <div\n ref={editorContainerRef}\n onKeyDown={(e) => {\n if (e.key === 'Tab') {\n closeIfTabbedAway();\n return;\n }\n if (e.key !== 'Escape') return;\n // Radix's DismissableLayer (Select, dropdowns, etc.) closes on a document\n // capture listener and never stops propagation, so this handler still\n // sees the Escape that already dismissed a nested overlay. Only collapse\n // when the key genuinely landed inside this editor's own DOM subtree, not\n // in a portalled overlay that merely propagates through the React tree.\n if (!editorContainerRef.current?.contains(e.target as Node)) return;\n returnFocusOnClose.current = true;\n setEditing(false);\n }}\n >\n <BlockEditor\n type={block.type}\n data={block.data}\n onChange={(data) => onUpdate(block.id, data)}\n onInsertBlock={handleInsertBlock}\n onDone={leaveEditing}\n />\n </div>\n );\n }\n\n const rest = Preview ? (\n <Preview data={block.data} blockId={block.id} />\n ) : (\n <p className=\"py-1 text-sm text-muted-foreground\">{definition?.label ?? block.type}</p>\n );\n\n // No way into an editor, because the canvas is read-only or this type has none.\n if (!editable) return <div>{rest}</div>;\n\n return (\n <div className=\"group/card relative\">\n <div\n onClick={(e) => {\n const target = e.target as HTMLElement;\n if (target.closest(INTERACTIVE_SELECTOR)) return;\n if (hasSelectionWithin(e.currentTarget)) return;\n clickedRef.current = {\n rendered: e.currentTarget.textContent ?? '',\n clickedText: target.textContent ?? '',\n renderedOffset: renderedOffsetAt(e.currentTarget, e.clientX, e.clientY),\n };\n scrollTopRef.current = (document.scrollingElement ?? document.documentElement).scrollTop;\n setEditing(true);\n }}\n >\n {rest}\n </div>\n <Button\n ref={editButtonRef}\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={`Edit block ${index + 1}`}\n onClick={() => setEditing(true)}\n className=\"absolute right-0 top-0 bg-background/90 opacity-0 transition-opacity group-hover/card:opacity-100 group-focus-within/card:opacity-100 focus-visible:opacity-100\"\n >\n <Pencil aria-hidden=\"true\" />\n </Button>\n </div>\n );\n}\n\nexport const BlockCard = React.memo(BlockCardImpl);\n","'use client';\n\nimport { useQuoin } from '../context';\nimport { blockByType } from '../registry';\nimport type { BlockEditorProps } from '../types';\n\nexport function BlockEditor({\n type,\n data,\n onChange,\n onInsertBlock,\n onDone,\n}: BlockEditorProps & { type: string }) {\n const { blockTypes } = useQuoin();\n const Editor = blockByType(blockTypes, type)?.editor;\n if (!Editor) return null;\n return <Editor data={data} onChange={onChange} onInsertBlock={onInsertBlock} onDone={onDone} />;\n}\n","/** What a click on a block's rendered body says about where the caret belongs. */\nexport type ClickProbe = {\n /** The whole text the preview drew for the block. */\n rendered: string;\n /** The text of the element the click actually landed on. */\n clickedText: string;\n /** Character offset of the click within `rendered`, or null when the browser places no caret there. */\n renderedOffset: number | null;\n};\n\ntype CaretPosition = { offsetNode: Node; offset: number };\n\ntype CaretDocument = Document & {\n caretPositionFromPoint?: (x: number, y: number) => CaretPosition | null;\n caretRangeFromPoint?: (x: number, y: number) => Range | null;\n};\n\nfunction caretPositionAt(x: number, y: number): CaretPosition | null {\n const doc = document as CaretDocument;\n const position = doc.caretPositionFromPoint?.(x, y);\n if (position) return position;\n const range = doc.caretRangeFromPoint?.(x, y);\n return range ? { offsetNode: range.startContainer, offset: range.startOffset } : null;\n}\n\n/** Character offset of the point within `container`'s text, or null when no caret can be placed there. */\nexport function renderedOffsetAt(container: HTMLElement, x: number, y: number): number | null {\n const position = caretPositionAt(x, y);\n if (!position || position.offsetNode.nodeType !== Node.TEXT_NODE) return null;\n if (!container.contains(position.offsetNode)) return null;\n\n const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT);\n let before = 0;\n while (walker.nextNode()) {\n if (walker.currentNode === position.offsetNode) return before + position.offset;\n before += walker.currentNode.textContent?.length ?? 0;\n }\n return null;\n}\n\nconst PROBE_LENGTHS = [40, 20, 8];\n\n/** A custom preview draws something other than the source, so the clicked text is looked\n * back up in it. Collapsing runs of whitespace is what lets a wrapped rendering match a\n * single source line, but it also makes a multi-line clicked string unfindable, so the\n * literal text is tried first and the collapsed form only after it. */\nfunction search(source: string, probe: ClickProbe): number {\n const literal = probe.clickedText.trim();\n // Clicking the block rather than a line inside it locates nothing. The end is where an\n // author can carry on writing; the top is the one place they certainly did not aim at.\n if (literal === '' || literal === probe.rendered.trim()) return source.length;\n\n const candidates = [literal, literal.replace(/\\s+/g, ' ')];\n for (const text of candidates) {\n const whole = source.indexOf(text);\n if (whole !== -1) return whole;\n }\n for (const length of PROBE_LENGTHS) {\n for (const text of candidates) {\n if (text.length < length) continue;\n const at = source.indexOf(text.slice(0, length));\n if (at !== -1) return at;\n }\n }\n return source.length;\n}\n\n/** Where in `source` the caret belongs for a click the preview reported through `probe`. */\nexport function sourceOffsetFor(source: string, probe: ClickProbe): number {\n // The stock previews draw the source verbatim, so the browser's own caret position is\n // the answer, with no searching and no ambiguity between repeated lines.\n if (probe.renderedOffset !== null && probe.rendered === source) {\n return Math.max(0, Math.min(probe.renderedOffset, source.length));\n }\n return search(source, probe);\n}\n","// Bundlers replace `process.env.NODE_ENV` at build time. Declared locally rather than\n// pulled in from @types/node, because nothing else here needs a Node environment, and\n// guarded with `typeof` so a runtime that defines no `process` still works.\ndeclare const process: { env?: { NODE_ENV?: string } } | undefined;\n\nconst seen = new Set<string>();\n\n/** Warns the developer once per distinct message, and never in a production build. */\nexport function devWarn(message: string): void {\n if (typeof process !== 'undefined' && process?.env?.NODE_ENV === 'production') return;\n if (seen.has(message)) return;\n seen.add(message);\n console.warn(`Quoin: ${message}`);\n}\n\n/** Lets a test observe the warning again; nothing in the package calls it. */\nexport function resetDevWarnings(): void {\n seen.clear();\n}\n","'use client';\n\nimport * as React from 'react';\nimport { Plus } from 'lucide-react';\nimport { useQuoin } from '../context';\nimport { paletteBlocks } from '../registry';\nimport { Button } from '../ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../ui/dropdown-menu';\n\nexport function BlockInserter({\n index,\n onInsert,\n label,\n canvasRef,\n}: {\n index: number;\n onInsert: (index: number, type: string, data?: Record<string, unknown>) => void;\n label: string;\n canvasRef: React.RefObject<HTMLElement | null>;\n}) {\n const { blockTypes } = useQuoin();\n const options = paletteBlocks(blockTypes);\n const insertedAtRef = React.useRef<number | null>(null);\n\n function handleSelect(type: string) {\n insertedAtRef.current = index;\n onInsert(index, type);\n }\n\n function handleCloseAutoFocus(event: Event) {\n const insertedAt = insertedAtRef.current;\n insertedAtRef.current = null;\n if (insertedAt === null) return;\n\n event.preventDefault();\n const card = canvasRef.current?.querySelector<HTMLElement>(`[data-block-index=\"${insertedAt}\"]`);\n if (!card) return;\n if (typeof card.scrollIntoView === 'function') {\n card.scrollIntoView({ block: 'center', behavior: 'smooth' });\n }\n card.querySelector<HTMLElement>('textarea, input, [role=\"combobox\"]')?.focus();\n }\n\n return (\n <div className=\"group/inserter relative flex h-6 items-center justify-center pointer-coarse:h-11\">\n <span\n aria-hidden=\"true\"\n className=\"absolute inset-x-0 top-1/2 h-px bg-border opacity-0 transition-opacity group-hover/inserter:opacity-100 group-focus-within/inserter:opacity-100\"\n />\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon-xs\"\n aria-label={label}\n className=\"relative z-10 rounded-full bg-background opacity-0 transition-opacity group-hover/inserter:opacity-100 group-focus-within/inserter:opacity-100 focus-visible:opacity-100 pointer-coarse:opacity-100\"\n >\n <Plus aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"center\" className=\"w-56\" onCloseAutoFocus={handleCloseAutoFocus}>\n {options.map((opt) => (\n <DropdownMenuItem key={opt.type} onSelect={() => handleSelect(opt.type)}>\n <opt.icon aria-hidden=\"true\" />\n <span>{opt.label}</span>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport type { ChangeEvent } from 'react';\nimport type { TextCommand } from '../markdown/commands';\nimport { insertCommand } from '../markdown/insert-command';\nimport { ShortcutsReference } from '../markdown/ShortcutsReference';\nimport { SlashPalette } from '../markdown/SlashPalette';\nimport { useSlashPalette } from '../markdown/useSlashPalette';\nimport { FOCUS_RING } from '../ui/focus';\n\nconst LINE = [\n 'w-full resize-none rounded-md border-0 bg-transparent px-2 py-1',\n 'text-base leading-7 placeholder:text-muted-foreground',\n 'transition-[color,box-shadow]',\n FOCUS_RING,\n].join(' ');\n\nexport function DocumentStarter({\n autoFocus = false,\n onStart,\n onInsertBlock,\n}: {\n autoFocus?: boolean;\n onStart: (markdown: string, selection?: { start: number; end: number }) => void;\n onInsertBlock: (type: string) => void;\n}) {\n const ref = React.useRef<HTMLTextAreaElement>(null);\n const palette = useSlashPalette(ref);\n const [shortcutsOpen, setShortcutsOpen] = React.useState(false);\n\n // The line never keeps what is typed into it: the first character becomes a\n // block instead. Clearing the node directly rather than through state keeps\n // that true even when the handler causes no re-render of this component.\n function handleChange(e: ChangeEvent<HTMLTextAreaElement>) {\n const value = e.target.value;\n e.target.value = '';\n if (value === '') return;\n // A virtual keyboard, an IME or a paste delivers \"/\" with no keydown to\n // intercept, so the shortcut is recognised from the value as well.\n if (value === '/') palette.openAtCaret();\n else onStart(value);\n }\n\n function startWith(command: TextCommand) {\n palette.setOpen(false);\n const edit = insertCommand(command, '', 0);\n onStart(edit.value, { start: edit.selectionStart, end: edit.selectionEnd });\n }\n\n return (\n <div className=\"relative\">\n <textarea\n ref={ref}\n aria-label=\"Write something\"\n defaultValue=\"\"\n onChange={handleChange}\n onKeyDown={(e) => {\n if (e.nativeEvent.isComposing || e.keyCode === 229) return;\n if (e.key !== '/') return;\n e.preventDefault();\n palette.openAtCaret();\n }}\n autoFocus={autoFocus}\n rows={1}\n placeholder=\"Write, or press / for commands\"\n className={LINE}\n />\n <SlashPalette\n open={palette.open}\n caret={palette.caret}\n onOpenChange={palette.setOpen}\n onTextCommand={startWith}\n onBlockCommand={(type) => {\n palette.setOpen(false);\n onInsertBlock(type);\n }}\n onShortcuts={() => {\n palette.setOpen(false);\n setShortcutsOpen(true);\n }}\n onDismiss={() => palette.setOpen(false)}\n />\n <ShortcutsReference open={shortcutsOpen} onOpenChange={setShortcutsOpen} />\n </div>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport { BlockCard } from './BlockCard';\nimport type { QuoinBlock } from '../types';\n\n/** Draws the document at rest: every block's preview, with no inserters, menus, drag handles or editors. */\nexport function ReadOnlyCanvas({\n blocks,\n onUpdate,\n root,\n}: {\n blocks: QuoinBlock[];\n onUpdate: (id: string, data: Record<string, unknown>) => void;\n root: React.ComponentPropsWithRef<'div'>;\n}) {\n return (\n <div {...root}>\n <ul className=\"flex flex-col\">\n {blocks.map((b, i) => (\n <li key={b.id}>\n <div data-block-index={i} className=\"rounded-lg px-2 py-1\">\n <BlockCard block={b} index={i} editingByDefault={false} readOnly onUpdate={onUpdate} />\n </div>\n </li>\n ))}\n </ul>\n </div>\n );\n}\n","export function reorderIndices(\n ids: string[],\n activeId: string,\n overId: string | null,\n): { from: number; to: number } | null {\n if (overId === null || activeId === overId) return null;\n const from = ids.indexOf(activeId);\n const to = ids.indexOf(overId);\n if (from === -1 || to === -1) return null;\n return { from, to };\n}\n","import type { QuoinBlock } from '../types';\n\nfunction sameData(a: Record<string, unknown>, b: Record<string, unknown>): boolean {\n if (a === b) return true;\n const keys = Object.keys(a);\n if (keys.length !== Object.keys(b).length) return false;\n return keys.every((key) => Object.hasOwn(b, key) && Object.is(a[key], b[key]));\n}\n\n/** Whether two documents hold the same blocks in the same order, comparing each block's data one level deep. */\nexport function sameBlocks(a: QuoinBlock[], b: QuoinBlock[]): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n return a.every((block, i) => {\n const other = b[i];\n return block.id === other.id && block.type === other.type && sameData(block.data, other.data);\n });\n}\n","'use client';\n\nimport { useSortable } from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\nimport { GripVertical } from 'lucide-react';\nimport type { ReactNode } from 'react';\nimport { Button } from '../ui/button';\nimport { cn } from '../ui/cn';\n\n/** The gutter only leaves the text column once the viewport is wide enough to\n * hold it beside a 68ch measure, which is past `lg`. Below that it stacks above\n * the block, where it also has to stay visible: hover is not available there. */\nconst GUTTER = [\n 'flex items-center justify-end gap-0.5 pb-1',\n 'lg:absolute lg:right-full lg:top-1 lg:justify-start lg:pb-0 lg:pr-1',\n 'lg:opacity-0 lg:transition-opacity',\n 'lg:group-hover/block:opacity-100 lg:group-focus-within/block:opacity-100',\n].join(' ');\n\nexport function SortableBlock({\n id,\n index,\n actions,\n children,\n}: {\n id: string;\n index: number;\n actions?: ReactNode;\n children: ReactNode;\n}) {\n const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } =\n useSortable({ id });\n\n return (\n <div\n ref={setNodeRef}\n style={{ transform: CSS.Transform.toString(transform), transition }}\n className={cn('group/block relative', isDragging && 'z-10 opacity-80')}\n >\n <div className={GUTTER}>\n {actions}\n <Button\n type=\"button\"\n ref={setActivatorNodeRef}\n variant=\"ghost\"\n size=\"icon-sm\"\n className=\"cursor-grab text-muted-foreground active:cursor-grabbing\"\n aria-label={`Reorder block ${index + 1}`}\n {...attributes}\n {...listeners}\n >\n <GripVertical aria-hidden=\"true\" />\n </Button>\n </div>\n <div\n data-block-index={index}\n className={cn(\n 'rounded-lg px-2 py-1 transition-colors',\n isDragging ? 'bg-popover shadow-md' : 'group-hover/block:bg-muted/40',\n )}\n >\n {children}\n </div>\n </div>\n );\n}\n","import type { QuoinBlock } from '../types';\nimport { sameBlocks } from './same-blocks';\n\nexport const STRUCTURAL_ECHO_LIMIT = 64;\n\n/**\n * The canvas's emissions the host has not handed back yet. Each is numbered in order, and handing one\n * back acknowledges it and every older one. Numbers are looked up by identity, so an emission is\n * recognised however late it returns without being kept alive. Only the newest outstanding ones are\n * kept, for a structural copy from a cloning store to be compared against, which also bounds what a\n * host that never echoes costs.\n */\nexport type Unacknowledged = {\n sequences: WeakMap<QuoinBlock[], number>;\n emitted: number;\n acknowledged: number;\n newest: QuoinBlock[][];\n};\n\nexport function createUnacknowledged(): Unacknowledged {\n return { sequences: new WeakMap(), emitted: 0, acknowledged: 0, newest: [] };\n}\n\nfunction keepNewest(outstanding: Unacknowledged) {\n const kept = Math.min(STRUCTURAL_ECHO_LIMIT, outstanding.emitted - outstanding.acknowledged);\n outstanding.newest.splice(0, outstanding.newest.length - kept);\n}\n\nexport function remember(outstanding: Unacknowledged, blocks: QuoinBlock[]) {\n outstanding.emitted += 1;\n outstanding.sequences.set(blocks, outstanding.emitted);\n outstanding.newest.push(blocks);\n keepNewest(outstanding);\n}\n\n/** The oldest match wins, so a document that returns to an earlier state cannot skip the emissions in between. */\nfunction copiedSequence(outstanding: Unacknowledged, blocks: QuoinBlock[]): number | undefined {\n for (const emitted of outstanding.newest) {\n if (sameBlocks(emitted, blocks)) return outstanding.sequences.get(emitted);\n }\n return undefined;\n}\n\n/**\n * Whether `blocks` hands back an outstanding emission, as the same array or a copy of a recent one.\n * An emission the host has already moved past is not an echo, so replaying it from the host's undo\n * stack reads as a document of its own.\n */\nexport function acknowledge(outstanding: Unacknowledged, blocks: QuoinBlock[]): boolean {\n const echoed = outstanding.sequences.get(blocks) ?? copiedSequence(outstanding, blocks);\n if (echoed === undefined || echoed <= outstanding.acknowledged) return false;\n outstanding.acknowledged = echoed;\n keepNewest(outstanding);\n return true;\n}\n\nexport function forgetAll(outstanding: Unacknowledged) {\n outstanding.acknowledged = outstanding.emitted;\n keepNewest(outstanding);\n}\n","import * as React from 'react';\nimport {\n alwaysRetry,\n attemptSave,\n clearTimer,\n nextRetryDelay,\n type TimerRef,\n} from './autosave-backoff';\n\n/** Where a debounced save stands, for a \"Saving...\" or \"Saved\" indicator. */\nexport type AutosaveStatus = 'idle' | 'saving' | 'saved' | 'retrying' | 'failed';\n\n/** What `useAutosave` tracks, how to build the payload, and how to persist it. */\nexport type UseAutosaveInput<T> = {\n /** The tracked fields. An edit to any of them marks dirty and restarts the debounce. */\n deps: React.DependencyList;\n build: () => T;\n /**\n * Persists the payload. Return anything: a mutation or a `fetch` that resolves to a body\n * can be passed straight in. A save fails by rejecting, or by resolving to `{ ok: false }`.\n */\n save: (payload: T) => unknown;\n debounceMs?: number;\n maxBackoffMs?: number;\n /** Retries after a failed save before giving up with status `failed`. Defaults to 8. */\n maxRetries?: number;\n /**\n * Whether a failed save is worth retrying. Receives the rejection, or the resolved\n * `{ ok: false }` value. Return false for a permanent failure. Defaults to always.\n */\n isRetryable?: (error: unknown) => boolean;\n /** Save a pending edit when the page is hidden or closed. Defaults to true. */\n flushOnHide?: boolean;\n};\n\n/** The current save status, the last failure, and ways to save immediately. */\nexport type UseAutosaveResult = {\n status: AutosaveStatus;\n /** The last failure, kept while a retry is pending and cleared by the next success. */\n error: unknown;\n /** Saves now, even when nothing is pending, and starts the retries over. */\n retry: () => void;\n /** Saves a pending edit now and starts the retries over. A no-op when nothing is pending. */\n flush: () => void;\n};\n\n/**\n * Debounced last-write-wins autosave. Nothing fires on mount, only after the first real\n * edit. One save runs at a time: edits made while it runs are saved once it settles, as one\n * save of the newest payload. A failed save backs off exponentially until it lands, stops\n * being retryable or runs out of retries. An edit still waiting for its debounce is saved\n * on unmount and when the page is hidden. `save` and `build` are read at fire time, so\n * passing fresh closures each render is safe.\n */\nexport function useAutosave<T>({\n deps,\n build,\n save,\n debounceMs = 2000,\n maxBackoffMs = 30000,\n maxRetries = 8,\n isRetryable = alwaysRetry,\n flushOnHide = true,\n}: UseAutosaveInput<T>): UseAutosaveResult {\n // The effect order below is load-bearing: the dirty flag must be set before the\n // scheduling effect reads it within the same commit, and the \"latest closure\" refs\n // must be assigned after commit rather than during render.\n const [status, setStatus] = React.useState<AutosaveStatus>('idle');\n const [error, setError] = React.useState<unknown>(null);\n const dirtyRef = React.useRef(false);\n const inFlightRef = React.useRef(false);\n const disposedRef = React.useRef(false);\n const retriesRef = React.useRef(0);\n const debounceRef: TimerRef = React.useRef(null);\n const backoffRef: TimerRef = React.useRef(null);\n const buildRef = React.useRef(build);\n const saveRef = React.useRef(save);\n const runRef = React.useRef<() => void>(() => {});\n\n React.useEffect(() => {\n buildRef.current = build;\n saveRef.current = save;\n const policy = { debounceMs, maxBackoffMs, maxRetries, isRetryable };\n runRef.current = () => {\n clearTimer(debounceRef);\n clearTimer(backoffRef);\n if (inFlightRef.current) return;\n inFlightRef.current = true;\n dirtyRef.current = false;\n if (!disposedRef.current) setStatus('saving');\n void (async () => {\n const failure = await attemptSave(() => saveRef.current(buildRef.current()));\n inFlightRef.current = false;\n if (disposedRef.current) {\n if (dirtyRef.current) runRef.current();\n return;\n }\n if (!failure) {\n retriesRef.current = 0;\n setError(null);\n if (dirtyRef.current) runRef.current();\n else setStatus('saved');\n return;\n }\n dirtyRef.current = true;\n setError(failure.error);\n const delay = nextRetryDelay(failure.error, retriesRef.current, policy);\n if (delay === null) {\n setStatus('failed');\n return;\n }\n retriesRef.current += 1;\n setStatus('retrying');\n backoffRef.current = setTimeout(() => runRef.current(), delay);\n })();\n };\n });\n\n // Compares values rather than counting mounts: React's development remount\n // re-runs this effect with identical deps, and a \"have I mounted\" flag survives\n // that remount, so a flag marks an untouched editor dirty and autosaves it.\n const seenRef = React.useRef<React.DependencyList | null>(null);\n React.useEffect(() => {\n const seen = seenRef.current;\n seenRef.current = deps;\n if (seen === null) return;\n const unchanged = seen.length === deps.length && seen.every((v, i) => v === deps[i]);\n if (!unchanged) dirtyRef.current = true;\n // eslint-disable-next-line react-hooks/exhaustive-deps -- the caller owns the tracked fields\n }, deps);\n\n React.useEffect(() => {\n if (!dirtyRef.current) return;\n clearTimer(debounceRef);\n debounceRef.current = setTimeout(() => runRef.current(), debounceMs);\n return () => clearTimer(debounceRef);\n // eslint-disable-next-line react-hooks/exhaustive-deps -- the caller owns the tracked fields\n }, deps);\n\n React.useEffect(() => {\n disposedRef.current = false;\n return () => {\n disposedRef.current = true;\n clearTimer(debounceRef);\n clearTimer(backoffRef);\n if (dirtyRef.current) runRef.current();\n };\n }, []);\n\n const retry = React.useCallback(() => {\n retriesRef.current = 0;\n runRef.current();\n }, []);\n\n const flush = React.useCallback(() => {\n if (dirtyRef.current) retry();\n }, [retry]);\n\n React.useEffect(() => {\n if (!flushOnHide) return;\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 }, [flushOnHide, flush]);\n\n return { status, error, retry, flush };\n}\n","export type TimerRef = { current: ReturnType<typeof setTimeout> | null };\n\nexport function clearTimer(ref: TimerRef) {\n if (ref.current !== null) clearTimeout(ref.current);\n ref.current = null;\n}\n\nexport const alwaysRetry = () => true;\n\n/**\n * Whether a resolved save reported failure. Only an explicit `{ ok: false }` counts, so a\n * `save` that resolves to a response body, a mutation result or nothing at all is a success\n * and needs no wrapper to discard its value. Rejecting is still the other way to fail.\n */\nfunction reportedFailure(result: unknown): boolean {\n return (\n typeof result === 'object' &&\n result !== null &&\n 'ok' in result &&\n (result as { ok?: unknown }).ok === false\n );\n}\n\n/** Runs one save and returns its failure, or null when it succeeded. */\nexport async function attemptSave(run: () => unknown): Promise<{ error: unknown } | null> {\n try {\n const result = await run();\n return reportedFailure(result) ? { error: result } : null;\n } catch (error) {\n return { error };\n }\n}\n\nexport type RetryPolicy = {\n debounceMs: number;\n maxBackoffMs: number;\n maxRetries: number;\n isRetryable: (error: unknown) => boolean;\n};\n\n/** The wait before the next retry, or null when the failure is final. */\nexport function nextRetryDelay(\n error: unknown,\n retriesSoFar: number,\n { debounceMs, maxBackoffMs, maxRetries, isRetryable }: RetryPolicy,\n): number | null {\n if (retriesSoFar >= maxRetries || !isRetryable(error)) return null;\n return Math.min(debounceMs * 2 ** (retriesSoFar + 1), maxBackoffMs);\n}\n"],"mappings":"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","names":["React","seen","Code","React","React","jsx","Button","jsx","jsx","jsxs","jsx","jsx","jsxs","jsx","jsx","jsxs","jsx","jsxs","jsxs","jsx","jsx","jsx","jsx","jsx","jsxs","React","text","at","INDENT","at","React","React","React","jsx","jsxs","jsx","jsxs","React","jsx","Textarea","jsx","jsxs","React","jsx","Input","jsx","jsxs","useEffect","useRef","React","jsx","jsxs","jsx","jsxs","useRef","useEffect","jsx","jsxs","jsx","Code","React","CheckIcon","jsx","jsxs","jsx","jsx","jsx","jsxs","React","jsx","jsx","jsxs","React","jsx","jsxs","React","jsx","jsxs","jsx","jsx","jsxs","jsx","jsxs","newBlockId","id","React","seen"]}