@particle-academy/fancy-code 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -1
- package/dist/index.cjs +50 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +47 -7
- package/dist/index.d.ts +47 -7
- package/dist/index.js +50 -10
- package/dist/index.js.map +1 -1
- package/docs/CodeEditor.md +16 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/CodeEditor/CodeEditor.context.ts","../src/components/CodeEditor/diff-gutter.ts","../src/components/CodeEditor/CodeEditorPanel.tsx","../src/components/CodeEditor/CodeEditorToolbarSeparator.tsx","../src/languages/registry.ts","../src/languages/builtin.ts","../src/components/CodeEditor/CodeEditorToolbar.tsx","../src/components/CodeEditor/CodeEditorStatusBar.tsx","../src/themes/registry.ts","../src/themes/light.ts","../src/themes/dark.ts","../src/engine/position.ts","../src/hooks/use-editor-engine.ts","../src/hooks/use-dark-mode.ts","../src/components/CodeEditor/CodeEditor.tsx","../src/components/MarkdownEditor/MarkdownEditor.tsx","../src/office-viewers.ts","../src/file-type.ts","../src/components/FileViewer/FileViewer.tsx","../src/engine/markdown-render.ts","../src/input-tag.tsx"],"names":["themeColors","lineCount","activeLine","jsx","jsxs","cn","Fragment","useState","useMemo","useCallback","useRef","useEffect","useControllableState","ContentRenderer"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { CodeEditorContextValue } from \"./CodeEditor.types\";\n\nexport const CodeEditorContext = createContext<CodeEditorContextValue | null>(null);\n\nexport function useCodeEditor(): CodeEditorContextValue {\n const ctx = useContext(CodeEditorContext);\n if (!ctx) {\n throw new Error(\"useCodeEditor must be used within a <CodeEditor> component\");\n }\n return ctx;\n}\n","/**\n * Diff-gutter model — the pure mapping between fancy-file-commons line\n * annotations and what the CodeEditor gutter renders per line-number row.\n * Kept DOM-free (like engine/position.ts) so it's unit-testable; the panel\n * only paints what this resolves.\n */\nimport type { DiffAnnotations, LineChangeType } from \"@particle-academy/fancy-file-commons\";\nimport type { ThemeColors } from \"../../themes/types\";\n\n/** What one line-number row shows: its own change bar and/or a deletion wedge above. */\nexport interface GutterDiffMark {\n /** The line's own change (colored bar), if any. */\n type?: LineChangeType;\n /** True when one or more lines were deleted immediately above this line (wedge). */\n deletedAbove: boolean;\n}\n\n/** Resolve the mark for a 1-based line, or null when the line is untouched. */\nexport function gutterDiffMark(\n annotations: DiffAnnotations | null,\n line: number,\n): GutterDiffMark | null {\n if (!annotations) return null;\n const a = annotations.byLine[line];\n if (!a) return null;\n return { type: a.type, deletedAbove: (a.deletedAbove ?? 0) > 0 };\n}\n\n/** Whether the deleted-at-EOF wedge should render under the last line. */\nexport function hasDeletedAtEnd(annotations: DiffAnnotations | null): boolean {\n return (annotations?.deletedAtEnd ?? 0) > 0;\n}\n\n/** VS Code-convention fallbacks for themes that don't define diff colors. */\nconst FALLBACK = { added: \"#3fb950\", modified: \"#4184e4\", removed: \"#f85149\" } as const;\n\n/** The bar color for a change type, honoring theme overrides. */\nexport function diffMarkColor(type: LineChangeType, colors: ThemeColors): string {\n return type === \"added\"\n ? (colors.diffAdded ?? FALLBACK.added)\n : (colors.diffModified ?? FALLBACK.modified);\n}\n\n/** The deletion-wedge color, honoring theme overrides. */\nexport function diffRemovedColor(colors: ThemeColors): string {\n return colors.diffRemoved ?? FALLBACK.removed;\n}\n","import { useMemo } from \"react\";\nimport { cn } from \"@particle-academy/react-fancy\";\nimport { useCodeEditor } from \"./CodeEditor.context\";\nimport {\n diffMarkColor,\n diffRemovedColor,\n gutterDiffMark,\n hasDeletedAtEnd,\n} from \"./diff-gutter\";\nimport type { CodeEditorPanelProps } from \"./CodeEditor.types\";\n\nexport function CodeEditorPanel({ className }: CodeEditorPanelProps) {\n const {\n _engineReturn: engine,\n lineNumbers,\n wordWrap,\n readOnly,\n placeholder,\n _diffAnnotations: diffAnnotations,\n _maxHeight,\n _minHeight,\n _highlightLines: highlightLines,\n } = useCodeEditor();\n\n // This `useMemo` MUST run before the `!engine` guard below it.\n //\n // The guard used to come first, so a render without an engine ran ZERO hooks\n // and the next one ran one. React compares hook counts between renders, so\n // that transition desyncs the hook order and throws from deep inside React,\n // naming none of this code. `_engineReturn` is typed `| null` and starts null,\n // so the transition is real rather than theoretical.\n //\n // Reading the engine's fields inside the callback (rather than destructuring\n // above) is what lets the hook run unconditionally.\n const lineNumberElements = useMemo(() => {\n if (!engine || !lineNumbers) return null;\n const { themeColors, lineCount, activeLine } = engine;\n const removed = diffRemovedColor(themeColors);\n const highlighted = new Set(highlightLines ?? []);\n const lines = [];\n for (let i = 1; i <= lineCount; i++) {\n const mark = gutterDiffMark(diffAnnotations, i);\n lines.push(\n <div\n key={i}\n data-diff={mark?.type}\n data-diff-deleted-above={mark?.deletedAbove ? \"\" : undefined}\n style={{\n position: \"relative\",\n color: i === activeLine || highlighted.has(i) ? themeColors.foreground : themeColors.gutterForeground,\n backgroundColor: i === activeLine ? themeColors.activeLineBackground : undefined,\n fontWeight: highlighted.has(i) ? 600 : undefined,\n }}\n className=\"pr-3 text-right text-[13px] leading-[1.5] select-none\"\n >\n {/* Change bar — VS Code convention: green added, blue modified. */}\n {mark?.type && (\n <span\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n bottom: 0,\n width: 3,\n borderRadius: 2,\n backgroundColor: diffMarkColor(mark.type, themeColors),\n }}\n />\n )}\n {/* Deletion wedge — lines were removed immediately above this one. */}\n {mark?.deletedAbove && (\n <span\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n left: 0,\n top: -4,\n width: 0,\n height: 0,\n borderLeft: `8px solid ${removed}`,\n borderTop: \"4px solid transparent\",\n borderBottom: \"4px solid transparent\",\n }}\n />\n )}\n {i}\n {/* Deletion at EOF — removed lines hang below the last line. */}\n {i === lineCount && hasDeletedAtEnd(diffAnnotations) && (\n <span\n aria-hidden=\"true\"\n data-diff-deleted-at-end=\"\"\n style={{\n position: \"absolute\",\n left: 0,\n bottom: -4,\n width: 0,\n height: 0,\n borderLeft: `8px solid ${removed}`,\n borderTop: \"4px solid transparent\",\n borderBottom: \"4px solid transparent\",\n }}\n />\n )}\n </div>,\n );\n }\n return lines;\n }, [engine, lineNumbers, diffAnnotations, highlightLines]);\n\n // Every hook is above this line.\n if (!engine) return null;\n\n const {\n textareaRef,\n highlightedHtml,\n lineCount,\n activeLine,\n themeColors,\n handleKeyDown,\n handleInput,\n handleScroll,\n handleSelect,\n scrollTop,\n scrollLeft,\n } = engine;\n\n const gutterWidth = lineNumbers ? `${Math.max(String(lineCount).length, 2) * 0.75 + 1.5}em` : \"0\";\n\n const containerStyle: React.CSSProperties = {\n backgroundColor: themeColors.background,\n color: themeColors.foreground,\n minHeight: _minHeight,\n maxHeight: _maxHeight,\n };\n\n const isEmpty = textareaRef.current ? textareaRef.current.value.length === 0 : highlightedHtml.length === 0;\n\n return (\n <div\n data-fancy-code-panel=\"\"\n className={cn(\"relative overflow-auto\", className)}\n style={containerStyle}\n >\n <div className=\"flex min-h-full\">\n {/* Line numbers gutter */}\n {lineNumbers && (\n <div\n className=\"sticky left-0 z-10 shrink-0 pt-2.5 pb-2.5 pl-2\"\n style={{\n backgroundColor: themeColors.gutterBackground,\n borderRight: `1px solid ${themeColors.gutterBorder}`,\n width: gutterWidth,\n }}\n >\n {lineNumberElements}\n </div>\n )}\n\n {/* Editor area */}\n <div className={cn(\"relative flex-1\", wordWrap && \"min-w-0\")}>\n {/*\n Line bands — \"here is the line you were sent to\". Behind the code, and\n placed in em so they track the 13px / 1.5 line grid the gutter uses;\n 0.625rem is the editor's top padding (p-2.5).\n */}\n {(highlightLines ?? [])\n .filter((n) => Number.isInteger(n) && n >= 1 && n <= lineCount)\n .map((n) => (\n <div\n key={`highlight-${n}`}\n data-fancy-code-highlight-line={n}\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-x-0 text-[13px] leading-[1.5]\"\n style={{\n top: `calc(0.625rem + ${(n - 1) * 1.5}em)`,\n height: \"1.5em\",\n backgroundColor: themeColors.selectionBackground,\n opacity: 0.55,\n }}\n />\n ))}\n\n {/* Highlighted code overlay */}\n <pre\n className=\"pointer-events-none absolute inset-0 m-0 overflow-hidden border-none p-2.5 text-[13px] leading-[1.5]\"\n aria-hidden=\"true\"\n style={{\n whiteSpace: wordWrap ? \"pre-wrap\" : \"pre\",\n overflowWrap: wordWrap ? \"break-word\" : \"normal\",\n }}\n >\n <code dangerouslySetInnerHTML={{ __html: highlightedHtml + \"\\n\" }} />\n </pre>\n\n {/* Placeholder */}\n {placeholder && isEmpty && (\n <div\n className=\"pointer-events-none absolute left-0 top-0 p-2.5 text-[13px] leading-[1.5] opacity-40\"\n style={{ color: themeColors.foreground }}\n >\n {placeholder}\n </div>\n )}\n\n {/* Actual textarea for input */}\n <textarea\n ref={textareaRef}\n className={cn(\n \"relative m-0 block resize-none border-none bg-transparent p-2.5 text-[13px] leading-[1.5] text-transparent outline-none\",\n wordWrap ? \"w-full\" : \"min-w-full\",\n )}\n style={{\n caretColor: themeColors.cursorColor,\n minHeight: _minHeight ? _minHeight - 40 : 80,\n overflow: \"hidden\",\n whiteSpace: wordWrap ? \"pre-wrap\" : \"pre\",\n overflowWrap: wordWrap ? \"break-word\" : \"normal\",\n }}\n spellCheck={false}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n autoCapitalize=\"off\"\n readOnly={readOnly}\n onKeyDown={handleKeyDown}\n onInput={handleInput}\n onScroll={handleScroll}\n onSelect={handleSelect}\n onClick={handleSelect}\n />\n </div>\n </div>\n </div>\n );\n}\n\nCodeEditorPanel.displayName = \"CodeEditorPanel\";\n","export function CodeEditorToolbarSeparator() {\n return (\n <div\n data-fancy-code-toolbar-separator=\"\"\n className=\"mx-1 h-4 w-px bg-zinc-200 dark:bg-zinc-700\"\n />\n );\n}\n\nCodeEditorToolbarSeparator.displayName = \"CodeEditorToolbarSeparator\";\n","import type { LanguageDefinition } from \"./types\";\n\nconst languageRegistry = new Map<string, LanguageDefinition>();\n\nexport function registerLanguage(def: LanguageDefinition): void {\n languageRegistry.set(def.name.toLowerCase(), def);\n if (def.aliases) {\n for (const alias of def.aliases) {\n languageRegistry.set(alias.toLowerCase(), def);\n }\n }\n}\n\nexport function getLanguage(name: string): LanguageDefinition | undefined {\n return languageRegistry.get(name.toLowerCase());\n}\n\nexport function getRegisteredLanguages(): string[] {\n const seen = new Set<LanguageDefinition>();\n const names: string[] = [];\n for (const [, def] of languageRegistry) {\n if (!seen.has(def)) {\n seen.add(def);\n names.push(def.name);\n }\n }\n return names;\n}\n","import { registerLanguage } from \"./registry\";\n// Every grammar lives in @particle-academy/fancy-file-commons, shared with\n// react-fancy's CodeBlock / CodeView; fancy-code only registers them.\nimport {\n tokenizeJavaScript,\n tokenizeHtml,\n tokenizePhp,\n tokenizePython,\n tokenizeGo,\n tokenizeMarkdown,\n tokenizeShell,\n tokenizeDotenv,\n} from \"@particle-academy/fancy-file-commons\";\n\nregisterLanguage({\n name: \"Markdown\",\n aliases: [\"md\", \"markdown\", \"mkd\"],\n tokenize: tokenizeMarkdown,\n});\n\nregisterLanguage({\n name: \"JavaScript\",\n aliases: [\"js\", \"javascript\", \"jsx\"],\n tokenize: tokenizeJavaScript,\n});\n\nregisterLanguage({\n name: \"TypeScript\",\n aliases: [\"ts\", \"typescript\", \"tsx\"],\n tokenize: tokenizeJavaScript, // Same tokenizer — JS/TS syntax is identical for highlighting\n});\n\nregisterLanguage({\n name: \"HTML\",\n aliases: [\"html\", \"htm\"],\n tokenize: tokenizeHtml,\n});\n\nregisterLanguage({\n name: \"PHP\",\n aliases: [\"php\"],\n tokenize: tokenizePhp,\n});\n\nregisterLanguage({\n name: \"Python\",\n aliases: [\"py\", \"python\"],\n tokenize: tokenizePython,\n});\n\nregisterLanguage({\n name: \"Go\",\n aliases: [\"go\", \"golang\"],\n tokenize: tokenizeGo,\n});\n\nregisterLanguage({\n name: \"Shell\",\n aliases: [\"sh\", \"bash\", \"zsh\", \"shell\"],\n tokenize: tokenizeShell,\n});\n\nregisterLanguage({\n name: \"Dotenv\",\n aliases: [\"env\", \"dotenv\"],\n tokenize: tokenizeDotenv,\n});\n","import { useState } from \"react\";\nimport { cn } from \"@particle-academy/react-fancy\";\nimport { useCodeEditor } from \"./CodeEditor.context\";\nimport { CodeEditorToolbarSeparator } from \"./CodeEditorToolbarSeparator\";\nimport { getRegisteredLanguages } from \"../../languages\";\nimport type { CodeEditorToolbarProps } from \"./CodeEditor.types\";\n\nconst iconBtnClass =\n \"inline-flex items-center justify-center rounded-md p-1 text-zinc-500 transition-colors hover:bg-zinc-100 hover:text-zinc-700 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-200\";\n\nfunction LanguageSelector() {\n const { language, setLanguage } = useCodeEditor();\n const languages = getRegisteredLanguages();\n\n return (\n <select\n value={language}\n onChange={(e) => setLanguage(e.target.value)}\n className=\"h-6 rounded border border-zinc-200 bg-transparent px-1.5 text-[11px] text-zinc-600 outline-none transition-colors hover:border-zinc-300 dark:border-zinc-700 dark:text-zinc-400 dark:hover:border-zinc-600\"\n >\n {languages.map((lang) => (\n <option key={lang} value={lang}>\n {lang}\n </option>\n ))}\n </select>\n );\n}\n\nfunction DefaultToolbarActions() {\n const { copyToClipboard, toggleWordWrap, wordWrap } = useCodeEditor();\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n await copyToClipboard();\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n };\n\n return (\n <>\n <LanguageSelector />\n <CodeEditorToolbarSeparator />\n <button\n type=\"button\"\n onClick={toggleWordWrap}\n title={wordWrap ? \"Disable Word Wrap\" : \"Enable Word Wrap\"}\n className={cn(iconBtnClass, wordWrap && \"text-blue-500 dark:text-blue-400\")}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <path d=\"M3 12h15a3 3 0 110 6h-4\" />\n <polyline points=\"16 16 14 18 16 20\" />\n <line x1=\"3\" y1=\"18\" x2=\"10\" y2=\"18\" />\n </svg>\n </button>\n <button type=\"button\" onClick={handleCopy} title=\"Copy to Clipboard\" className={iconBtnClass}>\n {copied ? (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n ) : (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1\" />\n </svg>\n )}\n </button>\n </>\n );\n}\n\nexport function CodeEditorToolbar({ children, className }: CodeEditorToolbarProps) {\n const hasChildren = children != null;\n\n return (\n <div\n data-fancy-code-toolbar=\"\"\n className={cn(\n \"flex items-center gap-0.5 border-b border-zinc-200 px-2 py-1 dark:border-zinc-700\",\n className,\n )}\n >\n {hasChildren ? children : <DefaultToolbarActions />}\n </div>\n );\n}\n\nCodeEditorToolbar.displayName = \"CodeEditorToolbar\";\n","import { cn } from \"@particle-academy/react-fancy\";\nimport { useCodeEditor } from \"./CodeEditor.context\";\nimport type { CodeEditorStatusBarProps } from \"./CodeEditor.types\";\n\nexport function CodeEditorStatusBar({ children, className }: CodeEditorStatusBarProps) {\n const { cursorPosition, selectionLength, language, tabSize } = useCodeEditor();\n\n return (\n <div\n data-fancy-code-statusbar=\"\"\n className={cn(\n \"flex items-center gap-3 border-t border-zinc-200 px-3 py-1 text-[11px] text-zinc-500 dark:border-zinc-700 dark:text-zinc-400\",\n className,\n )}\n >\n {children ?? (\n <>\n <span>Ln {cursorPosition.line}, Col {cursorPosition.col}</span>\n {selectionLength > 0 && <span>{selectionLength} selected</span>}\n <span className=\"ml-auto\">{language}</span>\n <span>{tabSize} spaces</span>\n </>\n )}\n </div>\n );\n}\n\nCodeEditorStatusBar.displayName = \"CodeEditorStatusBar\";\n","import type { ThemeDefinition } from \"./types\";\n\nconst themeRegistry = new Map<string, ThemeDefinition>();\n\nexport function registerTheme(theme: ThemeDefinition): void {\n themeRegistry.set(theme.name.toLowerCase(), theme);\n}\n\nexport function getTheme(name: string): ThemeDefinition | undefined {\n return themeRegistry.get(name.toLowerCase());\n}\n\nexport function getRegisteredThemes(): string[] {\n return Array.from(themeRegistry.keys());\n}\n","import { LIGHT_COLORS } from \"@particle-academy/fancy-file-commons\";\nimport { registerTheme } from \"./registry\";\n\n// The palette lives in commons; fancy-code wraps it into a named, registrable\n// theme for its IDE's theme picker + `theme=\"auto\"` resolution.\nregisterTheme({\n name: \"light\",\n variant: \"light\",\n colors: LIGHT_COLORS,\n});\n","import { DARK_COLORS } from \"@particle-academy/fancy-file-commons\";\nimport { registerTheme } from \"./registry\";\n\n// The palette lives in commons; fancy-code wraps it into a named, registrable\n// theme for its IDE's theme picker + `theme=\"auto\"` resolution.\nregisterTheme({\n name: \"dark\",\n variant: \"dark\",\n colors: DARK_COLORS,\n});\n","/**\n * Convert a 1-based `line` / `column` into a 0-based character offset within\n * `text`. Out-of-range values clamp to the document and line bounds, so the\n * result is always a valid offset in `[0, text.length]`.\n *\n * - `line` below 1 clamps to line 1; above the last line clamps to the last line.\n * - `column` below 1 clamps to column 1; past the end of the line clamps to just\n * after the last character (so you can place the caret at the line end).\n */\nexport function lineColumnToOffset(text: string, line: number, column = 1): number {\n const lines = text.split(\"\\n\");\n const targetLine = Math.max(1, Math.min(Math.trunc(line) || 1, lines.length));\n\n let offset = 0;\n for (let i = 0; i < targetLine - 1; i++) {\n offset += lines[i].length + 1; // +1 for the consumed \"\\n\"\n }\n\n const lineText = lines[targetLine - 1] ?? \"\";\n const col = Math.max(1, Math.min(Math.trunc(column) || 1, lineText.length + 1));\n return offset + (col - 1);\n}\n","import { useEffect, useRef, useCallback, useState, useMemo, type RefObject } from \"react\";\nimport { getLanguage } from \"../languages\";\nimport { getTheme } from \"../themes\";\nimport { highlightCode } from \"../engine/highlight\";\nimport { lineColumnToOffset } from \"../engine/position\";\nimport type { ThemeColors } from \"../themes/types\";\nimport type { Tokenizer } from \"../engine/tokenizer\";\n\nexport interface UseEditorEngineOptions {\n containerRef: RefObject<HTMLDivElement | null>;\n value: string;\n onChange?: (value: string) => void;\n language: string;\n theme: string;\n readOnly: boolean;\n lineNumbers: boolean;\n wordWrap: boolean;\n tabSize: number;\n placeholder?: string;\n minHeight?: number;\n maxHeight?: number;\n onCursorChange?: (pos: { line: number; col: number; selectionLength: number }) => void;\n}\n\nexport interface UseEditorEngineReturn {\n textareaRef: RefObject<HTMLTextAreaElement | null>;\n highlightedHtml: string;\n lineCount: number;\n activeLine: number;\n themeColors: ThemeColors;\n handleKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;\n handleInput: () => void;\n handleScroll: () => void;\n handleSelect: () => void;\n /**\n * Place the caret on a 1-based `line` / `column` and scroll the editor so the\n * line is centered in view. Out-of-range positions clamp to document bounds.\n */\n revealLine: (line: number, column?: number, opts?: { focus?: boolean }) => void;\n scrollTop: number;\n scrollLeft: number;\n}\n\nconst DEFAULT_COLORS: ThemeColors = {\n background: \"#18181b\",\n foreground: \"#e4e4e7\",\n gutterBackground: \"#18181b\",\n gutterForeground: \"#52525b\",\n gutterBorder: \"#27272a\",\n activeLineBackground: \"#27272a\",\n selectionBackground: \"#1e3a5f\",\n cursorColor: \"#60a5fa\",\n keyword: \"#c084fc\",\n string: \"#34d399\",\n comment: \"#71717a\",\n number: \"#fbbf24\",\n operator: \"#22d3ee\",\n function: \"#60a5fa\",\n type: \"#fbbf24\",\n tag: \"#f87171\",\n attribute: \"#fbbf24\",\n attributeValue: \"#34d399\",\n punctuation: \"#a1a1aa\",\n variable: \"#e4e4e7\",\n};\n\nexport function useEditorEngine({\n value,\n onChange,\n language,\n theme,\n readOnly,\n wordWrap,\n tabSize,\n onCursorChange,\n}: UseEditorEngineOptions): UseEditorEngineReturn {\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const onChangeRef = useRef(onChange);\n const onCursorChangeRef = useRef(onCursorChange);\n onChangeRef.current = onChange;\n onCursorChangeRef.current = onCursorChange;\n\n const [scrollTop, setScrollTop] = useState(0);\n const [scrollLeft, setScrollLeft] = useState(0);\n const [activeLine, setActiveLine] = useState(1);\n\n // Resolve theme colors\n const themeColors = useMemo<ThemeColors>(() => {\n const def = getTheme(theme);\n return def?.colors ?? DEFAULT_COLORS;\n }, [theme]);\n\n // Resolve tokenizer\n const tokenizer = useMemo<Tokenizer | null>(() => {\n const def = getLanguage(language);\n return def?.tokenize ?? null;\n }, [language]);\n\n // Generate highlighted HTML\n const highlightedHtml = useMemo(() => {\n if (!tokenizer) {\n // No tokenizer — just escape HTML\n return value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\");\n }\n const tokens = tokenizer(value);\n return highlightCode(value, tokens, themeColors);\n }, [value, tokenizer, themeColors]);\n\n const lineCount = useMemo(() => {\n let count = 1;\n for (let i = 0; i < value.length; i++) {\n if (value[i] === \"\\n\") count++;\n }\n return count;\n }, [value]);\n\n // Auto-resize textarea to match content so caret is always visible\n const autoResize = useCallback(() => {\n const ta = textareaRef.current;\n if (!ta) return;\n ta.style.height = \"auto\";\n ta.style.height = ta.scrollHeight + \"px\";\n\n if (!wordWrap) {\n // Shrink to 0 to measure true content width, then expand\n ta.style.width = \"0\";\n ta.style.width = ta.scrollWidth + \"px\";\n } else {\n ta.style.width = \"\";\n }\n }, [wordWrap]);\n\n // Sync textarea value and auto-resize when value changes\n useEffect(() => {\n const ta = textareaRef.current;\n if (!ta) return;\n if (ta.value !== value) {\n const { selectionStart, selectionEnd } = ta;\n ta.value = value;\n ta.selectionStart = selectionStart;\n ta.selectionEnd = selectionEnd;\n }\n // Always resize — handles initial mount and external value changes\n autoResize();\n }, [value, autoResize]);\n\n const updateCursorInfo = useCallback(() => {\n const ta = textareaRef.current;\n if (!ta) return;\n const pos = ta.selectionStart;\n const textBefore = ta.value.slice(0, pos);\n const line = (textBefore.match(/\\n/g) || []).length + 1;\n const lastNewline = textBefore.lastIndexOf(\"\\n\");\n const col = pos - lastNewline;\n const selLen = Math.abs(ta.selectionEnd - ta.selectionStart);\n setActiveLine(line);\n onCursorChangeRef.current?.({ line, col, selectionLength: selLen });\n }, []);\n\n const handleInput = useCallback(() => {\n const ta = textareaRef.current;\n if (!ta) return;\n onChangeRef.current?.(ta.value);\n autoResize();\n updateCursorInfo();\n }, [autoResize, updateCursorInfo]);\n\n const handleSelect = useCallback(() => {\n updateCursorInfo();\n }, [updateCursorInfo]);\n\n const handleScroll = useCallback(() => {\n const ta = textareaRef.current;\n if (!ta) return;\n setScrollTop(ta.scrollTop);\n setScrollLeft(ta.scrollLeft);\n }, []);\n\n const revealLine = useCallback(\n (line: number, column = 1, opts?: { focus?: boolean }) => {\n const ta = textareaRef.current;\n if (!ta) return;\n\n const offset = lineColumnToOffset(ta.value, line, column);\n if (opts?.focus) ta.focus();\n ta.selectionStart = ta.selectionEnd = offset;\n updateCursorInfo();\n\n // Scroll the editor's scroll container (the panel) so the target line is\n // centered. The textarea is auto-sized to fit its content, so the panel —\n // not the textarea — is what scrolls.\n const panel = ta.closest<HTMLElement>(\"[data-fancy-code-panel]\");\n if (!panel) return;\n const cs = getComputedStyle(ta);\n const lineHeight = parseFloat(cs.lineHeight) || 19.5;\n const paddingTop = parseFloat(cs.paddingTop) || 0;\n const lineIndex = (ta.value.slice(0, offset).match(/\\n/g) || []).length; // clamped (targetLine - 1)\n const textareaTopInPanel =\n ta.getBoundingClientRect().top - panel.getBoundingClientRect().top + panel.scrollTop;\n const lineTop = textareaTopInPanel + paddingTop + lineIndex * lineHeight;\n const target = lineTop - panel.clientHeight / 2 + lineHeight / 2;\n const maxScroll = panel.scrollHeight - panel.clientHeight;\n panel.scrollTop = Math.max(0, Math.min(target, maxScroll));\n },\n [updateCursorInfo],\n );\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (readOnly) {\n // Allow copy shortcuts in read-only mode\n if (e.key === \"c\" && (e.metaKey || e.ctrlKey)) return;\n if (e.key === \"a\" && (e.metaKey || e.ctrlKey)) return;\n e.preventDefault();\n return;\n }\n\n // Tab key — insert spaces\n if (e.key === \"Tab\") {\n e.preventDefault();\n const ta = e.currentTarget;\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n const spaces = \" \".repeat(tabSize);\n\n if (e.shiftKey) {\n // Dedent: remove leading spaces from selected lines\n const lines = ta.value.split(\"\\n\");\n const startLine = ta.value.slice(0, start).split(\"\\n\").length - 1;\n const endLine = ta.value.slice(0, end).split(\"\\n\").length - 1;\n let removed = 0;\n for (let i = startLine; i <= endLine; i++) {\n const match = lines[i].match(new RegExp(`^ {1,${tabSize}}`));\n if (match) {\n removed += match[0].length;\n lines[i] = lines[i].slice(match[0].length);\n }\n }\n const newValue = lines.join(\"\\n\");\n ta.value = newValue;\n ta.selectionStart = Math.max(0, start - (startLine === endLine ? removed : tabSize));\n ta.selectionEnd = Math.max(0, end - removed);\n onChangeRef.current?.(newValue);\n } else if (start !== end) {\n // Indent selected lines\n const lines = ta.value.split(\"\\n\");\n const startLine = ta.value.slice(0, start).split(\"\\n\").length - 1;\n const endLine = ta.value.slice(0, end).split(\"\\n\").length - 1;\n for (let i = startLine; i <= endLine; i++) {\n lines[i] = spaces + lines[i];\n }\n const newValue = lines.join(\"\\n\");\n ta.value = newValue;\n ta.selectionStart = start + tabSize;\n ta.selectionEnd = end + (endLine - startLine + 1) * tabSize;\n onChangeRef.current?.(newValue);\n } else {\n // Insert tab at cursor\n const before = ta.value.slice(0, start);\n const after = ta.value.slice(end);\n ta.value = before + spaces + after;\n ta.selectionStart = ta.selectionEnd = start + tabSize;\n onChangeRef.current?.(ta.value);\n }\n autoResize();\n updateCursorInfo();\n return;\n }\n\n // Enter — auto-indent\n if (e.key === \"Enter\") {\n e.preventDefault();\n const ta = e.currentTarget;\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n const before = ta.value.slice(0, start);\n const after = ta.value.slice(end);\n const currentLine = before.split(\"\\n\").pop() || \"\";\n const indent = currentLine.match(/^(\\s*)/)?.[1] || \"\";\n\n // Extra indent after { or (\n const lastChar = before.trimEnd().slice(-1);\n const extraIndent = (lastChar === \"{\" || lastChar === \"(\") ? \" \".repeat(tabSize) : \"\";\n\n const insertion = \"\\n\" + indent + extraIndent;\n ta.value = before + insertion + after;\n ta.selectionStart = ta.selectionEnd = start + insertion.length;\n onChangeRef.current?.(ta.value);\n autoResize();\n updateCursorInfo();\n return;\n }\n },\n [readOnly, tabSize, autoResize, updateCursorInfo],\n );\n\n return {\n textareaRef,\n highlightedHtml,\n lineCount,\n activeLine,\n themeColors,\n handleKeyDown,\n handleInput,\n handleScroll,\n handleSelect,\n revealLine,\n scrollTop,\n scrollLeft,\n };\n}\n","import { useSyncExternalStore } from \"react\";\n\nfunction subscribe(callback: () => void): () => void {\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n mq.addEventListener(\"change\", callback);\n return () => mq.removeEventListener(\"change\", callback);\n}\n\nfunction getSnapshot(): boolean {\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n}\n\nfunction getServerSnapshot(): boolean {\n return false;\n}\n\nexport function useDarkMode(): boolean {\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n","import { useEffect, useMemo, useRef, useState, useCallback } from \"react\";\nimport { cn, useControllableState } from \"@particle-academy/react-fancy\";\nimport { annotateLines } from \"@particle-academy/fancy-file-commons\";\nimport { CodeEditorContext } from \"./CodeEditor.context\";\nimport { CodeEditorPanel } from \"./CodeEditorPanel\";\nimport { CodeEditorToolbar } from \"./CodeEditorToolbar\";\nimport { CodeEditorToolbarSeparator } from \"./CodeEditorToolbarSeparator\";\nimport { CodeEditorStatusBar } from \"./CodeEditorStatusBar\";\nimport { useEditorEngine } from \"../../hooks/use-editor-engine\";\nimport { useDarkMode } from \"../../hooks/use-dark-mode\";\nimport { getLanguage } from \"../../languages\";\nimport type { CodeEditorProps, CodeEditorContextValue } from \"./CodeEditor.types\";\n\nfunction CodeEditorRoot({\n children,\n className,\n value: valueProp,\n defaultValue = \"\",\n onChange,\n language: languageProp = \"javascript\",\n onLanguageChange,\n theme = \"auto\",\n readOnly = false,\n lineNumbers: lineNumbersProp = true,\n wordWrap: wordWrapProp = false,\n tabSize: tabSizeProp = 2,\n placeholder,\n minHeight,\n maxHeight,\n cursorLine,\n cursorColumn,\n diffBase,\n highlightLines,\n}: CodeEditorProps) {\n const [currentValue, setCurrentValue] = useControllableState(valueProp, defaultValue, onChange);\n\n // Diff gutter: per-line change marks of the current value vs the baseline.\n // Line-level only (no intra-line segmentation), recomputed as the user types.\n const diffAnnotations = useMemo(\n () => (diffBase == null ? null : annotateLines(diffBase, currentValue)),\n [diffBase, currentValue],\n );\n\n // Reactive dark mode for \"auto\" theme\n const isDark = useDarkMode();\n const resolvedTheme = theme === \"auto\" ? (isDark ? \"dark\" : \"light\") : theme;\n\n // Language state (changeable via toolbar selector)\n const [currentLanguage, setCurrentLanguageState] = useState(() => {\n const def = getLanguage(languageProp);\n return def?.name ?? languageProp;\n });\n\n const setLanguage = useCallback(\n (lang: string) => {\n const def = getLanguage(lang);\n const resolved = def?.name ?? lang;\n setCurrentLanguageState(resolved);\n onLanguageChange?.(resolved);\n },\n [onLanguageChange],\n );\n\n // Toggle states\n const [showLineNumbers, setShowLineNumbers] = useState(lineNumbersProp);\n const [isWordWrap, setIsWordWrap] = useState(wordWrapProp);\n\n // Cursor position\n const [cursorPosition, setCursorPosition] = useState({ line: 1, col: 1 });\n const [selectionLength, setSelectionLength] = useState(0);\n\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Our custom editor engine\n const engineReturn = useEditorEngine({\n containerRef,\n value: currentValue,\n onChange: setCurrentValue,\n language: currentLanguage,\n theme: resolvedTheme,\n readOnly,\n lineNumbers: showLineNumbers,\n wordWrap: isWordWrap,\n tabSize: tabSizeProp,\n placeholder,\n minHeight,\n maxHeight,\n onCursorChange: ({ line, col, selectionLength: sel }) => {\n setCursorPosition({ line, col });\n setSelectionLength(sel);\n },\n });\n\n // Reveal + place the caret when cursorLine/cursorColumn change (and on mount).\n // revealLine is stable, so this fires only on target change; it runs after the\n // engine's value-sync effect, so the textarea is populated and sized first.\n const { revealLine: revealLineImpl } = engineReturn;\n useEffect(() => {\n if (cursorLine == null) return;\n revealLineImpl(cursorLine, cursorColumn ?? 1, { focus: false });\n }, [cursorLine, cursorColumn, revealLineImpl]);\n\n const contextValue = useMemo<CodeEditorContextValue>(\n () => ({\n getValue: () => engineReturn.textareaRef.current?.value ?? currentValue,\n getSelection: () => {\n const ta = engineReturn.textareaRef.current;\n if (!ta) return \"\";\n return ta.value.slice(ta.selectionStart, ta.selectionEnd);\n },\n setValue: (v: string) => setCurrentValue(v),\n replaceSelection: (text: string) => {\n const ta = engineReturn.textareaRef.current;\n if (!ta) return;\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n const before = ta.value.slice(0, start);\n const after = ta.value.slice(end);\n ta.value = before + text + after;\n ta.selectionStart = ta.selectionEnd = start + text.length;\n setCurrentValue(ta.value);\n },\n focus: () => engineReturn.textareaRef.current?.focus(),\n revealLine: (line: number, column?: number) =>\n engineReturn.revealLine(line, column ?? 1, { focus: true }),\n setCursor: ({ line, column }: { line: number; column?: number }) =>\n engineReturn.revealLine(line, column ?? 1, { focus: true }),\n language: currentLanguage,\n setLanguage,\n theme: resolvedTheme,\n readOnly,\n lineNumbers: showLineNumbers,\n wordWrap: isWordWrap,\n tabSize: tabSizeProp,\n toggleWordWrap: () => setIsWordWrap((w) => !w),\n toggleLineNumbers: () => setShowLineNumbers((l) => !l),\n copyToClipboard: async () => {\n const text = engineReturn.textareaRef.current?.value ?? currentValue;\n await navigator.clipboard.writeText(text);\n },\n cursorPosition,\n selectionLength,\n textareaRef: engineReturn.textareaRef,\n placeholder,\n diffStats: diffAnnotations\n ? {\n added: diffAnnotations.added,\n modified: diffAnnotations.modified,\n removed: diffAnnotations.removed,\n }\n : null,\n _diffAnnotations: diffAnnotations,\n _engineReturn: engineReturn,\n _minHeight: minHeight,\n _maxHeight: maxHeight,\n _highlightLines: highlightLines,\n }),\n [engineReturn, currentValue, currentLanguage, setLanguage, resolvedTheme, readOnly, showLineNumbers, isWordWrap, tabSizeProp, cursorPosition, selectionLength, setCurrentValue, placeholder, diffAnnotations, minHeight, maxHeight, highlightLines],\n );\n\n return (\n <CodeEditorContext.Provider value={contextValue}>\n <div\n data-fancy-code-editor=\"\"\n className={cn(\n \"overflow-hidden\",\n className,\n )}\n >\n {children}\n </div>\n </CodeEditorContext.Provider>\n );\n}\n\nCodeEditorRoot.displayName = \"CodeEditor\";\n\nconst ToolbarWithSeparator = Object.assign(CodeEditorToolbar, {\n Separator: CodeEditorToolbarSeparator,\n});\n\nexport const CodeEditor = Object.assign(CodeEditorRoot, {\n Toolbar: ToolbarWithSeparator,\n Panel: CodeEditorPanel,\n StatusBar: CodeEditorStatusBar,\n});\n","import { cn, ContentRenderer, useControllableState } from \"@particle-academy/react-fancy\";\nimport { CodeEditor } from \"../CodeEditor\";\n\nexport type MarkdownEditorMode = \"split\" | \"edit\" | \"preview\";\n\nexport interface MarkdownEditorProps {\n /** Controlled markdown value. */\n value?: string;\n /** Initial value (uncontrolled). */\n defaultValue?: string;\n /** Called with the new markdown whenever the document changes. */\n onValueChange?: (markdown: string) => void;\n /**\n * Layout: `split` (editor + live preview side by side), `edit` (editor only),\n * or `preview` (rendered only). Default `split`.\n */\n mode?: MarkdownEditorMode;\n /** Editor theme — `\"light\" | \"dark\" | \"auto\"` or a registered name. Default `auto`. */\n theme?: string;\n /** Prevent editing. */\n readOnly?: boolean;\n /** Show line numbers in the editor (default false — prose reads better without). */\n lineNumbers?: boolean;\n /** Wrap long lines in the editor (default true for prose). */\n wordWrap?: boolean;\n /** Placeholder shown when empty. */\n placeholder?: string;\n /**\n * Height bounds (px). `maxHeight` constrains the PREVIEW pane as well as the\n * editor — it previously reached only the editor, so a long document rendered\n * at full height instead of scrolling.\n */\n minHeight?: number;\n maxHeight?: number;\n className?: string;\n /**\n * Swap the markdown → HTML renderer used by the preview pane.\n *\n * Rarely needed now: the preview renders through react-fancy's\n * `<ContentRenderer format=\"markdown\">`, which is a full CommonMark + GFM\n * parse. Supply this only to impose your own pipeline — the returned HTML is\n * injected as-is, so it must already be sanitised.\n */\n renderPreview?: (markdown: string) => string;\n}\n\n/**\n * A markdown-aware editor: a syntax-highlighted `CodeEditor` (the registered\n * `markdown` language) with an optional live preview pane. Controlled via\n * `value` + `onValueChange`. The preview renders through react-fancy's\n * `<ContentRenderer format=\"markdown\">` — a full CommonMark + GFM parse,\n * sanitised by default. Pass `renderPreview` to impose your own pipeline.\n *\n * ```tsx\n * <MarkdownEditor value={md} onValueChange={setMd} mode=\"split\" minHeight={240} />\n * ```\n */\nexport function MarkdownEditor({\n value,\n defaultValue = \"\",\n onValueChange,\n mode = \"split\",\n theme = \"auto\",\n readOnly = false,\n lineNumbers = false,\n wordWrap = true,\n placeholder,\n minHeight,\n maxHeight,\n className,\n renderPreview,\n}: MarkdownEditorProps) {\n const [content, setContent] = useControllableState(value, defaultValue, onValueChange);\n\n const showEditor = mode !== \"preview\";\n const showPreview = mode !== \"edit\";\n\n return (\n <div\n data-fancy-markdown-editor=\"\"\n data-mode={mode}\n className={cn(\"fancy-md-editor\", className)}\n >\n {showEditor && (\n <div className=\"fancy-md-editor-pane\">\n <CodeEditor\n value={content}\n onChange={setContent}\n language=\"markdown\"\n theme={theme}\n readOnly={readOnly}\n lineNumbers={lineNumbers}\n wordWrap={wordWrap}\n placeholder={placeholder}\n minHeight={minHeight}\n maxHeight={maxHeight}\n >\n <CodeEditor.Panel />\n </CodeEditor>\n </div>\n )}\n {showPreview && (\n <div\n data-fancy-markdown-preview=\"\"\n className=\"fancy-md-preview\"\n style={maxHeight ? { maxHeight, overflowY: \"auto\" } : undefined}\n >\n {renderPreview ? (\n // The host imposed its own pipeline; its HTML is injected as-is and\n // is its own responsibility to sanitise.\n <div dangerouslySetInnerHTML={{ __html: renderPreview(content) }} />\n ) : (\n // The kit's own renderer — a full CommonMark + GFM parse that\n // sanitises by default. `marked` already sits in this tree as a\n // react-fancy runtime dependency, so the built-in renderer this\n // replaced was a second, weaker markdown implementation next to a\n // complete one.\n <ContentRenderer value={content} format=\"markdown\" />\n )}\n </div>\n )}\n </div>\n );\n}\n\nMarkdownEditor.displayName = \"MarkdownEditor\";\n","import type { ComponentType } from \"react\";\nimport type { FauxClientProps } from \"@particle-academy/react-fancy\";\nimport type { OfficeKind } from \"./file-type\";\n\n/** What a registered Office viewer is given. */\nexport interface OfficeViewerProps {\n /** The file's contents as our reader returns them (a dark-slide deck, a holy-sheet workbook, a last-word doc). */\n document: unknown;\n filename?: string;\n /** Passed through from `FileViewer`, for viewers that sit in the FauxClient frame. */\n frameProps?: Partial<FauxClientProps>;\n}\n\nexport interface OfficeViewerOptions {\n /**\n * Read the raw file in the browser, for when the app has only a URL. Give it\n * our JS reader, e.g. `(bytes) => new PptxReader().read(bytes)`. Without it,\n * a file with no server-read `document` gets the download card.\n */\n read?: (bytes: Uint8Array) => unknown;\n}\n\ninterface Registration {\n View: ComponentType<OfficeViewerProps>;\n read?: (bytes: Uint8Array) => unknown;\n}\n\nconst registry = new Map<OfficeKind, Registration>();\n\n/**\n * Show one Office format in `FileViewer` with a kit viewer. Call once at app\n * start, per format you want:\n *\n * ```ts\n * import { registerOfficeViewer } from \"@particle-academy/fancy-code\";\n * import { DeckFileView } from \"@particle-academy/fancy-slides\";\n * import { PptxReader } from \"@particle-academy/dark-slide\";\n *\n * registerOfficeViewer(\"pptx\", DeckFileView, { read: (b) => new PptxReader().read(b) });\n * ```\n *\n * A registry rather than an import because fancy-code must not depend on the\n * slide or sheet packages: an app that has neither (and does not want them)\n * would otherwise fail to build on a file type it never opens.\n */\nexport function registerOfficeViewer(\n kind: OfficeKind,\n View: ComponentType<OfficeViewerProps>,\n options: OfficeViewerOptions = {},\n): void {\n registry.set(kind, { View, read: options.read });\n}\n\n/** The viewer registered for a format, if any. */\nexport function officeViewerFor(kind: OfficeKind): Registration | undefined {\n return registry.get(kind);\n}\n\n/** Forget every registration (tests, hot reload). */\nexport function clearOfficeViewers(): void {\n registry.clear();\n}\n","import { resolveMediaType, type MediaKind } from \"@particle-academy/react-fancy\";\nimport { languageFromFilename } from \"@particle-academy/fancy-file-commons\";\n\n/**\n * The decision a file viewer makes about a file: render it as editable text, or\n * hand it to a media viewer. `media` carries the resolved {@link MediaKind};\n * `text` carries the editor language id.\n */\nexport type FileKind =\n | { kind: \"text\"; language: string }\n | { kind: \"media\"; mediaKind: MediaKind }\n /** Read as a reader sees it (rendered), not as source. `language` is for the source view. */\n | { kind: \"document\"; format: DocumentFormat; language: string }\n /** An Office file: binary, so never text. */\n | { kind: \"office\"; officeKind: OfficeKind };\n\nexport type DocumentFormat = \"markdown\" | \"html\" | \"text\";\nexport type OfficeKind = \"docx\" | \"xlsx\" | \"pptx\";\n\nconst OFFICE_EXT: Record<string, OfficeKind> = { docx: \"docx\", xlsx: \"xlsx\", xlsm: \"xlsx\", pptx: \"pptx\" };\nconst OFFICE_MIME: Record<string, OfficeKind> = {\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\": \"docx\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\": \"xlsx\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\": \"pptx\",\n};\n// By extension, not by editor language: `.xml` and `.vue` share the html\n// language for highlighting, and neither is a page to render.\nconst DOCUMENT_EXT: Record<string, DocumentFormat> = {\n md: \"markdown\",\n markdown: \"markdown\",\n html: \"html\",\n htm: \"html\",\n txt: \"text\",\n text: \"text\",\n};\nconst DOCUMENT_MIME: Record<string, DocumentFormat> = {\n \"text/markdown\": \"markdown\",\n \"text/x-markdown\": \"markdown\",\n \"text/html\": \"html\",\n \"text/plain\": \"text\",\n};\n\nfunction extensionOf(filename?: string): string {\n const name = (filename ?? \"\").split(/[?#]/)[0].split(\"/\").pop() ?? \"\";\n const dot = name.lastIndexOf(\".\");\n return dot > 0 ? name.slice(dot + 1).toLowerCase() : \"\";\n}\n\nexport interface ResolveFileKindInput {\n /** File name or path — sniffed for an extension (and used for the media check). */\n filename?: string;\n /** MIME type — preferred over the filename when known. */\n mime?: string;\n}\n\n// Filename → language now lives in @particle-academy/fancy-file-commons (the\n// shared core for the file packages — one EXT_LANGUAGE map suite-wide).\n// Re-exported so existing `fancy-code` imports keep working.\nexport { languageFromFilename };\n\n/**\n * Decide whether a file is previewable media (image / video / audio / PDF) or\n * text, from its MIME type (preferred) and/or filename. Media wins when the\n * type resolves to one; otherwise it's text and the editor language is derived\n * from the extension.\n *\n * Exposed so consumers can branch their own chrome (tabs, save buttons) the\n * same way `<FileViewer>` does internally.\n *\n * ```ts\n * resolveFileKind({ filename: \"logo.png\" }); // { kind: \"media\", mediaKind: \"image\" }\n * resolveFileKind({ filename: \"app.tsx\" }); // { kind: \"text\", language: \"typescript\" }\n * resolveFileKind({ mime: \"application/pdf\" }); // { kind: \"media\", mediaKind: \"pdf\" }\n * ```\n */\nexport function resolveFileKind({ filename, mime }: ResolveFileKindInput): FileKind {\n const media = resolveMediaType({ mime, src: filename });\n if (media !== \"unknown\") return { kind: \"media\", mediaKind: media };\n\n const type = (mime ?? \"\").split(\";\")[0].trim().toLowerCase();\n const ext = extensionOf(filename);\n\n const office = OFFICE_MIME[type] ?? OFFICE_EXT[ext];\n if (office) return { kind: \"office\", officeKind: office };\n\n const language = languageFromFilename(filename);\n // The extension wins when it names one: hosts label source `text/plain`.\n // A bare MIME decides only when the name says nothing (no filename, or a\n // plain-text one).\n const format = DOCUMENT_EXT[ext] ?? (language === \"plaintext\" ? DOCUMENT_MIME[type] : undefined);\n if (format) {\n // A text/* MIME with no filename still needs a source-view language.\n const lang = language !== \"plaintext\" ? language : format === \"markdown\" ? \"markdown\" : format === \"html\" ? \"html\" : \"plaintext\";\n return { kind: \"document\", format, language: lang };\n }\n\n return { kind: \"text\", language };\n}\n","import { useEffect, useState } from \"react\";\nimport { Callout, cn, ContentRenderer, FauxClient, MediaViewer } from \"@particle-academy/react-fancy\";\nimport { officeViewerFor } from \"../../office-viewers\";\nimport { CodeEditor } from \"../CodeEditor\";\nimport { resolveFileKind, type OfficeKind } from \"../../file-type\";\nimport type { FileViewerProps } from \"./FileViewer.types\";\n\n/**\n * A unified file viewer: renders text files in a read-only `CodeEditor` (with\n * syntax highlighting picked from the filename) and media files — image, video,\n * audio, PDF — via react-fancy's `<MediaViewer>`. The text-vs-media decision is\n * made by {@link resolveFileKind}; pass `fileKind` to override it, or call\n * `resolveFileKind` yourself to branch your own chrome (tabs, save buttons).\n *\n * Give the container a height for media files (PDF/image/video fill their box).\n *\n * ```tsx\n * // text\n * <FileViewer filename=\"app.tsx\" value={source} />\n * // media\n * <FileViewer filename=\"logo.png\" src={url} style={{ height: 360 }} />\n * ```\n */\nexport function FileViewer({\n filename,\n mime,\n src,\n value = \"\",\n onChange,\n readOnly = true,\n theme = \"auto\",\n fileKind,\n lineNumbers = true,\n wordWrap = false,\n line,\n column,\n highlightLines,\n minHeight,\n maxHeight,\n mediaProps,\n view = \"rendered\",\n frameProps,\n document,\n className,\n style,\n}: FileViewerProps) {\n const resolved = fileKind ?? resolveFileKind({ filename, mime });\n\n // A document reads as a reader sees it. Its source is shown instead when the\n // caller is editing, asked for it, or wants to land on a line (a line is a\n // place in the source, not in the rendered page).\n if (resolved.kind === \"document\" && view === \"rendered\" && readOnly && line == null) {\n return (\n <div\n data-fancy-file-viewer=\"\"\n data-kind=\"document\"\n data-format={resolved.format}\n className={className}\n style={style}\n >\n <FauxClient variant=\"device\" controls fill bodyClassName=\"overflow-auto\" {...frameProps}>\n <div className=\"px-6 py-5\">\n <ContentRenderer\n value={resolved.format === \"text\" ? textToHtml(value) : value}\n format={resolved.format === \"markdown\" ? \"markdown\" : \"html\"}\n />\n </div>\n </FauxClient>\n </div>\n );\n }\n\n // Office files are binary: never text. Until a viewer for the format is wired\n // in, they get MediaViewer's \"no preview\" card with a download.\n if (resolved.kind === \"office\") {\n return (\n <div\n data-fancy-file-viewer=\"\"\n data-kind=\"office\"\n data-office-kind={resolved.officeKind}\n className={cn(\"overflow-hidden\", className)}\n style={style}\n >\n <OfficeFile\n kind={resolved.officeKind}\n document={document}\n src={src}\n mime={mime}\n filename={filename}\n frameProps={frameProps}\n />\n </div>\n );\n }\n\n if (resolved.kind === \"media\") {\n // Image / video / PDF fill the sized wrapper so a height set on FileViewer\n // reaches the viewer; audio is a fixed-height card and shouldn't stretch.\n const { className: mediaClassName, ...restMediaProps } = mediaProps ?? {};\n // Images and PDFs carry the FauxClient frame every file viewer does; a\n // caller can still pass `frame: false` through `mediaProps`.\n restMediaProps.imageProps = { frame: true, frameProps, ...restMediaProps.imageProps };\n restMediaProps.pdfProps = { frame: true, frameProps, ...restMediaProps.pdfProps };\n const fill = resolved.mediaKind !== \"audio\";\n return (\n <div\n data-fancy-file-viewer=\"\"\n data-kind=\"media\"\n data-media-kind={resolved.mediaKind}\n className={cn(\"overflow-hidden\", className)}\n style={style}\n >\n <MediaViewer\n src={src ?? \"\"}\n mime={mime}\n alt={filename}\n kind={resolved.mediaKind}\n className={cn(fill && \"h-full w-full\", mediaClassName)}\n {...restMediaProps}\n />\n </div>\n );\n }\n\n return (\n <div\n data-fancy-file-viewer=\"\"\n data-kind=\"text\"\n className={className}\n style={style}\n >\n <CodeEditor\n value={value}\n onChange={readOnly ? undefined : onChange}\n language={resolved.language}\n theme={theme}\n readOnly={readOnly}\n lineNumbers={lineNumbers}\n wordWrap={wordWrap}\n minHeight={minHeight}\n maxHeight={maxHeight}\n // CodeEditor already reveals `cursorLine` on mount and on change; this\n // component never passed one through, so a viewer could not land anywhere.\n cursorLine={line}\n cursorColumn={column}\n highlightLines={highlightLines ?? (line != null ? [line] : undefined)}\n >\n <CodeEditor.Panel />\n </CodeEditor>\n </div>\n );\n}\n\nFileViewer.displayName = \"FileViewer\";\n\ntype OfficeState =\n | { status: \"idle\" }\n | { status: \"reading\" }\n | { status: \"read\"; document: unknown }\n | { status: \"failed\"; message: string };\n\n/**\n * An Office file in the viewer the app registered for its format.\n *\n * Where the contents come from, in order (owner, 2026-10-19: \"both, server\n * preferred\"): the `document` the app's server already read; else the file at\n * `src`, read in the browser by the reader the app registered; else the\n * download card. A file our reader cannot open says so, beside the download,\n * rather than showing an empty viewer.\n */\nfunction OfficeFile({\n kind,\n document,\n src,\n mime,\n filename,\n frameProps,\n}: {\n kind: OfficeKind;\n document: unknown;\n src?: string;\n mime?: string;\n filename?: string;\n frameProps?: FileViewerProps[\"frameProps\"];\n}) {\n const registration = officeViewerFor(kind);\n const read = registration?.read;\n const [state, setState] = useState<OfficeState>({ status: \"idle\" });\n\n useEffect(() => {\n if (!registration || document !== undefined || !src || !read) return;\n let live = true;\n setState({ status: \"reading\" });\n fetch(src)\n .then(async (response) => {\n if (!response.ok) throw new Error(`The file could not be fetched (${response.status}).`);\n const bytes = new Uint8Array(await response.arrayBuffer());\n const doc = read(bytes);\n if (live) setState({ status: \"read\", document: doc });\n })\n .catch((error: unknown) => {\n if (live) setState({ status: \"failed\", message: error instanceof Error ? error.message : String(error) });\n });\n\n return () => {\n live = false;\n };\n }, [registration, document, src, read]);\n\n const fallback = <MediaViewer src={src ?? \"\"} mime={mime} alt={filename} className=\"h-full w-full\" />;\n\n if (!registration) return fallback;\n\n const View = registration.View;\n if (document !== undefined) return <View document={document} filename={filename} frameProps={frameProps} />;\n if (state.status === \"read\") return <View document={state.document} filename={filename} frameProps={frameProps} />;\n if (state.status === \"reading\") {\n return <div className=\"flex h-full items-center justify-center p-6 text-sm text-zinc-500\">Opening {filename ?? \"the file\"}…</div>;\n }\n if (state.status === \"failed\") {\n return (\n <div className=\"flex h-full flex-col gap-2 p-2\">\n <Callout color=\"red\">\n {filename ?? \"This file\"} could not be opened: {state.message}\n </Callout>\n {fallback}\n </div>\n );\n }\n\n return fallback;\n}\n\nconst ESCAPES: Record<string, string> = { \"&\": \"&\", \"<\": \"<\", \">\": \">\", '\"': \""\", \"'\": \"'\" };\n\n/**\n * Plain text as HTML a reader would expect: a blank line is a new paragraph, a\n * single newline a line break, and every character escaped -- `*x*` in a text\n * file is asterisks, not emphasis, so it is not given to the Markdown renderer.\n */\nfunction textToHtml(text: string): string {\n return text\n .replace(/\\r\\n?/g, \"\\n\")\n .split(/\\n{2,}/)\n .filter((block) => block.trim() !== \"\")\n .map((block) => `<p>${block.replace(/[&<>\"']/g, (c) => ESCAPES[c]).replace(/\\n/g, \"<br>\")}</p>`)\n .join(\"\");\n}\n","/**\n * Tiny, dependency-free Markdown → HTML renderer for the MarkdownEditor preview\n * pane. Covers the common subset — headings, bold/italic, inline + fenced code,\n * links, images, blockquotes, ordered/unordered lists, hr, and paragraphs. Input\n * is HTML-escaped first, so raw HTML in the source is shown as text (safe by\n * default). Not a full CommonMark implementation; swap in a real renderer\n * downstream if you need one.\n */\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\");\n}\n\n/**\n * Escape a value for use inside a double-quoted HTML attribute. Adds quote\n * escaping on top of `escapeHtml`'s `&<>` so the value can't break out of the\n * attribute. Apply to text that has already been `escapeHtml`-ed.\n */\nfunction escapeAttr(s: string): string {\n return s.replace(/\"/g, \""\").replace(/'/g, \"'\");\n}\n\n/** Schemes a link may use. Anything else with a scheme renders as plain text. */\nconst LINK_SCHEMES = new Set([\"http\", \"https\", \"mailto\", \"tel\"]);\n\n/**\n * The scheme a browser would see in this URL, or null for a relative URL.\n *\n * Normalised the way the URL parser does it: leading C0 controls and spaces are\n * stripped and tab / CR / LF are removed anywhere, so `\" javascript:\"` and a\n * scheme split by a tab are both caught. Case-insensitive.\n */\nfunction schemeOf(url: string): string | null {\n let s = \"\";\n for (const ch of url) {\n const code = ch.codePointAt(0) ?? 0;\n if (code === 9 || code === 10 || code === 13) continue;\n if (s === \"\" && code <= 32) continue;\n s += ch;\n }\n const m = /^([a-zA-Z][a-zA-Z0-9+.-]*):/.exec(s);\n return m ? m[1].toLowerCase() : null;\n}\n\n/**\n * Is this URL safe in a preview inserted with innerHTML?\n *\n * The preview bypasses React, so React's `javascript:` guard never sees it. A\n * relative URL is always fine; an absolute one must use an allowed scheme, and\n * an image may additionally be a raster `data:image/...`. The input has already\n * been HTML-escaped, which neutralises entity-encoded schemes on its own.\n */\nfunction safeUrl(url: string, kind: \"link\" | \"image\"): boolean {\n const scheme = schemeOf(url);\n if (scheme === null) return true;\n if (scheme === \"http\" || scheme === \"https\") return true;\n if (kind === \"link\") return LINK_SCHEMES.has(scheme);\n return scheme === \"data\" && /^data:image\\/(png|jpe?g|gif|webp|avif|bmp);/i.test(url.trim());\n}\n\n/** Inline spans — run on already-escaped text. */\nfunction inline(text: string): string {\n return text\n // images  -- an unsafe src keeps only its alt text\n .replace(/!\\[([^\\]]*)\\]\\(([^)\\s]+)(?:\\s+\"([^\"]*)\")?\\)/g, (_m, alt, src, title) =>\n safeUrl(src, \"image\")\n ? `<img src=\"${escapeAttr(src)}\" alt=\"${escapeAttr(alt)}\"${title ? ` title=\"${escapeAttr(title)}\"` : \"\"}>`\n : alt)\n // links [text](href) -- an unsafe href keeps only its text\n .replace(/\\[([^\\]]+)\\]\\(([^)\\s]+)(?:\\s+\"([^\"]*)\")?\\)/g, (_m, t, href, title) =>\n safeUrl(href, \"link\")\n ? `<a href=\"${escapeAttr(href)}\"${title ? ` title=\"${escapeAttr(title)}\"` : \"\"} rel=\"noopener\">${t}</a>`\n : t)\n // inline code `code`\n .replace(/`([^`]+)`/g, (_m, c) => `<code>${c}</code>`)\n // bold **x** / __x__\n .replace(/(\\*\\*|__)(?=\\S)([\\s\\S]*?\\S)\\1/g, \"<strong>$2</strong>\")\n // italic *x* / _x_\n .replace(/(\\*|_)(?=\\S)([\\s\\S]*?\\S)\\1/g, \"<em>$2</em>\");\n}\n\nexport function renderMarkdown(markdown: string): string {\n const lines = markdown.replace(/\\r\\n?/g, \"\\n\").split(\"\\n\");\n const out: string[] = [];\n\n let i = 0;\n let para: string[] = [];\n let listType: \"ul\" | \"ol\" | null = null;\n\n const flushPara = () => {\n if (para.length) {\n out.push(`<p>${inline(para.join(\" \"))}</p>`);\n para = [];\n }\n };\n const closeList = () => {\n if (listType) {\n out.push(`</${listType}>`);\n listType = null;\n }\n };\n\n while (i < lines.length) {\n const line = lines[i];\n\n // Fenced code block\n const fence = line.match(/^\\s*(```|~~~)(.*)$/);\n if (fence) {\n flushPara();\n closeList();\n const lang = fence[2].trim();\n const body: string[] = [];\n i++;\n while (i < lines.length && !/^\\s*(```|~~~)/.test(lines[i])) {\n body.push(lines[i]);\n i++;\n }\n i++; // consume closing fence\n out.push(`<pre><code${lang ? ` class=\"language-${escapeAttr(escapeHtml(lang))}\"` : \"\"}>${escapeHtml(body.join(\"\\n\"))}</code></pre>`);\n continue;\n }\n\n const esc = escapeHtml(line);\n\n // Blank line — paragraph/list break\n if (/^\\s*$/.test(line)) {\n flushPara();\n closeList();\n i++;\n continue;\n }\n\n // Heading\n const heading = esc.match(/^(#{1,6})\\s+(.*)$/);\n if (heading) {\n flushPara();\n closeList();\n const level = heading[1].length;\n out.push(`<h${level}>${inline(heading[2])}</h${level}>`);\n i++;\n continue;\n }\n\n // Horizontal rule\n if (/^\\s*([-*_])(\\s*\\1){2,}\\s*$/.test(line)) {\n flushPara();\n closeList();\n out.push(\"<hr>\");\n i++;\n continue;\n }\n\n // Blockquote (single-level)\n const quote = esc.match(/^\\s*>\\s?(.*)$/);\n if (quote) {\n flushPara();\n closeList();\n out.push(`<blockquote>${inline(quote[1])}</blockquote>`);\n i++;\n continue;\n }\n\n // List item\n const ol = esc.match(/^\\s*\\d+\\.\\s+(.*)$/);\n const ul = esc.match(/^\\s*[-*+]\\s+(.*)$/);\n if (ol || ul) {\n flushPara();\n const type: \"ul\" | \"ol\" = ol ? \"ol\" : \"ul\";\n if (listType !== type) {\n closeList();\n out.push(`<${type}>`);\n listType = type;\n }\n out.push(`<li>${inline((ol ?? ul)![1])}</li>`);\n i++;\n continue;\n }\n\n // Plain paragraph text (accumulate)\n closeList();\n para.push(esc);\n i++;\n }\n\n flushPara();\n closeList();\n return out.join(\"\\n\");\n}\n","import { useMemo } from \"react\";\nimport {\n InputTag,\n textareaAdapter,\n type InputTagAdapter,\n type InputTagProps,\n type InputTagTriggers,\n} from \"@particle-academy/react-fancy\";\nimport { useCodeEditor } from \"./components/CodeEditor/CodeEditor.context\";\n\n/**\n * Glue between `@particle-academy/react-fancy`'s `<InputTag>` and the\n * `<CodeEditor>` from this package. `<CodeEditor>` renders a real DOM\n * `<textarea>` under its overlay, so the existing `textareaAdapter`\n * just works — this module hands it the right ref via the editor\n * context.\n *\n * <CodeEditor value={code} onChange={setCode} language=\"markdown\">\n * <CodeEditor.Toolbar />\n * <CodeEditor.Panel />\n * <CodeEditorInputTag\n * triggers={{\n * \"/\": { items: commands, insert: (c) => `${c.name} ` },\n * \"@\": { items: mentions, insert: (m) => `@${m.name} ` },\n * }}\n * />\n * </CodeEditor>\n *\n * Must be rendered as a descendant of `<CodeEditor>` (it reads the\n * editor's context). For ad-hoc wiring outside the component tree,\n * pull the textarea ref off the context and call `textareaAdapter`\n * yourself.\n */\n\n/**\n * Hook form — returns an `InputTagAdapter` bound to the surrounding\n * `<CodeEditor>`. Useful when you want to compose your own picker UI\n * around the same adapter.\n */\nexport function useCodeEditorInputTagAdapter(): InputTagAdapter {\n const ctx = useCodeEditor();\n return useMemo(() => textareaAdapter(ctx.textareaRef), [ctx.textareaRef]);\n}\n\nexport interface CodeEditorInputTagProps extends Omit<InputTagProps, \"adapter\"> {\n triggers: InputTagTriggers;\n}\n\n/**\n * Convenience wrapper — renders `<InputTag>` already wired to the\n * surrounding `<CodeEditor>`'s textarea. Equivalent to:\n *\n * const adapter = useCodeEditorInputTagAdapter();\n * return <InputTag adapter={adapter} {...rest} />;\n */\nexport function CodeEditorInputTag(props: CodeEditorInputTagProps) {\n const adapter = useCodeEditorInputTagAdapter();\n return <InputTag adapter={adapter} {...props} />;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/CodeEditor/CodeEditor.context.ts","../src/components/CodeEditor/diff-gutter.ts","../src/components/CodeEditor/CodeEditorPanel.tsx","../src/components/CodeEditor/CodeEditorToolbarSeparator.tsx","../src/languages/registry.ts","../src/languages/builtin.ts","../src/components/CodeEditor/CodeEditorToolbar.tsx","../src/components/CodeEditor/CodeEditorStatusBar.tsx","../src/themes/registry.ts","../src/themes/light.ts","../src/themes/dark.ts","../src/engine/position.ts","../src/hooks/use-editor-engine.ts","../src/hooks/use-dark-mode.ts","../src/components/CodeEditor/CodeEditor.tsx","../src/components/MarkdownEditor/MarkdownEditor.tsx","../src/office-viewers.ts","../src/file-type.ts","../src/components/FileViewer/FileViewer.tsx","../src/engine/markdown-render.ts","../src/input-tag.tsx"],"names":["themeColors","lineCount","activeLine","jsx","jsxs","cn","Fragment","useState","useMemo","useCallback","useRef","useEffect","useControllableState","ContentRenderer"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { CodeEditorContextValue } from \"./CodeEditor.types\";\n\nexport const CodeEditorContext = createContext<CodeEditorContextValue | null>(null);\n\nexport function useCodeEditor(): CodeEditorContextValue {\n const ctx = useContext(CodeEditorContext);\n if (!ctx) {\n throw new Error(\"useCodeEditor must be used within a <CodeEditor> component\");\n }\n return ctx;\n}\n","/**\n * Diff-gutter model — the pure mapping between fancy-file-commons line\n * annotations and what the CodeEditor gutter renders per line-number row.\n * Kept DOM-free (like engine/position.ts) so it's unit-testable; the panel\n * only paints what this resolves.\n */\nimport type { DiffAnnotations, LineChangeType } from \"@particle-academy/fancy-file-commons\";\nimport type { ThemeColors } from \"../../themes/types\";\n\n/** What one line-number row shows: its own change bar and/or a deletion wedge above. */\nexport interface GutterDiffMark {\n /** The line's own change (colored bar), if any. */\n type?: LineChangeType;\n /** True when one or more lines were deleted immediately above this line (wedge). */\n deletedAbove: boolean;\n}\n\n/** Resolve the mark for a 1-based line, or null when the line is untouched. */\nexport function gutterDiffMark(\n annotations: DiffAnnotations | null,\n line: number,\n): GutterDiffMark | null {\n if (!annotations) return null;\n const a = annotations.byLine[line];\n if (!a) return null;\n return { type: a.type, deletedAbove: (a.deletedAbove ?? 0) > 0 };\n}\n\n/** Whether the deleted-at-EOF wedge should render under the last line. */\nexport function hasDeletedAtEnd(annotations: DiffAnnotations | null): boolean {\n return (annotations?.deletedAtEnd ?? 0) > 0;\n}\n\n/** VS Code-convention fallbacks for themes that don't define diff colors. */\nconst FALLBACK = { added: \"#3fb950\", modified: \"#4184e4\", removed: \"#f85149\" } as const;\n\n/** The bar color for a change type, honoring theme overrides. */\nexport function diffMarkColor(type: LineChangeType, colors: ThemeColors): string {\n return type === \"added\"\n ? (colors.diffAdded ?? FALLBACK.added)\n : (colors.diffModified ?? FALLBACK.modified);\n}\n\n/** The deletion-wedge color, honoring theme overrides. */\nexport function diffRemovedColor(colors: ThemeColors): string {\n return colors.diffRemoved ?? FALLBACK.removed;\n}\n","import { useMemo } from \"react\";\nimport { cn } from \"@particle-academy/react-fancy\";\nimport { useCodeEditor } from \"./CodeEditor.context\";\nimport {\n diffMarkColor,\n diffRemovedColor,\n gutterDiffMark,\n hasDeletedAtEnd,\n} from \"./diff-gutter\";\nimport type { CodeEditorPanelProps } from \"./CodeEditor.types\";\n\nexport function CodeEditorPanel({ className }: CodeEditorPanelProps) {\n const {\n _engineReturn: engine,\n lineNumbers,\n wordWrap,\n readOnly,\n placeholder,\n _diffAnnotations: diffAnnotations,\n _maxHeight,\n _minHeight,\n _highlightLines: highlightLines,\n _aria: aria,\n } = useCodeEditor();\n\n // This `useMemo` MUST run before the `!engine` guard below it.\n //\n // The guard used to come first, so a render without an engine ran ZERO hooks\n // and the next one ran one. React compares hook counts between renders, so\n // that transition desyncs the hook order and throws from deep inside React,\n // naming none of this code. `_engineReturn` is typed `| null` and starts null,\n // so the transition is real rather than theoretical.\n //\n // Reading the engine's fields inside the callback (rather than destructuring\n // above) is what lets the hook run unconditionally.\n const lineNumberElements = useMemo(() => {\n if (!engine || !lineNumbers) return null;\n const { themeColors, lineCount, activeLine } = engine;\n const removed = diffRemovedColor(themeColors);\n const highlighted = new Set(highlightLines ?? []);\n const lines = [];\n for (let i = 1; i <= lineCount; i++) {\n const mark = gutterDiffMark(diffAnnotations, i);\n lines.push(\n <div\n key={i}\n data-diff={mark?.type}\n data-diff-deleted-above={mark?.deletedAbove ? \"\" : undefined}\n style={{\n position: \"relative\",\n color: i === activeLine || highlighted.has(i) ? themeColors.foreground : themeColors.gutterForeground,\n backgroundColor: i === activeLine ? themeColors.activeLineBackground : undefined,\n fontWeight: highlighted.has(i) ? 600 : undefined,\n }}\n className=\"pr-3 text-right text-[13px] leading-[1.5] select-none\"\n >\n {/* Change bar — VS Code convention: green added, blue modified. */}\n {mark?.type && (\n <span\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n bottom: 0,\n width: 3,\n borderRadius: 2,\n backgroundColor: diffMarkColor(mark.type, themeColors),\n }}\n />\n )}\n {/* Deletion wedge — lines were removed immediately above this one. */}\n {mark?.deletedAbove && (\n <span\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n left: 0,\n top: -4,\n width: 0,\n height: 0,\n borderLeft: `8px solid ${removed}`,\n borderTop: \"4px solid transparent\",\n borderBottom: \"4px solid transparent\",\n }}\n />\n )}\n {i}\n {/* Deletion at EOF — removed lines hang below the last line. */}\n {i === lineCount && hasDeletedAtEnd(diffAnnotations) && (\n <span\n aria-hidden=\"true\"\n data-diff-deleted-at-end=\"\"\n style={{\n position: \"absolute\",\n left: 0,\n bottom: -4,\n width: 0,\n height: 0,\n borderLeft: `8px solid ${removed}`,\n borderTop: \"4px solid transparent\",\n borderBottom: \"4px solid transparent\",\n }}\n />\n )}\n </div>,\n );\n }\n return lines;\n }, [engine, lineNumbers, diffAnnotations, highlightLines]);\n\n // Every hook is above this line.\n if (!engine) return null;\n\n const {\n textareaRef,\n highlightedHtml,\n lineCount,\n activeLine,\n themeColors,\n handleKeyDown,\n handleInput,\n handleBlur,\n handleScroll,\n handleSelect,\n scrollTop,\n scrollLeft,\n } = engine;\n\n const gutterWidth = lineNumbers ? `${Math.max(String(lineCount).length, 2) * 0.75 + 1.5}em` : \"0\";\n\n const containerStyle: React.CSSProperties = {\n backgroundColor: themeColors.background,\n color: themeColors.foreground,\n minHeight: _minHeight,\n maxHeight: _maxHeight,\n };\n\n const isEmpty = textareaRef.current ? textareaRef.current.value.length === 0 : highlightedHtml.length === 0;\n\n return (\n <div\n data-fancy-code-panel=\"\"\n className={cn(\"relative overflow-auto\", className)}\n style={containerStyle}\n >\n <div className=\"flex min-h-full\">\n {/* Line numbers gutter */}\n {lineNumbers && (\n <div\n className=\"sticky left-0 z-10 shrink-0 pt-2.5 pb-2.5 pl-2\"\n style={{\n backgroundColor: themeColors.gutterBackground,\n borderRight: `1px solid ${themeColors.gutterBorder}`,\n width: gutterWidth,\n }}\n >\n {lineNumberElements}\n </div>\n )}\n\n {/* Editor area */}\n <div className={cn(\"relative flex-1\", wordWrap && \"min-w-0\")}>\n {/*\n Line bands — \"here is the line you were sent to\". Behind the code, and\n placed in em so they track the 13px / 1.5 line grid the gutter uses;\n 0.625rem is the editor's top padding (p-2.5).\n */}\n {(highlightLines ?? [])\n .filter((n) => Number.isInteger(n) && n >= 1 && n <= lineCount)\n .map((n) => (\n <div\n key={`highlight-${n}`}\n data-fancy-code-highlight-line={n}\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-x-0 text-[13px] leading-[1.5]\"\n style={{\n top: `calc(0.625rem + ${(n - 1) * 1.5}em)`,\n height: \"1.5em\",\n backgroundColor: themeColors.selectionBackground,\n opacity: 0.55,\n }}\n />\n ))}\n\n {/* Highlighted code overlay */}\n <pre\n className=\"pointer-events-none absolute inset-0 m-0 overflow-hidden border-none p-2.5 text-[13px] leading-[1.5]\"\n aria-hidden=\"true\"\n style={{\n whiteSpace: wordWrap ? \"pre-wrap\" : \"pre\",\n overflowWrap: wordWrap ? \"break-word\" : \"normal\",\n }}\n >\n <code dangerouslySetInnerHTML={{ __html: highlightedHtml + \"\\n\" }} />\n </pre>\n\n {/* Placeholder */}\n {placeholder && isEmpty && (\n <div\n className=\"pointer-events-none absolute left-0 top-0 p-2.5 text-[13px] leading-[1.5] opacity-40\"\n style={{ color: themeColors.foreground }}\n >\n {placeholder}\n </div>\n )}\n\n {/* Actual textarea for input */}\n <textarea\n ref={textareaRef}\n // The name lands HERE, on the element a person types into.\n aria-label={aria?.[\"aria-label\"]}\n aria-labelledby={aria?.[\"aria-labelledby\"]}\n aria-describedby={aria?.[\"aria-describedby\"]}\n // The focus ring sits on the textarea itself: it is the element that\n // holds focus, and a ring on a wrapper is invisible to a checker\n // (and to anyone who reads focus from the focused element).\n className={cn(\n \"relative m-0 block resize-none border-none bg-transparent p-2.5 text-[13px] leading-[1.5] text-transparent\",\n \"focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[color:var(--fancy-focus,var(--color-blue-500))] dark:focus-visible:ring-[color:var(--fancy-focus-dark,var(--color-blue-400))]\",\n wordWrap ? \"w-full\" : \"min-w-full\",\n )}\n style={{\n caretColor: themeColors.cursorColor,\n minHeight: _minHeight ? _minHeight - 40 : 80,\n overflow: \"hidden\",\n whiteSpace: wordWrap ? \"pre-wrap\" : \"pre\",\n overflowWrap: wordWrap ? \"break-word\" : \"normal\",\n }}\n spellCheck={false}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n autoCapitalize=\"off\"\n readOnly={readOnly}\n onKeyDown={handleKeyDown}\n onInput={handleInput}\n onBlur={handleBlur}\n onScroll={handleScroll}\n onSelect={handleSelect}\n onClick={handleSelect}\n />\n </div>\n </div>\n </div>\n );\n}\n\nCodeEditorPanel.displayName = \"CodeEditorPanel\";\n","export function CodeEditorToolbarSeparator() {\n return (\n <div\n data-fancy-code-toolbar-separator=\"\"\n className=\"mx-1 h-4 w-px bg-zinc-200 dark:bg-zinc-700\"\n />\n );\n}\n\nCodeEditorToolbarSeparator.displayName = \"CodeEditorToolbarSeparator\";\n","import type { LanguageDefinition } from \"./types\";\n\nconst languageRegistry = new Map<string, LanguageDefinition>();\n\nexport function registerLanguage(def: LanguageDefinition): void {\n languageRegistry.set(def.name.toLowerCase(), def);\n if (def.aliases) {\n for (const alias of def.aliases) {\n languageRegistry.set(alias.toLowerCase(), def);\n }\n }\n}\n\nexport function getLanguage(name: string): LanguageDefinition | undefined {\n return languageRegistry.get(name.toLowerCase());\n}\n\nexport function getRegisteredLanguages(): string[] {\n const seen = new Set<LanguageDefinition>();\n const names: string[] = [];\n for (const [, def] of languageRegistry) {\n if (!seen.has(def)) {\n seen.add(def);\n names.push(def.name);\n }\n }\n return names;\n}\n","import { registerLanguage } from \"./registry\";\n// Every grammar lives in @particle-academy/fancy-file-commons, shared with\n// react-fancy's CodeBlock / CodeView; fancy-code only registers them.\nimport {\n tokenizeJavaScript,\n tokenizeHtml,\n tokenizePhp,\n tokenizePython,\n tokenizeGo,\n tokenizeMarkdown,\n tokenizeShell,\n tokenizeDotenv,\n} from \"@particle-academy/fancy-file-commons\";\n\nregisterLanguage({\n name: \"Markdown\",\n aliases: [\"md\", \"markdown\", \"mkd\"],\n tokenize: tokenizeMarkdown,\n});\n\nregisterLanguage({\n name: \"JavaScript\",\n aliases: [\"js\", \"javascript\", \"jsx\"],\n tokenize: tokenizeJavaScript,\n});\n\nregisterLanguage({\n name: \"TypeScript\",\n aliases: [\"ts\", \"typescript\", \"tsx\"],\n tokenize: tokenizeJavaScript, // Same tokenizer — JS/TS syntax is identical for highlighting\n});\n\nregisterLanguage({\n name: \"HTML\",\n aliases: [\"html\", \"htm\"],\n tokenize: tokenizeHtml,\n});\n\nregisterLanguage({\n name: \"PHP\",\n aliases: [\"php\"],\n tokenize: tokenizePhp,\n});\n\nregisterLanguage({\n name: \"Python\",\n aliases: [\"py\", \"python\"],\n tokenize: tokenizePython,\n});\n\nregisterLanguage({\n name: \"Go\",\n aliases: [\"go\", \"golang\"],\n tokenize: tokenizeGo,\n});\n\nregisterLanguage({\n name: \"Shell\",\n aliases: [\"sh\", \"bash\", \"zsh\", \"shell\"],\n tokenize: tokenizeShell,\n});\n\nregisterLanguage({\n name: \"Dotenv\",\n aliases: [\"env\", \"dotenv\"],\n tokenize: tokenizeDotenv,\n});\n","import { useState } from \"react\";\nimport { cn } from \"@particle-academy/react-fancy\";\nimport { useCodeEditor } from \"./CodeEditor.context\";\nimport { CodeEditorToolbarSeparator } from \"./CodeEditorToolbarSeparator\";\nimport { getRegisteredLanguages } from \"../../languages\";\nimport type { CodeEditorToolbarProps } from \"./CodeEditor.types\";\n\nconst iconBtnClass =\n \"inline-flex items-center justify-center rounded-md p-1 text-zinc-500 transition-colors hover:bg-zinc-100 hover:text-zinc-700 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-zinc-200\";\n\nfunction LanguageSelector() {\n const { language, setLanguage } = useCodeEditor();\n const languages = getRegisteredLanguages();\n\n return (\n <select\n value={language}\n onChange={(e) => setLanguage(e.target.value)}\n className=\"h-6 rounded border border-zinc-200 bg-transparent px-1.5 text-[11px] text-zinc-600 outline-none transition-colors hover:border-zinc-300 dark:border-zinc-700 dark:text-zinc-400 dark:hover:border-zinc-600\"\n >\n {languages.map((lang) => (\n <option key={lang} value={lang}>\n {lang}\n </option>\n ))}\n </select>\n );\n}\n\nfunction DefaultToolbarActions() {\n const { copyToClipboard, toggleWordWrap, wordWrap } = useCodeEditor();\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n await copyToClipboard();\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n };\n\n return (\n <>\n <LanguageSelector />\n <CodeEditorToolbarSeparator />\n <button\n type=\"button\"\n onClick={toggleWordWrap}\n title={wordWrap ? \"Disable Word Wrap\" : \"Enable Word Wrap\"}\n className={cn(iconBtnClass, wordWrap && \"text-blue-500 dark:text-blue-400\")}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <path d=\"M3 12h15a3 3 0 110 6h-4\" />\n <polyline points=\"16 16 14 18 16 20\" />\n <line x1=\"3\" y1=\"18\" x2=\"10\" y2=\"18\" />\n </svg>\n </button>\n <button type=\"button\" onClick={handleCopy} title=\"Copy to Clipboard\" className={iconBtnClass}>\n {copied ? (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n ) : (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1\" />\n </svg>\n )}\n </button>\n </>\n );\n}\n\nexport function CodeEditorToolbar({ children, className }: CodeEditorToolbarProps) {\n const hasChildren = children != null;\n\n return (\n <div\n data-fancy-code-toolbar=\"\"\n className={cn(\n \"flex items-center gap-0.5 border-b border-zinc-200 px-2 py-1 dark:border-zinc-700\",\n className,\n )}\n >\n {hasChildren ? children : <DefaultToolbarActions />}\n </div>\n );\n}\n\nCodeEditorToolbar.displayName = \"CodeEditorToolbar\";\n","import { cn } from \"@particle-academy/react-fancy\";\nimport { useCodeEditor } from \"./CodeEditor.context\";\nimport type { CodeEditorStatusBarProps } from \"./CodeEditor.types\";\n\nexport function CodeEditorStatusBar({ children, className }: CodeEditorStatusBarProps) {\n const { cursorPosition, selectionLength, language, tabSize } = useCodeEditor();\n\n return (\n <div\n data-fancy-code-statusbar=\"\"\n className={cn(\n \"flex items-center gap-3 border-t border-zinc-200 px-3 py-1 text-[11px] text-zinc-500 dark:border-zinc-700 dark:text-zinc-400\",\n className,\n )}\n >\n {children ?? (\n <>\n <span>Ln {cursorPosition.line}, Col {cursorPosition.col}</span>\n {selectionLength > 0 && <span>{selectionLength} selected</span>}\n <span className=\"ml-auto\">{language}</span>\n <span>{tabSize} spaces</span>\n </>\n )}\n </div>\n );\n}\n\nCodeEditorStatusBar.displayName = \"CodeEditorStatusBar\";\n","import type { ThemeDefinition } from \"./types\";\n\nconst themeRegistry = new Map<string, ThemeDefinition>();\n\nexport function registerTheme(theme: ThemeDefinition): void {\n themeRegistry.set(theme.name.toLowerCase(), theme);\n}\n\nexport function getTheme(name: string): ThemeDefinition | undefined {\n return themeRegistry.get(name.toLowerCase());\n}\n\nexport function getRegisteredThemes(): string[] {\n return Array.from(themeRegistry.keys());\n}\n","import { LIGHT_COLORS } from \"@particle-academy/fancy-file-commons\";\nimport { registerTheme } from \"./registry\";\n\n// The palette lives in commons; fancy-code wraps it into a named, registrable\n// theme for its IDE's theme picker + `theme=\"auto\"` resolution.\nregisterTheme({\n name: \"light\",\n variant: \"light\",\n colors: LIGHT_COLORS,\n});\n","import { DARK_COLORS } from \"@particle-academy/fancy-file-commons\";\nimport { registerTheme } from \"./registry\";\n\n// The palette lives in commons; fancy-code wraps it into a named, registrable\n// theme for its IDE's theme picker + `theme=\"auto\"` resolution.\nregisterTheme({\n name: \"dark\",\n variant: \"dark\",\n colors: DARK_COLORS,\n});\n","/**\n * Convert a 1-based `line` / `column` into a 0-based character offset within\n * `text`. Out-of-range values clamp to the document and line bounds, so the\n * result is always a valid offset in `[0, text.length]`.\n *\n * - `line` below 1 clamps to line 1; above the last line clamps to the last line.\n * - `column` below 1 clamps to column 1; past the end of the line clamps to just\n * after the last character (so you can place the caret at the line end).\n */\nexport function lineColumnToOffset(text: string, line: number, column = 1): number {\n const lines = text.split(\"\\n\");\n const targetLine = Math.max(1, Math.min(Math.trunc(line) || 1, lines.length));\n\n let offset = 0;\n for (let i = 0; i < targetLine - 1; i++) {\n offset += lines[i].length + 1; // +1 for the consumed \"\\n\"\n }\n\n const lineText = lines[targetLine - 1] ?? \"\";\n const col = Math.max(1, Math.min(Math.trunc(column) || 1, lineText.length + 1));\n return offset + (col - 1);\n}\n","import { useEffect, useRef, useCallback, useState, useMemo, type RefObject } from \"react\";\nimport { getLanguage } from \"../languages\";\nimport { getTheme } from \"../themes\";\nimport { highlightCode } from \"../engine/highlight\";\nimport { lineColumnToOffset } from \"../engine/position\";\nimport type { ThemeColors } from \"../themes/types\";\nimport type { Tokenizer } from \"../engine/tokenizer\";\n\nexport interface UseEditorEngineOptions {\n containerRef: RefObject<HTMLDivElement | null>;\n value: string;\n onChange?: (value: string) => void;\n language: string;\n theme: string;\n readOnly: boolean;\n lineNumbers: boolean;\n wordWrap: boolean;\n tabSize: number;\n placeholder?: string;\n minHeight?: number;\n maxHeight?: number;\n onCursorChange?: (pos: { line: number; col: number; selectionLength: number }) => void;\n}\n\nexport interface UseEditorEngineReturn {\n textareaRef: RefObject<HTMLTextAreaElement | null>;\n highlightedHtml: string;\n lineCount: number;\n activeLine: number;\n themeColors: ThemeColors;\n handleKeyDown: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;\n handleInput: () => void;\n /**\n * Ends the focus session: disarms Tab-indent so the next Tab into the editor\n * moves focus rather than indenting. Wire to the textarea's `onBlur`.\n */\n handleBlur: () => void;\n handleScroll: () => void;\n handleSelect: () => void;\n /**\n * Place the caret on a 1-based `line` / `column` and scroll the editor so the\n * line is centered in view. Out-of-range positions clamp to document bounds.\n */\n revealLine: (line: number, column?: number, opts?: { focus?: boolean }) => void;\n scrollTop: number;\n scrollLeft: number;\n}\n\nconst DEFAULT_COLORS: ThemeColors = {\n background: \"#18181b\",\n foreground: \"#e4e4e7\",\n gutterBackground: \"#18181b\",\n gutterForeground: \"#52525b\",\n gutterBorder: \"#27272a\",\n activeLineBackground: \"#27272a\",\n selectionBackground: \"#1e3a5f\",\n cursorColor: \"#60a5fa\",\n keyword: \"#c084fc\",\n string: \"#34d399\",\n comment: \"#71717a\",\n number: \"#fbbf24\",\n operator: \"#22d3ee\",\n function: \"#60a5fa\",\n type: \"#fbbf24\",\n tag: \"#f87171\",\n attribute: \"#fbbf24\",\n attributeValue: \"#34d399\",\n punctuation: \"#a1a1aa\",\n variable: \"#e4e4e7\",\n};\n\nexport function useEditorEngine({\n value,\n onChange,\n language,\n theme,\n readOnly,\n wordWrap,\n tabSize,\n onCursorChange,\n}: UseEditorEngineOptions): UseEditorEngineReturn {\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const onChangeRef = useRef(onChange);\n const onCursorChangeRef = useRef(onCursorChange);\n onChangeRef.current = onChange;\n onCursorChangeRef.current = onCursorChange;\n\n const [scrollTop, setScrollTop] = useState(0);\n const [scrollLeft, setScrollLeft] = useState(0);\n const [activeLine, setActiveLine] = useState(1);\n\n // \"Armed\" Tab (WCAG 2.1.2, no keyboard trap): Tab / Shift+Tab indent and\n // dedent only after the user has edited in the current focus session.\n // Escape and blur disarm. A ref, not state: it never affects rendering.\n const tabArmedRef = useRef(false);\n\n // Resolve theme colors\n const themeColors = useMemo<ThemeColors>(() => {\n const def = getTheme(theme);\n return def?.colors ?? DEFAULT_COLORS;\n }, [theme]);\n\n // Resolve tokenizer\n const tokenizer = useMemo<Tokenizer | null>(() => {\n const def = getLanguage(language);\n return def?.tokenize ?? null;\n }, [language]);\n\n // Generate highlighted HTML\n const highlightedHtml = useMemo(() => {\n if (!tokenizer) {\n // No tokenizer — just escape HTML\n return value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\");\n }\n const tokens = tokenizer(value);\n return highlightCode(value, tokens, themeColors);\n }, [value, tokenizer, themeColors]);\n\n const lineCount = useMemo(() => {\n let count = 1;\n for (let i = 0; i < value.length; i++) {\n if (value[i] === \"\\n\") count++;\n }\n return count;\n }, [value]);\n\n // Auto-resize textarea to match content so caret is always visible\n const autoResize = useCallback(() => {\n const ta = textareaRef.current;\n if (!ta) return;\n ta.style.height = \"auto\";\n ta.style.height = ta.scrollHeight + \"px\";\n\n if (!wordWrap) {\n // Shrink to 0 to measure true content width, then expand\n ta.style.width = \"0\";\n ta.style.width = ta.scrollWidth + \"px\";\n } else {\n ta.style.width = \"\";\n }\n }, [wordWrap]);\n\n // Sync textarea value and auto-resize when value changes\n useEffect(() => {\n const ta = textareaRef.current;\n if (!ta) return;\n if (ta.value !== value) {\n const { selectionStart, selectionEnd } = ta;\n ta.value = value;\n ta.selectionStart = selectionStart;\n ta.selectionEnd = selectionEnd;\n }\n // Always resize — handles initial mount and external value changes\n autoResize();\n }, [value, autoResize]);\n\n const updateCursorInfo = useCallback(() => {\n const ta = textareaRef.current;\n if (!ta) return;\n const pos = ta.selectionStart;\n const textBefore = ta.value.slice(0, pos);\n const line = (textBefore.match(/\\n/g) || []).length + 1;\n const lastNewline = textBefore.lastIndexOf(\"\\n\");\n const col = pos - lastNewline;\n const selLen = Math.abs(ta.selectionEnd - ta.selectionStart);\n setActiveLine(line);\n onCursorChangeRef.current?.({ line, col, selectionLength: selLen });\n }, []);\n\n const handleInput = useCallback(() => {\n const ta = textareaRef.current;\n if (!ta) return;\n // An edit (typing, paste, cut, drop, IME) arms Tab-indent for this focus\n // session.\n tabArmedRef.current = true;\n onChangeRef.current?.(ta.value);\n autoResize();\n updateCursorInfo();\n }, [autoResize, updateCursorInfo]);\n\n const handleSelect = useCallback(() => {\n updateCursorInfo();\n }, [updateCursorInfo]);\n\n const handleScroll = useCallback(() => {\n const ta = textareaRef.current;\n if (!ta) return;\n setScrollTop(ta.scrollTop);\n setScrollLeft(ta.scrollLeft);\n }, []);\n\n const revealLine = useCallback(\n (line: number, column = 1, opts?: { focus?: boolean }) => {\n const ta = textareaRef.current;\n if (!ta) return;\n\n const offset = lineColumnToOffset(ta.value, line, column);\n if (opts?.focus) ta.focus();\n ta.selectionStart = ta.selectionEnd = offset;\n updateCursorInfo();\n\n // Scroll the editor's scroll container (the panel) so the target line is\n // centered. The textarea is auto-sized to fit its content, so the panel —\n // not the textarea — is what scrolls.\n const panel = ta.closest<HTMLElement>(\"[data-fancy-code-panel]\");\n if (!panel) return;\n const cs = getComputedStyle(ta);\n const lineHeight = parseFloat(cs.lineHeight) || 19.5;\n const paddingTop = parseFloat(cs.paddingTop) || 0;\n const lineIndex = (ta.value.slice(0, offset).match(/\\n/g) || []).length; // clamped (targetLine - 1)\n const textareaTopInPanel =\n ta.getBoundingClientRect().top - panel.getBoundingClientRect().top + panel.scrollTop;\n const lineTop = textareaTopInPanel + paddingTop + lineIndex * lineHeight;\n const target = lineTop - panel.clientHeight / 2 + lineHeight / 2;\n const maxScroll = panel.scrollHeight - panel.clientHeight;\n panel.scrollTop = Math.max(0, Math.min(target, maxScroll));\n },\n [updateCursorInfo],\n );\n\n const handleBlur = useCallback(() => {\n // Leaving the editor ends the focus session: the next Tab in moves on.\n tabArmedRef.current = false;\n }, []);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (readOnly) {\n // The textarea's own `readOnly` attribute already refuses edits. Every\n // other key — Tab / Shift+Tab out, caret and navigation keys, copy —\n // must reach the browser, or focus can never leave (WCAG 2.1.2).\n return;\n }\n\n // Escape disarms Tab-indent, so the next Tab moves focus out.\n if (e.key === \"Escape\") {\n tabArmedRef.current = false;\n return;\n }\n\n // Tab only indents once the user has edited in this focus session.\n // Until then it moves focus like any other control (no keyboard trap).\n if (e.key === \"Tab\" && !tabArmedRef.current) return;\n\n // Tab key — insert spaces\n if (e.key === \"Tab\") {\n e.preventDefault();\n const ta = e.currentTarget;\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n const spaces = \" \".repeat(tabSize);\n\n if (e.shiftKey) {\n // Dedent: remove leading spaces from selected lines\n const lines = ta.value.split(\"\\n\");\n const startLine = ta.value.slice(0, start).split(\"\\n\").length - 1;\n const endLine = ta.value.slice(0, end).split(\"\\n\").length - 1;\n let removed = 0;\n for (let i = startLine; i <= endLine; i++) {\n const match = lines[i].match(new RegExp(`^ {1,${tabSize}}`));\n if (match) {\n removed += match[0].length;\n lines[i] = lines[i].slice(match[0].length);\n }\n }\n const newValue = lines.join(\"\\n\");\n ta.value = newValue;\n ta.selectionStart = Math.max(0, start - (startLine === endLine ? removed : tabSize));\n ta.selectionEnd = Math.max(0, end - removed);\n onChangeRef.current?.(newValue);\n } else if (start !== end) {\n // Indent selected lines\n const lines = ta.value.split(\"\\n\");\n const startLine = ta.value.slice(0, start).split(\"\\n\").length - 1;\n const endLine = ta.value.slice(0, end).split(\"\\n\").length - 1;\n for (let i = startLine; i <= endLine; i++) {\n lines[i] = spaces + lines[i];\n }\n const newValue = lines.join(\"\\n\");\n ta.value = newValue;\n ta.selectionStart = start + tabSize;\n ta.selectionEnd = end + (endLine - startLine + 1) * tabSize;\n onChangeRef.current?.(newValue);\n } else {\n // Insert tab at cursor\n const before = ta.value.slice(0, start);\n const after = ta.value.slice(end);\n ta.value = before + spaces + after;\n ta.selectionStart = ta.selectionEnd = start + tabSize;\n onChangeRef.current?.(ta.value);\n }\n autoResize();\n updateCursorInfo();\n return;\n }\n\n // Enter — auto-indent\n if (e.key === \"Enter\") {\n e.preventDefault();\n tabArmedRef.current = true;\n const ta = e.currentTarget;\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n const before = ta.value.slice(0, start);\n const after = ta.value.slice(end);\n const currentLine = before.split(\"\\n\").pop() || \"\";\n const indent = currentLine.match(/^(\\s*)/)?.[1] || \"\";\n\n // Extra indent after { or (\n const lastChar = before.trimEnd().slice(-1);\n const extraIndent = (lastChar === \"{\" || lastChar === \"(\") ? \" \".repeat(tabSize) : \"\";\n\n const insertion = \"\\n\" + indent + extraIndent;\n ta.value = before + insertion + after;\n ta.selectionStart = ta.selectionEnd = start + insertion.length;\n onChangeRef.current?.(ta.value);\n autoResize();\n updateCursorInfo();\n return;\n }\n },\n [readOnly, tabSize, autoResize, updateCursorInfo],\n );\n\n return {\n textareaRef,\n highlightedHtml,\n lineCount,\n activeLine,\n themeColors,\n handleKeyDown,\n handleInput,\n handleBlur,\n handleScroll,\n handleSelect,\n revealLine,\n scrollTop,\n scrollLeft,\n };\n}\n","import { useSyncExternalStore } from \"react\";\n\nfunction subscribe(callback: () => void): () => void {\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n mq.addEventListener(\"change\", callback);\n return () => mq.removeEventListener(\"change\", callback);\n}\n\nfunction getSnapshot(): boolean {\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n}\n\nfunction getServerSnapshot(): boolean {\n return false;\n}\n\nexport function useDarkMode(): boolean {\n return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n","import { useEffect, useMemo, useRef, useState, useCallback } from \"react\";\nimport { cn, useControllableState } from \"@particle-academy/react-fancy\";\nimport { annotateLines } from \"@particle-academy/fancy-file-commons\";\nimport { CodeEditorContext } from \"./CodeEditor.context\";\nimport { CodeEditorPanel } from \"./CodeEditorPanel\";\nimport { CodeEditorToolbar } from \"./CodeEditorToolbar\";\nimport { CodeEditorToolbarSeparator } from \"./CodeEditorToolbarSeparator\";\nimport { CodeEditorStatusBar } from \"./CodeEditorStatusBar\";\nimport { useEditorEngine } from \"../../hooks/use-editor-engine\";\nimport { useDarkMode } from \"../../hooks/use-dark-mode\";\nimport { getLanguage } from \"../../languages\";\nimport type { CodeEditorProps, CodeEditorContextValue } from \"./CodeEditor.types\";\n\nfunction CodeEditorRoot({\n children,\n className,\n value: valueProp,\n defaultValue = \"\",\n onChange,\n language: languageProp = \"javascript\",\n onLanguageChange,\n theme = \"auto\",\n readOnly = false,\n lineNumbers: lineNumbersProp = true,\n wordWrap: wordWrapProp = false,\n tabSize: tabSizeProp = 2,\n placeholder,\n minHeight,\n maxHeight,\n cursorLine,\n cursorColumn,\n diffBase,\n highlightLines,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n}: CodeEditorProps) {\n // The textarea's name. A labelledby wins, so no competing default is added;\n // otherwise it is never left unnamed (axe `label`, critical).\n const aria = useMemo(\n () => ({\n \"aria-label\": ariaLabelledBy ? undefined : (ariaLabel ?? \"Code editor\"),\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n }),\n [ariaLabel, ariaLabelledBy, ariaDescribedBy],\n );\n const [currentValue, setCurrentValue] = useControllableState(valueProp, defaultValue, onChange);\n\n // Diff gutter: per-line change marks of the current value vs the baseline.\n // Line-level only (no intra-line segmentation), recomputed as the user types.\n const diffAnnotations = useMemo(\n () => (diffBase == null ? null : annotateLines(diffBase, currentValue)),\n [diffBase, currentValue],\n );\n\n // Reactive dark mode for \"auto\" theme\n const isDark = useDarkMode();\n const resolvedTheme = theme === \"auto\" ? (isDark ? \"dark\" : \"light\") : theme;\n\n // Language state (changeable via toolbar selector)\n const [currentLanguage, setCurrentLanguageState] = useState(() => {\n const def = getLanguage(languageProp);\n return def?.name ?? languageProp;\n });\n\n const setLanguage = useCallback(\n (lang: string) => {\n const def = getLanguage(lang);\n const resolved = def?.name ?? lang;\n setCurrentLanguageState(resolved);\n onLanguageChange?.(resolved);\n },\n [onLanguageChange],\n );\n\n // Toggle states\n const [showLineNumbers, setShowLineNumbers] = useState(lineNumbersProp);\n const [isWordWrap, setIsWordWrap] = useState(wordWrapProp);\n\n // Cursor position\n const [cursorPosition, setCursorPosition] = useState({ line: 1, col: 1 });\n const [selectionLength, setSelectionLength] = useState(0);\n\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Our custom editor engine\n const engineReturn = useEditorEngine({\n containerRef,\n value: currentValue,\n onChange: setCurrentValue,\n language: currentLanguage,\n theme: resolvedTheme,\n readOnly,\n lineNumbers: showLineNumbers,\n wordWrap: isWordWrap,\n tabSize: tabSizeProp,\n placeholder,\n minHeight,\n maxHeight,\n onCursorChange: ({ line, col, selectionLength: sel }) => {\n setCursorPosition({ line, col });\n setSelectionLength(sel);\n },\n });\n\n // Reveal + place the caret when cursorLine/cursorColumn change (and on mount).\n // revealLine is stable, so this fires only on target change; it runs after the\n // engine's value-sync effect, so the textarea is populated and sized first.\n const { revealLine: revealLineImpl } = engineReturn;\n useEffect(() => {\n if (cursorLine == null) return;\n revealLineImpl(cursorLine, cursorColumn ?? 1, { focus: false });\n }, [cursorLine, cursorColumn, revealLineImpl]);\n\n const contextValue = useMemo<CodeEditorContextValue>(\n () => ({\n getValue: () => engineReturn.textareaRef.current?.value ?? currentValue,\n getSelection: () => {\n const ta = engineReturn.textareaRef.current;\n if (!ta) return \"\";\n return ta.value.slice(ta.selectionStart, ta.selectionEnd);\n },\n setValue: (v: string) => setCurrentValue(v),\n replaceSelection: (text: string) => {\n const ta = engineReturn.textareaRef.current;\n if (!ta) return;\n const start = ta.selectionStart;\n const end = ta.selectionEnd;\n const before = ta.value.slice(0, start);\n const after = ta.value.slice(end);\n ta.value = before + text + after;\n ta.selectionStart = ta.selectionEnd = start + text.length;\n setCurrentValue(ta.value);\n },\n focus: () => engineReturn.textareaRef.current?.focus(),\n revealLine: (line: number, column?: number) =>\n engineReturn.revealLine(line, column ?? 1, { focus: true }),\n setCursor: ({ line, column }: { line: number; column?: number }) =>\n engineReturn.revealLine(line, column ?? 1, { focus: true }),\n language: currentLanguage,\n setLanguage,\n theme: resolvedTheme,\n readOnly,\n lineNumbers: showLineNumbers,\n wordWrap: isWordWrap,\n tabSize: tabSizeProp,\n toggleWordWrap: () => setIsWordWrap((w) => !w),\n toggleLineNumbers: () => setShowLineNumbers((l) => !l),\n copyToClipboard: async () => {\n const text = engineReturn.textareaRef.current?.value ?? currentValue;\n await navigator.clipboard.writeText(text);\n },\n cursorPosition,\n selectionLength,\n textareaRef: engineReturn.textareaRef,\n placeholder,\n diffStats: diffAnnotations\n ? {\n added: diffAnnotations.added,\n modified: diffAnnotations.modified,\n removed: diffAnnotations.removed,\n }\n : null,\n _diffAnnotations: diffAnnotations,\n _engineReturn: engineReturn,\n _minHeight: minHeight,\n _maxHeight: maxHeight,\n _highlightLines: highlightLines,\n _aria: aria,\n }),\n [engineReturn, currentValue, currentLanguage, setLanguage, resolvedTheme, readOnly, showLineNumbers, isWordWrap, tabSizeProp, cursorPosition, selectionLength, setCurrentValue, placeholder, diffAnnotations, minHeight, maxHeight, highlightLines, aria],\n );\n\n return (\n <CodeEditorContext.Provider value={contextValue}>\n <div\n data-fancy-code-editor=\"\"\n className={cn(\n \"overflow-hidden\",\n className,\n )}\n >\n {children}\n </div>\n </CodeEditorContext.Provider>\n );\n}\n\nCodeEditorRoot.displayName = \"CodeEditor\";\n\nconst ToolbarWithSeparator = Object.assign(CodeEditorToolbar, {\n Separator: CodeEditorToolbarSeparator,\n});\n\nexport const CodeEditor = Object.assign(CodeEditorRoot, {\n Toolbar: ToolbarWithSeparator,\n Panel: CodeEditorPanel,\n StatusBar: CodeEditorStatusBar,\n});\n","import { cn, ContentRenderer, useControllableState } from \"@particle-academy/react-fancy\";\nimport { CodeEditor } from \"../CodeEditor\";\nimport type { EditorAriaProps } from \"../CodeEditor/CodeEditor.types\";\n\nexport type MarkdownEditorMode = \"split\" | \"edit\" | \"preview\";\n\n/**\n * `aria-label` / `aria-labelledby` / `aria-describedby` name the editing\n * textarea. Default name: \"Markdown editor\".\n */\nexport interface MarkdownEditorProps extends EditorAriaProps {\n /** Controlled markdown value. */\n value?: string;\n /** Initial value (uncontrolled). */\n defaultValue?: string;\n /** Called with the new markdown whenever the document changes. */\n onValueChange?: (markdown: string) => void;\n /**\n * Layout: `split` (editor + live preview side by side), `edit` (editor only),\n * or `preview` (rendered only). Default `split`.\n */\n mode?: MarkdownEditorMode;\n /** Editor theme — `\"light\" | \"dark\" | \"auto\"` or a registered name. Default `auto`. */\n theme?: string;\n /** Prevent editing. */\n readOnly?: boolean;\n /** Show line numbers in the editor (default false — prose reads better without). */\n lineNumbers?: boolean;\n /** Wrap long lines in the editor (default true for prose). */\n wordWrap?: boolean;\n /** Placeholder shown when empty. */\n placeholder?: string;\n /**\n * Height bounds (px). `maxHeight` constrains the PREVIEW pane as well as the\n * editor — it previously reached only the editor, so a long document rendered\n * at full height instead of scrolling.\n */\n minHeight?: number;\n maxHeight?: number;\n className?: string;\n /**\n * Swap the markdown → HTML renderer used by the preview pane.\n *\n * Rarely needed now: the preview renders through react-fancy's\n * `<ContentRenderer format=\"markdown\">`, which is a full CommonMark + GFM\n * parse. Supply this only to impose your own pipeline — the returned HTML is\n * injected as-is, so it must already be sanitised.\n */\n renderPreview?: (markdown: string) => string;\n}\n\n/**\n * A markdown-aware editor: a syntax-highlighted `CodeEditor` (the registered\n * `markdown` language) with an optional live preview pane. Controlled via\n * `value` + `onValueChange`. The preview renders through react-fancy's\n * `<ContentRenderer format=\"markdown\">` — a full CommonMark + GFM parse,\n * sanitised by default. Pass `renderPreview` to impose your own pipeline.\n *\n * ```tsx\n * <MarkdownEditor value={md} onValueChange={setMd} mode=\"split\" minHeight={240} />\n * ```\n */\nexport function MarkdownEditor({\n value,\n defaultValue = \"\",\n onValueChange,\n mode = \"split\",\n theme = \"auto\",\n readOnly = false,\n lineNumbers = false,\n wordWrap = true,\n placeholder,\n minHeight,\n maxHeight,\n className,\n renderPreview,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n}: MarkdownEditorProps) {\n const [content, setContent] = useControllableState(value, defaultValue, onValueChange);\n\n const showEditor = mode !== \"preview\";\n const showPreview = mode !== \"edit\";\n\n return (\n <div\n data-fancy-markdown-editor=\"\"\n data-mode={mode}\n className={cn(\"fancy-md-editor\", className)}\n >\n {showEditor && (\n <div className=\"fancy-md-editor-pane\">\n <CodeEditor\n value={content}\n onChange={setContent}\n language=\"markdown\"\n theme={theme}\n readOnly={readOnly}\n lineNumbers={lineNumbers}\n wordWrap={wordWrap}\n placeholder={placeholder}\n minHeight={minHeight}\n maxHeight={maxHeight}\n aria-label={ariaLabel ?? \"Markdown editor\"}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n >\n <CodeEditor.Panel />\n </CodeEditor>\n </div>\n )}\n {showPreview && (\n <div\n data-fancy-markdown-preview=\"\"\n className=\"fancy-md-preview\"\n style={maxHeight ? { maxHeight, overflowY: \"auto\" } : undefined}\n >\n {renderPreview ? (\n // The host imposed its own pipeline; its HTML is injected as-is and\n // is its own responsibility to sanitise.\n <div dangerouslySetInnerHTML={{ __html: renderPreview(content) }} />\n ) : (\n // The kit's own renderer — a full CommonMark + GFM parse that\n // sanitises by default. `marked` already sits in this tree as a\n // react-fancy runtime dependency, so the built-in renderer this\n // replaced was a second, weaker markdown implementation next to a\n // complete one.\n <ContentRenderer value={content} format=\"markdown\" />\n )}\n </div>\n )}\n </div>\n );\n}\n\nMarkdownEditor.displayName = \"MarkdownEditor\";\n","import type { ComponentType } from \"react\";\nimport type { FauxClientProps } from \"@particle-academy/react-fancy\";\nimport type { OfficeKind } from \"./file-type\";\n\n/** What a registered Office viewer is given. */\nexport interface OfficeViewerProps {\n /** The file's contents as our reader returns them (a dark-slide deck, a holy-sheet workbook, a last-word doc). */\n document: unknown;\n filename?: string;\n /** Passed through from `FileViewer`, for viewers that sit in the FauxClient frame. */\n frameProps?: Partial<FauxClientProps>;\n}\n\nexport interface OfficeViewerOptions {\n /**\n * Read the raw file in the browser, for when the app has only a URL. Give it\n * our JS reader, e.g. `(bytes) => new PptxReader().read(bytes)`. Without it,\n * a file with no server-read `document` gets the download card.\n */\n read?: (bytes: Uint8Array) => unknown;\n}\n\ninterface Registration {\n View: ComponentType<OfficeViewerProps>;\n read?: (bytes: Uint8Array) => unknown;\n}\n\nconst registry = new Map<OfficeKind, Registration>();\n\n/**\n * Show one Office format in `FileViewer` with a kit viewer. Call once at app\n * start, per format you want:\n *\n * ```ts\n * import { registerOfficeViewer } from \"@particle-academy/fancy-code\";\n * import { DeckFileView } from \"@particle-academy/fancy-slides\";\n * import { PptxReader } from \"@particle-academy/dark-slide\";\n *\n * registerOfficeViewer(\"pptx\", DeckFileView, { read: (b) => new PptxReader().read(b) });\n * ```\n *\n * A registry rather than an import because fancy-code must not depend on the\n * slide or sheet packages: an app that has neither (and does not want them)\n * would otherwise fail to build on a file type it never opens.\n */\nexport function registerOfficeViewer(\n kind: OfficeKind,\n View: ComponentType<OfficeViewerProps>,\n options: OfficeViewerOptions = {},\n): void {\n registry.set(kind, { View, read: options.read });\n}\n\n/** The viewer registered for a format, if any. */\nexport function officeViewerFor(kind: OfficeKind): Registration | undefined {\n return registry.get(kind);\n}\n\n/** Forget every registration (tests, hot reload). */\nexport function clearOfficeViewers(): void {\n registry.clear();\n}\n","import { resolveMediaType, type MediaKind } from \"@particle-academy/react-fancy\";\nimport { languageFromFilename } from \"@particle-academy/fancy-file-commons\";\n\n/**\n * The decision a file viewer makes about a file: render it as editable text, or\n * hand it to a media viewer. `media` carries the resolved {@link MediaKind};\n * `text` carries the editor language id.\n */\nexport type FileKind =\n | { kind: \"text\"; language: string }\n | { kind: \"media\"; mediaKind: MediaKind }\n /** Read as a reader sees it (rendered), not as source. `language` is for the source view. */\n | { kind: \"document\"; format: DocumentFormat; language: string }\n /** An Office file: binary, so never text. */\n | { kind: \"office\"; officeKind: OfficeKind };\n\nexport type DocumentFormat = \"markdown\" | \"html\" | \"text\";\nexport type OfficeKind = \"docx\" | \"xlsx\" | \"pptx\";\n\nconst OFFICE_EXT: Record<string, OfficeKind> = { docx: \"docx\", xlsx: \"xlsx\", xlsm: \"xlsx\", pptx: \"pptx\" };\nconst OFFICE_MIME: Record<string, OfficeKind> = {\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\": \"docx\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\": \"xlsx\",\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\": \"pptx\",\n};\n// By extension, not by editor language: `.xml` and `.vue` share the html\n// language for highlighting, and neither is a page to render.\nconst DOCUMENT_EXT: Record<string, DocumentFormat> = {\n md: \"markdown\",\n markdown: \"markdown\",\n html: \"html\",\n htm: \"html\",\n txt: \"text\",\n text: \"text\",\n};\nconst DOCUMENT_MIME: Record<string, DocumentFormat> = {\n \"text/markdown\": \"markdown\",\n \"text/x-markdown\": \"markdown\",\n \"text/html\": \"html\",\n \"text/plain\": \"text\",\n};\n\nfunction extensionOf(filename?: string): string {\n const name = (filename ?? \"\").split(/[?#]/)[0].split(\"/\").pop() ?? \"\";\n const dot = name.lastIndexOf(\".\");\n return dot > 0 ? name.slice(dot + 1).toLowerCase() : \"\";\n}\n\nexport interface ResolveFileKindInput {\n /** File name or path — sniffed for an extension (and used for the media check). */\n filename?: string;\n /** MIME type — preferred over the filename when known. */\n mime?: string;\n}\n\n// Filename → language now lives in @particle-academy/fancy-file-commons (the\n// shared core for the file packages — one EXT_LANGUAGE map suite-wide).\n// Re-exported so existing `fancy-code` imports keep working.\nexport { languageFromFilename };\n\n/**\n * Decide whether a file is previewable media (image / video / audio / PDF) or\n * text, from its MIME type (preferred) and/or filename. Media wins when the\n * type resolves to one; otherwise it's text and the editor language is derived\n * from the extension.\n *\n * Exposed so consumers can branch their own chrome (tabs, save buttons) the\n * same way `<FileViewer>` does internally.\n *\n * ```ts\n * resolveFileKind({ filename: \"logo.png\" }); // { kind: \"media\", mediaKind: \"image\" }\n * resolveFileKind({ filename: \"app.tsx\" }); // { kind: \"text\", language: \"typescript\" }\n * resolveFileKind({ mime: \"application/pdf\" }); // { kind: \"media\", mediaKind: \"pdf\" }\n * ```\n */\nexport function resolveFileKind({ filename, mime }: ResolveFileKindInput): FileKind {\n const media = resolveMediaType({ mime, src: filename });\n if (media !== \"unknown\") return { kind: \"media\", mediaKind: media };\n\n const type = (mime ?? \"\").split(\";\")[0].trim().toLowerCase();\n const ext = extensionOf(filename);\n\n const office = OFFICE_MIME[type] ?? OFFICE_EXT[ext];\n if (office) return { kind: \"office\", officeKind: office };\n\n const language = languageFromFilename(filename);\n // The extension wins when it names one: hosts label source `text/plain`.\n // A bare MIME decides only when the name says nothing (no filename, or a\n // plain-text one).\n const format = DOCUMENT_EXT[ext] ?? (language === \"plaintext\" ? DOCUMENT_MIME[type] : undefined);\n if (format) {\n // A text/* MIME with no filename still needs a source-view language.\n const lang = language !== \"plaintext\" ? language : format === \"markdown\" ? \"markdown\" : format === \"html\" ? \"html\" : \"plaintext\";\n return { kind: \"document\", format, language: lang };\n }\n\n return { kind: \"text\", language };\n}\n","import { useEffect, useState } from \"react\";\nimport { Callout, cn, ContentRenderer, FauxClient, MediaViewer } from \"@particle-academy/react-fancy\";\nimport { officeViewerFor } from \"../../office-viewers\";\nimport { CodeEditor } from \"../CodeEditor\";\nimport { resolveFileKind, type OfficeKind } from \"../../file-type\";\nimport type { FileViewerProps } from \"./FileViewer.types\";\n\n/**\n * A unified file viewer: renders text files in a read-only `CodeEditor` (with\n * syntax highlighting picked from the filename) and media files — image, video,\n * audio, PDF — via react-fancy's `<MediaViewer>`. The text-vs-media decision is\n * made by {@link resolveFileKind}; pass `fileKind` to override it, or call\n * `resolveFileKind` yourself to branch your own chrome (tabs, save buttons).\n *\n * Give the container a height for media files (PDF/image/video fill their box).\n *\n * ```tsx\n * // text\n * <FileViewer filename=\"app.tsx\" value={source} />\n * // media\n * <FileViewer filename=\"logo.png\" src={url} style={{ height: 360 }} />\n * ```\n */\nexport function FileViewer({\n filename,\n mime,\n src,\n value = \"\",\n onChange,\n readOnly = true,\n theme = \"auto\",\n fileKind,\n lineNumbers = true,\n wordWrap = false,\n line,\n column,\n highlightLines,\n minHeight,\n maxHeight,\n mediaProps,\n view = \"rendered\",\n frameProps,\n document,\n className,\n style,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n}: FileViewerProps) {\n const resolved = fileKind ?? resolveFileKind({ filename, mime });\n\n // A document reads as a reader sees it. Its source is shown instead when the\n // caller is editing, asked for it, or wants to land on a line (a line is a\n // place in the source, not in the rendered page).\n if (resolved.kind === \"document\" && view === \"rendered\" && readOnly && line == null) {\n return (\n <div\n data-fancy-file-viewer=\"\"\n data-kind=\"document\"\n data-format={resolved.format}\n className={className}\n style={style}\n >\n <FauxClient variant=\"device\" controls fill bodyClassName=\"overflow-auto\" {...frameProps}>\n <div className=\"px-6 py-5\">\n <ContentRenderer\n value={resolved.format === \"text\" ? textToHtml(value) : value}\n format={resolved.format === \"markdown\" ? \"markdown\" : \"html\"}\n />\n </div>\n </FauxClient>\n </div>\n );\n }\n\n // Office files are binary: never text. Until a viewer for the format is wired\n // in, they get MediaViewer's \"no preview\" card with a download.\n if (resolved.kind === \"office\") {\n return (\n <div\n data-fancy-file-viewer=\"\"\n data-kind=\"office\"\n data-office-kind={resolved.officeKind}\n className={cn(\"overflow-hidden\", className)}\n style={style}\n >\n <OfficeFile\n kind={resolved.officeKind}\n document={document}\n src={src}\n mime={mime}\n filename={filename}\n frameProps={frameProps}\n />\n </div>\n );\n }\n\n if (resolved.kind === \"media\") {\n // Image / video / PDF fill the sized wrapper so a height set on FileViewer\n // reaches the viewer; audio is a fixed-height card and shouldn't stretch.\n const { className: mediaClassName, ...restMediaProps } = mediaProps ?? {};\n // Images and PDFs carry the FauxClient frame every file viewer does; a\n // caller can still pass `frame: false` through `mediaProps`.\n restMediaProps.imageProps = { frame: true, frameProps, ...restMediaProps.imageProps };\n restMediaProps.pdfProps = { frame: true, frameProps, ...restMediaProps.pdfProps };\n const fill = resolved.mediaKind !== \"audio\";\n return (\n <div\n data-fancy-file-viewer=\"\"\n data-kind=\"media\"\n data-media-kind={resolved.mediaKind}\n className={cn(\"overflow-hidden\", className)}\n style={style}\n >\n <MediaViewer\n src={src ?? \"\"}\n mime={mime}\n alt={filename}\n kind={resolved.mediaKind}\n className={cn(fill && \"h-full w-full\", mediaClassName)}\n {...restMediaProps}\n />\n </div>\n );\n }\n\n return (\n <div\n data-fancy-file-viewer=\"\"\n data-kind=\"text\"\n className={className}\n style={style}\n >\n <CodeEditor\n value={value}\n onChange={readOnly ? undefined : onChange}\n language={resolved.language}\n theme={theme}\n readOnly={readOnly}\n lineNumbers={lineNumbers}\n wordWrap={wordWrap}\n minHeight={minHeight}\n maxHeight={maxHeight}\n // CodeEditor already reveals `cursorLine` on mount and on change; this\n // component never passed one through, so a viewer could not land anywhere.\n cursorLine={line}\n cursorColumn={column}\n highlightLines={highlightLines ?? (line != null ? [line] : undefined)}\n aria-label={ariaLabel ?? filename ?? \"File contents\"}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n >\n <CodeEditor.Panel />\n </CodeEditor>\n </div>\n );\n}\n\nFileViewer.displayName = \"FileViewer\";\n\ntype OfficeState =\n | { status: \"idle\" }\n | { status: \"reading\" }\n | { status: \"read\"; document: unknown }\n | { status: \"failed\"; message: string };\n\n/**\n * An Office file in the viewer the app registered for its format.\n *\n * Where the contents come from, in order (owner, 2026-10-19: \"both, server\n * preferred\"): the `document` the app's server already read; else the file at\n * `src`, read in the browser by the reader the app registered; else the\n * download card. A file our reader cannot open says so, beside the download,\n * rather than showing an empty viewer.\n */\nfunction OfficeFile({\n kind,\n document,\n src,\n mime,\n filename,\n frameProps,\n}: {\n kind: OfficeKind;\n document: unknown;\n src?: string;\n mime?: string;\n filename?: string;\n frameProps?: FileViewerProps[\"frameProps\"];\n}) {\n const registration = officeViewerFor(kind);\n const read = registration?.read;\n const [state, setState] = useState<OfficeState>({ status: \"idle\" });\n\n useEffect(() => {\n if (!registration || document !== undefined || !src || !read) return;\n let live = true;\n setState({ status: \"reading\" });\n fetch(src)\n .then(async (response) => {\n if (!response.ok) throw new Error(`The file could not be fetched (${response.status}).`);\n const bytes = new Uint8Array(await response.arrayBuffer());\n const doc = read(bytes);\n if (live) setState({ status: \"read\", document: doc });\n })\n .catch((error: unknown) => {\n if (live) setState({ status: \"failed\", message: error instanceof Error ? error.message : String(error) });\n });\n\n return () => {\n live = false;\n };\n }, [registration, document, src, read]);\n\n const fallback = <MediaViewer src={src ?? \"\"} mime={mime} alt={filename} className=\"h-full w-full\" />;\n\n if (!registration) return fallback;\n\n const View = registration.View;\n if (document !== undefined) return <View document={document} filename={filename} frameProps={frameProps} />;\n if (state.status === \"read\") return <View document={state.document} filename={filename} frameProps={frameProps} />;\n if (state.status === \"reading\") {\n return <div className=\"flex h-full items-center justify-center p-6 text-sm text-zinc-500\">Opening {filename ?? \"the file\"}…</div>;\n }\n if (state.status === \"failed\") {\n return (\n <div className=\"flex h-full flex-col gap-2 p-2\">\n <Callout color=\"red\">\n {filename ?? \"This file\"} could not be opened: {state.message}\n </Callout>\n {fallback}\n </div>\n );\n }\n\n return fallback;\n}\n\nconst ESCAPES: Record<string, string> = { \"&\": \"&\", \"<\": \"<\", \">\": \">\", '\"': \""\", \"'\": \"'\" };\n\n/**\n * Plain text as HTML a reader would expect: a blank line is a new paragraph, a\n * single newline a line break, and every character escaped -- `*x*` in a text\n * file is asterisks, not emphasis, so it is not given to the Markdown renderer.\n */\nfunction textToHtml(text: string): string {\n return text\n .replace(/\\r\\n?/g, \"\\n\")\n .split(/\\n{2,}/)\n .filter((block) => block.trim() !== \"\")\n .map((block) => `<p>${block.replace(/[&<>\"']/g, (c) => ESCAPES[c]).replace(/\\n/g, \"<br>\")}</p>`)\n .join(\"\");\n}\n","/**\n * Tiny, dependency-free Markdown → HTML renderer for the MarkdownEditor preview\n * pane. Covers the common subset — headings, bold/italic, inline + fenced code,\n * links, images, blockquotes, ordered/unordered lists, hr, and paragraphs. Input\n * is HTML-escaped first, so raw HTML in the source is shown as text (safe by\n * default). Not a full CommonMark implementation; swap in a real renderer\n * downstream if you need one.\n */\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\");\n}\n\n/**\n * Escape a value for use inside a double-quoted HTML attribute. Adds quote\n * escaping on top of `escapeHtml`'s `&<>` so the value can't break out of the\n * attribute. Apply to text that has already been `escapeHtml`-ed.\n */\nfunction escapeAttr(s: string): string {\n return s.replace(/\"/g, \""\").replace(/'/g, \"'\");\n}\n\n/** Schemes a link may use. Anything else with a scheme renders as plain text. */\nconst LINK_SCHEMES = new Set([\"http\", \"https\", \"mailto\", \"tel\"]);\n\n/**\n * The scheme a browser would see in this URL, or null for a relative URL.\n *\n * Normalised the way the URL parser does it: leading C0 controls and spaces are\n * stripped and tab / CR / LF are removed anywhere, so `\" javascript:\"` and a\n * scheme split by a tab are both caught. Case-insensitive.\n */\nfunction schemeOf(url: string): string | null {\n let s = \"\";\n for (const ch of url) {\n const code = ch.codePointAt(0) ?? 0;\n if (code === 9 || code === 10 || code === 13) continue;\n if (s === \"\" && code <= 32) continue;\n s += ch;\n }\n const m = /^([a-zA-Z][a-zA-Z0-9+.-]*):/.exec(s);\n return m ? m[1].toLowerCase() : null;\n}\n\n/**\n * Is this URL safe in a preview inserted with innerHTML?\n *\n * The preview bypasses React, so React's `javascript:` guard never sees it. A\n * relative URL is always fine; an absolute one must use an allowed scheme, and\n * an image may additionally be a raster `data:image/...`. The input has already\n * been HTML-escaped, which neutralises entity-encoded schemes on its own.\n */\nfunction safeUrl(url: string, kind: \"link\" | \"image\"): boolean {\n const scheme = schemeOf(url);\n if (scheme === null) return true;\n if (scheme === \"http\" || scheme === \"https\") return true;\n if (kind === \"link\") return LINK_SCHEMES.has(scheme);\n return scheme === \"data\" && /^data:image\\/(png|jpe?g|gif|webp|avif|bmp);/i.test(url.trim());\n}\n\n/** Inline spans — run on already-escaped text. */\nfunction inline(text: string): string {\n return text\n // images  -- an unsafe src keeps only its alt text\n .replace(/!\\[([^\\]]*)\\]\\(([^)\\s]+)(?:\\s+\"([^\"]*)\")?\\)/g, (_m, alt, src, title) =>\n safeUrl(src, \"image\")\n ? `<img src=\"${escapeAttr(src)}\" alt=\"${escapeAttr(alt)}\"${title ? ` title=\"${escapeAttr(title)}\"` : \"\"}>`\n : alt)\n // links [text](href) -- an unsafe href keeps only its text\n .replace(/\\[([^\\]]+)\\]\\(([^)\\s]+)(?:\\s+\"([^\"]*)\")?\\)/g, (_m, t, href, title) =>\n safeUrl(href, \"link\")\n ? `<a href=\"${escapeAttr(href)}\"${title ? ` title=\"${escapeAttr(title)}\"` : \"\"} rel=\"noopener\">${t}</a>`\n : t)\n // inline code `code`\n .replace(/`([^`]+)`/g, (_m, c) => `<code>${c}</code>`)\n // bold **x** / __x__\n .replace(/(\\*\\*|__)(?=\\S)([\\s\\S]*?\\S)\\1/g, \"<strong>$2</strong>\")\n // italic *x* / _x_\n .replace(/(\\*|_)(?=\\S)([\\s\\S]*?\\S)\\1/g, \"<em>$2</em>\");\n}\n\nexport function renderMarkdown(markdown: string): string {\n const lines = markdown.replace(/\\r\\n?/g, \"\\n\").split(\"\\n\");\n const out: string[] = [];\n\n let i = 0;\n let para: string[] = [];\n let listType: \"ul\" | \"ol\" | null = null;\n\n const flushPara = () => {\n if (para.length) {\n out.push(`<p>${inline(para.join(\" \"))}</p>`);\n para = [];\n }\n };\n const closeList = () => {\n if (listType) {\n out.push(`</${listType}>`);\n listType = null;\n }\n };\n\n while (i < lines.length) {\n const line = lines[i];\n\n // Fenced code block\n const fence = line.match(/^\\s*(```|~~~)(.*)$/);\n if (fence) {\n flushPara();\n closeList();\n const lang = fence[2].trim();\n const body: string[] = [];\n i++;\n while (i < lines.length && !/^\\s*(```|~~~)/.test(lines[i])) {\n body.push(lines[i]);\n i++;\n }\n i++; // consume closing fence\n out.push(`<pre><code${lang ? ` class=\"language-${escapeAttr(escapeHtml(lang))}\"` : \"\"}>${escapeHtml(body.join(\"\\n\"))}</code></pre>`);\n continue;\n }\n\n const esc = escapeHtml(line);\n\n // Blank line — paragraph/list break\n if (/^\\s*$/.test(line)) {\n flushPara();\n closeList();\n i++;\n continue;\n }\n\n // Heading\n const heading = esc.match(/^(#{1,6})\\s+(.*)$/);\n if (heading) {\n flushPara();\n closeList();\n const level = heading[1].length;\n out.push(`<h${level}>${inline(heading[2])}</h${level}>`);\n i++;\n continue;\n }\n\n // Horizontal rule\n if (/^\\s*([-*_])(\\s*\\1){2,}\\s*$/.test(line)) {\n flushPara();\n closeList();\n out.push(\"<hr>\");\n i++;\n continue;\n }\n\n // Blockquote (single-level)\n const quote = esc.match(/^\\s*>\\s?(.*)$/);\n if (quote) {\n flushPara();\n closeList();\n out.push(`<blockquote>${inline(quote[1])}</blockquote>`);\n i++;\n continue;\n }\n\n // List item\n const ol = esc.match(/^\\s*\\d+\\.\\s+(.*)$/);\n const ul = esc.match(/^\\s*[-*+]\\s+(.*)$/);\n if (ol || ul) {\n flushPara();\n const type: \"ul\" | \"ol\" = ol ? \"ol\" : \"ul\";\n if (listType !== type) {\n closeList();\n out.push(`<${type}>`);\n listType = type;\n }\n out.push(`<li>${inline((ol ?? ul)![1])}</li>`);\n i++;\n continue;\n }\n\n // Plain paragraph text (accumulate)\n closeList();\n para.push(esc);\n i++;\n }\n\n flushPara();\n closeList();\n return out.join(\"\\n\");\n}\n","import { useMemo } from \"react\";\nimport {\n InputTag,\n textareaAdapter,\n type InputTagAdapter,\n type InputTagProps,\n type InputTagTriggers,\n} from \"@particle-academy/react-fancy\";\nimport { useCodeEditor } from \"./components/CodeEditor/CodeEditor.context\";\n\n/**\n * Glue between `@particle-academy/react-fancy`'s `<InputTag>` and the\n * `<CodeEditor>` from this package. `<CodeEditor>` renders a real DOM\n * `<textarea>` under its overlay, so the existing `textareaAdapter`\n * just works — this module hands it the right ref via the editor\n * context.\n *\n * <CodeEditor value={code} onChange={setCode} language=\"markdown\">\n * <CodeEditor.Toolbar />\n * <CodeEditor.Panel />\n * <CodeEditorInputTag\n * triggers={{\n * \"/\": { items: commands, insert: (c) => `${c.name} ` },\n * \"@\": { items: mentions, insert: (m) => `@${m.name} ` },\n * }}\n * />\n * </CodeEditor>\n *\n * Must be rendered as a descendant of `<CodeEditor>` (it reads the\n * editor's context). For ad-hoc wiring outside the component tree,\n * pull the textarea ref off the context and call `textareaAdapter`\n * yourself.\n */\n\n/**\n * Hook form — returns an `InputTagAdapter` bound to the surrounding\n * `<CodeEditor>`. Useful when you want to compose your own picker UI\n * around the same adapter.\n */\nexport function useCodeEditorInputTagAdapter(): InputTagAdapter {\n const ctx = useCodeEditor();\n return useMemo(() => textareaAdapter(ctx.textareaRef), [ctx.textareaRef]);\n}\n\nexport interface CodeEditorInputTagProps extends Omit<InputTagProps, \"adapter\"> {\n triggers: InputTagTriggers;\n}\n\n/**\n * Convenience wrapper — renders `<InputTag>` already wired to the\n * surrounding `<CodeEditor>`'s textarea. Equivalent to:\n *\n * const adapter = useCodeEditorInputTagAdapter();\n * return <InputTag adapter={adapter} {...rest} />;\n */\nexport function CodeEditorInputTag(props: CodeEditorInputTagProps) {\n const adapter = useCodeEditorInputTagAdapter();\n return <InputTag adapter={adapter} {...props} />;\n}\n"]}
|
package/docs/CodeEditor.md
CHANGED
|
@@ -42,7 +42,7 @@ All three sub-components are optional — omit any to render a minimal editor.
|
|
|
42
42
|
| readOnly | `boolean` | `false` | Disable editing |
|
|
43
43
|
| lineNumbers | `boolean` | `true` | Show the gutter with line numbers |
|
|
44
44
|
| wordWrap | `boolean` | `false` | Wrap long lines instead of horizontal scroll |
|
|
45
|
-
| tabSize | `number` | `2` | Number of spaces per tab |
|
|
45
|
+
| tabSize | `number` | `2` | Number of spaces per tab (see [Keyboard](#keyboard)) |
|
|
46
46
|
| placeholder | `string` | - | Shown when the document is empty |
|
|
47
47
|
| minHeight | `number` | - | Minimum height in px |
|
|
48
48
|
| maxHeight | `number` | - | Maximum height in px (scrolls beyond) |
|
|
@@ -127,6 +127,21 @@ const [code, setCode] = useState("");
|
|
|
127
127
|
</CodeEditor>
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
+
## Keyboard
|
|
131
|
+
|
|
132
|
+
The editor never traps keyboard focus (WCAG 2.1.2):
|
|
133
|
+
|
|
134
|
+
- **Tab is armed by an edit.** Tabbing into the editor and pressing Tab again
|
|
135
|
+
moves focus on, like any other control. Once you edit (type, paste, cut,
|
|
136
|
+
Enter) in that focus session, Tab inserts `tabSize` spaces (or indents the
|
|
137
|
+
selected lines) and Shift+Tab dedents.
|
|
138
|
+
- **Escape disarms.** After Escape, the next Tab leaves the editor. Blurring
|
|
139
|
+
the editor disarms too, so every new visit starts unarmed.
|
|
140
|
+
- **Read-only editors** (`readOnly`, and `FileViewer`) never intercept keys:
|
|
141
|
+
arrows, Home/End, Page Up/Down, copy and Tab / Shift+Tab all behave natively.
|
|
142
|
+
- The editing textarea shows the kit focus ring (`--fancy-focus` /
|
|
143
|
+
`--fancy-focus-dark`) when focused from the keyboard.
|
|
144
|
+
|
|
130
145
|
## Read-Only Display
|
|
131
146
|
|
|
132
147
|
```tsx
|
package/package.json
CHANGED