@remyxjs/react 1.0.0-beta → 1.0.4-beta
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/{AttachmentModal-D-uxbXvb.cjs → AttachmentModal-BDFFiZJt.cjs} +2 -2
- package/dist/{AttachmentModal-D-uxbXvb.cjs.map → AttachmentModal-BDFFiZJt.cjs.map} +1 -1
- package/dist/{AttachmentModal--6T-vYJt.js → AttachmentModal-Di5V6QX-.js} +2 -2
- package/dist/{AttachmentModal--6T-vYJt.js.map → AttachmentModal-Di5V6QX-.js.map} +1 -1
- package/dist/{ContextMenu-B4K3Zbfp.cjs → ContextMenu-BafbP2Uh.cjs} +2 -2
- package/dist/{ContextMenu-B4K3Zbfp.cjs.map → ContextMenu-BafbP2Uh.cjs.map} +1 -1
- package/dist/{ContextMenu-D8wNSMc3.js → ContextMenu-DsA0YsY7.js} +2 -2
- package/dist/{ContextMenu-D8wNSMc3.js.map → ContextMenu-DsA0YsY7.js.map} +1 -1
- package/dist/{EmbedModal-Bh2Tcow9.cjs → EmbedModal-C73lODIT.cjs} +2 -2
- package/dist/{EmbedModal-Bh2Tcow9.cjs.map → EmbedModal-C73lODIT.cjs.map} +1 -1
- package/dist/{EmbedModal-cxE4maD2.js → EmbedModal-alpHQiAP.js} +2 -2
- package/dist/{EmbedModal-cxE4maD2.js.map → EmbedModal-alpHQiAP.js.map} +1 -1
- package/dist/{ExportModal-Cf1uE4r_.js → ExportModal-BN8LUaSR.js} +2 -2
- package/dist/{ExportModal-Cf1uE4r_.js.map → ExportModal-BN8LUaSR.js.map} +1 -1
- package/dist/{ExportModal-DwQVsrZE.cjs → ExportModal-Cu-cCwa6.cjs} +2 -2
- package/dist/{ExportModal-DwQVsrZE.cjs.map → ExportModal-Cu-cCwa6.cjs.map} +1 -1
- package/dist/{FindReplaceModal-Dgt_MrWb.js → FindReplaceModal-BqNcotUr.js} +2 -2
- package/dist/{FindReplaceModal-Dgt_MrWb.js.map → FindReplaceModal-BqNcotUr.js.map} +1 -1
- package/dist/{FindReplaceModal-DYL_2z8U.cjs → FindReplaceModal-DgysYT04.cjs} +2 -2
- package/dist/{FindReplaceModal-DYL_2z8U.cjs.map → FindReplaceModal-DgysYT04.cjs.map} +1 -1
- package/dist/{ImageModal-D39ywxqI.cjs → ImageModal-BzgYXY9y.cjs} +2 -2
- package/dist/{ImageModal-D39ywxqI.cjs.map → ImageModal-BzgYXY9y.cjs.map} +1 -1
- package/dist/{ImageModal-DqScpPrc.js → ImageModal-bCzSSTmd.js} +2 -2
- package/dist/{ImageModal-DqScpPrc.js.map → ImageModal-bCzSSTmd.js.map} +1 -1
- package/dist/{ImportDocumentModal-BKqMxO3z.js → ImportDocumentModal-BypTEn2i.js} +4 -4
- package/dist/{ImportDocumentModal-BKqMxO3z.js.map → ImportDocumentModal-BypTEn2i.js.map} +1 -1
- package/dist/{ImportDocumentModal-Bev9hp_J.cjs → ImportDocumentModal-gCFept9p.cjs} +2 -2
- package/dist/{ImportDocumentModal-Bev9hp_J.cjs.map → ImportDocumentModal-gCFept9p.cjs.map} +1 -1
- package/dist/{LinkModal-k9IeDtAb.js → LinkModal-CmkK4m-k.js} +3 -3
- package/dist/{LinkModal-k9IeDtAb.js.map → LinkModal-CmkK4m-k.js.map} +1 -1
- package/dist/{LinkModal-B-igSa-g.cjs → LinkModal-DPxg7YCE.cjs} +2 -2
- package/dist/{LinkModal-B-igSa-g.cjs.map → LinkModal-DPxg7YCE.cjs.map} +1 -1
- package/dist/{MenuBar-DWxJNHmb.js → MenuBar-DOv7JPwR.js} +2 -2
- package/dist/{MenuBar-DWxJNHmb.js.map → MenuBar-DOv7JPwR.js.map} +1 -1
- package/dist/{MenuBar-B-ZAX9rH.cjs → MenuBar-Lw_5Jp8u.cjs} +2 -2
- package/dist/{MenuBar-B-ZAX9rH.cjs.map → MenuBar-Lw_5Jp8u.cjs.map} +1 -1
- package/dist/{ModalOverlay-BDsGgv3_.cjs → ModalOverlay-Dh5quv7X.cjs} +2 -2
- package/dist/{ModalOverlay-BDsGgv3_.cjs.map → ModalOverlay-Dh5quv7X.cjs.map} +1 -1
- package/dist/{ModalOverlay-CLvRNHmp.js → ModalOverlay-Dt0JiW3M.js} +2 -2
- package/dist/{ModalOverlay-CLvRNHmp.js.map → ModalOverlay-Dt0JiW3M.js.map} +1 -1
- package/dist/{SourceModal-BNI_i4iW.cjs → SourceModal-CHKC5xcv.cjs} +2 -2
- package/dist/{SourceModal-BNI_i4iW.cjs.map → SourceModal-CHKC5xcv.cjs.map} +1 -1
- package/dist/{SourceModal-MdTGK3Uf.js → SourceModal-ChhNVz7y.js} +2 -2
- package/dist/{SourceModal-MdTGK3Uf.js.map → SourceModal-ChhNVz7y.js.map} +1 -1
- package/dist/{TablePickerModal-DYODWEA1.js → TablePickerModal-BnZHyMsk.js} +2 -2
- package/dist/{TablePickerModal-DYODWEA1.js.map → TablePickerModal-BnZHyMsk.js.map} +1 -1
- package/dist/{TablePickerModal-Do1QyoyM.cjs → TablePickerModal-Dr0wUx_h.cjs} +2 -2
- package/dist/{TablePickerModal-Do1QyoyM.cjs.map → TablePickerModal-Dr0wUx_h.cjs.map} +1 -1
- package/dist/index-Bg_uAWlM.js +3 -0
- package/dist/index-Bg_uAWlM.js.map +1 -0
- package/dist/index-DL-qBZZU.js +357 -0
- package/dist/index-DL-qBZZU.js.map +1 -0
- package/dist/index-OfJxpaev.cjs +2 -0
- package/dist/index-OfJxpaev.cjs.map +1 -0
- package/dist/index-qh1Yzh-l.cjs +2 -0
- package/dist/index-qh1Yzh-l.cjs.map +1 -0
- package/dist/remyx-react.cjs +1 -1
- package/dist/remyx-react.css +1 -1
- package/dist/remyx-react.js +1 -1
- package/package.json +3 -3
- package/dist/index-C720tbJA.js +0 -359
- package/dist/index-C720tbJA.js.map +0 -1
- package/dist/index-Dc63uIP0.cjs +0 -2
- package/dist/index-Dc63uIP0.cjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-Dc63uIP0.cjs","sources":["../src/hooks/createEditorEngine.js","../src/hooks/useEditorEngine.js","../src/hooks/useSelection.js","../src/hooks/useModal.js","../src/hooks/useContextMenu.js","../src/config/RemyxConfigProvider.jsx","../src/hooks/useRemyxConfig.js","../src/hooks/useResolvedConfig.js","../src/hooks/useAutosave.js","../src/hooks/useEditorRect.js","../src/hooks/useDragDrop.js","../src/hooks/usePinchZoom.js","../src/config/SelectionContext.js","../../node_modules/prop-types/node_modules/react-is/index.js","../../node_modules/prop-types/node_modules/react-is/cjs/react-is.production.min.js","../../node_modules/prop-types/node_modules/react-is/cjs/react-is.development.js","../../node_modules/object-assign/index.js","../../node_modules/prop-types/lib/ReactPropTypesSecret.js","../../node_modules/prop-types/lib/has.js","../../node_modules/prop-types/checkPropTypes.js","../../node_modules/prop-types/factoryWithTypeCheckers.js","../../node_modules/prop-types/factoryWithThrowingShims.js","../../node_modules/prop-types/index.js","../src/icons/helpers.jsx","../src/icons/index.jsx","../src/components/Tooltip/Tooltip.jsx","../src/components/Toolbar/ToolbarButton.jsx","../src/components/Toolbar/ToolbarDropdown.jsx","../src/components/Toolbar/ToolbarColorPicker.jsx","../src/components/Toolbar/ToolbarSeparator.jsx","../src/components/TypographyDropdown/TypographyDropdown.jsx","../src/components/Toolbar/Toolbar.jsx","../src/components/EditArea/EditArea.jsx","../src/components/EditArea/FloatingToolbar.jsx","../src/components/EditArea/ImageResizeHandles.jsx","../src/components/EditArea/TableControls.jsx","../src/components/EditArea/CodeBlockControls.jsx","../src/components/EditArea/DropZoneOverlay.jsx","../src/components/EditArea/BlockDragHandle.jsx","../src/components/SaveStatus/SaveStatus.jsx","../src/components/StatusBar/StatusBar.jsx","../src/components/RecoveryBanner/RecoveryBanner.jsx","../src/components/ErrorBoundary.jsx","../src/components/EmptyState/EmptyState.jsx","../src/components/BreadcrumbBar/BreadcrumbBar.jsx","../src/components/Minimap/Minimap.jsx","../src/components/SplitPreview/SplitPreview.jsx","../src/components/Toast/Toast.jsx","../src/components/EditorModals.jsx","../src/components/RemyxEditor.jsx","../src/hooks/usePortalAttachment.js","../src/hooks/useSwipeGesture.js","../src/hooks/useLongPress.js","../src/hooks/useVirtualKeyboard.js","../src/hooks/useExternalConfig.js","../src/components/CommentsPanel/CommentsPanel.jsx","../src/components/CollaborationBar/CollaborationBar.jsx","../src/components/RemyxEditorFromConfig.jsx","../src/hooks/useCollaboration.js","../src/hooks/useComments.js","../src/hooks/useRemyxEditor.js","../src/hooks/useSpellcheck.js"],"sourcesContent":["/**\n * Shared factory for creating and initializing an EditorEngine with all built-in\n * commands and plugins. Used by both useRemyxEditor and useEditorEngine to avoid\n * ~100 lines of duplicated init logic (Item 6).\n */\nimport {\n EditorEngine,\n registerFormattingCommands,\n registerHeadingCommands,\n registerAlignmentCommands,\n registerListCommands,\n registerLinkCommands,\n registerImageCommands,\n registerTableCommands,\n registerBlockCommands,\n registerFontCommands,\n registerMediaCommands,\n registerFindReplaceCommands,\n registerSourceModeCommands,\n registerFullscreenCommands,\n registerDistractionFreeCommands,\n registerSplitViewCommands,\n registerColorPresetCommands,\n registerMarkdownToggleCommands,\n registerAttachmentCommands,\n registerImportDocumentCommands,\n registerBlockConvertCommands,\n WordCountPlugin,\n PlaceholderPlugin,\n AutolinkPlugin,\n htmlToMarkdown,\n markdownToHtml,\n} from '@remyxjs/core'\n\n/** All built-in command registration functions, invoked in order during engine init */\nconst COMMAND_REGISTRARS = [\n registerFormattingCommands,\n registerHeadingCommands,\n registerAlignmentCommands,\n registerListCommands,\n registerLinkCommands,\n registerImageCommands,\n registerTableCommands,\n registerBlockCommands,\n registerFontCommands,\n registerMediaCommands,\n registerFindReplaceCommands,\n registerSourceModeCommands,\n registerFullscreenCommands,\n registerDistractionFreeCommands,\n registerSplitViewCommands,\n registerColorPresetCommands,\n registerMarkdownToggleCommands,\n registerAttachmentCommands,\n registerImportDocumentCommands,\n registerBlockConvertCommands,\n]\n\n/**\n * Create an EditorEngine, register all built-in commands and plugins, set initial content.\n *\n * @param {HTMLElement} element - The contenteditable element\n * @param {object} opts - Editor options\n * @returns {{ engine: EditorEngine, initialContent: string }}\n */\nexport function createEditorInstance(element, opts) {\n const engine = new EditorEngine(element, opts)\n\n // Register all built-in commands via registry loop\n for (const register of COMMAND_REGISTRARS) {\n register(engine)\n }\n\n // Register undo/redo commands\n engine.commands.register('undo', {\n execute(eng) { eng.history.undo() },\n isEnabled(eng) { return eng.history.canUndo() },\n shortcut: 'mod+z',\n meta: { icon: 'undo', tooltip: 'Undo' },\n })\n engine.commands.register('redo', {\n execute(eng) { eng.history.redo() },\n isEnabled(eng) { return eng.history.canRedo() },\n shortcut: 'mod+shift+z',\n meta: { icon: 'redo', tooltip: 'Redo' },\n })\n\n // Check if user already provided specific plugins to avoid duplicate registration\n const userPluginNames = new Set(\n (opts.plugins || []).map(p => p?.name).filter(Boolean)\n )\n\n // Register built-in plugins (skip if user already provided them)\n if (!userPluginNames.has('wordCount')) engine.plugins.register(WordCountPlugin())\n if (opts.placeholder && !userPluginNames.has('placeholder')) {\n engine.plugins.register(PlaceholderPlugin(opts.placeholder))\n }\n if (!userPluginNames.has('autolink')) engine.plugins.register(AutolinkPlugin())\n\n // Register user plugins\n if (opts.plugins) {\n opts.plugins.forEach((p) => engine.plugins.register(p))\n }\n\n // Set initial content (convert markdown -> HTML if needed)\n const isMarkdown = opts.outputFormat === 'markdown'\n let initialContent = opts.value || opts.defaultValue || ''\n if (initialContent && isMarkdown) {\n initialContent = markdownToHtml(initialContent)\n }\n if (initialContent) {\n engine.setHTML(initialContent)\n }\n\n return { engine, initialContent }\n}\n\nexport { htmlToMarkdown, markdownToHtml }\n","import { useEffect, useRef, useState, useCallback } from 'react'\nimport { createEditorInstance, htmlToMarkdown, markdownToHtml } from './createEditorEngine.js'\n\n/**\n * Item 6: Shared factory extracted to createEditorEngine.js.\n * Item 7: registerBlockConvertCommands included in shared factory.\n * Item 14: rAF cancelled on unmount.\n */\nexport function useEditorEngine(editAreaRef, options, readyTrigger) {\n const engineRef = useRef(null)\n const [ready, setReady] = useState(false)\n const lastValueRef = useRef(options.value || options.defaultValue || '')\n const rAFRef = useRef(null)\n\n // Use a ref to always access the latest options (avoids stale closure in initEngine)\n const optionsRef = useRef(options)\n optionsRef.current = options\n\n const initEngine = useCallback(() => {\n if (!editAreaRef.current || engineRef.current) return\n\n const opts = optionsRef.current\n const { engine } = createEditorInstance(editAreaRef.current, opts)\n\n engine.init()\n engineRef.current = engine\n setReady(true)\n opts.onReady?.(engine)\n\n // Emit initial content change so plugins (word count, placeholder) pick up content\n engine.eventBus.emit('content:change')\n\n // Listen for content changes — use optionsRef to always call latest onChange\n // Convert HTML -> markdown if outputFormat is 'markdown'\n // Item 14: Store rAF ID in ref for cleanup\n engine.on('content:change', () => {\n if (rAFRef.current) cancelAnimationFrame(rAFRef.current)\n rAFRef.current = requestAnimationFrame(() => {\n rAFRef.current = null\n let output\n if (engine.isMarkdownMode) {\n // In markdown editing mode, the content is raw markdown text\n output = engine.element.textContent\n } else {\n const html = engine.getHTML()\n const ismd = optionsRef.current.outputFormat === 'markdown'\n output = ismd ? htmlToMarkdown(html) : html\n }\n if (output !== lastValueRef.current) {\n lastValueRef.current = output\n optionsRef.current.onChange?.(output)\n }\n })\n })\n\n engine.on('focus', () => optionsRef.current.onFocus?.())\n engine.on('blur', () => optionsRef.current.onBlur?.())\n\n return engine\n }, []) // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n const engine = initEngine()\n return () => {\n // Item 14: Cancel any pending rAF on unmount\n if (rAFRef.current) {\n cancelAnimationFrame(rAFRef.current)\n rAFRef.current = null\n }\n if (engine) {\n engine.destroy()\n engineRef.current = null\n setReady(false)\n }\n }\n }, [initEngine, readyTrigger]) // readyTrigger allows deferred init (e.g. after portal mount)\n\n // Sync external value changes (convert markdown -> HTML if needed)\n useEffect(() => {\n if (!engineRef.current || !ready) return\n if (options.value === undefined) return\n if (options.value === lastValueRef.current) return\n\n lastValueRef.current = options.value\n const isMarkdown = options.outputFormat === 'markdown'\n const htmlValue = isMarkdown ? markdownToHtml(options.value) : options.value\n engineRef.current.setHTML(htmlValue)\n }, [options.value, options.outputFormat, ready])\n\n return { engine: engineRef.current, ready }\n}\n","import { useState, useEffect, useCallback, useRef, useMemo } from 'react'\n\nconst DEFAULT_FORMAT = {\n bold: false,\n italic: false,\n underline: false,\n strikethrough: false,\n subscript: false,\n superscript: false,\n heading: null,\n alignment: 'left',\n orderedList: false,\n unorderedList: false,\n blockquote: false,\n codeBlock: false,\n link: null,\n fontFamily: null,\n fontSize: null,\n foreColor: null,\n backColor: null,\n}\n\nconst DEFAULT_UI = {\n hasSelection: false,\n selectionRect: null,\n focusedImage: null,\n focusedTable: null,\n focusedCodeBlock: null,\n}\n\nconst FORMAT_KEYS = Object.keys(DEFAULT_FORMAT)\n\n/**\n * Shallow compare two objects by a set of keys.\n * Returns true if all values are identical (===).\n */\nfunction shallowEqual(a, b, keys) {\n for (const key of keys) {\n if (a[key] !== b[key]) return false\n }\n return true\n}\n\nexport function useSelection(engine) {\n // Task 262: Move domLookupCacheRef.current from module-level to a useRef inside the hook\n const domLookupCacheRef = useRef(new WeakMap())\n const [formatState, setFormatState] = useState(DEFAULT_FORMAT)\n const [uiState, setUiState] = useState(DEFAULT_UI)\n\n // Cache focused image/table DOM references to avoid unnecessary state updates\n const cachedFocusRef = useRef({ image: null, table: null })\n\n const handleSelectionChange = useCallback((formats) => {\n // Update format state — bail out if nothing changed\n setFormatState(prev => {\n const next = {}\n for (const key of FORMAT_KEYS) {\n next[key] = key in formats ? formats[key] : DEFAULT_FORMAT[key]\n }\n return shallowEqual(prev, next, FORMAT_KEYS) ? prev : next\n })\n\n // Compute UI state\n const sel = window.getSelection()\n const hasSelection = sel && !sel.isCollapsed && sel.toString().length > 0\n\n let selectionRect = null\n if (hasSelection && sel.rangeCount > 0) {\n try {\n selectionRect = sel.getRangeAt(0).getBoundingClientRect()\n } catch {\n // DOM mutations between rangeCount check and getRangeAt can clear the selection\n selectionRect = null\n }\n }\n\n // DOM queries for focused image/table/codeblock (with WeakMap cache)\n let focusedImage = null\n let focusedTable = null\n let focusedCodeBlock = null\n if (sel && sel.focusNode) {\n const node = sel.focusNode.nodeType === Node.TEXT_NODE ? sel.focusNode.parentElement : sel.focusNode\n if (node) {\n // Check WeakMap cache keyed by the focus node\n const cacheKey = sel.focusNode\n let cached = domLookupCacheRef.current.get(cacheKey)\n if (cached) {\n focusedImage = cached.image\n focusedTable = cached.table\n focusedCodeBlock = cached.codeBlock\n } else {\n const img = node.tagName === 'IMG' ? node : node.querySelector?.(':scope > img')\n if (img) focusedImage = img\n\n const table = node.closest?.('table')\n if (table) focusedTable = table\n\n const pre = node.closest?.('pre')\n if (pre) focusedCodeBlock = pre\n\n domLookupCacheRef.current.set(cacheKey, { image: focusedImage, table: focusedTable, codeBlock: focusedCodeBlock })\n }\n }\n }\n\n // Use cached references if the actual DOM element hasn't changed\n if (focusedImage === cachedFocusRef.current.image &&\n focusedTable === cachedFocusRef.current.table &&\n focusedCodeBlock === cachedFocusRef.current.codeBlock) {\n focusedImage = cachedFocusRef.current.image\n focusedTable = cachedFocusRef.current.table\n focusedCodeBlock = cachedFocusRef.current.codeBlock\n } else {\n cachedFocusRef.current = { image: focusedImage, table: focusedTable, codeBlock: focusedCodeBlock }\n }\n\n // Task 263: Compare DOMRect coordinates individually before creating new state\n setUiState(prev => {\n const rectUnchanged = !hasSelection || (\n prev.selectionRect &&\n selectionRect &&\n prev.selectionRect.top === selectionRect.top &&\n prev.selectionRect.left === selectionRect.left &&\n prev.selectionRect.width === selectionRect.width &&\n prev.selectionRect.height === selectionRect.height\n )\n if (prev.hasSelection === hasSelection &&\n prev.focusedImage === focusedImage &&\n prev.focusedTable === focusedTable &&\n prev.focusedCodeBlock === focusedCodeBlock &&\n rectUnchanged) {\n return prev\n }\n return { hasSelection, selectionRect, focusedImage, focusedTable, focusedCodeBlock }\n })\n }, [])\n\n // Subscribe to selection changes\n useEffect(() => {\n if (!engine) return\n const unsub = engine.eventBus.on('selection:change', handleSelectionChange)\n return unsub\n }, [engine, handleSelectionChange])\n\n // Clear cached DOM references when content changes (DOM may have mutated)\n useEffect(() => {\n if (!engine) return\n const clearCache = () => {\n cachedFocusRef.current = { image: null, table: null, codeBlock: null }\n // Note: WeakMap entries for detached DOM nodes are automatically GC'd\n }\n const unsub = engine.eventBus.on('content:change', clearCache)\n return unsub\n }, [engine])\n\n // Return split object with formatState and uiState as separate sub-objects\n return { formatState, uiState }\n}\n","import { useReducer, useCallback } from 'react'\n\nconst initialState = {\n link: { open: false, data: null },\n image: { open: false, data: null },\n table: { open: false, data: null },\n embed: { open: false, data: null },\n findReplace: { open: false, data: null },\n source: { open: false, data: null },\n attachment: { open: false, data: null },\n importDocument: { open: false, data: null },\n export: { open: false, data: null },\n}\n\n// Task 254: Replace useState object with useReducer for more efficient updates\nfunction modalReducer(state, action) {\n switch (action.type) {\n case 'OPEN':\n return { ...state, [action.name]: { open: true, data: action.data } }\n case 'CLOSE':\n return { ...state, [action.name]: { open: false, data: null } }\n default:\n return state\n }\n}\n\nexport function useModal() {\n const [modals, dispatch] = useReducer(modalReducer, initialState)\n\n const openModal = useCallback((name, data = null) => {\n dispatch({ type: 'OPEN', name, data })\n }, [])\n\n const closeModal = useCallback((name) => {\n dispatch({ type: 'CLOSE', name })\n }, [])\n\n const isOpen = useCallback((name) => modals[name]?.open || false, [modals])\n const getData = useCallback((name) => modals[name]?.data || null, [modals])\n\n return { modals, openModal, closeModal, isOpen, getData }\n}\n","import { useState, useCallback, useEffect, useRef } from 'react'\nimport { cleanPastedHTML } from '@remyxjs/core'\n// Task 256: Import shared insertPlainText utility\nimport { insertPlainText } from '@remyxjs/core'\n\n/**\n * Handle paste from the context menu using the full cleaning pipeline.\n * Tries navigator.clipboard.read() for rich text first, falls back to readText().\n */\nasync function handleContextMenuPaste(engine) {\n if (!engine) return\n\n engine.history.snapshot()\n\n try {\n // Try reading rich content (HTML) via the Clipboard API\n if (navigator.clipboard?.read) {\n const items = await navigator.clipboard.read()\n for (const item of items) {\n // Check for HTML content first\n if (item.types.includes('text/html')) {\n const blob = await item.getType('text/html')\n let html = await blob.text()\n html = cleanPastedHTML(html)\n html = engine.sanitizer.sanitize(html)\n engine.selection.insertHTML(html)\n engine.eventBus.emit('content:change')\n return\n }\n // Fall back to plain text\n if (item.types.includes('text/plain')) {\n const blob = await item.getType('text/plain')\n const text = await blob.text()\n insertPlainText(engine, text)\n engine.eventBus.emit('content:change')\n return\n }\n }\n }\n\n // Fallback: navigator.clipboard.readText()\n if (navigator.clipboard?.readText) {\n const text = await navigator.clipboard.readText()\n if (text) {\n insertPlainText(engine, text)\n engine.eventBus.emit('content:change')\n }\n }\n } catch {\n // Permission denied or API not available — try readText as last resort\n try {\n const text = await navigator.clipboard?.readText?.()\n if (text) {\n insertPlainText(engine, text)\n engine.eventBus.emit('content:change')\n }\n } catch {\n // Clipboard access denied entirely — nothing we can do\n }\n }\n}\n\nexport function useContextMenu(engine, editorRef) {\n const [contextMenu, setContextMenu] = useState({\n visible: false,\n x: 0,\n y: 0,\n items: [],\n })\n\n // Task 268: Extract stable command handler functions\n const cutHandler = useCallback(async () => {\n const sel = window.getSelection()\n if (sel && !sel.isCollapsed) {\n try {\n await navigator.clipboard.writeText(sel.toString())\n sel.getRangeAt(0).deleteContents()\n } catch { /* fallback: no-op in insecure contexts */ }\n }\n }, [])\n\n const copyHandler = useCallback(async () => {\n const sel = window.getSelection()\n if (sel && !sel.isCollapsed) {\n try { await navigator.clipboard.writeText(sel.toString()) } catch { /* no-op */ }\n }\n }, [])\n\n const pasteHandler = useCallback(() => handleContextMenuPaste(engine), [engine])\n\n const selectAllHandler = useCallback(() => {\n if (!engine) return\n const sel = window.getSelection()\n const range = document.createRange()\n range.selectNodeContents(engine.element)\n sel.removeAllRanges()\n sel.addRange(range)\n }, [engine])\n\n const handleContextMenu = useCallback((e) => {\n if (!engine) return\n e.preventDefault()\n\n const target = e.target\n const items = []\n\n // Always show basic items\n items.push(\n { label: 'Cut', command: cutHandler },\n { label: 'Copy', command: copyHandler },\n { label: 'Paste', command: pasteHandler },\n { separator: true },\n { label: 'Select All', command: selectAllHandler },\n )\n\n // Context-specific items\n const linkEl = target.closest?.('a')\n if (linkEl) {\n items.push(\n { separator: true },\n { label: 'Edit Link', command: 'editLinkModal', data: linkEl },\n { label: 'Remove Link', command: () => engine.executeCommand('removeLink') },\n { label: 'Open Link', command: () => {\n const href = linkEl.href\n if (!/^\\s*(javascript|vbscript|data\\s*:\\s*text\\/html)\\s*:/i.test(href)) {\n window.open(href, '_blank')\n }\n }},\n )\n }\n\n const imgEl = target.tagName === 'IMG' ? target : null\n if (imgEl) {\n items.push(\n { separator: true },\n { label: 'Align Left', command: () => engine.executeCommand('alignImage', { element: imgEl, alignment: 'left' }) },\n { label: 'Align Center', command: () => engine.executeCommand('alignImage', { element: imgEl, alignment: 'center' }) },\n { label: 'Align Right', command: () => engine.executeCommand('alignImage', { element: imgEl, alignment: 'right' }) },\n { label: 'Remove Image', command: () => engine.executeCommand('removeImage', { element: imgEl }) },\n )\n }\n\n const tableEl = target.closest?.('table')\n if (tableEl) {\n items.push(\n { separator: true },\n { label: 'Insert Row Before', command: () => engine.executeCommand('addRowBefore') },\n { label: 'Insert Row After', command: () => engine.executeCommand('addRowAfter') },\n { label: 'Insert Column Before', command: () => engine.executeCommand('addColBefore') },\n { label: 'Insert Column After', command: () => engine.executeCommand('addColAfter') },\n { separator: true },\n { label: 'Toggle Header Row', command: () => engine.executeCommand('toggleHeaderRow') },\n { separator: true },\n { label: 'Format as Number', command: () => engine.executeCommand('formatCell', { format: 'number' }) },\n { label: 'Format as Currency', command: () => engine.executeCommand('formatCell', { format: 'currency' }) },\n { label: 'Format as Percentage', command: () => engine.executeCommand('formatCell', { format: 'percentage' }) },\n { label: 'Format as Date', command: () => engine.executeCommand('formatCell', { format: 'date' }) },\n { separator: true },\n { label: 'Clear Filters', command: () => engine.executeCommand('clearTableFilters') },\n { separator: true },\n { label: 'Delete Row', command: () => engine.executeCommand('deleteRow') },\n { label: 'Delete Column', command: () => engine.executeCommand('deleteCol') },\n { label: 'Delete Table', command: () => engine.executeCommand('deleteTable') },\n )\n }\n\n setContextMenu({\n visible: true,\n x: e.clientX,\n y: e.clientY,\n items,\n })\n }, [engine, cutHandler, copyHandler, pasteHandler, selectAllHandler])\n\n const hideContextMenu = useCallback(() => {\n setContextMenu((prev) => ({ ...prev, visible: false }))\n }, [])\n\n // Task 267: Gate the scroll listener behind contextMenu.visible\n const visibleRef = useRef(false)\n visibleRef.current = contextMenu.visible\n\n useEffect(() => {\n const el = editorRef?.current\n if (!el) return\n el.addEventListener('contextmenu', handleContextMenu)\n document.addEventListener('click', hideContextMenu)\n\n // Task 267: Only add scroll listener when context menu is visible\n const handleScroll = () => {\n if (visibleRef.current) hideContextMenu()\n }\n document.addEventListener('scroll', handleScroll, true)\n\n return () => {\n el.removeEventListener('contextmenu', handleContextMenu)\n document.removeEventListener('click', hideContextMenu)\n document.removeEventListener('scroll', handleScroll, true)\n }\n }, [editorRef, handleContextMenu, hideContextMenu])\n\n return { contextMenu, hideContextMenu }\n}\n","import React, { createContext, useMemo } from 'react'\n\nexport const RemyxConfigContext = createContext(null)\n\n/**\n * Provides a RemyxEditor configuration to all descendant <RemyxEditor /> components.\n *\n * @param {object} props\n * @param {object} props.config - Configuration object from defineConfig()\n * @param {React.ReactNode} props.children\n */\nexport function RemyxConfigProvider({ config, children }) {\n const value = useMemo(() => config, [config])\n return (\n <RemyxConfigContext.Provider value={value}>\n {children}\n </RemyxConfigContext.Provider>\n )\n}\n","import { useContext, useMemo } from 'react'\nimport { RemyxConfigContext } from '../config/RemyxConfigProvider.jsx'\n\n/**\n * Resolves the merged configuration for a specific editor instance.\n * Priority: component props > named editor config > default config\n *\n * @param {string|undefined} configName - Named editor config to use\n * @returns {object|null} Resolved default + named config (without component props merged)\n */\nexport function useRemyxConfig(configName) {\n const config = useContext(RemyxConfigContext)\n\n return useMemo(() => {\n if (!config) return null\n\n // Extract default config (everything except `editors`)\n const { editors, ...defaults } = config\n\n // If a named config is requested, merge it on top of defaults\n if (configName && editors?.[configName]) {\n return { ...defaults, ...editors[configName] }\n }\n\n return defaults\n }, [config, configName])\n}\n","import { useMemo } from 'react'\nimport { useRemyxConfig } from './useRemyxConfig.js'\nimport { DEFAULT_TOOLBAR, DEFAULT_FONTS, DEFAULT_MENU_BAR, resolvePlugins } from '@remyxjs/core'\nimport { collectMenuBarCommands } from '../components/MenuBar/collectMenuBarCommands.js'\n\n/** Default editor content area height in pixels */\nexport const DEFAULT_EDITOR_HEIGHT = 300\n\n/**\n * Resolves editor configuration from props, context provider, and defaults.\n * Handles config merging, menu bar resolution, and toolbar auto-deduplication.\n */\nexport function useResolvedConfig(props) {\n const { config: configName, ...componentProps } = props\n\n // Resolve config from provider context (if any)\n const resolvedConfig = useRemyxConfig(configName)\n\n // Merge: resolved config as defaults, component props override where explicitly provided\n const merged = resolvedConfig\n ? Object.keys({ ...resolvedConfig, ...componentProps }).reduce((acc, key) => {\n acc[key] = componentProps[key] !== undefined ? componentProps[key] : resolvedConfig[key]\n return acc\n }, {})\n : componentProps\n\n // Destructure with defaults from the merged config\n const {\n attachTo,\n value,\n defaultValue,\n onChange,\n toolbar,\n menuBar: menuBarProp,\n theme = 'light',\n placeholder = '',\n height = DEFAULT_EDITOR_HEIGHT,\n minHeight,\n maxHeight,\n readOnly = false,\n plugins,\n onReady,\n onFocus,\n onBlur,\n className = '',\n style,\n uploadHandler,\n outputFormat = 'html',\n floatingToolbar: showFloatingToolbar = true,\n contextMenu: showContextMenu = true,\n fonts,\n googleFonts,\n statusBar = 'bottom',\n customTheme,\n toolbarItemTheme,\n sanitize,\n shortcuts,\n baseHeadingLevel,\n onError,\n errorFallback,\n commandPalette: showCommandPalette = true,\n autosave: autosaveProp = false,\n emptyState: emptyStateProp = false,\n breadcrumb: showBreadcrumb = false,\n minimap: showMinimap = false,\n splitViewFormat,\n customizableToolbar: customizableToolbarProp = false,\n onToolbarChange,\n } = merged\n\n // Resolve plugin names from config (strings/objects → plugin instances)\n const resolvedPlugins = useMemo(() => {\n if (!plugins || !Array.isArray(plugins)) return plugins\n const hasStringEntries = plugins.some(\n p => typeof p === 'string' || (typeof p === 'object' && p !== null && typeof p.name === 'string' && typeof p.init !== 'function')\n )\n if (hasStringEntries) {\n return resolvePlugins(plugins)\n }\n return plugins\n }, [plugins])\n\n // Task 247: Memoize autosaveConfig and menuBarConfig with separate useMemo calls\n const autosaveConfig = useMemo(() =>\n autosaveProp === true\n ? { enabled: true }\n : autosaveProp === false\n ? { enabled: false }\n : { enabled: true, ...autosaveProp },\n [autosaveProp]\n )\n\n const menuBarConfig = useMemo(() =>\n menuBarProp === true ? DEFAULT_MENU_BAR\n : Array.isArray(menuBarProp) ? menuBarProp\n : null,\n [menuBarProp]\n )\n\n // When both toolbar and menu bar are shown, keep the full toolbar intact.\n // The menu bar provides an alternative navigation layer, not a replacement.\n const effectiveToolbar = useMemo(() => {\n return toolbar || DEFAULT_TOOLBAR\n }, [toolbar])\n\n return useMemo(() => ({\n attachTo,\n value,\n defaultValue,\n onChange,\n toolbar,\n theme,\n placeholder,\n height,\n minHeight,\n maxHeight,\n readOnly,\n plugins: resolvedPlugins,\n onReady,\n onFocus,\n onBlur,\n className,\n style,\n uploadHandler,\n outputFormat,\n showFloatingToolbar,\n showContextMenu,\n fonts,\n googleFonts,\n statusBar,\n customTheme,\n toolbarItemTheme,\n sanitize,\n shortcuts,\n baseHeadingLevel,\n menuBarConfig,\n effectiveToolbar,\n onError,\n errorFallback,\n showCommandPalette,\n autosaveConfig,\n emptyState: emptyStateProp,\n showBreadcrumb,\n showMinimap,\n splitViewFormat,\n customizableToolbar: customizableToolbarProp,\n onToolbarChange,\n }), [\n attachTo, value, defaultValue, onChange, toolbar, theme, placeholder,\n height, minHeight, maxHeight, readOnly, resolvedPlugins, onReady, onFocus, onBlur,\n className, style, uploadHandler, outputFormat, showFloatingToolbar,\n showContextMenu, fonts, googleFonts, statusBar, customTheme, toolbarItemTheme,\n sanitize, shortcuts, baseHeadingLevel, menuBarConfig, effectiveToolbar,\n onError, errorFallback, showCommandPalette, autosaveConfig,\n emptyStateProp, showBreadcrumb, showMinimap, splitViewFormat,\n customizableToolbarProp, onToolbarChange,\n ])\n}\n","import { useState, useEffect, useRef, useCallback, useMemo } from 'react'\nimport { AutosaveManager } from '@remyxjs/core'\n\n/**\n * React hook for autosave integration with the editor engine.\n *\n * Manages AutosaveManager lifecycle, tracks save status, and handles\n * crash recovery detection with restore/dismiss actions.\n *\n * @param {import('@remyxjs/core').EditorEngine|null} engine\n * @param {Object} [config] - Autosave configuration\n * @param {boolean} [config.enabled] - Whether autosave is active\n * @param {number} [config.interval] - Periodic save interval in ms\n * @param {number} [config.debounce] - Debounce delay in ms\n * @param {string|object} [config.provider] - Storage provider config\n * @param {string} [config.key] - Storage key\n * @param {Function} [config.onRecover] - Callback when recovery data is found\n * @param {boolean} [config.showRecoveryBanner] - Whether to show recovery banner\n * @param {boolean} [config.showSaveStatus] - Whether to show save status\n * @returns {{ saveStatus, lastSaved, recoveryData, recoverContent, dismissRecovery }}\n */\nexport function useAutosave(engine, config) {\n // Task 274: Use a ref for saveStatus to avoid re-renders on every keystroke.\n // Only update state when the status actually changes.\n const saveStatusRef = useRef('saved')\n const [saveStatus, setSaveStatus] = useState('saved')\n const [lastSaved, setLastSaved] = useState(null)\n const [recoveryData, setRecoveryData] = useState(null)\n const managerRef = useRef(null)\n const onRecoverRef = useRef(config?.onRecover)\n\n // Keep onRecover ref fresh without triggering effect re-runs\n onRecoverRef.current = config?.onRecover\n\n // Stabilize config reference to avoid re-creating manager on every render\n const enabled = config?.enabled ?? false\n const configKey = config?.key\n const configInterval = config?.interval\n const configDebounce = config?.debounce\n const configProvider = config?.provider\n\n useEffect(() => {\n if (!engine || !enabled) return\n\n const manager = new AutosaveManager(engine, {\n enabled: true,\n key: configKey,\n interval: configInterval,\n debounce: configDebounce,\n provider: configProvider,\n })\n managerRef.current = manager\n\n // Task 274: Subscribe to autosave events with ref-based status to avoid re-renders\n const updateStatus = (newStatus) => {\n if (saveStatusRef.current !== newStatus) {\n saveStatusRef.current = newStatus\n setSaveStatus(newStatus)\n }\n }\n\n const unsubs = [\n engine.eventBus.on('autosave:saving', () => updateStatus('saving')),\n engine.eventBus.on('autosave:saved', ({ timestamp }) => {\n updateStatus('saved')\n setLastSaved(timestamp)\n }),\n engine.eventBus.on('autosave:error', () => updateStatus('error')),\n engine.eventBus.on('content:change', () => {\n if (saveStatusRef.current !== 'saving') {\n updateStatus('unsaved')\n }\n }),\n ]\n\n // Check for recovery data, then start autosaving after recovery check completes\n const currentContent = engine.getHTML()\n manager.checkRecovery(currentContent).then((data) => {\n if (data) {\n setRecoveryData(data)\n engine.eventBus.emit('autosave:recovered', data)\n onRecoverRef.current?.(data)\n }\n manager.init()\n }).catch((err) => {\n console.warn('[Remyx] Recovery check failed:', err)\n // Still init autosave even if recovery check fails\n manager.init()\n })\n\n return () => {\n unsubs.forEach((u) => u())\n manager.destroy()\n managerRef.current = null\n }\n // Re-create manager when timing, key, or provider changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [engine, enabled, configKey, configInterval, configDebounce, configProvider])\n\n const recoverContent = useCallback(() => {\n if (!engine || !recoveryData) return\n engine.setHTML(recoveryData.recoveredContent)\n engine.eventBus.emit('content:change')\n setRecoveryData(null)\n managerRef.current?.clearRecovery()\n }, [engine, recoveryData])\n\n const dismissRecovery = useCallback(() => {\n setRecoveryData(null)\n managerRef.current?.clearRecovery()\n }, [])\n\n return useMemo(\n () => ({\n saveStatus,\n lastSaved,\n recoveryData,\n recoverContent,\n dismissRecovery,\n }),\n [saveStatus, lastSaved, recoveryData, recoverContent, dismissRecovery],\n )\n}\n","import { useState, useEffect, useRef } from 'react'\n\n/**\n * Tracks the bounding rect of the editor root element.\n * Uses ResizeObserver instead of window resize events for precision,\n * and requestAnimationFrame to throttle scroll updates.\n * Task 258: Limit scroll listener to the editor's scrollable parent rather than global capture.\n */\nexport function useEditorRect(editorRootRef) {\n const [editorRect, setEditorRect] = useState(null)\n const rafRef = useRef(null)\n\n useEffect(() => {\n const el = editorRootRef.current\n if (!el) return // Early return guard if ref is not yet valid\n\n const updateRect = () => {\n const rect = el.getBoundingClientRect()\n if (rect) setEditorRect(rect)\n }\n\n // Initial measurement\n updateRect()\n\n // Use ResizeObserver instead of window resize listener\n const resizeObserver = new ResizeObserver(() => {\n if (rafRef.current) cancelAnimationFrame(rafRef.current)\n rafRef.current = requestAnimationFrame(updateRect)\n })\n resizeObserver.observe(el)\n\n // Task 258: Find the editor's scrollable parent and listen on that\n // instead of using global capture on window\n const scrollParent = findScrollableParent(el) || window\n const handleScroll = () => {\n if (rafRef.current) cancelAnimationFrame(rafRef.current)\n rafRef.current = requestAnimationFrame(updateRect)\n }\n scrollParent.addEventListener('scroll', handleScroll, { passive: true })\n\n return () => {\n resizeObserver.disconnect()\n scrollParent.removeEventListener('scroll', handleScroll)\n if (rafRef.current) cancelAnimationFrame(rafRef.current)\n }\n }, [editorRootRef])\n\n return editorRect\n}\n\n/**\n * Walk up the DOM to find the first scrollable parent.\n * @param {HTMLElement} el\n * @returns {HTMLElement|null}\n */\nfunction findScrollableParent(el) {\n let parent = el.parentElement\n while (parent && parent !== document.body) {\n const style = window.getComputedStyle(parent)\n const overflow = style.overflow + style.overflowY\n if (/auto|scroll/.test(overflow)) return parent\n parent = parent.parentElement\n }\n return null\n}\n","import { useState, useEffect, useCallback } from 'react'\n\n/**\n * Hook that tracks drag-and-drop state from the editor engine,\n * providing reactive state for the React overlay components.\n *\n * @param {Object} engine - The EditorEngine instance\n * @returns {{ isExternalDrag: boolean, dragFileTypes: string[] }}\n */\nexport function useDragDrop(engine) {\n const [isExternalDrag, setIsExternalDrag] = useState(false)\n const [dragFileTypes, setDragFileTypes] = useState([])\n\n useEffect(() => {\n if (!engine) return\n\n const onDragEnter = ({ isExternal, types }) => {\n if (isExternal) {\n setIsExternalDrag(true)\n setDragFileTypes(types || [])\n }\n }\n\n const onDragLeave = () => {\n setIsExternalDrag(false)\n setDragFileTypes([])\n }\n\n const onDragEnd = () => {\n setIsExternalDrag(false)\n setDragFileTypes([])\n }\n\n const onDrop = () => {\n setIsExternalDrag(false)\n setDragFileTypes([])\n }\n\n const unsubs = [\n engine.eventBus.on('drag:enter', onDragEnter),\n engine.eventBus.on('drag:leave', onDragLeave),\n engine.eventBus.on('drag:end', onDragEnd),\n engine.eventBus.on('drop', onDrop),\n ]\n\n return () => unsubs.forEach(unsub => unsub())\n }, [engine])\n\n return { isExternalDrag, dragFileTypes }\n}\n","import { useEffect, useRef, useCallback, useState } from 'react'\n\nconst MIN_SCALE = 0.5\nconst MAX_SCALE = 3.0\n\n/**\n * Calculates distance between two touch points.\n */\nfunction getTouchDistance(t1, t2) {\n const dx = t1.clientX - t2.clientX\n const dy = t1.clientY - t2.clientY\n return Math.sqrt(dx * dx + dy * dy)\n}\n\n/**\n * Detects pinch gestures on <img> and <table> elements within the editor.\n * Scales the element during pinch and applies final width/height on release.\n * Shows a reset-zoom button when an element is zoomed.\n *\n * @param {React.RefObject} editorRef - Ref to the editor content element\n * @returns {{ zoomedElement: Element|null, resetZoom: Function }}\n */\nexport function usePinchZoom(editorRef) {\n const [zoomedElement, setZoomedElement] = useState(null)\n const pinchRef = useRef(null)\n const scaleRef = useRef(1)\n\n const resetZoom = useCallback(() => {\n if (zoomedElement) {\n zoomedElement.style.transform = ''\n zoomedElement.style.transformOrigin = ''\n // Reset size attributes\n if (zoomedElement.tagName === 'IMG') {\n zoomedElement.removeAttribute('data-rmx-zoomed')\n } else {\n // For tables, remove the wrapper scale if present\n const wrapper = zoomedElement.closest('.rmx-pinch-zoom-wrapper')\n if (wrapper) {\n wrapper.style.transform = ''\n }\n zoomedElement.removeAttribute('data-rmx-zoomed')\n }\n setZoomedElement(null)\n }\n }, [zoomedElement])\n\n const handleTouchStart = useCallback((e) => {\n if (e.touches.length !== 2) return\n\n // Find if pinching on an img or table\n const target = e.target\n const zoomable = target.closest('img, table')\n if (!zoomable) return\n\n e.preventDefault()\n\n const initialDistance = getTouchDistance(e.touches[0], e.touches[1])\n\n // Get the current scale of the element\n const currentTransform = zoomable.style.transform\n const match = currentTransform.match(/scale\\(([^)]+)\\)/)\n const currentScale = match ? parseFloat(match[1]) : 1\n\n pinchRef.current = {\n element: zoomable,\n initialDistance,\n initialScale: currentScale,\n }\n\n zoomable.style.transformOrigin = 'center center'\n }, [])\n\n const handleTouchMove = useCallback((e) => {\n if (!pinchRef.current || e.touches.length !== 2) return\n\n e.preventDefault()\n\n const currentDistance = getTouchDistance(e.touches[0], e.touches[1])\n const { initialDistance, initialScale, element } = pinchRef.current\n\n let newScale = initialScale * (currentDistance / initialDistance)\n newScale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, newScale))\n scaleRef.current = newScale\n\n element.style.transform = `scale(${newScale})`\n }, [])\n\n const handleTouchEnd = useCallback((e) => {\n if (!pinchRef.current) return\n\n const { element } = pinchRef.current\n const finalScale = scaleRef.current\n\n if (Math.abs(finalScale - 1) > 0.05) {\n // Apply the scale by adjusting dimensions\n if (element.tagName === 'IMG') {\n const rect = element.getBoundingClientRect()\n const newWidth = Math.round(rect.width)\n const newHeight = Math.round(rect.height)\n element.style.transform = ''\n element.setAttribute('width', newWidth)\n element.setAttribute('height', newHeight)\n element.style.width = `${newWidth}px`\n element.style.height = `${newHeight}px`\n element.setAttribute('data-rmx-zoomed', 'true')\n setZoomedElement(element)\n } else if (element.tagName === 'TABLE') {\n // Keep the transform for tables since they have complex layouts\n element.setAttribute('data-rmx-zoomed', 'true')\n setZoomedElement(element)\n }\n } else {\n // Scale is close to 1, reset\n element.style.transform = ''\n element.style.transformOrigin = ''\n }\n\n pinchRef.current = null\n scaleRef.current = 1\n }, [])\n\n useEffect(() => {\n const el = editorRef?.current\n if (!el) return\n\n el.addEventListener('touchstart', handleTouchStart, { passive: false })\n el.addEventListener('touchmove', handleTouchMove, { passive: false })\n el.addEventListener('touchend', handleTouchEnd, { passive: true })\n\n return () => {\n el.removeEventListener('touchstart', handleTouchStart)\n el.removeEventListener('touchmove', handleTouchMove)\n el.removeEventListener('touchend', handleTouchEnd)\n }\n }, [editorRef, handleTouchStart, handleTouchMove, handleTouchEnd])\n\n return { zoomedElement, resetZoom }\n}\n","import { createContext, useContext } from 'react'\n\n/**\n * Context for sharing selection format state across the editor component tree.\n * Holds the formatState object from useSelection (bold, italic, link, etc.).\n * UI state (hasSelection, focusedImage, etc.) is kept separate in RemyxEditor.\n */\nexport const SelectionContext = createContext(null)\n\n/**\n * Hook to consume the selection format state from context.\n * @returns {import('../hooks/useSelection.js').FormatState} The current format state\n */\nexport function useSelectionContext() {\n return useContext(SelectionContext)\n}\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-is.production.min.js');\n} else {\n module.exports = require('./cjs/react-is.development.js');\n}\n","/** @license React v16.13.1\n * react-is.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';var b=\"function\"===typeof Symbol&&Symbol.for,c=b?Symbol.for(\"react.element\"):60103,d=b?Symbol.for(\"react.portal\"):60106,e=b?Symbol.for(\"react.fragment\"):60107,f=b?Symbol.for(\"react.strict_mode\"):60108,g=b?Symbol.for(\"react.profiler\"):60114,h=b?Symbol.for(\"react.provider\"):60109,k=b?Symbol.for(\"react.context\"):60110,l=b?Symbol.for(\"react.async_mode\"):60111,m=b?Symbol.for(\"react.concurrent_mode\"):60111,n=b?Symbol.for(\"react.forward_ref\"):60112,p=b?Symbol.for(\"react.suspense\"):60113,q=b?\nSymbol.for(\"react.suspense_list\"):60120,r=b?Symbol.for(\"react.memo\"):60115,t=b?Symbol.for(\"react.lazy\"):60116,v=b?Symbol.for(\"react.block\"):60121,w=b?Symbol.for(\"react.fundamental\"):60117,x=b?Symbol.for(\"react.responder\"):60118,y=b?Symbol.for(\"react.scope\"):60119;\nfunction z(a){if(\"object\"===typeof a&&null!==a){var u=a.$$typeof;switch(u){case c:switch(a=a.type,a){case l:case m:case e:case g:case f:case p:return a;default:switch(a=a&&a.$$typeof,a){case k:case n:case t:case r:case h:return a;default:return u}}case d:return u}}}function A(a){return z(a)===m}exports.AsyncMode=l;exports.ConcurrentMode=m;exports.ContextConsumer=k;exports.ContextProvider=h;exports.Element=c;exports.ForwardRef=n;exports.Fragment=e;exports.Lazy=t;exports.Memo=r;exports.Portal=d;\nexports.Profiler=g;exports.StrictMode=f;exports.Suspense=p;exports.isAsyncMode=function(a){return A(a)||z(a)===l};exports.isConcurrentMode=A;exports.isContextConsumer=function(a){return z(a)===k};exports.isContextProvider=function(a){return z(a)===h};exports.isElement=function(a){return\"object\"===typeof a&&null!==a&&a.$$typeof===c};exports.isForwardRef=function(a){return z(a)===n};exports.isFragment=function(a){return z(a)===e};exports.isLazy=function(a){return z(a)===t};\nexports.isMemo=function(a){return z(a)===r};exports.isPortal=function(a){return z(a)===d};exports.isProfiler=function(a){return z(a)===g};exports.isStrictMode=function(a){return z(a)===f};exports.isSuspense=function(a){return z(a)===p};\nexports.isValidElementType=function(a){return\"string\"===typeof a||\"function\"===typeof a||a===e||a===m||a===g||a===f||a===p||a===q||\"object\"===typeof a&&null!==a&&(a.$$typeof===t||a.$$typeof===r||a.$$typeof===h||a.$$typeof===k||a.$$typeof===n||a.$$typeof===w||a.$$typeof===x||a.$$typeof===y||a.$$typeof===v)};exports.typeOf=z;\n","/** @license React v16.13.1\n * react-is.development.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\n\n\nif (process.env.NODE_ENV !== \"production\") {\n (function() {\n'use strict';\n\n// The Symbol used to tag the ReactElement-like types. If there is no native Symbol\n// nor polyfill, then a plain number is used for performance.\nvar hasSymbol = typeof Symbol === 'function' && Symbol.for;\nvar REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;\nvar REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;\nvar REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;\nvar REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;\nvar REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;\nvar REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;\nvar REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary\n// (unstable) APIs that have been removed. Can we remove the symbols?\n\nvar REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for('react.async_mode') : 0xeacf;\nvar REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;\nvar REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;\nvar REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;\nvar REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;\nvar REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;\nvar REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;\nvar REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9;\nvar REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5;\nvar REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6;\nvar REACT_SCOPE_TYPE = hasSymbol ? Symbol.for('react.scope') : 0xead7;\n\nfunction isValidElementType(type) {\n return typeof type === 'string' || typeof type === 'function' || // Note: its typeof might be other than 'symbol' or 'number' if it's a polyfill.\n type === REACT_FRAGMENT_TYPE || type === REACT_CONCURRENT_MODE_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || typeof type === 'object' && type !== null && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_RESPONDER_TYPE || type.$$typeof === REACT_SCOPE_TYPE || type.$$typeof === REACT_BLOCK_TYPE);\n}\n\nfunction typeOf(object) {\n if (typeof object === 'object' && object !== null) {\n var $$typeof = object.$$typeof;\n\n switch ($$typeof) {\n case REACT_ELEMENT_TYPE:\n var type = object.type;\n\n switch (type) {\n case REACT_ASYNC_MODE_TYPE:\n case REACT_CONCURRENT_MODE_TYPE:\n case REACT_FRAGMENT_TYPE:\n case REACT_PROFILER_TYPE:\n case REACT_STRICT_MODE_TYPE:\n case REACT_SUSPENSE_TYPE:\n return type;\n\n default:\n var $$typeofType = type && type.$$typeof;\n\n switch ($$typeofType) {\n case REACT_CONTEXT_TYPE:\n case REACT_FORWARD_REF_TYPE:\n case REACT_LAZY_TYPE:\n case REACT_MEMO_TYPE:\n case REACT_PROVIDER_TYPE:\n return $$typeofType;\n\n default:\n return $$typeof;\n }\n\n }\n\n case REACT_PORTAL_TYPE:\n return $$typeof;\n }\n }\n\n return undefined;\n} // AsyncMode is deprecated along with isAsyncMode\n\nvar AsyncMode = REACT_ASYNC_MODE_TYPE;\nvar ConcurrentMode = REACT_CONCURRENT_MODE_TYPE;\nvar ContextConsumer = REACT_CONTEXT_TYPE;\nvar ContextProvider = REACT_PROVIDER_TYPE;\nvar Element = REACT_ELEMENT_TYPE;\nvar ForwardRef = REACT_FORWARD_REF_TYPE;\nvar Fragment = REACT_FRAGMENT_TYPE;\nvar Lazy = REACT_LAZY_TYPE;\nvar Memo = REACT_MEMO_TYPE;\nvar Portal = REACT_PORTAL_TYPE;\nvar Profiler = REACT_PROFILER_TYPE;\nvar StrictMode = REACT_STRICT_MODE_TYPE;\nvar Suspense = REACT_SUSPENSE_TYPE;\nvar hasWarnedAboutDeprecatedIsAsyncMode = false; // AsyncMode should be deprecated\n\nfunction isAsyncMode(object) {\n {\n if (!hasWarnedAboutDeprecatedIsAsyncMode) {\n hasWarnedAboutDeprecatedIsAsyncMode = true; // Using console['warn'] to evade Babel and ESLint\n\n console['warn']('The ReactIs.isAsyncMode() alias has been deprecated, ' + 'and will be removed in React 17+. Update your code to use ' + 'ReactIs.isConcurrentMode() instead. It has the exact same API.');\n }\n }\n\n return isConcurrentMode(object) || typeOf(object) === REACT_ASYNC_MODE_TYPE;\n}\nfunction isConcurrentMode(object) {\n return typeOf(object) === REACT_CONCURRENT_MODE_TYPE;\n}\nfunction isContextConsumer(object) {\n return typeOf(object) === REACT_CONTEXT_TYPE;\n}\nfunction isContextProvider(object) {\n return typeOf(object) === REACT_PROVIDER_TYPE;\n}\nfunction isElement(object) {\n return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;\n}\nfunction isForwardRef(object) {\n return typeOf(object) === REACT_FORWARD_REF_TYPE;\n}\nfunction isFragment(object) {\n return typeOf(object) === REACT_FRAGMENT_TYPE;\n}\nfunction isLazy(object) {\n return typeOf(object) === REACT_LAZY_TYPE;\n}\nfunction isMemo(object) {\n return typeOf(object) === REACT_MEMO_TYPE;\n}\nfunction isPortal(object) {\n return typeOf(object) === REACT_PORTAL_TYPE;\n}\nfunction isProfiler(object) {\n return typeOf(object) === REACT_PROFILER_TYPE;\n}\nfunction isStrictMode(object) {\n return typeOf(object) === REACT_STRICT_MODE_TYPE;\n}\nfunction isSuspense(object) {\n return typeOf(object) === REACT_SUSPENSE_TYPE;\n}\n\nexports.AsyncMode = AsyncMode;\nexports.ConcurrentMode = ConcurrentMode;\nexports.ContextConsumer = ContextConsumer;\nexports.ContextProvider = ContextProvider;\nexports.Element = Element;\nexports.ForwardRef = ForwardRef;\nexports.Fragment = Fragment;\nexports.Lazy = Lazy;\nexports.Memo = Memo;\nexports.Portal = Portal;\nexports.Profiler = Profiler;\nexports.StrictMode = StrictMode;\nexports.Suspense = Suspense;\nexports.isAsyncMode = isAsyncMode;\nexports.isConcurrentMode = isConcurrentMode;\nexports.isContextConsumer = isContextConsumer;\nexports.isContextProvider = isContextProvider;\nexports.isElement = isElement;\nexports.isForwardRef = isForwardRef;\nexports.isFragment = isFragment;\nexports.isLazy = isLazy;\nexports.isMemo = isMemo;\nexports.isPortal = isPortal;\nexports.isProfiler = isProfiler;\nexports.isStrictMode = isStrictMode;\nexports.isSuspense = isSuspense;\nexports.isValidElementType = isValidElementType;\nexports.typeOf = typeOf;\n })();\n}\n","/*\nobject-assign\n(c) Sindre Sorhus\n@license MIT\n*/\n\n'use strict';\n/* eslint-disable no-unused-vars */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nfunction shouldUseNative() {\n\ttry {\n\t\tif (!Object.assign) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Detect buggy property enumeration order in older V8 versions.\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\tvar test1 = new String('abc'); // eslint-disable-line no-new-wrappers\n\t\ttest1[5] = 'de';\n\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test2 = {};\n\t\tfor (var i = 0; i < 10; i++) {\n\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t}\n\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\treturn test2[n];\n\t\t});\n\t\tif (order2.join('') !== '0123456789') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test3 = {};\n\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\ttest3[letter] = letter;\n\t\t});\n\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} catch (err) {\n\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\treturn false;\n\t}\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (getOwnPropertySymbols) {\n\t\t\tsymbols = getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';\n\nmodule.exports = ReactPropTypesSecret;\n","module.exports = Function.call.bind(Object.prototype.hasOwnProperty);\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar printWarning = function() {};\n\nif (process.env.NODE_ENV !== 'production') {\n var ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');\n var loggedTypeFailures = {};\n var has = require('./lib/has');\n\n printWarning = function(text) {\n var message = 'Warning: ' + text;\n if (typeof console !== 'undefined') {\n console.error(message);\n }\n try {\n // --- Welcome to debugging React ---\n // This error was thrown as a convenience so that you can use this stack\n // to find the callsite that caused this warning to fire.\n throw new Error(message);\n } catch (x) { /**/ }\n };\n}\n\n/**\n * Assert that the values match with the type specs.\n * Error messages are memorized and will only be shown once.\n *\n * @param {object} typeSpecs Map of name to a ReactPropType\n * @param {object} values Runtime values that need to be type-checked\n * @param {string} location e.g. \"prop\", \"context\", \"child context\"\n * @param {string} componentName Name of the component for error messages.\n * @param {?Function} getStack Returns the component stack.\n * @private\n */\nfunction checkPropTypes(typeSpecs, values, location, componentName, getStack) {\n if (process.env.NODE_ENV !== 'production') {\n for (var typeSpecName in typeSpecs) {\n if (has(typeSpecs, typeSpecName)) {\n var error;\n // Prop type validation may throw. In case they do, we don't want to\n // fail the render phase where it didn't fail before. So we log it.\n // After these have been cleaned up, we'll let them throw.\n try {\n // This is intentionally an invariant that gets caught. It's the same\n // behavior as without this statement except with a better message.\n if (typeof typeSpecs[typeSpecName] !== 'function') {\n var err = Error(\n (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +\n 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' +\n 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.'\n );\n err.name = 'Invariant Violation';\n throw err;\n }\n error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);\n } catch (ex) {\n error = ex;\n }\n if (error && !(error instanceof Error)) {\n printWarning(\n (componentName || 'React class') + ': type specification of ' +\n location + ' `' + typeSpecName + '` is invalid; the type checker ' +\n 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +\n 'You may have forgotten to pass an argument to the type checker ' +\n 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +\n 'shape all require an argument).'\n );\n }\n if (error instanceof Error && !(error.message in loggedTypeFailures)) {\n // Only monitor this failure once because there tends to be a lot of the\n // same error.\n loggedTypeFailures[error.message] = true;\n\n var stack = getStack ? getStack() : '';\n\n printWarning(\n 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')\n );\n }\n }\n }\n }\n}\n\n/**\n * Resets warning cache when testing.\n *\n * @private\n */\ncheckPropTypes.resetWarningCache = function() {\n if (process.env.NODE_ENV !== 'production') {\n loggedTypeFailures = {};\n }\n}\n\nmodule.exports = checkPropTypes;\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactIs = require('react-is');\nvar assign = require('object-assign');\n\nvar ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');\nvar has = require('./lib/has');\nvar checkPropTypes = require('./checkPropTypes');\n\nvar printWarning = function() {};\n\nif (process.env.NODE_ENV !== 'production') {\n printWarning = function(text) {\n var message = 'Warning: ' + text;\n if (typeof console !== 'undefined') {\n console.error(message);\n }\n try {\n // --- Welcome to debugging React ---\n // This error was thrown as a convenience so that you can use this stack\n // to find the callsite that caused this warning to fire.\n throw new Error(message);\n } catch (x) {}\n };\n}\n\nfunction emptyFunctionThatReturnsNull() {\n return null;\n}\n\nmodule.exports = function(isValidElement, throwOnDirectAccess) {\n /* global Symbol */\n var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;\n var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.\n\n /**\n * Returns the iterator method function contained on the iterable object.\n *\n * Be sure to invoke the function with the iterable as context:\n *\n * var iteratorFn = getIteratorFn(myIterable);\n * if (iteratorFn) {\n * var iterator = iteratorFn.call(myIterable);\n * ...\n * }\n *\n * @param {?object} maybeIterable\n * @return {?function}\n */\n function getIteratorFn(maybeIterable) {\n var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]);\n if (typeof iteratorFn === 'function') {\n return iteratorFn;\n }\n }\n\n /**\n * Collection of methods that allow declaration and validation of props that are\n * supplied to React components. Example usage:\n *\n * var Props = require('ReactPropTypes');\n * var MyArticle = React.createClass({\n * propTypes: {\n * // An optional string prop named \"description\".\n * description: Props.string,\n *\n * // A required enum prop named \"category\".\n * category: Props.oneOf(['News','Photos']).isRequired,\n *\n * // A prop named \"dialog\" that requires an instance of Dialog.\n * dialog: Props.instanceOf(Dialog).isRequired\n * },\n * render: function() { ... }\n * });\n *\n * A more formal specification of how these methods are used:\n *\n * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...)\n * decl := ReactPropTypes.{type}(.isRequired)?\n *\n * Each and every declaration produces a function with the same signature. This\n * allows the creation of custom validation functions. For example:\n *\n * var MyLink = React.createClass({\n * propTypes: {\n * // An optional string or URI prop named \"href\".\n * href: function(props, propName, componentName) {\n * var propValue = props[propName];\n * if (propValue != null && typeof propValue !== 'string' &&\n * !(propValue instanceof URI)) {\n * return new Error(\n * 'Expected a string or an URI for ' + propName + ' in ' +\n * componentName\n * );\n * }\n * }\n * },\n * render: function() {...}\n * });\n *\n * @internal\n */\n\n var ANONYMOUS = '<<anonymous>>';\n\n // Important!\n // Keep this list in sync with production version in `./factoryWithThrowingShims.js`.\n var ReactPropTypes = {\n array: createPrimitiveTypeChecker('array'),\n bigint: createPrimitiveTypeChecker('bigint'),\n bool: createPrimitiveTypeChecker('boolean'),\n func: createPrimitiveTypeChecker('function'),\n number: createPrimitiveTypeChecker('number'),\n object: createPrimitiveTypeChecker('object'),\n string: createPrimitiveTypeChecker('string'),\n symbol: createPrimitiveTypeChecker('symbol'),\n\n any: createAnyTypeChecker(),\n arrayOf: createArrayOfTypeChecker,\n element: createElementTypeChecker(),\n elementType: createElementTypeTypeChecker(),\n instanceOf: createInstanceTypeChecker,\n node: createNodeChecker(),\n objectOf: createObjectOfTypeChecker,\n oneOf: createEnumTypeChecker,\n oneOfType: createUnionTypeChecker,\n shape: createShapeTypeChecker,\n exact: createStrictShapeTypeChecker,\n };\n\n /**\n * inlined Object.is polyfill to avoid requiring consumers ship their own\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is\n */\n /*eslint-disable no-self-compare*/\n function is(x, y) {\n // SameValue algorithm\n if (x === y) {\n // Steps 1-5, 7-10\n // Steps 6.b-6.e: +0 != -0\n return x !== 0 || 1 / x === 1 / y;\n } else {\n // Step 6.a: NaN == NaN\n return x !== x && y !== y;\n }\n }\n /*eslint-enable no-self-compare*/\n\n /**\n * We use an Error-like object for backward compatibility as people may call\n * PropTypes directly and inspect their output. However, we don't use real\n * Errors anymore. We don't inspect their stack anyway, and creating them\n * is prohibitively expensive if they are created too often, such as what\n * happens in oneOfType() for any type before the one that matched.\n */\n function PropTypeError(message, data) {\n this.message = message;\n this.data = data && typeof data === 'object' ? data: {};\n this.stack = '';\n }\n // Make `instanceof Error` still work for returned errors.\n PropTypeError.prototype = Error.prototype;\n\n function createChainableTypeChecker(validate) {\n if (process.env.NODE_ENV !== 'production') {\n var manualPropTypeCallCache = {};\n var manualPropTypeWarningCount = 0;\n }\n function checkType(isRequired, props, propName, componentName, location, propFullName, secret) {\n componentName = componentName || ANONYMOUS;\n propFullName = propFullName || propName;\n\n if (secret !== ReactPropTypesSecret) {\n if (throwOnDirectAccess) {\n // New behavior only for users of `prop-types` package\n var err = new Error(\n 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +\n 'Use `PropTypes.checkPropTypes()` to call them. ' +\n 'Read more at http://fb.me/use-check-prop-types'\n );\n err.name = 'Invariant Violation';\n throw err;\n } else if (process.env.NODE_ENV !== 'production' && typeof console !== 'undefined') {\n // Old behavior for people using React.PropTypes\n var cacheKey = componentName + ':' + propName;\n if (\n !manualPropTypeCallCache[cacheKey] &&\n // Avoid spamming the console because they are often not actionable except for lib authors\n manualPropTypeWarningCount < 3\n ) {\n printWarning(\n 'You are manually calling a React.PropTypes validation ' +\n 'function for the `' + propFullName + '` prop on `' + componentName + '`. This is deprecated ' +\n 'and will throw in the standalone `prop-types` package. ' +\n 'You may be seeing this warning due to a third-party PropTypes ' +\n 'library. See https://fb.me/react-warning-dont-call-proptypes ' + 'for details.'\n );\n manualPropTypeCallCache[cacheKey] = true;\n manualPropTypeWarningCount++;\n }\n }\n }\n if (props[propName] == null) {\n if (isRequired) {\n if (props[propName] === null) {\n return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.'));\n }\n return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.'));\n }\n return null;\n } else {\n return validate(props, propName, componentName, location, propFullName);\n }\n }\n\n var chainedCheckType = checkType.bind(null, false);\n chainedCheckType.isRequired = checkType.bind(null, true);\n\n return chainedCheckType;\n }\n\n function createPrimitiveTypeChecker(expectedType) {\n function validate(props, propName, componentName, location, propFullName, secret) {\n var propValue = props[propName];\n var propType = getPropType(propValue);\n if (propType !== expectedType) {\n // `propValue` being instance of, say, date/regexp, pass the 'object'\n // check, but we can offer a more precise error message here rather than\n // 'of type `object`'.\n var preciseType = getPreciseType(propValue);\n\n return new PropTypeError(\n 'Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.'),\n {expectedType: expectedType}\n );\n }\n return null;\n }\n return createChainableTypeChecker(validate);\n }\n\n function createAnyTypeChecker() {\n return createChainableTypeChecker(emptyFunctionThatReturnsNull);\n }\n\n function createArrayOfTypeChecker(typeChecker) {\n function validate(props, propName, componentName, location, propFullName) {\n if (typeof typeChecker !== 'function') {\n return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.');\n }\n var propValue = props[propName];\n if (!Array.isArray(propValue)) {\n var propType = getPropType(propValue);\n return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.'));\n }\n for (var i = 0; i < propValue.length; i++) {\n var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret);\n if (error instanceof Error) {\n return error;\n }\n }\n return null;\n }\n return createChainableTypeChecker(validate);\n }\n\n function createElementTypeChecker() {\n function validate(props, propName, componentName, location, propFullName) {\n var propValue = props[propName];\n if (!isValidElement(propValue)) {\n var propType = getPropType(propValue);\n return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.'));\n }\n return null;\n }\n return createChainableTypeChecker(validate);\n }\n\n function createElementTypeTypeChecker() {\n function validate(props, propName, componentName, location, propFullName) {\n var propValue = props[propName];\n if (!ReactIs.isValidElementType(propValue)) {\n var propType = getPropType(propValue);\n return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement type.'));\n }\n return null;\n }\n return createChainableTypeChecker(validate);\n }\n\n function createInstanceTypeChecker(expectedClass) {\n function validate(props, propName, componentName, location, propFullName) {\n if (!(props[propName] instanceof expectedClass)) {\n var expectedClassName = expectedClass.name || ANONYMOUS;\n var actualClassName = getClassName(props[propName]);\n return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.'));\n }\n return null;\n }\n return createChainableTypeChecker(validate);\n }\n\n function createEnumTypeChecker(expectedValues) {\n if (!Array.isArray(expectedValues)) {\n if (process.env.NODE_ENV !== 'production') {\n if (arguments.length > 1) {\n printWarning(\n 'Invalid arguments supplied to oneOf, expected an array, got ' + arguments.length + ' arguments. ' +\n 'A common mistake is to write oneOf(x, y, z) instead of oneOf([x, y, z]).'\n );\n } else {\n printWarning('Invalid argument supplied to oneOf, expected an array.');\n }\n }\n return emptyFunctionThatReturnsNull;\n }\n\n function validate(props, propName, componentName, location, propFullName) {\n var propValue = props[propName];\n for (var i = 0; i < expectedValues.length; i++) {\n if (is(propValue, expectedValues[i])) {\n return null;\n }\n }\n\n var valuesString = JSON.stringify(expectedValues, function replacer(key, value) {\n var type = getPreciseType(value);\n if (type === 'symbol') {\n return String(value);\n }\n return value;\n });\n return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + String(propValue) + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.'));\n }\n return createChainableTypeChecker(validate);\n }\n\n function createObjectOfTypeChecker(typeChecker) {\n function validate(props, propName, componentName, location, propFullName) {\n if (typeof typeChecker !== 'function') {\n return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.');\n }\n var propValue = props[propName];\n var propType = getPropType(propValue);\n if (propType !== 'object') {\n return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.'));\n }\n for (var key in propValue) {\n if (has(propValue, key)) {\n var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);\n if (error instanceof Error) {\n return error;\n }\n }\n }\n return null;\n }\n return createChainableTypeChecker(validate);\n }\n\n function createUnionTypeChecker(arrayOfTypeCheckers) {\n if (!Array.isArray(arrayOfTypeCheckers)) {\n process.env.NODE_ENV !== 'production' ? printWarning('Invalid argument supplied to oneOfType, expected an instance of array.') : void 0;\n return emptyFunctionThatReturnsNull;\n }\n\n for (var i = 0; i < arrayOfTypeCheckers.length; i++) {\n var checker = arrayOfTypeCheckers[i];\n if (typeof checker !== 'function') {\n printWarning(\n 'Invalid argument supplied to oneOfType. Expected an array of check functions, but ' +\n 'received ' + getPostfixForTypeWarning(checker) + ' at index ' + i + '.'\n );\n return emptyFunctionThatReturnsNull;\n }\n }\n\n function validate(props, propName, componentName, location, propFullName) {\n var expectedTypes = [];\n for (var i = 0; i < arrayOfTypeCheckers.length; i++) {\n var checker = arrayOfTypeCheckers[i];\n var checkerResult = checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret);\n if (checkerResult == null) {\n return null;\n }\n if (checkerResult.data && has(checkerResult.data, 'expectedType')) {\n expectedTypes.push(checkerResult.data.expectedType);\n }\n }\n var expectedTypesMessage = (expectedTypes.length > 0) ? ', expected one of type [' + expectedTypes.join(', ') + ']': '';\n return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`' + expectedTypesMessage + '.'));\n }\n return createChainableTypeChecker(validate);\n }\n\n function createNodeChecker() {\n function validate(props, propName, componentName, location, propFullName) {\n if (!isNode(props[propName])) {\n return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.'));\n }\n return null;\n }\n return createChainableTypeChecker(validate);\n }\n\n function invalidValidatorError(componentName, location, propFullName, key, type) {\n return new PropTypeError(\n (componentName || 'React class') + ': ' + location + ' type `' + propFullName + '.' + key + '` is invalid; ' +\n 'it must be a function, usually from the `prop-types` package, but received `' + type + '`.'\n );\n }\n\n function createShapeTypeChecker(shapeTypes) {\n function validate(props, propName, componentName, location, propFullName) {\n var propValue = props[propName];\n var propType = getPropType(propValue);\n if (propType !== 'object') {\n return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));\n }\n for (var key in shapeTypes) {\n var checker = shapeTypes[key];\n if (typeof checker !== 'function') {\n return invalidValidatorError(componentName, location, propFullName, key, getPreciseType(checker));\n }\n var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);\n if (error) {\n return error;\n }\n }\n return null;\n }\n return createChainableTypeChecker(validate);\n }\n\n function createStrictShapeTypeChecker(shapeTypes) {\n function validate(props, propName, componentName, location, propFullName) {\n var propValue = props[propName];\n var propType = getPropType(propValue);\n if (propType !== 'object') {\n return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type `' + propType + '` ' + ('supplied to `' + componentName + '`, expected `object`.'));\n }\n // We need to check all keys in case some are required but missing from props.\n var allKeys = assign({}, props[propName], shapeTypes);\n for (var key in allKeys) {\n var checker = shapeTypes[key];\n if (has(shapeTypes, key) && typeof checker !== 'function') {\n return invalidValidatorError(componentName, location, propFullName, key, getPreciseType(checker));\n }\n if (!checker) {\n return new PropTypeError(\n 'Invalid ' + location + ' `' + propFullName + '` key `' + key + '` supplied to `' + componentName + '`.' +\n '\\nBad object: ' + JSON.stringify(props[propName], null, ' ') +\n '\\nValid keys: ' + JSON.stringify(Object.keys(shapeTypes), null, ' ')\n );\n }\n var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret);\n if (error) {\n return error;\n }\n }\n return null;\n }\n\n return createChainableTypeChecker(validate);\n }\n\n function isNode(propValue) {\n switch (typeof propValue) {\n case 'number':\n case 'string':\n case 'undefined':\n return true;\n case 'boolean':\n return !propValue;\n case 'object':\n if (Array.isArray(propValue)) {\n return propValue.every(isNode);\n }\n if (propValue === null || isValidElement(propValue)) {\n return true;\n }\n\n var iteratorFn = getIteratorFn(propValue);\n if (iteratorFn) {\n var iterator = iteratorFn.call(propValue);\n var step;\n if (iteratorFn !== propValue.entries) {\n while (!(step = iterator.next()).done) {\n if (!isNode(step.value)) {\n return false;\n }\n }\n } else {\n // Iterator will provide entry [k,v] tuples rather than values.\n while (!(step = iterator.next()).done) {\n var entry = step.value;\n if (entry) {\n if (!isNode(entry[1])) {\n return false;\n }\n }\n }\n }\n } else {\n return false;\n }\n\n return true;\n default:\n return false;\n }\n }\n\n function isSymbol(propType, propValue) {\n // Native Symbol.\n if (propType === 'symbol') {\n return true;\n }\n\n // falsy value can't be a Symbol\n if (!propValue) {\n return false;\n }\n\n // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'\n if (propValue['@@toStringTag'] === 'Symbol') {\n return true;\n }\n\n // Fallback for non-spec compliant Symbols which are polyfilled.\n if (typeof Symbol === 'function' && propValue instanceof Symbol) {\n return true;\n }\n\n return false;\n }\n\n // Equivalent of `typeof` but with special handling for array and regexp.\n function getPropType(propValue) {\n var propType = typeof propValue;\n if (Array.isArray(propValue)) {\n return 'array';\n }\n if (propValue instanceof RegExp) {\n // Old webkits (at least until Android 4.0) return 'function' rather than\n // 'object' for typeof a RegExp. We'll normalize this here so that /bla/\n // passes PropTypes.object.\n return 'object';\n }\n if (isSymbol(propType, propValue)) {\n return 'symbol';\n }\n return propType;\n }\n\n // This handles more types than `getPropType`. Only used for error messages.\n // See `createPrimitiveTypeChecker`.\n function getPreciseType(propValue) {\n if (typeof propValue === 'undefined' || propValue === null) {\n return '' + propValue;\n }\n var propType = getPropType(propValue);\n if (propType === 'object') {\n if (propValue instanceof Date) {\n return 'date';\n } else if (propValue instanceof RegExp) {\n return 'regexp';\n }\n }\n return propType;\n }\n\n // Returns a string that is postfixed to a warning about an invalid type.\n // For example, \"undefined\" or \"of type array\"\n function getPostfixForTypeWarning(value) {\n var type = getPreciseType(value);\n switch (type) {\n case 'array':\n case 'object':\n return 'an ' + type;\n case 'boolean':\n case 'date':\n case 'regexp':\n return 'a ' + type;\n default:\n return type;\n }\n }\n\n // Returns class name of the object, if any.\n function getClassName(propValue) {\n if (!propValue.constructor || !propValue.constructor.name) {\n return ANONYMOUS;\n }\n return propValue.constructor.name;\n }\n\n ReactPropTypes.checkPropTypes = checkPropTypes;\n ReactPropTypes.resetWarningCache = checkPropTypes.resetWarningCache;\n ReactPropTypes.PropTypes = ReactPropTypes;\n\n return ReactPropTypes;\n};\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');\n\nfunction emptyFunction() {}\nfunction emptyFunctionWithReset() {}\nemptyFunctionWithReset.resetWarningCache = emptyFunction;\n\nmodule.exports = function() {\n function shim(props, propName, componentName, location, propFullName, secret) {\n if (secret === ReactPropTypesSecret) {\n // It is still safe when called from React.\n return;\n }\n var err = new Error(\n 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +\n 'Use PropTypes.checkPropTypes() to call them. ' +\n 'Read more at http://fb.me/use-check-prop-types'\n );\n err.name = 'Invariant Violation';\n throw err;\n };\n shim.isRequired = shim;\n function getShim() {\n return shim;\n };\n // Important!\n // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.\n var ReactPropTypes = {\n array: shim,\n bigint: shim,\n bool: shim,\n func: shim,\n number: shim,\n object: shim,\n string: shim,\n symbol: shim,\n\n any: shim,\n arrayOf: getShim,\n element: shim,\n elementType: shim,\n instanceOf: getShim,\n node: shim,\n objectOf: getShim,\n oneOf: getShim,\n oneOfType: getShim,\n shape: getShim,\n exact: getShim,\n\n checkPropTypes: emptyFunctionWithReset,\n resetWarningCache: emptyFunction\n };\n\n ReactPropTypes.PropTypes = ReactPropTypes;\n\n return ReactPropTypes;\n};\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nif (process.env.NODE_ENV !== 'production') {\n var ReactIs = require('react-is');\n\n // By explicitly using `prop-types` you are opting into new development behavior.\n // http://fb.me/prop-types-in-prod\n var throwOnDirectAccess = true;\n module.exports = require('./factoryWithTypeCheckers')(ReactIs.isElement, throwOnDirectAccess);\n} else {\n // By explicitly using `prop-types` you are opting into new production behavior.\n // http://fb.me/prop-types-in-prod\n module.exports = require('./factoryWithThrowingShims')();\n}\n","import React from 'react'\n\n/**\n * Create a stroke-based SVG icon component from a path or child elements.\n * @param {string|React.ReactNode} d - SVG path string or child elements\n * @param {string} [viewBox='0 0 24 24'] - SVG viewBox attribute\n * @returns {React.FC<{size?: number, className?: string}>}\n */\nexport const icon = (d, viewBox = '0 0 24 24') => ({ size = 18, className = '' }) => (\n <svg width={size} height={size} viewBox={viewBox} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" className={`rmx-icon ${className}`}>\n {typeof d === 'string' ? <path d={d} /> : d}\n </svg>\n)\n\n/**\n * Create a filled SVG icon component from child elements.\n * @param {React.ReactNode} children - SVG child elements\n * @param {string} [viewBox='0 0 24 24'] - SVG viewBox attribute\n * @returns {React.FC<{size?: number, className?: string}>}\n */\nexport const filled = (children, viewBox = '0 0 24 24') => ({ size = 18, className = '' }) => (\n <svg width={size} height={size} viewBox={viewBox} fill=\"currentColor\" className={`rmx-icon ${className}`}>\n {children}\n </svg>\n)\n","import React from 'react'\nimport { icon, filled } from './helpers.jsx'\n\nexport const BoldIcon = filled(\n <path d=\"M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6zM6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n)\n\nexport const ItalicIcon = icon(\n <>\n <line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\" />\n <line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\" />\n <line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\" />\n </>\n)\n\nexport const UnderlineIcon = icon(\n <>\n <path d=\"M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3\" />\n <line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\" />\n </>\n)\n\nexport const StrikethroughIcon = icon(\n <>\n <path d=\"M16 4H9a3 3 0 0 0-3 3c0 2 1.5 3 4 3.5\" />\n <path d=\"M14 16.5c0 1.38-1.12 2.5-2.5 2.5H9\" />\n <line x1=\"4\" y1=\"12\" x2=\"20\" y2=\"12\" />\n </>\n)\n\nexport const SubscriptIcon = filled(\n <>\n <text x=\"2\" y=\"16\" fontSize=\"16\" fontWeight=\"bold\" fill=\"currentColor\" stroke=\"none\">x</text>\n <text x=\"14\" y=\"20\" fontSize=\"10\" fill=\"currentColor\" stroke=\"none\">2</text>\n </>\n)\n\nexport const SuperscriptIcon = filled(\n <>\n <text x=\"2\" y=\"18\" fontSize=\"16\" fontWeight=\"bold\" fill=\"currentColor\" stroke=\"none\">x</text>\n <text x=\"14\" y=\"10\" fontSize=\"10\" fill=\"currentColor\" stroke=\"none\">2</text>\n </>\n)\n\nexport const HeadingIcon = filled(\n <>\n <path d=\"M6 4v16M18 4v16M6 12h12\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </>\n)\n\nexport const AlignLeftIcon = icon(\n <>\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <line x1=\"3\" y1=\"12\" x2=\"15\" y2=\"12\" />\n <line x1=\"3\" y1=\"18\" x2=\"18\" y2=\"18\" />\n </>\n)\n\nexport const AlignCenterIcon = icon(\n <>\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <line x1=\"6\" y1=\"12\" x2=\"18\" y2=\"12\" />\n <line x1=\"4\" y1=\"18\" x2=\"20\" y2=\"18\" />\n </>\n)\n\nexport const AlignRightIcon = icon(\n <>\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <line x1=\"9\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"6\" y1=\"18\" x2=\"21\" y2=\"18\" />\n </>\n)\n\nexport const AlignJustifyIcon = icon(\n <>\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\" />\n </>\n)\n\nexport const OrderedListIcon = icon(\n <>\n <line x1=\"10\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <line x1=\"10\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"10\" y1=\"18\" x2=\"21\" y2=\"18\" />\n <text x=\"4\" y=\"7.5\" fontSize=\"6\" fill=\"currentColor\" stroke=\"none\" fontWeight=\"bold\">1.</text>\n <text x=\"4\" y=\"13.5\" fontSize=\"6\" fill=\"currentColor\" stroke=\"none\" fontWeight=\"bold\">2.</text>\n <text x=\"4\" y=\"19.5\" fontSize=\"6\" fill=\"currentColor\" stroke=\"none\" fontWeight=\"bold\">3.</text>\n </>\n)\n\nexport const UnorderedListIcon = icon(\n <>\n <line x1=\"9\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <line x1=\"9\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"9\" y1=\"18\" x2=\"21\" y2=\"18\" />\n <circle cx=\"5\" cy=\"6\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\" />\n <circle cx=\"5\" cy=\"12\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\" />\n <circle cx=\"5\" cy=\"18\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\" />\n </>\n)\n\nexport const TaskListIcon = icon(\n <>\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\" />\n <line x1=\"13\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\" />\n <line x1=\"13\" y1=\"18\" x2=\"21\" y2=\"18\" />\n <polyline points=\"5.5 5.5 6.5 7 8.5 4\" strokeWidth=\"1.5\" />\n </>\n)\n\nexport const LinkIcon = icon(\n <>\n <path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\" />\n <path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\" />\n </>\n)\n\nexport const UnlinkIcon = icon(\n <>\n <path d=\"M18.84 12.25l1.72-1.71a5 5 0 0 0-7.07-7.07l-3 3a5 5 0 0 0 .12 7.19\" />\n <path d=\"M5.16 11.75l-1.72 1.71a5 5 0 0 0 7.07 7.07l3-3a5 5 0 0 0-.12-7.19\" />\n <line x1=\"2\" y1=\"2\" x2=\"22\" y2=\"22\" />\n </>\n)\n\nexport const ImageIcon = icon(\n <>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\" />\n <polyline points=\"21 15 16 10 5 21\" />\n </>\n)\n\nexport const TableIcon = icon(\n <>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\" />\n <line x1=\"3\" y1=\"15\" x2=\"21\" y2=\"15\" />\n <line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\" />\n <line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\" />\n </>\n)\n\nexport const BlockquoteIcon = filled(\n <>\n <path d=\"M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z\" />\n <path d=\"M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z\" />\n </>\n)\n\nexport const CodeBlockIcon = icon(\n <>\n <polyline points=\"16 18 22 12 16 6\" />\n <polyline points=\"8 6 2 12 8 18\" />\n </>\n)\n\nexport const HorizontalRuleIcon = icon(\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\" strokeWidth=\"3\" />\n)\n\nexport const UndoIcon = icon(\n <>\n <polyline points=\"1 4 1 10 7 10\" />\n <path d=\"M3.51 15a9 9 0 1 0 2.13-9.36L1 10\" />\n </>\n)\n\nexport const RedoIcon = icon(\n <>\n <polyline points=\"23 4 23 10 17 10\" />\n <path d=\"M20.49 15a9 9 0 1 1-2.12-9.36L23 10\" />\n </>\n)\n\nexport const ForeColorIcon = ({ size = 18, color = '#000000', className = '' }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" className={`rmx-icon ${className}`}>\n <text x=\"6\" y=\"16\" fontSize=\"16\" fontWeight=\"bold\" fill=\"currentColor\" stroke=\"none\">A</text>\n <rect x=\"3\" y=\"20\" width=\"18\" height=\"3\" rx=\"1\" fill={color} />\n </svg>\n)\n\nexport const BackColorIcon = ({ size = 18, color = '#ffff00', className = '' }) => (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" className={`rmx-icon ${className}`}>\n <rect x=\"2\" y=\"2\" width=\"20\" height=\"16\" rx=\"2\" fill={color} opacity=\"0.3\" />\n <text x=\"6\" y=\"14\" fontSize=\"14\" fontWeight=\"bold\" fill=\"currentColor\" stroke=\"none\">A</text>\n <rect x=\"3\" y=\"20\" width=\"18\" height=\"3\" rx=\"1\" fill={color} />\n </svg>\n)\n\nexport const FontFamilyIcon = filled(\n <text x=\"3\" y=\"18\" fontSize=\"18\" fontWeight=\"bold\" fill=\"currentColor\" stroke=\"none\" fontFamily=\"serif\">T</text>\n)\n\nexport const FontSizeIcon = filled(\n <>\n <text x=\"1\" y=\"20\" fontSize=\"20\" fontWeight=\"bold\" fill=\"currentColor\" stroke=\"none\">A</text>\n <text x=\"14\" y=\"20\" fontSize=\"12\" fill=\"currentColor\" stroke=\"none\">A</text>\n </>\n)\n\nexport const EmbedMediaIcon = icon(\n <>\n <rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\" />\n <polygon points=\"10 9 15 12 10 15\" fill=\"currentColor\" stroke=\"none\" />\n </>\n)\n\nexport const FindReplaceIcon = icon(\n <>\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n </>\n)\n\nexport const SourceModeIcon = icon(\n <>\n <polyline points=\"16 18 22 12 16 6\" />\n <polyline points=\"8 6 2 12 8 18\" />\n <line x1=\"14\" y1=\"4\" x2=\"10\" y2=\"20\" strokeWidth=\"1\" />\n </>\n)\n\nexport const FullscreenIcon = icon(\n <>\n <polyline points=\"15 3 21 3 21 9\" />\n <polyline points=\"9 21 3 21 3 15\" />\n <line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\" />\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\n </>\n)\n\nexport const ExitFullscreenIcon = icon(\n <>\n <polyline points=\"4 14 10 14 10 20\" />\n <polyline points=\"20 10 14 10 14 4\" />\n <line x1=\"14\" y1=\"10\" x2=\"21\" y2=\"3\" />\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\n </>\n)\n\nexport const IndentIcon = icon(\n <>\n <line x1=\"21\" y1=\"6\" x2=\"11\" y2=\"6\" />\n <line x1=\"21\" y1=\"12\" x2=\"11\" y2=\"12\" />\n <line x1=\"21\" y1=\"18\" x2=\"11\" y2=\"18\" />\n <polyline points=\"3 8 7 12 3 16\" />\n </>\n)\n\nexport const OutdentIcon = icon(\n <>\n <line x1=\"21\" y1=\"6\" x2=\"11\" y2=\"6\" />\n <line x1=\"21\" y1=\"12\" x2=\"11\" y2=\"12\" />\n <line x1=\"21\" y1=\"18\" x2=\"11\" y2=\"18\" />\n <polyline points=\"7 8 3 12 7 16\" />\n </>\n)\n\nexport const ExportIcon = icon(\n <>\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" />\n </>\n)\n\nexport const CommandPaletteIcon = icon(\n <>\n <polyline points=\"4 17 10 11 4 5\" />\n <line x1=\"12\" y1=\"19\" x2=\"20\" y2=\"19\" />\n </>\n)\n\nexport const ToggleMarkdownIcon = filled(\n <>\n <path d=\"M3 5h18v14H3V5zm2 2v10h14V7H5z\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M7 15V9l2.5 3L12 9v6\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M17 15l-2-2.5V15\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M15 12.5V9\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </>\n)\n\nexport const ImportDocumentIcon = icon(\n <>\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <polyline points=\"14 2 14 8 20 8\" />\n <line x1=\"12\" y1=\"18\" x2=\"12\" y2=\"12\" />\n <polyline points=\"9 15 12 12 15 15\" />\n </>\n)\n\nexport const AttachmentIcon = icon(\n <>\n <path d=\"M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48\" />\n </>\n)\n\nexport const RemoveFormatIcon = icon(\n <>\n <path d=\"M6 4h12l-4 16\" />\n <line x1=\"2\" y1=\"21\" x2=\"22\" y2=\"3\" strokeWidth=\"2\" />\n </>\n)\n\nexport const CloseIcon = icon(\n <>\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </>\n)\n\nexport const ChevronDownIcon = icon(\n <polyline points=\"6 9 12 15 18 9\" />\n)\n\nexport const ChevronRightIcon = icon(\n <polyline points=\"9 6 15 12 9 18\" />\n)\n\nexport const CheckIcon = icon(\n <polyline points=\"20 6 9 17 4 12\" />\n)\n\nexport const TrashIcon = icon(\n <>\n <polyline points=\"3 6 5 6 21 6\" />\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </>\n)\n\n// Plugin feature icons\nexport const CalloutIcon = icon(\n <>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"3\" />\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\" strokeWidth=\"2\" />\n <circle cx=\"12\" cy=\"16\" r=\"1\" fill=\"currentColor\" stroke=\"none\" />\n </>\n)\n\nexport const MathIcon = filled(\n <>\n <text x=\"2\" y=\"18\" fontSize=\"16\" fontWeight=\"bold\" fill=\"currentColor\" stroke=\"none\" fontStyle=\"italic\" fontFamily=\"serif\">f</text>\n <text x=\"10\" y=\"14\" fontSize=\"12\" fill=\"currentColor\" stroke=\"none\">(x)</text>\n </>\n)\n\nexport const TocIcon = icon(\n <>\n <line x1=\"3\" y1=\"6\" x2=\"5\" y2=\"6\" strokeWidth=\"2\" />\n <line x1=\"8\" y1=\"6\" x2=\"18\" y2=\"6\" />\n <line x1=\"5\" y1=\"12\" x2=\"7\" y2=\"12\" strokeWidth=\"2\" />\n <line x1=\"10\" y1=\"12\" x2=\"20\" y2=\"12\" />\n <line x1=\"5\" y1=\"18\" x2=\"7\" y2=\"18\" strokeWidth=\"2\" />\n <line x1=\"10\" y1=\"18\" x2=\"17\" y2=\"18\" />\n </>\n)\n\nexport const BookmarkIcon = icon(\n <path d=\"M6 2h12a1 1 0 0 1 1 1v18l-7-4-7 4V3a1 1 0 0 1 1-1z\" />\n)\n\nexport const MergeTagIcon = icon(\n <>\n <path d=\"M7 8l-4 4 4 4\" />\n <path d=\"M17 8l4 4-4 4\" />\n <line x1=\"14\" y1=\"4\" x2=\"10\" y2=\"20\" />\n </>\n)\n\nexport const SpellcheckIcon = icon(\n <>\n <text x=\"2\" y=\"15\" fontSize=\"14\" fontWeight=\"bold\" fill=\"currentColor\" stroke=\"none\">ABC</text>\n <polyline points=\"16 18 18 20 22 14\" strokeWidth=\"2.5\" />\n </>\n)\n\nexport const AnalyticsIcon = icon(\n <>\n <rect x=\"3\" y=\"14\" width=\"4\" height=\"7\" rx=\"1\" />\n <rect x=\"10\" y=\"9\" width=\"4\" height=\"12\" rx=\"1\" />\n <rect x=\"17\" y=\"4\" width=\"4\" height=\"17\" rx=\"1\" />\n </>\n)\n\nexport const CommentIcon = icon(\n <>\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </>\n)\n\nexport const RemoveFormatIcon2 = icon(\n <>\n <path d=\"M6 4h12l-4 16\" />\n <line x1=\"2\" y1=\"21\" x2=\"22\" y2=\"3\" strokeWidth=\"2\" />\n </>\n)\n\nexport const CollaborationIcon = icon(\n <>\n <path d=\"M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\" />\n <circle cx=\"9\" cy=\"7\" r=\"4\" />\n <path d=\"M23 21v-2a4 4 0 0 0-3-3.87\" />\n <path d=\"M16 3.13a4 4 0 0 1 0 7.75\" />\n </>\n)\n\n// UX feature icons\nexport const DistractionFreeIcon = icon(\n <>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\" />\n </>\n)\n\nexport const SplitViewIcon = icon(\n <>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"21\" />\n </>\n)\n\nexport const ICON_MAP = {\n bold: BoldIcon,\n italic: ItalicIcon,\n underline: UnderlineIcon,\n strikethrough: StrikethroughIcon,\n subscript: SubscriptIcon,\n superscript: SuperscriptIcon,\n heading: HeadingIcon,\n headings: HeadingIcon,\n alignLeft: AlignLeftIcon,\n alignCenter: AlignCenterIcon,\n alignRight: AlignRightIcon,\n alignJustify: AlignJustifyIcon,\n orderedList: OrderedListIcon,\n unorderedList: UnorderedListIcon,\n taskList: TaskListIcon,\n link: LinkIcon,\n insertLink: LinkIcon,\n unlink: UnlinkIcon,\n image: ImageIcon,\n insertImage: ImageIcon,\n table: TableIcon,\n insertTable: TableIcon,\n blockquote: BlockquoteIcon,\n codeBlock: CodeBlockIcon,\n horizontalRule: HorizontalRuleIcon,\n undo: UndoIcon,\n redo: RedoIcon,\n foreColor: ForeColorIcon,\n backColor: BackColorIcon,\n fontFamily: FontFamilyIcon,\n fontSize: FontSizeIcon,\n embedMedia: EmbedMediaIcon,\n findReplace: FindReplaceIcon,\n sourceMode: SourceModeIcon,\n fullscreen: FullscreenIcon,\n exitFullscreen: ExitFullscreenIcon,\n indent: IndentIcon,\n outdent: OutdentIcon,\n removeFormat: RemoveFormatIcon,\n close: CloseIcon,\n chevronDown: ChevronDownIcon,\n check: CheckIcon,\n trash: TrashIcon,\n attachment: AttachmentIcon,\n insertAttachment: AttachmentIcon,\n importDocument: ImportDocumentIcon,\n toggleMarkdown: ToggleMarkdownIcon,\n export: ExportIcon,\n commandPalette: CommandPaletteIcon,\n // Plugin feature icons\n insertCallout: CalloutIcon,\n callout: CalloutIcon,\n insertMath: MathIcon,\n math: MathIcon,\n insertToc: TocIcon,\n toc: TocIcon,\n insertBookmark: BookmarkIcon,\n bookmark: BookmarkIcon,\n insertMergeTag: MergeTagIcon,\n mergeTag: MergeTagIcon,\n analytics: AnalyticsIcon,\n getAnalytics: AnalyticsIcon,\n toggleAnalytics: AnalyticsIcon,\n // Spellcheck icons\n spellcheck: SpellcheckIcon,\n toggleSpellcheck: SpellcheckIcon,\n checkGrammar: SpellcheckIcon,\n // Comment & format icons\n addComment: CommentIcon,\n comment: CommentIcon,\n // Collaboration icons\n collaboration: CollaborationIcon,\n startCollaboration: CollaborationIcon,\n stopCollaboration: CollaborationIcon,\n // UX feature icons\n distractionFree: DistractionFreeIcon,\n splitView: SplitViewIcon,\n toggleSplitView: SplitViewIcon,\n}\n","import React, { useState, useRef, useCallback } from 'react'\n\n/**\n * Styled tooltip component that replaces native `title` attributes.\n * Shows on hover/focus with a small delay, displaying command name\n * and optional keyboard shortcut hint.\n *\n * @param {{ text: string, shortcut?: string, children: React.ReactNode }} props\n */\nfunction TooltipInner({ text, shortcut, children }) {\n const [visible, setVisible] = useState(false)\n const timerRef = useRef(null)\n\n const show = useCallback(() => {\n timerRef.current = setTimeout(() => setVisible(true), 200)\n }, [])\n\n const hide = useCallback(() => {\n clearTimeout(timerRef.current)\n setVisible(false)\n }, [])\n\n if (!text) return children\n\n const label = shortcut ? `${text} \\u2014 ${shortcut}` : text\n\n return (\n <span\n className=\"rmx-tooltip-wrap\"\n onMouseEnter={show}\n onMouseLeave={hide}\n onFocus={show}\n onBlur={hide}\n >\n {children}\n {visible && (\n <span className=\"rmx-tooltip\" role=\"tooltip\" aria-hidden=\"true\">\n <span className=\"rmx-tooltip-text\">{label}</span>\n <span className=\"rmx-tooltip-arrow\" />\n </span>\n )}\n </span>\n )\n}\n\nexport const Tooltip = React.memo(TooltipInner)\n","import React, { useCallback } from 'react'\nimport PropTypes from 'prop-types'\nimport { ICON_MAP } from '../../icons/index.jsx'\nimport { Tooltip } from '../Tooltip/Tooltip.jsx'\n\nexport const ToolbarButton = React.memo(function ToolbarButton({ command, icon, tooltip, active, disabled, onClick, shortcutLabel, children, itemStyle }) {\n const IconComponent = children ? null : ICON_MAP[icon || command]\n\n const handleClick = useCallback((e) => {\n e.preventDefault()\n e.stopPropagation()\n if (!disabled) onClick?.()\n }, [disabled, onClick])\n\n const handleMouseDown = useCallback((e) => e.preventDefault(), [])\n\n return (\n <Tooltip text={tooltip} shortcut={shortcutLabel}>\n <button\n className={`rmx-toolbar-btn ${active ? 'rmx-active' : ''} ${disabled ? 'rmx-disabled' : ''}`}\n style={itemStyle || undefined}\n onClick={handleClick}\n onMouseDown={handleMouseDown}\n disabled={disabled}\n type=\"button\"\n aria-pressed={active}\n aria-label={tooltip}\n >\n {children || (IconComponent ? <IconComponent size={18} /> : command)}\n </button>\n </Tooltip>\n )\n})\n\nToolbarButton.propTypes = {\n command: PropTypes.string,\n icon: PropTypes.string,\n tooltip: PropTypes.string,\n active: PropTypes.bool,\n disabled: PropTypes.bool,\n onClick: PropTypes.func,\n shortcutLabel: PropTypes.string,\n children: PropTypes.node,\n itemStyle: PropTypes.object,\n}\n","import React, { useState, useRef, useEffect, useCallback } from 'react'\nimport PropTypes from 'prop-types'\nimport { ChevronDownIcon } from '../../icons/index.jsx'\n\nexport const ToolbarDropdown = React.memo(function ToolbarDropdown({ label, value, options, onChange, tooltip, icon: Icon, width = 120, itemStyle }) {\n const [open, setOpen] = useState(false)\n const [activeIndex, setActiveIndex] = useState(-1)\n const ref = useRef(null)\n const menuRef = useRef(null)\n\n useEffect(() => {\n if (!open) return\n const handleClick = (e) => {\n if (ref.current && !ref.current.contains(e.target)) {\n setOpen(false)\n }\n }\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [open])\n\n // Reset activeIndex when opening\n useEffect(() => {\n if (open) {\n const idx = options.findIndex((o) => o.value === value)\n setActiveIndex(idx >= 0 ? idx : 0)\n }\n }, [open, options, value])\n\n const currentOption = options.find((o) => o.value === value)\n const displayLabel = currentOption?.label || label\n\n const handleToggle = useCallback((e) => {\n e.preventDefault()\n setOpen(prev => !prev)\n }, [])\n\n const handleMouseDown = useCallback((e) => e.preventDefault(), [])\n\n // #25: Keyboard navigation for dropdown\n const handleKeyDown = useCallback((e) => {\n if (!open) {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n setOpen(true)\n }\n return\n }\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n setActiveIndex(prev => (prev + 1) % options.length)\n break\n case 'ArrowUp':\n e.preventDefault()\n setActiveIndex(prev => (prev - 1 + options.length) % options.length)\n break\n case 'Enter':\n case ' ':\n e.preventDefault()\n if (activeIndex >= 0 && activeIndex < options.length) {\n onChange(options[activeIndex].value)\n setOpen(false)\n }\n break\n case 'Escape':\n e.preventDefault()\n setOpen(false)\n break\n default:\n break\n }\n }, [open, activeIndex, options, onChange])\n\n // Scroll active item into view\n useEffect(() => {\n if (open && menuRef.current && activeIndex >= 0) {\n const items = menuRef.current.querySelectorAll('[role=\"option\"]')\n if (items[activeIndex]) {\n items[activeIndex].scrollIntoView({ block: 'nearest' })\n }\n }\n }, [open, activeIndex])\n\n const activeDescendant = open && activeIndex >= 0 ? `rmx-dd-opt-${options[activeIndex]?.value}` : undefined\n\n return (\n <div className=\"rmx-toolbar-dropdown\" ref={ref} style={{ minWidth: width, ...itemStyle }}>\n <button\n className={`rmx-toolbar-btn rmx-toolbar-dropdown-btn`}\n onClick={handleToggle}\n onMouseDown={handleMouseDown}\n onKeyDown={handleKeyDown}\n title={tooltip}\n aria-label={tooltip}\n type=\"button\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-activedescendant={activeDescendant}\n >\n {Icon && <Icon size={16} />}\n <span className=\"rmx-toolbar-dropdown-label\">{displayLabel}</span>\n <ChevronDownIcon size={14} />\n </button>\n {open && (\n <div className=\"rmx-toolbar-dropdown-menu\" role=\"listbox\" ref={menuRef}>\n {options.map((option, i) => (\n <button\n key={option.value}\n id={`rmx-dd-opt-${option.value}`}\n className={`rmx-toolbar-dropdown-item ${option.value === value ? 'rmx-active' : ''} ${i === activeIndex ? 'rmx-focused' : ''}`}\n onClick={(e) => {\n e.preventDefault()\n onChange(option.value)\n setOpen(false)\n }}\n onMouseDown={handleMouseDown}\n onMouseEnter={() => setActiveIndex(i)}\n role=\"option\"\n aria-selected={option.value === value}\n type=\"button\"\n style={option.style}\n >\n {option.label}\n </button>\n ))}\n </div>\n )}\n </div>\n )\n})\n\nToolbarDropdown.propTypes = {\n label: PropTypes.string,\n value: PropTypes.string,\n options: PropTypes.arrayOf(\n PropTypes.shape({\n value: PropTypes.string.isRequired,\n label: PropTypes.string.isRequired,\n style: PropTypes.object,\n })\n ).isRequired,\n onChange: PropTypes.func.isRequired,\n tooltip: PropTypes.string,\n icon: PropTypes.elementType,\n width: PropTypes.number,\n itemStyle: PropTypes.object,\n}\n","import React, { useState, useRef, useEffect, useCallback } from 'react'\nimport PropTypes from 'prop-types'\nimport { DEFAULT_COLORS, loadColorPresets, saveColorPreset } from '@remyxjs/core'\nimport { ICON_MAP } from '../../icons/index.jsx'\n\n// #44: Human-readable color names for common hex values\nconst COLOR_NAMES = {\n '#000000': 'Black', '#ffffff': 'White', '#ff0000': 'Red', '#00ff00': 'Lime',\n '#0000ff': 'Blue', '#ffff00': 'Yellow', '#ff00ff': 'Magenta', '#00ffff': 'Cyan',\n '#808080': 'Gray', '#800000': 'Maroon', '#808000': 'Olive', '#008000': 'Green',\n '#800080': 'Purple', '#008080': 'Teal', '#000080': 'Navy', '#c0c0c0': 'Silver',\n '#ffa500': 'Orange', '#ffc0cb': 'Pink', '#a52a2a': 'Brown', '#f5f5dc': 'Beige',\n '#ff6347': 'Tomato', '#4682b4': 'Steel Blue', '#2e8b57': 'Sea Green',\n '#daa520': 'Goldenrod', '#cd5c5c': 'Indian Red', '#4b0082': 'Indigo',\n '#ee82ee': 'Violet', '#f0e68c': 'Khaki', '#e6e6fa': 'Lavender',\n '#fa8072': 'Salmon', '#40e0d0': 'Turquoise', '#ff69b4': 'Hot Pink',\n}\n\n// Number of columns in the color grid (matching CSS grid-template-columns)\nconst GRID_COLS = 10\n\nexport const ToolbarColorPicker = React.memo(function ToolbarColorPicker({ command, tooltip, currentColor, onColorSelect, itemStyle, engine }) {\n const [open, setOpen] = useState(false)\n const [focusedIndex, setFocusedIndex] = useState(-1)\n const ref = useRef(null)\n const swatchRefs = useRef([])\n\n useEffect(() => {\n if (!open) return\n const handleClick = (e) => {\n if (ref.current && !ref.current.contains(e.target)) {\n setOpen(false)\n }\n }\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [open])\n\n // #36: Escape key handler\n useEffect(() => {\n if (!open) return\n const handleKeyDown = (e) => {\n if (e.key === 'Escape') {\n e.preventDefault()\n setOpen(false)\n }\n }\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [open])\n\n // Reset focused index when palette opens\n useEffect(() => {\n if (open) {\n const idx = DEFAULT_COLORS.findIndex(c => c === currentColor)\n setFocusedIndex(idx >= 0 ? idx : 0)\n }\n }, [open, currentColor])\n\n // #26: Focus swatch when focusedIndex changes (roving tabindex)\n useEffect(() => {\n if (open && focusedIndex >= 0 && swatchRefs.current[focusedIndex]) {\n swatchRefs.current[focusedIndex].focus()\n }\n }, [open, focusedIndex])\n\n const IconComponent = ICON_MAP[command]\n\n const handleToggle = useCallback((e) => {\n e.preventDefault()\n setOpen(prev => !prev)\n }, [])\n\n const handleMouseDown = useCallback((e) => e.preventDefault(), [])\n\n // #26: Keyboard navigation for color swatches\n const handleSwatchKeyDown = useCallback((e, index) => {\n const totalColors = DEFAULT_COLORS.length\n let newIndex = index\n\n switch (e.key) {\n case 'ArrowRight':\n e.preventDefault()\n newIndex = (index + 1) % totalColors\n break\n case 'ArrowLeft':\n e.preventDefault()\n newIndex = (index - 1 + totalColors) % totalColors\n break\n case 'ArrowDown':\n e.preventDefault()\n newIndex = index + GRID_COLS < totalColors ? index + GRID_COLS : index\n break\n case 'ArrowUp':\n e.preventDefault()\n newIndex = index - GRID_COLS >= 0 ? index - GRID_COLS : index\n break\n case 'Enter':\n case ' ':\n e.preventDefault()\n onColorSelect(DEFAULT_COLORS[index])\n setOpen(false)\n return\n case 'Escape':\n e.preventDefault()\n setOpen(false)\n return\n default:\n return\n }\n\n setFocusedIndex(newIndex)\n }, [onColorSelect])\n\n // #30: Default button handler\n const handleDefault = useCallback((e) => {\n e.preventDefault()\n onColorSelect('')\n setOpen(false)\n }, [onColorSelect])\n\n return (\n <div className=\"rmx-toolbar-colorpicker\" ref={ref} style={itemStyle || undefined}>\n <button\n className=\"rmx-toolbar-btn\"\n onClick={handleToggle}\n onMouseDown={handleMouseDown}\n title={tooltip}\n aria-label={tooltip}\n type=\"button\"\n aria-haspopup=\"true\"\n aria-expanded={open}\n >\n {IconComponent && <IconComponent size={18} color={currentColor || (command === 'foreColor' ? '#000000' : '#ffff00')} />}\n </button>\n {open && (\n <div className=\"rmx-color-palette\">\n {/* #30: Default button to remove color */}\n <button\n type=\"button\"\n className=\"rmx-color-default-btn\"\n onClick={handleDefault}\n onMouseDown={handleMouseDown}\n >\n Default\n </button>\n <div className=\"rmx-color-grid\" role=\"grid\">\n {DEFAULT_COLORS.map((color, i) => (\n <button\n key={color}\n ref={(el) => { swatchRefs.current[i] = el }}\n className={`rmx-color-swatch ${color === currentColor ? 'rmx-active' : ''}`}\n style={{ backgroundColor: color }}\n onClick={(e) => {\n e.preventDefault()\n onColorSelect(color)\n setOpen(false)\n }}\n onMouseDown={handleMouseDown}\n onKeyDown={(e) => handleSwatchKeyDown(e, i)}\n title={COLOR_NAMES[color.toLowerCase()] || color}\n type=\"button\"\n tabIndex={i === focusedIndex ? 0 : -1}\n aria-label={`Color ${COLOR_NAMES[color.toLowerCase()] || color}`}\n />\n ))}\n </div>\n <div className=\"rmx-color-custom\">\n <label>\n Custom:\n <input\n type=\"color\"\n value={currentColor || '#000000'}\n onChange={(e) => {\n onColorSelect(e.target.value)\n setOpen(false)\n }}\n onMouseDown={(e) => e.stopPropagation()}\n />\n </label>\n </div>\n <ColorPresetSection engine={engine} onColorSelect={onColorSelect} />\n </div>\n )}\n </div>\n )\n})\n\n/**\n * Color preset section — save/load named color palettes from localStorage.\n * #56: Uses CSS classes instead of inline styles.\n */\nfunction ColorPresetSection({ engine, onColorSelect }) {\n const [presets, setPresets] = useState(() => loadColorPresets())\n const [showSave, setShowSave] = useState(false)\n const [presetName, setPresetName] = useState('')\n\n useEffect(() => {\n if (!engine) return\n const unsub = engine.eventBus?.on('colorPresets:change', ({ presets: p }) => setPresets(p))\n return unsub\n }, [engine])\n\n const handleSave = () => {\n if (!presetName.trim()) return\n saveColorPreset(presetName.trim(), [...DEFAULT_COLORS])\n setPresets(loadColorPresets())\n setPresetName('')\n setShowSave(false)\n }\n\n if (presets.length === 0 && !showSave) {\n return (\n <div className=\"rmx-color-presets\">\n <button\n type=\"button\"\n onClick={() => setShowSave(true)}\n className=\"rmx-color-preset-save-btn\"\n >\n + Save Preset\n </button>\n </div>\n )\n }\n\n return (\n <div className=\"rmx-color-presets\">\n {presets.map((preset) => (\n <div key={preset.name} className=\"rmx-color-preset-row\">\n <span className=\"rmx-color-preset-name\">{preset.name}</span>\n <div className=\"rmx-color-preset-swatches\">\n {preset.colors.slice(0, 6).map((c, i) => (\n <button\n key={i}\n type=\"button\"\n className=\"rmx-color-preset-swatch\"\n style={{ backgroundColor: c }}\n onClick={() => onColorSelect(c)}\n title={COLOR_NAMES[c.toLowerCase()] || c}\n />\n ))}\n </div>\n </div>\n ))}\n {showSave ? (\n <div className=\"rmx-color-preset-save-form\">\n <input\n type=\"text\"\n value={presetName}\n onChange={(e) => setPresetName(e.target.value)}\n placeholder=\"Preset name...\"\n className=\"rmx-color-preset-save-input\"\n onKeyDown={(e) => e.key === 'Enter' && handleSave()}\n onMouseDown={(e) => e.stopPropagation()}\n />\n <button type=\"button\" onClick={handleSave} className=\"rmx-color-preset-save-confirm\">Save</button>\n </div>\n ) : (\n <button\n type=\"button\"\n onClick={() => setShowSave(true)}\n className=\"rmx-color-preset-save-btn\"\n style={{ marginTop: 2 }}\n >\n + Save Preset\n </button>\n )}\n </div>\n )\n}\n\nToolbarColorPicker.propTypes = {\n command: PropTypes.string.isRequired,\n tooltip: PropTypes.string,\n currentColor: PropTypes.string,\n onColorSelect: PropTypes.func.isRequired,\n itemStyle: PropTypes.object,\n engine: PropTypes.object,\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\n\nexport const ToolbarSeparator = React.memo(function ToolbarSeparator({ separatorStyle }) {\n return <div className=\"rmx-toolbar-separator\" role=\"separator\" style={separatorStyle || undefined} />\n})\n\nToolbarSeparator.propTypes = {\n separatorStyle: PropTypes.object,\n}\n","import React, { useState, useRef, useEffect, useCallback } from 'react'\n\n/**\n * TypographyDropdown — toolbar dropdown for line height, letter spacing,\n * and paragraph spacing. Uses the same inline style wrapping pattern as fontSize.\n */\n\nconst LINE_HEIGHT_OPTIONS = ['1', '1.15', '1.5', '1.7', '2', '2.5', '3']\nconst LETTER_SPACING_OPTIONS = ['-0.5px', '0', '0.5px', '1px', '1.5px', '2px', '3px', '5px']\nconst PARAGRAPH_SPACING_OPTIONS = ['0', '4px', '8px', '12px', '16px', '24px', '32px']\n\nexport const TypographyDropdown = React.memo(function TypographyDropdown({ engine, itemStyle }) {\n const [open, setOpen] = useState(false)\n const ref = useRef(null)\n\n useEffect(() => {\n if (!open) return\n const handleClick = (e) => {\n if (ref.current && !ref.current.contains(e.target)) {\n setOpen(false)\n }\n }\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [open])\n\n const handleToggle = useCallback((e) => {\n e.preventDefault()\n setOpen(prev => !prev)\n }, [])\n\n const handleMouseDown = useCallback((e) => e.preventDefault(), [])\n\n const handleLineHeight = useCallback((e) => {\n engine?.executeCommand('lineHeight', e.target.value)\n }, [engine])\n\n const handleLetterSpacing = useCallback((e) => {\n engine?.executeCommand('letterSpacing', e.target.value)\n }, [engine])\n\n const handleParagraphSpacing = useCallback((e) => {\n engine?.executeCommand('paragraphSpacing', e.target.value)\n }, [engine])\n\n return (\n <div className=\"rmx-typography-dropdown\" ref={ref} style={itemStyle || undefined}>\n <button\n className=\"rmx-toolbar-btn\"\n onClick={handleToggle}\n onMouseDown={handleMouseDown}\n title=\"Typography\"\n type=\"button\"\n aria-haspopup=\"true\"\n aria-expanded={open}\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M3 4h12M5 4v10M13 4v10M7 14h-4M15 14h-4M6 9h6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n </button>\n {open && (\n <div className=\"rmx-typography-menu\" onMouseDown={handleMouseDown}>\n <div className=\"rmx-typography-row\">\n <label>Line Height</label>\n <select onChange={handleLineHeight} defaultValue=\"\">\n <option value=\"\" disabled>Select...</option>\n {LINE_HEIGHT_OPTIONS.map(v => (\n <option key={v} value={v}>{v}</option>\n ))}\n </select>\n </div>\n <div className=\"rmx-typography-row\">\n <label>Letter Spacing</label>\n <select onChange={handleLetterSpacing} defaultValue=\"\">\n <option value=\"\" disabled>Select...</option>\n {LETTER_SPACING_OPTIONS.map(v => (\n <option key={v} value={v}>{v}</option>\n ))}\n </select>\n </div>\n <div className=\"rmx-typography-row\">\n <label>Paragraph Spacing</label>\n <select onChange={handleParagraphSpacing} defaultValue=\"\">\n <option value=\"\" disabled>Select...</option>\n {PARAGRAPH_SPACING_OPTIONS.map(v => (\n <option key={v} value={v}>{v}</option>\n ))}\n </select>\n </div>\n </div>\n )}\n </div>\n )\n})\n","import React, { useMemo, useCallback, useRef, useState, useEffect } from 'react'\nimport { ToolbarButton } from './ToolbarButton.jsx'\nimport { ToolbarDropdown } from './ToolbarDropdown.jsx'\nimport { ToolbarColorPicker } from './ToolbarColorPicker.jsx'\nimport { ToolbarSeparator } from './ToolbarSeparator.jsx'\nimport { TypographyDropdown } from '../TypographyDropdown/TypographyDropdown.jsx'\nimport { DEFAULT_TOOLBAR, DEFAULT_FONTS, DEFAULT_FONT_SIZES, HEADING_OPTIONS, BUTTON_COMMANDS, TOOLTIP_MAP, getShortcutLabel, getCommandActiveState } from '@remyxjs/core'\nimport { useSelectionContext } from '../../config/SelectionContext.js'\n\n// Heading dropdown font size formula: base size minus level * step\nconst HEADING_BASE_FONT_SIZE = 22\nconst HEADING_FONT_SIZE_STEP = 2\n\n// Pre-compute heading options with styles (static — never changes)\nconst HEADING_OPTIONS_WITH_STYLES = HEADING_OPTIONS.map(o => ({\n ...o,\n style: o.tag !== 'p' ? { fontSize: `${HEADING_BASE_FONT_SIZE - (parseInt(o.tag?.[1]) || 0) * HEADING_FONT_SIZE_STEP}px`, fontWeight: 'bold' } : {},\n}))\n\nexport const Toolbar = React.memo(function Toolbar({ config, engine, onOpenModal, fonts = DEFAULT_FONTS, wordCountButton, toolbarItemTheme, customizableToolbar, onToolbarChange }) {\n const selectionState = useSelectionContext()\n const toolbarConfig = config || DEFAULT_TOOLBAR\n const toolbarRef = useRef(null)\n const innerRef = useRef(null)\n const [overflowIndex, setOverflowIndex] = useState(-1)\n const [overflowOpen, setOverflowOpen] = useState(false)\n const overflowMenuRef = useRef(null)\n const [dragItem, setDragItem] = useState(null)\n const [dragOverItem, setDragOverItem] = useState(null)\n const [customOrder, setCustomOrder] = useState(() => {\n if (!customizableToolbar) return null\n try {\n const saved = localStorage.getItem('rmx-toolbar-order')\n return saved ? JSON.parse(saved) : null\n } catch { return null }\n })\n\n // Memoize font family options — only recompute when fonts array changes\n const fontOptions = useMemo(() =>\n fonts.map((f) => ({ label: f, value: f, style: { fontFamily: f } })),\n [fonts]\n )\n\n // Memoize command handlers to avoid creating new functions each render\n const handleHeadingChange = useCallback((value) => {\n engine?.executeCommand('heading', value === 'p' ? 'p' : value.replace('h', ''))\n }, [engine])\n\n const handleFontFamilyChange = useCallback((value) => {\n engine?.executeCommand('fontFamily', value)\n }, [engine])\n\n const handleFontSizeChange = useCallback((value) => {\n engine?.executeCommand('fontSize', value)\n }, [engine])\n\n const handleForeColorSelect = useCallback((color) => {\n engine?.executeCommand('foreColor', color)\n }, [engine])\n\n const handleBackColorSelect = useCallback((color) => {\n engine?.executeCommand('backColor', color)\n }, [engine])\n\n // Task 269: Pre-memoize modal onClick handlers with useCallback\n const handleOpenImage = useCallback(() => onOpenModal?.('image'), [onOpenModal])\n const handleOpenAttachment = useCallback(() => onOpenModal?.('attachment'), [onOpenModal])\n const handleOpenImportDocument = useCallback(() => onOpenModal?.('importDocument'), [onOpenModal])\n const handleOpenTable = useCallback(() => onOpenModal?.('table'), [onOpenModal])\n const handleOpenEmbed = useCallback(() => onOpenModal?.('embed'), [onOpenModal])\n const handleOpenFindReplace = useCallback(() => onOpenModal?.('findReplace'), [onOpenModal])\n const handleOpenExport = useCallback(() => onOpenModal?.('export'), [onOpenModal])\n const handleOpenCommandPalette = useCallback(() => onOpenModal?.('commandPalette'), [onOpenModal])\n\n const items = useMemo(() => {\n const result = []\n toolbarConfig.forEach((group, gi) => {\n if (gi > 0) result.push({ type: 'separator', key: `sep-${gi}` })\n\n const groupItems = Array.isArray(group) ? group : [group]\n groupItems.forEach((item) => {\n if (item === '|') {\n result.push({ type: 'separator', key: `sep-${gi}-inline` })\n } else if (typeof item === 'string') {\n result.push({ type: 'item', command: item, key: item })\n } else {\n result.push({ type: 'custom', ...item, key: item.command || item.name })\n }\n })\n })\n return result\n }, [toolbarConfig])\n\n // ResizeObserver-based overflow detection\n useEffect(() => {\n const toolbar = toolbarRef.current\n const inner = innerRef.current\n if (!toolbar || !inner) return\n\n const checkOverflow = () => {\n const containerWidth = toolbar.clientWidth\n const children = Array.from(inner.children)\n let cutIndex = -1\n\n // Reserve space for overflow button (approx 36px)\n const reservedWidth = 40\n let accumulatedWidth = 0\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i]\n // Skip hidden overflow items\n if (child.classList.contains('rmx-toolbar-overflow-btn')) continue\n accumulatedWidth += child.offsetWidth + 1 // 1px gap\n if (accumulatedWidth > containerWidth - reservedWidth) {\n cutIndex = i\n break\n }\n }\n\n setOverflowIndex(cutIndex)\n }\n\n const observer = new ResizeObserver(checkOverflow)\n observer.observe(toolbar)\n checkOverflow()\n\n return () => observer.disconnect()\n }, [items])\n\n // Close overflow menu on outside click\n useEffect(() => {\n if (!overflowOpen) return\n const handleClick = (e) => {\n if (overflowMenuRef.current && !overflowMenuRef.current.contains(e.target)) {\n setOverflowOpen(false)\n }\n }\n document.addEventListener('pointerdown', handleClick)\n return () => document.removeEventListener('pointerdown', handleClick)\n }, [overflowOpen])\n\n // #35: Focus first item on overflow menu open + keyboard navigation\n useEffect(() => {\n if (!overflowOpen || !overflowMenuRef.current) return\n const firstBtn = overflowMenuRef.current.querySelector('button:not([disabled])')\n if (firstBtn) firstBtn.focus()\n }, [overflowOpen])\n\n const handleOverflowKeyDown = useCallback((e) => {\n if (!overflowMenuRef.current) return\n const items = Array.from(overflowMenuRef.current.querySelectorAll('button:not([disabled])'))\n const currentIndex = items.indexOf(document.activeElement)\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n if (currentIndex < items.length - 1) items[currentIndex + 1].focus()\n else items[0].focus()\n break\n case 'ArrowUp':\n e.preventDefault()\n if (currentIndex > 0) items[currentIndex - 1].focus()\n else items[items.length - 1].focus()\n break\n case 'Escape':\n e.preventDefault()\n setOverflowOpen(false)\n break\n default:\n break\n }\n }, [])\n\n // Apply custom ordering if customizableToolbar is enabled\n const orderedItems = useMemo(() => {\n if (!customizableToolbar || !customOrder) return items\n const orderMap = new Map(customOrder.map((key, i) => [key, i]))\n const sorted = [...items].sort((a, b) => {\n const ai = orderMap.get(a.key)\n const bi = orderMap.get(b.key)\n if (ai === undefined && bi === undefined) return 0\n if (ai === undefined) return 1\n if (bi === undefined) return -1\n return ai - bi\n })\n return sorted\n }, [items, customOrder, customizableToolbar])\n\n // Drag handlers for customizable toolbar\n const handleDragStart = useCallback((e, item) => {\n if (!customizableToolbar) return\n setDragItem(item.key)\n e.dataTransfer.effectAllowed = 'move'\n }, [customizableToolbar])\n\n const handleDragOver = useCallback((e, item) => {\n if (!customizableToolbar || !dragItem) return\n e.preventDefault()\n e.dataTransfer.dropEffect = 'move'\n setDragOverItem(item.key)\n }, [customizableToolbar, dragItem])\n\n const handleDrop = useCallback((e, targetItem) => {\n if (!customizableToolbar || !dragItem) return\n e.preventDefault()\n const currentOrder = orderedItems.map(i => i.key)\n const fromIdx = currentOrder.indexOf(dragItem)\n const toIdx = currentOrder.indexOf(targetItem.key)\n if (fromIdx < 0 || toIdx < 0 || fromIdx === toIdx) return\n\n const newOrder = [...currentOrder]\n const [moved] = newOrder.splice(fromIdx, 1)\n newOrder.splice(toIdx, 0, moved)\n\n setCustomOrder(newOrder)\n try { localStorage.setItem('rmx-toolbar-order', JSON.stringify(newOrder)) } catch {}\n onToolbarChange?.(newOrder)\n setDragItem(null)\n setDragOverItem(null)\n }, [customizableToolbar, dragItem, orderedItems, onToolbarChange])\n\n const handleDragEnd = useCallback(() => {\n setDragItem(null)\n setDragOverItem(null)\n }, [])\n\n // #46: Render placeholder when engine is not ready\n if (!engine) {\n return (\n <div className=\"rmx-toolbar\" role=\"toolbar\" aria-label=\"Editor toolbar\" style={{ minHeight: 44 }}>\n <div className=\"rmx-toolbar-inner\" />\n </div>\n )\n }\n\n const renderItem = (item) => {\n if (item.type === 'separator') {\n return <ToolbarSeparator key={item.key} separatorStyle={toolbarItemTheme?._separator} />\n }\n\n const { command } = item\n const itemStyle = toolbarItemTheme?.[command] || null\n\n // Dropdown items\n if (command === 'headings') {\n const current = selectionState.heading || 'p'\n return (\n <ToolbarDropdown\n key={command}\n label=\"Normal\"\n value={current}\n options={HEADING_OPTIONS_WITH_STYLES}\n onChange={handleHeadingChange}\n tooltip=\"Block Type\"\n width={130}\n itemStyle={itemStyle}\n />\n )\n }\n\n if (command === 'fontFamily') {\n const current = selectionState.fontFamily?.replace(/['\"]/g, '') || ''\n return (\n <ToolbarDropdown\n key={command}\n label=\"Font\"\n value={current}\n options={fontOptions}\n onChange={handleFontFamilyChange}\n tooltip=\"Font Family\"\n width={140}\n itemStyle={itemStyle}\n />\n )\n }\n\n if (command === 'fontSize') {\n return (\n <ToolbarDropdown\n key={command}\n label=\"Size\"\n value={selectionState.fontSize || ''}\n options={DEFAULT_FONT_SIZES}\n onChange={handleFontSizeChange}\n tooltip=\"Font Size\"\n width={80}\n itemStyle={itemStyle}\n />\n )\n }\n\n // Color pickers\n if (command === 'foreColor') {\n return (\n <ToolbarColorPicker\n key={command}\n command=\"foreColor\"\n tooltip=\"Text Color\"\n currentColor={selectionState.foreColor}\n onColorSelect={handleForeColorSelect}\n itemStyle={itemStyle}\n engine={engine}\n />\n )\n }\n\n if (command === 'backColor') {\n return (\n <ToolbarColorPicker\n key={command}\n command=\"backColor\"\n tooltip=\"Background Color\"\n currentColor={selectionState.backColor}\n onColorSelect={handleBackColorSelect}\n itemStyle={itemStyle}\n engine={engine}\n />\n )\n }\n\n if (command === 'typography') {\n return (\n <TypographyDropdown\n key={command}\n engine={engine}\n itemStyle={itemStyle}\n />\n )\n }\n\n // Modal triggers\n if (command === 'link') {\n return (\n <ToolbarButton\n key={command}\n command={command}\n tooltip={TOOLTIP_MAP[command]}\n active={!!selectionState.link}\n onClick={() => {\n if (selectionState.link) {\n onOpenModal?.('link', selectionState.link)\n } else {\n onOpenModal?.('link', { text: engine.selection.getSelectedText() })\n }\n }}\n shortcutLabel={getShortcutLabel('insertLink')}\n itemStyle={itemStyle}\n />\n )\n }\n\n if (command === 'image') {\n return (\n <ToolbarButton key={command} command={command} tooltip={TOOLTIP_MAP[command]}\n onClick={handleOpenImage} itemStyle={itemStyle} />\n )\n }\n\n if (command === 'attachment') {\n return (\n <ToolbarButton key={command} command={command} tooltip={TOOLTIP_MAP[command]}\n onClick={handleOpenAttachment} itemStyle={itemStyle} />\n )\n }\n\n if (command === 'importDocument') {\n return (\n <ToolbarButton key={command} command={command} tooltip={TOOLTIP_MAP[command]}\n onClick={handleOpenImportDocument} itemStyle={itemStyle} />\n )\n }\n\n if (command === 'table') {\n return (\n <ToolbarButton key={command} command={command} tooltip={TOOLTIP_MAP[command]}\n onClick={handleOpenTable} itemStyle={itemStyle} />\n )\n }\n\n if (command === 'embedMedia') {\n return (\n <ToolbarButton key={command} command={command} tooltip={TOOLTIP_MAP[command]}\n onClick={handleOpenEmbed} itemStyle={itemStyle} />\n )\n }\n\n if (command === 'findReplace') {\n return (\n <ToolbarButton key={command} command={command} tooltip={TOOLTIP_MAP[command]}\n onClick={handleOpenFindReplace}\n shortcutLabel={getShortcutLabel(command)} itemStyle={itemStyle} />\n )\n }\n\n if (command === 'export') {\n return (\n <ToolbarButton key={command} command={command} tooltip={TOOLTIP_MAP[command]}\n onClick={handleOpenExport} itemStyle={itemStyle} />\n )\n }\n\n if (command === 'commandPalette') {\n return (\n <ToolbarButton key={command} command={command} tooltip={TOOLTIP_MAP[command]}\n onClick={handleOpenCommandPalette}\n shortcutLabel={getShortcutLabel(command)} itemStyle={itemStyle} />\n )\n }\n\n // Regular button commands\n if (BUTTON_COMMANDS.has(command)) {\n const isActive = getCommandActiveState(command, selectionState, engine)\n\n // Guard: only render if command is registered (plugin may not be loaded)\n const isRegistered = engine.commands?.has?.(command) ?? true\n\n return (\n <ToolbarButton\n key={command}\n command={command}\n tooltip={TOOLTIP_MAP[command] || command}\n active={isActive}\n disabled={!isRegistered}\n onClick={() => {\n if (isRegistered) engine.executeCommand(command)\n }}\n shortcutLabel={getShortcutLabel(command)}\n itemStyle={itemStyle}\n />\n )\n }\n\n // Fallback — guard unregistered commands\n const isRegistered = engine.commands?.has?.(command) ?? true\n return (\n <ToolbarButton\n key={command}\n command={command}\n tooltip={TOOLTIP_MAP[command] || command}\n disabled={!isRegistered}\n onClick={() => {\n if (isRegistered) engine.executeCommand(command)\n }}\n itemStyle={itemStyle}\n />\n )\n }\n\n // Split items into visible and overflow groups\n const finalItems = customizableToolbar ? orderedItems : items\n const visibleItems = overflowIndex > 0 ? finalItems.slice(0, overflowIndex) : finalItems\n const overflowItems = overflowIndex > 0 ? finalItems.slice(overflowIndex) : []\n\n const renderDraggableItem = (item) => {\n const rendered = renderItem(item)\n if (!customizableToolbar || item.type === 'separator') return rendered\n return (\n <span\n key={`drag-${item.key}`}\n draggable\n onDragStart={(e) => handleDragStart(e, item)}\n onDragOver={(e) => handleDragOver(e, item)}\n onDrop={(e) => handleDrop(e, item)}\n onDragEnd={handleDragEnd}\n className={`${dragItem === item.key ? 'rmx-dragging' : ''} ${dragOverItem === item.key ? 'rmx-toolbar-drag-over' : ''}`}\n role=\"listitem\"\n aria-roledescription=\"draggable toolbar item\"\n >\n {rendered}\n </span>\n )\n }\n\n return (\n <div className={`rmx-toolbar${customizableToolbar ? ' rmx-toolbar-customizable' : ''}`} role=\"toolbar\" aria-label=\"Editor toolbar\" ref={toolbarRef}>\n <div className=\"rmx-toolbar-inner\" ref={innerRef}>\n {visibleItems.map(customizableToolbar ? renderDraggableItem : renderItem)}\n {overflowItems.length > 0 && (\n <div className=\"rmx-toolbar-overflow-container\" style={{ position: 'relative' }}>\n <button\n className=\"rmx-toolbar-btn rmx-toolbar-overflow-btn\"\n onClick={() => setOverflowOpen(prev => !prev)}\n aria-label=\"More toolbar options\"\n aria-expanded={overflowOpen}\n type=\"button\"\n >\n ⋯\n </button>\n {overflowOpen && (\n <div\n ref={overflowMenuRef}\n className=\"rmx-toolbar-overflow-menu\"\n role=\"menu\"\n onKeyDown={handleOverflowKeyDown}\n >\n {overflowItems.map(renderItem)}\n </div>\n )}\n </div>\n )}\n {wordCountButton && (\n <>\n <ToolbarSeparator />\n {wordCountButton}\n </>\n )}\n </div>\n </div>\n )\n})\n","import { forwardRef } from 'react'\nimport PropTypes from 'prop-types'\n\nexport const EditArea = forwardRef(function EditArea({ style, readOnly, className = '', id }, ref) {\n return (\n <div className={`rmx-edit-area ${className}`} id={id}>\n <div\n ref={ref}\n className=\"rmx-content\"\n style={style}\n suppressContentEditableWarning\n />\n {readOnly && <div className=\"rmx-readonly-overlay\" />}\n </div>\n )\n})\n\nEditArea.propTypes = {\n style: PropTypes.object,\n readOnly: PropTypes.bool,\n className: PropTypes.string,\n id: PropTypes.string,\n}\n","import React, { useRef, useEffect, useState, useCallback } from 'react'\nimport PropTypes from 'prop-types'\nimport { ToolbarButton } from '../Toolbar/ToolbarButton.jsx'\nimport { useSelectionContext } from '../../config/SelectionContext.js'\n\nconst FLOATING_COMMANDS = ['bold', 'italic', 'underline', 'strikethrough', 'link']\n\n// Positioning constants\nconst TOOLBAR_FALLBACK_HEIGHT = 40\nconst TOOLBAR_FALLBACK_WIDTH = 200\nconst TOOLBAR_GAP = 8\nconst TOOLBAR_EDGE_PADDING = 4\n\n// Touch selection delay to let browser settle\nconst TOUCH_SELECTION_DELAY = 300\n\nfunction FloatingToolbarInner({ visible, selectionRect, engine, editorRect, onOpenModal, onDismiss }) {\n const selectionState = useSelectionContext()\n const ref = useRef(null)\n const sizeRef = useRef({ width: 0, height: 0 })\n const [position, setPosition] = useState({ top: 0, left: 0 })\n const [hasFocus, setHasFocus] = useState(false)\n const [placedBelow, setPlacedBelow] = useState(false)\n\n // Touch-based drag repositioning state\n const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 })\n const dragStartRef = useRef(null)\n const isDraggingRef = useRef(false)\n\n // Touch selection support: listen for touchend + selectionchange with delay\n const [touchVisible, setTouchVisible] = useState(false)\n const touchTimerRef = useRef(null)\n\n // Task 252: Removed direct selectionchange listener. Rely on engine's selection:change event.\n useEffect(() => {\n if (!engine?.element) return\n\n const el = engine.element\n\n const onTouchEnd = () => {\n // Clear any pending timer\n if (touchTimerRef.current) clearTimeout(touchTimerRef.current)\n // Wait for browser to settle the selection\n touchTimerRef.current = setTimeout(() => {\n const sel = window.getSelection()\n if (sel && !sel.isCollapsed && sel.rangeCount > 0) {\n setTouchVisible(true)\n } else {\n setTouchVisible(false)\n }\n }, TOUCH_SELECTION_DELAY)\n }\n\n // Use engine's selection:change event instead of document selectionchange\n const unsub = engine.eventBus.on('selection:change', () => {\n const sel = window.getSelection()\n if (!sel || sel.isCollapsed) {\n setTouchVisible(false)\n }\n })\n\n el.addEventListener('touchend', onTouchEnd, { passive: true })\n\n return () => {\n el.removeEventListener('touchend', onTouchEnd)\n unsub()\n if (touchTimerRef.current) clearTimeout(touchTimerRef.current)\n }\n }, [engine])\n\n // Cache toolbar dimensions via ResizeObserver to avoid forced reflows\n useEffect(() => {\n if (!ref.current) return\n const observer = new ResizeObserver(([entry]) => {\n sizeRef.current = {\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n }\n })\n observer.observe(ref.current)\n return () => observer.disconnect()\n }, [])\n\n useEffect(() => {\n if ((!visible && !touchVisible) || !selectionRect || !editorRect) return\n\n const toolbarHeight = sizeRef.current.height || ref.current?.offsetHeight || TOOLBAR_FALLBACK_HEIGHT\n const toolbarWidth = sizeRef.current.width || ref.current?.offsetWidth || TOOLBAR_FALLBACK_WIDTH\n\n // Default: position ABOVE the selection\n let top = selectionRect.top - editorRect.top - toolbarHeight - TOOLBAR_GAP\n let left = selectionRect.left - editorRect.left + selectionRect.width / 2 - toolbarWidth / 2\n let below = false\n\n // If no space above, place BELOW the selection (avoid overlapping highlight)\n if (top < 0) {\n top = selectionRect.bottom - editorRect.top + TOOLBAR_GAP\n below = true\n }\n\n // Clamp to editor bounds horizontally\n if (left < 0) left = TOOLBAR_EDGE_PADDING\n if (left + toolbarWidth > editorRect.width) left = editorRect.width - toolbarWidth - TOOLBAR_EDGE_PADDING\n\n setPosition({ top, left })\n setPlacedBelow(below)\n setDragOffset({ x: 0, y: 0 })\n }, [visible, touchVisible, selectionRect, editorRect])\n\n // Arrow-key navigation between toolbar buttons\n const handleKeyDown = useCallback((e) => {\n const toolbar = ref.current\n if (!toolbar) return\n\n const buttons = Array.from(toolbar.querySelectorAll('button:not([disabled])'))\n const currentIndex = buttons.indexOf(document.activeElement)\n\n let nextIndex = -1\n if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {\n e.preventDefault()\n nextIndex = currentIndex < buttons.length - 1 ? currentIndex + 1 : 0\n } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {\n e.preventDefault()\n nextIndex = currentIndex > 0 ? currentIndex - 1 : buttons.length - 1\n } else if (e.key === 'Home') {\n e.preventDefault()\n nextIndex = 0\n } else if (e.key === 'End') {\n e.preventDefault()\n nextIndex = buttons.length - 1\n }\n\n if (nextIndex >= 0 && buttons[nextIndex]) {\n buttons[nextIndex].focus()\n }\n }, [])\n\n // Keep toolbar visible while any button inside has focus\n const handleFocusIn = useCallback(() => setHasFocus(true), [])\n const handleFocusOut = useCallback(() => setHasFocus(false), [])\n\n // Prevent editor from losing focus/selection on mousedown (task 222)\n const handlePointerDown = useCallback((e) => e.preventDefault(), [])\n\n // Drag handle for repositioning toolbar on touch\n const handleGripPointerDown = useCallback((e) => {\n e.preventDefault()\n e.stopPropagation()\n isDraggingRef.current = true\n dragStartRef.current = {\n x: e.clientX,\n y: e.clientY,\n offsetX: dragOffset.x,\n offsetY: dragOffset.y,\n }\n\n const target = e.currentTarget\n target.setPointerCapture(e.pointerId)\n\n const onMove = (moveEvent) => {\n if (!isDraggingRef.current || !dragStartRef.current) return\n const dx = moveEvent.clientX - dragStartRef.current.x\n const dy = moveEvent.clientY - dragStartRef.current.y\n setDragOffset({\n x: dragStartRef.current.offsetX + dx,\n y: dragStartRef.current.offsetY + dy,\n })\n }\n\n const onUp = () => {\n isDraggingRef.current = false\n dragStartRef.current = null\n target.removeEventListener('pointermove', onMove)\n target.removeEventListener('pointerup', onUp)\n }\n\n target.addEventListener('pointermove', onMove)\n target.addEventListener('pointerup', onUp)\n }, [dragOffset])\n\n const isVisible = visible || touchVisible\n if ((!isVisible && !hasFocus) || !engine) return null\n\n return (\n <div\n ref={ref}\n className={`rmx-floating-toolbar rmx-floating-toolbar-touch ${placedBelow ? 'rmx-floating-below' : ''}`}\n style={{\n top: position.top + dragOffset.y,\n left: position.left + dragOffset.x,\n }}\n role=\"toolbar\"\n aria-label=\"Formatting toolbar\"\n onPointerDown={handlePointerDown}\n onKeyDown={handleKeyDown}\n onFocus={handleFocusIn}\n onBlur={handleFocusOut}\n >\n {FLOATING_COMMANDS.map((cmd, i) => {\n if (cmd === 'link') {\n return (\n <ToolbarButton\n key={cmd}\n command={cmd}\n tooltip=\"Insert Link\"\n active={!!selectionState.link}\n onClick={() => onOpenModal?.('link', { text: engine.selection.getSelectedText() })}\n />\n )\n }\n const isActive = selectionState[cmd] || false\n return (\n <ToolbarButton\n key={cmd}\n command={cmd}\n tooltip={cmd.charAt(0).toUpperCase() + cmd.slice(1)}\n active={isActive}\n onClick={() => engine.executeCommand(cmd)}\n />\n )\n })}\n {/* Draggable grip handle for touch repositioning */}\n <div\n className=\"rmx-floating-toolbar-grip\"\n onPointerDown={handleGripPointerDown}\n aria-label=\"Drag to reposition toolbar\"\n role=\"separator\"\n >\n <svg width=\"20\" height=\"6\" viewBox=\"0 0 20 6\" fill=\"currentColor\" aria-hidden=\"true\">\n <rect x=\"2\" y=\"0\" width=\"16\" height=\"2\" rx=\"1\" opacity=\"0.4\" />\n <rect x=\"2\" y=\"4\" width=\"16\" height=\"2\" rx=\"1\" opacity=\"0.4\" />\n </svg>\n </div>\n </div>\n )\n}\n\nexport const FloatingToolbar = React.memo(FloatingToolbarInner)\n\nFloatingToolbar.propTypes = {\n visible: PropTypes.bool.isRequired,\n selectionRect: PropTypes.object,\n engine: PropTypes.object,\n editorRect: PropTypes.object,\n onOpenModal: PropTypes.func,\n onDismiss: PropTypes.func,\n}\n","import { useState, useCallback, useEffect, useRef } from 'react'\n\nexport function ImageResizeHandles({ image, engine, editorRect }) {\n const [resizing, setResizing] = useState(false)\n const [startPos, setStartPos] = useState(null)\n const [startSize, setStartSize] = useState(null)\n const [editingAlt, setEditingAlt] = useState(false)\n const [altText, setAltText] = useState('')\n const altInputRef = useRef(null)\n\n // Sync alt text when image changes\n useEffect(() => {\n if (image) {\n setAltText(image.getAttribute('alt') || '')\n setEditingAlt(false)\n }\n }, [image])\n\n // Focus the alt input when editing starts\n useEffect(() => {\n if (editingAlt && altInputRef.current) {\n altInputRef.current.focus()\n }\n }, [editingAlt])\n\n if (!image || !editorRect) return null\n\n const imgRect = image.getBoundingClientRect()\n const top = imgRect.top - editorRect.top\n const left = imgRect.left - editorRect.left\n\n const handlePointerDown = useCallback((e, corner) => {\n e.preventDefault()\n e.stopPropagation()\n // Capture pointer for reliable tracking across touch and mouse\n e.target.setPointerCapture(e.pointerId)\n setResizing(true)\n setStartPos({ x: e.clientX, y: e.clientY })\n setStartSize({ width: image.offsetWidth, height: image.offsetHeight })\n }, [image])\n\n useEffect(() => {\n if (!resizing) return\n\n const handlePointerMove = (e) => {\n if (!startPos || !startSize) return\n const dx = e.clientX - startPos.x\n const aspectRatio = startSize.width > 0 ? startSize.height / startSize.width : 1\n const newWidth = Math.max(50, startSize.width + dx)\n const newHeight = newWidth * aspectRatio\n\n image.style.width = `${newWidth}px`\n image.style.height = `${newHeight}px`\n }\n\n const handlePointerUp = () => {\n setResizing(false)\n engine?.eventBus.emit('content:change')\n }\n\n document.addEventListener('pointermove', handlePointerMove)\n document.addEventListener('pointerup', handlePointerUp)\n return () => {\n document.removeEventListener('pointermove', handlePointerMove)\n document.removeEventListener('pointerup', handlePointerUp)\n }\n }, [resizing, startPos, startSize, image, engine])\n\n const handleAltSave = useCallback(() => {\n if (image) {\n image.setAttribute('alt', altText)\n engine?.eventBus.emit('content:change')\n }\n setEditingAlt(false)\n }, [image, altText, engine])\n\n const handleAltKeyDown = useCallback((e) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n handleAltSave()\n } else if (e.key === 'Escape') {\n setEditingAlt(false)\n setAltText(image?.getAttribute('alt') || '')\n }\n }, [handleAltSave, image])\n\n return (\n <div\n className=\"rmx-image-handles\"\n style={{\n position: 'absolute',\n top,\n left,\n width: imgRect.width,\n height: imgRect.height,\n pointerEvents: 'none',\n }}\n >\n <div className=\"rmx-image-handle rmx-handle-border\" />\n {['nw', 'ne', 'sw', 'se'].map((corner) => (\n <div\n key={corner}\n className={`rmx-image-handle rmx-handle-${corner}`}\n style={{ pointerEvents: 'all', touchAction: 'none' }}\n onPointerDown={(e) => handlePointerDown(e, corner)}\n />\n ))}\n <div\n className=\"rmx-image-alt-overlay\"\n style={{ pointerEvents: 'all' }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n {editingAlt ? (\n <input\n ref={altInputRef}\n className=\"rmx-image-alt-input\"\n type=\"text\"\n value={altText}\n onChange={(e) => setAltText(e.target.value)}\n onBlur={handleAltSave}\n onKeyDown={handleAltKeyDown}\n placeholder=\"Enter alt text...\"\n />\n ) : (\n <button\n className=\"rmx-image-alt-label\"\n onClick={() => setEditingAlt(true)}\n type=\"button\"\n title=\"Edit alt text\"\n >\n {altText ? `Alt: ${altText}` : 'Add alt text'}\n </button>\n )}\n </div>\n </div>\n )\n}\n","import React, { useCallback } from 'react'\n\nexport function TableControls({ table, engine, editorRect }) {\n if (!table || !engine || !editorRect) return null\n\n const tableRect = table.getBoundingClientRect()\n const top = tableRect.top - editorRect.top\n const left = tableRect.left - editorRect.left\n\n const handleDeleteTable = useCallback(() => {\n if (window.confirm('Are you sure you want to delete this table? This cannot be undone.')) {\n engine.executeCommand('deleteTable')\n }\n }, [engine])\n\n return (\n <div\n className=\"rmx-table-controls\"\n style={{ position: 'absolute', top: top - 28, left }}\n onMouseDown={(e) => e.preventDefault()}\n >\n <button\n className=\"rmx-table-control-btn\"\n onClick={() => engine.executeCommand('addRowBefore')}\n aria-label=\"Add row above\"\n title=\"Add row above\"\n type=\"button\"\n >\n +Row\n </button>\n <button\n className=\"rmx-table-control-btn\"\n onClick={() => engine.executeCommand('addRowAfter')}\n aria-label=\"Add row below\"\n title=\"Add row below\"\n type=\"button\"\n >\n Row+\n </button>\n <button\n className=\"rmx-table-control-btn\"\n onClick={() => engine.executeCommand('addColBefore')}\n aria-label=\"Add column before\"\n title=\"Add column before\"\n type=\"button\"\n >\n +Col\n </button>\n <button\n className=\"rmx-table-control-btn\"\n onClick={() => engine.executeCommand('addColAfter')}\n aria-label=\"Add column after\"\n title=\"Add column after\"\n type=\"button\"\n >\n Col+\n </button>\n <button\n className=\"rmx-table-control-btn rmx-danger\"\n onClick={handleDeleteTable}\n aria-label=\"Delete table\"\n title=\"Delete table\"\n type=\"button\"\n >\n Delete\n </button>\n </div>\n )\n}\n","import React, { useState, useRef, useEffect, useCallback } from 'react'\nimport { SUPPORTED_LANGUAGES } from '@remyxjs/core'\n\n/**\n * CodeBlockControls — Floating language selector that appears above a focused\n * code block. Allows the user to pick or search for a programming language,\n * which then triggers syntax highlighting via the SyntaxHighlightPlugin.\n */\nexport function CodeBlockControls({ codeBlock, engine, editorRect }) {\n if (!codeBlock || !engine || !editorRect) return null\n\n const code = codeBlock.querySelector('code')\n const currentLang = code?.getAttribute('data-language') || ''\n\n const [open, setOpen] = useState(false)\n const [filter, setFilter] = useState('')\n const dropdownRef = useRef(null)\n const inputRef = useRef(null)\n\n // Close dropdown on outside click\n // Include codeBlock in deps to clean up listener when the target block changes\n useEffect(() => {\n if (!open) return\n const handleClick = (e) => {\n if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {\n setOpen(false)\n setFilter('')\n }\n }\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [open, codeBlock])\n\n // Reset dropdown state when the code block changes\n useEffect(() => {\n setOpen(false)\n setFilter('')\n }, [codeBlock])\n\n // Focus filter input when dropdown opens\n useEffect(() => {\n if (open && inputRef.current) {\n inputRef.current.focus()\n }\n }, [open])\n\n const handleSelect = useCallback((langId) => {\n engine.executeCommand('setCodeLanguage', { language: langId })\n setOpen(false)\n setFilter('')\n }, [engine])\n\n const filteredLangs = SUPPORTED_LANGUAGES.filter(\n lang => lang.label.toLowerCase().includes(filter.toLowerCase()) ||\n lang.id.toLowerCase().includes(filter.toLowerCase())\n )\n\n const codeBlockRect = codeBlock.getBoundingClientRect()\n const top = codeBlockRect.top - editorRect.top\n const right = editorRect.right - codeBlockRect.right\n\n const displayLabel = SUPPORTED_LANGUAGES.find(l => l.id === currentLang)?.label || currentLang || 'Auto'\n\n return (\n <div\n ref={dropdownRef}\n className=\"rmx-codeblock-controls\"\n style={{\n position: 'absolute',\n top: top + 4,\n right: right + 4,\n zIndex: 10,\n }}\n onMouseDown={(e) => e.preventDefault()}\n >\n <button\n className=\"rmx-codeblock-lang-btn\"\n onClick={() => setOpen(!open)}\n type=\"button\"\n title=\"Change language\"\n >\n {displayLabel}\n </button>\n\n {open && (\n <div className=\"rmx-codeblock-lang-dropdown\">\n <input\n ref={inputRef}\n className=\"rmx-codeblock-lang-search\"\n type=\"text\"\n placeholder=\"Search languages...\"\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Escape') {\n setOpen(false)\n setFilter('')\n } else if (e.key === 'Enter' && filteredLangs.length > 0) {\n handleSelect(filteredLangs[0].id)\n }\n }}\n />\n <ul className=\"rmx-codeblock-lang-list\">\n {filteredLangs.map(lang => (\n <li key={lang.id}>\n <button\n className={`rmx-codeblock-lang-option ${lang.id === currentLang ? 'rmx-active' : ''}`}\n onClick={() => handleSelect(lang.id)}\n type=\"button\"\n >\n {lang.label}\n </button>\n </li>\n ))}\n {filteredLangs.length === 0 && (\n <li className=\"rmx-codeblock-lang-empty\">No languages found</li>\n )}\n </ul>\n </div>\n )}\n </div>\n )\n}\n","import React from 'react'\n\n/**\n * Full-editor overlay shown when external content (files, images, rich text)\n * is dragged over the editor from the desktop or another application.\n *\n * Renders a translucent overlay with an upload icon and descriptive text.\n * The overlay is pointer-events: none so it doesn't interfere with drop targeting.\n */\nexport function DropZoneOverlay({ visible, fileTypes }) {\n if (!visible) return null\n\n const hasImages = fileTypes.includes('Files') || fileTypes.some(t => t.startsWith('image/'))\n const label = hasImages ? 'Drop files here' : 'Drop content here'\n const hint = hasImages ? 'Images, documents, and rich text' : 'Rich text and HTML content'\n\n return (\n <div className=\"rmx-drop-zone-overlay\" aria-hidden=\"true\">\n <svg\n className=\"rmx-drop-zone-icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"7 10 12 15 17 10\" />\n <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\" />\n </svg>\n <span className=\"rmx-drop-zone-text\">{label}</span>\n <span className=\"rmx-drop-zone-hint\">{hint}</span>\n </div>\n )\n}\n","import React, { useState, useEffect, useRef, useCallback } from 'react'\n\n/**\n * A drag handle that appears on the left side of block elements when hovered or touched.\n * Uses pointer events for cross-device support (mouse + touch + pen).\n * Supports touch-based drag via setPointerCapture with ghost preview.\n * #53: Drop indicator managed via React state instead of direct DOM manipulation.\n */\nexport function BlockDragHandle({ engine, editorRect, editAreaRef }) {\n const [hoveredBlock, setHoveredBlock] = useState(null)\n const [handlePos, setHandlePos] = useState(null)\n const [isDragging, setIsDragging] = useState(false)\n const [ghostPos, setGhostPos] = useState(null)\n const [dropIndicator, setDropIndicator] = useState(null) // { top, left, width }\n const handleRef = useRef(null)\n const rafRef = useRef(null)\n const draggedBlockRef = useRef(null)\n const ghostRef = useRef(null)\n const dropTargetRef = useRef(null)\n\n const updateHoveredBlock = useCallback((e) => {\n if (!engine || !editAreaRef.current) return\n\n // Don't show handle during active drags\n if (engine.dragDrop.isDragging()) {\n setHoveredBlock(null)\n return\n }\n\n const target = e.target\n const block = engine.dragDrop.getDraggableBlock(target)\n\n if (block && block !== hoveredBlock) {\n setHoveredBlock(block)\n\n const blockRect = block.getBoundingClientRect()\n const editorEl = engine.element\n const editorElRect = editorEl.getBoundingClientRect()\n\n setHandlePos({\n top: blockRect.top - editorElRect.top + editorEl.scrollTop + 2,\n left: -24,\n })\n } else if (!block) {\n setHoveredBlock(null)\n }\n }, [engine, editAreaRef, hoveredBlock])\n\n // Use pointer events for cross-device support\n useEffect(() => {\n if (!engine) return\n const editorEl = engine.element\n\n const onPointerMove = (e) => {\n if (rafRef.current) cancelAnimationFrame(rafRef.current)\n rafRef.current = requestAnimationFrame(() => updateHoveredBlock(e))\n }\n\n const onPointerLeave = () => {\n setHoveredBlock(null)\n }\n\n editorEl.addEventListener('pointermove', onPointerMove)\n editorEl.addEventListener('pointerleave', onPointerLeave)\n\n return () => {\n editorEl.removeEventListener('pointermove', onPointerMove)\n editorEl.removeEventListener('pointerleave', onPointerLeave)\n if (rafRef.current) cancelAnimationFrame(rafRef.current)\n }\n }, [engine, updateHoveredBlock])\n\n // When hoveredBlock changes, make it draggable\n useEffect(() => {\n if (!engine || !hoveredBlock) return\n engine.dragDrop.makeBlockDraggable(hoveredBlock)\n return () => {\n engine.dragDrop.unmakeBlockDraggable(hoveredBlock)\n }\n }, [engine, hoveredBlock])\n\n // Touch-based drag via pointer capture\n const handlePointerDown = useCallback((e) => {\n if (!hoveredBlock || !engine) return\n\n // For touch devices, use pointer capture for drag\n const isTouch = e.pointerType === 'touch' || e.pointerType === 'pen'\n if (!isTouch) {\n // For mouse, let native drag handle it\n return\n }\n\n e.preventDefault()\n const handle = handleRef.current\n if (!handle) return\n\n handle.setPointerCapture(e.pointerId)\n setIsDragging(true)\n draggedBlockRef.current = hoveredBlock\n\n // Create ghost preview\n const blockRect = hoveredBlock.getBoundingClientRect()\n setGhostPos({\n x: e.clientX,\n y: e.clientY,\n width: blockRect.width,\n text: hoveredBlock.textContent?.slice(0, 50) || 'Block',\n })\n\n // Add dragging visual\n hoveredBlock.style.opacity = '0.4'\n\n const onPointerMove = (moveEvent) => {\n setGhostPos(prev => prev ? {\n ...prev,\n x: moveEvent.clientX,\n y: moveEvent.clientY,\n } : null)\n\n // Find drop target\n const editorEl = engine.element\n const elements = editorEl.querySelectorAll('[data-block-id], p, h1, h2, h3, h4, h5, h6, ul, ol, blockquote, pre, table, hr')\n let closestBlock = null\n let closestDist = Infinity\n\n for (const el of elements) {\n if (el === draggedBlockRef.current) continue\n const rect = el.getBoundingClientRect()\n const centerY = rect.top + rect.height / 2\n const dist = Math.abs(moveEvent.clientY - centerY)\n if (dist < closestDist) {\n closestDist = dist\n closestBlock = el\n }\n }\n\n // #53: Update drop indicator via React state\n if (closestBlock) {\n const rect = closestBlock.getBoundingClientRect()\n const editorElRect = editorEl.getBoundingClientRect()\n const insertBefore = moveEvent.clientY < rect.top + rect.height / 2\n const indicatorTop = insertBefore\n ? rect.top - editorElRect.top + editorEl.scrollTop\n : rect.bottom - editorElRect.top + editorEl.scrollTop\n\n setDropIndicator({\n top: indicatorTop,\n left: 12,\n width: editorElRect.width - 24,\n })\n dropTargetRef.current = { block: closestBlock, insertBefore }\n } else {\n setDropIndicator(null)\n dropTargetRef.current = null\n }\n }\n\n const onPointerUp = () => {\n handle.removeEventListener('pointermove', onPointerMove)\n handle.removeEventListener('pointerup', onPointerUp)\n\n // Clean up ghost and indicators\n setIsDragging(false)\n setGhostPos(null)\n setDropIndicator(null)\n\n if (draggedBlockRef.current) {\n draggedBlockRef.current.style.opacity = ''\n }\n\n // Move block to the drop target position\n if (dropTargetRef.current && draggedBlockRef.current) {\n const { block: targetBlock, insertBefore } = dropTargetRef.current\n if (targetBlock.parentNode) {\n if (insertBefore) {\n targetBlock.parentNode.insertBefore(draggedBlockRef.current, targetBlock)\n } else {\n targetBlock.parentNode.insertBefore(draggedBlockRef.current, targetBlock.nextSibling)\n }\n }\n }\n\n draggedBlockRef.current = null\n dropTargetRef.current = null\n }\n\n handle.addEventListener('pointermove', onPointerMove)\n handle.addEventListener('pointerup', onPointerUp)\n }, [hoveredBlock, engine])\n\n if (!hoveredBlock || !handlePos) return null\n\n return (\n <>\n <div\n ref={handleRef}\n className=\"rmx-block-drag-handle rmx-block-drag-handle-touch rmx-visible\"\n style={{\n top: handlePos.top,\n left: handlePos.left,\n touchAction: 'none',\n }}\n title=\"Drag to reorder\"\n aria-label=\"Drag to reorder block\"\n role=\"button\"\n onPointerDown={handlePointerDown}\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"currentColor\"\n >\n <circle cx=\"4\" cy=\"3\" r=\"1.2\" />\n <circle cx=\"10\" cy=\"3\" r=\"1.2\" />\n <circle cx=\"4\" cy=\"7\" r=\"1.2\" />\n <circle cx=\"10\" cy=\"7\" r=\"1.2\" />\n <circle cx=\"4\" cy=\"11\" r=\"1.2\" />\n <circle cx=\"10\" cy=\"11\" r=\"1.2\" />\n </svg>\n </div>\n {/* #53: Drop indicator rendered via React state */}\n {isDragging && dropIndicator && (\n <div\n className=\"rmx-touch-drop-indicator\"\n style={{\n position: 'absolute',\n top: dropIndicator.top,\n left: dropIndicator.left,\n width: dropIndicator.width,\n height: 2,\n background: 'var(--rmx-primary, #6366f1)',\n borderRadius: 1,\n pointerEvents: 'none',\n zIndex: 50,\n }}\n />\n )}\n {/* Ghost preview during touch drag */}\n {isDragging && ghostPos && (\n <div\n ref={ghostRef}\n className=\"rmx-drag-ghost\"\n style={{\n position: 'fixed',\n left: ghostPos.x - 20,\n top: ghostPos.y - 20,\n width: Math.min(ghostPos.width, 300),\n pointerEvents: 'none',\n zIndex: 10000,\n }}\n >\n {ghostPos.text}\n </div>\n )}\n </>\n )\n}\n","import React from 'react'\nimport PropTypes from 'prop-types'\n\nconst STATUS_LABELS = {\n saved: 'Saved',\n saving: 'Saving\\u2026',\n unsaved: 'Unsaved changes',\n error: 'Save failed',\n}\n\n/**\n * Inline save-status indicator for the StatusBar.\n * Renders a colored dot and label reflecting the current autosave state.\n *\n * @param {{ saveStatus: 'saved'|'saving'|'unsaved'|'error', lastSaved?: number }} props\n */\nfunction SaveStatusInner({ saveStatus }) {\n const label = STATUS_LABELS[saveStatus] || ''\n const className = `rmx-save-status rmx-save-status--${saveStatus}`\n\n return (\n <span className={className} role=\"status\" aria-live=\"polite\">\n <span className=\"rmx-save-status-dot\" aria-hidden=\"true\" />\n <span className=\"rmx-save-status-label\">{label}</span>\n </span>\n )\n}\n\nexport const SaveStatus = React.memo(SaveStatusInner)\n\nSaveStatus.propTypes = {\n saveStatus: PropTypes.oneOf(['saved', 'saving', 'unsaved', 'error']).isRequired,\n}\n","import React, { useState, useEffect, useRef, useCallback } from 'react'\nimport { ICON_MAP } from '../../icons/index.jsx'\nimport { SaveStatus } from '../SaveStatus/SaveStatus.jsx'\n\nfunction StatusBarInner({ engine, position = 'bottom', saveStatus, showSaveStatus }) {\n const [counts, setCounts] = useState({ wordCount: 0, charCount: 0 })\n const [dirty, setDirty] = useState(false)\n\n // Shallow comparison before setting counts to avoid unnecessary re-renders\n const updateCounts = useCallback((newCounts) => {\n setCounts(prev => {\n if (prev.wordCount === newCounts.wordCount && prev.charCount === newCounts.charCount) {\n return prev\n }\n return newCounts\n })\n }, [])\n\n useEffect(() => {\n if (!engine) return\n if (engine._wordCount) updateCounts(engine._wordCount)\n const unsub = engine.eventBus.on('wordcount:update', updateCounts)\n return unsub\n }, [engine, updateCounts])\n\n // Track dirty state: set on content:change, clear on save\n useEffect(() => {\n if (!engine) return\n const markDirty = () => setDirty(true)\n const markClean = () => setDirty(false)\n const unsubs = [\n engine.eventBus.on('content:change', markDirty),\n engine.eventBus.on('autosave:saved', markClean),\n engine.eventBus.on('save', markClean),\n ]\n return () => unsubs.forEach(fn => fn())\n }, [engine])\n\n const className = `rmx-statusbar${position === 'top' ? ' rmx-statusbar-top' : ''}`\n\n // Show \"Edited\" indicator when content has changed and autosave is not active\n const showDirtyIndicator = dirty && !showSaveStatus\n\n return (\n <div className={className}>\n {showSaveStatus && (\n <>\n <SaveStatus saveStatus={saveStatus} />\n <span className=\"rmx-statusbar-sep\" aria-hidden=\"true\" />\n </>\n )}\n {showDirtyIndicator && (\n <>\n <span className=\"rmx-statusbar-dirty\" role=\"status\" aria-live=\"polite\">\n <span className=\"rmx-statusbar-dirty-dot\" aria-hidden=\"true\" />\n Edited\n </span>\n <span className=\"rmx-statusbar-sep\" aria-hidden=\"true\" />\n </>\n )}\n <span className=\"rmx-statusbar-item\">\n {counts.wordCount} {counts.wordCount === 1 ? 'word' : 'words'}\n </span>\n <span className=\"rmx-statusbar-sep\" aria-hidden=\"true\" />\n <span className=\"rmx-statusbar-item\">\n {counts.charCount} {counts.charCount === 1 ? 'character' : 'characters'}\n </span>\n </div>\n )\n}\n\nexport const StatusBar = React.memo(StatusBarInner)\n\nfunction WordCountButtonInner({ engine }) {\n const [counts, setCounts] = useState({ wordCount: 0, charCount: 0 })\n const [open, setOpen] = useState(false)\n const ref = useRef(null)\n\n // Shallow comparison before setting counts to avoid unnecessary re-renders\n const updateCounts = useCallback((newCounts) => {\n setCounts(prev => {\n if (prev.wordCount === newCounts.wordCount && prev.charCount === newCounts.charCount) {\n return prev\n }\n return newCounts\n })\n }, [])\n\n useEffect(() => {\n if (!engine) return\n if (engine._wordCount) updateCounts(engine._wordCount)\n const unsub = engine.eventBus.on('wordcount:update', updateCounts)\n return unsub\n }, [engine, updateCounts])\n\n // Close popover on outside click\n useEffect(() => {\n if (!open) return\n const handle = (e) => {\n if (ref.current && !ref.current.contains(e.target)) setOpen(false)\n }\n document.addEventListener('mousedown', handle)\n return () => document.removeEventListener('mousedown', handle)\n }, [open])\n\n const WordCountIcon = ICON_MAP.findReplace\n\n return (\n <div ref={ref} className=\"rmx-wordcount-btn-wrap rmx-inline-flex-relative\">\n <button\n className={`rmx-toolbar-btn ${open ? 'rmx-active' : ''}`}\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n setOpen(o => !o)\n }}\n onMouseDown={(e) => e.preventDefault()}\n title=\"Word Count\"\n type=\"button\"\n aria-label=\"Word Count\"\n aria-expanded={open}\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M4 7h16M4 12h10M4 17h12\" />\n </svg>\n </button>\n {open && (\n <div className=\"rmx-wordcount-popover\">\n <div className=\"rmx-wordcount-popover-row\">\n <span className=\"rmx-wordcount-popover-label\">Words</span>\n <span className=\"rmx-wordcount-popover-value\">{counts.wordCount}</span>\n </div>\n <div className=\"rmx-wordcount-popover-row\">\n <span className=\"rmx-wordcount-popover-label\">Characters</span>\n <span className=\"rmx-wordcount-popover-value\">{counts.charCount}</span>\n </div>\n </div>\n )}\n </div>\n )\n}\n\nexport const WordCountButton = React.memo(WordCountButtonInner)\n","import React from 'react'\nimport PropTypes from 'prop-types'\n\n/**\n * Compute a human-readable relative time string from a timestamp.\n * @param {number} timestamp - Unix timestamp in milliseconds\n * @returns {string}\n */\nfunction formatTimeAgo(timestamp) {\n if (!timestamp) return 'a previous session'\n\n const seconds = Math.floor((Date.now() - timestamp) / 1000)\n\n if (seconds < 10) return 'just now'\n if (seconds < 60) return `${seconds} seconds ago`\n\n const minutes = Math.floor(seconds / 60)\n if (minutes === 1) return '1 minute ago'\n if (minutes < 60) return `${minutes} minutes ago`\n\n const hours = Math.floor(minutes / 60)\n if (hours === 1) return '1 hour ago'\n if (hours < 24) return `${hours} hours ago`\n\n const days = Math.floor(hours / 24)\n if (days === 1) return 'yesterday'\n return `${days} days ago`\n}\n\n/**\n * Recovery banner shown above the edit area when autosaved content\n * is detected that differs from the current editor content.\n *\n * @param {{ recoveryData: {recoveredContent: string, timestamp: number}|null, onRecover: () => void, onDismiss: () => void }} props\n */\nfunction RecoveryBannerInner({ recoveryData, onRecover, onDismiss }) {\n if (!recoveryData) return null\n\n const timeAgo = formatTimeAgo(recoveryData.timestamp)\n\n return (\n <div className=\"rmx-recovery-banner\" role=\"alert\">\n <svg\n className=\"rmx-recovery-banner-icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <polyline points=\"12 6 12 12 16 14\" />\n </svg>\n <span className=\"rmx-recovery-banner-text\">\n Unsaved changes found from {timeAgo}\n </span>\n <div className=\"rmx-recovery-banner-actions\">\n <button\n className=\"rmx-recovery-btn rmx-recovery-btn--restore\"\n onClick={onRecover}\n type=\"button\"\n >\n Restore\n </button>\n <button\n className=\"rmx-recovery-btn rmx-recovery-btn--dismiss\"\n onClick={onDismiss}\n type=\"button\"\n >\n Dismiss\n </button>\n </div>\n </div>\n )\n}\n\nexport const RecoveryBanner = React.memo(RecoveryBannerInner)\n\nRecoveryBanner.propTypes = {\n recoveryData: PropTypes.shape({\n recoveredContent: PropTypes.string.isRequired,\n timestamp: PropTypes.number.isRequired,\n }),\n onRecover: PropTypes.func.isRequired,\n onDismiss: PropTypes.func.isRequired,\n}\n","import React from 'react'\n\nexport class EditorErrorBoundary extends React.Component {\n constructor(props) {\n super(props)\n this.state = { hasError: false, error: null }\n }\n\n static getDerivedStateFromError(error) {\n return { hasError: true, error }\n }\n\n componentDidCatch(error, errorInfo) {\n this.props.onError?.(error, errorInfo)\n }\n\n render() {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback\n }\n return (\n <div className=\"rmx-error-boundary\">\n <p>Something went wrong with the editor.</p>\n <button onClick={() => this.setState({ hasError: false, error: null })}>\n Try again\n </button>\n </div>\n )\n }\n return this.props.children\n }\n}\n","import React from 'react'\n\n/**\n * EmptyState — renders when the editor has no content.\n * Configurable via the `emptyState` prop on RemyxEditor:\n * - `true` → shows the default illustration + \"Start typing...\" message\n * - React node → renders the provided custom content\n * - `false` / omitted → not rendered\n */\nexport function EmptyState({ custom, onClick }) {\n if (custom && custom !== true) {\n return (\n <div className=\"rmx-empty-state\" onClick={onClick} role=\"button\" tabIndex={0}>\n {custom}\n </div>\n )\n }\n\n return (\n <div className=\"rmx-empty-state\" onClick={onClick} role=\"button\" tabIndex={0}>\n <div className=\"rmx-empty-state-icon\">\n <svg viewBox=\"0 0 64 64\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <rect x=\"8\" y=\"8\" width=\"48\" height=\"48\" rx=\"6\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" />\n <line x1=\"16\" y1=\"20\" x2=\"48\" y2=\"20\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n <line x1=\"16\" y1=\"28\" x2=\"40\" y2=\"28\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" opacity=\"0.6\" />\n <line x1=\"16\" y1=\"36\" x2=\"44\" y2=\"36\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" opacity=\"0.4\" />\n <line x1=\"16\" y1=\"44\" x2=\"32\" y2=\"44\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" opacity=\"0.2\" />\n </svg>\n </div>\n <div className=\"rmx-empty-state-text\">Start typing...</div>\n <div className=\"rmx-empty-state-hint\">or paste content, drag a file, or use the toolbar above</div>\n </div>\n )\n}\n","import React, { useState, useEffect, useCallback } from 'react'\n\n/**\n * BreadcrumbBar — shows the DOM path from editor root to current selection.\n * e.g., \"Blockquote > Paragraph\" or \"Table > Row 2 > Cell 3\"\n * Updates on selection:change. Renders between toolbar and edit area.\n * #49: Items are clickable — clicking selects the corresponding element.\n */\n\nconst TAG_LABELS = {\n P: 'Paragraph',\n H1: 'Heading 1', H2: 'Heading 2', H3: 'Heading 3',\n H4: 'Heading 4', H5: 'Heading 5', H6: 'Heading 6',\n BLOCKQUOTE: 'Blockquote',\n PRE: 'Code Block',\n UL: 'Bulleted List', OL: 'Numbered List',\n LI: 'List Item',\n TABLE: 'Table', THEAD: 'Header', TBODY: 'Body',\n TR: 'Row', TH: 'Header Cell', TD: 'Cell',\n A: 'Link', STRONG: 'Bold', EM: 'Italic',\n U: 'Underline', S: 'Strikethrough',\n DIV: 'Block', SPAN: 'Inline',\n DETAILS: 'Collapsible', SUMMARY: 'Summary',\n FIGURE: 'Figure', FIGCAPTION: 'Caption',\n IMG: 'Image',\n}\n\nfunction getLabel(el) {\n const tag = el.tagName\n let label = TAG_LABELS[tag] || tag.toLowerCase()\n\n // Provide context for table rows/cells\n if (tag === 'TR' && el.parentElement) {\n const rows = Array.from(el.parentElement.children)\n const index = rows.indexOf(el) + 1\n label = `Row ${index}`\n }\n if ((tag === 'TD' || tag === 'TH') && el.parentElement) {\n const cells = Array.from(el.parentElement.children)\n const index = cells.indexOf(el) + 1\n label = `Cell ${index}`\n }\n if (tag === 'LI' && el.parentElement) {\n const items = Array.from(el.parentElement.children)\n const index = items.indexOf(el) + 1\n label = `Item ${index}`\n }\n\n return label\n}\n\nfunction buildPath(node, editorEl) {\n const path = []\n let current = node\n\n // Walk up from the selection node to the editor element\n while (current && current !== editorEl && current !== document.body) {\n if (current.nodeType === Node.ELEMENT_NODE) {\n // Skip the edit area wrapper\n if (current.classList?.contains('rmx-edit-area') || current.classList?.contains('rmx-content')) {\n current = current.parentElement\n continue\n }\n path.unshift({ label: getLabel(current), element: current })\n }\n current = current.parentElement\n }\n\n return path.length > 0 ? path : [{ label: 'Paragraph', element: null }]\n}\n\nexport const BreadcrumbBar = React.memo(function BreadcrumbBar({ engine }) {\n const [path, setPath] = useState([{ label: 'Paragraph', element: null }])\n\n const updatePath = useCallback(() => {\n if (!engine?.element) return\n const sel = window.getSelection()\n if (!sel || sel.rangeCount === 0) return\n\n let node = sel.anchorNode\n if (!node) return\n if (node.nodeType === Node.TEXT_NODE) node = node.parentElement\n if (!node || !engine.element.contains(node)) return\n\n setPath(buildPath(node, engine.element))\n }, [engine])\n\n useEffect(() => {\n if (!engine) return\n const unsub = engine.eventBus.on('selection:change', updatePath)\n updatePath()\n return unsub\n }, [engine, updatePath])\n\n // #49: Click handler to select corresponding element\n const handleClick = useCallback((element) => {\n if (!element || !engine) return\n try {\n const range = document.createRange()\n range.selectNodeContents(element)\n const sel = window.getSelection()\n sel.removeAllRanges()\n sel.addRange(range)\n engine.eventBus.emit('selection:change')\n } catch {\n // Ignore errors if element is no longer in DOM\n }\n }, [engine])\n\n return (\n <div className=\"rmx-breadcrumb-bar\" role=\"navigation\" aria-label=\"Document path\">\n {path.map((segment, i) => (\n <React.Fragment key={i}>\n {i > 0 && <span className=\"rmx-breadcrumb-separator\" aria-hidden=\"true\">›</span>}\n <button\n type=\"button\"\n className=\"rmx-breadcrumb-item\"\n onClick={() => handleClick(segment.element)}\n style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '0 2px', font: 'inherit', color: 'inherit' }}\n >\n {segment.label}\n </button>\n </React.Fragment>\n ))}\n </div>\n )\n})\n","import React, { useRef, useState, useEffect, useCallback } from 'react'\n\n/**\n * Minimap — renders a scaled-down preview of the document on the right edge.\n * Click to scroll. Updates on content:change. Optional via `minimap` prop.\n */\nexport const Minimap = React.memo(function Minimap({ engine, editAreaRef }) {\n const minimapRef = useRef(null)\n const contentRef = useRef(null)\n const [viewportTop, setViewportTop] = useState(0)\n const [viewportHeight, setViewportHeight] = useState(20)\n const [textContent, setTextContent] = useState('')\n\n // Update minimap content when editor content changes\n const updateContent = useCallback(() => {\n if (!engine?.element) return\n // Task 244: Use textContent instead of innerText (faster, no layout reflow)\n const text = engine.element.textContent || ''\n setTextContent(text)\n }, [engine])\n\n // Update viewport indicator on scroll\n const updateViewport = useCallback(() => {\n if (!editAreaRef?.current || !minimapRef.current) return\n const area = editAreaRef.current\n const minimap = minimapRef.current\n\n const scrollRatio = area.scrollTop / (area.scrollHeight || 1)\n const visibleRatio = area.clientHeight / (area.scrollHeight || 1)\n\n const minimapHeight = minimap.clientHeight\n setViewportTop(scrollRatio * minimapHeight)\n setViewportHeight(Math.max(visibleRatio * minimapHeight, 10))\n }, [editAreaRef])\n\n useEffect(() => {\n if (!engine) return\n const unsub = engine.eventBus.on('content:change', updateContent)\n updateContent()\n return unsub\n }, [engine, updateContent])\n\n // Task 245: Wrap scroll handler with requestAnimationFrame throttling\n useEffect(() => {\n const area = editAreaRef?.current\n if (!area) return\n\n let rafId = null\n const throttledUpdateViewport = () => {\n if (rafId) return\n rafId = requestAnimationFrame(() => {\n updateViewport()\n rafId = null\n })\n }\n\n area.addEventListener('scroll', throttledUpdateViewport)\n updateViewport()\n return () => {\n area.removeEventListener('scroll', throttledUpdateViewport)\n if (rafId) cancelAnimationFrame(rafId)\n }\n }, [editAreaRef, updateViewport])\n\n // Click to scroll\n const handleClick = useCallback((e) => {\n if (!editAreaRef?.current || !minimapRef.current) return\n const minimap = minimapRef.current\n const area = editAreaRef.current\n\n const rect = minimap.getBoundingClientRect()\n const clickRatio = (e.clientY - rect.top) / rect.height\n const scrollTarget = clickRatio * area.scrollHeight - area.clientHeight / 2\n\n area.scrollTo({ top: Math.max(0, scrollTarget), behavior: 'smooth' })\n }, [editAreaRef])\n\n return (\n <div className=\"rmx-minimap\" ref={minimapRef} onClick={handleClick} aria-hidden=\"true\">\n <div className=\"rmx-minimap-content\" ref={contentRef}>\n {textContent}\n </div>\n <div\n className=\"rmx-minimap-viewport\"\n style={{ top: viewportTop, height: viewportHeight }}\n />\n </div>\n )\n})\n","import React, { useState, useEffect, useCallback, useRef } from 'react'\nimport { htmlToMarkdown } from '@remyxjs/core'\n\n/**\n * SplitPreview — side-by-side preview pane showing rendered HTML or markdown source.\n * Shown when split view is active. Updates on content:change.\n * Task 246: Debounced content update with 200ms timeout.\n */\nexport const SplitPreview = React.memo(function SplitPreview({ engine, format }) {\n const [content, setContent] = useState('')\n const previewFormat = format || 'html'\n const debounceRef = useRef(null)\n\n const updateContent = useCallback(() => {\n if (!engine) return\n const html = engine.getHTML()\n if (previewFormat === 'markdown') {\n setContent(htmlToMarkdown(html))\n } else {\n setContent(html)\n }\n }, [engine, previewFormat])\n\n useEffect(() => {\n if (!engine) return\n const debouncedUpdate = () => {\n clearTimeout(debounceRef.current)\n debounceRef.current = setTimeout(updateContent, 200)\n }\n const unsub = engine.eventBus.on('content:change', debouncedUpdate)\n updateContent() // Initial content without debounce\n return () => {\n unsub()\n clearTimeout(debounceRef.current)\n }\n }, [engine, updateContent])\n\n return (\n <div className=\"rmx-split-preview-container\" style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0 }}>\n <div className=\"rmx-split-preview-label\">\n <span>{previewFormat === 'markdown' ? 'Markdown' : 'HTML'} Preview</span>\n </div>\n <div className=\"rmx-split-preview\">\n {content}\n </div>\n </div>\n )\n})\n","import { useState, useEffect, useCallback } from 'react'\n\n/**\n * Lightweight toast notification component.\n * Shows a brief message at the bottom-center of the screen and auto-dismisses.\n *\n * @param {string} message - The text to display\n * @param {'info'|'success'|'warning'} type - Visual style (default: 'info')\n * @param {number} duration - Auto-dismiss time in ms (default: 3000)\n * @param {function} onDismiss - Called when toast is dismissed\n */\nexport function Toast({ message, type = 'info', duration = 3000, onDismiss }) {\n const [visible, setVisible] = useState(true)\n\n useEffect(() => {\n if (!message) return\n setVisible(true)\n const timer = setTimeout(() => {\n setVisible(false)\n onDismiss?.()\n }, duration)\n return () => clearTimeout(timer)\n }, [message, duration, onDismiss])\n\n if (!visible || !message) return null\n\n return (\n <div\n className={`rmx-toast rmx-toast--${type}`}\n role=\"status\"\n aria-live=\"polite\"\n style={{ animationDuration: `${duration}ms` }}\n >\n {message}\n </div>\n )\n}\n\n/**\n * Hook to manage toast state. Returns [toast element, showToast function].\n *\n * Usage:\n * const [toastEl, showToast] = useToast()\n * showToast('Saved!', 'success')\n * return <>{toastEl}</>\n */\nexport function useToast() {\n const [toastState, setToastState] = useState(null)\n\n const showToast = useCallback((message, type = 'info', duration = 3000) => {\n // Force re-render by using a new key\n setToastState({ message, type, duration, key: Date.now() })\n }, [])\n\n const handleDismiss = useCallback(() => {\n setToastState(null)\n }, [])\n\n const toastEl = toastState ? (\n <Toast\n key={toastState.key}\n message={toastState.message}\n type={toastState.type}\n duration={toastState.duration}\n onDismiss={handleDismiss}\n />\n ) : null\n\n return [toastEl, showToast]\n}\n","import React, { Suspense } from 'react'\n\n/**\n * Item 22: Extracted from RemyxEditor.jsx — handles all lazy-loaded modal rendering.\n * Reduces RemyxEditor component size by consolidating modal Suspense boundaries.\n */\n\n// Lazy-loaded modal components — only loaded when opened\nconst CommandPalette = React.lazy(() => import('./CommandPalette/CommandPalette.jsx').then(m => ({ default: m.CommandPalette })))\nconst LinkModal = React.lazy(() => import('./Modals/LinkModal.jsx').then(m => ({ default: m.LinkModal })))\nconst ImageModal = React.lazy(() => import('./Modals/ImageModal.jsx').then(m => ({ default: m.ImageModal })))\nconst TablePickerModal = React.lazy(() => import('./Modals/TablePickerModal.jsx').then(m => ({ default: m.TablePickerModal })))\nconst EmbedModal = React.lazy(() => import('./Modals/EmbedModal.jsx').then(m => ({ default: m.EmbedModal })))\nconst FindReplacePanel = React.lazy(() => import('./Modals/FindReplaceModal.jsx').then(m => ({ default: m.FindReplacePanel })))\nconst SourceModal = React.lazy(() => import('./Modals/SourceModal.jsx').then(m => ({ default: m.SourceModal })))\nconst ExportModal = React.lazy(() => import('./Modals/ExportModal.jsx').then(m => ({ default: m.ExportModal })))\nconst AttachmentModal = React.lazy(() => import('./Modals/AttachmentModal.jsx').then(m => ({ default: m.AttachmentModal })))\nconst ImportDocumentModal = React.lazy(() => import('./Modals/ImportDocumentModal.jsx').then(m => ({ default: m.ImportDocumentModal })))\n\n/**\n * @param {object} props\n * @param {object} props.modals - Modal state from useModal\n * @param {Function} props.closeModal - Close a modal by name\n * @param {object} props.engine - Editor engine instance\n * @param {boolean} props.showCommandPalette - Whether command palette is enabled\n * @param {boolean} props.commandPaletteOpen - Whether command palette is currently open\n * @param {Function} props.setCommandPaletteOpen - Toggle command palette\n * @param {Function} props.handleOpenModal - Open modal handler\n */\nexport function EditorModals({\n modals,\n closeModal,\n engine,\n showCommandPalette,\n commandPaletteOpen,\n setCommandPaletteOpen,\n handleOpenModal,\n}) {\n return (\n <Suspense fallback={<div className=\"rmx-loading-spinner\" />}>\n {modals.link.open && (\n <LinkModal\n open={modals.link.open}\n onClose={() => closeModal('link')}\n engine={engine}\n data={modals.link.data}\n />\n )}\n {modals.image.open && (\n <ImageModal\n open={modals.image.open}\n onClose={() => closeModal('image')}\n engine={engine}\n />\n )}\n {modals.attachment?.open && (\n <AttachmentModal\n open={modals.attachment.open}\n onClose={() => closeModal('attachment')}\n engine={engine}\n />\n )}\n {modals.importDocument?.open && (\n <ImportDocumentModal\n open={modals.importDocument.open}\n onClose={() => closeModal('importDocument')}\n engine={engine}\n />\n )}\n {modals.table.open && (\n <TablePickerModal\n open={modals.table.open}\n onClose={() => closeModal('table')}\n engine={engine}\n />\n )}\n {modals.embed.open && (\n <EmbedModal\n open={modals.embed.open}\n onClose={() => closeModal('embed')}\n engine={engine}\n />\n )}\n {modals.source.open && (\n <SourceModal\n open={modals.source.open}\n onClose={() => {\n closeModal('source')\n if (engine?.isSourceMode) {\n engine.isSourceMode = false\n engine.eventBus.emit('mode:change', { sourceMode: false })\n }\n }}\n engine={engine}\n />\n )}\n {modals.export.open && (\n <ExportModal\n open={modals.export.open}\n onClose={() => closeModal('export')}\n engine={engine}\n />\n )}\n {showCommandPalette && commandPaletteOpen && (\n <CommandPalette\n open={commandPaletteOpen}\n onClose={() => setCommandPaletteOpen(false)}\n engine={engine}\n onOpenModal={handleOpenModal}\n />\n )}\n </Suspense>\n )\n}\n\nexport { FindReplacePanel }\n","import React, { useRef, useState, useCallback, useEffect, useMemo, Suspense } from 'react'\nimport { createPortal } from 'react-dom'\nimport { useEditorEngine } from '../hooks/useEditorEngine.js'\nimport { useSelection } from '../hooks/useSelection.js'\nimport { useModal } from '../hooks/useModal.js'\nimport { useContextMenu } from '../hooks/useContextMenu.js'\n\nimport { useResolvedConfig } from '../hooks/useResolvedConfig.js'\nimport { useAutosave } from '../hooks/useAutosave.js'\nimport { usePortalAttachment } from '../hooks/usePortalAttachment.js'\nimport { useEditorRect } from '../hooks/useEditorRect.js'\nimport { useDragDrop } from '../hooks/useDragDrop.js'\nimport { useSwipeGesture } from '../hooks/useSwipeGesture.js'\nimport { useLongPress } from '../hooks/useLongPress.js'\nimport { usePinchZoom } from '../hooks/usePinchZoom.js'\nimport { useVirtualKeyboard } from '../hooks/useVirtualKeyboard.js'\nimport { loadGoogleFonts, DEFAULT_FONTS } from '@remyxjs/core'\nimport { SelectionContext } from '../config/SelectionContext.js'\nimport { Toolbar } from './Toolbar/Toolbar.jsx'\nimport { EditArea } from './EditArea/EditArea.jsx'\nimport { FloatingToolbar } from './EditArea/FloatingToolbar.jsx'\nimport { ImageResizeHandles } from './EditArea/ImageResizeHandles.jsx'\nimport { TableControls } from './EditArea/TableControls.jsx'\nimport { CodeBlockControls } from './EditArea/CodeBlockControls.jsx'\nimport { DropZoneOverlay } from './EditArea/DropZoneOverlay.jsx'\nimport { BlockDragHandle } from './EditArea/BlockDragHandle.jsx'\nimport { StatusBar, WordCountButton } from './StatusBar/StatusBar.jsx'\nimport { RecoveryBanner } from './RecoveryBanner/RecoveryBanner.jsx'\nimport { EditorErrorBoundary } from './ErrorBoundary.jsx'\nimport { EmptyState } from './EmptyState/EmptyState.jsx'\nimport { BreadcrumbBar } from './BreadcrumbBar/BreadcrumbBar.jsx'\nimport { Minimap } from './Minimap/Minimap.jsx'\nimport { SplitPreview } from './SplitPreview/SplitPreview.jsx'\nimport { useToast } from './Toast/Toast.jsx'\n\n// Lazy-loaded components — only loaded when needed\nconst MenuBar = React.lazy(() => import('./MenuBar/MenuBar.jsx').then(m => ({ default: m.MenuBar })))\nconst ContextMenu = React.lazy(() => import('./ContextMenu/ContextMenu.jsx').then(m => ({ default: m.ContextMenu })))\n\n// Item 22: Modals extracted to EditorModals sub-component\nimport { EditorModals, FindReplacePanel } from './EditorModals.jsx'\n\nexport default function RemyxEditor(props) {\n // Resolve configuration from props, context, and defaults\n const {\n attachTo, value, defaultValue, onChange, toolbar,\n theme, placeholder, height, minHeight, maxHeight,\n readOnly, plugins, onReady, onFocus, onBlur,\n className, style, uploadHandler, outputFormat,\n showFloatingToolbar, showContextMenu, fonts, googleFonts,\n statusBar, customTheme, toolbarItemTheme, sanitize, shortcuts,\n baseHeadingLevel, menuBarConfig, effectiveToolbar, onError, errorFallback,\n showCommandPalette,\n autosaveConfig,\n emptyState: emptyStateProp,\n showBreadcrumb,\n showMinimap,\n splitViewFormat,\n customizableToolbar: customizableToolbarProp,\n onToolbarChange,\n } = useResolvedConfig(props)\n\n const editAreaRef = useRef(null)\n const editorRootRef = useRef(null)\n\n // Load Google Fonts and merge into font list\n useEffect(() => {\n if (googleFonts && googleFonts.length > 0) {\n loadGoogleFonts(googleFonts)\n }\n }, [googleFonts])\n\n const mergedFonts = useMemo(() => {\n if (!googleFonts || googleFonts.length === 0) return fonts\n const googleFontNames = googleFonts.map(f => f.split(':')[0])\n const base = fonts || DEFAULT_FONTS\n const existing = new Set(base.map(f => f.toLowerCase()))\n const newFonts = googleFontNames.filter(f => !existing.has(f.toLowerCase()))\n return [...base, ...newFonts]\n }, [fonts, googleFonts])\n\n // Portal attachment for textarea/div binding\n const { portalContainer, effectiveValue, effectiveOnChange } = usePortalAttachment({\n attachTo, value, defaultValue, onChange,\n })\n\n const { engine, ready } = useEditorEngine(editAreaRef, {\n value: attachTo ? effectiveValue : value,\n defaultValue: attachTo ? undefined : defaultValue,\n onChange: effectiveOnChange,\n outputFormat,\n placeholder,\n readOnly,\n plugins,\n onReady,\n onFocus,\n onBlur,\n uploadHandler,\n sanitize,\n shortcuts,\n baseHeadingLevel,\n }, portalContainer)\n\n const { formatState, uiState } = useSelection(engine)\n const { modals, openModal, closeModal } = useModal()\n const { contextMenu, hideContextMenu } = useContextMenu(engine, editAreaRef)\n const { saveStatus, recoveryData, recoverContent, dismissRecovery } = useAutosave(engine, autosaveConfig)\n\n // #39: Toast notification system\n const [toastEl, showToast] = useToast()\n\n // Wire toast to engine events for transient feedback\n useEffect(() => {\n if (!engine) return\n const unsubs = [\n engine.eventBus.on('export:success', () => showToast('Export successful', 'success')),\n engine.eventBus.on('clipboard:copy', () => showToast('Copied to clipboard', 'info')),\n ]\n return () => unsubs.forEach(unsub => typeof unsub === 'function' && unsub())\n }, [engine, showToast])\n\n // Track editor rect for positioning overlays (ResizeObserver + rAF throttled)\n const editorRect = useEditorRect(editorRootRef)\n\n // Expose engine on the DOM element for E2E testing and external integrations\n useEffect(() => {\n if (editorRootRef.current && engine) {\n editorRootRef.current.__engine = engine\n }\n }, [engine])\n\n // Track drag-and-drop state for overlay rendering\n const { isExternalDrag, dragFileTypes } = useDragDrop(engine)\n\n // Mobile & touch optimization hooks\n useSwipeGesture(engine, editAreaRef, {\n onDismissToolbar: () => {\n // Trigger floating toolbar dismiss by clearing selection\n if (engine?.element) {\n window.getSelection()?.removeAllRanges()\n }\n },\n })\n\n // Long-press context menu on touch devices\n const handleLongPress = useCallback(({ x, y }) => {\n if (!engine) return\n // Simulate a context menu event at the touch position\n const fakeEvent = { clientX: x, clientY: y, preventDefault: () => {} }\n engine.eventBus.emit('contextmenu', fakeEvent)\n }, [engine])\n useLongPress(editAreaRef, handleLongPress, { enabled: showContextMenu && !readOnly })\n\n // Pinch-to-zoom on images and tables\n const { zoomedElement, resetZoom } = usePinchZoom(editAreaRef)\n\n // Virtual keyboard awareness\n useVirtualKeyboard(engine, editorRootRef)\n\n // Handle source mode toggle\n useEffect(() => {\n if (!engine) return\n const unsub = engine.eventBus.on('mode:change', ({ sourceMode: sm }) => {\n if (sm) {\n openModal('source')\n }\n })\n return unsub\n }, [engine, openModal])\n\n // Task 259: Merged keydown handlers (Cmd+F and Cmd+Shift+P) into a single useEffect\n useEffect(() => {\n if (!engine) return\n const handleKeyDown = (e) => {\n const mod = navigator.platform.includes('Mac') ? e.metaKey : e.ctrlKey\n if (mod && e.key === 'f') {\n e.preventDefault()\n openModal('findReplace')\n }\n if (showCommandPalette && mod && e.shiftKey && (e.key === 'p' || e.key === 'P')) {\n e.preventDefault()\n setCommandPaletteOpen(prev => !prev)\n }\n }\n engine.element?.addEventListener('keydown', handleKeyDown)\n return () => engine.element?.removeEventListener('keydown', handleKeyDown)\n }, [engine, openModal, showCommandPalette])\n\n // Wire onError callback to engine error events\n useEffect(() => {\n if (!engine || !onError) return\n const unsubs = [\n engine.eventBus.on('plugin:error', ({ name, error }) => onError(error, { source: 'plugin', pluginName: name })),\n engine.eventBus.on('editor:error', ({ phase, error }) => onError(error, { source: 'engine', phase })),\n engine.eventBus.on('upload:error', ({ file, error }) => onError(error, { source: 'upload', file })),\n ]\n return () => unsubs.forEach(unsub => unsub())\n }, [engine, onError])\n\n const handleOpenModal = useCallback((name, data) => {\n if (name === 'commandPalette') {\n setCommandPaletteOpen(true)\n return\n }\n openModal(name, data)\n }, [openModal])\n\n // Command palette state\n const [commandPaletteOpen, setCommandPaletteOpen] = useState(false)\n\n // Task 241: Consolidated content read — compute isEmpty from engine.getText() once\n const [isEmpty, setIsEmpty] = useState(true)\n useEffect(() => {\n if (!engine) return\n const check = () => {\n const text = engine.getText().trim()\n setIsEmpty(text === '' || text === '\\n')\n }\n const unsub = engine.eventBus.on('content:change', check)\n check()\n return unsub\n }, [engine])\n\n // Split view state\n const [splitViewActive, setSplitViewActive] = useState(false)\n useEffect(() => {\n if (!engine) return\n const unsub = engine.eventBus.on('splitView:toggle', ({ active }) => setSplitViewActive(active))\n return unsub\n }, [engine])\n\n // Task 257: Memoize wordCountButton element\n const wordCountBtn = useMemo(() =>\n statusBar === 'popup' ? <WordCountButton engine={engine} /> : null,\n [statusBar, engine]\n )\n\n // Task 239: Memoize theme className\n const themeClassName = useMemo(() =>\n `rmx-editor rmx-theme-${/^[a-zA-Z0-9_-]+$/.test(theme) ? theme : 'light'} ${className || ''}`,\n [theme, className]\n )\n\n const editAreaStyle = useMemo(() => ({\n minHeight: minHeight || height,\n maxHeight: maxHeight || undefined,\n height: maxHeight ? undefined : height,\n overflowY: 'auto',\n }), [minHeight, height, maxHeight])\n\n const mergedStyle = useMemo(() =>\n customTheme ? { ...customTheme, ...style } : style,\n [customTheme, style]\n )\n\n const editorTree = (\n <SelectionContext.Provider value={formatState}>\n <div\n ref={editorRootRef}\n className={themeClassName}\n style={mergedStyle}\n >\n <a className=\"rmx-skip-link\" href=\"#rmx-edit-area\">\n Skip to editor content\n </a>\n\n {menuBarConfig && (\n <Suspense fallback={<div className=\"rmx-loading-spinner\" />}>\n <MenuBar\n config={menuBarConfig}\n engine={engine}\n onOpenModal={handleOpenModal}\n />\n </Suspense>\n )}\n\n <Toolbar\n config={effectiveToolbar || toolbar}\n engine={engine}\n onOpenModal={handleOpenModal}\n fonts={mergedFonts}\n statusBarMode={statusBar}\n wordCountButton={wordCountBtn}\n toolbarItemTheme={toolbarItemTheme}\n customizableToolbar={customizableToolbarProp}\n onToolbarChange={onToolbarChange}\n />\n\n {autosaveConfig.enabled && autosaveConfig.showRecoveryBanner !== false && (\n <RecoveryBanner\n recoveryData={recoveryData}\n onRecover={recoverContent}\n onDismiss={dismissRecovery}\n />\n )}\n\n {showBreadcrumb && engine && (\n <BreadcrumbBar engine={engine} />\n )}\n\n {statusBar === 'top' && (\n <StatusBar\n engine={engine}\n position=\"top\"\n saveStatus={saveStatus}\n showSaveStatus={autosaveConfig.enabled && autosaveConfig.showSaveStatus !== false}\n />\n )}\n\n <div className=\"rmx-editor-body\" style={{ position: 'relative' }}>\n {emptyStateProp && isEmpty && !readOnly && (\n <EmptyState\n custom={emptyStateProp}\n onClick={() => engine?.focus()}\n />\n )}\n\n <EditArea\n ref={editAreaRef}\n style={editAreaStyle}\n readOnly={readOnly}\n id=\"rmx-edit-area\"\n />\n\n {splitViewActive && engine && (\n <SplitPreview engine={engine} format={splitViewFormat} />\n )}\n\n {showMinimap && engine && (\n <Minimap engine={engine} editAreaRef={editAreaRef} />\n )}\n\n {showFloatingToolbar && (\n <FloatingToolbar\n visible={uiState.hasSelection}\n selectionRect={uiState.selectionRect}\n engine={engine}\n editorRect={editorRect}\n onOpenModal={handleOpenModal}\n />\n )}\n\n {uiState.focusedImage && (\n <ImageResizeHandles\n image={uiState.focusedImage}\n engine={engine}\n editorRect={editorRect}\n />\n )}\n\n {uiState.focusedTable && (\n <TableControls\n table={uiState.focusedTable}\n engine={engine}\n editorRect={editorRect}\n />\n )}\n\n {uiState.focusedCodeBlock && (\n <CodeBlockControls\n codeBlock={uiState.focusedCodeBlock}\n engine={engine}\n editorRect={editorRect}\n />\n )}\n\n {!readOnly && engine && (\n <BlockDragHandle\n engine={engine}\n editorRect={editorRect}\n editAreaRef={editAreaRef}\n />\n )}\n\n {zoomedElement && (\n <button\n className=\"rmx-pinch-zoom-reset\"\n onClick={resetZoom}\n type=\"button\"\n aria-label=\"Reset zoom\"\n >\n Reset Zoom\n </button>\n )}\n\n <DropZoneOverlay\n visible={isExternalDrag}\n fileTypes={dragFileTypes}\n />\n\n <Suspense fallback={<div className=\"rmx-loading-spinner\" />}>\n {modals.findReplace.open && (\n <FindReplacePanel\n open={modals.findReplace.open}\n onClose={() => closeModal('findReplace')}\n engine={engine}\n />\n )}\n </Suspense>\n </div>\n\n {statusBar === 'bottom' && (\n <StatusBar\n engine={engine}\n saveStatus={saveStatus}\n showSaveStatus={autosaveConfig.enabled && autosaveConfig.showSaveStatus !== false}\n />\n )}\n\n {showContextMenu && (\n <Suspense fallback={<div className=\"rmx-loading-spinner\" />}>\n <ContextMenu\n contextMenu={contextMenu}\n onHide={hideContextMenu}\n onOpenModal={handleOpenModal}\n />\n </Suspense>\n )}\n\n {/* #39: Toast notifications */}\n {toastEl}\n\n {/* Item 22: Modals extracted to EditorModals sub-component */}\n <EditorModals\n modals={modals}\n closeModal={closeModal}\n engine={engine}\n showCommandPalette={showCommandPalette}\n commandPaletteOpen={commandPaletteOpen}\n setCommandPaletteOpen={setCommandPaletteOpen}\n handleOpenModal={handleOpenModal}\n />\n </div>\n </SelectionContext.Provider>\n )\n\n const wrappedTree = (\n <EditorErrorBoundary onError={onError} fallback={errorFallback}>\n {editorTree}\n </EditorErrorBoundary>\n )\n\n // When attachTo is provided, render via portal into the target's location\n if (attachTo) {\n if (!portalContainer) return null\n return createPortal(wrappedTree, portalContainer)\n }\n\n return wrappedTree\n}\n","import { useState, useCallback, useEffect, useRef } from 'react'\n\n/**\n * Manages portal-based attachment to existing textarea/div elements.\n * Handles initial content extraction, portal container creation/cleanup,\n * and syncing changes back to the original element.\n */\nexport function usePortalAttachment({ attachTo, value, defaultValue, onChange }) {\n const [portalContainer, setPortalContainer] = useState(null)\n const [attachedInitialContent, setAttachedInitialContent] = useState(undefined)\n const attachCleanupRef = useRef(null)\n\n useEffect(() => {\n const target = attachTo?.current\n if (!target) {\n setPortalContainer(null)\n return\n }\n\n const tag = target.tagName.toLowerCase()\n const isFormElement = tag === 'textarea' || tag === 'input'\n\n // Read initial content from the target element\n if (value === undefined && defaultValue === undefined) {\n const initial = isFormElement ? (target.value || '') : (target.innerHTML || '')\n setAttachedInitialContent(initial)\n }\n\n // Create portal container div\n const container = document.createElement('div')\n\n if (isFormElement) {\n // Hide the original form element and insert the editor after it\n target.style.display = 'none'\n target.parentNode.insertBefore(container, target.nextSibling)\n\n attachCleanupRef.current = () => {\n target.style.display = ''\n if (container.parentNode) container.parentNode.removeChild(container)\n }\n } else {\n // For divs/other elements: save original content as text, render editor inside\n const originalContent = target.innerHTML\n target.innerHTML = ''\n target.appendChild(container)\n\n attachCleanupRef.current = () => {\n target.innerHTML = originalContent\n }\n }\n\n setPortalContainer(container)\n\n return () => {\n if (attachCleanupRef.current) {\n attachCleanupRef.current()\n attachCleanupRef.current = null\n }\n setPortalContainer(null)\n }\n }, [attachTo]) // eslint-disable-line react-hooks/exhaustive-deps\n\n // Sync changes back to the attached element\n const handleChange = useCallback((html) => {\n if (attachTo?.current) {\n const tag = attachTo.current.tagName.toLowerCase()\n if (tag === 'textarea' || tag === 'input') {\n attachTo.current.value = html\n }\n }\n onChange?.(html)\n }, [attachTo, onChange])\n\n // Determine the effective value and onChange\n const effectiveValue = value !== undefined ? value : attachedInitialContent\n const effectiveOnChange = attachTo ? handleChange : onChange\n\n return { portalContainer, effectiveValue, effectiveOnChange }\n}\n","import { useEffect, useRef, useCallback } from 'react'\n\nconst MIN_SWIPE_DISTANCE = 50\nconst MAX_VERTICAL_DEVIATION = 30\n\n/**\n * Detects horizontal swipe gestures on list items and blockquotes within the editor.\n * Swipe right → indent, swipe left → outdent.\n * Also supports swipe-down on the floating toolbar to dismiss it.\n *\n * @param {object} engine - The editor engine instance\n * @param {React.RefObject} editorRef - Ref to the editor content element\n * @param {object} [options] - Optional settings\n * @param {Function} [options.onDismissToolbar] - Callback to dismiss floating toolbar\n */\nexport function useSwipeGesture(engine, editorRef, options = {}) {\n const touchRef = useRef(null)\n const swipingElRef = useRef(null)\n\n const handleTouchStart = useCallback((e) => {\n if (!e.touches.length) return\n const touch = e.touches[0]\n touchRef.current = {\n startX: touch.clientX,\n startY: touch.clientY,\n currentX: touch.clientX,\n currentY: touch.clientY,\n }\n\n // Check if swiping on a list item or blockquote\n const target = e.target\n const swipable = target.closest('li, blockquote')\n if (swipable) {\n swipingElRef.current = swipable\n } else {\n swipingElRef.current = null\n }\n }, [])\n\n const handleTouchMove = useCallback((e) => {\n if (!touchRef.current) return\n const touch = e.touches[0]\n touchRef.current.currentX = touch.clientX\n touchRef.current.currentY = touch.clientY\n\n const dx = touch.clientX - touchRef.current.startX\n const dy = Math.abs(touch.clientY - touchRef.current.startY)\n\n // Show visual indicator during horizontal swipe on swipable elements\n if (swipingElRef.current && dy < MAX_VERTICAL_DEVIATION) {\n // Clamp translateX for visual feedback\n const clampedDx = Math.max(-80, Math.min(80, dx))\n swipingElRef.current.style.transform = `translateX(${clampedDx}px)`\n swipingElRef.current.style.transition = 'none'\n }\n }, [])\n\n const handleTouchEnd = useCallback((e) => {\n if (!touchRef.current || !engine) {\n touchRef.current = null\n return\n }\n\n const { startX, startY, currentX, currentY } = touchRef.current\n const dx = currentX - startX\n const dy = currentY - startY\n const absDx = Math.abs(dx)\n const absDy = Math.abs(dy)\n\n // Reset visual transform on the swiped element\n if (swipingElRef.current) {\n swipingElRef.current.style.transform = ''\n swipingElRef.current.style.transition = 'transform 0.2s ease'\n // Clear transition after animation\n setTimeout(() => {\n if (swipingElRef.current) {\n swipingElRef.current.style.transition = ''\n }\n }, 200)\n }\n\n // Check for horizontal swipe on list items / blockquotes\n if (swipingElRef.current && absDx >= MIN_SWIPE_DISTANCE && absDy < MAX_VERTICAL_DEVIATION) {\n if (dx > 0) {\n // Swipe right → indent\n engine.executeCommand('indent')\n } else {\n // Swipe left → outdent\n engine.executeCommand('outdent')\n }\n }\n\n // Check for swipe-down on floating toolbar to dismiss\n if (dy > MIN_SWIPE_DISTANCE && absDx < MAX_VERTICAL_DEVIATION) {\n const target = e.target\n if (target.closest('.rmx-floating-toolbar')) {\n options.onDismissToolbar?.()\n }\n }\n\n touchRef.current = null\n swipingElRef.current = null\n }, [engine, options])\n\n useEffect(() => {\n const el = editorRef?.current\n if (!el) return\n\n el.addEventListener('touchstart', handleTouchStart, { passive: true })\n el.addEventListener('touchmove', handleTouchMove, { passive: true })\n el.addEventListener('touchend', handleTouchEnd, { passive: true })\n\n return () => {\n el.removeEventListener('touchstart', handleTouchStart)\n el.removeEventListener('touchmove', handleTouchMove)\n el.removeEventListener('touchend', handleTouchEnd)\n }\n }, [editorRef, handleTouchStart, handleTouchMove, handleTouchEnd])\n}\n","import { useEffect, useRef, useCallback } from 'react'\n\nconst LONG_PRESS_DURATION = 500\nconst MOVE_CANCEL_THRESHOLD = 10\n\n/**\n * Detects long-press (500ms hold) on touch devices and triggers a context menu\n * at the touch position. Supports haptic feedback and cancels on movement.\n *\n * @param {React.RefObject} elementRef - Ref to the element to listen on\n * @param {Function} onLongPress - Callback receiving { x, y } position\n * @param {object} [options]\n * @param {boolean} [options.enabled=true] - Whether long-press detection is active\n */\nexport function useLongPress(elementRef, onLongPress, options = {}) {\n const { enabled = true } = options\n const timerRef = useRef(null)\n const startPosRef = useRef(null)\n const firedRef = useRef(false)\n\n const clear = useCallback(() => {\n if (timerRef.current) {\n clearTimeout(timerRef.current)\n timerRef.current = null\n }\n startPosRef.current = null\n firedRef.current = false\n }, [])\n\n const handleTouchStart = useCallback((e) => {\n if (!enabled || !e.touches.length) return\n\n const touch = e.touches[0]\n startPosRef.current = { x: touch.clientX, y: touch.clientY }\n firedRef.current = false\n\n timerRef.current = setTimeout(() => {\n // Trigger haptic feedback if available\n if (navigator.vibrate) {\n try { navigator.vibrate(10) } catch (_) { /* ignore */ }\n }\n\n firedRef.current = true\n onLongPress?.({\n x: startPosRef.current.x,\n y: startPosRef.current.y,\n })\n }, LONG_PRESS_DURATION)\n }, [enabled, onLongPress])\n\n const handleTouchMove = useCallback((e) => {\n if (!startPosRef.current || !e.touches.length) return\n\n const touch = e.touches[0]\n const dx = Math.abs(touch.clientX - startPosRef.current.x)\n const dy = Math.abs(touch.clientY - startPosRef.current.y)\n\n // Cancel long-press if user moves finger beyond threshold\n if (dx > MOVE_CANCEL_THRESHOLD || dy > MOVE_CANCEL_THRESHOLD) {\n clear()\n }\n }, [clear])\n\n const handleTouchEnd = useCallback((e) => {\n // If long-press fired, prevent default browser context menu\n if (firedRef.current) {\n e.preventDefault()\n }\n clear()\n }, [clear])\n\n const handleContextMenu = useCallback((e) => {\n // Prevent default browser context menu on touch devices when long-press is active\n if (firedRef.current) {\n e.preventDefault()\n }\n }, [])\n\n useEffect(() => {\n const el = elementRef?.current\n if (!el || !enabled) return\n\n el.addEventListener('touchstart', handleTouchStart, { passive: true })\n el.addEventListener('touchmove', handleTouchMove, { passive: true })\n el.addEventListener('touchend', handleTouchEnd)\n el.addEventListener('contextmenu', handleContextMenu)\n\n return () => {\n el.removeEventListener('touchstart', handleTouchStart)\n el.removeEventListener('touchmove', handleTouchMove)\n el.removeEventListener('touchend', handleTouchEnd)\n el.removeEventListener('contextmenu', handleContextMenu)\n clear()\n }\n }, [elementRef, enabled, handleTouchStart, handleTouchMove, handleTouchEnd, handleContextMenu, clear])\n}\n","import { useEffect, useRef, useCallback, useState } from 'react'\n\n/**\n * Detects virtual keyboard open/close and adjusts the editor to keep the\n * caret visible above the keyboard. Uses the visualViewport API when available,\n * falling back to window.innerHeight change detection.\n *\n * @param {object} engine - The editor engine instance\n * @param {React.RefObject} editorRootRef - Ref to the editor root element\n * @returns {{ keyboardVisible: boolean, keyboardHeight: number }}\n */\nexport function useVirtualKeyboard(engine, editorRootRef) {\n const [keyboardVisible, setKeyboardVisible] = useState(false)\n const [keyboardHeight, setKeyboardHeight] = useState(0)\n const initialHeightRef = useRef(null)\n\n const scrollCaretIntoView = useCallback((kbHeight) => {\n if (!engine?.element) return\n\n const sel = window.getSelection()\n if (!sel || sel.rangeCount === 0) return\n\n const range = sel.getRangeAt(0)\n const rect = range.getBoundingClientRect()\n if (!rect || (rect.top === 0 && rect.left === 0)) return\n\n const viewportHeight = window.visualViewport\n ? window.visualViewport.height\n : window.innerHeight - kbHeight\n\n // If the caret is below the visible area (above the keyboard), scroll it into view\n if (rect.bottom > viewportHeight - 20) {\n const scrollAmount = rect.bottom - viewportHeight + 60 // 60px padding\n engine.element.scrollTop += scrollAmount\n }\n }, [engine])\n\n useEffect(() => {\n if (typeof window === 'undefined') return\n\n // Store initial viewport height to detect keyboard\n initialHeightRef.current = window.innerHeight\n\n // Prefer visualViewport API\n if (window.visualViewport) {\n const vv = window.visualViewport\n\n const handleResize = () => {\n const fullHeight = initialHeightRef.current || window.screen.height\n const currentHeight = vv.height\n const diff = fullHeight - currentHeight\n\n if (diff > 100) {\n // Keyboard is likely open\n setKeyboardVisible(true)\n setKeyboardHeight(diff)\n\n // Adjust editor root if needed\n if (editorRootRef?.current) {\n editorRootRef.current.style.paddingBottom = `${diff}px`\n }\n\n // Scroll caret into view\n scrollCaretIntoView(diff)\n } else {\n setKeyboardVisible(false)\n setKeyboardHeight(0)\n\n if (editorRootRef?.current) {\n editorRootRef.current.style.paddingBottom = ''\n }\n }\n }\n\n vv.addEventListener('resize', handleResize)\n return () => vv.removeEventListener('resize', handleResize)\n }\n\n // Fallback: detect via window resize (innerHeight changes)\n let prevHeight = window.innerHeight\n\n const handleResize = () => {\n const currentHeight = window.innerHeight\n const diff = prevHeight - currentHeight\n\n if (diff > 100) {\n setKeyboardVisible(true)\n setKeyboardHeight(diff)\n\n if (editorRootRef?.current) {\n editorRootRef.current.style.paddingBottom = `${diff}px`\n }\n\n scrollCaretIntoView(diff)\n } else if (currentHeight >= (initialHeightRef.current || prevHeight) - 50) {\n setKeyboardVisible(false)\n setKeyboardHeight(0)\n\n if (editorRootRef?.current) {\n editorRootRef.current.style.paddingBottom = ''\n }\n }\n\n prevHeight = currentHeight\n }\n\n window.addEventListener('resize', handleResize)\n return () => window.removeEventListener('resize', handleResize)\n }, [engine, editorRootRef, scrollCaretIntoView])\n\n return { keyboardVisible, keyboardHeight }\n}\n","import { useState, useEffect, useCallback, useRef } from 'react'\nimport { loadConfig } from '@remyxjs/core'\n\n/**\n * Hook that loads a RemyxEditor configuration from an external URL.\n *\n * Features:\n * - Fetches JSON or YAML config from a URL\n * - Environment-based config merging (pass `env` option)\n * - Runtime config reloading via returned `reload()` function\n * - Automatic reload on URL change\n * - Polling-based auto-reload via `pollInterval` option\n * - Loading/error state tracking\n *\n * @param {string} url - URL to fetch configuration from\n * @param {object} [options]\n * @param {string} [options.env] - Environment name for config merging\n * @param {Record<string, string>} [options.headers] - Custom fetch headers\n * @param {number} [options.pollInterval] - Auto-reload interval in ms (0 = disabled)\n * @param {(config: object) => void} [options.onLoad] - Callback when config is loaded\n * @param {(error: Error) => void} [options.onError] - Callback on load error\n * @returns {{ config: object|null, loading: boolean, error: Error|null, reload: () => Promise<void> }}\n */\nexport function useExternalConfig(url, options = {}) {\n const { env, headers, pollInterval = 0, onLoad, onError } = options\n const [config, setConfig] = useState(null)\n const [loading, setLoading] = useState(!!url)\n const [error, setError] = useState(null)\n const abortRef = useRef(null)\n\n // Item 5: Move callback/object deps to refs to avoid infinite re-fetch\n const onLoadRef = useRef(onLoad)\n onLoadRef.current = onLoad\n const onErrorRef = useRef(onError)\n onErrorRef.current = onError\n const headersRef = useRef(headers)\n headersRef.current = headers\n\n const fetchConfig = useCallback(async () => {\n if (!url) {\n setConfig(null)\n setLoading(false)\n return\n }\n\n // Cancel any in-flight request\n if (abortRef.current) {\n abortRef.current.abort()\n }\n const controller = new AbortController()\n abortRef.current = controller\n\n setLoading(true)\n setError(null)\n\n try {\n const result = await loadConfig(url, {\n env,\n headers: headersRef.current,\n signal: controller.signal,\n })\n\n if (!controller.signal.aborted) {\n setConfig(result)\n setLoading(false)\n onLoadRef.current?.(result)\n }\n } catch (err) {\n if (!controller.signal.aborted) {\n setError(err)\n setLoading(false)\n onErrorRef.current?.(err)\n }\n }\n }, [url, env])\n\n // Initial load and reload on URL/env change\n useEffect(() => {\n fetchConfig()\n return () => {\n if (abortRef.current) {\n abortRef.current.abort()\n }\n }\n }, [fetchConfig])\n\n // Polling-based auto-reload\n useEffect(() => {\n if (!pollInterval || pollInterval <= 0 || !url) return\n const interval = setInterval(fetchConfig, pollInterval)\n return () => clearInterval(interval)\n }, [pollInterval, fetchConfig, url])\n\n return { config, loading, error, reload: fetchConfig }\n}\n","import React, { useState, useCallback, useRef } from 'react'\n\n/**\n * Format a timestamp as a relative time string.\n * @param {number} ts — timestamp in milliseconds\n * @returns {string}\n */\nfunction timeAgo(ts) {\n const seconds = Math.floor((Date.now() - ts) / 1000)\n if (seconds < 60) return 'just now'\n const minutes = Math.floor(seconds / 60)\n if (minutes < 60) return `${minutes}m ago`\n const hours = Math.floor(minutes / 60)\n if (hours < 24) return `${hours}h ago`\n const days = Math.floor(hours / 24)\n return `${days}d ago`\n}\n\n/**\n * Render body text with @mentions highlighted.\n */\nfunction CommentBody({ text }) {\n if (!text) return null\n const parts = text.split(/(@[\\w.-]+)/g)\n return (\n <span>\n {parts.map((part, i) =>\n part.startsWith('@') ? (\n <span key={i} className=\"rmx-comment-mention\">{part}</span>\n ) : (\n <span key={i}>{part}</span>\n )\n )}\n </span>\n )\n}\n\n/**\n * CommentsPanel — sidebar component displaying all comment threads.\n *\n * @param {object} props\n * @param {import('../../hooks/useComments.js').CommentThread[]} props.threads\n * @param {object|null} props.activeThread\n * @param {Function} props.onNavigate — called with threadId when a thread is clicked\n * @param {Function} props.onResolve — called with (threadId, resolved)\n * @param {Function} props.onDelete — called with threadId\n * @param {Function} props.onReply — called with (threadId, { author, body })\n * @param {string} [props.className] — additional CSS class\n * @param {'all'|'open'|'resolved'} [props.filter='all'] — which threads to show\n */\nfunction CommentsPanelInner({\n threads = [],\n activeThread,\n onNavigate,\n onResolve,\n onDelete,\n onReply,\n className = '',\n filter = 'all',\n}) {\n const [replyingTo, setReplyingTo] = useState(null)\n const [replyText, setReplyText] = useState('')\n const replyInputRef = useRef(null)\n\n const filteredThreads = threads.filter(t => {\n if (filter === 'open') return !t.resolved\n if (filter === 'resolved') return t.resolved\n return true\n })\n\n const unresolvedCount = threads.filter(t => !t.resolved).length\n\n const handleReplySubmit = useCallback((threadId) => {\n if (!replyText.trim()) return\n onReply?.(threadId, { author: 'You', body: replyText.trim() })\n setReplyText('')\n setReplyingTo(null)\n }, [replyText, onReply])\n\n const startReply = useCallback((threadId) => {\n setReplyingTo(threadId)\n setReplyText('')\n requestAnimationFrame(() => replyInputRef.current?.focus())\n }, [])\n\n return (\n <div className={`rmx-comments-panel ${className}`.trim()} role=\"complementary\" aria-label=\"Comments\">\n <div className=\"rmx-comments-panel-header\">\n <span>Comments</span>\n <span className=\"rmx-comments-panel-count\">\n {unresolvedCount} open · {threads.length - unresolvedCount} resolved\n </span>\n </div>\n\n {filteredThreads.length === 0 ? (\n <div style={{ color: 'var(--rmx-text-secondary)', fontSize: 13, padding: '8px 0' }}>\n {filter === 'resolved'\n ? 'No resolved comments'\n : filter === 'open'\n ? 'No open comments'\n : 'No comments yet. Select text and click \"Add Comment\" to start.'}\n </div>\n ) : (\n filteredThreads.map((thread) => (\n <div\n key={thread.id}\n className={`rmx-comment-thread${thread.resolved ? ' rmx-resolved' : ''}${\n activeThread?.id === thread.id ? ' rmx-active' : ''\n }`}\n onClick={() => onNavigate?.(thread.id)}\n >\n <div className=\"rmx-comment-thread-header\">\n <span className=\"rmx-comment-author\">{thread.author}</span>\n <span className=\"rmx-comment-time\">{timeAgo(thread.createdAt)}</span>\n </div>\n\n <div className=\"rmx-comment-body\">\n <CommentBody text={thread.body} />\n </div>\n\n <span className={`rmx-comment-status ${thread.resolved ? 'rmx-closed' : 'rmx-open'}`}>\n {thread.resolved ? 'Resolved' : 'Open'}\n </span>\n\n {/* Replies */}\n {thread.replies.map((reply) => (\n <div key={reply.id} className=\"rmx-comment-reply\">\n <div className=\"rmx-comment-thread-header\">\n <span className=\"rmx-comment-author\">{reply.author}</span>\n <span className=\"rmx-comment-time\">{timeAgo(reply.createdAt)}</span>\n </div>\n <div className=\"rmx-comment-body\">\n <CommentBody text={reply.body} />\n </div>\n </div>\n ))}\n\n {/* Reply input */}\n {replyingTo === thread.id && (\n <div className=\"rmx-comment-reply\" style={{ marginTop: 6 }}>\n <input\n ref={replyInputRef}\n type=\"text\"\n placeholder=\"Reply...\"\n value={replyText}\n onChange={(e) => setReplyText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleReplySubmit(thread.id)\n if (e.key === 'Escape') setReplyingTo(null)\n }}\n onClick={(e) => e.stopPropagation()}\n style={{\n width: '100%',\n padding: '4px 8px',\n fontSize: 12,\n border: '1px solid var(--rmx-border, #e2e8f0)',\n borderRadius: 4,\n outline: 'none',\n }}\n />\n </div>\n )}\n\n {/* Actions */}\n <div className=\"rmx-comment-actions\" onClick={(e) => e.stopPropagation()}>\n <button\n className=\"rmx-comment-action-btn\"\n onClick={() => startReply(thread.id)}\n >\n Reply\n </button>\n <button\n className=\"rmx-comment-action-btn rmx-resolve-btn\"\n onClick={() => onResolve?.(thread.id, !thread.resolved)}\n >\n {thread.resolved ? 'Reopen' : 'Resolve'}\n </button>\n <button\n className=\"rmx-comment-action-btn rmx-delete-btn\"\n onClick={() => onDelete?.(thread.id)}\n >\n Delete\n </button>\n </div>\n </div>\n ))\n )}\n </div>\n )\n}\n\nexport const CommentsPanel = React.memo(CommentsPanelInner)\n","import React from 'react'\nimport PropTypes from 'prop-types'\n\n/**\n * CollaborationBar — Presence indicator showing connected collaborators.\n *\n * Displays a connection status dot, avatar circles for each remote user,\n * and the local user's avatar. Designed to sit above or beside the editor.\n */\nfunction CollaborationBarInner({\n collaborators = [],\n connectionStatus = 'disconnected',\n localUser,\n className = '',\n showCount = true,\n}) {\n return (\n <div className={`rmx-collab-bar ${className}`} role=\"status\" aria-label=\"Collaborators\">\n <div\n className=\"rmx-collab-status-dot\"\n data-status={connectionStatus}\n title={connectionStatus}\n />\n\n {localUser && (\n <div\n className=\"rmx-collab-avatar rmx-collab-avatar-local\"\n style={{ backgroundColor: localUser.userColor }}\n title={`${localUser.userName} (you)`}\n >\n {localUser.userName.charAt(0).toUpperCase()}\n </div>\n )}\n\n {collaborators.map((c) => (\n <div\n key={c.userId}\n className=\"rmx-collab-avatar\"\n style={{\n backgroundColor: c.userColor,\n opacity: c.status === 'idle' ? 0.6 : 1,\n }}\n title={`${c.userName} (${c.status})`}\n >\n {c.userName.charAt(0).toUpperCase()}\n </div>\n ))}\n\n {showCount && (\n <span style={{ fontSize: 11, color: '#64748b', marginLeft: 4 }}>\n {collaborators.length + (localUser ? 1 : 0)} user{collaborators.length > 0 ? 's' : ''}\n </span>\n )}\n </div>\n )\n}\n\nCollaborationBarInner.propTypes = {\n collaborators: PropTypes.arrayOf(\n PropTypes.shape({\n userId: PropTypes.string.isRequired,\n userName: PropTypes.string.isRequired,\n userColor: PropTypes.string.isRequired,\n status: PropTypes.string,\n })\n ),\n connectionStatus: PropTypes.string,\n localUser: PropTypes.shape({\n userId: PropTypes.string,\n userName: PropTypes.string.isRequired,\n userColor: PropTypes.string.isRequired,\n }),\n className: PropTypes.string,\n showCount: PropTypes.bool,\n}\n\nexport const CollaborationBar = React.memo(CollaborationBarInner)\n","import React, { useMemo } from 'react'\nimport RemyxEditor from './RemyxEditor.jsx'\nimport { useExternalConfig } from '../hooks/useExternalConfig.js'\nimport { resolvePlugins } from '@remyxjs/core'\n\n/**\n * Fully declarative editor setup from an external JSON/YAML config URL.\n *\n * Loads the config asynchronously, shows a loading state until ready,\n * and renders <RemyxEditor /> with the loaded configuration merged with\n * any additional props passed directly.\n *\n * Supports runtime config reloading: when the config URL changes or\n * `pollInterval` is set, the editor re-renders with the updated config.\n *\n * Usage:\n * <RemyxEditorFromConfig\n * url=\"/editor-config.json\"\n * env=\"production\"\n * value={content}\n * onChange={setContent}\n * />\n *\n * @param {object} props\n * @param {string} props.url - URL to a JSON/YAML config file\n * @param {string} [props.env] - Environment name for config merging\n * @param {Record<string, string>} [props.fetchHeaders] - Custom headers for config fetch\n * @param {number} [props.pollInterval] - Auto-reload interval in ms (0 = disabled)\n * @param {(config: object) => void} [props.onConfigLoad] - Callback when config is loaded\n * @param {(error: Error) => void} [props.onConfigError] - Callback on load error\n * @param {React.ReactNode} [props.loadingFallback] - Custom loading UI (default: null)\n * @param {React.ReactNode} [props.errorFallback] - Custom error UI (default: error message)\n * @param {...*} props.rest - All other props are forwarded to <RemyxEditor />\n */\nexport function RemyxEditorFromConfig({\n url,\n env,\n fetchHeaders,\n pollInterval,\n onConfigLoad,\n onConfigError,\n loadingFallback = null,\n errorFallback: errorFallbackProp,\n ...editorProps\n}) {\n const { config, loading, error, reload } = useExternalConfig(url, {\n env,\n headers: fetchHeaders,\n pollInterval,\n onLoad: onConfigLoad,\n onError: onConfigError,\n })\n\n if (loading && !config) {\n return loadingFallback\n }\n\n if (error && !config) {\n if (errorFallbackProp !== undefined) {\n return typeof errorFallbackProp === 'function'\n ? errorFallbackProp({ error, reload })\n : errorFallbackProp\n }\n return (\n <div className=\"rmx-config-error\" role=\"alert\">\n <p>Failed to load editor configuration.</p>\n <button onClick={reload} type=\"button\">Retry</button>\n </div>\n )\n }\n\n // Merge: loaded config as defaults, direct props override\n const mergedProps = config\n ? Object.keys({ ...config, ...editorProps }).reduce((acc, key) => {\n acc[key] = editorProps[key] !== undefined ? editorProps[key] : config[key]\n return acc\n }, {})\n : editorProps\n\n // Resolve plugin names from config (strings/objects → plugin instances)\n // Only resolve if plugins came from config (not from direct props)\n const resolvedPlugins = useMemo(() => {\n if (editorProps.plugins !== undefined) return editorProps.plugins\n if (mergedProps.plugins && Array.isArray(mergedProps.plugins)) {\n const hasStringEntries = mergedProps.plugins.some(\n p => typeof p === 'string' || (typeof p === 'object' && p !== null && typeof p.name === 'string' && typeof p.init !== 'function')\n )\n if (hasStringEntries) {\n return resolvePlugins(mergedProps.plugins)\n }\n }\n return mergedProps.plugins\n }, [mergedProps.plugins, editorProps.plugins])\n\n return <RemyxEditor {...mergedProps} plugins={resolvedPlugins} />\n}\n","import { useState, useEffect, useRef, useCallback } from 'react'\n\n/**\n * React hook for collaboration state.\n * Follows the useComments pattern — subscribes to collaboration events\n * on the engine's eventBus and provides reactive state.\n *\n * @param {Object|null} engine - EditorEngine instance (from onReady or useEditorEngine)\n * @returns {{ collaborators, connectionStatus, startCollaboration, stopCollaboration, localUser }}\n */\nexport function useCollaboration(engine) {\n const [collaborators, setCollaborators] = useState([])\n const [connectionStatus, setConnectionStatus] = useState('disconnected')\n const unsubsRef = useRef([])\n\n useEffect(() => {\n if (!engine?.eventBus) return\n\n const refresh = () => {\n if (engine._collaboration) {\n setCollaborators(engine._collaboration.getCollaborators())\n setConnectionStatus(engine._collaboration.getConnectionStatus())\n }\n }\n\n refresh()\n\n const events = [\n 'collab:userJoin',\n 'collab:userLeave',\n 'collab:connected',\n 'collab:disconnected',\n 'collab:sync',\n ]\n const unsubs = events.map(evt => engine.eventBus.on(evt, refresh))\n unsubsRef.current = unsubs\n\n return () => {\n for (const u of unsubsRef.current) u?.()\n unsubsRef.current = []\n }\n }, [engine])\n\n const startCollaboration = useCallback(() => {\n engine?._collaboration?.startCollaboration()\n }, [engine])\n\n const stopCollaboration = useCallback(() => {\n engine?._collaboration?.stopCollaboration()\n }, [engine])\n\n const localUser = engine?._collaboration\n ? {\n userId: engine._collaboration.userId,\n userName: engine._collaboration.userName,\n userColor: engine._collaboration.userColor,\n }\n : null\n\n return {\n collaborators,\n connectionStatus,\n startCollaboration,\n stopCollaboration,\n localUser,\n }\n}\n","import { useState, useEffect, useCallback, useRef } from 'react'\n\n/**\n * React hook for interacting with the CommentsPlugin.\n *\n * Provides reactive state for comment threads and convenience methods\n * for creating, resolving, replying to, and deleting comments.\n *\n * @param {object|null} engine — the EditorEngine instance (from useEditorEngine or onReady)\n * @returns {object} comments API\n */\nexport function useComments(engine) {\n const [threads, setThreads] = useState([])\n const [activeThread, setActiveThread] = useState(null)\n const unsubsRef = useRef([])\n\n // Refresh thread list from the plugin\n const refresh = useCallback(() => {\n if (!engine?._comments) return\n setThreads(engine._comments.getAllThreads())\n }, [engine])\n\n useEffect(() => {\n if (!engine?.eventBus) return\n\n // Initial load\n refresh()\n\n // Subscribe to comment lifecycle events\n const events = [\n 'comment:created',\n 'comment:deleted',\n 'comment:resolved',\n 'comment:replied',\n 'comment:updated',\n 'comment:imported',\n ]\n\n const unsubs = events.map(evt =>\n engine.eventBus.on(evt, refresh)\n )\n\n // Track which thread is clicked/active\n const unsubClick = engine.eventBus.on('comment:clicked', ({ thread }) => {\n setActiveThread(thread)\n })\n unsubs.push(unsubClick)\n\n unsubsRef.current = unsubs\n\n return () => {\n for (const unsub of unsubsRef.current) unsub?.()\n unsubsRef.current = []\n }\n }, [engine, refresh])\n\n const addComment = useCallback((params) => {\n return engine?._comments?.addComment(params) ?? null\n }, [engine])\n\n const deleteComment = useCallback((threadId) => {\n engine?._comments?.deleteComment(threadId)\n }, [engine])\n\n const resolveComment = useCallback((threadId, resolved = true) => {\n engine?._comments?.resolveComment(threadId, resolved)\n }, [engine])\n\n const replyToComment = useCallback((threadId, params) => {\n return engine?._comments?.replyToComment(threadId, params) ?? null\n }, [engine])\n\n const editComment = useCallback((threadId, newBody) => {\n engine?._comments?.editComment(threadId, newBody)\n }, [engine])\n\n const navigateToComment = useCallback((threadId) => {\n engine?._comments?.navigateToComment(threadId)\n const thread = engine?._comments?.getThread(threadId)\n if (thread) setActiveThread(thread)\n }, [engine])\n\n const importThreads = useCallback((data) => {\n engine?._comments?.importThreads(data)\n }, [engine])\n\n const exportThreads = useCallback(() => {\n return engine?._comments?.exportThreads() ?? []\n }, [engine])\n\n const getMentionUsers = useCallback(() => {\n return engine?._comments?.getMentionUsers() ?? []\n }, [engine])\n\n return {\n /** All comment threads (newest first) */\n threads,\n /** The currently active/clicked thread (or null) */\n activeThread,\n /** Set the active thread manually */\n setActiveThread,\n /** Create a comment on the current selection */\n addComment,\n /** Delete a comment thread by ID */\n deleteComment,\n /** Resolve or unresolve a thread */\n resolveComment,\n /** Add a reply to a thread */\n replyToComment,\n /** Edit a thread's body text */\n editComment,\n /** Scroll to and select the annotated text */\n navigateToComment,\n /** Import threads from serialized data */\n importThreads,\n /** Export all threads as JSON-serializable array */\n exportThreads,\n /** Get the list of available @mention users */\n getMentionUsers,\n /** Force refresh the thread list */\n refresh,\n }\n}\n","import { useEffect, useRef, useState, useCallback } from 'react'\nimport { createEditorInstance, htmlToMarkdown, markdownToHtml } from './createEditorEngine.js'\n\n/**\n * useRemyxEditor - A hook to attach a full WYSIWYG editor to any existing\n * DOM element (div, textarea, or any block element).\n *\n * Item 6: Shared init logic extracted to createEditorEngine.js.\n * Item 7: registerBlockConvertCommands included in shared factory.\n *\n * For textareas: hides the textarea and creates a contenteditable div that\n * syncs back to the textarea's value. On form submit the textarea value is\n * up to date.\n *\n * For divs / other elements: uses the element directly as the contenteditable\n * surface (or creates a child contenteditable if the element contains other\n * content to preserve).\n *\n * Usage:\n * const targetRef = useRef(null)\n * const { engine, containerRef } = useRemyxEditor(targetRef, { onChange, placeholder, ... })\n *\n * return <textarea ref={targetRef} />\n * // or <div ref={targetRef} />\n *\n * The hook returns:\n * - engine: the EditorEngine instance (null until initialized)\n * - containerRef: ref to the wrapper div that contains toolbar + edit area\n * - ready: boolean\n */\nexport function useRemyxEditor(targetRef, options = {}) {\n const engineRef = useRef(null)\n const containerRef = useRef(null)\n const editableRef = useRef(null)\n const [ready, setReady] = useState(false)\n const lastValueRef = useRef('')\n const cleanupRef = useRef(null)\n const formRef = useRef(null)\n const syncToTextareaRef = useRef(null)\n\n const initEditor = useCallback(() => {\n const target = targetRef.current\n if (!target || engineRef.current) return\n\n const tagName = target.tagName.toLowerCase()\n const isTextarea = tagName === 'textarea'\n const isInput = tagName === 'input'\n\n // Determine initial content\n let initialContent = ''\n if (isTextarea || isInput) {\n initialContent = target.value || ''\n } else {\n initialContent = target.innerHTML || ''\n }\n // Use provided value/defaultValue over element content\n if (options.value !== undefined) {\n initialContent = options.value\n } else if (options.defaultValue !== undefined) {\n initialContent = options.defaultValue\n }\n\n // Create the wrapper container\n const container = document.createElement('div')\n const safeTheme = /^[a-zA-Z0-9_-]+$/.test(options.theme) ? options.theme : 'light'\n container.className = `rmx-editor rmx-theme-${safeTheme} ${options.className || ''}`\n if (options.style) {\n const ALLOWED_STYLE_KEYS = new Set([\n 'width', 'height', 'minHeight', 'maxHeight', 'minWidth', 'maxWidth',\n 'margin', 'padding', 'border', 'borderRadius', 'background', 'backgroundColor',\n 'color', 'fontSize', 'fontFamily', 'overflow', 'overflowY', 'overflowX',\n ])\n for (const [key, val] of Object.entries(options.style)) {\n if (ALLOWED_STYLE_KEYS.has(key)) {\n container.style[key] = val\n }\n }\n }\n containerRef.current = container\n\n // Create the editable div\n const editable = document.createElement('div')\n editable.className = 'rmx-content'\n const DEFAULT_HEIGHT = 300\n const height = options.height || DEFAULT_HEIGHT\n editable.style.minHeight = typeof height === 'number' ? `${height}px` : height\n editable.style.overflowY = 'auto'\n\n // Create the edit area wrapper\n const editArea = document.createElement('div')\n editArea.className = 'rmx-edit-area'\n editArea.appendChild(editable)\n\n // Build container structure (toolbar placeholder + edit area + status bar)\n container.appendChild(editArea)\n\n editableRef.current = editable\n\n if (isTextarea || isInput) {\n // Hide the original textarea and insert the editor after it\n target.style.display = 'none'\n target.parentNode.insertBefore(container, target.nextSibling)\n\n // Sync back to textarea on change\n const syncToTextarea = () => {\n if (engineRef.current) {\n target.value = engineRef.current.getHTML()\n }\n }\n cleanupRef.current = () => {\n syncToTextarea()\n target.style.display = ''\n if (container.parentNode) {\n container.parentNode.removeChild(container)\n }\n }\n\n // Wire up form submit to sync\n const form = target.closest('form')\n if (form) {\n formRef.current = form\n syncToTextareaRef.current = syncToTextarea\n form.addEventListener('submit', syncToTextarea)\n const prevCleanup = cleanupRef.current\n cleanupRef.current = () => {\n formRef.current?.removeEventListener('submit', syncToTextareaRef.current)\n formRef.current = null\n syncToTextareaRef.current = null\n prevCleanup()\n }\n }\n } else {\n // For div / other elements: replace the element's content with the editor\n const originalContent = target.textContent\n target.innerHTML = ''\n target.appendChild(container)\n\n cleanupRef.current = () => {\n target.textContent = originalContent\n }\n }\n\n // Use shared factory (Items 6, 7)\n const engineOpts = {\n ...options,\n value: initialContent,\n }\n const { engine } = createEditorInstance(editable, engineOpts)\n\n engine.init()\n engineRef.current = engine\n const isMarkdown = options.outputFormat === 'markdown'\n lastValueRef.current = isMarkdown ? htmlToMarkdown(initialContent) : initialContent\n setReady(true)\n options.onReady?.(engine)\n engine.eventBus.emit('content:change')\n\n // Listen for content changes\n engine.on('content:change', () => {\n const html = engine.getHTML()\n const output = isMarkdown ? htmlToMarkdown(html) : html\n if (output !== lastValueRef.current) {\n lastValueRef.current = output\n options.onChange?.(output)\n // Keep textarea in sync\n if ((isTextarea || isInput) && target) {\n target.value = output\n }\n }\n })\n\n engine.on('focus', () => options.onFocus?.())\n engine.on('blur', () => options.onBlur?.())\n\n return engine\n }, []) // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n const engine = initEditor()\n return () => {\n if (engine) {\n engine.destroy()\n engineRef.current = null\n setReady(false)\n }\n if (cleanupRef.current) {\n cleanupRef.current()\n cleanupRef.current = null\n }\n }\n }, [initEditor])\n\n // Sync external value changes (convert markdown -> HTML if needed)\n useEffect(() => {\n if (!engineRef.current || !ready) return\n if (options.value === undefined) return\n if (options.value === lastValueRef.current) return\n lastValueRef.current = options.value\n const isMarkdown = options.outputFormat === 'markdown'\n const htmlValue = isMarkdown ? markdownToHtml(options.value) : options.value\n engineRef.current.setHTML(htmlValue)\n }, [options.value, options.outputFormat, ready])\n\n return {\n engine: engineRef.current,\n containerRef,\n editableRef,\n ready,\n }\n}\n","import { useState, useEffect, useCallback, useRef } from 'react'\n\n/**\n * React hook for interacting with the SpellcheckPlugin.\n *\n * Provides reactive state for spellcheck errors, statistics, and convenience\n * methods for toggling, correcting, and managing the dictionary.\n *\n * @param {object|null} engine — the EditorEngine instance (from useEditorEngine or onReady)\n * @returns {object} spellcheck API\n */\nexport function useSpellcheck(engine) {\n const [errors, setErrors] = useState([])\n const [stats, setStats] = useState({ total: 0, grammar: 0, style: 0, byRule: {} })\n const [enabled, setEnabled] = useState(true)\n const [stylePreset, setStylePresetState] = useState('formal')\n const [language, setLanguageState] = useState('en-US')\n const unsubsRef = useRef([])\n\n // Refresh state from the plugin\n const refresh = useCallback(() => {\n if (!engine?._spellcheck) return\n const s = engine._spellcheck.getStats()\n setErrors(engine._spellcheck.getErrors())\n setStats(s)\n setEnabled(engine._spellcheck.isEnabled())\n setStylePresetState(engine._spellcheck.getWritingStyle())\n setLanguageState(engine._spellcheck.getLanguage())\n }, [engine])\n\n useEffect(() => {\n if (!engine?.eventBus) return\n\n // Initial load\n refresh()\n\n // Subscribe to spellcheck events\n const events = [\n 'spellcheck:update',\n 'spellcheck:toggle',\n 'spellcheck:style:change',\n 'spellcheck:language:change',\n 'spellcheck:dictionary:add',\n 'spellcheck:ignored:add',\n 'spellcheck:correction',\n ]\n\n const unsubs = events.map(evt =>\n engine.eventBus.on(evt, refresh)\n )\n\n unsubsRef.current = unsubs\n\n return () => {\n for (const unsub of unsubsRef.current) unsub?.()\n unsubsRef.current = []\n }\n }, [engine, refresh])\n\n const toggleSpellcheck = useCallback(() => {\n return engine?.executeCommand?.('toggleSpellcheck') ?? false\n }, [engine])\n\n const checkGrammar = useCallback(async () => {\n return engine?._spellcheck?.runCheck() ?? []\n }, [engine])\n\n const addToDictionary = useCallback((word) => {\n engine?._spellcheck?.addToDictionary(word)\n }, [engine])\n\n const removeFromDictionary = useCallback((word) => {\n engine?._spellcheck?.removeFromDictionary(word)\n }, [engine])\n\n const ignoreWord = useCallback((word) => {\n engine?._spellcheck?.ignoreWord(word)\n }, [engine])\n\n const setWritingStyle = useCallback((preset) => {\n engine?._spellcheck?.setWritingStyle(preset)\n }, [engine])\n\n const setLanguage = useCallback((lang) => {\n engine?._spellcheck?.setLanguage(lang)\n }, [engine])\n\n const getDictionary = useCallback(() => {\n return engine?._spellcheck?.getDictionary() ?? []\n }, [engine])\n\n const getIgnoredWords = useCallback(() => {\n return engine?._spellcheck?.getIgnoredWords() ?? []\n }, [engine])\n\n return {\n /** All current spellcheck/grammar errors */\n errors,\n /** Summary statistics */\n stats,\n /** Whether spellcheck is enabled */\n enabled,\n /** Current writing style preset */\n stylePreset,\n /** Current language */\n language,\n /** Toggle spellcheck on/off */\n toggleSpellcheck,\n /** Run a grammar check now */\n checkGrammar,\n /** Add a word to the custom dictionary */\n addToDictionary,\n /** Remove a word from the custom dictionary */\n removeFromDictionary,\n /** Ignore a word for this session */\n ignoreWord,\n /** Set the writing style preset */\n setWritingStyle,\n /** Set the language */\n setLanguage,\n /** Get all dictionary words */\n getDictionary,\n /** Get all ignored words */\n getIgnoredWords,\n /** Force refresh state */\n refresh,\n }\n}\n"],"names":["COMMAND_REGISTRARS","registerFormattingCommands","registerHeadingCommands","registerAlignmentCommands","registerListCommands","registerLinkCommands","registerImageCommands","registerTableCommands","registerBlockCommands","registerFontCommands","registerMediaCommands","registerFindReplaceCommands","registerSourceModeCommands","registerFullscreenCommands","registerDistractionFreeCommands","registerSplitViewCommands","registerColorPresetCommands","registerMarkdownToggleCommands","registerAttachmentCommands","registerImportDocumentCommands","registerBlockConvertCommands","createEditorInstance","element","opts","engine","EditorEngine","register","commands","execute","eng","history","undo","isEnabled","canUndo","shortcut","meta","icon","tooltip","redo","canRedo","userPluginNames","Set","plugins","map","p","name","filter","Boolean","has","WordCountPlugin","placeholder","PlaceholderPlugin","AutolinkPlugin","forEach","isMarkdown","outputFormat","initialContent","value","defaultValue","markdownToHtml","setHTML","useEditorEngine","editAreaRef","options","readyTrigger","engineRef","useRef","ready","setReady","useState","lastValueRef","rAFRef","optionsRef","current","initEngine","useCallback","init","onReady","eventBus","emit","on","cancelAnimationFrame","requestAnimationFrame","output","isMarkdownMode","textContent","html","getHTML","htmlToMarkdown","onChange","onFocus","onBlur","useEffect","destroy","htmlValue","DEFAULT_FORMAT","bold","italic","underline","strikethrough","subscript","superscript","heading","alignment","orderedList","unorderedList","blockquote","codeBlock","link","fontFamily","fontSize","foreColor","backColor","DEFAULT_UI","hasSelection","selectionRect","focusedImage","focusedTable","focusedCodeBlock","FORMAT_KEYS","Object","keys","initialState","open","data","image","table","embed","findReplace","source","attachment","importDocument","export","modalReducer","state","action","type","useContextMenu","editorRef","contextMenu","setContextMenu","visible","x","y","items","cutHandler","async","sel","window","getSelection","isCollapsed","navigator","clipboard","writeText","toString","getRangeAt","deleteContents","copyHandler","pasteHandler","snapshot","read","item","types","includes","blob","getType","text","cleanPastedHTML","sanitizer","sanitize","selection","insertHTML","insertPlainText","readText","handleContextMenuPaste","selectAllHandler","range","document","createRange","selectNodeContents","removeAllRanges","addRange","handleContextMenu","e","preventDefault","target","push","label","command","separator","linkEl","closest","executeCommand","href","test","imgEl","tagName","tableEl","format","clientX","clientY","hideContextMenu","prev","visibleRef","el","addEventListener","handleScroll","removeEventListener","RemyxConfigContext","createContext","useRemyxConfig","configName","config","useContext","useMemo","editors","defaults","DEFAULT_EDITOR_HEIGHT","useAutosave","saveStatusRef","saveStatus","setSaveStatus","lastSaved","setLastSaved","recoveryData","setRecoveryData","managerRef","onRecoverRef","onRecover","enabled","configKey","key","configInterval","interval","configDebounce","debounce","configProvider","provider","manager","AutosaveManager","updateStatus","newStatus","unsubs","timestamp","currentContent","checkRecovery","then","catch","err","u","recoverContent","recoveredContent","clearRecovery","dismissRecovery","useEditorRect","editorRootRef","editorRect","setEditorRect","rafRef","updateRect","rect","getBoundingClientRect","resizeObserver","ResizeObserver","observe","scrollParent","parent","parentElement","body","style","getComputedStyle","overflow","overflowY","findScrollableParent","passive","disconnect","useDragDrop","isExternalDrag","setIsExternalDrag","dragFileTypes","setDragFileTypes","isExternal","unsub","getTouchDistance","t1","t2","dx","dy","Math","sqrt","SelectionContext","useSelectionContext","process","env","NODE_ENV","reactIsModule","exports","b","Symbol","for","c","d","f","g","h","k","l","m","n","q","r","t","v","w","z","a","$$typeof","A","reactIs_production_min","AsyncMode","ConcurrentMode","ContextConsumer","Element","ForwardRef","Fragment","Lazy","Portal","Profiler","StrictMode","Suspense","isAsyncMode","isConcurrentMode","isContextConsumer","isContextProvider","isElement","isForwardRef","isFragment","isLazy","isMemo","isProfiler","isStrictMode","isSuspense","isValidElementType","typeOf","require$$0","hasSymbol","REACT_ELEMENT_TYPE","REACT_PORTAL_TYPE","REACT_FRAGMENT_TYPE","REACT_STRICT_MODE_TYPE","REACT_PROFILER_TYPE","REACT_PROVIDER_TYPE","REACT_CONTEXT_TYPE","REACT_ASYNC_MODE_TYPE","REACT_CONCURRENT_MODE_TYPE","REACT_FORWARD_REF_TYPE","REACT_SUSPENSE_TYPE","REACT_SUSPENSE_LIST_TYPE","REACT_MEMO_TYPE","REACT_LAZY_TYPE","REACT_BLOCK_TYPE","REACT_FUNDAMENTAL_TYPE","REACT_RESPONDER_TYPE","REACT_SCOPE_TYPE","object","$$typeofType","ContextProvider","Memo","hasWarnedAboutDeprecatedIsAsyncMode","reactIs_development","isPortal","getOwnPropertySymbols","hasOwnProperty","prototype","propIsEnumerable","propertyIsEnumerable","objectAssign","assign","test1","String","getOwnPropertyNames","test2","i","fromCharCode","join","test3","split","letter","shouldUseNative","from","symbols","to","val","TypeError","toObject","s","arguments","length","call","ReactPropTypesSecret_1","Function","bind","printWarning","ReactPropTypesSecret","loggedTypeFailures","require$$1","message","Error","checkPropTypes","typeSpecs","values","location","componentName","getStack","typeSpecName","error","ex","stack","resetWarningCache","checkPropTypes_1","ReactIs","require$$2","require$$3","require$$4","emptyFunctionThatReturnsNull","factoryWithTypeCheckers","isValidElement","throwOnDirectAccess","ITERATOR_SYMBOL","iterator","ANONYMOUS","ReactPropTypes","array","createPrimitiveTypeChecker","bigint","bool","func","number","string","symbol","any","createChainableTypeChecker","arrayOf","typeChecker","props","propName","propFullName","PropTypeError","propValue","Array","isArray","getPropType","elementType","instanceOf","expectedClass","expectedClassName","constructor","node","isNode","objectOf","propType","oneOf","expectedValues","is","valuesString","JSON","stringify","getPreciseType","oneOfType","arrayOfTypeCheckers","checker","getPostfixForTypeWarning","expectedTypes","checkerResult","expectedType","shape","shapeTypes","invalidValidatorError","exact","allKeys","this","validate","manualPropTypeCallCache","manualPropTypeWarningCount","checkType","isRequired","secret","console","cacheKey","chainedCheckType","every","iteratorFn","maybeIterable","getIteratorFn","step","entries","next","done","entry","RegExp","isSymbol","Date","PropTypes","emptyFunction","emptyFunctionWithReset","factoryWithThrowingShims","shim","getShim","propTypesModule","viewBox","size","className","jsx","width","height","fill","stroke","strokeWidth","strokeLinecap","strokeLinejoin","children","filled","BoldIcon","ItalicIcon","jsxs","x1","y1","x2","y2","UnderlineIcon","StrikethroughIcon","SubscriptIcon","fontWeight","SuperscriptIcon","HeadingIcon","AlignLeftIcon","AlignCenterIcon","AlignRightIcon","AlignJustifyIcon","OrderedListIcon","UnorderedListIcon","cx","cy","TaskListIcon","rx","points","LinkIcon","UnlinkIcon","ImageIcon","ry","TableIcon","BlockquoteIcon","CodeBlockIcon","HorizontalRuleIcon","UndoIcon","RedoIcon","FontFamilyIcon","FontSizeIcon","EmbedMediaIcon","FindReplaceIcon","SourceModeIcon","FullscreenIcon","ExitFullscreenIcon","IndentIcon","OutdentIcon","ExportIcon","CommandPaletteIcon","ToggleMarkdownIcon","ImportDocumentIcon","AttachmentIcon","RemoveFormatIcon","CloseIcon","ChevronDownIcon","ChevronRightIcon","CheckIcon","TrashIcon","CalloutIcon","MathIcon","fontStyle","TocIcon","BookmarkIcon","MergeTagIcon","SpellcheckIcon","AnalyticsIcon","CommentIcon","CollaborationIcon","DistractionFreeIcon","SplitViewIcon","ICON_MAP","headings","alignLeft","alignCenter","alignRight","alignJustify","taskList","insertLink","unlink","insertImage","insertTable","horizontalRule","color","opacity","embedMedia","sourceMode","fullscreen","exitFullscreen","indent","outdent","removeFormat","close","chevronDown","check","trash","insertAttachment","toggleMarkdown","commandPalette","insertCallout","callout","insertMath","math","insertToc","toc","insertBookmark","bookmark","insertMergeTag","mergeTag","analytics","getAnalytics","toggleAnalytics","spellcheck","toggleSpellcheck","checkGrammar","addComment","comment","collaboration","startCollaboration","stopCollaboration","distractionFree","splitView","toggleSplitView","Tooltip","React","memo","setVisible","timerRef","show","setTimeout","hide","clearTimeout","onMouseEnter","onMouseLeave","role","ToolbarButton","active","disabled","onClick","shortcutLabel","itemStyle","IconComponent","handleClick","stopPropagation","handleMouseDown","onMouseDown","propTypes","ToolbarDropdown","Icon","setOpen","activeIndex","setActiveIndex","ref","menuRef","contains","idx","findIndex","o","currentOption","find","displayLabel","handleToggle","handleKeyDown","querySelectorAll","scrollIntoView","block","activeDescendant","minWidth","onKeyDown","title","option","id","COLOR_NAMES","ToolbarColorPicker","currentColor","onColorSelect","focusedIndex","setFocusedIndex","swatchRefs","DEFAULT_COLORS","focus","handleSwatchKeyDown","index","totalColors","newIndex","handleDefault","backgroundColor","toLowerCase","tabIndex","ColorPresetSection","presets","setPresets","loadColorPresets","showSave","setShowSave","presetName","setPresetName","handleSave","trim","saveColorPreset","preset","colors","slice","marginTop","ToolbarSeparator","separatorStyle","LINE_HEIGHT_OPTIONS","LETTER_SPACING_OPTIONS","PARAGRAPH_SPACING_OPTIONS","TypographyDropdown","handleLineHeight","handleLetterSpacing","handleParagraphSpacing","xmlns","HEADING_OPTIONS_WITH_STYLES","HEADING_OPTIONS","tag","parseInt","Toolbar","onOpenModal","fonts","DEFAULT_FONTS","wordCountButton","toolbarItemTheme","customizableToolbar","onToolbarChange","selectionState","toolbarConfig","DEFAULT_TOOLBAR","toolbarRef","innerRef","overflowIndex","setOverflowIndex","overflowOpen","setOverflowOpen","overflowMenuRef","dragItem","setDragItem","dragOverItem","setDragOverItem","customOrder","setCustomOrder","saved","localStorage","getItem","parse","fontOptions","handleHeadingChange","replace","handleFontFamilyChange","handleFontSizeChange","handleForeColorSelect","handleBackColorSelect","handleOpenImage","handleOpenAttachment","handleOpenImportDocument","handleOpenTable","handleOpenEmbed","handleOpenFindReplace","handleOpenExport","handleOpenCommandPalette","result","group","gi","toolbar","inner","checkOverflow","containerWidth","clientWidth","cutIndex","accumulatedWidth","child","classList","offsetWidth","observer","firstBtn","querySelector","handleOverflowKeyDown","currentIndex","indexOf","activeElement","orderedItems","orderMap","Map","sort","ai","get","bi","handleDragStart","dataTransfer","effectAllowed","handleDragOver","dropEffect","handleDrop","targetItem","currentOrder","fromIdx","toIdx","newOrder","moved","splice","setItem","handleDragEnd","minHeight","renderItem","_separator","DEFAULT_FONT_SIZES","TOOLTIP_MAP","getSelectedText","getShortcutLabel","BUTTON_COMMANDS","isActive","getCommandActiveState","isRegistered","finalItems","visibleItems","overflowItems","rendered","draggable","onDragStart","onDragOver","onDrop","onDragEnd","position","EditArea","forwardRef","readOnly","suppressContentEditableWarning","FLOATING_COMMANDS","FloatingToolbar","onDismiss","sizeRef","setPosition","top","left","hasFocus","setHasFocus","placedBelow","setPlacedBelow","dragOffset","setDragOffset","dragStartRef","isDraggingRef","touchVisible","setTouchVisible","touchTimerRef","onTouchEnd","rangeCount","contentRect","toolbarHeight","offsetHeight","toolbarWidth","below","bottom","buttons","nextIndex","handleFocusIn","handleFocusOut","handlePointerDown","handleGripPointerDown","offsetX","offsetY","currentTarget","setPointerCapture","pointerId","onMove","moveEvent","onUp","onPointerDown","cmd","charAt","toUpperCase","ImageResizeHandles","resizing","setResizing","startPos","setStartPos","startSize","setStartSize","editingAlt","setEditingAlt","altText","setAltText","altInputRef","getAttribute","imgRect","corner","handlePointerMove","aspectRatio","newWidth","max","newHeight","handlePointerUp","handleAltSave","setAttribute","handleAltKeyDown","pointerEvents","touchAction","TableControls","tableRect","handleDeleteTable","confirm","CodeBlockControls","code","currentLang","setFilter","dropdownRef","inputRef","handleSelect","langId","language","filteredLangs","SUPPORTED_LANGUAGES","lang","codeBlockRect","right","zIndex","DropZoneOverlay","fileTypes","hasImages","some","startsWith","hint","BlockDragHandle","hoveredBlock","setHoveredBlock","handlePos","setHandlePos","isDragging","setIsDragging","ghostPos","setGhostPos","dropIndicator","setDropIndicator","handleRef","draggedBlockRef","ghostRef","dropTargetRef","updateHoveredBlock","dragDrop","getDraggableBlock","blockRect","editorEl","editorElRect","scrollTop","onPointerMove","onPointerLeave","makeBlockDraggable","unmakeBlockDraggable","pointerType","handle","elements","closestBlock","closestDist","Infinity","centerY","dist","abs","insertBefore","indicatorTop","onPointerUp","targetBlock","parentNode","nextSibling","background","borderRadius","min","STATUS_LABELS","saving","unsaved","SaveStatus","StatusBar","showSaveStatus","counts","setCounts","wordCount","charCount","dirty","setDirty","updateCounts","newCounts","_wordCount","markClean","fn","showDirtyIndicator","WordCountButton","RecoveryBanner","timeAgo","seconds","floor","now","minutes","hours","days","formatTimeAgo","EditorErrorBoundary","Component","super","hasError","getDerivedStateFromError","componentDidCatch","errorInfo","onError","render","fallback","setState","EmptyState","custom","TAG_LABELS","P","H1","H2","H3","H4","H5","H6","BLOCKQUOTE","PRE","UL","OL","LI","TABLE","THEAD","TBODY","TR","TH","TD","STRONG","EM","U","S","DIV","SPAN","DETAILS","SUMMARY","FIGURE","FIGCAPTION","IMG","getLabel","BreadcrumbBar","path","setPath","updatePath","anchorNode","nodeType","Node","TEXT_NODE","ELEMENT_NODE","unshift","buildPath","segment","border","cursor","padding","font","Minimap","minimapRef","contentRef","viewportTop","setViewportTop","viewportHeight","setViewportHeight","setTextContent","updateContent","updateViewport","area","minimap","scrollRatio","scrollHeight","visibleRatio","clientHeight","minimapHeight","rafId","throttledUpdateViewport","scrollTarget","scrollTo","behavior","SplitPreview","content","setContent","previewFormat","debounceRef","flex","display","flexDirection","Toast","duration","timer","animationDuration","useToast","toastState","setToastState","showToast","handleDismiss","CommandPalette","lazy","Promise","resolve","require","default","LinkModal","ImageModal","TablePickerModal","EmbedModal","FindReplacePanel","SourceModal","ExportModal","AttachmentModal","ImportDocumentModal","EditorModals","modals","closeModal","showCommandPalette","commandPaletteOpen","setCommandPaletteOpen","handleOpenModal","onClose","isSourceMode","MenuBar","ContextMenu","RemyxEditor","attachTo","theme","maxHeight","uploadHandler","showFloatingToolbar","showContextMenu","googleFonts","statusBar","customTheme","shortcuts","baseHeadingLevel","menuBarConfig","effectiveToolbar","errorFallback","autosaveConfig","emptyState","emptyStateProp","showBreadcrumb","showMinimap","splitViewFormat","customizableToolbarProp","componentProps","resolvedConfig","merged","reduce","acc","menuBar","menuBarProp","floatingToolbar","autosave","autosaveProp","breadcrumb","resolvedPlugins","resolvePlugins","DEFAULT_MENU_BAR","useResolvedConfig","loadGoogleFonts","mergedFonts","googleFontNames","base","existing","newFonts","portalContainer","effectiveValue","effectiveOnChange","setPortalContainer","attachedInitialContent","setAttachedInitialContent","attachCleanupRef","isFormElement","initial","innerHTML","container","createElement","removeChild","originalContent","appendChild","handleChange","usePortalAttachment","formatState","uiState","domLookupCacheRef","WeakMap","setFormatState","setUiState","cachedFocusRef","handleSelectionChange","formats","shallowEqual","focusNode","cached","img","pre","set","rectUnchanged","useSelection","openModal","dispatch","useReducer","isOpen","getData","useModal","toastEl","__engine","touchRef","swipingElRef","handleTouchStart","touches","touch","startX","startY","currentX","currentY","swipable","handleTouchMove","clampedDx","transform","transition","handleTouchEnd","absDx","absDy","onDismissToolbar","useSwipeGesture","elementRef","onLongPress","startPosRef","firedRef","clear","vibrate","_","useLongPress","fakeEvent","zoomedElement","resetZoom","setZoomedElement","pinchRef","scaleRef","transformOrigin","removeAttribute","wrapper","zoomable","initialDistance","match","currentScale","parseFloat","initialScale","currentDistance","newScale","finalScale","round","usePinchZoom","keyboardVisible","setKeyboardVisible","keyboardHeight","setKeyboardHeight","initialHeightRef","scrollCaretIntoView","kbHeight","visualViewport","innerHeight","scrollAmount","vv","handleResize","diff","screen","paddingBottom","prevHeight","currentHeight","useVirtualKeyboard","sm","mod","platform","metaKey","ctrlKey","shiftKey","pluginName","phase","file","isEmpty","setIsEmpty","getText","splitViewActive","setSplitViewActive","wordCountBtn","themeClassName","editAreaStyle","mergedStyle","editorTree","Provider","statusBarMode","showRecoveryBanner","onHide","wrappedTree","createPortal","useExternalConfig","url","headers","pollInterval","onLoad","setConfig","loading","setLoading","setError","abortRef","onLoadRef","onErrorRef","headersRef","fetchConfig","abort","controller","AbortController","loadConfig","signal","aborted","setInterval","clearInterval","reload","ts","CommentBody","parts","part","CommentsPanel","threads","activeThread","onNavigate","onResolve","onDelete","onReply","replyingTo","setReplyingTo","replyText","setReplyText","replyInputRef","filteredThreads","resolved","unresolvedCount","handleReplySubmit","threadId","author","startReply","thread","createdAt","replies","reply","outline","CollaborationBarInner","collaborators","connectionStatus","localUser","showCount","userColor","userName","status","userId","marginLeft","CollaborationBar","fetchHeaders","onConfigLoad","onConfigError","loadingFallback","errorFallbackProp","editorProps","mergedProps","setCollaborators","setConnectionStatus","unsubsRef","refresh","_collaboration","getCollaborators","getConnectionStatus","evt","setThreads","setActiveThread","_comments","getAllThreads","unsubClick","params","deleteComment","resolveComment","replyToComment","editComment","newBody","navigateToComment","getThread","importThreads","exportThreads","getMentionUsers","targetRef","containerRef","editableRef","cleanupRef","formRef","syncToTextareaRef","initEditor","isTextarea","isInput","safeTheme","ALLOWED_STYLE_KEYS","editable","editArea","syncToTextarea","form","prevCleanup","engineOpts","errors","setErrors","stats","setStats","total","grammar","byRule","setEnabled","stylePreset","setStylePresetState","setLanguageState","_spellcheck","getStats","getErrors","getWritingStyle","getLanguage","runCheck","addToDictionary","word","removeFromDictionary","ignoreWord","setWritingStyle","setLanguage","getDictionary","getIgnoredWords"],"mappings":"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","x_google_ignoreList":[13,14,15,16,17,18,19,20,21,22]}
|