@mieweb/ui 0.11.0-dev.23 → 0.11.0-dev.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-67REGSKI.js → chunk-GTZUG646.js} +3 -3
- package/dist/{chunk-67REGSKI.js.map → chunk-GTZUG646.js.map} +1 -1
- package/dist/{chunk-ESXTC5GW.cjs → chunk-HKLTJYRU.cjs} +4 -4
- package/dist/{chunk-ESXTC5GW.cjs.map → chunk-HKLTJYRU.cjs.map} +1 -1
- package/dist/{chunk-5EOW6AP3.js → chunk-IYY7NKA3.js} +97 -19
- package/dist/chunk-IYY7NKA3.js.map +1 -0
- package/dist/{chunk-7BA7ENN5.cjs → chunk-VEPARPUE.cjs} +97 -19
- package/dist/chunk-VEPARPUE.cjs.map +1 -0
- package/dist/components/EmailEditor/index.cjs +11 -11
- package/dist/components/EmailEditor/index.js +2 -2
- package/dist/components/RichTextEditor/index.cjs +4 -4
- package/dist/components/RichTextEditor/index.d.cts +14 -0
- package/dist/components/RichTextEditor/index.d.ts +14 -0
- package/dist/components/RichTextEditor/index.js +1 -1
- package/dist/index.cjs +15 -15
- package/dist/index.d.cts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-5EOW6AP3.js.map +0 -1
- package/dist/chunk-7BA7ENN5.cjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/MacroLibrary/MacroLibrary.tsx","../src/components/RichTextEditor/processDictation.ts","../src/components/RichTextEditor/RichTextEditor.tsx"],"names":["React","MacroLibrary","jsxs","jsx","Fragment","BookOpen"],"mappings":"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","file":"chunk-5EOW6AP3.js","sourcesContent":["import * as React from 'react';\nimport {\n SearchIcon,\n HistoryIcon,\n BookOpenIcon,\n ChevronDownIcon,\n ChevronRightIcon,\n CloseIcon,\n PlusIcon,\n} from '../Icons';\nimport { cn } from '../../utils/cn';\nimport { Button } from '../Button';\nimport { Input } from '../Input';\n\nexport interface Macro {\n /** Stable identifier. */\n id: string;\n /** Human-readable name shown in the list. */\n label: string;\n /** Plain text inserted into the editor. `\\n` is preserved. */\n content: string;\n /** Optional shortcut identifier shown as a badge (e.g. `.b`). */\n shortcut?: string;\n /** Extra search terms that are not displayed. */\n keywords?: string[];\n}\n\nexport interface MacroGroup {\n /** Stable identifier. */\n id: string;\n /** Group heading (e.g. \"Default library\"). */\n label: string;\n /**\n * `previous` renders the group visually distinct from library macros\n * (history icon, muted header) so prior values are never mistaken for\n * predefined content. Defaults to `library`.\n */\n kind?: 'library' | 'previous';\n /** Macros belonging to the group. */\n macros: Macro[];\n}\n\nexport interface MacroLibraryProps {\n /** Grouped macros supplied by the application. */\n groups: MacroGroup[];\n /** Called with the chosen macro. The caller performs the insertion. */\n onSelect: (macro: Macro) => void;\n /** Id for the panel root (e.g. the target of a toggle's aria-controls). */\n id?: string;\n /**\n * Name of the insertion target shown in the header (e.g. the editor's\n * label), rendered as \"Insert into <target>\".\n */\n targetLabel?: string;\n /** When provided, renders a close button and enables Escape-to-close. */\n onClose?: () => void;\n /** When provided, renders a \"Save as macro\" action in the footer. */\n onCreateMacro?: () => void;\n /** Autofocus the search input on mount. Defaults to false. */\n autoFocusSearch?: boolean;\n /** Additional class for the panel root. */\n className?: string;\n /** Overridable labels for i18n. */\n labels?: Partial<typeof DEFAULT_LABELS>;\n}\n\nconst DEFAULT_LABELS = {\n insertInto: 'Insert into',\n macros: 'Macros',\n searchPlaceholder: 'Search macros…',\n searchLabel: 'Search macros',\n close: 'Close macros',\n createMacro: 'Save as macro',\n empty: 'No macros available',\n emptyHint: 'The application has not provided a macro list.',\n noResults: 'No macros match',\n clearSearch: 'Clear search',\n showFullContent: 'Show full content',\n hideFullContent: 'Hide full content',\n more: 'more',\n less: 'less',\n};\n\n/** Case-insensitive match across label, shortcut, keywords and content. */\nfunction matchesQuery(macro: Macro, query: string): boolean {\n const q = query.toLowerCase();\n return (\n macro.label.toLowerCase().includes(q) ||\n (macro.shortcut ?? '').toLowerCase().includes(q) ||\n (macro.keywords ?? []).some((k) => k.toLowerCase().includes(q)) ||\n macro.content.toLowerCase().includes(q)\n );\n}\n\n/** Query is a prefix of the macro's shortcut identifier. */\nfunction isShortcutHit(macro: Macro, query: string): boolean {\n return (\n query.length > 0 &&\n (macro.shortcut ?? '').toLowerCase().startsWith(query.toLowerCase())\n );\n}\n\n/** Shortcut-prefix matches rank before everything else. */\nfunction rankMacros(macros: Macro[], query: string): Macro[] {\n return [...macros].sort(\n (a, b) => Number(isShortcutHit(b, query)) - Number(isShortcutHit(a, query))\n );\n}\n\ninterface MacroRowProps {\n macro: Macro;\n isPrevious: boolean;\n isPeeked: boolean;\n peekId: string;\n labels: typeof DEFAULT_LABELS;\n onSelect: (macro: Macro) => void;\n onTogglePeek: () => void;\n onRowKeyDown: (event: React.KeyboardEvent) => void;\n}\n\n/**\n * One macro row. The two-line preview measures its own clamping so the\n * \"more\" toggle only appears when content is actually truncated.\n */\nfunction MacroRow({\n macro,\n isPrevious,\n isPeeked,\n peekId,\n labels,\n onSelect,\n onTogglePeek,\n onRowKeyDown,\n}: MacroRowProps) {\n const [truncated, setTruncated] = React.useState(false);\n const rowRef = React.useRef<HTMLButtonElement>(null);\n const lessRef = React.useRef<HTMLButtonElement>(null);\n // Toggling unmounts the activated control; move focus to its replacement\n // (\"less\" on expand, the row on collapse — the \"more\" chip is hidden until\n // hover/focus) so keyboard focus never drops to <body> and Escape keeps\n // closing the panel.\n const focusAfterToggle = React.useRef(false);\n React.useEffect(() => {\n if (!focusAfterToggle.current) return;\n focusAfterToggle.current = false;\n (isPeeked ? lessRef.current : rowRef.current)?.focus();\n }, [isPeeked]);\n const handleToggle = () => {\n focusAfterToggle.current = true;\n onTogglePeek();\n };\n // Remeasure on resize: docking/undocking or narrowing the panel can clamp\n // content without a React render.\n const previewObserver = React.useRef<ResizeObserver | null>(null);\n const measurePreview = (el: HTMLSpanElement | null) => {\n previewObserver.current?.disconnect();\n previewObserver.current = null;\n if (!el) return;\n const measure = () => setTruncated(el.scrollHeight > el.clientHeight);\n measure();\n if (typeof ResizeObserver !== 'undefined') {\n previewObserver.current = new ResizeObserver(measure);\n previewObserver.current.observe(el);\n }\n };\n return (\n <div\n data-slot=\"macro-library-item\"\n className=\"group/macro hover:bg-muted/60 relative rounded-md\"\n >\n <button\n type=\"button\"\n data-macro-row\n ref={rowRef}\n className=\"focus-visible:ring-ring text-foreground hover:text-primary flex w-full cursor-pointer flex-col items-stretch gap-0.5 rounded-md px-2 py-1.5 text-start focus-visible:ring-2 focus-visible:outline-none\"\n onClick={() => onSelect(macro)}\n onKeyDown={onRowKeyDown}\n >\n <span className=\"flex items-center gap-2\">\n {macro.shortcut && (\n <span\n // Shortcuts are typed sequences; keep them LTR in RTL locales.\n dir=\"ltr\"\n className={cn(\n 'border-border bg-background text-muted-foreground rounded border px-1 font-mono text-[11px]',\n isPrevious &&\n 'border-warning-300 bg-warning-50 text-warning-800 dark:border-warning-700 dark:bg-warning-950 dark:text-warning-300'\n )}\n >\n {macro.shortcut}\n </span>\n )}\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {macro.label}\n </span>\n </span>\n {!isPeeked && (\n <span\n ref={measurePreview}\n className=\"text-muted-foreground line-clamp-2 text-xs break-words\"\n >\n {macro.content}\n </span>\n )}\n </button>\n {isPeeked && (\n <div\n id={peekId}\n data-slot=\"macro-library-peek\"\n className=\"text-muted-foreground px-2 pb-1 text-xs break-words whitespace-pre-line\"\n >\n {macro.content}\n </div>\n )}\n {truncated && !isPeeked && (\n // Overlays the end of the clamped second line; revealed on row\n // hover or keyboard focus so short rows stay entirely clean. Always\n // visible on devices without hover (touch).\n <button\n type=\"button\"\n className=\"bg-muted text-muted-foreground hover:text-primary focus-visible:ring-ring invisible absolute end-1.5 bottom-1.5 flex cursor-pointer items-center rounded-sm px-1 text-[11px] leading-4 group-focus-within/macro:visible group-hover/macro:visible hover:underline focus-visible:ring-2 focus-visible:outline-none [@media(hover:none)]:visible\"\n aria-expanded={false}\n aria-label={`${labels.showFullContent}: ${macro.label}`}\n onClick={handleToggle}\n >\n {labels.more}\n <ChevronRightIcon\n aria-hidden=\"true\"\n className=\"h-3 w-3 rtl:-scale-x-100\"\n />\n </button>\n )}\n {isPeeked && (\n <span className=\"-mt-1 flex justify-end px-2 pb-1\">\n <button\n type=\"button\"\n ref={lessRef}\n className=\"text-muted-foreground hover:text-primary focus-visible:ring-ring cursor-pointer rounded text-[11px] hover:underline focus-visible:ring-2 focus-visible:outline-none\"\n aria-expanded\n aria-controls={peekId}\n aria-label={`${labels.hideFullContent}: ${macro.label}`}\n onClick={handleToggle}\n >\n {labels.less}\n </button>\n </span>\n )}\n </div>\n );\n}\n\n/**\n * A searchable, grouped macro browser designed to dock inside an editor's\n * chrome. Editor-agnostic: selecting a macro calls `onSelect` and the host\n * performs the insertion. Previous-value groups (`kind: 'previous'`) are\n * rendered distinctly from library macros. All rows and controls are real\n * buttons with roving arrow-key focus from the search input.\n */\nexport const MacroLibrary = React.forwardRef<HTMLDivElement, MacroLibraryProps>(\n function MacroLibrary(\n {\n groups,\n onSelect,\n id,\n targetLabel,\n onClose,\n onCreateMacro,\n autoFocusSearch = false,\n className,\n labels: labelOverrides,\n },\n ref\n ) {\n const labels = { ...DEFAULT_LABELS, ...labelOverrides };\n const [query, setQuery] = React.useState('');\n const [collapsed, setCollapsed] = React.useState<Record<string, boolean>>(\n {}\n );\n const [peeked, setPeeked] = React.useState<string | null>(null);\n const listRef = React.useRef<HTMLDivElement>(null);\n const searchRef = React.useRef<HTMLInputElement>(null);\n const panelId = React.useId();\n\n React.useEffect(() => {\n if (autoFocusSearch) searchRef.current?.focus();\n }, [autoFocusSearch]);\n\n const trimmed = query.trim();\n const searching = trimmed.length > 0;\n\n const visibleGroups = groups\n .map((group) => ({\n ...group,\n macros: searching\n ? rankMacros(\n group.macros.filter((m) => matchesQuery(m, trimmed)),\n trimmed\n )\n : group.macros,\n }))\n .filter((group) => group.macros.length > 0)\n // Groups containing shortcut-prefix hits rank first so \".c\" reaches\n // the macro with that shortcut before incidental content matches in\n // earlier groups; the stable sort keeps group context otherwise.\n .sort(\n (a, b) =>\n Number(b.macros.some((m) => isShortcutHit(m, trimmed))) -\n Number(a.macros.some((m) => isShortcutHit(m, trimmed)))\n );\n\n const hasMacros = groups.some((g) => g.macros.length > 0);\n const noResults = hasMacros && searching && visibleGroups.length === 0;\n\n /** Roving focus across visible macro-row buttons. */\n const moveFocus = (delta: 1 | -1) => {\n const rows = Array.from(\n listRef.current?.querySelectorAll<HTMLButtonElement>(\n '[data-macro-row]'\n ) ?? []\n );\n if (rows.length === 0) return;\n const index = rows.findIndex((row) => row === document.activeElement);\n if (index === -1) {\n rows[delta === 1 ? 0 : rows.length - 1].focus();\n return;\n }\n const next = index + delta;\n if (next < 0) {\n searchRef.current?.focus();\n return;\n }\n rows[Math.min(next, rows.length - 1)].focus();\n };\n\n const handlePanelKeyDown = (event: React.KeyboardEvent) => {\n // Escape during IME composition cancels the composition; never close.\n if (event.nativeEvent.isComposing) return;\n if (event.key === 'Escape' && onClose) {\n event.stopPropagation();\n onClose();\n }\n };\n\n const handleSearchKeyDown = (event: React.KeyboardEvent) => {\n // ArrowDown during IME composition navigates conversion candidates.\n if (event.nativeEvent.isComposing) return;\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n moveFocus(1);\n }\n };\n\n const handleRowKeyDown = (event: React.KeyboardEvent) => {\n if (event.nativeEvent.isComposing) return;\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n moveFocus(1);\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n moveFocus(-1);\n }\n };\n\n return (\n // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- keydown only delegates Escape-to-close from focusable children\n <div\n ref={ref}\n id={id}\n role=\"group\"\n aria-label={\n targetLabel ? `${labels.insertInto} ${targetLabel}` : labels.macros\n }\n data-slot=\"macro-library\"\n className={cn('bg-muted/20 flex min-h-0 flex-col', className)}\n onKeyDown={handlePanelKeyDown}\n >\n <div\n data-slot=\"macro-library-header\"\n className=\"border-border flex items-center justify-between gap-2 border-b px-3 py-2\"\n >\n <span className=\"text-muted-foreground min-w-0 truncate text-xs\">\n {targetLabel ? (\n <>\n {labels.insertInto}{' '}\n <span className=\"text-foreground font-semibold\">\n {targetLabel}\n </span>\n </>\n ) : (\n labels.macros\n )}\n </span>\n {onClose && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 w-6 shrink-0 p-0\"\n onClick={onClose}\n aria-label={labels.close}\n >\n <CloseIcon className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n </div>\n\n {hasMacros ? (\n <>\n <div className=\"px-3 pt-2\">\n <div className=\"relative\">\n <SearchIcon\n aria-hidden=\"true\"\n className=\"text-muted-foreground pointer-events-none absolute start-2.5 top-1/2 z-10 h-3.5 w-3.5 -translate-y-1/2\"\n />\n <Input\n ref={searchRef}\n label={labels.searchLabel}\n hideLabel\n size=\"sm\"\n type=\"search\"\n placeholder={labels.searchPlaceholder}\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={handleSearchKeyDown}\n className=\"ps-8\"\n aria-controls={`${panelId}-list`}\n />\n </div>\n </div>\n\n {/* Persistent polite region so a failed search is announced. */}\n <div role=\"status\" className=\"sr-only\">\n {noResults ? `${labels.noResults} “${trimmed}”` : ''}\n </div>\n\n <div\n ref={listRef}\n id={`${panelId}-list`}\n data-slot=\"macro-library-list\"\n className=\"min-h-0 flex-1 overflow-y-auto p-1.5\"\n >\n {noResults && (\n <div className=\"text-muted-foreground px-2 py-8 text-center text-sm\">\n <p>\n {labels.noResults} “{trimmed}”\n </p>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"mt-2\"\n onClick={() => {\n setQuery('');\n searchRef.current?.focus();\n }}\n >\n {labels.clearSearch}\n </Button>\n </div>\n )}\n\n {visibleGroups.map((group) => {\n const isPrevious = group.kind === 'previous';\n // Strict check: ids like \"constructor\" must not read\n // inherited Object.prototype members as collapsed state.\n const isCollapsed = !searching && collapsed[group.id] === true;\n const GroupIcon = isPrevious ? HistoryIcon : BookOpenIcon;\n return (\n <div\n key={group.id}\n data-slot=\"macro-library-group\"\n data-kind={group.kind ?? 'library'}\n >\n <button\n type=\"button\"\n className={cn(\n 'text-muted-foreground hover:text-foreground flex w-full items-center gap-1.5 rounded px-2 pt-2.5 pb-1 text-start text-[11px] font-semibold tracking-wide uppercase',\n isPrevious && 'text-warning-700 dark:text-warning-400'\n )}\n aria-expanded={!isCollapsed}\n disabled={searching}\n onClick={() =>\n setCollapsed((prev) => ({\n ...prev,\n [group.id]: prev[group.id] !== true,\n }))\n }\n >\n <GroupIcon aria-hidden=\"true\" className=\"h-3 w-3\" />\n <span className=\"min-w-0 flex-1 truncate\">\n {group.label}\n </span>\n {!searching &&\n (isCollapsed ? (\n <ChevronRightIcon\n aria-hidden=\"true\"\n className=\"h-3 w-3\"\n />\n ) : (\n <ChevronDownIcon\n aria-hidden=\"true\"\n className=\"h-3 w-3\"\n />\n ))}\n </button>\n\n {!isCollapsed &&\n group.macros.map((macro) => {\n const isPeeked = peeked === macro.id;\n return (\n <MacroRow\n key={macro.id}\n macro={macro}\n isPrevious={isPrevious}\n isPeeked={isPeeked}\n peekId={`${panelId}-peek-${macro.id}`}\n labels={labels}\n onSelect={onSelect}\n onTogglePeek={() =>\n setPeeked(isPeeked ? null : macro.id)\n }\n onRowKeyDown={handleRowKeyDown}\n />\n );\n })}\n </div>\n );\n })}\n </div>\n </>\n ) : (\n <div className=\"text-muted-foreground flex flex-1 flex-col items-center justify-center gap-1 px-4 py-10 text-center text-sm\">\n <BookOpenIcon aria-hidden=\"true\" className=\"mb-1 h-5 w-5\" />\n <p className=\"text-foreground font-medium\">{labels.empty}</p>\n <p className=\"text-xs\">{labels.emptyHint}</p>\n </div>\n )}\n\n {onCreateMacro && (\n <div\n data-slot=\"macro-library-footer\"\n className=\"border-border border-t px-2 py-1.5\"\n >\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"w-full justify-start gap-1.5\"\n onClick={onCreateMacro}\n >\n <PlusIcon aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n {labels.createMacro}\n </Button>\n </div>\n )}\n </div>\n );\n }\n);\n","/**\n * Converts spoken punctuation words (e.g. \"period\", \"comma\") into the\n * corresponding characters, using lightweight context heuristics so that words\n * like \"time period\" or \"the colon\" are left intact. Pure and side-effect free\n * so it can be unit tested independently of the editor.\n */\nexport function processDictation(text: string): string {\n let result = text;\n\n // \"period\" as a word vs. as punctuation.\n result = result.replace(\n /\\b(the|a|this|that|each|every|same|time|grace|trial|waiting|probationary|pay|billing|accounting)\\s+period\\b/gi,\n '$1 period'\n );\n result = result.replace(\n /\\bperiod\\s+(of|in|for|from|to|during|between|after|before|when|where|is|was|will|has|had)\\b/gi,\n 'period $1'\n );\n result = result.replace(/\\s+period(\\s*$)/gi, '.$1');\n result = result.replace(/\\s+period\\s+(?=[A-Z])/g, '. ');\n\n // \"comma\"\n result = result.replace(/\\bcomma\\s+(separated|delimited)/gi, 'comma $1');\n result = result.replace(/\\s+comma\\b/gi, ',');\n\n // \"colon\"\n result = result.replace(\n /\\b(the|a|my|your|his|her|their|semicolon|ascending|descending|transverse|sigmoid)\\s+colon\\b/gi,\n '$1 colon'\n );\n result = result.replace(\n /\\bcolon\\s+(cancer|surgery|health|polyp|scope|oscopy)/gi,\n 'colon $1'\n );\n result = result.replace(/\\s+colon\\b/gi, ':');\n\n // \"dash\"\n result = result.replace(\n /\\b(yard|meter|hundred|mad|quick|wild)\\s+dash\\b/gi,\n '$1 dash'\n );\n result = result.replace(/\\bdash\\s+(to|for|of)\\b/gi, 'dash $1');\n result = result.replace(/\\s+dash\\b/gi, ' -');\n\n const simplePunctuation: Record<string, string> = {\n ' full stop': '.',\n ' question mark': '?',\n ' exclamation point': '!',\n ' exclamation mark': '!',\n ' semicolon': ';',\n ' semi colon': ';',\n ' hyphen': '-',\n ' open parenthesis': ' (',\n ' close parenthesis': ')',\n ' open bracket': ' [',\n ' close bracket': ']',\n ' open quote': ' \"',\n ' close quote': '\"',\n ' quote': '\"',\n ' apostrophe': \"'\",\n ' new line': '\\n',\n ' newline': '\\n',\n ' new paragraph': '\\n\\n',\n ' tab': '\\t',\n };\n\n for (const [spoken, punctuation] of Object.entries(simplePunctuation)) {\n const regex = new RegExp(spoken, 'gi');\n result = result.replace(regex, punctuation);\n }\n\n // Capitalize after sentence-ending punctuation.\n result = result.replace(\n /([.!?])\\s+([a-z])/g,\n (_match, punct: string, letter: string) =>\n `${punct} ${letter.toUpperCase()}`\n );\n\n return result;\n}\n\n/**\n * Converts `<<field>>` (and the HTML-encoded `<<field>>`) syntax\n * into mustache `{{field}}` syntax. Pure helper operating on an HTML string.\n */\nexport function convertAngleBracketsToMustache(html: string): string {\n return html\n .replace(\n /<<([^&]*)>>/g,\n (_m, field: string) => `{{${field.trim()}}}`\n )\n .replace(/<<([^>]*)>>/g, (_m, field: string) => `{{${field.trim()}}}`);\n}\n\n/**\n * Returns true when an HTML string has no visible text content.\n * Note: This is a visibility check, not a sanitizer. It strips tags to inspect\n * remaining text — do NOT use this for XSS prevention.\n */\nexport { isHtmlEmpty } from '../../utils/html';\n","import * as React from 'react';\nimport {\n Bold,\n Italic,\n Underline,\n List,\n ListOrdered,\n AlignLeft,\n AlignCenter,\n AlignRight,\n Braces,\n Replace,\n Mic,\n MicOff,\n BookOpen,\n} from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { Button } from '../Button';\nimport { Separator } from '../Separator';\nimport {\n MacroLibrary,\n type Macro,\n type MacroGroup,\n type MacroLibraryProps,\n} from '../MacroLibrary';\nimport {\n Dropdown,\n DropdownItem,\n DropdownLabel,\n DropdownSeparator,\n} from '../Dropdown';\nimport {\n processDictation,\n convertAngleBracketsToMustache,\n isHtmlEmpty,\n} from './processDictation';\n\nexport interface RichTextVariable {\n /** Human-readable label shown in the variable menu. */\n label: string;\n /** The token displayed for the variable (e.g. `{{employee.name}}`). */\n value: string;\n /** Optional text inserted instead of `value` (e.g. an expanded group). */\n insertValue?: string;\n}\n\nexport interface RichTextVariableGroup {\n /** Group heading shown in the variable menu. */\n label: string;\n /** Variables belonging to the group. */\n variables: RichTextVariable[];\n}\n\nexport interface RichTextEditorProps {\n /** Current HTML value of the editor. */\n value: string;\n /** Called with the updated HTML whenever the content changes. */\n onChange: (value: string) => void;\n /** Placeholder shown when the editor is empty. */\n placeholder?: string;\n /** Additional class for the editor wrapper. */\n className?: string;\n /**\n * Variable groups for the \"Insert variable\" menu. When omitted the variable\n * menu and the `<< >>` → `{{ }}` convert button are hidden.\n */\n variableGroups?: RichTextVariableGroup[];\n /** Enable the speech-to-text dictation button. Defaults to true. */\n enableDictation?: boolean;\n /** Called when dictation cannot start (replaces native alerts). */\n onDictationError?: (message: string) => void;\n /** Disable editing and toolbar actions. */\n disabled?: boolean;\n /**\n * Sanitises HTML introduced by paste or drop before it reaches the editable\n * DOM. Without it, pasted markup is inserted as the browser provides it.\n */\n sanitizeHtml?: (html: string) => string;\n /**\n * Grouped macros for the optional macro addon. When omitted the editor is\n * unchanged. When provided, a \"Macros\" toolbar toggle docks a searchable\n * macro panel inside the editor; selecting a macro inserts its content at\n * the retained caret position. Typing a macro shortcut (e.g. `.b`)\n * followed by a space expands it in place, panel open or not.\n */\n macros?: MacroGroup[];\n /** Open the macro panel initially. Defaults to false. */\n defaultMacrosOpen?: boolean;\n /**\n * Overridable labels for the macro addon (i18n). Panel labels are\n * forwarded to the docked `MacroLibrary`; `macros` doubles as the toolbar\n * toggle text, and `showMacros`/`hideMacros` set the toggle's title.\n */\n macroLabels?: MacroLibraryProps['labels'] & {\n /** Toggle title while the panel is closed. Defaults to \"Show macros\". */\n showMacros?: string;\n /** Toggle title while the panel is open. Defaults to \"Hide macros\". */\n hideMacros?: string;\n };\n /** Forwarded to the macro panel's \"Save as macro\" action. */\n onCreateMacro?: () => void;\n /** Accessible label for the editable region. */\n 'aria-label'?: string;\n}\n\n// --- Minimal Web Speech API typings (absent from the standard DOM lib) ---\ninterface SpeechRecognitionAlternativeLike {\n transcript: string;\n}\ninterface SpeechRecognitionResultLike {\n isFinal: boolean;\n [index: number]: SpeechRecognitionAlternativeLike;\n}\ninterface SpeechRecognitionResultListLike {\n length: number;\n [index: number]: SpeechRecognitionResultLike;\n}\ninterface SpeechRecognitionEventLike {\n resultIndex: number;\n results: SpeechRecognitionResultListLike;\n}\ninterface SpeechRecognitionErrorEventLike {\n error: string;\n}\ninterface SpeechRecognitionLike {\n continuous: boolean;\n interimResults: boolean;\n lang: string;\n maxAlternatives: number;\n onstart: (() => void) | null;\n onresult: ((event: SpeechRecognitionEventLike) => void) | null;\n onerror: ((event: SpeechRecognitionErrorEventLike) => void) | null;\n onend: (() => void) | null;\n start: () => void;\n stop: () => void;\n}\ntype SpeechRecognitionCtor = new () => SpeechRecognitionLike;\ninterface SpeechWindow {\n SpeechRecognition?: SpeechRecognitionCtor;\n webkitSpeechRecognition?: SpeechRecognitionCtor;\n}\n\nfunction getSpeechRecognition(): SpeechRecognitionCtor | undefined {\n const w = window as unknown as SpeechWindow;\n return w.SpeechRecognition || w.webkitSpeechRecognition;\n}\n\n/** Elements that end a visible word, equivalent to whitespace. */\nconst BLOCK_BOUNDARY =\n /^(BR|DIV|P|LI|UL|OL|TABLE|TR|TD|TH|H[1-6]|BLOCKQUOTE|PRE|HR)$/;\n\n/**\n * Last non-empty text node rendered inside `node`, or 'boundary' when it\n * ends with a line break or block element.\n */\nfunction lastTextWithin(node: Node): Text | 'boundary' | null {\n if (node.nodeType === Node.TEXT_NODE) {\n return (node.textContent ?? '').length > 0 ? (node as Text) : null;\n }\n if (node.nodeType !== Node.ELEMENT_NODE) return null;\n if (BLOCK_BOUNDARY.test((node as HTMLElement).tagName)) return 'boundary';\n for (let child = node.lastChild; child; child = child.previousSibling) {\n const found = lastTextWithin(child);\n if (found) return found;\n }\n return null;\n}\n\n/**\n * Previous visible text node before `node`, looking across adjacent inline\n * elements (e.g. the \".\" in `.<b>c</b>` precedes the \"c\"). Returns null at\n * a block/line-break boundary or the editor root, where a word cannot\n * continue.\n */\nfunction previousVisibleText(node: Node, root: HTMLElement): Text | null {\n let current: Node = node;\n while (current !== root) {\n let sibling: Node | null = current.previousSibling;\n while (sibling) {\n const found = lastTextWithin(sibling);\n if (found === 'boundary') return null;\n if (found) return found;\n sibling = sibling.previousSibling;\n }\n const parent: Node | null = current.parentNode;\n if (!parent) return null;\n if (\n parent !== root &&\n parent.nodeType === Node.ELEMENT_NODE &&\n BLOCK_BOUNDARY.test((parent as HTMLElement).tagName)\n ) {\n return null;\n }\n current = parent;\n }\n return null;\n}\n\n/**\n * A presentational rich-text editor with formatting, template-variable\n * insertion and optional speech-to-text dictation. Content is supplied and\n * surfaced via `value`/`onChange` so it can be wired to any store. The variable\n * menu is data-agnostic — pass `variableGroups` to populate it.\n */\nconst RichTextEditor = React.forwardRef<HTMLDivElement, RichTextEditorProps>(\n (\n {\n value,\n onChange,\n placeholder,\n className,\n variableGroups,\n enableDictation = true,\n onDictationError,\n disabled = false,\n sanitizeHtml,\n macros,\n defaultMacrosOpen = false,\n macroLabels,\n onCreateMacro,\n 'aria-label': ariaLabel,\n },\n ref\n ) => {\n const editorRef = React.useRef<HTMLDivElement>(null);\n const [isListening, setIsListening] = React.useState(false);\n const [speechSupported, setSpeechSupported] = React.useState(false);\n const recognitionRef = React.useRef<SpeechRecognitionLike | null>(null);\n const isListeningRef = React.useRef(false);\n const shouldRestartRef = React.useRef(false);\n const [macrosOpen, setMacrosOpen] = React.useState(defaultMacrosOpen);\n // Last caret/selection inside the editable region, retained while the\n // macro panel has focus so insertion lands where the clinician left off.\n const savedRangeRef = React.useRef<Range | null>(null);\n const macroPanelId = React.useId();\n\n const hasVariables = Boolean(variableGroups && variableGroups.length > 0);\n const hasMacros = Boolean(macros);\n const isEmpty = isHtmlEmpty(value);\n\n React.useImperativeHandle(ref, () => editorRef.current as HTMLDivElement);\n\n React.useEffect(() => {\n setSpeechSupported(Boolean(getSpeechRecognition()));\n }, []);\n\n React.useEffect(() => {\n return () => {\n if (recognitionRef.current) {\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n recognitionRef.current.stop();\n }\n };\n }, []);\n\n React.useEffect(() => {\n if (editorRef.current && editorRef.current.innerHTML !== value) {\n editorRef.current.innerHTML = value;\n }\n }, [value]);\n\n const updateContent = () => {\n if (editorRef.current) onChange(editorRef.current.innerHTML);\n };\n\n // Pasted/dropped HTML otherwise lands in the live DOM unfiltered, where\n // hostile markup (position:fixed overlays, host CSS classes) is active.\n const insertSanitized = (html: string) => {\n if (!sanitizeHtml) return false;\n document.execCommand('insertHTML', false, sanitizeHtml(html));\n updateContent();\n return true;\n };\n const handlePaste = (e: React.ClipboardEvent) => {\n const html = e.clipboardData.getData('text/html');\n if (html && sanitizeHtml) {\n e.preventDefault();\n insertSanitized(html);\n }\n };\n const handleDrop = (e: React.DragEvent) => {\n const html = e.dataTransfer.getData('text/html');\n if (!html || !sanitizeHtml) return;\n e.preventDefault();\n const caret = (\n document as Document & {\n caretRangeFromPoint?: (\n x: number,\n y: number\n ) => ReturnType<Document['createRange']> | null;\n }\n ).caretRangeFromPoint?.(e.clientX, e.clientY);\n if (caret) {\n const selection = window.getSelection();\n selection?.removeAllRanges();\n selection?.addRange(caret);\n }\n editorRef.current?.focus();\n insertSanitized(html);\n };\n\n const execCommand = (command: string) => {\n if (disabled) return;\n document.execCommand(command, false);\n editorRef.current?.focus();\n updateContent();\n };\n\n const handleConvertToMustache = () => {\n if (disabled || !editorRef.current) return;\n editorRef.current.innerHTML = convertAngleBracketsToMustache(\n editorRef.current.innerHTML\n );\n updateContent();\n };\n\n const insertVariable = (variable: RichTextVariable) => {\n if (disabled || !editorRef.current) return;\n editorRef.current.focus();\n const textToInsert = variable.insertValue ?? variable.value;\n\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n range.deleteContents();\n if (textToInsert.includes('\\n')) {\n const fragment = document.createDocumentFragment();\n const lines = textToInsert.split('\\n');\n lines.forEach((line, index) => {\n fragment.appendChild(document.createTextNode(line));\n if (index < lines.length - 1) {\n fragment.appendChild(document.createElement('br'));\n }\n });\n range.insertNode(fragment);\n range.collapse(false);\n } else {\n const textNode = document.createTextNode(textToInsert);\n range.insertNode(textNode);\n range.setStartAfter(textNode);\n range.setEndAfter(textNode);\n }\n selection.removeAllRanges();\n selection.addRange(range);\n } else {\n editorRef.current.innerHTML += textToInsert.replace(/\\n/g, '<br>');\n }\n updateContent();\n };\n\n const reportError = (message: string) => {\n if (onDictationError) onDictationError(message);\n else if (typeof console !== 'undefined') console.warn(message);\n };\n\n /** Bookmark the selection whenever it lives inside the editable region. */\n const saveSelection = () => {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0 || !editorRef.current)\n return;\n const range = selection.getRangeAt(0);\n if (editorRef.current.contains(range.commonAncestorContainer)) {\n savedRangeRef.current = range.cloneRange();\n }\n };\n\n /** Focus the editor and restore the bookmarked selection if still valid. */\n const focusRestoringSelection = () => {\n if (!editorRef.current) return;\n editorRef.current.focus();\n const saved = savedRangeRef.current;\n const selection = window.getSelection();\n if (\n saved &&\n selection &&\n editorRef.current.contains(saved.commonAncestorContainer)\n ) {\n selection.removeAllRanges();\n selection.addRange(saved);\n }\n };\n\n const insertMacro = (macro: Macro) => {\n if (disabled || !editorRef.current) return;\n focusRestoringSelection();\n insertTextAtSelection(macro.content);\n };\n\n /**\n * Replace the current selection with plain text. execCommand participates\n * in the browser's native undo stack, so an insertion can be reverted\n * with a single undo.\n */\n const insertTextAtSelection = (content: string) => {\n let inserted = false;\n try {\n inserted = document.execCommand('insertText', false, content);\n } catch {\n inserted = false;\n }\n if (!inserted) {\n // Fallback (and jsdom path): manual range insertion. Content is\n // always inserted as text nodes, never parsed as HTML.\n const fragment = document.createDocumentFragment();\n const lines = content.split('\\n');\n lines.forEach((line, index) => {\n fragment.appendChild(document.createTextNode(line));\n if (index < lines.length - 1) {\n fragment.appendChild(document.createElement('br'));\n }\n });\n const sel = window.getSelection();\n if (sel && sel.rangeCount > 0) {\n const range = sel.getRangeAt(0);\n range.deleteContents();\n range.insertNode(fragment);\n range.collapse(false);\n sel.removeAllRanges();\n sel.addRange(range);\n } else if (editorRef.current) {\n editorRef.current.appendChild(fragment);\n }\n }\n saveSelection();\n updateContent();\n };\n\n /**\n * Expand a typed macro shortcut (dot phrase). When the word immediately\n * before the caret matches a macro shortcut and the user presses space,\n * the shortcut is replaced with the macro content in a single undoable\n * edit; the triggering space is consumed.\n */\n const expandTypedShortcut = (\n event: React.KeyboardEvent<HTMLDivElement>\n ) => {\n if (\n disabled ||\n event.key !== ' ' ||\n // Space during IME composition selects/converts a candidate; never\n // hijack it for macro expansion.\n event.nativeEvent.isComposing ||\n event.ctrlKey ||\n event.metaKey ||\n event.altKey ||\n !macros\n )\n return;\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0 || !selection.isCollapsed)\n return;\n const caret = selection.getRangeAt(0);\n const node = caret.startContainer;\n if (\n node.nodeType !== Node.TEXT_NODE ||\n !editorRef.current?.contains(node)\n )\n return;\n const typed = /(\\S+)$/.exec(\n (node.textContent ?? '').slice(0, caret.startOffset)\n );\n if (!typed) return;\n // Collect the complete visible token — a word may span adjacent\n // inline nodes (`.<b>c</b>` is \".c\"; `etc<strong>.c</strong>` is\n // \"etc.c\", which matches no shortcut and is left alone).\n let token = typed[1];\n let startNode: Node = node;\n let startOffset = caret.startOffset - typed[1].length;\n while (startOffset === 0) {\n const prev = previousVisibleText(startNode, editorRef.current);\n if (!prev) break;\n const text = prev.textContent ?? '';\n const continued = /(\\S+)$/.exec(text);\n if (!continued) break;\n token = continued[1] + token;\n startNode = prev;\n startOffset = text.length - continued[1].length;\n }\n const lowered = token.toLowerCase();\n const macro = macros\n .flatMap((group) => group.macros)\n .find((candidate) => candidate.shortcut?.toLowerCase() === lowered);\n if (!macro) return;\n\n event.preventDefault();\n const replaceRange = document.createRange();\n replaceRange.setStart(startNode, startOffset);\n replaceRange.setEnd(node, caret.startOffset);\n selection.removeAllRanges();\n selection.addRange(replaceRange);\n insertTextAtSelection(macro.content);\n };\n\n const toggleDictation = async () => {\n const SpeechRecognition = getSpeechRecognition();\n if (!SpeechRecognition) return;\n\n if (isListening && recognitionRef.current) {\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n recognitionRef.current.stop();\n setIsListening(false);\n return;\n }\n\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: true,\n });\n stream.getTracks().forEach((track) => track.stop());\n } catch {\n reportError(\n 'Microphone access is required for dictation. Please allow microphone access in your browser settings and try again.'\n );\n return;\n }\n\n const recognition = new SpeechRecognition();\n recognition.continuous = true;\n recognition.interimResults = true;\n recognition.lang = 'en-US';\n recognition.maxAlternatives = 1;\n\n recognition.onstart = () => {\n setIsListening(true);\n isListeningRef.current = true;\n shouldRestartRef.current = true;\n };\n\n recognition.onresult = (event) => {\n let finalTranscript = '';\n for (let i = event.resultIndex; i < event.results.length; i++) {\n const result = event.results[i];\n if (result.isFinal) finalTranscript += result[0].transcript;\n }\n\n if (finalTranscript && editorRef.current) {\n const processedText = processDictation(finalTranscript);\n editorRef.current.focus();\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n range.deleteContents();\n const textNode = document.createTextNode(processedText + ' ');\n range.insertNode(textNode);\n range.setStartAfter(textNode);\n range.setEndAfter(textNode);\n selection.removeAllRanges();\n selection.addRange(range);\n } else {\n editorRef.current.innerHTML += processedText + ' ';\n }\n updateContent();\n }\n };\n\n recognition.onerror = (event) => {\n if (event.error === 'no-speech' || event.error === 'aborted') return;\n if (event.error === 'not-allowed') {\n reportError(\n 'Microphone access was denied. Please allow microphone access in your browser settings and try again.'\n );\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n setIsListening(false);\n return;\n }\n if (event.error === 'network') return;\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n setIsListening(false);\n };\n\n recognition.onend = () => {\n if (shouldRestartRef.current && isListeningRef.current) {\n setTimeout(() => {\n if (shouldRestartRef.current && isListeningRef.current) {\n try {\n recognition.start();\n } catch {\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n setIsListening(false);\n }\n }\n }, 100);\n } else {\n setIsListening(false);\n }\n };\n\n recognitionRef.current = recognition;\n try {\n recognition.start();\n } catch {\n reportError('Failed to start speech recognition. Please try again.');\n }\n };\n\n const iconButtonClass = 'h-8 w-8 p-0';\n\n return (\n <div\n data-slot=\"rich-text-editor\"\n className={cn(\n 'border-border bg-background flex flex-col overflow-hidden rounded-lg border',\n className\n )}\n >\n <div\n data-slot=\"rich-text-editor-toolbar\"\n className=\"border-border bg-muted/30 sticky top-0 z-10 flex flex-wrap items-center gap-1 border-b p-2\"\n >\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('bold')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Bold\"\n title=\"Bold\"\n >\n <Bold className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('italic')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Italic\"\n title=\"Italic\"\n >\n <Italic className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('underline')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Underline\"\n title=\"Underline\"\n >\n <Underline className=\"h-4 w-4\" />\n </Button>\n\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('insertUnorderedList')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Bullet list\"\n title=\"Bullet list\"\n >\n <List className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('insertOrderedList')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Numbered list\"\n title=\"Numbered list\"\n >\n <ListOrdered className=\"h-4 w-4\" />\n </Button>\n\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('justifyLeft')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Align left\"\n title=\"Align left\"\n >\n <AlignLeft className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('justifyCenter')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Align center\"\n title=\"Align center\"\n >\n <AlignCenter className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('justifyRight')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Align right\"\n title=\"Align right\"\n >\n <AlignRight className=\"h-4 w-4\" />\n </Button>\n\n {hasVariables && (\n <>\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <Dropdown\n placement=\"bottom-start\"\n width={240}\n searchable\n searchPlaceholder=\"Search variables…\"\n searchAriaLabel=\"Search template variables\"\n disabled={disabled}\n trigger={\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 gap-1 px-2\"\n disabled={disabled}\n title=\"Insert variable\"\n >\n <Braces className=\"h-4 w-4\" />\n <span className=\"ms-1 text-xs\">Variables</span>\n </Button>\n }\n >\n {variableGroups!.map((group, groupIndex) => (\n <React.Fragment key={group.label}>\n {groupIndex > 0 && <DropdownSeparator />}\n <DropdownLabel>{group.label}</DropdownLabel>\n {group.variables.map((variable) => (\n <DropdownItem\n key={variable.value}\n onClick={() => insertVariable(variable)}\n >\n {variable.label}\n </DropdownItem>\n ))}\n </React.Fragment>\n ))}\n </Dropdown>\n\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleConvertToMustache}\n disabled={disabled}\n className=\"h-8 gap-1 px-2\"\n title=\"Convert <<field>> to {{field}}\"\n >\n <Replace className=\"h-4 w-4\" />\n <span className=\"ms-1 text-xs\">{'<< >> to {{ }}'}</span>\n </Button>\n </>\n )}\n\n {enableDictation && (\n <>\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <Button\n type=\"button\"\n variant={isListening ? 'danger' : 'ghost'}\n size=\"sm\"\n onClick={toggleDictation}\n disabled={disabled || !speechSupported}\n className={cn('h-8 gap-1 px-2', isListening && 'animate-pulse')}\n title={\n !speechSupported\n ? 'Speech recognition not supported in this browser'\n : isListening\n ? 'Stop dictation'\n : 'Start dictation'\n }\n >\n {isListening ? (\n <MicOff className=\"h-4 w-4\" />\n ) : (\n <Mic className=\"h-4 w-4\" />\n )}\n <span className=\"ms-1 text-xs\">\n {isListening ? 'Stop' : 'Dictate'}\n </span>\n </Button>\n </>\n )}\n\n {hasMacros && (\n <>\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setMacrosOpen((open) => !open)}\n disabled={disabled}\n className={cn('h-8 gap-1 px-2', macrosOpen && 'bg-muted')}\n aria-expanded={macrosOpen}\n aria-controls={macrosOpen ? macroPanelId : undefined}\n title={\n macrosOpen\n ? (macroLabels?.hideMacros ?? 'Hide macros')\n : (macroLabels?.showMacros ?? 'Show macros')\n }\n >\n <BookOpen className=\"h-4 w-4\" />\n <span className=\"ms-1 text-xs\">\n {macroLabels?.macros ?? 'Macros'}\n </span>\n </Button>\n </>\n )}\n </div>\n\n <div className=\"relative flex min-h-0 flex-1 flex-col\">\n <div\n className={cn(\n 'relative flex-1',\n hasMacros && macrosOpen && 'md:me-72'\n )}\n >\n {isEmpty && placeholder && (\n <div\n aria-hidden=\"true\"\n className=\"text-muted-foreground pointer-events-none absolute start-0 top-0 p-4\"\n >\n {placeholder}\n </div>\n )}\n <div\n ref={editorRef}\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-label={ariaLabel ?? placeholder}\n contentEditable={!disabled}\n tabIndex={disabled ? -1 : 0}\n onInput={updateContent}\n onPaste={handlePaste}\n onDrop={handleDrop}\n onBlur={hasMacros ? saveSelection : undefined}\n onKeyDown={hasMacros ? expandTypedShortcut : undefined}\n onKeyUp={hasMacros ? saveSelection : undefined}\n onMouseUp={hasMacros ? saveSelection : undefined}\n className={cn(\n 'min-h-[250px] overflow-y-auto p-4 focus:outline-none',\n 'prose prose-sm max-w-none',\n hasMacros && macrosOpen && 'md:min-h-[400px]',\n disabled &&\n 'bg-muted/20 cursor-not-allowed text-neutral-700 dark:text-neutral-300'\n )}\n suppressContentEditableWarning\n />\n </div>\n\n {hasMacros && macrosOpen && (\n <MacroLibrary\n id={macroPanelId}\n groups={macros!}\n onSelect={insertMacro}\n targetLabel={ariaLabel ?? placeholder}\n onClose={() => {\n setMacrosOpen(false);\n // Selecting text in the panel moves the document selection;\n // put the caret back where the user left it.\n focusRestoringSelection();\n }}\n onCreateMacro={onCreateMacro}\n labels={macroLabels}\n className=\"border-border max-h-72 border-t md:absolute md:inset-y-0 md:end-0 md:max-h-none md:w-72 md:border-s md:border-t-0\"\n />\n )}\n </div>\n </div>\n );\n }\n);\n\nRichTextEditor.displayName = 'RichTextEditor';\n\nexport { RichTextEditor };\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/MacroLibrary/MacroLibrary.tsx","../src/components/RichTextEditor/processDictation.ts","../src/components/RichTextEditor/RichTextEditor.tsx"],"names":["React","jsxs","jsx","cn","ChevronRight","MacroLibrary","Fragment","Button","X","Search","Input","History","BookOpen","ChevronDown","Plus","React2","isHtmlEmpty","Bold","Italic","Underline","Separator","List","ListOrdered","AlignLeft","AlignCenter","AlignRight","Dropdown","Braces","DropdownSeparator","DropdownLabel","DropdownItem","Replace","MicOff","Mic"],"mappings":"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","file":"chunk-7BA7ENN5.cjs","sourcesContent":["import * as React from 'react';\nimport {\n SearchIcon,\n HistoryIcon,\n BookOpenIcon,\n ChevronDownIcon,\n ChevronRightIcon,\n CloseIcon,\n PlusIcon,\n} from '../Icons';\nimport { cn } from '../../utils/cn';\nimport { Button } from '../Button';\nimport { Input } from '../Input';\n\nexport interface Macro {\n /** Stable identifier. */\n id: string;\n /** Human-readable name shown in the list. */\n label: string;\n /** Plain text inserted into the editor. `\\n` is preserved. */\n content: string;\n /** Optional shortcut identifier shown as a badge (e.g. `.b`). */\n shortcut?: string;\n /** Extra search terms that are not displayed. */\n keywords?: string[];\n}\n\nexport interface MacroGroup {\n /** Stable identifier. */\n id: string;\n /** Group heading (e.g. \"Default library\"). */\n label: string;\n /**\n * `previous` renders the group visually distinct from library macros\n * (history icon, muted header) so prior values are never mistaken for\n * predefined content. Defaults to `library`.\n */\n kind?: 'library' | 'previous';\n /** Macros belonging to the group. */\n macros: Macro[];\n}\n\nexport interface MacroLibraryProps {\n /** Grouped macros supplied by the application. */\n groups: MacroGroup[];\n /** Called with the chosen macro. The caller performs the insertion. */\n onSelect: (macro: Macro) => void;\n /** Id for the panel root (e.g. the target of a toggle's aria-controls). */\n id?: string;\n /**\n * Name of the insertion target shown in the header (e.g. the editor's\n * label), rendered as \"Insert into <target>\".\n */\n targetLabel?: string;\n /** When provided, renders a close button and enables Escape-to-close. */\n onClose?: () => void;\n /** When provided, renders a \"Save as macro\" action in the footer. */\n onCreateMacro?: () => void;\n /** Autofocus the search input on mount. Defaults to false. */\n autoFocusSearch?: boolean;\n /** Additional class for the panel root. */\n className?: string;\n /** Overridable labels for i18n. */\n labels?: Partial<typeof DEFAULT_LABELS>;\n}\n\nconst DEFAULT_LABELS = {\n insertInto: 'Insert into',\n macros: 'Macros',\n searchPlaceholder: 'Search macros…',\n searchLabel: 'Search macros',\n close: 'Close macros',\n createMacro: 'Save as macro',\n empty: 'No macros available',\n emptyHint: 'The application has not provided a macro list.',\n noResults: 'No macros match',\n clearSearch: 'Clear search',\n showFullContent: 'Show full content',\n hideFullContent: 'Hide full content',\n more: 'more',\n less: 'less',\n};\n\n/** Case-insensitive match across label, shortcut, keywords and content. */\nfunction matchesQuery(macro: Macro, query: string): boolean {\n const q = query.toLowerCase();\n return (\n macro.label.toLowerCase().includes(q) ||\n (macro.shortcut ?? '').toLowerCase().includes(q) ||\n (macro.keywords ?? []).some((k) => k.toLowerCase().includes(q)) ||\n macro.content.toLowerCase().includes(q)\n );\n}\n\n/** Query is a prefix of the macro's shortcut identifier. */\nfunction isShortcutHit(macro: Macro, query: string): boolean {\n return (\n query.length > 0 &&\n (macro.shortcut ?? '').toLowerCase().startsWith(query.toLowerCase())\n );\n}\n\n/** Shortcut-prefix matches rank before everything else. */\nfunction rankMacros(macros: Macro[], query: string): Macro[] {\n return [...macros].sort(\n (a, b) => Number(isShortcutHit(b, query)) - Number(isShortcutHit(a, query))\n );\n}\n\ninterface MacroRowProps {\n macro: Macro;\n isPrevious: boolean;\n isPeeked: boolean;\n peekId: string;\n labels: typeof DEFAULT_LABELS;\n onSelect: (macro: Macro) => void;\n onTogglePeek: () => void;\n onRowKeyDown: (event: React.KeyboardEvent) => void;\n}\n\n/**\n * One macro row. The two-line preview measures its own clamping so the\n * \"more\" toggle only appears when content is actually truncated.\n */\nfunction MacroRow({\n macro,\n isPrevious,\n isPeeked,\n peekId,\n labels,\n onSelect,\n onTogglePeek,\n onRowKeyDown,\n}: MacroRowProps) {\n const [truncated, setTruncated] = React.useState(false);\n const rowRef = React.useRef<HTMLButtonElement>(null);\n const lessRef = React.useRef<HTMLButtonElement>(null);\n // Toggling unmounts the activated control; move focus to its replacement\n // (\"less\" on expand, the row on collapse — the \"more\" chip is hidden until\n // hover/focus) so keyboard focus never drops to <body> and Escape keeps\n // closing the panel.\n const focusAfterToggle = React.useRef(false);\n React.useEffect(() => {\n if (!focusAfterToggle.current) return;\n focusAfterToggle.current = false;\n (isPeeked ? lessRef.current : rowRef.current)?.focus();\n }, [isPeeked]);\n const handleToggle = () => {\n focusAfterToggle.current = true;\n onTogglePeek();\n };\n // Remeasure on resize: docking/undocking or narrowing the panel can clamp\n // content without a React render.\n const previewObserver = React.useRef<ResizeObserver | null>(null);\n const measurePreview = (el: HTMLSpanElement | null) => {\n previewObserver.current?.disconnect();\n previewObserver.current = null;\n if (!el) return;\n const measure = () => setTruncated(el.scrollHeight > el.clientHeight);\n measure();\n if (typeof ResizeObserver !== 'undefined') {\n previewObserver.current = new ResizeObserver(measure);\n previewObserver.current.observe(el);\n }\n };\n return (\n <div\n data-slot=\"macro-library-item\"\n className=\"group/macro hover:bg-muted/60 relative rounded-md\"\n >\n <button\n type=\"button\"\n data-macro-row\n ref={rowRef}\n className=\"focus-visible:ring-ring text-foreground hover:text-primary flex w-full cursor-pointer flex-col items-stretch gap-0.5 rounded-md px-2 py-1.5 text-start focus-visible:ring-2 focus-visible:outline-none\"\n onClick={() => onSelect(macro)}\n onKeyDown={onRowKeyDown}\n >\n <span className=\"flex items-center gap-2\">\n {macro.shortcut && (\n <span\n // Shortcuts are typed sequences; keep them LTR in RTL locales.\n dir=\"ltr\"\n className={cn(\n 'border-border bg-background text-muted-foreground rounded border px-1 font-mono text-[11px]',\n isPrevious &&\n 'border-warning-300 bg-warning-50 text-warning-800 dark:border-warning-700 dark:bg-warning-950 dark:text-warning-300'\n )}\n >\n {macro.shortcut}\n </span>\n )}\n <span className=\"min-w-0 flex-1 truncate text-sm font-medium\">\n {macro.label}\n </span>\n </span>\n {!isPeeked && (\n <span\n ref={measurePreview}\n className=\"text-muted-foreground line-clamp-2 text-xs break-words\"\n >\n {macro.content}\n </span>\n )}\n </button>\n {isPeeked && (\n <div\n id={peekId}\n data-slot=\"macro-library-peek\"\n className=\"text-muted-foreground px-2 pb-1 text-xs break-words whitespace-pre-line\"\n >\n {macro.content}\n </div>\n )}\n {truncated && !isPeeked && (\n // Overlays the end of the clamped second line; revealed on row\n // hover or keyboard focus so short rows stay entirely clean. Always\n // visible on devices without hover (touch).\n <button\n type=\"button\"\n className=\"bg-muted text-muted-foreground hover:text-primary focus-visible:ring-ring invisible absolute end-1.5 bottom-1.5 flex cursor-pointer items-center rounded-sm px-1 text-[11px] leading-4 group-focus-within/macro:visible group-hover/macro:visible hover:underline focus-visible:ring-2 focus-visible:outline-none [@media(hover:none)]:visible\"\n aria-expanded={false}\n aria-label={`${labels.showFullContent}: ${macro.label}`}\n onClick={handleToggle}\n >\n {labels.more}\n <ChevronRightIcon\n aria-hidden=\"true\"\n className=\"h-3 w-3 rtl:-scale-x-100\"\n />\n </button>\n )}\n {isPeeked && (\n <span className=\"-mt-1 flex justify-end px-2 pb-1\">\n <button\n type=\"button\"\n ref={lessRef}\n className=\"text-muted-foreground hover:text-primary focus-visible:ring-ring cursor-pointer rounded text-[11px] hover:underline focus-visible:ring-2 focus-visible:outline-none\"\n aria-expanded\n aria-controls={peekId}\n aria-label={`${labels.hideFullContent}: ${macro.label}`}\n onClick={handleToggle}\n >\n {labels.less}\n </button>\n </span>\n )}\n </div>\n );\n}\n\n/**\n * A searchable, grouped macro browser designed to dock inside an editor's\n * chrome. Editor-agnostic: selecting a macro calls `onSelect` and the host\n * performs the insertion. Previous-value groups (`kind: 'previous'`) are\n * rendered distinctly from library macros. All rows and controls are real\n * buttons with roving arrow-key focus from the search input.\n */\nexport const MacroLibrary = React.forwardRef<HTMLDivElement, MacroLibraryProps>(\n function MacroLibrary(\n {\n groups,\n onSelect,\n id,\n targetLabel,\n onClose,\n onCreateMacro,\n autoFocusSearch = false,\n className,\n labels: labelOverrides,\n },\n ref\n ) {\n const labels = { ...DEFAULT_LABELS, ...labelOverrides };\n const [query, setQuery] = React.useState('');\n const [collapsed, setCollapsed] = React.useState<Record<string, boolean>>(\n {}\n );\n const [peeked, setPeeked] = React.useState<string | null>(null);\n const listRef = React.useRef<HTMLDivElement>(null);\n const searchRef = React.useRef<HTMLInputElement>(null);\n const panelId = React.useId();\n\n React.useEffect(() => {\n if (autoFocusSearch) searchRef.current?.focus();\n }, [autoFocusSearch]);\n\n const trimmed = query.trim();\n const searching = trimmed.length > 0;\n\n const visibleGroups = groups\n .map((group) => ({\n ...group,\n macros: searching\n ? rankMacros(\n group.macros.filter((m) => matchesQuery(m, trimmed)),\n trimmed\n )\n : group.macros,\n }))\n .filter((group) => group.macros.length > 0)\n // Groups containing shortcut-prefix hits rank first so \".c\" reaches\n // the macro with that shortcut before incidental content matches in\n // earlier groups; the stable sort keeps group context otherwise.\n .sort(\n (a, b) =>\n Number(b.macros.some((m) => isShortcutHit(m, trimmed))) -\n Number(a.macros.some((m) => isShortcutHit(m, trimmed)))\n );\n\n const hasMacros = groups.some((g) => g.macros.length > 0);\n const noResults = hasMacros && searching && visibleGroups.length === 0;\n\n /** Roving focus across visible macro-row buttons. */\n const moveFocus = (delta: 1 | -1) => {\n const rows = Array.from(\n listRef.current?.querySelectorAll<HTMLButtonElement>(\n '[data-macro-row]'\n ) ?? []\n );\n if (rows.length === 0) return;\n const index = rows.findIndex((row) => row === document.activeElement);\n if (index === -1) {\n rows[delta === 1 ? 0 : rows.length - 1].focus();\n return;\n }\n const next = index + delta;\n if (next < 0) {\n searchRef.current?.focus();\n return;\n }\n rows[Math.min(next, rows.length - 1)].focus();\n };\n\n const handlePanelKeyDown = (event: React.KeyboardEvent) => {\n // Escape during IME composition cancels the composition; never close.\n if (event.nativeEvent.isComposing) return;\n if (event.key === 'Escape' && onClose) {\n event.stopPropagation();\n onClose();\n }\n };\n\n const handleSearchKeyDown = (event: React.KeyboardEvent) => {\n // ArrowDown during IME composition navigates conversion candidates.\n if (event.nativeEvent.isComposing) return;\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n moveFocus(1);\n }\n };\n\n const handleRowKeyDown = (event: React.KeyboardEvent) => {\n if (event.nativeEvent.isComposing) return;\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n moveFocus(1);\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n moveFocus(-1);\n }\n };\n\n return (\n // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- keydown only delegates Escape-to-close from focusable children\n <div\n ref={ref}\n id={id}\n role=\"group\"\n aria-label={\n targetLabel ? `${labels.insertInto} ${targetLabel}` : labels.macros\n }\n data-slot=\"macro-library\"\n className={cn('bg-muted/20 flex min-h-0 flex-col', className)}\n onKeyDown={handlePanelKeyDown}\n >\n <div\n data-slot=\"macro-library-header\"\n className=\"border-border flex items-center justify-between gap-2 border-b px-3 py-2\"\n >\n <span className=\"text-muted-foreground min-w-0 truncate text-xs\">\n {targetLabel ? (\n <>\n {labels.insertInto}{' '}\n <span className=\"text-foreground font-semibold\">\n {targetLabel}\n </span>\n </>\n ) : (\n labels.macros\n )}\n </span>\n {onClose && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-6 w-6 shrink-0 p-0\"\n onClick={onClose}\n aria-label={labels.close}\n >\n <CloseIcon className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n </div>\n\n {hasMacros ? (\n <>\n <div className=\"px-3 pt-2\">\n <div className=\"relative\">\n <SearchIcon\n aria-hidden=\"true\"\n className=\"text-muted-foreground pointer-events-none absolute start-2.5 top-1/2 z-10 h-3.5 w-3.5 -translate-y-1/2\"\n />\n <Input\n ref={searchRef}\n label={labels.searchLabel}\n hideLabel\n size=\"sm\"\n type=\"search\"\n placeholder={labels.searchPlaceholder}\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={handleSearchKeyDown}\n className=\"ps-8\"\n aria-controls={`${panelId}-list`}\n />\n </div>\n </div>\n\n {/* Persistent polite region so a failed search is announced. */}\n <div role=\"status\" className=\"sr-only\">\n {noResults ? `${labels.noResults} “${trimmed}”` : ''}\n </div>\n\n <div\n ref={listRef}\n id={`${panelId}-list`}\n data-slot=\"macro-library-list\"\n className=\"min-h-0 flex-1 overflow-y-auto p-1.5\"\n >\n {noResults && (\n <div className=\"text-muted-foreground px-2 py-8 text-center text-sm\">\n <p>\n {labels.noResults} “{trimmed}”\n </p>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"mt-2\"\n onClick={() => {\n setQuery('');\n searchRef.current?.focus();\n }}\n >\n {labels.clearSearch}\n </Button>\n </div>\n )}\n\n {visibleGroups.map((group) => {\n const isPrevious = group.kind === 'previous';\n // Strict check: ids like \"constructor\" must not read\n // inherited Object.prototype members as collapsed state.\n const isCollapsed = !searching && collapsed[group.id] === true;\n const GroupIcon = isPrevious ? HistoryIcon : BookOpenIcon;\n return (\n <div\n key={group.id}\n data-slot=\"macro-library-group\"\n data-kind={group.kind ?? 'library'}\n >\n <button\n type=\"button\"\n className={cn(\n 'text-muted-foreground hover:text-foreground flex w-full items-center gap-1.5 rounded px-2 pt-2.5 pb-1 text-start text-[11px] font-semibold tracking-wide uppercase',\n isPrevious && 'text-warning-700 dark:text-warning-400'\n )}\n aria-expanded={!isCollapsed}\n disabled={searching}\n onClick={() =>\n setCollapsed((prev) => ({\n ...prev,\n [group.id]: prev[group.id] !== true,\n }))\n }\n >\n <GroupIcon aria-hidden=\"true\" className=\"h-3 w-3\" />\n <span className=\"min-w-0 flex-1 truncate\">\n {group.label}\n </span>\n {!searching &&\n (isCollapsed ? (\n <ChevronRightIcon\n aria-hidden=\"true\"\n className=\"h-3 w-3\"\n />\n ) : (\n <ChevronDownIcon\n aria-hidden=\"true\"\n className=\"h-3 w-3\"\n />\n ))}\n </button>\n\n {!isCollapsed &&\n group.macros.map((macro) => {\n const isPeeked = peeked === macro.id;\n return (\n <MacroRow\n key={macro.id}\n macro={macro}\n isPrevious={isPrevious}\n isPeeked={isPeeked}\n peekId={`${panelId}-peek-${macro.id}`}\n labels={labels}\n onSelect={onSelect}\n onTogglePeek={() =>\n setPeeked(isPeeked ? null : macro.id)\n }\n onRowKeyDown={handleRowKeyDown}\n />\n );\n })}\n </div>\n );\n })}\n </div>\n </>\n ) : (\n <div className=\"text-muted-foreground flex flex-1 flex-col items-center justify-center gap-1 px-4 py-10 text-center text-sm\">\n <BookOpenIcon aria-hidden=\"true\" className=\"mb-1 h-5 w-5\" />\n <p className=\"text-foreground font-medium\">{labels.empty}</p>\n <p className=\"text-xs\">{labels.emptyHint}</p>\n </div>\n )}\n\n {onCreateMacro && (\n <div\n data-slot=\"macro-library-footer\"\n className=\"border-border border-t px-2 py-1.5\"\n >\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"w-full justify-start gap-1.5\"\n onClick={onCreateMacro}\n >\n <PlusIcon aria-hidden=\"true\" className=\"h-3.5 w-3.5\" />\n {labels.createMacro}\n </Button>\n </div>\n )}\n </div>\n );\n }\n);\n","/**\n * Converts spoken punctuation words (e.g. \"period\", \"comma\") into the\n * corresponding characters, using lightweight context heuristics so that words\n * like \"time period\" or \"the colon\" are left intact. Pure and side-effect free\n * so it can be unit tested independently of the editor.\n */\nexport function processDictation(text: string): string {\n let result = text;\n\n // \"period\" as a word vs. as punctuation.\n result = result.replace(\n /\\b(the|a|this|that|each|every|same|time|grace|trial|waiting|probationary|pay|billing|accounting)\\s+period\\b/gi,\n '$1 period'\n );\n result = result.replace(\n /\\bperiod\\s+(of|in|for|from|to|during|between|after|before|when|where|is|was|will|has|had)\\b/gi,\n 'period $1'\n );\n result = result.replace(/\\s+period(\\s*$)/gi, '.$1');\n result = result.replace(/\\s+period\\s+(?=[A-Z])/g, '. ');\n\n // \"comma\"\n result = result.replace(/\\bcomma\\s+(separated|delimited)/gi, 'comma $1');\n result = result.replace(/\\s+comma\\b/gi, ',');\n\n // \"colon\"\n result = result.replace(\n /\\b(the|a|my|your|his|her|their|semicolon|ascending|descending|transverse|sigmoid)\\s+colon\\b/gi,\n '$1 colon'\n );\n result = result.replace(\n /\\bcolon\\s+(cancer|surgery|health|polyp|scope|oscopy)/gi,\n 'colon $1'\n );\n result = result.replace(/\\s+colon\\b/gi, ':');\n\n // \"dash\"\n result = result.replace(\n /\\b(yard|meter|hundred|mad|quick|wild)\\s+dash\\b/gi,\n '$1 dash'\n );\n result = result.replace(/\\bdash\\s+(to|for|of)\\b/gi, 'dash $1');\n result = result.replace(/\\s+dash\\b/gi, ' -');\n\n const simplePunctuation: Record<string, string> = {\n ' full stop': '.',\n ' question mark': '?',\n ' exclamation point': '!',\n ' exclamation mark': '!',\n ' semicolon': ';',\n ' semi colon': ';',\n ' hyphen': '-',\n ' open parenthesis': ' (',\n ' close parenthesis': ')',\n ' open bracket': ' [',\n ' close bracket': ']',\n ' open quote': ' \"',\n ' close quote': '\"',\n ' quote': '\"',\n ' apostrophe': \"'\",\n ' new line': '\\n',\n ' newline': '\\n',\n ' new paragraph': '\\n\\n',\n ' tab': '\\t',\n };\n\n for (const [spoken, punctuation] of Object.entries(simplePunctuation)) {\n const regex = new RegExp(spoken, 'gi');\n result = result.replace(regex, punctuation);\n }\n\n // Capitalize after sentence-ending punctuation.\n result = result.replace(\n /([.!?])\\s+([a-z])/g,\n (_match, punct: string, letter: string) =>\n `${punct} ${letter.toUpperCase()}`\n );\n\n return result;\n}\n\n/**\n * Converts `<<field>>` (and the HTML-encoded `<<field>>`) syntax\n * into mustache `{{field}}` syntax. Pure helper operating on an HTML string.\n */\nexport function convertAngleBracketsToMustache(html: string): string {\n return html\n .replace(\n /<<([^&]*)>>/g,\n (_m, field: string) => `{{${field.trim()}}}`\n )\n .replace(/<<([^>]*)>>/g, (_m, field: string) => `{{${field.trim()}}}`);\n}\n\n/**\n * Returns true when an HTML string has no visible text content.\n * Note: This is a visibility check, not a sanitizer. It strips tags to inspect\n * remaining text — do NOT use this for XSS prevention.\n */\nexport { isHtmlEmpty } from '../../utils/html';\n","import * as React from 'react';\nimport {\n Bold,\n Italic,\n Underline,\n List,\n ListOrdered,\n AlignLeft,\n AlignCenter,\n AlignRight,\n Braces,\n Replace,\n Mic,\n MicOff,\n BookOpen,\n} from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { Button } from '../Button';\nimport { Separator } from '../Separator';\nimport {\n MacroLibrary,\n type Macro,\n type MacroGroup,\n type MacroLibraryProps,\n} from '../MacroLibrary';\nimport {\n Dropdown,\n DropdownItem,\n DropdownLabel,\n DropdownSeparator,\n} from '../Dropdown';\nimport {\n processDictation,\n convertAngleBracketsToMustache,\n isHtmlEmpty,\n} from './processDictation';\n\nexport interface RichTextVariable {\n /** Human-readable label shown in the variable menu. */\n label: string;\n /** The token displayed for the variable (e.g. `{{employee.name}}`). */\n value: string;\n /** Optional text inserted instead of `value` (e.g. an expanded group). */\n insertValue?: string;\n}\n\nexport interface RichTextVariableGroup {\n /** Group heading shown in the variable menu. */\n label: string;\n /** Variables belonging to the group. */\n variables: RichTextVariable[];\n}\n\nexport interface RichTextEditorProps {\n /** Current HTML value of the editor. */\n value: string;\n /** Called with the updated HTML whenever the content changes. */\n onChange: (value: string) => void;\n /** Placeholder shown when the editor is empty. */\n placeholder?: string;\n /** Additional class for the editor wrapper. */\n className?: string;\n /**\n * Variable groups for the \"Insert variable\" menu. When omitted the variable\n * menu and the `<< >>` → `{{ }}` convert button are hidden.\n */\n variableGroups?: RichTextVariableGroup[];\n /** Enable the speech-to-text dictation button. Defaults to true. */\n enableDictation?: boolean;\n /** Called when dictation cannot start (replaces native alerts). */\n onDictationError?: (message: string) => void;\n /** Disable editing and toolbar actions. */\n disabled?: boolean;\n /**\n * Sanitises HTML introduced by paste or drop before it reaches the editable\n * DOM. Without it, pasted markup is inserted as the browser provides it.\n */\n sanitizeHtml?: (html: string) => string;\n /**\n * Grouped macros for the optional macro addon. When omitted the editor is\n * unchanged. When provided, a \"Macros\" toolbar toggle docks a searchable\n * macro panel inside the editor; selecting a macro inserts its content at\n * the retained caret position. Typing a macro shortcut (e.g. `.b`)\n * followed by a space expands it in place, panel open or not.\n */\n macros?: MacroGroup[];\n /** Open the macro panel initially. Defaults to false. */\n defaultMacrosOpen?: boolean;\n /**\n * Overridable labels for the macro addon (i18n). Panel labels are\n * forwarded to the docked `MacroLibrary`; `macros` doubles as the toolbar\n * toggle text, and `showMacros`/`hideMacros` set the toggle's title.\n */\n macroLabels?: MacroLibraryProps['labels'] & {\n /** Toggle title while the panel is closed. Defaults to \"Show macros\". */\n showMacros?: string;\n /** Toggle title while the panel is open. Defaults to \"Hide macros\". */\n hideMacros?: string;\n };\n /** Forwarded to the macro panel's \"Save as macro\" action. */\n onCreateMacro?: () => void;\n /** Accessible label for the editable region. */\n 'aria-label'?: string;\n}\n\n// --- Minimal Web Speech API typings (absent from the standard DOM lib) ---\ninterface SpeechRecognitionAlternativeLike {\n transcript: string;\n}\ninterface SpeechRecognitionResultLike {\n isFinal: boolean;\n [index: number]: SpeechRecognitionAlternativeLike;\n}\ninterface SpeechRecognitionResultListLike {\n length: number;\n [index: number]: SpeechRecognitionResultLike;\n}\ninterface SpeechRecognitionEventLike {\n resultIndex: number;\n results: SpeechRecognitionResultListLike;\n}\ninterface SpeechRecognitionErrorEventLike {\n error: string;\n}\ninterface SpeechRecognitionLike {\n continuous: boolean;\n interimResults: boolean;\n lang: string;\n maxAlternatives: number;\n onstart: (() => void) | null;\n onresult: ((event: SpeechRecognitionEventLike) => void) | null;\n onerror: ((event: SpeechRecognitionErrorEventLike) => void) | null;\n onend: (() => void) | null;\n start: () => void;\n stop: () => void;\n}\ntype SpeechRecognitionCtor = new () => SpeechRecognitionLike;\ninterface SpeechWindow {\n SpeechRecognition?: SpeechRecognitionCtor;\n webkitSpeechRecognition?: SpeechRecognitionCtor;\n}\n\nfunction getSpeechRecognition(): SpeechRecognitionCtor | undefined {\n const w = window as unknown as SpeechWindow;\n return w.SpeechRecognition || w.webkitSpeechRecognition;\n}\n\n/** Elements that end a visible word, equivalent to whitespace. */\nconst BLOCK_BOUNDARY =\n /^(BR|DIV|P|LI|UL|OL|TABLE|TR|TD|TH|H[1-6]|BLOCKQUOTE|PRE|HR)$/;\n\n/**\n * Last non-empty text node rendered inside `node`, or 'boundary' when it\n * ends with a line break or block element.\n */\nfunction lastTextWithin(node: Node): Text | 'boundary' | null {\n if (node.nodeType === Node.TEXT_NODE) {\n return (node.textContent ?? '').length > 0 ? (node as Text) : null;\n }\n if (node.nodeType !== Node.ELEMENT_NODE) return null;\n if (BLOCK_BOUNDARY.test((node as HTMLElement).tagName)) return 'boundary';\n for (let child = node.lastChild; child; child = child.previousSibling) {\n const found = lastTextWithin(child);\n if (found) return found;\n }\n return null;\n}\n\n/**\n * Previous visible text node before `node`, looking across adjacent inline\n * elements (e.g. the \".\" in `.<b>c</b>` precedes the \"c\"). Returns null at\n * a block/line-break boundary or the editor root, where a word cannot\n * continue.\n */\nfunction previousVisibleText(node: Node, root: HTMLElement): Text | null {\n let current: Node = node;\n while (current !== root) {\n let sibling: Node | null = current.previousSibling;\n while (sibling) {\n const found = lastTextWithin(sibling);\n if (found === 'boundary') return null;\n if (found) return found;\n sibling = sibling.previousSibling;\n }\n const parent: Node | null = current.parentNode;\n if (!parent) return null;\n if (\n parent !== root &&\n parent.nodeType === Node.ELEMENT_NODE &&\n BLOCK_BOUNDARY.test((parent as HTMLElement).tagName)\n ) {\n return null;\n }\n current = parent;\n }\n return null;\n}\n\n/**\n * A presentational rich-text editor with formatting, template-variable\n * insertion and optional speech-to-text dictation. Content is supplied and\n * surfaced via `value`/`onChange` so it can be wired to any store. The variable\n * menu is data-agnostic — pass `variableGroups` to populate it.\n */\nconst RichTextEditor = React.forwardRef<HTMLDivElement, RichTextEditorProps>(\n (\n {\n value,\n onChange,\n placeholder,\n className,\n variableGroups,\n enableDictation = true,\n onDictationError,\n disabled = false,\n sanitizeHtml,\n macros,\n defaultMacrosOpen = false,\n macroLabels,\n onCreateMacro,\n 'aria-label': ariaLabel,\n },\n ref\n ) => {\n const editorRef = React.useRef<HTMLDivElement>(null);\n const [isListening, setIsListening] = React.useState(false);\n const [speechSupported, setSpeechSupported] = React.useState(false);\n const recognitionRef = React.useRef<SpeechRecognitionLike | null>(null);\n const isListeningRef = React.useRef(false);\n const shouldRestartRef = React.useRef(false);\n const [macrosOpen, setMacrosOpen] = React.useState(defaultMacrosOpen);\n // Last caret/selection inside the editable region, retained while the\n // macro panel has focus so insertion lands where the clinician left off.\n const savedRangeRef = React.useRef<Range | null>(null);\n const macroPanelId = React.useId();\n\n const hasVariables = Boolean(variableGroups && variableGroups.length > 0);\n const hasMacros = Boolean(macros);\n const isEmpty = isHtmlEmpty(value);\n\n React.useImperativeHandle(ref, () => editorRef.current as HTMLDivElement);\n\n React.useEffect(() => {\n setSpeechSupported(Boolean(getSpeechRecognition()));\n }, []);\n\n React.useEffect(() => {\n return () => {\n if (recognitionRef.current) {\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n recognitionRef.current.stop();\n }\n };\n }, []);\n\n React.useEffect(() => {\n if (editorRef.current && editorRef.current.innerHTML !== value) {\n editorRef.current.innerHTML = value;\n }\n }, [value]);\n\n const updateContent = () => {\n if (editorRef.current) onChange(editorRef.current.innerHTML);\n };\n\n // Pasted/dropped HTML otherwise lands in the live DOM unfiltered, where\n // hostile markup (position:fixed overlays, host CSS classes) is active.\n const insertSanitized = (html: string) => {\n if (!sanitizeHtml) return false;\n document.execCommand('insertHTML', false, sanitizeHtml(html));\n updateContent();\n return true;\n };\n const handlePaste = (e: React.ClipboardEvent) => {\n const html = e.clipboardData.getData('text/html');\n if (html && sanitizeHtml) {\n e.preventDefault();\n insertSanitized(html);\n }\n };\n const handleDrop = (e: React.DragEvent) => {\n const html = e.dataTransfer.getData('text/html');\n if (!html || !sanitizeHtml) return;\n e.preventDefault();\n const caret = (\n document as Document & {\n caretRangeFromPoint?: (\n x: number,\n y: number\n ) => ReturnType<Document['createRange']> | null;\n }\n ).caretRangeFromPoint?.(e.clientX, e.clientY);\n if (caret) {\n const selection = window.getSelection();\n selection?.removeAllRanges();\n selection?.addRange(caret);\n }\n editorRef.current?.focus();\n insertSanitized(html);\n };\n\n const execCommand = (command: string) => {\n if (disabled) return;\n document.execCommand(command, false);\n editorRef.current?.focus();\n updateContent();\n };\n\n const handleConvertToMustache = () => {\n if (disabled || !editorRef.current) return;\n editorRef.current.innerHTML = convertAngleBracketsToMustache(\n editorRef.current.innerHTML\n );\n updateContent();\n };\n\n const insertVariable = (variable: RichTextVariable) => {\n if (disabled || !editorRef.current) return;\n editorRef.current.focus();\n const textToInsert = variable.insertValue ?? variable.value;\n\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n range.deleteContents();\n if (textToInsert.includes('\\n')) {\n const fragment = document.createDocumentFragment();\n const lines = textToInsert.split('\\n');\n lines.forEach((line, index) => {\n fragment.appendChild(document.createTextNode(line));\n if (index < lines.length - 1) {\n fragment.appendChild(document.createElement('br'));\n }\n });\n range.insertNode(fragment);\n range.collapse(false);\n } else {\n const textNode = document.createTextNode(textToInsert);\n range.insertNode(textNode);\n range.setStartAfter(textNode);\n range.setEndAfter(textNode);\n }\n selection.removeAllRanges();\n selection.addRange(range);\n } else {\n editorRef.current.innerHTML += textToInsert.replace(/\\n/g, '<br>');\n }\n updateContent();\n };\n\n const reportError = (message: string) => {\n if (onDictationError) onDictationError(message);\n else if (typeof console !== 'undefined') console.warn(message);\n };\n\n /** Bookmark the selection whenever it lives inside the editable region. */\n const saveSelection = () => {\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0 || !editorRef.current)\n return;\n const range = selection.getRangeAt(0);\n if (editorRef.current.contains(range.commonAncestorContainer)) {\n savedRangeRef.current = range.cloneRange();\n }\n };\n\n /** Focus the editor and restore the bookmarked selection if still valid. */\n const focusRestoringSelection = () => {\n if (!editorRef.current) return;\n editorRef.current.focus();\n const saved = savedRangeRef.current;\n const selection = window.getSelection();\n if (\n saved &&\n selection &&\n editorRef.current.contains(saved.commonAncestorContainer)\n ) {\n selection.removeAllRanges();\n selection.addRange(saved);\n }\n };\n\n const insertMacro = (macro: Macro) => {\n if (disabled || !editorRef.current) return;\n focusRestoringSelection();\n insertTextAtSelection(macro.content);\n };\n\n /**\n * Replace the current selection with plain text. execCommand participates\n * in the browser's native undo stack, so an insertion can be reverted\n * with a single undo.\n */\n const insertTextAtSelection = (content: string) => {\n let inserted = false;\n try {\n inserted = document.execCommand('insertText', false, content);\n } catch {\n inserted = false;\n }\n if (!inserted) {\n // Fallback (and jsdom path): manual range insertion. Content is\n // always inserted as text nodes, never parsed as HTML.\n const fragment = document.createDocumentFragment();\n const lines = content.split('\\n');\n lines.forEach((line, index) => {\n fragment.appendChild(document.createTextNode(line));\n if (index < lines.length - 1) {\n fragment.appendChild(document.createElement('br'));\n }\n });\n const sel = window.getSelection();\n if (sel && sel.rangeCount > 0) {\n const range = sel.getRangeAt(0);\n range.deleteContents();\n range.insertNode(fragment);\n range.collapse(false);\n sel.removeAllRanges();\n sel.addRange(range);\n } else if (editorRef.current) {\n editorRef.current.appendChild(fragment);\n }\n }\n saveSelection();\n updateContent();\n };\n\n /**\n * Expand a typed macro shortcut (dot phrase). When the word immediately\n * before the caret matches a macro shortcut and the user presses space,\n * the shortcut is replaced with the macro content in a single undoable\n * edit; the triggering space is consumed.\n */\n const expandTypedShortcut = (\n event: React.KeyboardEvent<HTMLDivElement>\n ) => {\n if (\n disabled ||\n event.key !== ' ' ||\n // Space during IME composition selects/converts a candidate; never\n // hijack it for macro expansion.\n event.nativeEvent.isComposing ||\n event.ctrlKey ||\n event.metaKey ||\n event.altKey ||\n !macros\n )\n return;\n const selection = window.getSelection();\n if (!selection || selection.rangeCount === 0 || !selection.isCollapsed)\n return;\n const caret = selection.getRangeAt(0);\n const node = caret.startContainer;\n if (\n node.nodeType !== Node.TEXT_NODE ||\n !editorRef.current?.contains(node)\n )\n return;\n const typed = /(\\S+)$/.exec(\n (node.textContent ?? '').slice(0, caret.startOffset)\n );\n if (!typed) return;\n // Collect the complete visible token — a word may span adjacent\n // inline nodes (`.<b>c</b>` is \".c\"; `etc<strong>.c</strong>` is\n // \"etc.c\", which matches no shortcut and is left alone).\n let token = typed[1];\n let startNode: Node = node;\n let startOffset = caret.startOffset - typed[1].length;\n while (startOffset === 0) {\n const prev = previousVisibleText(startNode, editorRef.current);\n if (!prev) break;\n const text = prev.textContent ?? '';\n const continued = /(\\S+)$/.exec(text);\n if (!continued) break;\n token = continued[1] + token;\n startNode = prev;\n startOffset = text.length - continued[1].length;\n }\n const lowered = token.toLowerCase();\n const macro = macros\n .flatMap((group) => group.macros)\n .find((candidate) => candidate.shortcut?.toLowerCase() === lowered);\n if (!macro) return;\n\n event.preventDefault();\n const replaceRange = document.createRange();\n replaceRange.setStart(startNode, startOffset);\n replaceRange.setEnd(node, caret.startOffset);\n selection.removeAllRanges();\n selection.addRange(replaceRange);\n insertTextAtSelection(macro.content);\n };\n\n const toggleDictation = async () => {\n const SpeechRecognition = getSpeechRecognition();\n if (!SpeechRecognition) return;\n\n if (isListening && recognitionRef.current) {\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n recognitionRef.current.stop();\n setIsListening(false);\n return;\n }\n\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: true,\n });\n stream.getTracks().forEach((track) => track.stop());\n } catch {\n reportError(\n 'Microphone access is required for dictation. Please allow microphone access in your browser settings and try again.'\n );\n return;\n }\n\n const recognition = new SpeechRecognition();\n recognition.continuous = true;\n recognition.interimResults = true;\n recognition.lang = 'en-US';\n recognition.maxAlternatives = 1;\n\n recognition.onstart = () => {\n setIsListening(true);\n isListeningRef.current = true;\n shouldRestartRef.current = true;\n };\n\n recognition.onresult = (event) => {\n let finalTranscript = '';\n for (let i = event.resultIndex; i < event.results.length; i++) {\n const result = event.results[i];\n if (result.isFinal) finalTranscript += result[0].transcript;\n }\n\n if (finalTranscript && editorRef.current) {\n const processedText = processDictation(finalTranscript);\n editorRef.current.focus();\n const selection = window.getSelection();\n if (selection && selection.rangeCount > 0) {\n const range = selection.getRangeAt(0);\n range.deleteContents();\n const textNode = document.createTextNode(processedText + ' ');\n range.insertNode(textNode);\n range.setStartAfter(textNode);\n range.setEndAfter(textNode);\n selection.removeAllRanges();\n selection.addRange(range);\n } else {\n editorRef.current.innerHTML += processedText + ' ';\n }\n updateContent();\n }\n };\n\n recognition.onerror = (event) => {\n if (event.error === 'no-speech' || event.error === 'aborted') return;\n if (event.error === 'not-allowed') {\n reportError(\n 'Microphone access was denied. Please allow microphone access in your browser settings and try again.'\n );\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n setIsListening(false);\n return;\n }\n if (event.error === 'network') return;\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n setIsListening(false);\n };\n\n recognition.onend = () => {\n if (shouldRestartRef.current && isListeningRef.current) {\n setTimeout(() => {\n if (shouldRestartRef.current && isListeningRef.current) {\n try {\n recognition.start();\n } catch {\n shouldRestartRef.current = false;\n isListeningRef.current = false;\n setIsListening(false);\n }\n }\n }, 100);\n } else {\n setIsListening(false);\n }\n };\n\n recognitionRef.current = recognition;\n try {\n recognition.start();\n } catch {\n reportError('Failed to start speech recognition. Please try again.');\n }\n };\n\n const iconButtonClass = 'h-8 w-8 p-0';\n\n return (\n <div\n data-slot=\"rich-text-editor\"\n className={cn(\n 'border-border bg-background flex flex-col overflow-hidden rounded-lg border',\n className\n )}\n >\n <div\n data-slot=\"rich-text-editor-toolbar\"\n className=\"border-border bg-muted/30 sticky top-0 z-10 flex flex-wrap items-center gap-1 border-b p-2\"\n >\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('bold')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Bold\"\n title=\"Bold\"\n >\n <Bold className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('italic')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Italic\"\n title=\"Italic\"\n >\n <Italic className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('underline')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Underline\"\n title=\"Underline\"\n >\n <Underline className=\"h-4 w-4\" />\n </Button>\n\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('insertUnorderedList')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Bullet list\"\n title=\"Bullet list\"\n >\n <List className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('insertOrderedList')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Numbered list\"\n title=\"Numbered list\"\n >\n <ListOrdered className=\"h-4 w-4\" />\n </Button>\n\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('justifyLeft')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Align left\"\n title=\"Align left\"\n >\n <AlignLeft className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('justifyCenter')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Align center\"\n title=\"Align center\"\n >\n <AlignCenter className=\"h-4 w-4\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => execCommand('justifyRight')}\n disabled={disabled}\n className={iconButtonClass}\n aria-label=\"Align right\"\n title=\"Align right\"\n >\n <AlignRight className=\"h-4 w-4\" />\n </Button>\n\n {hasVariables && (\n <>\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <Dropdown\n placement=\"bottom-start\"\n width={240}\n searchable\n searchPlaceholder=\"Search variables…\"\n searchAriaLabel=\"Search template variables\"\n disabled={disabled}\n trigger={\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 gap-1 px-2\"\n disabled={disabled}\n title=\"Insert variable\"\n >\n <Braces className=\"h-4 w-4\" />\n <span className=\"ms-1 text-xs\">Variables</span>\n </Button>\n }\n >\n {variableGroups!.map((group, groupIndex) => (\n <React.Fragment key={group.label}>\n {groupIndex > 0 && <DropdownSeparator />}\n <DropdownLabel>{group.label}</DropdownLabel>\n {group.variables.map((variable) => (\n <DropdownItem\n key={variable.value}\n onClick={() => insertVariable(variable)}\n >\n {variable.label}\n </DropdownItem>\n ))}\n </React.Fragment>\n ))}\n </Dropdown>\n\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleConvertToMustache}\n disabled={disabled}\n className=\"h-8 gap-1 px-2\"\n title=\"Convert <<field>> to {{field}}\"\n >\n <Replace className=\"h-4 w-4\" />\n <span className=\"ms-1 text-xs\">{'<< >> to {{ }}'}</span>\n </Button>\n </>\n )}\n\n {enableDictation && (\n <>\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <Button\n type=\"button\"\n variant={isListening ? 'danger' : 'ghost'}\n size=\"sm\"\n onClick={toggleDictation}\n disabled={disabled || !speechSupported}\n className={cn('h-8 gap-1 px-2', isListening && 'animate-pulse')}\n title={\n !speechSupported\n ? 'Speech recognition not supported in this browser'\n : isListening\n ? 'Stop dictation'\n : 'Start dictation'\n }\n >\n {isListening ? (\n <MicOff className=\"h-4 w-4\" />\n ) : (\n <Mic className=\"h-4 w-4\" />\n )}\n <span className=\"ms-1 text-xs\">\n {isListening ? 'Stop' : 'Dictate'}\n </span>\n </Button>\n </>\n )}\n\n {hasMacros && (\n <>\n <Separator orientation=\"vertical\" className=\"mx-1 h-6\" />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setMacrosOpen((open) => !open)}\n disabled={disabled}\n className={cn('h-8 gap-1 px-2', macrosOpen && 'bg-muted')}\n aria-expanded={macrosOpen}\n aria-controls={macrosOpen ? macroPanelId : undefined}\n title={\n macrosOpen\n ? (macroLabels?.hideMacros ?? 'Hide macros')\n : (macroLabels?.showMacros ?? 'Show macros')\n }\n >\n <BookOpen className=\"h-4 w-4\" />\n <span className=\"ms-1 text-xs\">\n {macroLabels?.macros ?? 'Macros'}\n </span>\n </Button>\n </>\n )}\n </div>\n\n <div className=\"relative flex min-h-0 flex-1 flex-col\">\n <div\n className={cn(\n 'relative flex-1',\n hasMacros && macrosOpen && 'md:me-72'\n )}\n >\n {isEmpty && placeholder && (\n <div\n aria-hidden=\"true\"\n className=\"text-muted-foreground pointer-events-none absolute start-0 top-0 p-4\"\n >\n {placeholder}\n </div>\n )}\n <div\n ref={editorRef}\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-label={ariaLabel ?? placeholder}\n contentEditable={!disabled}\n tabIndex={disabled ? -1 : 0}\n onInput={updateContent}\n onPaste={handlePaste}\n onDrop={handleDrop}\n onBlur={hasMacros ? saveSelection : undefined}\n onKeyDown={hasMacros ? expandTypedShortcut : undefined}\n onKeyUp={hasMacros ? saveSelection : undefined}\n onMouseUp={hasMacros ? saveSelection : undefined}\n className={cn(\n 'min-h-[250px] overflow-y-auto p-4 focus:outline-none',\n 'prose prose-sm max-w-none',\n hasMacros && macrosOpen && 'md:min-h-[400px]',\n disabled &&\n 'bg-muted/20 cursor-not-allowed text-neutral-700 dark:text-neutral-300'\n )}\n suppressContentEditableWarning\n />\n </div>\n\n {hasMacros && macrosOpen && (\n <MacroLibrary\n id={macroPanelId}\n groups={macros!}\n onSelect={insertMacro}\n targetLabel={ariaLabel ?? placeholder}\n onClose={() => {\n setMacrosOpen(false);\n // Selecting text in the panel moves the document selection;\n // put the caret back where the user left it.\n focusRestoringSelection();\n }}\n onCreateMacro={onCreateMacro}\n labels={macroLabels}\n className=\"border-border max-h-72 border-t md:absolute md:inset-y-0 md:end-0 md:max-h-none md:w-72 md:border-s md:border-t-0\"\n />\n )}\n </div>\n </div>\n );\n }\n);\n\nRichTextEditor.displayName = 'RichTextEditor';\n\nexport { RichTextEditor };\n"]}
|