noteloom 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +344 -53
- package/bin/noteloom.mjs +139 -0
- package/dist/canvas.cjs +2 -0
- package/dist/canvas.cjs.map +1 -0
- package/dist/canvas.d.ts +2 -0
- package/dist/canvas.js +5 -0
- package/dist/canvas.js.map +1 -0
- package/dist/collab.cjs +2 -0
- package/dist/collab.cjs.map +1 -0
- package/dist/collab.d.ts +19 -0
- package/dist/collab.js +379 -0
- package/dist/collab.js.map +1 -0
- package/dist/comments.cjs +2 -0
- package/dist/comments.cjs.map +1 -0
- package/dist/comments.d.ts +17 -0
- package/dist/comments.js +19 -0
- package/dist/comments.js.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +392 -32
- package/dist/index.js +3983 -0
- package/dist/index.js.map +1 -0
- package/dist/persistence.cjs +2 -0
- package/dist/persistence.cjs.map +1 -0
- package/dist/persistence.d.ts +11 -0
- package/dist/persistence.js +12 -0
- package/dist/persistence.js.map +1 -0
- package/dist/shared/CommentAvatar-TKqsM8vG.js +53 -0
- package/dist/shared/CommentAvatar-TKqsM8vG.js.map +1 -0
- package/dist/shared/CommentAvatar-V457IgoQ.cjs +2 -0
- package/dist/shared/CommentAvatar-V457IgoQ.cjs.map +1 -0
- package/dist/shared/CommentThreadCard-CAJ3oPdr.cjs +2 -0
- package/dist/shared/CommentThreadCard-CAJ3oPdr.cjs.map +1 -0
- package/dist/shared/CommentThreadCard-Cxf8GwHJ.js +213 -0
- package/dist/shared/CommentThreadCard-Cxf8GwHJ.js.map +1 -0
- package/dist/shared/CommentsPanel-BwVVyMOC.js +76 -0
- package/dist/shared/CommentsPanel-BwVVyMOC.js.map +1 -0
- package/dist/shared/CommentsPanel-CES4uzye.cjs +2 -0
- package/dist/shared/CommentsPanel-CES4uzye.cjs.map +1 -0
- package/dist/shared/VersionHistory-Bg6fufP5.js +1120 -0
- package/dist/shared/VersionHistory-Bg6fufP5.js.map +1 -0
- package/dist/shared/VersionHistory-DELa2Wbq.cjs +12 -0
- package/dist/shared/VersionHistory-DELa2Wbq.cjs.map +1 -0
- package/dist/shared/VoiceListeningIndicator-BOfVmLK0.js +338 -0
- package/dist/shared/VoiceListeningIndicator-BOfVmLK0.js.map +1 -0
- package/dist/shared/VoiceListeningIndicator-DNX8JlQM.cjs +2 -0
- package/dist/shared/VoiceListeningIndicator-DNX8JlQM.cjs.map +1 -0
- package/dist/shared/fieldRegistry-BoYyW3GH.cjs +2 -0
- package/dist/shared/fieldRegistry-BoYyW3GH.cjs.map +1 -0
- package/dist/shared/fieldRegistry-PjJWXFoB.js +223 -0
- package/dist/shared/fieldRegistry-PjJWXFoB.js.map +1 -0
- package/dist/shared/icons-C1_s0jKK.js +4269 -0
- package/dist/shared/icons-C1_s0jKK.js.map +1 -0
- package/dist/shared/icons-DtCsXuU6.cjs +3531 -0
- package/dist/shared/icons-DtCsXuU6.cjs.map +1 -0
- package/dist/shared/index-B9jyyL8u.js +2145 -0
- package/dist/shared/index-B9jyyL8u.js.map +1 -0
- package/dist/shared/index-D9WEXpYM.cjs +2 -0
- package/dist/shared/index-D9WEXpYM.cjs.map +1 -0
- package/dist/shared/indexedDbPersistence-BKlGPFTP.js +112 -0
- package/dist/shared/indexedDbPersistence-BKlGPFTP.js.map +1 -0
- package/dist/shared/indexedDbPersistence-BWJ1h5Vp.cjs +2 -0
- package/dist/shared/indexedDbPersistence-BWJ1h5Vp.cjs.map +1 -0
- package/dist/shared/leafBlockFactory-A9eUhSe-.js +335 -0
- package/dist/shared/leafBlockFactory-A9eUhSe-.js.map +1 -0
- package/dist/shared/leafBlockFactory-Dp382eP8.cjs +2 -0
- package/dist/shared/leafBlockFactory-Dp382eP8.cjs.map +1 -0
- package/dist/shared/serialize-DWEfk0vU.cjs +3 -0
- package/dist/shared/serialize-DWEfk0vU.cjs.map +1 -0
- package/dist/shared/serialize-T9Odwx24.js +86 -0
- package/dist/shared/serialize-T9Odwx24.js.map +1 -0
- package/dist/shared/starter-kit-CY5wzYDf.js +4980 -0
- package/dist/shared/starter-kit-CY5wzYDf.js.map +1 -0
- package/dist/shared/starter-kit-lPN-NpJ5.cjs +27 -0
- package/dist/shared/starter-kit-lPN-NpJ5.cjs.map +1 -0
- package/dist/shared/usePopoverEdgeClamp-CDG26jBM.cjs +2 -0
- package/dist/shared/usePopoverEdgeClamp-CDG26jBM.cjs.map +1 -0
- package/dist/shared/usePopoverEdgeClamp-gmFm0CnI.js +109 -0
- package/dist/shared/usePopoverEdgeClamp-gmFm0CnI.js.map +1 -0
- package/dist/shared/useServiceWorkerUpdate-BduabXv6.js +94 -0
- package/dist/shared/useServiceWorkerUpdate-BduabXv6.js.map +1 -0
- package/dist/shared/useServiceWorkerUpdate-DQboGesi.cjs +2 -0
- package/dist/shared/useServiceWorkerUpdate-DQboGesi.cjs.map +1 -0
- package/dist/starter-kit.cjs +2 -0
- package/dist/starter-kit.cjs.map +1 -0
- package/dist/starter-kit.d.ts +9 -0
- package/dist/starter-kit.js +10 -0
- package/dist/starter-kit.js.map +1 -0
- package/dist/style.css +3529 -3200
- package/dist/versions.cjs +2 -0
- package/dist/versions.cjs.map +1 -0
- package/dist/versions.d.ts +11 -0
- package/dist/versions.js +13 -0
- package/dist/versions.js.map +1 -0
- package/dist/voice.cjs +2 -0
- package/dist/voice.cjs.map +1 -0
- package/dist/voice.d.ts +7 -0
- package/dist/voice.js +8 -0
- package/dist/voice.js.map +1 -0
- package/package.json +159 -92
- package/dist/noteloom.cjs +0 -3209
- package/dist/noteloom.cjs.map +0 -1
- package/dist/noteloom.es.js +0 -14622
- package/dist/noteloom.es.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"starter-kit-CY5wzYDf.js","sources":["../../src/blocks/shared/blockEmpty.js","../../src/blocks/shared/contentless.js","../../src/react/LinkEditModal.jsx","../../src/react/useAutoAdjustedPosition.js","../../src/react/LinkHoverCard.jsx","../../src/react/CommentPopoverHeader.jsx","../../src/react/CommentPopover.jsx","../../src/react/EditableBlockContent.jsx","../../src/blocks/shared/ensureRootNonEmpty.js","../../src/blocks/shared/mergeCommands.js","../../src/blocks/shared/focusAfterMerge.js","../../src/blocks/shared/resolveBlockDir.js","../../src/blocks/paragraph/markdownShortcuts.js","../../src/blocks/paragraph/ParagraphBlock.jsx","../../src/inline/runOps.js","../../src/blocks/paragraph/index.js","../../src/blocks/heading/HeadingBlock.jsx","../../src/blocks/heading/index.js","../../src/react/useBlockChildren.js","../../src/react/BlockErrorBoundary.jsx","../../src/react/BlockRenderer.jsx","../../src/react/useMenuKeyboardNav.js","../../src/react/liveAnnouncer.js","../../src/blocks/callout/createCalloutBlock.js","../../src/blocks/shared/turnInto.js","../../src/react/TurnIntoSubmenu.jsx","../../src/blocks/shared/blockActions.js","../../src/react/BlockGutterRow.jsx","../../src/react/BlockChildren.jsx","../../src/blocks/listItem/listMarkers.js","../../src/blocks/listItem/createListItemBlock.js","../../src/blocks/listItem/indentCommands.js","../../src/blocks/listItem/mergeCommands.js","../../src/blocks/listItem/exitListItem.js","../../src/blocks/listItem/ListItemBlock.jsx","../../src/blocks/listItem/index.js","../../src/blocks/table/tableColumns.js","../../src/blocks/table/tableView.js","../../src/blocks/table/tableEditCommands.js","../../src/react/useFieldTypes.js","../../src/react/useVirtualKeyboardInset.js","../../src/react/Select.jsx","../../src/blocks/table/tagColors.js","../../src/blocks/table/TableHeaderRow.jsx","../../src/blocks/table/TableBlock.jsx","../../src/blocks/table/TableRowBlock.jsx","../../src/blocks/table/tableNavigation.js","../../src/blocks/table/TableCellBlock.jsx","../../src/blocks/table/createTableBlock.js","../../src/blocks/table/index.js","../../src/blocks/layout/LayoutBlock.jsx","../../src/blocks/layout/LayoutColumnBlock.jsx","../../src/blocks/layout/createLayoutBlock.js","../../src/blocks/layout/index.js","../../src/blocks/divider/DividerBlock.jsx","../../src/blocks/divider/index.js","../../src/blocks/callout/CalloutBlock.jsx","../../src/blocks/callout/index.js","../../src/blocks/blockquote/BlockquoteBlock.jsx","../../src/blocks/blockquote/index.js","../../src/blocks/code/CodeBlock.jsx","../../src/blocks/code/index.js","../../src/blocks/toggleHeading/mergeCommands.js","../../src/blocks/toggleHeading/ToggleHeadingBlock.jsx","../../src/blocks/toggleHeading/createToggleHeadingBlock.js","../../src/blocks/toggleHeading/index.js","../../src/blocks/button/ButtonEditModal.jsx","../../src/blocks/button/ButtonBlock.jsx","../../src/blocks/button/createButtonBlock.js","../../src/blocks/button/index.js","../../src/blocks/embed/resolveFileEmbed.js","../../src/blocks/embed/oembedProviders.js","../../src/blocks/embed/EmbedBlock.jsx","../../src/blocks/embed/createEmbedBlock.js","../../src/blocks/embed/index.js","../../src/react/pendingAutoOpen.js","../../src/inlineTypes/shared/advanceAfterPick.js","../../src/inlineTypes/select/SelectInlineNode.jsx","../../src/inlineTypes/shared/insertInlineRun.js","../../src/inlineTypes/select/index.js","../../src/inlineTypes/date/DateInlineNode.jsx","../../src/inlineTypes/date/index.js","../../src/inlineTypes/checkbox/CheckboxInlineNode.jsx","../../src/inlineTypes/checkbox/index.js","../../src/inlineTypes/tableSelect/TableSelectInlineNode.jsx","../../src/inlineTypes/tableSelect/index.js","../../src/inlineTypes/emoji/index.js","../../src/starter-kit.js"],"sourcesContent":["/**\n * True when `run` contributes no real content: absent, or a text run whose\n * value is ''. An atomic (non-text) run — a date/select/checkbox/custom-field\n * chip — is never blank even without a \"value\", since there's a real chip\n * sitting there for the user to see/interact with.\n */\nexport function isRunBlank(run) {\n if (!run) return true;\n if (run.type !== 'text') return false;\n return (run.value ?? '') === '';\n}\n\n/**\n * True when every run in `runIds` is blank — used to decide whether to show\n * a placeholder hint (e.g. \"Type '/' for commands\") for a block that has\n * nothing in it yet. Same semantics as isCurrentBlockEmpty in\n * react/selectAllCommand.js (which needs a live caret to find the block\n * first); this version just takes run ids directly, since callers here\n * already have the block in hand from useBlock.\n */\nexport function isRunsEmpty(store, runIds) {\n if (!runIds || runIds.length === 0) return true;\n return runIds.every((id) => isRunBlank(store.getRun(id)));\n}\n","/** True for a block with nothing to merge/focus into (e.g. a divider): no run-bearing contentIds and no titleRunIds. */\nexport function isContentlessBlock(store, block) {\n if (!block) return false;\n const hasRuns = block.contentIds.length > 0;\n const hasTitleRuns = (block.props?.titleRunIds?.length ?? 0) > 0;\n return !hasRuns && !hasTitleRuns;\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { Modal } from './Modal.jsx';\n\n/**\n * URL + \"open in\" form shown for both creating a link (FloatingToolbar's\n * Link button, over a fresh selection) and editing one (LinkHoverCard's\n * pencil icon, over an existing link mark) — one shared modal so both\n * flows look and behave identically, rather than the hover card growing\n * its own smaller inline editor that drifts out of sync with this one.\n */\nexport function LinkEditModal({\n isOpen,\n initialHref,\n initialTarget,\n hasExistingLink,\n onSave,\n onRemove,\n onClose,\n}) {\n const [href, setHref] = useState('');\n const [target, setTarget] = useState('_self');\n\n useEffect(() => {\n if (!isOpen) return;\n setHref(initialHref);\n setTarget(initialTarget);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n const trimmedHref = href.trim();\n\n const handleSubmit = useCallback(\n (event) => {\n event.preventDefault();\n if (!trimmedHref) return;\n onSave(trimmedHref, target);\n },\n [trimmedHref, target, onSave],\n );\n\n return (\n <Modal isOpen={isOpen} onClose={onClose} title={hasExistingLink ? 'Edit link' : 'Add link'}>\n <form onSubmit={handleSubmit}>\n <label className=\"be-modal-field\">\n <span>URL</span>\n <input\n type=\"text\"\n value={href}\n onChange={(event) => setHref(event.target.value)}\n placeholder=\"https://example.com\"\n autoFocus\n />\n </label>\n <label className=\"be-modal-field\">\n <span>Open in</span>\n <select value={target} onChange={(event) => setTarget(event.target.value)}>\n <option value=\"_self\">Same tab</option>\n <option value=\"_blank\">New tab</option>\n </select>\n </label>\n <div className=\"be-modal-actions\">\n {hasExistingLink && (\n <button type=\"button\" className=\"be-modal-delete\" onClick={onRemove}>\n Remove link\n </button>\n )}\n <button type=\"button\" className=\"be-modal-cancel\" onClick={onClose}>\n Cancel\n </button>\n <button type=\"submit\" className=\"be-modal-save\" disabled={!trimmedHref}>\n Save\n </button>\n </div>\n </form>\n </Modal>\n );\n}\n","import { useLayoutEffect, useState } from 'react';\nimport { clampLeftToViewport, clampTopToViewport } from './popoverPosition.js';\n\n/**\n * Takes a `{ top, left }` position computed off a trigger's own\n * getBoundingClientRect() (as every portaled top-left-anchored menu here\n * already does) and, once the portaled element has actually mounted at\n * `menuRef`, measures its real size and shifts it back inside the viewport\n * if it would otherwise overflow — same \"shift\" behavior as antd's\n * `autoAdjustOverflow`, not a side-flip. Without this, a menu anchored near\n * the right/bottom edge (e.g. TurnIntoSubmenu opening to the right of its\n * trigger) can render partly or entirely off-screen, making its items\n * unreachable.\n *\n * `top`/`left` are taken as plain numbers (not a `{top,left}` object) so a\n * caller re-rendering every frame doesn't retrigger the adjustment via a\n * fresh object identity — only an actual numeric change re-anchors.\n *\n * Two-phase by design: the first effect snaps to the raw, unadjusted\n * position (matching the trigger) so the menu doesn't visibly jump on open;\n * the second effect then measures and clamps once real layout exists. Since\n * clamping the already-clamped position is a no-op, this settles after at\n * most one extra render — never loops. Both effects are `useLayoutEffect`s,\n * so React flushes the whole chain before the browser paints; nothing\n * visibly flashes at the raw position first.\n *\n * Only fits a plain top-left anchor (box grows right/down, no CSS\n * transform) — see popoverPosition.js's other hooks for centered\n * (translateX(-50%)) or right-anchored (translateX(-100%)) popovers, which\n * need the clamp math applied differently.\n */\nexport function useAutoAdjustedPosition(menuRef, isOpen, top, left) {\n const [position, setPosition] = useState(null);\n\n useLayoutEffect(() => {\n if (top == null || left == null) {\n setPosition(null);\n return;\n }\n setPosition({ top, left });\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [top, left]);\n\n useLayoutEffect(() => {\n if (!isOpen || !menuRef.current || !position) return;\n const rect = menuRef.current.getBoundingClientRect();\n const clampedLeft = clampLeftToViewport(position.left, rect.width);\n const clampedTop = clampTopToViewport(position.top, rect.height);\n if (clampedLeft !== position.left || clampedTop !== position.top) {\n setPosition({ top: clampedTop, left: clampedLeft });\n }\n }, [isOpen, menuRef, position]);\n\n return position;\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { updateRun } from '../store/operations.js';\nimport { LinkEditModal } from './LinkEditModal.jsx';\nimport { useAutoAdjustedPosition } from './useAutoAdjustedPosition.js';\nimport { PencilIcon, XIcon } from './icons.jsx';\n\n/**\n * Hover card for editing/removing an existing link mark — the counterpart\n * to FloatingToolbar's Link button (which only handles *creating* a link\n * over a selection). A plain click on link text just places the caret (see\n * EditableBlockContent's marksToStyle/onclick comment — navigation is\n * Ctrl/Cmd+click only, since the text is still editable), so there needs\n * to be some other way to discover \"this is a link\" and get back into it\n * without re-selecting the exact same text again. Hovering is that\n * discovery path, the same link-tooltip pattern most rich text editors use.\n *\n * The pencil button opens the exact same LinkEditModal FloatingToolbar's\n * Link button uses (pre-filled), rather than a second, smaller inline\n * editor — one link-editing UI, not two that could drift apart.\n *\n * Mutates the run directly via updateRun(runId, {marks}) rather than going\n * through the selection-based markCommands primitives — there's no live\n * text selection here at all, just \"this one run, whichever block it's\n * in\", so addressing it by run id directly is both simpler and correct\n * (no need to resolve/reconstruct a blockId+selection just to describe\n * \"the whole of this one run\").\n */\nexport function LinkHoverCard({ containerRef, store }) {\n const [hovered, setHovered] = useState(null); // { runId, rect } | null\n const [isModalOpen, setIsModalOpen] = useState(false);\n const hideTimerRef = useRef(null);\n const cardRef = useRef(null);\n\n const clearHideTimer = useCallback(() => {\n if (hideTimerRef.current) {\n clearTimeout(hideTimerRef.current);\n hideTimerRef.current = null;\n }\n }, []);\n\n const scheduleHide = useCallback(() => {\n clearHideTimer();\n hideTimerRef.current = setTimeout(() => {\n // A modal-open edit shouldn't vanish just because the mouse left the\n // hover card that launched it — only actually dismiss the underlying\n // hover state once the modal itself is closed (see the Save/Cancel\n // handlers below, which clear `hovered` themselves).\n setHovered((prev) => (isModalOpen ? prev : null));\n }, 250);\n }, [clearHideTimer, isModalOpen]);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return undefined;\n\n const handleMouseOver = (event) => {\n const runEl = event.target.closest?.('[data-run-id]');\n if (!runEl || !container.contains(runEl)) return;\n const runId = runEl.dataset.runId;\n const run = store.getRun(runId);\n if (!run?.marks?.link) return;\n clearHideTimer();\n setHovered((prev) =>\n prev?.runId === runId ? prev : { runId, rect: runEl.getBoundingClientRect() },\n );\n };\n const handleMouseOut = () => scheduleHide();\n\n container.addEventListener('mouseover', handleMouseOver);\n container.addEventListener('mouseout', handleMouseOut);\n return () => {\n container.removeEventListener('mouseover', handleMouseOver);\n container.removeEventListener('mouseout', handleMouseOut);\n };\n }, [containerRef, store, clearHideTimer, scheduleHide]);\n\n useEffect(() => () => clearHideTimer(), [clearHideTimer]);\n\n const openModal = useCallback(() => setIsModalOpen(true), []);\n const closeModal = useCallback(() => {\n setIsModalOpen(false);\n setHovered(null);\n }, []);\n\n const saveLink = useCallback(\n (href, target) => {\n if (!hovered) return;\n const run = store.getRun(hovered.runId);\n if (!run) return;\n store.applyOperation(\n updateRun(hovered.runId, { marks: { ...run.marks, link: { href, target } } }),\n );\n closeModal();\n },\n [hovered, store, closeModal],\n );\n\n const removeLink = useCallback(() => {\n if (!hovered) return;\n const run = store.getRun(hovered.runId);\n if (!run) return;\n const nextMarks = { ...run.marks };\n delete nextMarks.link;\n store.applyOperation(updateRun(hovered.runId, { marks: nextMarks }));\n closeModal();\n }, [hovered, store, closeModal]);\n\n const run = hovered && store.getRun(hovered.runId);\n const link = run?.marks?.link;\n const isCardOpen = Boolean(hovered && link && !isModalOpen);\n const position = useAutoAdjustedPosition(\n cardRef,\n isCardOpen,\n hovered ? hovered.rect.bottom + 6 : null,\n hovered ? hovered.rect.left : null,\n );\n\n return (\n <>\n {isCardOpen && position\n ? createPortal(\n <div\n ref={cardRef}\n className=\"be-link-hover-card\"\n contentEditable={false}\n style={{ position: 'fixed', top: position.top, left: position.left }}\n onMouseEnter={clearHideTimer}\n onMouseLeave={scheduleHide}\n >\n <a\n className=\"be-link-hover-card-url\"\n href={link.href}\n target={link.target === '_blank' ? '_blank' : '_self'}\n rel=\"noopener noreferrer\"\n >\n {link.href}\n </a>\n <button\n type=\"button\"\n className=\"be-link-hover-card-btn\"\n onClick={openModal}\n aria-label=\"Edit link\"\n title=\"Edit link\"\n >\n <PencilIcon size={13} />\n </button>\n <button\n type=\"button\"\n className=\"be-link-hover-card-btn\"\n onClick={removeLink}\n aria-label=\"Remove link\"\n title=\"Remove link\"\n >\n <XIcon size={13} />\n </button>\n </div>,\n document.body,\n )\n : null}\n <LinkEditModal\n isOpen={isModalOpen}\n initialHref={link?.href ?? ''}\n initialTarget={link?.target ?? '_self'}\n hasExistingLink={Boolean(link)}\n onSave={saveLink}\n onRemove={removeLink}\n onClose={closeModal}\n />\n </>\n );\n}\n","import { XIcon } from './icons.jsx';\n\n/** Shared title + close-button row for both CommentPopover (viewing existing threads) and FloatingToolbar's standalone \"Add comment\" composer -- one small header, not duplicated markup in each. */\nexport function CommentPopoverHeader({ title, onClose }) {\n return (\n <div className=\"be-comment-popover-header\">\n <span className=\"be-comment-popover-title\">{title}</span>\n <button\n type=\"button\"\n className=\"be-comment-popover-close\"\n onClick={onClose}\n aria-label=\"Close\"\n >\n <XIcon size={14} />\n </button>\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useAutoAdjustedPosition } from './useAutoAdjustedPosition.js';\nimport { CommentThreadCard } from './CommentThreadCard.jsx';\nimport { CommentPopoverHeader } from './CommentPopoverHeader.jsx';\nimport { useHoveredComment } from './EditorProvider.jsx';\n\n/**\n * The click-or-hover popover for VIEWING/replying to/resolving/deleting an\n * EXISTING comment thread over highlighted text (`.be-comment-highlight`,\n * see commentMarks.js) — the read/react counterpart to FloatingToolbar's\n * Comment button, which only handles *creating* a new comment over a fresh\n * selection. Mirrors LinkHoverCard's exact hover-card mechanism (same\n * container-level mouseover/mouseout listening, same hide-timer dance,\n * mounted the same way in EditableBlockContent.jsx) but additionally opens\n * (and stays open, \"pinned\") on a plain click, since a comment is more often\n * something you deliberately open than glance at in passing.\n *\n * A run can carry more than one `commentIds` entry (overlapping comments) —\n * every thread attached to the clicked/hovered run is shown, stacked,\n * inside one popover.\n */\nconst FOCUSABLE_SELECTOR =\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n\nexport function CommentPopover({ containerRef, store, authorId }) {\n const [target, setTarget] = useState(null); // { rect, commentIds } | null\n const [pinned, setPinned] = useState(false);\n const hideTimerRef = useRef(null);\n const popoverRef = useRef(null);\n const previouslyFocusedRef = useRef(null);\n const [, setHoveredCommentId] = useHoveredComment();\n\n const clearHideTimer = useCallback(() => {\n if (hideTimerRef.current) {\n clearTimeout(hideTimerRef.current);\n hideTimerRef.current = null;\n }\n }, []);\n\n const scheduleHide = useCallback(() => {\n clearHideTimer();\n hideTimerRef.current = setTimeout(() => {\n setTarget((prev) => (pinned ? prev : null));\n }, 250);\n }, [clearHideTimer, pinned]);\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return undefined;\n\n const findCommentRun = (el) => {\n const runEl = el?.closest?.('[data-run-id]');\n if (!runEl || !container.contains(runEl)) return null;\n const commentIds = store.getRun(runEl.dataset.runId)?.marks?.commentIds;\n if (!commentIds?.length) return null;\n return { runEl, commentIds };\n };\n\n const handleMouseOver = (event) => {\n const found = findCommentRun(event.target);\n if (!found) return;\n clearHideTimer();\n setTarget((prev) =>\n prev && prev.runEl === found.runEl\n ? prev\n : {\n rect: found.runEl.getBoundingClientRect(),\n commentIds: found.commentIds,\n runEl: found.runEl,\n },\n );\n };\n const handleMouseOut = () => scheduleHide();\n\n const handleClick = (event) => {\n const found = findCommentRun(event.target);\n if (!found) {\n setPinned(false);\n setTarget(null);\n return;\n }\n clearHideTimer();\n setPinned(true);\n setTarget({\n rect: found.runEl.getBoundingClientRect(),\n commentIds: found.commentIds,\n runEl: found.runEl,\n });\n };\n\n container.addEventListener('mouseover', handleMouseOver);\n container.addEventListener('mouseout', handleMouseOut);\n container.addEventListener('click', handleClick);\n return () => {\n container.removeEventListener('mouseover', handleMouseOver);\n container.removeEventListener('mouseout', handleMouseOut);\n container.removeEventListener('click', handleClick);\n };\n }, [containerRef, store, clearHideTimer, scheduleHide]);\n\n // Outside-click / Escape closes a pinned (click-opened) popover -- a\n // click landing inside the popover itself (portaled to document.body, so\n // outside `container`) doesn't count as \"outside\".\n useEffect(() => {\n if (!target) return undefined;\n const handlePointerDown = (event) => {\n if (popoverRef.current?.contains(event.target)) return;\n if (containerRef.current?.contains(event.target)) return; // handled by handleClick above\n setPinned(false);\n setTarget(null);\n };\n const handleKeyDown = (event) => {\n if (event.key === 'Escape') {\n setPinned(false);\n setTarget(null);\n }\n };\n document.addEventListener('mousedown', handlePointerDown);\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('mousedown', handlePointerDown);\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [target, containerRef]);\n\n useEffect(() => () => clearHideTimer(), [clearHideTimer]);\n\n // Echoes onto the matching thread card in the panel, if one's rendered --\n // see useHoveredComment.\n useEffect(() => {\n setHoveredCommentId(target?.commentIds?.[0] ?? null);\n }, [target, setHoveredCommentId]);\n\n const closePopover = useCallback(() => {\n setPinned(false);\n setTarget(null);\n }, []);\n\n const isOpen = Boolean(target);\n const position = useAutoAdjustedPosition(\n popoverRef,\n isOpen,\n target ? target.rect.bottom + 6 : null,\n target ? target.rect.left : null,\n );\n\n // Only a \"pinned\" (click-)opened popover takes focus — a hover preview\n // must never steal focus away from wherever the user is actually typing\n // just because their mouse passed over a comment highlight. Mirrors\n // Modal.jsx's own one-time move-in-on-open / move-back-out-on-close\n // (not a focus trap), keyed on `pinned` rather than a generic `isOpen`.\n //\n // Also depends on `position` (not just `pinned`) for the same reason the\n // Select popover's own \"focus the search input on open\" effect needed a\n // matching fix this session: `position` starts `null` and the popover\n // returns nothing (see the `if (!isOpen || !position) return null` below)\n // until useAutoAdjustedPosition resolves it, so `popoverRef.current` is\n // still null on the exact render `pinned` first flips true. `didFocusRef`\n // guards against re-running the actual focus-move once `position` is\n // merely re-clamped afterward.\n const didFocusRef = useRef(false);\n useEffect(() => {\n if (pinned && popoverRef.current && !didFocusRef.current) {\n didFocusRef.current = true;\n previouslyFocusedRef.current = document.activeElement;\n const focusable = popoverRef.current.querySelector(FOCUSABLE_SELECTOR);\n (focusable ?? popoverRef.current).focus();\n } else if (!pinned && didFocusRef.current) {\n didFocusRef.current = false;\n previouslyFocusedRef.current?.focus?.();\n previouslyFocusedRef.current = null;\n }\n }, [pinned, position]);\n\n if (!isOpen || !position) return null;\n\n const threads = target.commentIds.map((id) => store.getComment(id)).filter(Boolean);\n if (threads.length === 0) return null;\n\n return createPortal(\n <div\n ref={popoverRef}\n className=\"be-comment-popover\"\n contentEditable={false}\n style={{ position: 'fixed', top: position.top, left: position.left }}\n onMouseEnter={clearHideTimer}\n onMouseLeave={scheduleHide}\n role=\"dialog\"\n aria-modal={pinned || undefined}\n aria-label={`Comments (${threads.length})`}\n tabIndex={-1}\n >\n <CommentPopoverHeader title={`Comments (${threads.length})`} onClose={closePopover} />\n {threads.map((thread) => (\n <CommentThreadCard key={thread.id} store={store} thread={thread} authorId={authorId} />\n ))}\n </div>,\n document.body,\n );\n}\n","import { useCallback, useEffect, useLayoutEffect, useRef } from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n useEditorStore,\n useInlineRegistry,\n useSelectedBlock,\n useCommentAuthorId,\n useHoveredComment,\n} from './EditorProvider.jsx';\nimport { useRun } from './useBlock.js';\nimport { updateRun, setBlockRuns, removeBlock } from '../store/operations.js';\nimport {\n reconcileDomToRuns,\n EMPTY_RUN_PLACEHOLDER,\n stripEmptyRunPlaceholder,\n} from './domRunSync.js';\nimport { isRunBlank, isRunsEmpty } from '../blocks/shared/blockEmpty.js';\nimport { isContentlessBlock } from '../blocks/shared/contentless.js';\nimport { genId } from '../utils/idGen.js';\nimport { focusRunEnd, focusRunStart } from './focusRun.js';\nimport { LinkHoverCard } from './LinkHoverCard.jsx';\nimport { CommentPopover } from './CommentPopover.jsx';\n\n/**\n * Keeps the block wrapper's data-empty attribute (see the be-*[data-empty]\n * placeholder CSS) in sync on every keystroke — not just on structural\n * changes. Ordinary typing goes through the \"onlyValueChanges\" fast path in\n * handleInput below, which applies a plain updateRun op that only notifies\n * that *run's* own subscribers (see EditorStore's UPDATE_RUN case) — the\n * block itself never re-renders, by design, so it can't recompute this\n * itself from a React render the way its *initial* data-empty value is set.\n * Written directly onto containerRef.current.parentElement — always the block's\n * own wrapper element (the div/h-tag every ParagraphBlock/HeadingBlock/\n * ListItemBlock renders EditableBlockContent directly inside of) — gated on\n * data-placeholder so this is a no-op for block types (table cells) that\n * don't opt into the placeholder hint at all.\n */\nfunction syncEmptyAttr(container, runs) {\n const wrapper = container?.parentElement;\n if (!wrapper || !wrapper.hasAttribute('data-placeholder')) return;\n const isEmpty = runs.length === 0 || runs.every(isRunBlank);\n if (isEmpty) wrapper.setAttribute('data-empty', '');\n else wrapper.removeAttribute('data-empty');\n}\n\nfunction marksToStyle(marks = {}) {\n return {\n fontWeight: marks.bold ? 'bold' : undefined,\n fontStyle: marks.italic ? 'italic' : undefined,\n textDecoration:\n [(marks.underline || marks.link) && 'underline', marks.strike && 'line-through']\n .filter(Boolean)\n .join(' ') || undefined,\n verticalAlign: marks.subscript ? 'sub' : marks.superscript ? 'super' : undefined,\n fontSize: marks.subscript || marks.superscript ? 'smaller' : undefined,\n color: marks.color || (marks.link ? 'var(--noteloom-accent)' : undefined),\n backgroundColor: marks.highlight || undefined,\n cursor: marks.link ? 'pointer' : undefined,\n };\n}\n\n/**\n * Syncs one text run's value/marks onto a `host` DOM element that\n * `EditableBlockContent` created and owns imperatively (see hostsRef/\n * getOrCreateHost below) — this component renders no DOM of its own\n * (`return null`); it only ever writes into `host` via a layout effect,\n * the same \"only touch the DOM if it actually differs\" discipline the old\n * EditableRun used.\n *\n * Subscribes to its own run via useRun (not a prop pre-resolved by the\n * parent) so an *external* value change — undo/redo, a future\n * collaborator's edit — still triggers a re-render and gets synced to the\n * DOM. Local typing bypasses this entirely: the browser mutates the text\n * node directly, `EditableBlockContent`'s input handler writes the same\n * value back into the store, and this sync then sees the DOM (once the\n * placeholder is stripped) already matches and does nothing.\n *\n * Critical: the comparison below is against the *stripped* DOM text, not\n * the raw text. `host.textContent = ...` always destroys and recreates the\n * underlying Text node, which resets/collapses the browser's active\n * Selection — comparing raw text (including the placeholder) meant every\n * empty-to-non-empty transition triggered a \"cleanup\" write that looked\n * harmless but silently reset the caret to the start of the run right\n * after the very first keystroke. Comparing stripped text means ordinary\n * typing — where the DOM already holds the right characters plus a leftover\n * placeholder byte — is a true no-op, so the caret is never touched.\n *\n * The rewrite itself (`setHostText` below) still has to happen on the\n * *opposite* transition — real content backspaced down to nothing — since a\n * host with zero children isn't a valid caret anchor either. But that write\n * mutates the existing Text node's own `.nodeValue` in place instead of\n * going through `host.textContent = ...` whenever a reusable node is\n * already there: a Range/Selection stays anchored to a Text node across a\n * `.nodeValue` change (same node, new data), but `textContent =` always\n * discards the old node and creates a new one, silently collapsing any\n * Selection that pointed into it. Continuously holding Backspace across a\n * whole run hits exactly this transition once, right as the run empties\n * out — on desktop a collapsed Selection is barely noticeable, but a mobile\n * on-screen keyboard treats the same momentary loss as \"the field lost\n * focus\" and dismisses itself, which is what this specifically fixes.\n */\nfunction setHostText(host, displayValue) {\n const onlyChild = host.childNodes.length === 1 ? host.firstChild : null;\n if (onlyChild && onlyChild.nodeType === 3) {\n if (onlyChild.nodeValue !== displayValue) onlyChild.nodeValue = displayValue;\n } else {\n host.textContent = displayValue;\n }\n}\n\nfunction TextRunSpan({ id, host, onValueSynced }) {\n const run = useRun(id);\n const [hoveredCommentId] = useHoveredComment();\n\n useLayoutEffect(() => {\n if (!host || !run) return;\n const value = run.value ?? '';\n const currentLogicalText = stripEmptyRunPlaceholder(host.textContent);\n const needsRewrite = currentLogicalText !== value || (value === '' && host.textContent === '');\n if (needsRewrite) {\n setHostText(host, value === '' ? EMPTY_RUN_PLACEHOLDER : value);\n }\n\n const style = marksToStyle(run.marks);\n host.style.fontWeight = style.fontWeight ?? '';\n host.style.fontStyle = style.fontStyle ?? '';\n host.style.textDecoration = style.textDecoration ?? '';\n host.style.verticalAlign = style.verticalAlign ?? '';\n host.style.fontSize = style.fontSize ?? '';\n host.style.color = style.color ?? '';\n host.style.backgroundColor = style.backgroundColor ?? '';\n host.style.cursor = style.cursor ?? '';\n\n // Comment-highlight is a plain CSS class (not an inline style, unlike\n // every mark above) since it's a presence/absence toggle with no\n // per-comment value to compute -- see src/comments/commentMarks.js for\n // how `marks.commentIds` gets populated.\n host.classList.toggle('be-comment-highlight', (run.marks?.commentIds?.length ?? 0) > 0);\n // Echoes a hover from the comment panel/popover back onto the text --\n // see useHoveredComment.\n host.classList.toggle(\n 'be-comment-highlight-active',\n Boolean(hoveredCommentId) && Boolean(run.marks?.commentIds?.includes(hoveredCommentId)),\n );\n\n // A link mark is a *style*, not a real <a> — the host is always a plain\n // <span> (created once, before any run's marks are known; see\n // getOrCreateHost), so navigation is opt-in via Ctrl/Cmd+click rather\n // than a native anchor, matching most rich text editors: a plain click\n // still just places the caret for editing.\n const link = run.marks?.link;\n host.title = link?.href ? `${link.href} — Ctrl+Click to open` : '';\n host.onclick = link?.href\n ? (event) => {\n if (!event.ctrlKey && !event.metaKey) return;\n event.preventDefault();\n window.open(\n link.href,\n link.target === '_blank' ? '_blank' : '_self',\n 'noopener,noreferrer',\n );\n }\n : null;\n\n // Covers value changes this component didn't cause itself — undo/redo,\n // a future collaborator's edit — which only notify this *run's* own\n // subscribers (see EditorStore's UPDATE_RUN case), never the block's.\n // Ordinary typing is already covered by handleInput's own call to\n // syncEmptyAttr; this makes every other path to a run's value changing\n // keep the placeholder hint in sync too.\n onValueSynced?.();\n }, [host, run, onValueSynced, hoveredCommentId]);\n\n return null;\n}\n\n/**\n * When the collapsed caret sits right at the boundary between a text run\n * and an atomic (contentEditable={false}) inline chip, native Backspace/\n * Delete would have the *browser* rip that chip's DOM node out on its own —\n * before React ever finds out. React's fiber tree still expects that node\n * to be there, so the next commit's `removeChild` throws\n * (\"NotFoundError: ... not a child of this node\"). The fix is to never let\n * the browser touch an atomic node's DOM directly: detect the adjacency\n * here, `preventDefault`, and delete the run purely through the store so\n * React's own reconciliation is the only thing that ever removes that DOM\n * node.\n *\n * Deliberately does NOT use `previousElementSibling`/`nextElementSibling` to\n * decide whether the neighbor is atomic — holding Backspace/Delete down\n * fires keydowns faster than React necessarily commits the previous\n * removal's DOM update, so a chip that's already gone from the *logical*\n * run list can still be physically sitting in the DOM for one more event.\n * Trusting that lingering DOM node re-triggered a second delete of an\n * already-deleted run and reproduced the same crash intermittently. `runIds`\n * (the block's current prop, always in sync with the store) and `getRun`\n * are the source of truth for \"what's adjacent and is it atomic\"; the DOM\n * is only used to find which run the caret currently sits in.\n */\nfunction findAdjacentAtomicRunId(containerEl, runIds, getRun, backward) {\n const selection = window.getSelection?.();\n if (!selection || !selection.isCollapsed || selection.rangeCount === 0) return null;\n const { anchorNode, anchorOffset } = selection;\n if (!anchorNode || !containerEl.contains(anchorNode)) return null;\n\n const neighborAtomicId = (caretRunId) => {\n const idx = runIds.indexOf(caretRunId);\n if (idx === -1) return null; // caret's run already isn't in the current logical model\n const neighborId = backward ? runIds[idx - 1] : runIds[idx + 1];\n if (!neighborId) return null;\n const neighborRun = getRun(neighborId);\n return neighborRun && neighborRun.type !== 'text' ? neighborId : null;\n };\n\n // Some browsers select an atomic island as a whole unit, anchoring the\n // caret on the container itself with a child-index offset rather than\n // inside an adjacent text node.\n if (anchorNode === containerEl) {\n const idx = backward ? anchorOffset - 1 : anchorOffset;\n const child = containerEl.childNodes[idx];\n const runId = child?.nodeType === 1 ? child.dataset?.runId : undefined;\n if (!runId || runIds.indexOf(runId) === -1) return null;\n const run = getRun(runId);\n return run && run.type !== 'text' ? runId : null;\n }\n\n const el = anchorNode.nodeType === 1 ? anchorNode : anchorNode.parentElement;\n const runEl = el?.closest?.('[data-run-id]');\n if (!runEl || !containerEl.contains(runEl)) return null;\n\n const atBoundary = backward\n ? anchorOffset === 0\n : anchorOffset === (anchorNode.textContent ?? '').length;\n if (!atBoundary) return null;\n\n return neighborAtomicId(runEl.getAttribute('data-run-id'));\n}\n\n/**\n * Real browsers frequently turn arrow-key navigation past an atomic\n * `contentEditable={false}` island into a *non-collapsed* \"select this one\n * node as a unit\" selection (the same way an `<img>` gets selected as a\n * whole), rather than leaving a collapsed caret beside it — this is common\n * on ArrowLeft/ArrowRight approach and on click. `findAdjacentAtomicRunId`\n * only handles the collapsed-caret case; without this check, Backspace/\n * Delete on a whole-node selection falls through to native deletion and\n * reproduces the exact same removeChild crash it was meant to prevent.\n *\n * Same rapid-repeat-keydown caution as findAdjacentAtomicRunId: confirm the\n * selected node's run id is still in `runIds` before trusting it.\n */\nfunction findWhollySelectedAtomicRunId(containerEl, runIds, getRun) {\n const selection = window.getSelection?.();\n if (!selection || selection.isCollapsed || selection.rangeCount === 0) return null;\n const range = selection.getRangeAt(0);\n if (range.startContainer !== range.endContainer) return null;\n if (!containerEl.contains(range.startContainer)) return null;\n if (range.endOffset !== range.startOffset + 1) return null;\n\n const child = range.startContainer.childNodes[range.startOffset];\n const runId = child?.nodeType === 1 ? child.dataset?.runId : undefined;\n if (!runId || runIds.indexOf(runId) === -1) return null;\n const run = getRun(runId);\n return run && run.type !== 'text' ? runId : null;\n}\n\n/**\n * Resolves a Range/StaticRange boundary point to \"which child of\n * containerEl does it fall in, and at what character offset\" — the common\n * currency computeRunsAfterRangeDeletion needs for both boundaries,\n * regardless of whether the point addresses a run's text node directly or\n * the container itself (the same child-index addressing style seen in\n * findAdjacentAtomicRunId/findWhollySelectedAtomicRunId for whole-node\n * selections). Returns null if the point isn't inside any known run.\n */\nfunction resolveRangeBoundary(containerEl, node, offset) {\n if (node === containerEl) return { childIndex: offset, charOffset: null };\n const el = node.nodeType === 1 ? node : node.parentElement;\n const runEl = el?.closest?.('[data-run-id]');\n if (!runEl || !containerEl.contains(runEl)) return null;\n const childIndex = Array.prototype.indexOf.call(containerEl.childNodes, runEl);\n const charOffset =\n node === runEl ? (offset === 0 ? 0 : (runEl.textContent ?? '').length) : offset;\n return { childIndex, charOffset };\n}\n\n/**\n * Typing a replacement character (or composing, or a word/line/cut\n * deletion) over a selection that spans or fully covers an atomic chip\n * goes through `beforeinput`, not a Backspace/Delete keydown — so it's a\n * completely different native-DOM-mutation path than the one\n * findAdjacentAtomicRunId/findWhollySelectedAtomicRunId guard, and hits the\n * exact same removeChild crash if left to native handling. This computes\n * the resulting run list ourselves for any range that touches at least one\n * atomic run, so the caller can preventDefault and apply it through the\n * store instead. Returns null when the range doesn't touch any atomic run\n * at all, so ordinary text edits are completely unaffected — no change in\n * behavior, no new failure mode, for the common case.\n */\nfunction computeRunsAfterRangeDeletion(containerEl, runIds, getRun, range) {\n const start = resolveRangeBoundary(containerEl, range.startContainer, range.startOffset);\n const end = resolveRangeBoundary(containerEl, range.endContainer, range.endOffset);\n if (!start || !end) return null;\n\n const children = Array.from(containerEl.childNodes).filter(\n (n) => n.nodeType === 1 && n.dataset?.runId && runIds.indexOf(n.dataset.runId) !== -1,\n );\n\n let touchesAtomic = false;\n const nextRuns = [];\n let insertionIndex = null;\n\n children.forEach((child, i) => {\n const runId = child.dataset.runId;\n const run = getRun(runId);\n if (!run) return;\n\n const beforeStart = i < start.childIndex;\n const afterEnd = end.charOffset === null ? i >= end.childIndex : i > end.childIndex;\n\n if (beforeStart || afterEnd) {\n nextRuns.push(run);\n return;\n }\n\n const isStartChild = start.charOffset !== null && i === start.childIndex;\n const isEndChild = end.charOffset !== null && i === end.childIndex;\n\n if (run.type !== 'text') {\n touchesAtomic = true;\n if (insertionIndex === null) insertionIndex = nextRuns.length;\n return; // atomic run fully consumed by the range: dropped\n }\n\n const value = run.value ?? '';\n if (isStartChild && isEndChild) {\n const survivor = value.slice(0, start.charOffset) + value.slice(end.charOffset);\n if (survivor) nextRuns.push({ ...run, value: survivor });\n insertionIndex = nextRuns.length;\n } else if (isStartChild) {\n const prefix = value.slice(0, start.charOffset);\n if (prefix) nextRuns.push({ ...run, value: prefix });\n if (insertionIndex === null) insertionIndex = nextRuns.length;\n } else if (isEndChild) {\n const suffix = value.slice(end.charOffset);\n if (suffix) nextRuns.push({ id: genId(), type: 'text', value: suffix, marks: run.marks });\n }\n // else: fully inside the range, dropped entirely\n });\n\n if (!touchesAtomic) return null;\n return { nextRuns, insertionIndex: insertionIndex ?? nextRuns.length };\n}\n\n/** Caret is collapsed and sits at the very first text position of the container's first child. */\nfunction isCaretAtContainerStart(containerEl) {\n const selection = window.getSelection?.();\n if (!selection || !selection.isCollapsed) return false;\n const firstChild = containerEl.firstChild;\n if (!firstChild) return true;\n\n if (selection.anchorNode === containerEl) return selection.anchorOffset === 0;\n\n let probe = firstChild;\n while (probe && probe.firstChild) probe = probe.firstChild;\n if (selection.anchorNode !== probe && selection.anchorNode !== firstChild) return false;\n\n // A first run that's still just the placeholder has no real content yet,\n // so any caret position within it (offset 0 or 1) counts as \"at start\".\n const maxStartOffset =\n probe.nodeType === 3 && probe.textContent === EMPTY_RUN_PLACEHOLDER ? 1 : 0;\n return selection.anchorOffset <= maxStartOffset;\n}\n\n/** Symmetric to isCaretAtContainerStart: caret is collapsed at the very last text position of the container's last child. */\nfunction isCaretAtContainerEnd(containerEl) {\n const selection = window.getSelection?.();\n if (!selection || !selection.isCollapsed) return false;\n const lastChild = containerEl.lastChild;\n if (!lastChild) return true;\n\n if (selection.anchorNode === containerEl)\n return selection.anchorOffset >= containerEl.childNodes.length;\n\n let probe = lastChild;\n while (probe && probe.lastChild) probe = probe.lastChild;\n if (selection.anchorNode !== probe && selection.anchorNode !== lastChild) return false;\n\n const textLength = probe.nodeType === 3 ? (probe.textContent ?? '').length : 0;\n return selection.anchorOffset >= textLength;\n}\n\n/**\n * Resolves the sibling of `blockId` in `direction` ('backward' | 'forward')\n * only if it's a non-editable/contentless block (image/video/audio/file\n * embed, divider, ...) — a real leaf/container with actual content returns\n * null here, since Backspace/Delete into *that* is ordinary merge/no-op\n * territory (handled by onBackspaceAtStart), not this select-then-delete\n * flow.\n */\nfunction findAdjacentContentlessSiblingId(store, blockId, direction) {\n const block = store.getBlock(blockId);\n const parent = store.getBlock(block?.parentId);\n if (!parent) return null;\n const index = parent.contentIds.indexOf(blockId);\n const adjacentIndex = direction === 'backward' ? index - 1 : index + 1;\n if (adjacentIndex < 0 || adjacentIndex >= parent.contentIds.length) return null;\n const adjacentId = parent.contentIds[adjacentIndex];\n return isContentlessBlock(store, store.getBlock(adjacentId)) ? adjacentId : null;\n}\n\n/**\n * Dispatches one run's id to the right renderer: TextRunSpan for text, the\n * inline registry's component otherwise. Also passes `blockId` (the\n * containing leaf block — a paragraph, or a table cell) down to atomic\n * components — runs themselves have no parent back-reference in the store,\n * so this is the only place that can hand it to them. Most inline types\n * ignore it (select/date/custom field types are self-contained); it exists for types\n * like a table's select column that need to resolve their own containing\n * cell/row/table to read shared, column-level state.\n */\nfunction RunNode({ id, blockId, host, inlineRegistry, onValueSynced }) {\n const run = useRun(id);\n if (!run) return null;\n if (run.type === 'text') return <TextRunSpan id={id} host={host} onValueSynced={onValueSynced} />;\n\n const entry = inlineRegistry?.get(run.type);\n if (!entry) {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.warn(`[block-editor] No inline type registered for \"${run.type}\" (run: ${id})`);\n }\n return null;\n }\n const Component = entry.component;\n return <Component id={id} blockId={blockId} />;\n}\n\n/**\n * Creates (once) or reuses the persistent DOM element that hosts one run's\n * content — `data-run-id`, and for atomic (non-text) runs `contentEditable=\n * \"false\"`, live on this element, not on anything React renders into it.\n * The host is looked up directly from the store (not the `useRun` hook)\n * because this only needs to run once per id, at creation time — a run's\n * type never changes after creation (a semantic change always creates a\n * new run with a new id elsewhere in this codebase), so there's nothing to\n * keep reactive here.\n */\nfunction getOrCreateHost(hostsMap, store, id) {\n let host = hostsMap.get(id);\n if (!host) {\n host = document.createElement('span');\n host.dataset.runId = id;\n const run = store.getRun(id);\n if (run && run.type !== 'text') host.setAttribute('contenteditable', 'false');\n hostsMap.set(id, host);\n }\n return host;\n}\n\n/**\n * Renders every run of a leaf block (paragraph/heading/tableCell's own\n * contentIds, or a listItem's props.titleRunIds) inside ONE shared\n * contentEditable region — replacing the old one-contentEditable-per-run\n * model. This is what lets the browser's native selection/typing/cursor\n * movement work across formatting boundaries and atomic inline elements\n * (a select/date chip), instead of each run being its own disconnected\n * editable island.\n *\n * Every run — text or atomic — gets a persistent \"host\" DOM element that\n * *this component creates, positions, and removes imperatively* (see\n * hostsRef/getOrCreateHost and the layout effect below); React only ever\n * renders each run's *content* into its host via `createPortal`. React's\n * own fiber tree therefore never owns the operation of inserting or\n * removing a run's DOM node relative to its siblings — that's the same\n * technique Lexical uses for its \"decorator\" nodes. It's what closes the\n * \"NotFoundError: removeChild ... not a child of this node\" crash for\n * good: that error was always React's commit phase trying to remove a\n * host node the *browser* had already ripped out natively (via Backspace/\n * Delete, typing over a selection, word-delete, autocorrect, IME, drag —\n * there is no finite list of native paths that can do this). Since React\n * no longer has a fiber responsible for that removal at all, no native\n * mutation of a run's DOM node can ever race against — or be duplicated\n * by — a React-driven one.\n *\n * `runIds` must come from the caller's own `useBlock` subscription\n * (block.contentIds for paragraph/heading/tableCell, or\n * block.props.titleRunIds for a listItem) — that's what keeps this\n * component reactive to *structural* changes (e.g. a mark-toggle split),\n * while each individual run's *value* reactivity is owned by RunNode/\n * TextRunSpan subscribing to that one run id themselves.\n */\nexport function EditableBlockContent({\n blockId,\n runIds,\n dir = 'auto',\n onEnter,\n onBackspaceAtStart,\n onDeleteAtEnd,\n onArrowUp,\n onArrowDown,\n onTab,\n onShiftTab,\n onAutoformat,\n}) {\n const store = useEditorStore();\n const inlineRegistry = useInlineRegistry();\n const commentAuthorId = useCommentAuthorId();\n const { getSelectedBlockId, setSelectedBlockId } = useSelectedBlock();\n const containerRef = useRef(null);\n // IME composition (CJK/Korean/etc.) produces a sequence of transient,\n // uncommitted `input` events while the user is still choosing characters.\n // Reconciling — and possibly rewriting DOM text — mid-composition would\n // fight the browser/OS IME UI and can cut a composition session short.\n // Defer reconciliation until compositionend commits the final text.\n const isComposingRef = useRef(false);\n const hostsRef = useRef(new Map()); // runId -> persistent host DOM element (see getOrCreateHost)\n\n // Keeps containerRef's *actual* DOM children (the hosts) in the same\n // membership/order as runIds — the only place any run's DOM node is ever\n // inserted or removed. Runs on every runIds change (structural edits:\n // insert/remove/reorder/split); ordinary text edits don't change runIds\n // at all, so this doesn't run on every keystroke.\n useLayoutEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const liveIds = new Set(runIds);\n for (const [id, host] of hostsRef.current) {\n if (!liveIds.has(id)) {\n host.remove();\n hostsRef.current.delete(id);\n }\n }\n\n let previous = null;\n for (const id of runIds) {\n const host = hostsRef.current.get(id);\n if (!host) continue; // created synchronously during render, in the map already\n const expectedNext = previous ? previous.nextSibling : container.firstChild;\n if (expectedNext !== host) container.insertBefore(host, expectedNext);\n previous = host;\n }\n }, [runIds]);\n\n const handleInput = useCallback(() => {\n if (isComposingRef.current) return;\n const container = containerRef.current;\n if (!container) return;\n const currentRuns = runIds.map((id) => store.getRun(id)).filter(Boolean);\n const {\n runs: nextRuns,\n changed,\n onlyValueChanges,\n } = reconcileDomToRuns(container, currentRuns);\n if (!changed) return;\n\n if (onlyValueChanges) {\n nextRuns.forEach((run, i) => {\n if (run !== currentRuns[i]) store.applyOperation(updateRun(run.id, { value: run.value }));\n });\n // A markdown shortcut (e.g. \"1. \" -> ordered list) always types into a\n // single existing run, never a structural DOM change, so it only ever\n // applies on this branch. On a match, blockId's block was just\n // replaced by a different type — the container/wrapper this callback\n // is running inside of is about to unmount, so there's nothing left\n // here to sync.\n if (onAutoformat?.(nextRuns)) return;\n } else {\n // Same \"never zero runs\" guard as removeRun — belt-and-suspenders,\n // since reconcileDomToRuns normally never drops a matched run.\n store.applyOperation(\n setBlockRuns(\n blockId,\n nextRuns.length ? nextRuns : [{ id: genId(), type: 'text', value: '', marks: {} }],\n ),\n );\n }\n syncEmptyAttr(container, nextRuns);\n }, [store, blockId, runIds, onAutoformat]);\n\n const syncEmptyFromStore = useCallback(() => {\n syncEmptyAttr(containerRef.current, runIds.map((id) => store.getRun(id)).filter(Boolean));\n }, [store, runIds]);\n\n const handleCompositionStart = useCallback(() => {\n isComposingRef.current = true;\n }, []);\n\n const handleCompositionEnd = useCallback(() => {\n isComposingRef.current = false;\n handleInput(); // reconcile now that the composed text has been committed\n }, [handleInput]);\n\n const removeRun = useCallback(\n (runId) => {\n const currentRuns = runIds.map((id) => store.getRun(id)).filter(Boolean);\n const nextRuns = currentRuns.filter((run) => run.id !== runId);\n // Never leave the block with zero runs: an empty contentEditable\n // region (no children at all) isn't a valid caret anchor in most\n // browsers, so the very next keystroke lands on the *container*\n // instead of any run, producing a stray untracked text node that\n // reconcileDomToRuns can't ever match back to an existing run —\n // every keystroke after that mints a brand new run+host instead of\n // updating one in place (the \"characters double\" bug).\n store.applyOperation(\n setBlockRuns(\n blockId,\n nextRuns.length ? nextRuns : [{ id: genId(), type: 'text', value: '', marks: {} }],\n ),\n );\n },\n [store, blockId, runIds],\n );\n\n /**\n * The common convention for a non-editable neighbor (image/video/\n * audio/file embed, divider): the first Backspace/Delete that reaches it\n * only selects/highlights it (see the be-block-selected class toggled by\n * setSelectedBlockId); a second press while it's already selected is\n * what actually removes it. Neither press ever touches or refocuses\n * *this* block — the caret never moves, since only the neighbor is\n * selected or removed, not anything in the block the user is actually\n * typing in.\n */\n const selectOrDeleteContentlessNeighbor = useCallback(\n (neighborId) => {\n if (getSelectedBlockId() === neighborId) {\n store.applyOperation(removeBlock(neighborId));\n setSelectedBlockId(null);\n } else {\n setSelectedBlockId(neighborId);\n }\n },\n [store, getSelectedBlockId, setSelectedBlockId],\n );\n\n /**\n * Catches every native content-editable mutation that can rip an atomic\n * run's DOM node out directly — not just Backspace/Delete, but typing a\n * replacement character over a selection that spans a chip, Ctrl/Cmd+\n * Backspace word/line delete, and cut — all of which fire `beforeinput`\n * with the exact range about to be affected (`getTargetRanges()`, falling\n * back to the live selection where unsupported). When that range touches\n * an atomic run, this computes the resulting content itself and applies\n * it through the store, so the browser never gets to mutate that node.\n * Ordinary text-only edits are untouched: computeRunsAfterRangeDeletion\n * returns null for them and this handler is a no-op, leaving the existing\n * fast-path onInput reconciliation to handle typing exactly as before.\n */\n const handleBeforeInput = useCallback(\n (event) => {\n if (isComposingRef.current) return;\n\n // A native `beforeinput` (or `input`, elsewhere) fired by a real form\n // control nested inside an atomic run's own host (the checkbox\n // label's <input>, a date chip's <input type=\"date\">, ...) still\n // bubbles up through this contenteditable=true container, even\n // though that host is contenteditable=\"false\" and typing into it has\n // nothing to do with the surrounding text flow. Left unguarded, the\n // fallback to window.getSelection() below can pick up a *stale*\n // range still pointing at that atomic run's position from before\n // focus moved into its nested control, get misread as \"this range\n // touches an atomic run,\" and rewrite it clean out of the block —\n // the exact \"typing in the checkbox's label deletes the checkbox\"\n // bug this guard closes. That nested control owns its own value via\n // its own onChange; this container-level pipeline must stay out of\n // it entirely.\n if (event.target instanceof Node) {\n const el = event.target.nodeType === 1 ? event.target : event.target.parentElement;\n if (el?.closest?.('[contenteditable=\"false\"]')) return;\n }\n\n const inputType = event.inputType ?? '';\n const isDelete = inputType.startsWith('delete');\n const isReplaceTyped = inputType === 'insertText' || inputType === 'insertReplacementText';\n if (!isDelete && !isReplaceTyped) return;\n\n const container = containerRef.current;\n if (!container) return;\n\n const targetRanges = event.getTargetRanges?.();\n const selection = window.getSelection?.();\n const range = targetRanges?.[0] ?? (selection?.rangeCount ? selection.getRangeAt(0) : null);\n if (!range) return;\n if (!container.contains(range.startContainer) || !container.contains(range.endContainer))\n return;\n\n const result = computeRunsAfterRangeDeletion(\n container,\n runIds,\n (id) => store.getRun(id),\n range,\n );\n if (!result) return; // no atomic run in range: let native/existing handling proceed unchanged\n\n event.preventDefault();\n let { nextRuns, insertionIndex } = result;\n\n let focusRunId = null;\n let focusAtStart = false;\n\n if (isReplaceTyped && event.data) {\n const typedRun = { id: genId(), type: 'text', value: event.data, marks: {} };\n nextRuns = [\n ...nextRuns.slice(0, insertionIndex),\n typedRun,\n ...nextRuns.slice(insertionIndex),\n ];\n focusRunId = typedRun.id;\n focusAtStart = false;\n } else if (insertionIndex > 0) {\n focusRunId = nextRuns[insertionIndex - 1]?.id;\n focusAtStart = false;\n } else if (nextRuns.length > 0) {\n focusRunId = nextRuns[0].id;\n focusAtStart = true;\n }\n\n const finalRuns = nextRuns.length\n ? nextRuns\n : [{ id: genId(), type: 'text', value: '', marks: {} }];\n store.applyOperation(setBlockRuns(blockId, finalRuns));\n\n const landingRunId = focusRunId ?? finalRuns[0].id;\n if (focusAtStart) focusRunStart(landingRunId);\n else focusRunEnd(landingRunId);\n },\n [store, blockId, runIds],\n );\n\n // React's `onBeforeInput` JSX prop does NOT correspond to the native\n // `beforeinput` event — it's a legacy pre-InputEvent-spec polyfill\n // synthesized from keypress/textInput/composition events, so it never\n // fires for Backspace/Delete/word-delete and carries no `inputType` or\n // `getTargetRanges()`. Attaching a real native listener directly (same\n // pattern useEditorKeyboardShortcuts uses for its own native handling)\n // is the only way to actually observe and cancel these before the\n // browser mutates an atomic run's DOM node itself.\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return undefined;\n container.addEventListener('beforeinput', handleBeforeInput);\n return () => container.removeEventListener('beforeinput', handleBeforeInput);\n }, [handleBeforeInput]);\n\n const handleKeyDown = useCallback(\n (event) => {\n // While composing, Enter/Backspace/arrows are the IME's own candidate-\n // selection UI (confirming a suggestion, moving between candidates) —\n // must not also trigger this block's own Enter/merge/navigation.\n if (isComposingRef.current) return;\n\n if (event.key === 'Enter' && onEnter) {\n event.preventDefault();\n onEnter(event);\n return;\n }\n if (event.key === 'Backspace') {\n const container = containerRef.current;\n const wholeId =\n container && findWhollySelectedAtomicRunId(container, runIds, store.getRun.bind(store));\n if (wholeId) {\n event.preventDefault();\n removeRun(wholeId);\n return;\n }\n const atomicId =\n container && findAdjacentAtomicRunId(container, runIds, store.getRun.bind(store), true);\n if (atomicId) {\n event.preventDefault();\n removeRun(atomicId);\n return;\n }\n if (container && isCaretAtContainerStart(container)) {\n // Only offer the select-then-delete flow for a non-editable\n // neighbor when THIS block still has real content of its own —\n // an empty current block (e.g. a trailing blank paragraph right\n // after an image) must disappear on its own first, exactly like\n // Backspace on any other empty block, before the neighbor is\n // offered at all. Otherwise the very first Backspace on an empty\n // paragraph would highlight the image instead of removing the\n // paragraph, which is backwards. onBackspaceAtStart (the normal\n // merge/delete path) handles the empty case, and itself lands on\n // selecting the neighbor via focusAfterMerge once there's\n // nothing left of the current block to focus back into.\n const isCurrentEmpty = isRunsEmpty(store, runIds);\n if (!isCurrentEmpty) {\n const neighborId = findAdjacentContentlessSiblingId(store, blockId, 'backward');\n if (neighborId) {\n event.preventDefault();\n selectOrDeleteContentlessNeighbor(neighborId);\n return;\n }\n }\n // Always claim this keypress once we know it's Backspace-at-\n // absolute-start being handled here (native backspace has nothing\n // to do at this exact position anyway, so this is a no-op for the\n // browser) — this is what lets the global handler in\n // useEditorKeyboardShortcuts distinguish \"a neighbor was *just*\n // selected as part of *this* keypress\" (defaultPrevented is now\n // true, so it must NOT also delete that neighbor on this same\n // press) from \"a neighbor was already selected from a *previous*\n // keypress\" (a fresh event, defaultPrevented starts false again,\n // so the global handler correctly deletes it then).\n event.preventDefault();\n if (onBackspaceAtStart) onBackspaceAtStart(event);\n }\n return;\n }\n if (event.key === 'Delete') {\n const container = containerRef.current;\n const wholeId =\n container && findWhollySelectedAtomicRunId(container, runIds, store.getRun.bind(store));\n if (wholeId) {\n event.preventDefault();\n removeRun(wholeId);\n return;\n }\n const atomicId =\n container && findAdjacentAtomicRunId(container, runIds, store.getRun.bind(store), false);\n if (atomicId) {\n event.preventDefault();\n removeRun(atomicId);\n return;\n }\n if (container && isCaretAtContainerEnd(container)) {\n const neighborId = findAdjacentContentlessSiblingId(store, blockId, 'forward');\n if (neighborId) {\n event.preventDefault();\n selectOrDeleteContentlessNeighbor(neighborId);\n return;\n }\n if (onDeleteAtEnd) onDeleteAtEnd(event);\n }\n return;\n }\n if (event.key === 'ArrowUp' && onArrowUp) {\n event.preventDefault();\n onArrowUp(event);\n return;\n }\n if (event.key === 'ArrowDown' && onArrowDown) {\n event.preventDefault();\n onArrowDown(event);\n return;\n }\n if (event.key === 'Tab') {\n if (event.shiftKey && onShiftTab) {\n event.preventDefault();\n onShiftTab(event);\n } else if (!event.shiftKey && onTab) {\n event.preventDefault();\n onTab(event);\n }\n }\n },\n [\n onEnter,\n onBackspaceAtStart,\n onDeleteAtEnd,\n onArrowUp,\n onArrowDown,\n onTab,\n onShiftTab,\n removeRun,\n selectOrDeleteContentlessNeighbor,\n runIds,\n blockId,\n store,\n ],\n );\n\n return (\n <>\n <span\n ref={containerRef}\n className=\"be-editable\"\n dir={dir}\n contentEditable\n suppressContentEditableWarning\n onInput={handleInput}\n onCompositionStart={handleCompositionStart}\n onCompositionEnd={handleCompositionEnd}\n onKeyDown={handleKeyDown}\n >\n {runIds.map((id) => {\n const host = getOrCreateHost(hostsRef.current, store, id);\n return createPortal(\n <RunNode\n key={id}\n id={id}\n blockId={blockId}\n host={host}\n inlineRegistry={inlineRegistry}\n onValueSynced={syncEmptyFromStore}\n />,\n host,\n );\n })}\n </span>\n <LinkHoverCard containerRef={containerRef} store={store} />\n <CommentPopover containerRef={containerRef} store={store} authorId={commentAuthorId} />\n </>\n );\n}\n","import { insertBlock } from '../../store/operations.js';\nimport { createTextLeafBlock } from './leafBlockFactory.js';\n\n/**\n * Call after any operation that might have deleted the *last* block under\n * the document root. Every real editor keeps at least one empty paragraph\n * rather than allowing a genuinely blank document — a page with zero\n * children isn't just a UX dead end (nothing to click into), it also\n * breaks caret placement entirely, since there's no contentEditable region\n * left anywhere for the browser to anchor a click or keystroke in.\n *\n * No-op (returns null) if the root already has content. `store` may be a\n * plain EditorStore or a History wrapper — either way this issues its own\n * `applyOperation` call, so call it *after* whatever batch removed the\n * block, not folded into that same batch (the fallback should only ever\n * fire if the removal actually emptied the root, which isn't knowable\n * until after it's applied).\n */\nexport function ensureRootNonEmpty(store) {\n const rootId = store.getRootId();\n const root = store.getBlock(rootId);\n if (!root || root.contentIds.length > 0) return null;\n\n const { block, runs } = createTextLeafBlock('paragraph')(rootId);\n store.applyOperation(insertBlock(block, rootId, 0, { blocks: [block], runs }));\n return block.id;\n}\n","import { removeBlock, setBlockContentIds, insertBlock } from '../../store/operations.js';\nimport { isContentlessBlock } from './contentless.js';\nimport { createTextLeafBlock } from './leafBlockFactory.js';\nimport { ensureRootNonEmpty } from './ensureRootNonEmpty.js';\n\n// Container types that should vanish entirely once their one-and-only\n// content block is emptied out, rather than leaving an empty box behind —\n// e.g. an empty callout with nothing typed into it. Deliberately does NOT\n// include layoutColumn: removing one column would break an N-column\n// layout's symmetry, which isn't the same situation as a callout with\n// nothing left to say.\nconst UNWRAP_WHEN_SOLE_CHILD_EMPTIED = new Set(['callout']);\n\n// Block types whose contentIds are always run ids (never child blocks) and\n// whose only real difference is presentational (heading level, or a quote's\n// left border, vs plain paragraph) — merging across these keeps the\n// surviving (previous) block's own type/props untouched, so merging a\n// paragraph up into a heading stays a heading, backspacing into a quote\n// keeps it a quote, and vice versa. Deliberately does NOT include\n// tableCell/listItem: those have distinct structural roles (a cell belongs\n// to a row; a list item carries indentation/marker state) where \"just\n// concatenate the text and keep whichever type was already there\" isn't\n// the right semantics.\nexport const MERGEABLE_TEXT_TYPES = new Set(['paragraph', 'heading', 'blockquote']);\n\nexport function canMergeTypes(prevType, blockType) {\n return (\n prevType === blockType ||\n (MERGEABLE_TEXT_TYPES.has(prevType) && MERGEABLE_TEXT_TYPES.has(blockType))\n );\n}\n\n/**\n * Backspace-at-start-of-block behavior:\n * 1. If the previous sibling is contentless (e.g. a divider), delete *it*\n * first and stay put — matches the familiar \"backspace clears the\n * nearest obstacle\" convention, and means a second\n * backspace then merges into whatever's before the divider.\n * 2. Else if this block is empty, delete it.\n * 3. Else merge its inline content onto the end of the previous sibling —\n * same type, or both are in MERGEABLE_TEXT_TYPES (paragraph/heading, in\n * either direction) — and delete the now-empty shell. Any other type\n * pairing (a table, a list item, ...) is left alone; merging into those\n * doesn't have well-defined semantics in v1.\n *\n * 4. Special case when there's *nothing before this block at all* (it's\n * first in its container, so there's no \"merge into\" target): a block\n * with real content still does nothing (matches every other editor —\n * Backspace at the absolute start of the first line is a no-op when\n * there's something to preserve). But an *empty* leading block should\n * still go away — removed outright if something follows it, or, if\n * it's the only block left, replaced with a blank paragraph (same\n * \"never leave nothing to click into\" fallback as\n * exitListItemToParagraph / ensureRootNonEmpty). Without this, an empty\n * heading/paragraph that happens to be first (very often *the only\n * block left* after deleting everything else) could never be removed\n * at all.\n *\n * All of this is one atomic undo step: if `store` is a History instance\n * (has performBatch), the ops are grouped; a plain EditorStore just applies\n * them in sequence (no undo tracking to group).\n *\n * Returns the id of the block that should receive focus afterward, or null\n * if there was nothing to do.\n */\nexport function mergeWithPreviousOrDelete(store, blockId) {\n const block = store.getBlock(blockId);\n if (!block) return null;\n\n const parent = store.getBlock(block.parentId);\n const index = parent.contentIds.indexOf(blockId);\n const isEmpty =\n block.contentIds.length === 0 ||\n (block.contentIds.length === 1 && isBlankRun(store, block.contentIds[0]));\n\n if (index <= 0) {\n if (!isEmpty) return null; // real content, nothing before it: no-op, as every other editor does\n\n if (parent.contentIds.length > 1) {\n applyOps(store, [removeBlock(blockId)]);\n return store.getBlock(parent.id).contentIds[0]; // whatever's now first\n }\n\n // The sole (now-empty) child of a container that should disappear once\n // there's nothing left in it (e.g. a callout) — remove the CONTAINER\n // itself, not just this child, instead of leaving an empty box behind.\n if (UNWRAP_WHEN_SOLE_CHILD_EMPTIED.has(parent.type)) {\n return unwrapEmptyContainer(store, parent);\n }\n\n if (block.type === 'paragraph') return null; // already the fallback shape; nothing to do\n\n const { block: fallbackBlock, runs } = createTextLeafBlock('paragraph')(parent.id);\n applyOps(store, [\n insertBlock(fallbackBlock, parent.id, index, { blocks: [fallbackBlock], runs }),\n removeBlock(blockId),\n ]);\n return fallbackBlock.id;\n }\n\n const prevId = parent.contentIds[index - 1];\n const prev = store.getBlock(prevId);\n\n // An empty CURRENT block always goes first, even when the previous\n // sibling is a non-editable block (divider/embed) — Backspace on a\n // trailing empty paragraph should make the empty paragraph disappear\n // (ordinary empty-block behavior) before anything about the\n // non-editable neighbor is offered at all. Checking isContentlessBlock\n // first here would instead delete the neighbor immediately, one\n // Backspace too early. (In the normal keyboard path this is actually\n // decided one layer up, in EditableBlockContent, which only offers the\n // neighbor select-then-delete flow once the current block has real\n // content left — this ordering just keeps the pure function's own\n // behavior consistent for direct callers.)\n if (isEmpty) {\n applyOps(store, [removeBlock(blockId)]);\n return prevId;\n }\n\n if (isContentlessBlock(store, prev)) {\n applyOps(store, [removeBlock(prevId)]);\n return blockId; // stay put; the obstacle is gone, no DOM remount needed\n }\n\n if (!prev || !canMergeTypes(prev.type, block.type)) return null;\n\n const mergedContentIds = [...prev.contentIds, ...block.contentIds];\n applyOps(store, [\n setBlockContentIds(prevId, mergedContentIds),\n setBlockContentIds(blockId, []), // detach moved runs before deleting the shell\n removeBlock(blockId),\n ]);\n return prevId;\n}\n\nfunction isBlankRun(store, runId) {\n const run = store.getRun(runId);\n return !run || (run.value ?? '') === '';\n}\n\n/**\n * Removes `container` itself (e.g. a callout whose only child was just\n * emptied out), focusing whatever now sits where it used to — its previous\n * sibling, or else its next sibling, or else (the container was the only\n * thing under the document root) whatever ensureRootNonEmpty falls back\n * to, so there's always still somewhere to land the caret.\n */\nfunction unwrapEmptyContainer(store, container) {\n const grandParent = store.getBlock(container.parentId);\n if (!grandParent) return null;\n const idx = grandParent.contentIds.indexOf(container.id);\n const prevId = idx > 0 ? grandParent.contentIds[idx - 1] : null;\n const nextId =\n idx !== -1 && idx < grandParent.contentIds.length - 1 ? grandParent.contentIds[idx + 1] : null;\n\n applyOps(store, [removeBlock(container.id)]);\n const fallbackId = ensureRootNonEmpty(store);\n return prevId ?? nextId ?? fallbackId;\n}\n\nfunction applyOps(store, ops) {\n if (typeof store.performBatch === 'function') {\n store.performBatch(ops);\n } else {\n for (const op of ops) store.applyOperation(op);\n }\n}\n","import { focusRunEnd } from '../../react/focusRun.js';\nimport { resolveBlockLastRun } from './navigationCommands.js';\n\n/**\n * Resolves what to do with focus after a merge/delete operation returns\n * `focusBlockId` — normally focus the end of its last *focusable* run, but\n * if there's truly nothing to put a caret in (e.g. the current block's own\n * empty content was just deleted, landing \"focus\" on a divider/embed\n * sibling), select/highlight it instead, via the exact same select-then-\n * delete flow as backspacing straight into a non-editable neighbor (see\n * EditableBlockContent's selectOrDeleteContentlessNeighbor) — this is what\n * makes that flow reachable at all for \"empty paragraph right after an\n * image\": the empty paragraph is deleted first (ordinary empty-block\n * Backspace), *then* the image becomes selected, rather than the image\n * jumping straight to selected before the empty paragraph itself ever\n * goes away.\n *\n * Uses resolveBlockLastRun (not focusBlockId's own contentIds directly) so\n * this also does the right thing when focusBlockId is a *container* — e.g.\n * backspacing away the block right after a callout should land the caret\n * at the end of the callout's own last child, not fail silently because a\n * container's contentIds are child block ids, not run ids.\n */\nexport function focusAfterMerge(store, focusBlockId, currentBlockId, setSelectedBlockId) {\n if (!focusBlockId || focusBlockId === currentBlockId) return;\n const lastRunId = resolveBlockLastRun(store, focusBlockId);\n if (lastRunId) {\n focusRunEnd(lastRunId);\n return;\n }\n setSelectedBlockId(focusBlockId);\n // The current block (whose empty content just got deleted) is gone from\n // the DOM entirely, so — unlike EditableBlockContent's own select-then-\n // delete flow, which deliberately never steals focus away from a block\n // that's still there — nothing else has focus here. Move it onto the\n // now-selected non-editable block directly (divider/embed both set\n // tabIndex={-1} for exactly this) so the surface's own keydown listener\n // keeps capturing the next Backspace/Delete.\n requestAnimationFrame(() => {\n document.querySelector(`[data-block-id=\"${focusBlockId}\"]`)?.focus();\n });\n}\n","/**\n * Resolves the `dir` attribute a block's editable region/wrapper should\n * render with: the block's own `props.dir` override, else the document\n * root's `props.dir` (a document-wide default), else `'auto'`.\n *\n * `'auto'` is the actual workhorse for multi-language support, not just a\n * fallback: it lets the browser's own Unicode bidi algorithm detect\n * direction per block from its first strong character, which is exactly\n * what a document mixing LTR and RTL blocks (e.g. an English heading over\n * an Arabic paragraph) needs with zero configuration. The explicit\n * override exists for what `auto` can't infer on its own — most commonly\n * an empty block with no text yet to detect a direction from.\n */\nexport function resolveBlockDir(store, block) {\n if (!block) return 'auto';\n if (block.props?.dir) return block.props.dir;\n const root = store.getBlock(store.getRootId());\n return root?.props?.dir ?? 'auto';\n}\n","import { updateRun } from '../../store/operations.js';\nimport { convertBlockType } from '../shared/convertBlockType.js';\nimport { focusRunStart } from '../../react/focusRun.js';\n\nfunction applyOps(store, ops) {\n if (typeof store.performBatch === 'function') store.performBatch(ops);\n else for (const op of ops) store.applyOperation(op);\n}\n\n// Markdown shortcuts: a recognized prefix, typed at the\n// very start of an otherwise-plain paragraph, converts the block once the\n// pattern is complete — most need a trailing trigger space (\"# \", \"- \",\n// \"1. \", \"> \", \"[] \"), matching every other editor's convention that the\n// space itself commits the conversion (so \"#\" alone, mid-typing, doesn't\n// convert early); \"```\" has no trailing space since there's nothing after\n// the third backtick to wait for.\n//\n// The trigger character class is `[ ]`, not a literal \" \" — browsers\n// commonly insert a *non-breaking* space (U+00A0) instead of an ordinary\n// one for a trailing space in a contentEditable region (so it doesn't get\n// collapsed away by normal HTML whitespace rules), and every one of these\n// shortcuts' trigger is exactly that: the last character in the region at\n// the moment it's typed. Matching only a literal \" \" meant none of these\n// ever fired against real typed input, only against text set up directly\n// in a test — jsdom doesn't reproduce this browser quirk, which is why it\n// wasn't caught there.\nconst RULES = [\n { re: /^(#{1,3})[ ]$/, type: 'heading', props: (m) => ({ level: m[1].length }) },\n { re: /^[-*][ ]$/, type: 'listItem', props: () => ({ ordered: false, titleRunIds: [] }) },\n { re: /^\\d+\\.[ ]$/, type: 'listItem', props: () => ({ ordered: true, titleRunIds: [] }) },\n {\n re: /^\\[\\][ ]$/,\n type: 'listItem',\n props: () => ({ ordered: false, checked: false, titleRunIds: [] }),\n },\n { re: /^>[ ]$/, type: 'blockquote', props: () => ({}) },\n { re: /^```$/, type: 'code', props: () => ({ language: 'plaintext' }) },\n];\n\n/**\n * Checks the block's current run list against every rule above and, on a\n * match, converts it: strips the matched prefix from the first run's text\n * and swaps the block for the matching type via convertBlockType, carrying\n * over the (now-stripped) run so any text/marks typed after the prefix\n * survive — all as one atomic undo step. Only fires when the block's\n * ENTIRE content is a single plain text run (no marks/atomic runs mixed in\n * yet); typing the same characters mid-sentence, or spanning multiple\n * runs, never triggers it — scoped to a fresh, still-plain line.\n *\n * `runs` is the block's just-committed run list (see EditableBlockContent's\n * handleInput, onlyValueChanges path — a markdown shortcut is always typed\n * into a single existing run, never a structural DOM change). Returns\n * `true` if a conversion happened (the caller should treat blockId as gone\n * — a new block now occupies its place).\n */\nexport function applyMarkdownShortcut(store, blockId, runs) {\n if (runs.length !== 1 || runs[0].type !== 'text') return false;\n const value = runs[0].value ?? '';\n\n for (const rule of RULES) {\n const match = rule.re.exec(value);\n if (!match) continue;\n\n const strippedValue = value.slice(match[0].length);\n const { ops } = convertBlockType(store, blockId, rule.type, rule.props(match), [runs[0].id]);\n applyOps(store, [updateRun(runs[0].id, { value: strippedValue }), ...ops]);\n focusRunStart(runs[0].id);\n return true;\n }\n return false;\n}\n","import { useCallback } from 'react';\nimport { EditableBlockContent } from '../../react/EditableBlockContent.jsx';\nimport { useBlock } from '../../react/useBlock.js';\nimport {\n useEditorStore,\n useSelectedBlock,\n useBlockClassName,\n} from '../../react/EditorProvider.jsx';\nimport {\n insertSiblingSplitAtCaretAndFocus,\n insertSiblingAfterAndFocus,\n} from '../shared/blockCommands.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\nimport { mergeWithPreviousOrDelete } from '../shared/mergeCommands.js';\nimport { isRunsEmpty } from '../shared/blockEmpty.js';\nimport { focusAfterMerge } from '../shared/focusAfterMerge.js';\nimport { focusRunEnd } from '../../react/focusRun.js';\nimport { focusAdjacentBlock } from '../shared/navigationCommands.js';\nimport { resolveBlockDir } from '../shared/resolveBlockDir.js';\nimport { applyMarkdownShortcut } from './markdownShortcuts.js';\n\n// Container types a nested paragraph can \"exit\" out of on an empty last\n// line — pressing Enter on a blank final paragraph inside one of these\n// creates the new paragraph as a SIBLING OF THE CONTAINER ITSELF (back out\n// at the outer level), instead of yet another paragraph nested inside it.\n// This is how you get out of a callout/toggle heading's body to keep\n// writing in the main document — there's no other affordance for it, so\n// without this an empty trailing line is a dead end.\nconst EXITABLE_PARENT_TYPES = new Set(['callout', 'toggleHeading']);\n\nexport function ParagraphBlock({ id }) {\n const store = useEditorStore();\n const block = useBlock(id);\n const { setSelectedBlockId } = useSelectedBlock();\n\n const handleEnter = useCallback(() => {\n const parent = store.getBlock(block?.parentId);\n const isEmpty = isRunsEmpty(store, block?.contentIds ?? []);\n const isLastChild = Boolean(parent) && parent.contentIds[parent.contentIds.length - 1] === id;\n\n if (isEmpty && isLastChild && EXITABLE_PARENT_TYPES.has(parent?.type)) {\n insertSiblingAfterAndFocus(store, parent.id, createTextLeafBlock('paragraph'));\n return;\n }\n\n insertSiblingSplitAtCaretAndFocus(\n store,\n id,\n block?.contentIds ?? [],\n createTextLeafBlock('paragraph'),\n );\n }, [store, id, block]);\n\n const handleBackspaceAtStart = useCallback(() => {\n const parent = store.getBlock(block?.parentId);\n const isEmpty = isRunsEmpty(store, block?.contentIds ?? []);\n const isSoleChild = parent?.contentIds?.length === 1 && parent.contentIds[0] === id;\n\n if (isEmpty && isSoleChild && parent?.type === 'toggleHeading') {\n // Pop back out to the toggle heading's own title instead of deleting\n // anything here — mirrors how a nested list item's empty Backspace\n // pops out one level at a time. Backspacing *again* from the title\n // (now that focus is there) is what actually removes an entirely\n // blank toggle heading, via mergeToggleHeadingOrNoop — this is the\n // first of those two steps, not a dead end.\n const titleRunIds = parent.props?.titleRunIds ?? [];\n const lastTitleRunId = titleRunIds[titleRunIds.length - 1];\n if (lastTitleRunId) focusRunEnd(lastTitleRunId);\n return;\n }\n\n const focusBlockId = mergeWithPreviousOrDelete(store, id);\n focusAfterMerge(store, focusBlockId, id, setSelectedBlockId);\n }, [store, id, block, setSelectedBlockId]);\n\n const handleArrowUp = useCallback(() => focusAdjacentBlock(store, id, 'up'), [store, id]);\n const handleArrowDown = useCallback(() => focusAdjacentBlock(store, id, 'down'), [store, id]);\n\n const handleAutoformat = useCallback(\n (runs) => applyMarkdownShortcut(store, id, runs),\n [store, id],\n );\n const className = useBlockClassName('be-paragraph', block);\n\n if (!block) return null;\n const isEmpty = isRunsEmpty(store, block.contentIds);\n const dir = resolveBlockDir(store, block);\n\n return (\n <div\n className={className}\n data-block-id={id}\n data-empty={isEmpty ? '' : undefined}\n data-placeholder=\"Type '/' for commands\"\n dir={dir}\n >\n <EditableBlockContent\n blockId={id}\n runIds={block.contentIds}\n dir={dir}\n onEnter={handleEnter}\n onBackspaceAtStart={handleBackspaceAtStart}\n onArrowUp={handleArrowUp}\n onArrowDown={handleArrowDown}\n onAutoformat={handleAutoformat}\n />\n </div>\n );\n}\n","import { genId } from '../utils/idGen.js';\n\nconst TAG_TO_MARK = {\n STRONG: 'bold',\n B: 'bold',\n EM: 'italic',\n I: 'italic',\n U: 'underline',\n S: 'strike',\n STRIKE: 'strike',\n DEL: 'strike',\n CODE: 'code',\n SUB: 'subscript',\n SUP: 'superscript',\n};\n\n/**\n * Walks a DOM node's inline children (text + <strong>/<em>/<a>/etc., plus\n * any registered non-text inline type like a select chip) and produces an\n * array of Run objects carrying the accumulated marks. Reused by every leaf\n * block type's fromHTML matcher so paste-formatting logic is written once,\n * not duplicated per block type.\n *\n * `ctx.inlineRegistry` is optional — omit it if the caller never mixes in\n * non-text inline types (matched elements just fall through to their own\n * text content instead).\n */\nexport function domInlineToRuns(node, ctx, activeMarks = {}) {\n const runs = [];\n\n const walk = (n, marks) => {\n if (n.nodeType === 3 /* TEXT_NODE */) {\n const value = n.textContent;\n if (value) runs.push({ id: genId(), type: 'text', value, marks: { ...marks } });\n return;\n }\n if (n.nodeType !== 1 /* ELEMENT_NODE */) return;\n\n if (ctx?.inlineRegistry) {\n for (const entry of ctx.inlineRegistry.listHtmlMatchers()) {\n const run = entry.fromHTML(n, ctx);\n if (run) {\n runs.push(run);\n return; // atomic: don't also walk its children as plain text\n }\n }\n }\n\n let nextMarks = marks;\n const markName = TAG_TO_MARK[n.tagName];\n if (markName) nextMarks = { ...nextMarks, [markName]: true };\n if (n.tagName === 'A' && n.getAttribute('href')) {\n nextMarks = {\n ...nextMarks,\n link: {\n href: n.getAttribute('href'),\n target: n.getAttribute('target') === '_blank' ? '_blank' : '_self',\n },\n };\n }\n // Color/highlight round-trip via inline style (see marks.js's runToHTML)\n // rather than a fixed tag — style.color/backgroundColor are only ever\n // set by us in that exact shape, so reading them back is unambiguous\n // for our own copy/paste; arbitrary third-party HTML with these styles\n // picks up the same treatment, which is a reasonable default.\n if (n.style?.color) nextMarks = { ...nextMarks, color: n.style.color };\n if (n.style?.backgroundColor) nextMarks = { ...nextMarks, highlight: n.style.backgroundColor };\n\n for (const child of n.childNodes) walk(child, nextMarks);\n };\n\n walk(node, activeMarks);\n return runs.length ? runs : [{ id: genId(), type: 'text', value: '', marks: {} }];\n}\n","import { ParagraphBlock } from './ParagraphBlock.jsx';\nimport { defineBlock } from '../../registry/define.js';\nimport { runToHTML, runToPlainText, runsToMarkdown } from '../../inline/marks.js';\nimport { domInlineToRuns } from '../../inline/runOps.js';\nimport { genId } from '../../utils/idGen.js';\nimport { trimSlashQueryAndInsertAfter } from '../shared/blockCommands.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\nimport { TextIcon } from '../../react/icons.jsx';\n\nfunction toHTML(block, ctx) {\n const runs = block.contentIds.map((runId) => ctx.store.getRun(runId));\n return `<p>${runs.map((r) => runToHTML(r, ctx)).join('')}</p>`;\n}\n\nfunction toPlainText(block, ctx) {\n return block.contentIds.map((runId) => runToPlainText(ctx.store.getRun(runId), ctx)).join('');\n}\n\nfunction toMarkdown(block, ctx) {\n return runsToMarkdown(\n block.contentIds.map((runId) => ctx.store.getRun(runId)),\n ctx,\n );\n}\n\nfunction fromHTML(node, ctx) {\n if (node.tagName !== 'P') return null;\n const runs = domInlineToRuns(node, ctx);\n const block = {\n id: genId(),\n type: 'paragraph',\n parentId: null,\n contentIds: runs.map((r) => r.id),\n props: {},\n };\n return { block, runs };\n}\n\nexport const paragraphBlockType = defineBlock({\n name: 'paragraph',\n component: ParagraphBlock,\n contentModel: 'runs',\n defaultProps: {},\n toHTML,\n toPlainText,\n toMarkdown,\n fromHTML,\n slashCommand: {\n label: 'Text',\n icon: TextIcon,\n keywords: ['paragraph', 'text', 'p'],\n run: (store, ctx) => trimSlashQueryAndInsertAfter(store, ctx, createTextLeafBlock('paragraph')),\n },\n});\n","import { useCallback } from 'react';\nimport { EditableBlockContent } from '../../react/EditableBlockContent.jsx';\nimport { useBlock } from '../../react/useBlock.js';\nimport {\n useEditorStore,\n useSelectedBlock,\n useBlockClassName,\n} from '../../react/EditorProvider.jsx';\nimport { insertSiblingSplitAtCaretAndFocus } from '../shared/blockCommands.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\nimport { mergeWithPreviousOrDelete } from '../shared/mergeCommands.js';\nimport { isRunsEmpty } from '../shared/blockEmpty.js';\nimport { focusAfterMerge } from '../shared/focusAfterMerge.js';\nimport { focusAdjacentBlock } from '../shared/navigationCommands.js';\nimport { resolveBlockDir } from '../shared/resolveBlockDir.js';\n\nexport function HeadingBlock({ id }) {\n const store = useEditorStore();\n const block = useBlock(id);\n const { setSelectedBlockId } = useSelectedBlock();\n\n const handleEnter = useCallback(() => {\n insertSiblingSplitAtCaretAndFocus(\n store,\n id,\n block?.contentIds ?? [],\n createTextLeafBlock('paragraph'),\n );\n }, [store, id, block]);\n\n const handleBackspaceAtStart = useCallback(() => {\n const focusBlockId = mergeWithPreviousOrDelete(store, id);\n focusAfterMerge(store, focusBlockId, id, setSelectedBlockId);\n }, [store, id, setSelectedBlockId]);\n\n const handleArrowUp = useCallback(() => focusAdjacentBlock(store, id, 'up'), [store, id]);\n const handleArrowDown = useCallback(() => focusAdjacentBlock(store, id, 'down'), [store, id]);\n\n // A level-specific class (be-heading-1/2/3) alongside the shared\n // be-heading one — lets a host style/override each heading level\n // independently (font-size, etc.) via a real class instead of having to\n // rely on h1/h2/h3 tag-selector specificity tricks, and gives\n // getBlockClassName's own extra string a distinct per-level hook too.\n const level = block?.props?.level ?? 3;\n const className = useBlockClassName(`be-heading be-heading-${level}`, block);\n\n if (!block) return null;\n const Tag = `h${level}`;\n const isEmpty = isRunsEmpty(store, block.contentIds);\n const dir = resolveBlockDir(store, block);\n\n return (\n <Tag\n className={className}\n data-block-id={id}\n data-empty={isEmpty ? '' : undefined}\n data-placeholder={`Heading ${level}`}\n dir={dir}\n >\n <EditableBlockContent\n blockId={id}\n runIds={block.contentIds}\n dir={dir}\n onEnter={handleEnter}\n onBackspaceAtStart={handleBackspaceAtStart}\n onArrowUp={handleArrowUp}\n onArrowDown={handleArrowDown}\n />\n </Tag>\n );\n}\n","import { HeadingBlock } from './HeadingBlock.jsx';\nimport { defineBlock } from '../../registry/define.js';\nimport { runToHTML, runToPlainText, runsToMarkdown } from '../../inline/marks.js';\nimport { domInlineToRuns } from '../../inline/runOps.js';\nimport { genId } from '../../utils/idGen.js';\nimport { trimSlashQueryAndInsertAfter } from '../shared/blockCommands.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\nimport { Heading1Icon, Heading2Icon, Heading3Icon } from '../../react/icons.jsx';\n\nconst HEADING_ICONS = { 1: Heading1Icon, 2: Heading2Icon, 3: Heading3Icon };\n\nconst TAG_TO_LEVEL = { H1: 1, H2: 2, H3: 3 };\n\nfunction toHTML(block, ctx) {\n const level = block.props?.level ?? 3;\n const runs = block.contentIds.map((runId) => ctx.store.getRun(runId));\n return `<h${level}>${runs.map((r) => runToHTML(r, ctx)).join('')}</h${level}>`;\n}\n\nfunction toPlainText(block, ctx) {\n return block.contentIds.map((runId) => runToPlainText(ctx.store.getRun(runId), ctx)).join('');\n}\n\nfunction toMarkdown(block, ctx) {\n const level = block.props?.level ?? 3;\n const text = runsToMarkdown(\n block.contentIds.map((runId) => ctx.store.getRun(runId)),\n ctx,\n );\n return `${'#'.repeat(level)} ${text}`;\n}\n\nfunction fromHTML(node, ctx) {\n const level = TAG_TO_LEVEL[node.tagName];\n if (!level) return null;\n const runs = domInlineToRuns(node, ctx);\n const block = {\n id: genId(),\n type: 'heading',\n parentId: null,\n contentIds: runs.map((r) => r.id),\n props: { level },\n };\n return { block, runs };\n}\n\nexport const headingBlockType = defineBlock({\n name: 'heading',\n contentModel: 'runs',\n component: HeadingBlock,\n defaultProps: { level: 3 },\n toHTML,\n toPlainText,\n toMarkdown,\n fromHTML,\n slashCommands: [\n {\n label: 'Heading 1',\n icon: HEADING_ICONS[1],\n keywords: ['heading', 'h1', 'title'],\n run: (store, ctx) =>\n trimSlashQueryAndInsertAfter(store, ctx, createTextLeafBlock('heading', { level: 1 })),\n },\n {\n label: 'Heading 2',\n icon: HEADING_ICONS[2],\n keywords: ['heading', 'h2', 'subtitle'],\n run: (store, ctx) =>\n trimSlashQueryAndInsertAfter(store, ctx, createTextLeafBlock('heading', { level: 2 })),\n },\n {\n label: 'Heading 3',\n icon: HEADING_ICONS[3],\n keywords: ['heading', 'h3', 'title'],\n run: (store, ctx) =>\n trimSlashQueryAndInsertAfter(store, ctx, createTextLeafBlock('heading', { level: 3 })),\n },\n ],\n});\n","import { useCallback, useSyncExternalStore } from 'react';\nimport { useEditorStore } from './EditorProvider.jsx';\n\n// Stable empty-array reference so a not-yet-existing/childless block never\n// trips the useSyncExternalStore \"snapshot changed\" check by returning a\n// fresh [] every call.\nconst EMPTY_CONTENT_IDS = [];\n\n/**\n * Subscribes only to a block's `contentIds` array reference. EditorStore\n * only replaces that reference when membership/order actually changes\n * (insert/remove/move), never on a leaf edit inside one of the children —\n * so this hook (and the list-rendering component that calls it) does not\n * re-render on every keystroke inside a child, only on structural changes.\n */\nexport function useBlockChildren(parentId) {\n const store = useEditorStore();\n const subscribe = useCallback(\n (onStoreChange) => store.subscribe(parentId, onStoreChange),\n [store, parentId],\n );\n const getSnapshot = useCallback(() => {\n const block = store.getBlock(parentId);\n return block ? block.contentIds : EMPTY_CONTENT_IDS;\n }, [store, parentId]);\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n","import { Component, Fragment } from 'react';\n\n/**\n * Wraps a single block's rendered output so that a crash in one block (e.g.\n * a contentEditable/DOM desync throwing during React's commit phase) can't\n * take the whole document down with it — without this, an uncaught error\n * from any single block unmounts the entire root, blanking the page for a\n * problem that only ever affected one paragraph.\n *\n * Recovery is a full remount, not a permanent fallback message: the DOM\n * subtree that threw may be in a state React no longer trusts, so the only\n * sound way back is to throw it away and rebuild fresh from the current\n * store state, which is unaffected (the store is a separate source of\n * truth from the DOM). Bumping `nonce` and keying a Fragment on it forces\n * exactly that remount with zero extra DOM nodes. Recovery happens on the\n * next microtask so React finishes unwinding the failed commit first.\n */\nexport class BlockErrorBoundary extends Component {\n state = { hasError: false, nonce: 0 };\n\n static getDerivedStateFromError() {\n return { hasError: true };\n }\n\n componentDidCatch(error, info) {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error(\n '[block-editor] a block failed to render; recovering by remounting it:',\n error,\n info,\n );\n }\n this.props.onError?.(error, info);\n queueMicrotask(() => this.setState((s) => ({ hasError: false, nonce: s.nonce + 1 })));\n }\n\n render() {\n if (this.state.hasError) return null; // one brief frame while recovery is queued\n return <Fragment key={this.state.nonce}>{this.props.children}</Fragment>;\n }\n}\n","import { memo } from 'react';\nimport { useBlock } from './useBlock.js';\nimport { useBlockRegistry } from './EditorProvider.jsx';\nimport { BlockErrorBoundary } from './BlockErrorBoundary.jsx';\n\n/**\n * Recursive entry point: given a block id, looks up its type in the\n * registry and renders that type's component. Every block component (leaf\n * or container) receives only `id` — never the whole document — and is\n * memoized here so unrelated blocks skip re-rendering when a sibling's\n * data changes elsewhere in the tree.\n */\nexport const BlockRenderer = memo(function BlockRenderer({ id }) {\n const block = useBlock(id);\n const registry = useBlockRegistry();\n\n if (!block) return null; // about to be removed this frame; render nothing\n\n const entry = registry.get(block.type);\n if (!entry) {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.warn(`[block-editor] No block type registered for \"${block.type}\" (id: ${id})`);\n }\n return null;\n }\n\n const Component = entry.component;\n return (\n <BlockErrorBoundary>\n <Component id={id} />\n </BlockErrorBoundary>\n );\n});\n","import { useEffect, useRef } from 'react';\n\n/**\n * Makes a portaled `role=\"menu\"` popover keyboard-operable: on open, moves\n * real DOM focus onto its first `[role=\"menuitem\"]`; ArrowDown/ArrowUp move\n * focus between items (wrapping), Home/End jump to the first/last, and\n * Escape calls `onClose()` and returns focus to `triggerRef.current`.\n * Activating an item (Enter/Space) is already handled by each item being a\n * real `<button>` — no extra wiring needed for that part.\n *\n * Modeled on Select.jsx's own already-working real-focus-move pattern\n * (not SlashMenu's activedescendant one) — these are standalone action\n * menus, not inline-typeahead where staying in the surrounding text\n * matters, so moving real focus into the menu is the right (and simpler)\n * choice here. Needed because these menus are portaled to `document.body`\n * (escaping ancestor `overflow` clipping, same reason Select's popover is\n * portaled) — being disconnected from the trigger in DOM order means a\n * keyboard user tabbing forward from the trigger would never reach the\n * menu at all without this.\n *\n * Each caller keeps its own `useOutsideClickAndEscape` for outside-click\n * dismissal — this hook only owns the *keyboard* half (arrow nav + this\n * menu's own Escape-with-focus-restore), which outside-click handling\n * doesn't provide on its own.\n */\nexport function useMenuKeyboardNav(menuRef, isOpen, onClose, triggerRef) {\n const wasOpenRef = useRef(false);\n const didFocusRef = useRef(false);\n\n // Deliberately no dependency array: some menus (BlockRangeActionMenu, in\n // particular) compute their portal position via a separate effect that\n // runs *after* `isOpen` flips true, so `menuRef.current` is still null on\n // the render where `isOpen` first becomes true — the menu only mounts on\n // a follow-up render once that position state lands. Re-checking after\n // every render (instead of only when `isOpen` changes) means this hook\n // picks the menu up on that follow-up render too, without caring whether\n // the caller mounts the menu synchronously or a tick later. `didFocusRef`\n // keeps first-item focus a one-time-per-open-session thing rather than\n // re-stealing focus back to item 0 on every subsequent re-render while\n // still open (e.g. BlockRangeActionMenu's own rect recompute on scroll).\n useEffect(() => {\n if (!isOpen) {\n didFocusRef.current = false;\n if (wasOpenRef.current) {\n wasOpenRef.current = false;\n triggerRef?.current?.focus?.();\n }\n return undefined;\n }\n wasOpenRef.current = true;\n\n const menu = menuRef.current;\n if (!menu) return undefined;\n\n const items = () => Array.from(menu.querySelectorAll('[role=\"menuitem\"]'));\n\n const focusItem = (index) => {\n const list = items();\n if (list.length === 0) return;\n const clamped = ((index % list.length) + list.length) % list.length;\n list[clamped]?.focus();\n };\n\n if (!didFocusRef.current) {\n didFocusRef.current = true;\n focusItem(0);\n }\n\n const handleKeyDown = (event) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n onClose();\n return;\n }\n\n // Some menus (the table column menu, in particular) mix real\n // menuitems with other interactive content (a type <Select>, a\n // rename <input>) — only hijack arrow/Home/End when focus is\n // actually ON one of the tracked menuitems, so typing in an input\n // or arrowing through a Select's own popover elsewhere in the same\n // menu is never interrupted.\n const list = items();\n const currentIndex = list.indexOf(document.activeElement);\n if (currentIndex === -1) return;\n\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n focusItem(currentIndex + 1);\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n focusItem(currentIndex - 1);\n } else if (event.key === 'Home') {\n event.preventDefault();\n focusItem(0);\n } else if (event.key === 'End') {\n event.preventDefault();\n focusItem(list.length - 1);\n }\n };\n\n menu.addEventListener('keydown', handleKeyDown);\n return () => menu.removeEventListener('keydown', handleKeyDown);\n });\n}\n","const LIVE_REGION_ID = 'be-live-region';\n\n/**\n * Lazily creates (once — idempotent, same singleton pattern as\n * injectDefaultStyles.js) a visually-hidden `aria-live=\"polite\"` region\n * appended to `document.body`, so screen-reader users get an announcement\n * for structural actions that don't otherwise move focus anywhere\n * describable (duplicate/move/hide/delete a block or a block range) —\n * previously there was no `aria-live` region anywhere in this codebase at\n * all, so none of those actions were announced.\n */\nfunction getOrCreateLiveRegion() {\n if (typeof document === 'undefined') return null; // SSR guard\n let region = document.getElementById(LIVE_REGION_ID);\n if (region) return region;\n\n region = document.createElement('div');\n region.id = LIVE_REGION_ID;\n region.setAttribute('role', 'status');\n region.setAttribute('aria-live', 'polite');\n region.setAttribute('aria-atomic', 'true');\n // Visually hidden but still exposed to assistive tech (the standard\n // \"clip\" pattern — display:none/visibility:hidden would hide it from\n // screen readers too, defeating the point).\n Object.assign(region.style, {\n position: 'absolute',\n width: '1px',\n height: '1px',\n margin: '-1px',\n padding: '0',\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n border: '0',\n });\n document.body.appendChild(region);\n return region;\n}\n\n/**\n * Announces `message` via the shared live region. Clears the region's\n * text first (on a microtask-length delay) before setting the new\n * message — most screen readers only announce an `aria-live` region when\n * its *text content changes*, so announcing the same message twice in a\n * row (e.g. \"Block deleted\" after two separate deletes) would otherwise\n * silently not fire the second time.\n */\nexport function announce(message) {\n const region = getOrCreateLiveRegion();\n if (!region) return;\n region.textContent = '';\n // setTimeout(0), not a microtask — needs to land in a separate paint/\n // AT-observation tick from the clear above for some screen readers to\n // register the change as new content rather than coalescing both writes\n // into one.\n setTimeout(() => {\n region.textContent = message;\n }, 0);\n}\n","import { genId } from '../../utils/idGen.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\n\nexport const DEFAULT_CALLOUT_ICON = '💡';\n\n/**\n * factory(parentId) -> {block, runs, subtreeBlocks} for a fresh callout —\n * a plain container (same contentIds-holds-child-block-ids shape as\n * layoutColumn/page) plus an `icon` prop, seeded with one empty paragraph\n * so there's somewhere to type immediately (same convention as\n * createLayoutBlock's columns).\n */\nexport const DEFAULT_CALLOUT_COLOR = 'gray';\n\nexport function createCalloutBlock({\n icon = DEFAULT_CALLOUT_ICON,\n color = DEFAULT_CALLOUT_COLOR,\n} = {}) {\n return function factory(parentId) {\n const calloutId = genId();\n const { block: paragraphBlock, runs } = createTextLeafBlock('paragraph')(calloutId);\n const block = {\n id: calloutId,\n type: 'callout',\n parentId,\n contentIds: [paragraphBlock.id],\n props: { icon, color },\n };\n return { block, runs, subtreeBlocks: [paragraphBlock] };\n };\n}\n","import { convertBlockType } from './convertBlockType.js';\nimport { updateRun } from '../../store/operations.js';\nimport { DEFAULT_CALLOUT_ICON } from '../callout/createCalloutBlock.js';\nimport {\n TextIcon,\n Heading1Icon,\n Heading2Icon,\n Heading3Icon,\n BulletedListIcon,\n NumberedListIcon,\n CheckboxIcon,\n ChevronRightIcon,\n QuoteIcon,\n CalloutIcon,\n CodeIcon,\n} from '../../react/icons.jsx';\n\n/**\n * The \"text family\" — every block type this codebase's own R&D pass (see\n * README/commit history) settled on as freely inter-convertible, matching\n * the same boundary most block editors independently draw:\n * blocks holding rich/plain text content. Deliberately excludes the\n * \"structural\" group (table, layout/layoutColumn, embed, divider, button)\n * — few block editors offer generic type-conversion for those\n * either; they keep their own dedicated creation/management UI instead.\n *\n * Each entry's `props` matches the exact shape that type's own slash\n * command already inserts with (see e.g. `markdownShortcuts.js`'s RULES,\n * or each block type's own `index.js` `slashCommand(s)`) — this is data,\n * not new conversion logic.\n */\nexport const TEXT_FAMILY_TARGETS = [\n { type: 'paragraph', props: {}, label: 'Text', icon: TextIcon },\n { type: 'heading', props: { level: 1 }, label: 'Heading 1', icon: Heading1Icon },\n { type: 'heading', props: { level: 2 }, label: 'Heading 2', icon: Heading2Icon },\n { type: 'heading', props: { level: 3 }, label: 'Heading 3', icon: Heading3Icon },\n {\n type: 'listItem',\n props: { ordered: false, titleRunIds: [] },\n label: 'Bulleted list',\n icon: BulletedListIcon,\n },\n {\n type: 'listItem',\n props: { ordered: true, titleRunIds: [] },\n label: 'Numbered list',\n icon: NumberedListIcon,\n },\n {\n type: 'listItem',\n props: { ordered: false, checked: false, titleRunIds: [] },\n label: 'To-do list',\n icon: CheckboxIcon,\n },\n {\n type: 'listItem',\n props: { ordered: false, collapsed: false, titleRunIds: [] },\n label: 'Toggle list',\n icon: ChevronRightIcon,\n },\n {\n type: 'toggleHeading',\n props: { level: 2, collapsed: false, titleRunIds: [] },\n label: 'Toggle heading',\n icon: ChevronRightIcon,\n },\n { type: 'blockquote', props: {}, label: 'Quote', icon: QuoteIcon },\n { type: 'callout', props: { icon: DEFAULT_CALLOUT_ICON }, label: 'Callout', icon: CalloutIcon },\n { type: 'code', props: { language: 'plaintext' }, label: 'Code', icon: CodeIcon },\n];\n\nconst TEXT_FAMILY_TYPES = new Set(TEXT_FAMILY_TARGETS.map((t) => t.type));\n\n/** Single source of truth for \"is this block type offered by Turn into at all\" — menu visibility and range-selection filtering both key off this. */\nexport function isTurnIntoEligible(type) {\n return TEXT_FAMILY_TYPES.has(type);\n}\n\n/**\n * A block's own inline text run ids -- `props.titleRunIds` for a container\n * that has them (listItem, toggleHeading), or `contentIds` for a leaf\n * (paragraph, heading, blockquote, code), since a leaf's contentIds *are*\n * its runs. A container WITHOUT titleRunIds (callout) owns no text runs of\n * its own at all -- its contentIds are child blocks (e.g. a nested\n * paragraph that holds the actual text), not runs -- so it must report no\n * own runIds rather than have its children's block ids misread as run ids.\n * Requires `registry` to tell \"leaf whose contentIds are runs\" apart from\n * \"container whose contentIds are children\"; without one, only a leaf\n * shape is assumed (matches this function's own two other callers, which\n * only ever operate on a fresh, childless, single-run paragraph).\n */\nfunction getOwnRunIds(block, registry) {\n if (block?.props && 'titleRunIds' in block.props) return block.props.titleRunIds;\n if (registry && !registry.isLeaf(block?.type)) return [];\n return block?.contentIds ?? [];\n}\n\n/**\n * Converts one block to `target` ({ type, props }), reusing\n * `convertBlockType` — this is the one shared place `getOwnRunIds` and the\n * \"strip marks when converting into code\" rule live, rather than\n * duplicating either per call site (gutter menu vs. range menu).\n *\n * Marks are stripped only when the target is `code` — code shouldn't carry\n * bold/italic/etc (its own `toHTML` never emits mark tags either) — via\n * plain `updateRun` ops folded into the same batch, so it's still one\n * atomic undo step. This is scoped entirely to this new call path; it\n * never touches `convertBlockType` itself or its two original callers.\n *\n * Returns `{ ops, newBlockId }`, same contract as `convertBlockType` — the\n * caller applies `ops` as one batch (directly, or concatenated with other\n * blocks' ops for a multi-block conversion).\n */\nexport function turnBlockInto(store, registry, blockId, target) {\n const block = store.getBlock(blockId);\n const runIds = getOwnRunIds(block, registry);\n\n const ops = [];\n if (target.type === 'code') {\n for (const runId of runIds) {\n const run = store.getRun(runId);\n if (run?.marks && Object.keys(run.marks).length > 0)\n ops.push(updateRun(runId, { marks: {} }));\n }\n }\n\n // Cloned, not passed by reference — TEXT_FAMILY_TARGETS entries are\n // shared module-level objects reused across every conversion; convertBlockType\n // hands `props` straight to the new block as-is, so a raw shared reference\n // here would mean every block converted via the same menu entry ends up\n // pointing at the exact same props object.\n const props = { ...target.props };\n const { ops: convertOps, newBlockId } = convertBlockType(\n store,\n blockId,\n target.type,\n props,\n runIds,\n registry,\n );\n return { ops: [...ops, ...convertOps], newBlockId };\n}\n","import { useCallback, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useOutsideClickAndEscape } from './useOutsideClickAndEscape.js';\nimport { useMenuKeyboardNav } from './useMenuKeyboardNav.js';\nimport { useAutoAdjustedPosition } from './useAutoAdjustedPosition.js';\nimport { TEXT_FAMILY_TARGETS } from '../blocks/shared/turnInto.js';\nimport { ChevronRightIcon } from './icons.jsx';\n\n/**\n * A menu item that opens a second, nested `role=\"menu\"` listing every\n * `TEXT_FAMILY_TARGETS` entry — the one reusable \"submenu\" this codebase\n * has (see turnInto.js's plan doc comment: no prior submenu pattern\n * existed here). Modeled directly on BlockGutterRow's own portaled-menu\n * convention (own `rect` off the trigger's own `getBoundingClientRect()`,\n * own `menuRef` + `useMenuKeyboardNav` + `useOutsideClickAndEscape`) rather\n * than introducing a new one.\n *\n * `onSelect(target)` is called with the chosen `{ type, props, label, icon }`\n * entry; the caller (BlockGutterRow / BlockRangeActionMenu) owns actually\n * converting the block(s) and closing its own outer menu — this component\n * only owns picking a target and closing itself, via `onClose()`, which the\n * caller passes down (its Escape/outside-click here calls `onClose` only,\n * never the outer menu's).\n *\n * `containerRef` (optional) receives the submenu's own portaled DOM node —\n * the caller (BlockGutterRow/BlockRangeActionMenu) must fold it into its\n * OWN outer menu's outside-click ref list. Without this, a click on a\n * submenu item registers as \"outside\" the outer menu (the submenu portal is\n * a DOM sibling of the outer menu, not a descendant of it, even though it's\n * a React child of this component) — the outer menu's own\n * useOutsideClickAndEscape closes it on `mousedown`, unmounting this\n * component and its submenu *before* the follow-up `click` event that would\n * have actually fired `onSelect` ever reaches the browser, so selecting a\n * target silently did nothing.\n *\n * ArrowRight on the trigger opens the submenu (focusing its first item, via\n * useMenuKeyboardNav's own on-open behavior); ArrowLeft anywhere inside the\n * submenu closes it and returns focus to the trigger (via that same hook's\n * on-close behavior) — the standard nested-menu convention (most native OS\n * menus, and most block editors) alongside Escape/outside-click, which already worked.\n */\nexport function TurnIntoSubmenu({\n onSelect,\n onClose,\n containerRef,\n menuClassName = 'be-block-gutter-menu',\n itemClassName = 'be-block-gutter-menu-item',\n}) {\n const [isOpen, setIsOpen] = useState(false);\n const [rect, setRect] = useState(null);\n const triggerRef = useRef(null);\n const menuRef = useRef(null);\n\n const setMenuRef = useCallback(\n (el) => {\n menuRef.current = el;\n if (containerRef) containerRef.current = el;\n },\n [containerRef],\n );\n\n const close = useCallback(() => {\n setIsOpen(false);\n onClose?.();\n }, [onClose]);\n\n useOutsideClickAndEscape([triggerRef, menuRef], isOpen, close);\n useMenuKeyboardNav(menuRef, isOpen, close, triggerRef);\n\n const position = useAutoAdjustedPosition(\n menuRef,\n isOpen,\n rect?.top,\n rect ? rect.right + 4 : null,\n );\n\n const open = useCallback(() => {\n setRect(triggerRef.current?.getBoundingClientRect() ?? null);\n setIsOpen(true);\n }, []);\n\n const handleSelect = useCallback(\n (target) => {\n onSelect(target);\n close();\n },\n [onSelect, close],\n );\n\n const handleTriggerKeyDown = useCallback(\n (event) => {\n if (event.key === 'ArrowRight' && !isOpen) {\n event.preventDefault();\n open();\n }\n },\n [isOpen, open],\n );\n\n const handleSubmenuKeyDown = useCallback(\n (event) => {\n if (event.key === 'ArrowLeft') {\n event.preventDefault();\n close();\n }\n },\n [close],\n );\n\n return (\n <>\n <button\n ref={triggerRef}\n type=\"button\"\n role=\"menuitem\"\n className={itemClassName}\n aria-haspopup=\"menu\"\n aria-expanded={isOpen}\n onClick={() => (isOpen ? close() : open())}\n onKeyDown={handleTriggerKeyDown}\n >\n <ChevronRightIcon size={15} /> Turn into\n </button>\n {isOpen &&\n position &&\n createPortal(\n <div\n ref={setMenuRef}\n role=\"menu\"\n aria-label=\"Turn into\"\n className={menuClassName}\n style={{ position: 'fixed', top: position.top, left: position.left }}\n onKeyDown={handleSubmenuKeyDown}\n >\n {TEXT_FAMILY_TARGETS.map((target, i) => {\n const Icon = target.icon;\n return (\n <button\n key={`${target.type}-${i}`}\n type=\"button\"\n role=\"menuitem\"\n className={itemClassName}\n onClick={() => handleSelect(target)}\n >\n <Icon size={15} /> {target.label}\n </button>\n );\n })}\n </div>,\n document.body,\n )}\n </>\n );\n}\n","import { insertBlock, removeBlock, moveBlock } from '../../store/operations.js';\nimport { captureSubtree, remapSubtreeIds } from '../../clipboard/serialize.js';\nimport { focusBlockStart } from './navigationCommands.js';\nimport { ensureRootNonEmpty } from './ensureRootNonEmpty.js';\n\n/**\n * Clones `blockId`'s entire subtree (itself + every descendant + their\n * runs, all with fresh ids — see remapSubtreeIds) and inserts the copy\n * right after the original, then focuses the copy's own first typeable\n * position. Reuses the exact same subtree-capture/id-remap machinery the\n * same-editor clipboard JSON path already relies on (see serialize.js) —\n * \"duplicate\" is exactly \"copy, then paste right after itself.\"\n */\nexport function duplicateBlock(store, blockId) {\n const original = store.getBlock(blockId);\n if (!original) return null;\n const parent = store.getBlock(original.parentId);\n const index = parent.contentIds.indexOf(blockId);\n\n const subtree = captureSubtree(store, blockId);\n const { block, runs, subtreeBlocks } = remapSubtreeIds(subtree);\n\n store.applyOperation(\n insertBlock(block, parent.id, index + 1, { blocks: [block, ...subtreeBlocks], runs }),\n );\n focusBlockStart(store, block.id);\n return block.id;\n}\n\n/**\n * Swaps `blockId` with its previous sibling under the same parent — a\n * no-op (returns false) if it's already first. `moveBlock`'s own `toIndex`\n * is interpreted against the array *after* the block has already been\n * removed from it (see EditorStore's MOVE_BLOCK case) — `index - 1` lands\n * it exactly one slot earlier in that already-shifted array, which is\n * what makes this a plain adjacent swap rather than needing any special\n * \"moving backward\" arithmetic.\n */\nexport function moveBlockUp(store, blockId) {\n const block = store.getBlock(blockId);\n const parent = block && store.getBlock(block.parentId);\n if (!parent) return false;\n const index = parent.contentIds.indexOf(blockId);\n if (index <= 0) return false;\n store.applyOperation(moveBlock(blockId, parent.id, index - 1));\n return true;\n}\n\n/** Symmetric to moveBlockUp: swaps with the next sibling, a no-op if already last. */\nexport function moveBlockDown(store, blockId) {\n const block = store.getBlock(blockId);\n const parent = block && store.getBlock(block.parentId);\n if (!parent) return false;\n const index = parent.contentIds.indexOf(blockId);\n if (index === -1 || index >= parent.contentIds.length - 1) return false;\n store.applyOperation(moveBlock(blockId, parent.id, index + 1));\n return true;\n}\n\n/**\n * Removes `blockId` (its whole subtree) and moves focus to whatever's now\n * in its old spot — the previous sibling, or else the next one, or else\n * (it was the only top-level block) whatever ensureRootNonEmpty falls back\n * to, so there's always still somewhere to land the caret. Same\n * prev-or-next-or-fallback convention as unwrapEmptyContainer/\n * removeTableAndFocusSibling elsewhere in this codebase.\n */\nexport function deleteBlockAndFocusSibling(store, blockId) {\n const block = store.getBlock(blockId);\n if (!block) return null;\n const parent = store.getBlock(block.parentId);\n const index = parent.contentIds.indexOf(blockId);\n const prevId = index > 0 ? parent.contentIds[index - 1] : null;\n const nextId =\n index !== -1 && index < parent.contentIds.length - 1 ? parent.contentIds[index + 1] : null;\n\n store.applyOperation(removeBlock(blockId));\n const fallbackId = ensureRootNonEmpty(store);\n const targetId = prevId ?? nextId ?? fallbackId;\n if (targetId) focusBlockStart(store, targetId);\n return targetId ?? null;\n}\n","import { useCallback, useMemo, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useEditorStore, useBlockRegistry, useBlockRangeSelection } from './EditorProvider.jsx';\nimport { useBlock } from './useBlock.js';\nimport { useOutsideClickAndEscape } from './useOutsideClickAndEscape.js';\nimport { useMenuKeyboardNav } from './useMenuKeyboardNav.js';\nimport { useAutoAdjustedPosition } from './useAutoAdjustedPosition.js';\nimport { announce } from './liveAnnouncer.js';\nimport { BlockRenderer } from './BlockRenderer.jsx';\nimport { TurnIntoSubmenu } from './TurnIntoSubmenu.jsx';\nimport { insertSiblingAfterAndFocus } from '../blocks/shared/blockCommands.js';\nimport { createTextLeafBlock } from '../blocks/shared/leafBlockFactory.js';\nimport {\n duplicateBlock,\n moveBlockUp,\n moveBlockDown,\n deleteBlockAndFocusSibling,\n} from '../blocks/shared/blockActions.js';\nimport { resolveBlockDir } from '../blocks/shared/resolveBlockDir.js';\nimport { isTurnIntoEligible, turnBlockInto } from '../blocks/shared/turnInto.js';\nimport { updateBlockProps } from '../store/operations.js';\nimport {\n PlusIcon,\n GripVerticalIcon,\n CopyIcon,\n ArrowUpIcon,\n ArrowDownIcon,\n TrashIcon,\n EyeIcon,\n EyeOffIcon,\n AlignLeftIcon,\n AlignRightIcon,\n} from './icons.jsx';\n\n/**\n * Wraps ONE top-level block with a hover-revealed left gutter — a \"+\" to\n * insert a new paragraph right after it, and a grip-handle trigger opening\n * a small menu (Duplicate / Move Up / Move Down / Hide-Show / Delete), the\n * same per-block affordance most block editors show. Only used for\n * TOP-LEVEL blocks (see BlockChildren's `isTopLevel` prop) — nested\n * content (list item children, table cells, layout columns) doesn't get\n * its own gutter, matching every one of those editors' own convention of\n * only offering this at the outermost level. Never rendered at all in\n * preview mode (see BlockChildren) — a preview isn't something you edit.\n *\n * Deliberately does not implement drag-and-drop reordering itself (a much\n * larger feature on its own) — the grip icon here is just the\n * conventional trigger for the menu; Move Up/Down cover reordering\n * instead. The menu is portaled to document.body (position:fixed off the\n * trigger's own rect), same convention as Select/SlashMenu/the table\n * header menu elsewhere in this codebase.\n *\n * \"Hide\"/\"Show\" toggles a generic `props.hidden` flag — works on any block\n * type since props is a free-form per-block object, no schema change\n * needed anywhere. In edit mode a hidden block still renders with full\n * functionality, just dimmed (see the be-block-row-hidden CSS) as a visual\n * reminder it won't appear once switched to preview mode, where\n * BlockChildren skips it entirely instead.\n *\n * `be-block-row-range-selected` (see useBlockRangeSelection) highlights\n * this row when it's part of a drag-selected block range — the actual\n * drag-start detection lives in useBlockRangeDrag, mounted once at the\n * surface level rather than here, since it needs to catch presses in the\n * blank page margin on either side of the content column too, not just\n * this row's own narrow gutter.\n */\nfunction applyOps(store, ops) {\n if (typeof store.performBatch === 'function') store.performBatch(ops);\n else for (const op of ops) store.applyOperation(op);\n}\n\nexport function BlockGutterRow({ id }) {\n const store = useEditorStore();\n const registry = useBlockRegistry();\n const block = useBlock(id);\n const [isMenuOpen, setIsMenuOpen] = useState(false);\n const [rect, setRect] = useState(null);\n const triggerRef = useRef(null);\n const menuRef = useRef(null);\n const turnIntoMenuRef = useRef(null);\n // The Turn into item's own submenu is a SEPARATE portal (a DOM sibling of\n // this menu, not a descendant, even though it's a React child of it) — it\n // must be included here or a click inside it reads as \"outside this menu\"\n // and closes (unmounts) everything before the submenu's own click handler\n // ever fires. See TurnIntoSubmenu's own doc comment for the full story.\n const outsideRefs = useMemo(() => [triggerRef, menuRef, turnIntoMenuRef], []);\n const [selectedBlockRange] = useBlockRangeSelection();\n const isRangeSelected = selectedBlockRange.includes(id);\n\n const closeMenu = useCallback(() => setIsMenuOpen(false), []);\n useOutsideClickAndEscape(outsideRefs, isMenuOpen, closeMenu);\n useMenuKeyboardNav(menuRef, isMenuOpen, closeMenu, triggerRef);\n\n const openMenu = useCallback(() => {\n setRect(triggerRef.current?.getBoundingClientRect() ?? null);\n setIsMenuOpen(true);\n }, []);\n\n const position = useAutoAdjustedPosition(\n menuRef,\n isMenuOpen,\n rect?.bottom != null ? rect.bottom + 4 : null,\n rect?.left,\n );\n\n const handleAdd = useCallback(() => {\n insertSiblingAfterAndFocus(store, id, createTextLeafBlock('paragraph'));\n }, [store, id]);\n\n const handleDuplicate = useCallback(() => {\n duplicateBlock(store, id);\n announce('Block duplicated');\n closeMenu();\n }, [store, id, closeMenu]);\n\n const handleMoveUp = useCallback(() => {\n if (moveBlockUp(store, id)) announce('Block moved up');\n closeMenu();\n }, [store, id, closeMenu]);\n\n const handleMoveDown = useCallback(() => {\n if (moveBlockDown(store, id)) announce('Block moved down');\n closeMenu();\n }, [store, id, closeMenu]);\n\n const handleDelete = useCallback(() => {\n deleteBlockAndFocusSibling(store, id);\n announce('Block deleted');\n closeMenu();\n }, [store, id, closeMenu]);\n\n const isHidden = Boolean(block?.props?.hidden);\n const handleToggleHidden = useCallback(() => {\n store.applyOperation(updateBlockProps(id, { hidden: !isHidden }));\n announce(isHidden ? 'Block shown in preview' : 'Block hidden in preview');\n closeMenu();\n }, [store, id, isHidden, closeMenu]);\n\n // Explicitly overrides resolveBlockDir's own 'auto'/document-default\n // resolution for just this block — for the common case (a document\n // that's uniformly one direction) the document-level default this menu\n // doesn't touch is all that's needed; this exists for the block that's\n // the odd one out (e.g. a single quoted line in the other language).\n const isRtl = resolveBlockDir(store, block) === 'rtl';\n const handleToggleDir = useCallback(() => {\n store.applyOperation(updateBlockProps(id, { dir: isRtl ? 'ltr' : 'rtl' }));\n announce(isRtl ? 'Block set to left-to-right' : 'Block set to right-to-left');\n closeMenu();\n }, [store, id, isRtl, closeMenu]);\n\n const handleTurnInto = useCallback(\n (target) => {\n const { ops } = turnBlockInto(store, registry, id, target);\n applyOps(store, ops);\n announce(`Turned into ${target.label}`);\n closeMenu();\n },\n [store, registry, id, closeMenu],\n );\n\n if (!block) return null;\n\n return (\n <div\n className={`be-block-row${isHidden ? ' be-block-row-hidden' : ''}${isRangeSelected ? ' be-block-row-range-selected' : ''}`}\n data-block-row-id={id}\n dir={resolveBlockDir(store, block)}\n >\n <div\n className={`be-block-gutter${isMenuOpen ? ' be-block-gutter-active' : ''}`}\n contentEditable={false}\n >\n <button\n type=\"button\"\n className=\"be-block-gutter-btn\"\n onClick={handleAdd}\n aria-label=\"Add block below\"\n >\n <PlusIcon size={16} />\n </button>\n <button\n ref={triggerRef}\n type=\"button\"\n className=\"be-block-gutter-btn\"\n aria-label=\"More options\"\n aria-haspopup=\"menu\"\n aria-expanded={isMenuOpen}\n onClick={() => (isMenuOpen ? closeMenu() : openMenu())}\n >\n <GripVerticalIcon size={16} />\n </button>\n </div>\n <div className=\"be-block-row-content\">\n <BlockRenderer id={id} />\n </div>\n {isMenuOpen &&\n position &&\n createPortal(\n <div\n ref={menuRef}\n role=\"menu\"\n aria-label=\"Block options\"\n className=\"be-block-gutter-menu\"\n style={{ position: 'fixed', top: position.top, left: position.left }}\n >\n <button\n type=\"button\"\n role=\"menuitem\"\n className=\"be-block-gutter-menu-item\"\n onClick={handleDuplicate}\n >\n <CopyIcon size={15} /> Duplicate\n </button>\n <button\n type=\"button\"\n role=\"menuitem\"\n className=\"be-block-gutter-menu-item\"\n onClick={handleMoveUp}\n >\n <ArrowUpIcon size={15} /> Move up\n </button>\n <button\n type=\"button\"\n role=\"menuitem\"\n className=\"be-block-gutter-menu-item\"\n onClick={handleMoveDown}\n >\n <ArrowDownIcon size={15} /> Move down\n </button>\n <button\n type=\"button\"\n role=\"menuitem\"\n className=\"be-block-gutter-menu-item\"\n onClick={handleToggleHidden}\n >\n {isHidden ? <EyeIcon size={15} /> : <EyeOffIcon size={15} />}\n {isHidden ? 'Show in preview' : 'Hide in preview'}\n </button>\n <button\n type=\"button\"\n role=\"menuitem\"\n className=\"be-block-gutter-menu-item\"\n onClick={handleToggleDir}\n >\n {isRtl ? <AlignLeftIcon size={15} /> : <AlignRightIcon size={15} />}\n {isRtl ? 'Switch to left-to-right' : 'Switch to right-to-left'}\n </button>\n {isTurnIntoEligible(block.type) && (\n <TurnIntoSubmenu\n onSelect={handleTurnInto}\n onClose={() => {}}\n containerRef={turnIntoMenuRef}\n />\n )}\n <button\n type=\"button\"\n role=\"menuitem\"\n className=\"be-block-gutter-menu-item be-block-gutter-menu-item-danger\"\n onClick={handleDelete}\n >\n <TrashIcon size={15} /> Delete\n </button>\n </div>,\n document.body,\n )}\n </div>\n );\n}\n","import { useBlockChildren } from './useBlockChildren.js';\nimport { useEditorStore, usePreviewMode } from './EditorProvider.jsx';\nimport { BlockRenderer } from './BlockRenderer.jsx';\nimport { BlockGutterRow } from './BlockGutterRow.jsx';\n\n/**\n * Renders the child blocks of any container block. This is the single piece\n * of tree-walking logic shared by every container type (page, list item,\n * table row, table cell-as-container, layout column) — none of them need\n * their own child-rendering loop.\n *\n * `isTopLevel` opts into wrapping each child with the per-block hover\n * gutter (+/duplicate/move/delete/hide — see BlockGutterRow) — pass it only\n * for the ONE call site rendering the document's actual top-level blocks\n * (the page root), never for a nested container's own children: most block\n * editors restrict this affordance to the outermost level only, and\n * showing it for a table cell's or list item's own content would\n * be visually cramped and semantically confusing (e.g. \"delete\" there\n * could read as deleting the cell/item itself or just its content).\n *\n * In preview mode (see usePreviewMode), the gutter never renders at all —\n * a preview isn't something you edit — and any block whose own\n * `props.hidden` is true is skipped entirely, at every level (not just\n * top-level), rather than rendered dimmed the way edit mode shows it: the\n * whole point of \"hidden\" is that it disappears from what a reader\n * eventually sees.\n *\n * `filterIds`, if given, renders exactly this subset/order instead of the\n * block's own `contentIds` — the real content is untouched either way;\n * this only changes what's RENDERED. Used by TableBlock for its own\n * (local, non-persisted) column filter: hiding a non-matching row from the\n * table's own view without deleting it. Still calls `useBlockChildren`\n * unconditionally (so this component re-renders when the underlying\n * `contentIds` actually change, which is what `filterIds` is derived\n * from), its own return value just isn't what gets rendered in that case.\n */\nexport function BlockChildren({ parentId, isTopLevel = false, filterIds }) {\n const contentIds = useBlockChildren(parentId);\n const store = useEditorStore();\n const [isPreviewMode] = usePreviewMode();\n\n const baseIds = filterIds ?? contentIds;\n const visibleIds = isPreviewMode\n ? baseIds.filter((childId) => !store.getBlock(childId)?.props?.hidden)\n : baseIds;\n\n if (isTopLevel && !isPreviewMode) {\n return visibleIds.map((childId) => <BlockGutterRow key={childId} id={childId} />);\n }\n return visibleIds.map((childId) => <BlockRenderer key={childId} id={childId} />);\n}\n","const ALPHA_START = 'a'.charCodeAt(0);\nconst ROMAN_TABLE = [\n [1000, 'm'],\n [900, 'cm'],\n [500, 'd'],\n [400, 'cd'],\n [100, 'c'],\n [90, 'xc'],\n [50, 'l'],\n [40, 'xl'],\n [10, 'x'],\n [9, 'ix'],\n [5, 'v'],\n [4, 'iv'],\n [1, 'i'],\n];\n\n/** 1 -> \"a\", 26 -> \"z\", 27 -> \"aa\", ... (spreadsheet-column style, no zero digit). */\nfunction toAlpha(n) {\n let out = '';\n while (n > 0) {\n n -= 1;\n out = String.fromCharCode(ALPHA_START + (n % 26)) + out;\n n = Math.floor(n / 26);\n }\n return out;\n}\n\nfunction toRoman(n) {\n let out = '';\n let rest = n;\n for (const [value, symbol] of ROMAN_TABLE) {\n while (rest >= value) {\n out += symbol;\n rest -= value;\n }\n }\n return out;\n}\n\n/**\n * A \"plain\" list item is one whose marker is a bullet/number (not a to-do\n * checkbox, not a toggle disclosure triangle) — only these participate in\n * numbering/bullet-style cycling at all.\n */\nfunction isPlainMarkerItem(block) {\n return (\n block?.type === 'listItem' &&\n block.props?.checked === undefined &&\n block.props?.collapsed === undefined\n );\n}\n\n/**\n * How many listItem ancestors this block is nested under — 0 for a\n * top-level item, 1 for its first nested level, and so on. Cycles every 3\n * levels for marker style (a common numbered-list convention:\n * 1,2,3 -> a,b,c -> i,ii,iii -> 1,2,3 again as you keep nesting), applied\n * uniformly regardless of whether ancestors at those levels happen to be\n * ordered, bulleted, or a mix.\n */\nexport function listItemDepth(store, block) {\n let depth = 0;\n let current = block;\n while (current) {\n const parent = store.getBlock(current.parentId);\n if (!parent || parent.type !== 'listItem') break;\n depth += 1;\n current = parent;\n }\n return depth;\n}\n\n/**\n * This item's 1-based position within its *contiguous run* of ordered\n * sibling list items — counting backward from this item only while\n * immediately-preceding siblings are also plain ordered list items, so\n * numbering restarts at 1 after any interruption (a bullet item, a toggle,\n * a to-do, or a completely different block type) — a numbered list restarts\n * after a break rather than continuing a global counter across the whole\n * document.\n */\nexport function orderedItemIndex(store, block, siblingIds) {\n const pos = siblingIds.indexOf(block.id);\n let count = 1;\n for (let i = pos - 1; i >= 0; i -= 1) {\n const sibling = store.getBlock(siblingIds[i]);\n if (!isPlainMarkerItem(sibling) || !sibling.props.ordered) break;\n count += 1;\n }\n return count;\n}\n\n/** e.g. depth 0 -> \"1.\", depth 1 -> \"a.\", depth 2 -> \"i.\", depth 3 -> \"1.\" again. */\nexport function orderedMarkerText(depth, index) {\n const style = ((depth % 3) + 3) % 3;\n if (style === 0) return `${index}.`;\n if (style === 1) return `${toAlpha(index)}.`;\n return `${toRoman(index)}.`;\n}\n\nconst BULLET_GLYPHS = ['•', '◦', '▪'];\n\n/** e.g. depth 0 -> \"•\" (disc), depth 1 -> \"◦\" (circle), depth 2 -> \"▪\" (square), depth 3 -> \"•\" again. */\nexport function bulletMarkerText(depth) {\n const style = ((depth % 3) + 3) % 3;\n return BULLET_GLYPHS[style];\n}\n","import { genId } from '../../utils/idGen.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\n\n/**\n * factory(parentId, initialRuns?) -> {block, runs, subtreeBlocks} for a\n * list item. `checked` left undefined (default) renders a bullet/number\n * marker; passing a boolean turns it into a to-do item with a checkbox\n * marker. `collapsed` left undefined (default) is the same plain bullet/\n * number/todo marker; passing a boolean turns it into a \"toggle\" item\n * instead — a disclosure triangle marker whose nested children (contentIds)\n * render only while `collapsed` is false. `checked` and `collapsed` are\n * mutually exclusive markers in the UI (whichever is set decides which\n * marker renders; see ListItemBlock) — passing both is not a supported\n * combination — matches the common \"one marker style per item\" convention.\n * `initialRuns`, when given (Enter-to-split), seeds the title with the runs\n * that landed after the caret instead of a single blank run.\n *\n * A toggle is seeded with one empty paragraph child right away (same\n * convention as callout/toggleHeading) — without this, a toggle created\n * with no children at all has nothing to expand: its own disclosure\n * marker has nothing to reveal, and there was no other way to get content\n * into it (this was a real dead end for exactly this reason before the\n * seeding was added).\n */\nexport function createListItemBlock({ ordered = false, checked, collapsed } = {}) {\n return function factory(parentId, initialRuns) {\n const blockId = genId();\n const runs = initialRuns?.length\n ? initialRuns\n : [{ id: genId(), type: 'text', value: '', marks: {} }];\n const props = { ordered, titleRunIds: runs.map((r) => r.id) };\n if (checked !== undefined) props.checked = checked;\n\n let contentIds = [];\n let subtreeBlocks = [];\n let allRuns = runs;\n if (collapsed !== undefined) {\n props.collapsed = collapsed;\n const { block: childBlock, runs: childRuns } = createTextLeafBlock('paragraph')(blockId);\n contentIds = [childBlock.id];\n subtreeBlocks = [childBlock];\n allRuns = [...runs, ...childRuns];\n }\n\n return {\n block: { id: blockId, type: 'listItem', parentId, contentIds, props },\n runs: allRuns,\n subtreeBlocks,\n };\n };\n}\n","import { moveBlock } from '../../store/operations.js';\nimport { focusAdjacentBlock, focusBlockStart } from '../shared/navigationCommands.js';\n\n/**\n * Tab: makes this list item a child (nested one level deeper) of its\n * previous sibling — but only when that previous sibling is itself a\n * listItem. Nesting under a non-container block (a paragraph, heading,\n * etc.) would silently make this item invisible: only container block\n * types render `<BlockChildren>` for their contentIds, so a listItem\n * reparented under, say, a paragraph would still exist in the store but\n * never be rendered anywhere — this is what \"the whole list disappeared\"\n * turned out to be. When there's no previous sibling to nest under (this\n * is the first item, or no valid listItem precedes it), Tab moves focus to\n * the next block instead of doing nothing silently.\n *\n * moveBlock reparents the item — a different contentIds array now owns it,\n * so React remounts its subtree under the new parent and any DOM focus it\n * had is destroyed. Must explicitly refocus afterward, same as every other\n * reparenting path (outdent-on-Backspace, outdent-on-Enter) already does.\n */\nexport function indentListItem(store, blockId) {\n const block = store.getBlock(blockId);\n const parent = store.getBlock(block.parentId);\n const index = parent.contentIds.indexOf(blockId);\n const prevId = index > 0 ? parent.contentIds[index - 1] : null;\n const prev = prevId ? store.getBlock(prevId) : null;\n\n if (!prev || prev.type !== 'listItem') {\n focusAdjacentBlock(store, blockId, 'down');\n return;\n }\n\n store.applyOperation(moveBlock(blockId, prevId, prev.contentIds.length));\n focusBlockStart(store, blockId);\n}\n\n/**\n * Shift+Tab: promotes this list item to be a sibling of its current parent\n * list item, placed right after it. No-op if the parent isn't itself a\n * list item (i.e. this item is already at the top level). Also reparents\n * (see indentListItem's note above) — refocuses afterward for the same\n * reason.\n */\nexport function outdentListItem(store, blockId) {\n const block = store.getBlock(blockId);\n const currentParent = store.getBlock(block.parentId);\n if (!currentParent || currentParent.type !== 'listItem') return;\n const grandParentId = currentParent.parentId;\n const grandParent = store.getBlock(grandParentId);\n const parentIndex = grandParent.contentIds.indexOf(currentParent.id);\n store.applyOperation(moveBlock(blockId, grandParentId, parentIndex + 1));\n focusBlockStart(store, blockId);\n}\n","import { removeBlock, updateBlockProps, insertBlock } from '../../store/operations.js';\nimport { outdentListItem } from './indentCommands.js';\nimport { isContentlessBlock } from '../shared/contentless.js';\nimport { isRunsEmpty } from '../shared/blockEmpty.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\n\nfunction applyOps(store, ops) {\n if (typeof store.performBatch === 'function') store.performBatch(ops);\n else for (const op of ops) store.applyOperation(op);\n}\n\nexport function isBlankTitle(store, titleRunIds) {\n return (\n titleRunIds.length === 0 ||\n (titleRunIds.length === 1 && (store.getRun(titleRunIds[0])?.value ?? '') === '')\n );\n}\n\n/**\n * True when a list item's own nested content is empty — either no children\n * at all, or just its single seeded blank paragraph, still untouched. A\n * toggle item (collapsed !== undefined) is *always* seeded with one blank\n * paragraph child by createListItemBlock, so checking for literally zero\n * children (as the rest of this file used to) can never be true for a\n * toggle in practice — making an entirely empty toggle permanently\n * undeletable via Backspace. This treats \"just the untouched seeded\n * paragraph\" the same as \"no children\", matching the same fix already\n * applied to toggle heading (see toggleHeading/mergeCommands.js's\n * isBodyEmpty).\n */\nfunction isBodyEmpty(store, block) {\n const childIds = block.contentIds ?? [];\n if (childIds.length === 0) return true;\n if (childIds.length > 1) return false;\n const onlyChild = store.getBlock(childIds[0]);\n return (\n Boolean(onlyChild) && onlyChild.type === 'paragraph' && isRunsEmpty(store, onlyChild.contentIds)\n );\n}\n\n/**\n * Backspace-at-start-of-title behavior for a list item, distinct from\n * mergeWithPreviousOrDelete (paragraph/heading) because a list item's own\n * text lives in props.titleRunIds, not contentIds (contentIds holds nested\n * child items instead).\n *\n * - Previous sibling at this level is contentless (e.g. a divider): delete\n * *it* first and stay put, same convention as mergeWithPreviousOrDelete.\n * - Previous sibling at this level + this item is empty: just delete it.\n * - Previous sibling at this level + this item has text, no nested\n * children of its own: merge its title onto the previous sibling's title\n * (only when the previous sibling is also a listItem) and delete the\n * shell. If it has nested children, merging is skipped (v1 scope — see\n * navigationCommands' similar container-boundary caveat).\n * - No previous sibling, but nested under another list item: outdent\n * instead (matches common list-editor Backspace behavior).\n * - No previous sibling and already top-level: no-op (nothing sensible to\n * merge into without cross-container merging, which is out of scope).\n *\n * Returns `{ focusBlockId, needsRefocus }` or null if nothing happened.\n * `needsRefocus` distinguishes two cases that both return the item's own\n * id: after an outdent the item is reparented (a different contentIds\n * array owns it, so React remounts it and focus is lost — needsRefocus:\n * true); after deleting a preceding divider the item never moved (same\n * parent, same position, no remount — needsRefocus: false, the browser\n * keeps the caret where it already was).\n */\nexport function mergeListItemOrOutdent(store, blockId) {\n const block = store.getBlock(blockId);\n if (!block) return null;\n const parent = store.getBlock(block.parentId);\n const index = parent.contentIds.indexOf(blockId);\n const titleRunIds = block.props.titleRunIds ?? [];\n const titleEmpty = isBlankTitle(store, titleRunIds);\n // Entirely empty means BOTH the title and the nested body are empty (see\n // isBodyEmpty) — an empty title with real nested content underneath\n // (very common for a toggle, whose whole point is holding content under\n // a collapsed/expanded line) must not vanish along with its subtree just\n // because its own title happens to be blank right now.\n const empty = titleEmpty && isBodyEmpty(store, block);\n\n if (index > 0) {\n const prevId = parent.contentIds[index - 1];\n const prev = store.getBlock(prevId);\n\n // An empty CURRENT item goes first, even next to a non-editable\n // previous sibling (divider) — see the matching comment in\n // shared/mergeCommands.js for why this ordering matters.\n if (empty) {\n applyOps(store, [removeBlock(blockId)]);\n return { focusBlockId: prevId, needsRefocus: true };\n }\n\n if (isContentlessBlock(store, prev)) {\n applyOps(store, [removeBlock(prevId)]);\n return { focusBlockId: blockId, needsRefocus: false };\n }\n\n if (prev?.type === 'listItem' && block.contentIds.length === 0) {\n const mergedTitleRunIds = [...(prev.props.titleRunIds ?? []), ...titleRunIds];\n applyOps(store, [\n updateBlockProps(prevId, { titleRunIds: mergedTitleRunIds }),\n updateBlockProps(blockId, { titleRunIds: [] }), // detach before delete\n removeBlock(blockId),\n ]);\n return { focusBlockId: prevId, needsRefocus: true };\n }\n\n return null; // has nested children or previous sibling isn't a listItem: v1 skips this merge\n }\n\n if (parent.type === 'listItem') {\n outdentListItem(store, blockId);\n return { focusBlockId: blockId, needsRefocus: true }; // reparented: remounted, needs explicit refocus\n }\n\n // Top-level first item with nothing before it: real content stays put,\n // matching every other editor's \"Backspace at the absolute start is a\n // no-op when there's something to preserve\". But an entirely empty item\n // should still be removable — same \"never a permanent dead end\" fallback\n // as mergeToggleHeadingOrNoop/mergeWithPreviousOrDelete: without this, a\n // toggle (always seeded with one blank child) could never satisfy the old\n // \"contentIds.length === 0\" check, making it permanently undeletable\n // whenever it happens to be first/only in its container.\n if (!empty) return null;\n\n if (parent.contentIds.length > 1) {\n applyOps(store, [removeBlock(blockId)]);\n return { focusBlockId: store.getBlock(parent.id).contentIds[0], needsRefocus: true };\n }\n\n const { block: fallbackBlock, runs } = createTextLeafBlock('paragraph')(parent.id);\n applyOps(store, [\n insertBlock(fallbackBlock, parent.id, index, { blocks: [fallbackBlock], runs }),\n removeBlock(blockId),\n ]);\n return { focusBlockId: fallbackBlock.id, needsRefocus: true };\n}\n","import { insertBlock, removeBlock, updateBlockProps } from '../../store/operations.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\nimport { focusBlockStart } from '../shared/navigationCommands.js';\n\nfunction applyOps(store, ops) {\n if (typeof store.performBatch === 'function') store.performBatch(ops);\n else for (const op of ops) store.applyOperation(op);\n}\n\n/**\n * Enter on an empty, top-level (not nested under another list item),\n * childless list item exits the list entirely: it's replaced in place by\n * an empty paragraph, and focus moves there. Matches every other list\n * editor's \"Enter on the last empty bullet leaves the list\" convention —\n * the nested case (mergeCommands.js's outdent-on-empty) only pops one\n * level; this is the top-level equivalent that leaves the list altogether.\n */\nexport function exitListItemToParagraph(store, blockId) {\n const block = store.getBlock(blockId);\n const parentId = block.parentId;\n const parent = store.getBlock(parentId);\n const index = parent.contentIds.indexOf(blockId);\n const { block: paragraphBlock, runs } = createTextLeafBlock('paragraph')(parentId);\n\n applyOps(store, [\n insertBlock(paragraphBlock, parentId, index, { blocks: [paragraphBlock], runs }),\n updateBlockProps(blockId, { titleRunIds: [] }), // detach its own (empty) run before deleting\n removeBlock(blockId),\n ]);\n\n focusBlockStart(store, paragraphBlock.id);\n return paragraphBlock.id;\n}\n","import { useCallback } from 'react';\nimport { useBlock } from '../../react/useBlock.js';\nimport { useBlockChildren } from '../../react/useBlockChildren.js';\nimport { EditableBlockContent } from '../../react/EditableBlockContent.jsx';\nimport { BlockChildren } from '../../react/BlockChildren.jsx';\nimport {\n useEditorStore,\n useSelectedBlock,\n useBlockClassName,\n} from '../../react/EditorProvider.jsx';\nimport {\n listItemDepth,\n orderedItemIndex,\n orderedMarkerText,\n bulletMarkerText,\n} from './listMarkers.js';\nimport { ChevronRightIcon, ChevronDownIcon } from '../../react/icons.jsx';\nimport {\n insertSiblingSplitAtCaretAndFocus,\n insertFirstChildSplitAtCaretAndFocus,\n} from '../shared/blockCommands.js';\nimport { createListItemBlock } from './createListItemBlock.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\nimport { indentListItem, outdentListItem } from './indentCommands.js';\nimport { mergeListItemOrOutdent, isBlankTitle } from './mergeCommands.js';\nimport { exitListItemToParagraph } from './exitListItem.js';\nimport { isRunsEmpty } from '../shared/blockEmpty.js';\nimport { focusAfterMerge } from '../shared/focusAfterMerge.js';\nimport { updateBlockProps, insertBlock } from '../../store/operations.js';\nimport { focusAdjacentBlock } from '../shared/navigationCommands.js';\nimport { resolveBlockDir } from '../shared/resolveBlockDir.js';\nimport { focusRunEnd } from '../../react/focusRun.js';\n\nfunction applyOps(store, ops) {\n if (typeof store.performBatch === 'function') store.performBatch(ops);\n else for (const op of ops) store.applyOperation(op);\n}\n\n/**\n * Indentation/nesting is modeled the same way as every other container\n * block (parentId + contentIds referencing child block ids) — a list item's\n * own text lives in props.titleRunIds (run ids) rather than contentIds,\n * since a list item needs both an inline title *and* nested child blocks at\n * once, unlike a pure leaf (paragraph/heading) or pure container (page).\n *\n * When `props.checked` is not undefined, this doubles as a to-do item: the\n * marker becomes a checkbox instead of a bullet/number.\n */\nexport function ListItemBlock({ id }) {\n const store = useEditorStore();\n const block = useBlock(id);\n const { setSelectedBlockId } = useSelectedBlock();\n // Subscribed purely so this item re-renders when a SIBLING is inserted,\n // removed, or reordered at this level — needed to keep its own marker\n // (numbered position, or depth-based bullet/number style) correct, since\n // BlockRenderer's memo would otherwise skip re-rendering this item on a\n // sibling-only structural change (its own block data didn't change).\n // Cheap and scoped to exactly this list level, unlike the parent\n // (BlockChildren) re-rendering, which is unaffected either way.\n const siblingIds = useBlockChildren(block?.parentId);\n\n const handleEnter = useCallback(() => {\n // Enter on an empty item that's nested under another list item pops it\n // out one level instead of creating yet another empty nested item —\n // this is how the caret \"comes out\" of a list, matching every other\n // list editor's convention.\n const titleRunIds = block?.props?.titleRunIds ?? [];\n const parent = store.getBlock(block?.parentId);\n const empty = isBlankTitle(store, titleRunIds);\n\n if (empty && parent?.type === 'listItem') {\n outdentListItem(store, id); // refocuses itself (reparenting remounts the DOM)\n return;\n }\n\n // Enter on an empty, top-level, childless item exits the list\n // altogether (becomes a paragraph) — matches the same convention every\n // other list editor uses for \"Enter on the last empty bullet\".\n const hasNestedChildren = (block?.contentIds?.length ?? 0) > 0;\n if (empty && parent?.type !== 'listItem' && !hasNestedChildren) {\n exitListItemToParagraph(store, id);\n return;\n }\n\n const isTodo = block?.props?.checked !== undefined;\n const isToggle = block?.props?.collapsed !== undefined;\n const factory = createListItemBlock({\n ordered: block?.props?.ordered,\n checked: isTodo ? false : undefined,\n collapsed: isToggle ? false : undefined,\n });\n\n // If this item already has nested children, the new item belongs at\n // the SAME indent level as those children, positioned before them —\n // not as this item's own sibling, which would render below the entire\n // nested list instead of right after the line the caret is on. This\n // does NOT apply to a toggle: its contentIds are the collapsible body,\n // not \"the next line of a continued list\" — Enter on a toggle's own\n // title always creates a new sibling toggle at the same level,\n // (Tab is the only way to nest something under it).\n if (hasNestedChildren && !isToggle) {\n insertFirstChildSplitAtCaretAndFocus(store, id, titleRunIds, factory);\n } else {\n insertSiblingSplitAtCaretAndFocus(store, id, titleRunIds, factory);\n }\n }, [store, id, block]);\n\n const handleTab = useCallback(() => indentListItem(store, id), [store, id]);\n const handleShiftTab = useCallback(() => outdentListItem(store, id), [store, id]);\n\n const handleBackspaceAtStart = useCallback(() => {\n const result = mergeListItemOrOutdent(store, id);\n if (!result || !result.needsRefocus) return; // no-op, or stayed in place with no remount\n focusAfterMerge(store, result.focusBlockId, id, setSelectedBlockId);\n }, [store, id, setSelectedBlockId]);\n\n const handleArrowUp = useCallback(() => focusAdjacentBlock(store, id, 'up'), [store, id]);\n const handleArrowDown = useCallback(() => focusAdjacentBlock(store, id, 'down'), [store, id]);\n\n const toggleChecked = useCallback(() => {\n store.applyOperation(updateBlockProps(id, { checked: !block?.props?.checked }));\n }, [store, id, block?.props?.checked]);\n\n const toggleCollapsed = useCallback(() => {\n const hasChildren = (block?.contentIds?.length ?? 0) > 0;\n if (!hasChildren) {\n // A childless toggle has nothing to expand/collapse yet — this was\n // previously a disabled dead end (no way to ever get content into a\n // toggle that didn't happen to be seeded with a child already, e.g.\n // one created before the seeding in createListItemBlock existed, or\n // one whose only child was removed by some other action). Clicking\n // now bootstraps the first (empty) child and expands, the same\n // seeded shape callout/toggleHeading start with.\n const { block: childBlock, runs } = createTextLeafBlock('paragraph')(id);\n applyOps(store, [\n insertBlock(childBlock, id, 0, { blocks: [childBlock], runs }),\n updateBlockProps(id, { collapsed: false }),\n ]);\n focusRunEnd(childBlock.contentIds[0]);\n return;\n }\n store.applyOperation(updateBlockProps(id, { collapsed: !block?.props?.collapsed }));\n }, [store, id, block?.contentIds, block?.props?.collapsed]);\n\n const className = useBlockClassName('be-list-item', block);\n\n if (!block) return null;\n const { ordered, checked, collapsed, titleRunIds = [] } = block.props;\n const isTodo = checked !== undefined;\n const isToggle = !isTodo && collapsed !== undefined;\n const hasNestedChildren = block.contentIds.length > 0;\n // Best-effort accessible name for the checkbox: a native checkbox with no\n // name reads to a screen reader as just \"checkbox, checked/not checked\",\n // with no indication of *which* to-do it's for. Atomic (non-text) runs\n // contribute nothing here — this is a plain-text summary, not a full\n // serialization.\n const titleText = titleRunIds\n .map((runId) => store.getRun(runId))\n .filter((run) => run?.type === 'text')\n .map((run) => run.value)\n .join('')\n .trim();\n const dir = resolveBlockDir(store, block);\n\n return (\n <div className={className} data-block-id={id} dir={dir}>\n <div className=\"be-list-item-row\">\n {isTodo ? (\n <input\n type=\"checkbox\"\n className=\"be-list-checkbox\"\n checked={Boolean(checked)}\n onChange={toggleChecked}\n aria-label={titleText || 'To-do item'}\n />\n ) : isToggle ? (\n // A real button (not decorative, unlike the plain bullet/number\n // marker below): it's the only way to reveal/hide this item's\n // children, so assistive tech needs to know it's interactive and\n // what state it's in.\n <button\n type=\"button\"\n className=\"be-list-toggle-marker\"\n onClick={toggleCollapsed}\n aria-expanded={!collapsed}\n aria-label={\n !hasNestedChildren\n ? 'Add content to toggle'\n : collapsed\n ? 'Expand toggle'\n : 'Collapse toggle'\n }\n >\n {collapsed ? <ChevronRightIcon /> : <ChevronDownIcon />}\n </button>\n ) : (\n // Decorative: list structure/position is conveyed by the DOM\n // order itself, not by this glyph, so it's hidden from assistive\n // tech. The glyph itself cycles with nesting depth (1,2,3 ->\n // a,b,c -> i,ii,iii for numbered; disc -> circle -> square for\n // bulleted, repeating every 3 levels), a common list-nesting\n // convention — see listMarkers.js.\n <span className=\"be-list-marker\" aria-hidden=\"true\">\n {ordered\n ? orderedMarkerText(\n listItemDepth(store, block),\n orderedItemIndex(store, block, siblingIds),\n )\n : bulletMarkerText(listItemDepth(store, block))}\n </span>\n )}\n <div\n className=\"be-list-item-title\"\n data-empty={isRunsEmpty(store, titleRunIds) ? '' : undefined}\n data-placeholder={isTodo ? 'To-do' : isToggle ? 'Toggle' : 'List item'}\n style={checked ? { textDecoration: 'line-through', opacity: 0.6 } : undefined}\n >\n <EditableBlockContent\n blockId={id}\n runIds={titleRunIds}\n dir={dir}\n onEnter={handleEnter}\n onTab={handleTab}\n onShiftTab={handleShiftTab}\n onBackspaceAtStart={handleBackspaceAtStart}\n onArrowUp={handleArrowUp}\n onArrowDown={handleArrowDown}\n />\n </div>\n </div>\n {/*\n A toggle's children stay in the store (contentIds unchanged) while\n collapsed — only the DOM for them is skipped. Copy/cut/paste,\n select-all, and serialization all walk contentIds directly and have\n no notion of \"collapsed\" at all, so a collapsed toggle's hidden\n content still copies/serializes/undoes correctly for free; this is\n the only place collapsed state has any effect.\n */}\n {(!isToggle || !collapsed) && (\n <div className=\"be-list-item-children\">\n <BlockChildren parentId={id} />\n </div>\n )}\n </div>\n );\n}\n","import { ListItemBlock } from './ListItemBlock.jsx';\nimport { defineBlock } from '../../registry/define.js';\nimport { runToHTML, runToPlainText, runsToMarkdown } from '../../inline/marks.js';\nimport { domInlineToRuns } from '../../inline/runOps.js';\nimport { genId } from '../../utils/idGen.js';\nimport { trimSlashQueryAndInsertAfter } from '../shared/blockCommands.js';\nimport { createListItemBlock } from './createListItemBlock.js';\nimport {\n BulletedListIcon,\n NumberedListIcon,\n CheckboxIcon,\n ChevronRightIcon,\n} from '../../react/icons.jsx';\n\n/**\n * Emits just `<li>...</li>` (with nested `<ul>/<ol>` for indented children).\n * Grouping consecutive sibling list items into one wrapping `<ul>/<ol>` is\n * the container serializer's job (see clipboard/serialize.js), not this\n * block type's — a single item doesn't know about its siblings.\n */\nfunction toHTML(block, ctx) {\n const { titleRunIds = [], ordered } = block.props;\n const titleHTML = titleRunIds.map((runId) => runToHTML(ctx.store.getRun(runId), ctx)).join('');\n const childrenHTML = block.contentIds\n .map((childId) =>\n ctx.registry.get(ctx.store.getBlock(childId).type).toHTML(ctx.store.getBlock(childId), ctx),\n )\n .join('');\n const nested = childrenHTML\n ? `<${ordered ? 'ol' : 'ul'}>${childrenHTML}</${ordered ? 'ol' : 'ul'}>`\n : '';\n return `<li>${titleHTML}${nested}</li>`;\n}\n\nfunction toPlainText(block, ctx) {\n const { titleRunIds = [] } = block.props;\n return titleRunIds.map((runId) => runToPlainText(ctx.store.getRun(runId), ctx)).join('');\n}\n\n/**\n * Nested children are indented two spaces per level and recursed into\n * directly here (rather than left to a container joiner) — same\n * self-contained-nesting idea as this type's own toHTML building its\n * nested `<ul>/<ol>` inline. `ordered` always emits \"1.\" (Markdown\n * renderers auto-number a list regardless of which digit each line uses,\n * so there's no need to track this item's actual position among its\n * siblings). `collapsed` (a toggle item) has no native Markdown disclosure\n * widget, so it degrades to a plain bullet — same \"no exact equivalent,\n * fall back to something readable\" choice `toggleHeading` makes in its own\n * `toMarkdown` below.\n */\nfunction toMarkdown(block, ctx) {\n const { titleRunIds = [], ordered, checked } = block.props;\n const marker = checked !== undefined ? (checked ? '- [x] ' : '- [ ] ') : ordered ? '1. ' : '- ';\n const title = runsToMarkdown(\n titleRunIds.map((runId) => ctx.store.getRun(runId)),\n ctx,\n );\n const childrenMd = block.contentIds\n .map((childId) => {\n const child = ctx.store.getBlock(childId);\n const entry = ctx.registry.get(child.type);\n const childMd = (entry.toMarkdown ?? entry.toPlainText)(child, ctx);\n return childMd\n .split('\\n')\n .map((line) => (line ? ` ${line}` : line))\n .join('\\n');\n })\n .join('\\n');\n return childrenMd ? `${marker}${title}\\n${childrenMd}` : `${marker}${title}`;\n}\n\n/** Builds one list item block (+ its nested list items) from a single <li>. */\nfunction fromLiNode(liNode, ctx) {\n const inlineNodes = [];\n const nestedListNodes = [];\n for (const child of liNode.childNodes) {\n if (child.nodeType === 1 && (child.tagName === 'UL' || child.tagName === 'OL')) {\n nestedListNodes.push(child);\n } else {\n inlineNodes.push(child);\n }\n }\n\n const wrapper = liNode.ownerDocument.createElement('span');\n for (const n of inlineNodes) wrapper.appendChild(n.cloneNode(true));\n const titleRuns = domInlineToRuns(wrapper, ctx);\n\n const blockId = genId();\n const childRuns = [...titleRuns];\n const childBlocks = [];\n const contentIds = [];\n\n for (const listNode of nestedListNodes) {\n const ordered = listNode.tagName === 'OL';\n for (const li of listNode.children) {\n if (li.tagName !== 'LI') continue;\n const nested = fromLiNode(li, ctx);\n nested.block.parentId = blockId;\n nested.block.props.ordered = ordered;\n childBlocks.push(nested.block, ...nested.childBlocks);\n childRuns.push(...nested.runs);\n contentIds.push(nested.block.id);\n }\n }\n\n const block = {\n id: blockId,\n type: 'listItem',\n parentId: null,\n contentIds,\n props: { ordered: false, titleRunIds: titleRuns.map((r) => r.id) },\n };\n\n return { block, runs: childRuns, childBlocks };\n}\n\nfunction fromHTML(node, ctx) {\n if (node.tagName !== 'LI') return null;\n const { block, runs, childBlocks } = fromLiNode(node, ctx);\n return { block, runs, subtreeBlocks: childBlocks };\n}\n\nexport const listItemBlockType = defineBlock({\n name: 'listItem',\n contentModel: 'blocks',\n component: ListItemBlock,\n defaultProps: { ordered: false, titleRunIds: [] },\n toHTML,\n toPlainText,\n toMarkdown,\n fromHTML,\n slashCommands: [\n {\n label: 'Bulleted list',\n icon: BulletedListIcon,\n keywords: ['list', 'bullet', 'ul'],\n run: (store, ctx) =>\n trimSlashQueryAndInsertAfter(store, ctx, createListItemBlock({ ordered: false })),\n },\n {\n label: 'Numbered list',\n icon: NumberedListIcon,\n keywords: ['list', 'number', 'ordered', 'ol'],\n run: (store, ctx) =>\n trimSlashQueryAndInsertAfter(store, ctx, createListItemBlock({ ordered: true })),\n },\n {\n label: 'To-do list',\n icon: CheckboxIcon,\n keywords: ['todo', 'checkbox', 'task', 'checklist'],\n run: (store, ctx) =>\n trimSlashQueryAndInsertAfter(\n store,\n ctx,\n createListItemBlock({ ordered: false, checked: false }),\n ),\n },\n {\n label: 'Toggle list',\n icon: ChevronRightIcon,\n keywords: ['toggle', 'collapse', 'expand', 'dropdown', 'accordion'],\n run: (store, ctx) =>\n trimSlashQueryAndInsertAfter(\n store,\n ctx,\n createListItemBlock({ ordered: false, collapsed: false }),\n ),\n },\n ],\n});\n","import { genId } from '../../utils/idGen.js';\n\nexport const COLUMN_TYPES = ['text', 'date', 'checkbox', 'select'];\nexport const DEFAULT_COLUMN_TYPE = 'text';\nexport const DEFAULT_COLUMN_WIDTH = 160;\nexport const MIN_COLUMN_WIDTH = 80;\n\nexport function defaultColumnLabel(index) {\n return `Column ${index + 1}`;\n}\n\nexport function createDefaultColumns(count) {\n return Array.from({ length: count }, (_, i) => ({\n id: genId(),\n label: defaultColumnLabel(i),\n type: DEFAULT_COLUMN_TYPE,\n width: DEFAULT_COLUMN_WIDTH,\n }));\n}\n\n/**\n * Returns a table's column metadata (`{ id, label, type, width }` per\n * column), falling back to generated (all-text, default-width) defaults\n * when it's missing or the wrong length — a table pasted in from external\n * HTML, loaded from a document saved before this feature existed, or\n * hand-built by a host app never had a chance to set `props.columns` at\n * all, and it's cheap insurance against a stale array (e.g. a column\n * added/removed through a code path that didn't know to keep it in sync)\n * ever crashing the header row instead of just re-deriving something\n * sensible. Also fills in `type: 'text'`/`width: DEFAULT_COLUMN_WIDTH` for\n * any column entry that predates those fields.\n */\nexport function resolveColumns(table, colCount) {\n const columns = table.props?.columns;\n if (!Array.isArray(columns) || columns.length !== colCount) return createDefaultColumns(colCount);\n return columns.map((c) => {\n const type = c.type ?? DEFAULT_COLUMN_TYPE;\n const width = c.width ?? DEFAULT_COLUMN_WIDTH;\n return type === c.type && width === c.width ? c : { ...c, type, width };\n });\n}\n\n/**\n * A blank run of the given column type — the shape reused table-wide,\n * whether creating a fresh cell or converting an existing one. A \"select\"\n * column's runs are `tableSelect` runs with no options of their own — the\n * shared, column-level `options` array (see resolveColumns) is the single\n * source of truth every cell's dropdown reads from, so a brand new blank\n * cell in an already-typed select column immediately gets the same\n * choices as every other cell in that column, with nothing to seed here.\n */\nexport function blankRunForType(type) {\n switch (type) {\n case 'date':\n return { id: genId(), type: 'date', value: '', marks: {}, data: { isoDate: '' } };\n case 'checkbox':\n return {\n id: genId(),\n type: 'checkbox',\n value: '',\n marks: {},\n data: { checked: false, label: '' },\n };\n case 'select':\n return {\n id: genId(),\n type: 'tableSelect',\n value: '',\n marks: {},\n data: { selectedValue: '', selectedLabel: '' },\n };\n default:\n return { id: genId(), type: 'text', value: '', marks: {} };\n }\n}\n\n/** A fresh empty cell block + its one run, matching `column`'s type — the single \"create a table cell\" primitive every row/column insert path shares. */\nexport function createCellForColumn(parentId, column) {\n const run = blankRunForType(column?.type);\n return {\n block: { id: genId(), type: 'tableCell', parentId, contentIds: [run.id], props: {} },\n run,\n };\n}\n\n/**\n * Converts one existing run to `newType`, attempting to preserve its data\n * rather than silently discarding it (the bug this whole feature set was\n * partly motivated by fixing, compared to the legacy notevo table's\n * \"change type wipes the cell\" behavior). Converting *from* a non-text\n * atomic type reads its plain-text value via the old type's own\n * `toPlainText` (through the inline registry) rather than needing a\n * hand-written conversion for every type pair — e.g. a date becomes its\n * formatted string, which then seeds the new checkbox's label, etc.\n * `inlineRegistry` may be omitted only when `run.type` is already `'text'`\n * (no lookup needed for that case).\n *\n * Does NOT handle `newType === 'select'` — converting a whole column *to*\n * select needs to look at every cell together (to build one shared,\n * deduplicated option list), which a single-run function can't do; see\n * setColumnType's own dedicated handling for that case instead.\n */\nexport function convertRunToType(run, newType, inlineRegistry) {\n if (run.type === newType) return run;\n\n let text;\n if (run.type === 'text') {\n text = run.value ?? '';\n } else {\n const entry = inlineRegistry?.get(run.type);\n text = entry?.toPlainText ? entry.toPlainText(run) : '';\n }\n\n if (newType === 'date') {\n const parsed = text ? new Date(text) : null;\n const isoDate =\n parsed && !Number.isNaN(parsed.getTime()) ? parsed.toISOString().slice(0, 10) : '';\n return { id: genId(), type: 'date', value: '', marks: {}, data: { isoDate } };\n }\n if (newType === 'checkbox') {\n return {\n id: genId(),\n type: 'checkbox',\n value: '',\n marks: {},\n data: { checked: false, label: text },\n };\n }\n return { id: genId(), type: 'text', value: text, marks: {} };\n}\n","/**\n * Pure sort/filter/aggregate math for a table — no store mutation here (see\n * tableEditCommands.js's `sortTableByColumn`/`setColumnAggregate` for the\n * operations that apply this). Kept separate so the comparison/aggregate\n * logic itself is trivially unit-testable without an EditorStore.\n */\n\n/** A cell run's plain-text value, regardless of type (text/date/checkbox/tableSelect) — the single shared helper every sort/filter/aggregate/conversion path in this table feature set reuses instead of re-deriving. */\nexport function runPlainText(run, inlineRegistry) {\n if (!run) return '';\n if (run.type === 'text') return run.value ?? '';\n const entry = inlineRegistry?.get(run.type);\n return entry?.toPlainText ? entry.toPlainText(run) : '';\n}\n\n/** The value a column's own type cares about for sorting/aggregating — not always the same as its rendered plain text (a checkbox sorts by checked state, a date by its ISO string, not a locale-formatted display string). */\nfunction sortKeyForColumn(run, columnType, inlineRegistry) {\n if (columnType === 'date') return run?.data?.isoDate ?? '';\n if (columnType === 'checkbox') return run?.data?.checked ? 1 : 0;\n if (columnType === 'select') return (run?.data?.selectedLabel ?? '').trim();\n return runPlainText(run, inlineRegistry).trim();\n}\n\nfunction compareValues(a, b, columnType) {\n if (columnType === 'checkbox') return a - b;\n // Numeric-ish text/select values (e.g. a \"text\" column holding numbers,\n // a common real-world case) sort numerically when BOTH sides parse\n // cleanly; otherwise falls back to a locale-aware string compare.\n const na = Number(a);\n const nb = Number(b);\n if (a !== '' && b !== '' && !Number.isNaN(na) && !Number.isNaN(nb)) return na - nb;\n return String(a).localeCompare(String(b), undefined, { sensitivity: 'base' });\n}\n\n/**\n * Sorts `rows` (`[{ rowId, run }]`, one entry per row's cell in the target\n * column) by that column's own type-aware comparison — returns just the\n * reordered `rowId`s. Blank cells always sort to the end regardless of\n * `direction` (the common spreadsheet convention), so switching a sort's\n * direction doesn't make empty rows jump from the bottom to the top.\n */\nexport function sortRowIdsByColumn(rows, columnType, direction, inlineRegistry) {\n const withKeys = rows.map(({ rowId, run }) => ({\n rowId,\n key: sortKeyForColumn(run, columnType, inlineRegistry),\n }));\n const isEmptyKey = (key) => key === '' || key == null;\n\n withKeys.sort((a, b) => {\n const aEmpty = isEmptyKey(a.key);\n const bEmpty = isEmptyKey(b.key);\n if (aEmpty && bEmpty) return 0;\n if (aEmpty) return 1;\n if (bEmpty) return -1;\n const cmp = compareValues(a.key, b.key, columnType);\n return direction === 'desc' ? -cmp : cmp;\n });\n\n return withKeys.map((r) => r.rowId);\n}\n\nexport const AGGREGATE_TYPES = [\n 'none',\n 'count',\n 'count-values',\n 'count-empty',\n 'sum',\n 'average',\n 'min',\n 'max',\n];\n\nexport const AGGREGATE_LABELS = {\n none: 'None',\n count: 'Count all',\n 'count-values': 'Count filled',\n 'count-empty': 'Count empty',\n sum: 'Sum',\n average: 'Average',\n min: 'Min',\n max: 'Max',\n};\n\n/** Compact prefix shown in the table footer cell itself — the full labels above are for the dropdown, where there's room to spell them out. */\nexport const AGGREGATE_SHORT_LABELS = {\n count: 'Count',\n 'count-values': 'Filled',\n 'count-empty': 'Empty',\n sum: 'Sum',\n average: 'Avg',\n min: 'Min',\n max: 'Max',\n};\n\n/**\n * Computes one column's footer aggregate over `runs` (the cell run of each\n * currently-VISIBLE row in that column, so a filtered-out row never\n * contributes) — a lightweight, dependency-free \"computed column\" stand-in\n * for a real formula engine, which this zero-runtime-dependency package\n * deliberately doesn't ship (no expression parser/evaluator, no\n * user-authored code execution surface). `sum`/`average`/`min`/`max` parse\n * each run's own plain text as a number, silently skipping any run that\n * doesn't parse (a text/select column holding numbers works the same as a\n * dedicated \"number\" column would, since there isn't one) — a column with\n * no numeric values at all returns `null` for those four rather than `0`,\n * so the footer can show an honest \"—\" instead of a misleading zero.\n */\nexport function computeColumnAggregate(runs, columnType, aggregateType, inlineRegistry) {\n if (!aggregateType || aggregateType === 'none') return null;\n if (aggregateType === 'count') return runs.length;\n\n const texts = runs.map((run) => runPlainText(run, inlineRegistry).trim());\n if (aggregateType === 'count-values') return texts.filter((t) => t !== '').length;\n if (aggregateType === 'count-empty') return texts.filter((t) => t === '').length;\n\n const numbers = texts.map(Number).filter((n, i) => texts[i] !== '' && !Number.isNaN(n));\n if (numbers.length === 0) return null;\n if (aggregateType === 'sum') return numbers.reduce((a, b) => a + b, 0);\n if (aggregateType === 'average') return numbers.reduce((a, b) => a + b, 0) / numbers.length;\n if (aggregateType === 'min') return Math.min(...numbers);\n if (aggregateType === 'max') return Math.max(...numbers);\n return null;\n}\n\n/** Formats an aggregate's numeric result for display — integers print bare, non-integers round to 2 decimal places (avoids ugly floating-point noise like 3.300000000000001 from a sum of decimals). */\nexport function formatAggregateValue(value) {\n if (value == null) return '';\n if (Number.isInteger(value)) return String(value);\n return value.toFixed(2);\n}\n","import {\n removeBlock,\n insertBlock,\n updateBlockProps,\n setBlockRuns,\n updateRun,\n setBlockContentIds,\n} from '../../store/operations.js';\nimport { genId } from '../../utils/idGen.js';\nimport { focusBlockStart } from '../shared/navigationCommands.js';\nimport { ensureRootNonEmpty } from '../shared/ensureRootNonEmpty.js';\nimport {\n resolveColumns,\n createCellForColumn,\n convertRunToType,\n DEFAULT_COLUMN_TYPE,\n DEFAULT_COLUMN_WIDTH,\n MIN_COLUMN_WIDTH,\n} from './tableColumns.js';\nimport { sortRowIdsByColumn, runPlainText } from './tableView.js';\n\nfunction applyOps(store, ops) {\n if (typeof store.performBatch === 'function') store.performBatch(ops);\n else for (const op of ops) store.applyOperation(op);\n}\n\n/** Removes the whole table (used when deleting its last row/column) and focuses whatever's now at its old position. */\nfunction removeTableAndFocusSibling(store, table) {\n const parent = store.getBlock(table.parentId);\n const tableIndex = parent.contentIds.indexOf(table.id);\n applyOps(store, [removeBlock(table.id)]);\n\n // The table may have been the only block in the whole document — never\n // leave the document with zero blocks (see ensureRootNonEmpty).\n const fallbackParagraphId = ensureRootNonEmpty(store);\n if (fallbackParagraphId) {\n focusBlockStart(store, fallbackParagraphId);\n return null;\n }\n\n const parentAfter = store.getBlock(table.parentId);\n const siblingId = parentAfter.contentIds[tableIndex] ?? parentAfter.contentIds[tableIndex - 1];\n if (siblingId) focusBlockStart(store, siblingId);\n return null;\n}\n\n/**\n * Inserts a new empty row right after `rowId`, with the same column count,\n * and focuses its first cell. Each new cell matches its own column's\n * configured type (see tableColumns.js) — a date/select/checkbox column\n * keeps getting date/select/checkbox cells for every row added after it\n * was typed, not a plain blank text cell.\n */\nexport function insertRowAfter(store, rowId) {\n const row = store.getBlock(rowId);\n const table = store.getBlock(row.parentId);\n const rowIndex = table.contentIds.indexOf(rowId);\n const columns = resolveColumns(table, row.contentIds.length);\n\n const newRowId = genId();\n const cellBlocks = [];\n const runs = [];\n const contentIds = [];\n for (const column of columns) {\n const cell = createCellForColumn(newRowId, column);\n cellBlocks.push(cell.block);\n runs.push(cell.run);\n contentIds.push(cell.block.id);\n }\n const newRow = { id: newRowId, type: 'tableRow', parentId: table.id, contentIds, props: {} };\n\n store.applyOperation(\n insertBlock(newRow, table.id, rowIndex + 1, { blocks: [newRow, ...cellBlocks], runs }),\n );\n focusBlockStart(store, newRowId);\n return newRowId;\n}\n\n/**\n * Removes a row. If it's the table's only row, removes the whole table\n * instead (nothing left to show otherwise) and focuses the block now at\n * the table's old position. Otherwise focuses the row that ends up in the\n * same slot (the next row, or the new-last row if the deleted one was last).\n */\nexport function deleteRow(store, rowId) {\n const row = store.getBlock(rowId);\n const table = store.getBlock(row.parentId);\n\n if (table.contentIds.length <= 1) {\n return removeTableAndFocusSibling(store, table);\n }\n\n const rowIndex = table.contentIds.indexOf(rowId);\n applyOps(store, [removeBlock(rowId)]);\n\n const updatedTable = store.getBlock(table.id);\n const targetRowIndex = Math.min(rowIndex, updatedTable.contentIds.length - 1);\n const targetRowId = updatedTable.contentIds[targetRowIndex];\n if (targetRowId) focusBlockStart(store, targetRowId);\n return targetRowId ?? null;\n}\n\n/** Inserts a new (always plain-text) column at `colIndex + 1` in every row of the table, and focuses the first new cell. One atomic undo step, including the new column's metadata. */\nexport function insertColumnAfter(store, tableId, colIndex) {\n const table = store.getBlock(tableId);\n const currentColumns = resolveColumns(\n table,\n table.contentIds[0] ? store.getBlock(table.contentIds[0]).contentIds.length : 0,\n );\n const newColumn = {\n id: genId(),\n label: 'New Column',\n type: DEFAULT_COLUMN_TYPE,\n width: DEFAULT_COLUMN_WIDTH,\n };\n const ops = [];\n let firstNewCellId = null;\n\n for (const rowId of table.contentIds) {\n const cell = createCellForColumn(rowId, newColumn);\n if (firstNewCellId === null) firstNewCellId = cell.block.id;\n ops.push(\n insertBlock(cell.block, rowId, colIndex + 1, { blocks: [cell.block], runs: [cell.run] }),\n );\n }\n\n const nextColumns = [...currentColumns];\n nextColumns.splice(colIndex + 1, 0, newColumn);\n ops.push(updateBlockProps(tableId, { columns: nextColumns }));\n\n applyOps(store, ops);\n if (firstNewCellId) focusBlockStart(store, firstNewCellId);\n return firstNewCellId;\n}\n\n/**\n * Removes the cell at `colIndex` from every row. If it's the table's only\n * column, removes the whole table instead (same convention as deleteRow).\n * Otherwise focuses the cell now in the same column slot of the first row.\n * One atomic undo step, including the removed column's metadata.\n */\nexport function deleteColumn(store, tableId, colIndex) {\n const table = store.getBlock(tableId);\n const firstRow = store.getBlock(table.contentIds[0]);\n\n if (!firstRow || firstRow.contentIds.length <= 1) {\n return removeTableAndFocusSibling(store, table);\n }\n\n const currentColumns = resolveColumns(table, firstRow.contentIds.length);\n const ops = table.contentIds.map((rowId) => {\n const row = store.getBlock(rowId);\n return removeBlock(row.contentIds[colIndex]);\n });\n const nextColumns = currentColumns.filter((_, i) => i !== colIndex);\n ops.push(updateBlockProps(tableId, { columns: nextColumns }));\n applyOps(store, ops);\n\n const updatedFirstRow = store.getBlock(table.contentIds[0]);\n const targetColIndex = Math.min(colIndex, updatedFirstRow.contentIds.length - 1);\n const targetCellId = updatedFirstRow.contentIds[targetColIndex];\n if (targetCellId) focusBlockStart(store, targetCellId);\n return targetCellId ?? null;\n}\n\n/** Sets the column at `colIndex`'s pixel width (clamped to MIN_COLUMN_WIDTH) — one atomic undo step. */\nexport function setColumnWidth(store, tableId, colIndex, width) {\n const table = store.getBlock(tableId);\n const firstRow = store.getBlock(table.contentIds[0]);\n const currentColumns = resolveColumns(table, firstRow ? firstRow.contentIds.length : 0);\n if (!currentColumns[colIndex]) return;\n const nextColumns = [...currentColumns];\n nextColumns[colIndex] = {\n ...currentColumns[colIndex],\n width: Math.max(MIN_COLUMN_WIDTH, Math.round(width)),\n };\n store.applyOperation(updateBlockProps(tableId, { columns: nextColumns }));\n}\n\n/** Renames the column at `colIndex` — one atomic undo step. */\nexport function renameColumn(store, tableId, colIndex, label) {\n const table = store.getBlock(tableId);\n const firstRow = store.getBlock(table.contentIds[0]);\n const currentColumns = resolveColumns(table, firstRow ? firstRow.contentIds.length : 0);\n const nextColumns = [...currentColumns];\n if (!nextColumns[colIndex]) return;\n nextColumns[colIndex] = { ...nextColumns[colIndex], label };\n store.applyOperation(updateBlockProps(tableId, { columns: nextColumns }));\n}\n\n/**\n * Physically reorders the table's rows by the column at `colIndex` — a\n * one-time action (like a spreadsheet's \"Sort A→Z\"), not a live-maintained\n * view: rows keep this order until sorted again, edited, or manually\n * reordered, rather than continuously re-sorting as cell values change.\n * One atomic undo step via `setBlockContentIds`, whose own inverse is the\n * table's exact previous row order.\n *\n * Same collaboration scope as any other wholesale `contentIds` rewrite\n * (see `SET_BLOCK_CONTENT_IDS` in EditorStore.js) — local-only for now, no\n * live broadcast to already-connected peers; an already-open row order\n * resyncs correctly on their next full-document reconnect.\n */\nexport function sortTableByColumn(store, tableId, colIndex, direction, inlineRegistry) {\n const table = store.getBlock(tableId);\n const rows = table.contentIds.map((rowId) => {\n const row = store.getBlock(rowId);\n const cell = store.getBlock(row.contentIds[colIndex]);\n return { rowId, run: cell ? store.getRun(cell.contentIds[0]) : null };\n });\n const columns = resolveColumns(\n table,\n rows.length ? store.getBlock(table.contentIds[0]).contentIds.length : 0,\n );\n const columnType = columns[colIndex]?.type ?? DEFAULT_COLUMN_TYPE;\n\n const orderedIds = sortRowIdsByColumn(rows, columnType, direction, inlineRegistry);\n store.applyOperation(setBlockContentIds(tableId, orderedIds));\n}\n\n/** Sets the column at `colIndex`'s footer aggregate (see tableView.js's AGGREGATE_TYPES) — one atomic undo step. */\nexport function setColumnAggregate(store, tableId, colIndex, aggregate) {\n const table = store.getBlock(tableId);\n const firstRow = store.getBlock(table.contentIds[0]);\n const currentColumns = resolveColumns(table, firstRow ? firstRow.contentIds.length : 0);\n if (!currentColumns[colIndex]) return;\n const nextColumns = [...currentColumns];\n nextColumns[colIndex] = { ...currentColumns[colIndex], aggregate };\n store.applyOperation(updateBlockProps(tableId, { columns: nextColumns }));\n}\n\nfunction cellRunsForColumn(store, table, colIndex) {\n return table.contentIds.map((rowId) => {\n const row = store.getBlock(rowId);\n const cellId = row.contentIds[colIndex];\n const cell = store.getBlock(cellId);\n return { cellId, run: store.getRun(cell.contentIds[0]) };\n });\n}\n\n/**\n * Changing a column *to* select needs every cell's current value at once\n * (to build one shared, deduplicated option list — the common \"text ->\n * select\" convention: one tag per distinct existing string, not one per\n * cell), which is why it's split out from the generic per-run\n * convertRunToType. Each cell is assigned whichever option matches its own\n * former text (blank cells stay unselected).\n */\nfunction buildSelectColumnConversion(store, table, colIndex, inlineRegistry) {\n const cellRuns = cellRunsForColumn(store, table, colIndex);\n const options = [];\n const optionByLabel = new Map();\n\n for (const { run } of cellRuns) {\n const text = runPlainText(run, inlineRegistry).trim();\n if (!text || optionByLabel.has(text)) continue;\n const option = { value: genId(), label: text };\n optionByLabel.set(text, option);\n options.push(option);\n }\n\n const newRuns = cellRuns.map(({ cellId, run }) => {\n const text = runPlainText(run, inlineRegistry).trim();\n const option = optionByLabel.get(text);\n return {\n cellId,\n run: {\n id: genId(),\n type: 'tableSelect',\n value: '',\n marks: {},\n data: { selectedValue: option?.value ?? '', selectedLabel: option?.label ?? '' },\n },\n };\n });\n\n return { options, newRuns };\n}\n\n/**\n * Changes the column at `colIndex` to `newType`, converting every existing\n * cell's run in that column instead of discarding their data (unlike the\n * legacy notevo table this was modeled after, which silently wiped a\n * column's values on any type change). `inlineRegistry` is needed to read\n * a non-text run's plain-text value when converting *away* from an atomic\n * type (date/checkbox/select) — pass the one from `useInlineRegistry()`.\n * One atomic undo step for the whole column, metadata and every cell\n * together.\n */\nexport function setColumnType(store, tableId, colIndex, newType, inlineRegistry) {\n const table = store.getBlock(tableId);\n const firstRow = store.getBlock(table.contentIds[0]);\n const currentColumns = resolveColumns(table, firstRow ? firstRow.contentIds.length : 0);\n const column = currentColumns[colIndex];\n if (!column || column.type === newType) return;\n\n const nextColumns = [...currentColumns];\n\n if (newType === 'select') {\n const { options, newRuns } = buildSelectColumnConversion(\n store,\n table,\n colIndex,\n inlineRegistry,\n );\n nextColumns[colIndex] = { ...column, type: newType, options };\n const ops = [updateBlockProps(tableId, { columns: nextColumns })];\n for (const { cellId, run } of newRuns) ops.push(setBlockRuns(cellId, [run]));\n applyOps(store, ops);\n return;\n }\n\n nextColumns[colIndex] = { ...column, type: newType };\n const ops = [updateBlockProps(tableId, { columns: nextColumns })];\n for (const { cellId, run: oldRun } of cellRunsForColumn(store, table, colIndex)) {\n if (!oldRun) continue;\n const newRun = convertRunToType(oldRun, newType, inlineRegistry);\n ops.push(setBlockRuns(cellId, [newRun]));\n }\n applyOps(store, ops);\n}\n\n/**\n * Replaces a \"select\" column's shared option list — the header menu's\n * add/rename/remove-option UI, acting on the whole column at once (unlike\n * the general inline `select` type's per-cell add/remove buttons). Any\n * cell whose `selectedValue` no longer matches a surviving option (i.e.\n * that option was removed) is cleared back to unselected rather than left\n * pointing at a dangling id; a cell whose option was only *renamed* keeps\n * its selection and just picks up the new label. One atomic undo step.\n */\nexport function setColumnOptions(store, tableId, colIndex, options) {\n const table = store.getBlock(tableId);\n const firstRow = store.getBlock(table.contentIds[0]);\n const currentColumns = resolveColumns(table, firstRow ? firstRow.contentIds.length : 0);\n const column = currentColumns[colIndex];\n if (!column) return;\n\n const nextColumns = [...currentColumns];\n nextColumns[colIndex] = { ...column, options };\n const ops = [updateBlockProps(tableId, { columns: nextColumns })];\n\n const optionById = new Map(options.map((o) => [o.value, o]));\n for (const { run } of cellRunsForColumn(store, table, colIndex)) {\n if (!run || run.type !== 'tableSelect') continue;\n const selectedValue = run.data?.selectedValue ?? '';\n const match = optionById.get(selectedValue);\n const nextSelectedValue = match ? selectedValue : '';\n const nextSelectedLabel = match ? match.label : '';\n if (\n nextSelectedValue !== selectedValue ||\n nextSelectedLabel !== (run.data?.selectedLabel ?? '')\n ) {\n ops.push(\n updateRun(run.id, {\n data: { selectedValue: nextSelectedValue, selectedLabel: nextSelectedLabel },\n }),\n );\n }\n }\n\n applyOps(store, ops);\n}\n","import { useCallback, useSyncExternalStore } from 'react';\nimport { useEditorStore } from './EditorProvider.jsx';\n\nconst FIELD_TYPES_KEY = '$fieldTypes';\n\n/**\n * Subscribes to the store's persisted, user-created field type definitions\n * (see createSelectFieldType / registerStoredFieldTypes) — reactive so a\n * \"manage field types\" list re-renders after add/update/remove, the same\n * way useBlock re-renders on a single block's change. Not used by the\n * slash menu itself: that reads inlineRegistry.listSlashCommands() fresh\n * on every trigger, so a newly-registered type shows up there without any\n * separate subscription.\n *\n * store.getFieldTypes() returns a referentially-stable array (cached,\n * invalidated only by a fieldTypes op) — required by useSyncExternalStore,\n * same contract as useBlock/useRun.\n */\nexport function useFieldTypes() {\n const store = useEditorStore();\n const subscribe = useCallback(\n (onStoreChange) => store.subscribe(FIELD_TYPES_KEY, onStoreChange),\n [store],\n );\n const getSnapshot = useCallback(() => store.getFieldTypes(), [store]);\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n","import { useEffect, useState } from 'react';\n\nfunction computeInset() {\n if (typeof window === 'undefined' || !window.visualViewport) return 0;\n const vv = window.visualViewport;\n // How much of the layout viewport's bottom is currently covered by the\n // on-screen keyboard (or any other viewport-shrinking browser chrome):\n // the gap between the full layout height and the visual viewport's own\n // bottom edge (its height plus however far it's scrolled/offset down).\n const inset = window.innerHeight - (vv.height + vv.offsetTop);\n return inset > 0 ? Math.round(inset) : 0;\n}\n\n/**\n * Tracks the on-screen keyboard's real height via the visualViewport API —\n * 0 when there's no keyboard (or no visualViewport support at all, e.g.\n * older browsers/SSR). This is what lets MobileActionBar sit at\n * `bottom: <inset>px` and land exactly above the keyboard instead of\n * guessing a fixed offset, and lets trigger-menu/Select popovers clamp\n * their own vertical position so they don't render underneath it.\n *\n * Listens on visualViewport's own 'resize'/'scroll' (not window's) — the\n * keyboard opening/closing changes the *visual* viewport, not the layout\n * one, and most mobile browsers don't fire window 'resize' for it at all.\n */\nexport function useVirtualKeyboardInset() {\n const [inset, setInset] = useState(computeInset);\n\n useEffect(() => {\n if (typeof window === 'undefined' || !window.visualViewport) return undefined;\n const vv = window.visualViewport;\n const handleChange = () => setInset(computeInset());\n handleChange();\n vv.addEventListener('resize', handleChange);\n vv.addEventListener('scroll', handleChange);\n return () => {\n vv.removeEventListener('resize', handleChange);\n vv.removeEventListener('scroll', handleChange);\n };\n }, []);\n\n return inset;\n}\n","import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport { ChevronDownIcon } from './icons.jsx';\nimport { useOutsideClickAndEscape } from './useOutsideClickAndEscape.js';\nimport { useVirtualKeyboardInset } from './useVirtualKeyboardInset.js';\nimport { useHorizontalAutoAdjustedLeft } from './usePopoverEdgeClamp.js';\n\n// Rough worst-case popover height (max-height in .be-select-options's own\n// CSS is 220px, plus the search input and padding) — only used to decide\n// which side of the trigger to open on, not as an exact pixel budget.\nconst ESTIMATED_POPOVER_HEIGHT = 280;\n\n// Matches .be-select-options' own CSS max-height — the option list's\n// rendered height is capped there regardless of content, so this is a\n// reliable stand-in for the real value without needing to measure the\n// scroll container itself (see the virtualization doc comment below).\nconst LIST_HEIGHT = 220;\n// A reasonable guess for one option row's height, used only until the\n// first actually-rendered row can be measured for real (see rowHeight\n// state below) — refined once, not per-render.\nconst ROW_HEIGHT_FALLBACK = 32;\n// Extra rows rendered above/below the visible window so a fast arrow-key\n// press or scroll doesn't ever show a flash of blank space before the next\n// render catches up.\nconst OVERSCAN = 6;\n\nfunction matchesQuery(option, query) {\n if (!query) return true;\n return option.label.toLowerCase().includes(query.toLowerCase());\n}\n\n/**\n * A lightweight, dependency-free \"searchable select\" (Ant Design Select-\n * style combobox) used everywhere this editor previously used a native\n * `<select>`: a trigger button showing the current value, opening a\n * fixed-position popover with a search input and a filtered, keyboard-\n * navigable option list on click. A native `<select>`'s own dropdown can't\n * be styled or searched, which is the whole reason this exists — visually\n * and behaviorally consistent across every dropdown in the editor instead\n * of each one looking like the browser's own chrome.\n *\n * `options` is `[{ value, label }]`; `onChange(value, option)` fires on\n * pick (both are passed since several call sites want the option's label\n * too, e.g. to store alongside its id). Deliberately does NOT support\n * creating new options inline — that's each call site's own concern (e.g.\n * a table's \"select\" column options are managed via TableHeaderRow's own\n * add/rename/remove UI) — this component only ever picks one of the\n * options it's given.\n *\n * The popover (search input + option list) is rendered via a portal to\n * `document.body` — same as SlashMenu/FloatingToolbar, which are also\n * mounted as siblings of the contentEditable tree, never nested inside it.\n * Several call sites mount this *trigger* deep inside an atomic\n * contentEditable=false inline chip (select/table-select/custom field type), which\n * itself lives inside a contentEditable=true paragraph. A real, focusable\n * `<input>` — unlike a native `<select>`'s own OS-level dropdown, which\n * never actually hands page focus to anything — left nested that deep\n * fights the surrounding contentEditable region for focus in ways real\n * browsers resolve inconsistently (and jsdom doesn't reproduce at all):\n * the very first character typed could land back in the paragraph instead\n * of the search box, since a real native `<input>` there is a genuinely new\n * DOM subtree fighting for focus a native `<select>` never had to. Portaling\n * the popover out to `document.body` sidesteps the whole problem — it's a\n * true DOM sibling of the editor surface, not a descendant, so it can never\n * lose that tug-of-war.\n *\n * `variant=\"tag\"` renders the selected value (and each option in the list)\n * as a small colored pill instead of plain text in a bordered/chevroned\n * box — a familiar Select-property look. Pass `color: { bg, text }` on\n * each option for this (see blocks/table/tagColors.js); the trigger itself\n * loses its border/background/chevron chrome entirely in this mode — just\n * the pill (or the placeholder, if nothing's chosen yet) is clickable.\n *\n * `options` may also be a function `(query) => Option[] | Promise<Option[]>`\n * instead of a plain array — this is how custom field types (see\n * createSelectFieldType) support DB/API-backed option sources (react-\n * select's `loadOptions`, essentially) alongside plain static lists,\n * through the exact same component and contract. When `options` is a\n * function it's called fresh on every query change (debounced ~250ms so\n * fast typing doesn't fire one request per keystroke) — deliberately no\n * caching layer here, so the host's own resolver is always the source of\n * truth for a given query; any caching is that function's own concern.\n * Static array callers are entirely unaffected: filtering there stays\n * synchronous and instant, exactly as before.\n *\n * Since a dynamic resolver's currently-loaded page may not contain the\n * option matching the CURRENT value (it was picked under a different\n * query, or came from elsewhere), pass `selectedLabel` to control what the\n * trigger displays for the current value directly, instead of relying on\n * an `options.find(...)` lookup that only works for static arrays.\n *\n * The option list is windowed (virtualized): only the rows actually\n * scrolled into view (plus a small OVERSCAN buffer) are ever mounted,\n * regardless of how many options `filtered` holds — a static list of\n * thousands of options (or a dynamic resolver returning a big page) stays\n * just as smooth to scroll as one of ten, since the DOM node count no\n * longer grows with the option count. `rowHeight` starts at a guess\n * (ROW_HEIGHT_FALLBACK) and is corrected once from the first real rendered\n * row's own measured height (`useLayoutEffect`, before paint, so there's no\n * visible jump) — deliberately not hardcoded, since `variant=\"tag\"` rows\n * render taller than plain-text ones and a host's own CSS could change\n * either. `LIST_HEIGHT` mirrors `.be-select-options`'s own CSS max-height\n * rather than measuring the container, since that's already the exact\n * value CSS enforces regardless of content.\n *\n * Keyboard navigation (Arrow Up/Down) no longer calls `scrollIntoView()` on\n * the active option's own DOM node — a virtualized item outside the\n * current window doesn't have one to call it on. Instead the \"keep the\n * active option in view\" effect computes the target row's pixel position\n * from `activeIndex * rowHeight` and adjusts the scroll container's\n * `scrollTop` directly, the windowed-list equivalent of the same\n * \"nearest edge\" behavior.\n *\n * `autoOpen` (default false) opens the popover — and focuses its search\n * input, via the same effect a click already triggers — immediately on\n * mount, once, instead of waiting for the user to click the trigger.\n * Meant for a chip that was just inserted from the slash/@ menu (see\n * insertInlineRunAtCursor's own `autoOpen` option), where landing straight\n * in \"ready to search\" is a better default than requiring a second click\n * right after the first one that inserted it.\n */\nexport function Select({\n value,\n options,\n onChange,\n placeholder = 'Select…',\n ariaLabel,\n className = '',\n variant = 'default',\n selectedLabel,\n selectedColor,\n onManageOptions,\n manageOptionsLabel = 'Manage options…',\n mention = false,\n autoOpen = false,\n}) {\n const [isOpen, setIsOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [activeIndex, setActiveIndex] = useState(0);\n const [rect, setRect] = useState(null);\n const keyboardInset = useVirtualKeyboardInset();\n const [asyncOptions, setAsyncOptions] = useState([]);\n const [isLoading, setIsLoading] = useState(false);\n const [loadError, setLoadError] = useState(false);\n const rootRef = useRef(null);\n const buttonRef = useRef(null);\n const popoverRef = useRef(null);\n const inputRef = useRef(null);\n const listRef = useRef(null);\n const firstRowRef = useRef(null);\n const outsideRefs = useMemo(() => [rootRef, popoverRef], []);\n const isTag = variant === 'tag';\n const isDynamic = typeof options === 'function';\n\n const [rowHeight, setRowHeight] = useState(ROW_HEIGHT_FALLBACK);\n const [scrollTop, setScrollTop] = useState(0);\n\n const staticSelected = !isDynamic ? options.find((o) => o.value === value) : undefined;\n const selected = value\n ? (staticSelected ??\n (selectedLabel ? { value, label: selectedLabel, color: selectedColor } : undefined))\n : undefined;\n\n const filtered = useMemo(\n () => (isDynamic ? asyncOptions : options.filter((o) => matchesQuery(o, query))),\n [isDynamic, asyncOptions, options, query],\n );\n\n // Windowing math — see the doc comment above. Clamps scrollTop against\n // the CURRENT filtered length before computing startIndex so a shorter\n // result set (e.g. a new search narrowing a long list) can't leave the\n // window scrolled past the end of it, which would otherwise render a\n // blank list for one frame until the active-option effect below catches up.\n const maxScrollTop = Math.max(0, (filtered.length - 1) * rowHeight);\n const clampedScrollTop = Math.min(scrollTop, maxScrollTop);\n const startIndex = filtered.length\n ? Math.max(0, Math.floor(clampedScrollTop / rowHeight) - OVERSCAN)\n : 0;\n const visibleCount = Math.ceil(LIST_HEIGHT / rowHeight) + OVERSCAN * 2;\n const endIndex = Math.min(filtered.length, startIndex + visibleCount);\n const visibleOptions = filtered.slice(startIndex, endIndex);\n const topPadding = startIndex * rowHeight;\n const bottomPadding = Math.max(0, (filtered.length - endIndex) * rowHeight);\n\n // Refines rowHeight from the first actually-rendered row's real measured\n // height, once — before paint, so any correction from the fallback guess\n // is invisible. No-ops (stays at the fallback) in an environment with no\n // real layout, e.g. jsdom under tests.\n useLayoutEffect(() => {\n const measured = firstRowRef.current?.getBoundingClientRect().height;\n if (measured && Math.abs(measured - rowHeight) > 0.5) setRowHeight(measured);\n });\n\n // Dynamic resolvers already do their own query-based filtering (a DB\n // search, typically) — refetch on every query change while the popover\n // is open, debounced so a fast typist doesn't fire one call per keystroke.\n useEffect(() => {\n if (!isDynamic || !isOpen) return undefined;\n let cancelled = false;\n setIsLoading(true);\n setLoadError(false);\n const timer = setTimeout(() => {\n Promise.resolve(options(query))\n .then((result) => {\n if (cancelled) return;\n setAsyncOptions(result ?? []);\n setIsLoading(false);\n })\n .catch(() => {\n if (cancelled) return;\n setAsyncOptions([]);\n setIsLoading(false);\n setLoadError(true);\n });\n }, 250);\n return () => {\n cancelled = true;\n clearTimeout(timer);\n };\n }, [isDynamic, isOpen, options, query]);\n\n const close = useCallback(() => setIsOpen(false), []);\n\n useOutsideClickAndEscape(outsideRefs, isOpen, close);\n const adjustedLeft = useHorizontalAutoAdjustedLeft(popoverRef, isOpen, rect?.left);\n\n const open = useCallback(() => {\n setRect(buttonRef.current?.getBoundingClientRect() ?? null);\n setQuery('');\n setActiveIndex(0);\n setScrollTop(0);\n setIsOpen(true);\n }, []);\n\n // Fires exactly once, on mount — autoOpen is only ever true for a chip\n // that was just inserted (see the doc comment above), so there's no\n // later point where re-opening on its own would make sense.\n useEffect(() => {\n if (autoOpen) open();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Also depends on adjustedLeft, not just isOpen — the popover (and its\n // search <input>) only actually mounts once adjustedLeft resolves from\n // its initial `null` to a real value (useHorizontalAutoAdjustedLeft's own\n // two-pass measure-then-clamp, see its doc comment), which is USUALLY\n // one render pass after isOpen itself first flips true. Depending on\n // isOpen alone meant this effect's one-and-only run could land before\n // inputRef.current existed at all — a real, if easy to miss, bug: it\n // happened to go unnoticed for a plain click-to-open because reopening\n // an already-was-open-before popover reuses adjustedLeft's already-\n // resolved value from last time (no gap on that render pass), but a\n // COLD first-ever open (autoOpen right after insertion, most notably)\n // had no such warm state to fall back on and silently focused nothing.\n useEffect(() => {\n if (isOpen) inputRef.current?.focus();\n }, [isOpen, adjustedLeft]);\n\n // Keeps the keyboard-active option (Arrow Up/Down) visible as it moves\n // past the edge of the scrollable list — without this, arrowing down\n // past the bottom of a long option list leaves the \"active\" highlight\n // scrolled out of view with nothing on screen showing which one it is.\n // Computed from activeIndex * rowHeight rather than a DOM ref + native\n // scrollIntoView(), since a virtualized item outside the current window\n // isn't necessarily mounted at all (see the doc comment above).\n useEffect(() => {\n const container = listRef.current;\n if (!container) return;\n const itemTop = activeIndex * rowHeight;\n const itemBottom = itemTop + rowHeight;\n const viewTop = container.scrollTop;\n const viewHeight = container.clientHeight || LIST_HEIGHT;\n const viewBottom = viewTop + viewHeight;\n let nextScrollTop = null;\n if (itemTop < viewTop) nextScrollTop = itemTop;\n else if (itemBottom > viewBottom) nextScrollTop = itemBottom - viewHeight;\n if (nextScrollTop !== null) {\n container.scrollTop = nextScrollTop;\n setScrollTop(nextScrollTop);\n }\n }, [activeIndex, rowHeight]);\n\n const selectOption = useCallback(\n (option) => {\n onChange(option.value, option);\n close();\n buttonRef.current?.focus();\n },\n [onChange, close],\n );\n\n const handleSearchKeyDown = useCallback(\n (event) => {\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n setActiveIndex((i) => Math.min(i + 1, Math.max(filtered.length - 1, 0)));\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n setActiveIndex((i) => Math.max(i - 1, 0));\n } else if (event.key === 'Enter') {\n event.preventDefault();\n if (filtered[activeIndex]) selectOption(filtered[activeIndex]);\n } else if (event.key === 'Escape') {\n event.preventDefault();\n close();\n buttonRef.current?.focus();\n }\n },\n [filtered, activeIndex, selectOption, close],\n );\n\n return (\n <span className={`be-select ${className}`.trim()} ref={rootRef}>\n <button\n type=\"button\"\n ref={buttonRef}\n className={`be-select-trigger${isTag ? ' be-select-trigger-tag' : ''}${mention ? ' be-select-trigger-mention' : ''}`}\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n aria-label={ariaLabel}\n onClick={() => (isOpen ? close() : open())}\n >\n {isTag ? (\n selected ? (\n <span\n className={`be-select-tag${mention ? ' be-select-tag-mention' : ''}`}\n style={\n mention\n ? undefined\n : { background: selected.color?.bg, color: selected.color?.text }\n }\n >\n {mention ? `@${selected.label}` : selected.label}\n </span>\n ) : (\n <span className=\"be-select-value be-select-value-placeholder\">{placeholder}</span>\n )\n ) : (\n <>\n <span className=\"be-select-value\">{selected ? selected.label : placeholder}</span>\n <ChevronDownIcon size={14} className=\"be-select-chevron\" />\n </>\n )}\n </button>\n {isOpen &&\n rect &&\n adjustedLeft != null &&\n createPortal(\n <div\n ref={popoverRef}\n className=\"be-select-popover\"\n style={{\n position: 'fixed',\n left: adjustedLeft,\n minWidth: rect.width,\n // Flips above the trigger instead of below it once there isn't\n // enough room left before the keyboard (or screen bottom) —\n // otherwise the popover can render partly/entirely hidden\n // underneath an open on-screen keyboard.\n ...(rect.bottom + ESTIMATED_POPOVER_HEIGHT > window.innerHeight - keyboardInset\n ? { bottom: window.innerHeight - rect.top + 4 }\n : { top: rect.bottom + 4 }),\n }}\n >\n <input\n ref={inputRef}\n type=\"text\"\n className=\"be-select-search\"\n value={query}\n onChange={(event) => {\n setQuery(event.target.value);\n setActiveIndex(0);\n }}\n onKeyDown={handleSearchKeyDown}\n placeholder=\"Search…\"\n aria-label={ariaLabel ? `Search ${ariaLabel}` : 'Search options'}\n />\n <div\n className=\"be-select-options\"\n role=\"listbox\"\n ref={listRef}\n onScroll={(event) => setScrollTop(event.currentTarget.scrollTop)}\n >\n {isDynamic && isLoading && <div className=\"be-select-empty\">Loading…</div>}\n {isDynamic && !isLoading && loadError && (\n <div className=\"be-select-empty be-select-error\">Couldn't load options</div>\n )}\n {!isLoading && !loadError && filtered.length === 0 && (\n <div className=\"be-select-empty\">No results</div>\n )}\n {!isLoading && !loadError && filtered.length > 0 && (\n <>\n {topPadding > 0 && <div style={{ height: topPadding }} aria-hidden=\"true\" />}\n {visibleOptions.map((option, localIndex) => {\n const i = startIndex + localIndex;\n return (\n <div\n key={option.value}\n ref={localIndex === 0 ? firstRowRef : undefined}\n role=\"option\"\n aria-selected={option.value === value}\n className={`be-select-option${i === activeIndex ? ' be-select-option-active' : ''}${\n option.value === value ? ' be-select-option-selected' : ''\n }`}\n onMouseDown={(event) => {\n event.preventDefault(); // keep focus in the search input until a real selection commits\n selectOption(option);\n }}\n onMouseEnter={() => setActiveIndex(i)}\n >\n {isTag ? (\n <span\n className=\"be-select-tag\"\n style={{ background: option.color?.bg, color: option.color?.text }}\n >\n {option.label}\n </span>\n ) : (\n option.label\n )}\n </div>\n );\n })}\n {bottomPadding > 0 && (\n <div style={{ height: bottomPadding }} aria-hidden=\"true\" />\n )}\n </>\n )}\n </div>\n {onManageOptions && (\n <button\n type=\"button\"\n className=\"be-select-manage-options\"\n onMouseDown={(event) => {\n event.preventDefault();\n close();\n onManageOptions();\n }}\n >\n {manageOptionsLabel}\n </button>\n )}\n </div>,\n document.body,\n )}\n </span>\n );\n}\n","/**\n * Tag color palette for a table's \"select\" column — assigned\n * once, at option-creation time (see TableHeaderRow's SelectOptionsManager),\n * and stored on the option itself (`{ value, label, color }`) so it stays\n * stable across reorders/removals: a tag keeps whatever color it was\n * first given.\n */\nexport const TAG_COLORS = [\n { bg: '#e9e9e7', text: '#32302c' }, // gray (default)\n { bg: '#eee0da', text: '#64473a' }, // brown\n { bg: '#fadec9', text: '#8a4b23' }, // orange\n { bg: '#fdecc8', text: '#8a6116' }, // yellow\n { bg: '#dbeddb', text: '#256029' }, // green\n { bg: '#d3e5ef', text: '#1a5f8a' }, // blue\n { bg: '#e8deee', text: '#5b3a8a' }, // purple\n { bg: '#f5e0e9', text: '#8a3a5f' }, // pink\n { bg: '#ffe2dd', text: '#a13a2f' }, // red\n];\n\n/** Cycles through TAG_COLORS by index — deterministic, no randomness. */\nexport function pickTagColor(index) {\n return TAG_COLORS[((index % TAG_COLORS.length) + TAG_COLORS.length) % TAG_COLORS.length];\n}\n","import { useCallback, useMemo, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n useEditorStore,\n useInlineRegistry,\n useFieldTypeEditor,\n} from '../../react/EditorProvider.jsx';\nimport { useFieldTypes } from '../../react/useFieldTypes.js';\nimport { useOutsideClickAndEscape } from '../../react/useOutsideClickAndEscape.js';\nimport { useMenuKeyboardNav } from '../../react/useMenuKeyboardNav.js';\nimport { useAutoAdjustedRightLeft } from '../../react/usePopoverEdgeClamp.js';\nimport {\n insertColumnAfter,\n deleteColumn,\n renameColumn,\n setColumnType,\n setColumnOptions,\n setColumnWidth,\n sortTableByColumn,\n setColumnAggregate,\n} from './tableEditCommands.js';\nimport { COLUMN_TYPES, MIN_COLUMN_WIDTH } from './tableColumns.js';\nimport { AGGREGATE_TYPES, AGGREGATE_LABELS } from './tableView.js';\nimport { genId } from '../../utils/idGen.js';\nimport { XIcon, ArrowUpIcon, ArrowDownIcon } from '../../react/icons.jsx';\nimport { Select } from '../../react/Select.jsx';\nimport { pickTagColor } from './tagColors.js';\n\nconst TYPE_LABELS = { text: 'Text', date: 'Date', checkbox: 'Checkbox', select: 'Select' };\nconst AGGREGATE_OPTIONS = AGGREGATE_TYPES.map((value) => ({\n value,\n label: AGGREGATE_LABELS[value],\n}));\nconst TYPE_OPTIONS = COLUMN_TYPES.map((type) => ({ value: type, label: TYPE_LABELS[type] }));\n\n// A column's actual drag width is unbounded (no real max exists in\n// tableColumns.js) — this is only a hint for the resize handle's own\n// aria-valuemax, so a screen reader has *some* sense of position within a\n// reasonable range, not a value that's ever enforced against real dragging.\nconst MAX_COLUMN_WIDTH_HINT = 800;\n\n/**\n * Lets a \"select\" column start from an already-created custom field type's\n * option list (see createSelectFieldType / FieldTypeEditorModal) instead\n * of typing options out by hand every time — the same `[{value, label,\n * color}]` shape both a field type's own `options` and a select column's\n * `column.options` already use, so this is a plain one-time copy\n * (`setColumnOptions`), not a live link: picking one seeds the column's\n * own independent list, which the SelectOptionsManager below it can then\n * rename/add-to/remove-from freely without touching the source field type.\n *\n * \"+ New field type\" opens the same create flow a chip's own \"Manage\n * options…\" popover reaches (`useFieldTypeEditor().openCreate()`) — the\n * newly-created type then shows up in this same list on the next open, to\n * be picked from like any other. Requires a `<FieldTypeEditorModal />`\n * mounted somewhere in the host app to actually render that dialog (same\n * pre-existing requirement `createSelectFieldType`'s in-editor create/edit\n * UI already has) — the button still opens the request either way, it's\n * just a no-op visually if nothing is listening for it.\n */\nfunction ColumnFieldTypePicker({ tableId, colIndex }) {\n const store = useEditorStore();\n const fieldTypes = useFieldTypes();\n const { openCreate } = useFieldTypeEditor();\n\n const handlePick = useCallback(\n (fieldTypeId) => {\n const fieldType = store.getFieldType(fieldTypeId);\n if (fieldType) setColumnOptions(store, tableId, colIndex, fieldType.options ?? []);\n },\n [store, tableId, colIndex],\n );\n\n return (\n <div className=\"be-table-header-menu-field-type\">\n {fieldTypes.length > 0 && (\n <Select\n value=\"\"\n options={fieldTypes.map((ft) => ({ value: ft.id, label: ft.label }))}\n onChange={handlePick}\n placeholder=\"Copy options from…\"\n ariaLabel=\"Copy options from an existing field type\"\n />\n )}\n <button type=\"button\" className=\"be-table-header-menu-item\" onClick={openCreate}>\n + New field type\n </button>\n </div>\n );\n}\n\n/**\n * Manages a \"select\" column's shared option list (add/rename/remove) —\n * configured once here, for the whole column, rather than per cell. This\n * is the piece that makes a select column behave like a shared property\n * instead of the general-purpose inline `select` type's\n * independent-per-chip options: every cell reads the *same* list (see\n * TableSelectInlineNode), so it only needs managing in one place.\n */\nfunction SelectOptionsManager({ tableId, colIndex, options }) {\n const store = useEditorStore();\n const [draft, setDraft] = useState('');\n\n const handleRename = useCallback(\n (optionValue, label) => {\n setColumnOptions(\n store,\n tableId,\n colIndex,\n options.map((o) => (o.value === optionValue ? { ...o, label } : o)),\n );\n },\n [store, tableId, colIndex, options],\n );\n const handleRemove = useCallback(\n (optionValue) =>\n setColumnOptions(\n store,\n tableId,\n colIndex,\n options.filter((o) => o.value !== optionValue),\n ),\n [store, tableId, colIndex, options],\n );\n const handleAdd = useCallback(() => {\n const label = draft.trim();\n setDraft('');\n if (!label) return;\n // Color is assigned once, here, at creation time — not derived from\n // position at render time — so it stays the same tag color even after\n // other options are reordered/removed — a tag's color is fixed once\n // you pick/create it.\n setColumnOptions(store, tableId, colIndex, [\n ...options,\n { value: genId(), label, color: pickTagColor(options.length) },\n ]);\n }, [store, tableId, colIndex, options, draft]);\n\n return (\n <div className=\"be-table-header-menu-options\">\n <div className=\"be-table-header-menu-options-label\">Options</div>\n {options.map((option, i) => (\n <div key={option.value} className=\"be-table-header-menu-option-row\">\n <span\n className=\"be-table-header-menu-option-swatch\"\n style={{ background: (option.color ?? pickTagColor(i)).bg }}\n aria-hidden=\"true\"\n />\n <input\n className=\"be-table-header-menu-option-input\"\n value={option.label}\n onChange={(event) => handleRename(option.value, event.target.value)}\n aria-label={`Rename option ${option.label}`}\n />\n <button\n type=\"button\"\n className=\"be-table-header-menu-option-remove\"\n onClick={() => handleRemove(option.value)}\n aria-label={`Remove option ${option.label}`}\n >\n <XIcon size={14} />\n </button>\n </div>\n ))}\n <div className=\"be-table-header-menu-option-row\">\n <input\n className=\"be-table-header-menu-option-input\"\n value={draft}\n onChange={(event) => setDraft(event.target.value)}\n placeholder=\"New option…\"\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n handleAdd();\n }\n }}\n />\n <button\n type=\"button\"\n className=\"be-table-header-menu-option-add\"\n onClick={handleAdd}\n aria-label=\"Add option\"\n >\n +\n </button>\n </div>\n </div>\n );\n}\n\n/**\n * One header cell: an editable label, a small self-built menu (change\n * type, manage select options, insert column left/right, delete column),\n * and a drag handle on its right edge to resize the column.\n *\n * The menu is portaled to `document.body` (`position: fixed`, computed\n * from the trigger button's own bounding rect) — same convention as\n * Select/SlashMenu elsewhere in this codebase — instead of a plain\n * absolutely-positioned child of this `<th>`. A table can genuinely\n * overflow its wrapper (see `.be-table-wrapper`'s `overflow-x: auto`), and\n * a plain in-flow popup gets visually clipped by that; portaling escapes\n * it entirely, the same reason Select's own popover is portaled.\n *\n * Changing type runs every existing cell in the column through\n * setColumnType's data-preserving conversion (see tableColumns.js) rather\n * than discarding values — the actual gap this feature was built to close\n * versus the legacy notevo table it's modeled after.\n */\nfunction ColumnHeaderCell({ tableId, column, colIndex, colCount, filterValue, onFilterChange }) {\n const store = useEditorStore();\n const inlineRegistry = useInlineRegistry();\n const [isMenuOpen, setIsMenuOpen] = useState(false);\n const [rect, setRect] = useState(null);\n const [dragWidth, setDragWidth] = useState(null);\n const triggerRef = useRef(null);\n const menuRef = useRef(null);\n const thRef = useRef(null);\n const outsideRefs = useMemo(() => [triggerRef, menuRef], []);\n\n const closeMenu = useCallback(() => setIsMenuOpen(false), []);\n useOutsideClickAndEscape(outsideRefs, isMenuOpen, closeMenu);\n useMenuKeyboardNav(menuRef, isMenuOpen, closeMenu, triggerRef);\n const rightLeft = useAutoAdjustedRightLeft(menuRef, isMenuOpen, rect?.right);\n\n const openMenu = useCallback(() => {\n // Anchor to the whole header cell, not the small vertically-centered\n // trigger icon (triggerRef) — using the icon's own rect put the menu's\n // top a few px below the icon's *midpoint*, which sat mid-cell and\n // overlapped the column label instead of opening cleanly below it.\n setRect(thRef.current?.getBoundingClientRect() ?? null);\n setIsMenuOpen(true);\n }, []);\n\n const handleLabelChange = useCallback(\n (event) => renameColumn(store, tableId, colIndex, event.target.value),\n [store, tableId, colIndex],\n );\n const handleInsertLeft = useCallback(() => {\n insertColumnAfter(store, tableId, colIndex - 1);\n closeMenu();\n }, [store, tableId, colIndex, closeMenu]);\n const handleInsertRight = useCallback(() => {\n insertColumnAfter(store, tableId, colIndex);\n closeMenu();\n }, [store, tableId, colIndex, closeMenu]);\n const handleDelete = useCallback(() => {\n deleteColumn(store, tableId, colIndex);\n closeMenu();\n }, [store, tableId, colIndex, closeMenu]);\n const handleTypeChange = useCallback(\n (type) => setColumnType(store, tableId, colIndex, type, inlineRegistry),\n [store, tableId, colIndex, inlineRegistry],\n );\n const handleSortAsc = useCallback(() => {\n sortTableByColumn(store, tableId, colIndex, 'asc', inlineRegistry);\n closeMenu();\n }, [store, tableId, colIndex, inlineRegistry, closeMenu]);\n const handleSortDesc = useCallback(() => {\n sortTableByColumn(store, tableId, colIndex, 'desc', inlineRegistry);\n closeMenu();\n }, [store, tableId, colIndex, inlineRegistry, closeMenu]);\n const handleAggregateChange = useCallback(\n (aggregate) => setColumnAggregate(store, tableId, colIndex, aggregate),\n [store, tableId, colIndex],\n );\n\n // Live-updates the <colgroup>'s own <col> element directly during drag\n // (see TableBlock.jsx's data-col-index) rather than dispatching a store\n // write on every mousemove — the store only gets ONE write, on mouseup,\n // matching EmbedBlock's own resize-handle convention.\n const handleResizeStart = useCallback(\n (event) => {\n event.preventDefault();\n const table = thRef.current?.closest('table');\n const col = table?.querySelector(`col[data-col-index=\"${colIndex}\"]`);\n if (!col) return;\n const startWidth = thRef.current.getBoundingClientRect().width;\n const startX = event.clientX;\n\n const computeWidth = (moveEvent) =>\n Math.max(MIN_COLUMN_WIDTH, Math.round(startWidth + (moveEvent.clientX - startX)));\n\n const handleMouseMove = (moveEvent) => {\n const width = computeWidth(moveEvent);\n col.style.width = `${width}px`;\n setDragWidth(width);\n };\n const handleMouseUp = (upEvent) => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n setColumnWidth(store, tableId, colIndex, computeWidth(upEvent));\n setDragWidth(null);\n };\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n },\n [store, tableId, colIndex],\n );\n\n // Same gap/fix as EmbedBlock's own resize handle: role=\"slider\" alone\n // doesn't make a mouse-only handle keyboard-operable — Left/Right (Shift\n // for a finer 1px step) and Home/End now actually resize the column.\n const handleResizeKeyDown = useCallback(\n (event) => {\n const current = column.width ?? MIN_COLUMN_WIDTH;\n const step = event.shiftKey ? 1 : 16;\n let next;\n if (event.key === 'ArrowLeft' || event.key === 'ArrowDown')\n next = Math.max(MIN_COLUMN_WIDTH, current - step);\n else if (event.key === 'ArrowRight' || event.key === 'ArrowUp')\n next = Math.min(MAX_COLUMN_WIDTH_HINT, current + step);\n else if (event.key === 'Home') next = MIN_COLUMN_WIDTH;\n else if (event.key === 'End') next = MAX_COLUMN_WIDTH_HINT;\n else return;\n event.preventDefault();\n setColumnWidth(store, tableId, colIndex, next);\n },\n [store, tableId, colIndex, column.width],\n );\n\n return (\n <th ref={thRef} scope=\"col\" className=\"be-table-header-cell\" contentEditable={false}>\n <input\n className=\"be-table-header-label\"\n value={column.label}\n onChange={handleLabelChange}\n aria-label={`Column ${colIndex + 1} name`}\n />\n <button\n ref={triggerRef}\n type=\"button\"\n className=\"be-table-header-menu-trigger\"\n aria-label={`Column ${colIndex + 1} options`}\n aria-haspopup=\"menu\"\n aria-expanded={isMenuOpen}\n onClick={() => (isMenuOpen ? closeMenu() : openMenu())}\n >\n ⋮\n </button>\n <div\n className=\"be-table-col-resize-handle\"\n onMouseDown={handleResizeStart}\n onKeyDown={handleResizeKeyDown}\n role=\"slider\"\n tabIndex={0}\n aria-label={`Resize column ${colIndex + 1}`}\n aria-valuemin={MIN_COLUMN_WIDTH}\n aria-valuemax={MAX_COLUMN_WIDTH_HINT}\n aria-valuenow={dragWidth ?? column.width}\n />\n {isMenuOpen &&\n rect &&\n rightLeft != null &&\n createPortal(\n <div\n ref={menuRef}\n role=\"menu\"\n aria-label={`Column ${colIndex + 1} options`}\n className=\"be-table-header-menu\"\n style={{\n position: 'fixed',\n top: rect.bottom + 4,\n left: rightLeft,\n transform: 'translateX(-100%)',\n }}\n >\n <div className=\"be-table-header-menu-type\">\n <span id={`be-table-col-type-${column.id}`}>Type</span>\n <Select\n value={column.type}\n options={TYPE_OPTIONS}\n onChange={handleTypeChange}\n ariaLabel=\"Column type\"\n className=\"\"\n />\n </div>\n {column.type === 'select' && (\n <>\n <ColumnFieldTypePicker tableId={tableId} colIndex={colIndex} />\n <SelectOptionsManager\n tableId={tableId}\n colIndex={colIndex}\n options={column.options ?? []}\n />\n </>\n )}\n <div className=\"be-table-header-menu-sort\">\n <button\n type=\"button\"\n role=\"menuitem\"\n className=\"be-table-header-menu-item\"\n onClick={handleSortAsc}\n >\n <ArrowUpIcon size={13} /> Sort ascending\n </button>\n <button\n type=\"button\"\n role=\"menuitem\"\n className=\"be-table-header-menu-item\"\n onClick={handleSortDesc}\n >\n <ArrowDownIcon size={13} /> Sort descending\n </button>\n </div>\n <label className=\"be-table-header-menu-filter\">\n <span>Filter</span>\n <input\n type=\"text\"\n className=\"be-table-header-menu-filter-input\"\n placeholder=\"Rows containing…\"\n value={filterValue ?? ''}\n onChange={(event) => onFilterChange(column.id, event.target.value)}\n aria-label={`Filter column ${colIndex + 1}`}\n />\n </label>\n <div className=\"be-table-header-menu-type be-table-header-menu-aggregate\">\n <span id={`be-table-col-aggregate-${column.id}`}>Footer</span>\n <Select\n value={column.aggregate ?? 'none'}\n options={AGGREGATE_OPTIONS}\n onChange={handleAggregateChange}\n ariaLabel=\"Column footer aggregate\"\n className=\"\"\n />\n </div>\n <button\n type=\"button\"\n role=\"menuitem\"\n className=\"be-table-header-menu-item\"\n onClick={handleInsertLeft}\n >\n Insert column left\n </button>\n <button\n type=\"button\"\n role=\"menuitem\"\n className=\"be-table-header-menu-item\"\n onClick={handleInsertRight}\n >\n Insert column right\n </button>\n <button\n type=\"button\"\n role=\"menuitem\"\n className=\"be-table-header-menu-item be-table-header-menu-item-danger\"\n onClick={handleDelete}\n disabled={colCount <= 1}\n >\n Delete column\n </button>\n </div>,\n document.body,\n )}\n </th>\n );\n}\n\n/**\n * Renders as a real `<thead>` above the table's `<tbody>` (see TableBlock),\n * one `<th>` per column driven by the table's own `props.columns` metadata\n * (see tableColumns.js) — not a \"block\" of its own, since column labels\n * are table-level metadata, not content that needs runs/selection/undo\n * machinery of its own. A trailing spacer `<th>` keeps header columns\n * aligned with TableRowBlock's extra row-actions column.\n */\nexport function TableHeaderRow({ tableId, columns, filters, onFilterChange }) {\n return (\n <thead>\n <tr className=\"be-table-header-row\">\n {columns.map((column, i) => (\n <ColumnHeaderCell\n key={column.id}\n tableId={tableId}\n column={column}\n colIndex={i}\n colCount={columns.length}\n filterValue={filters?.[column.id]}\n onFilterChange={onFilterChange}\n />\n ))}\n <th className=\"be-table-header-spacer\" aria-hidden=\"true\" />\n </tr>\n </thead>\n );\n}\n","import { useCallback, useMemo, useState } from 'react';\nimport { BlockChildren } from '../../react/BlockChildren.jsx';\nimport { useBlock } from '../../react/useBlock.js';\nimport {\n useEditorStore,\n useBlockClassName,\n useInlineRegistry,\n} from '../../react/EditorProvider.jsx';\nimport { insertRowAfter } from './tableEditCommands.js';\nimport { resolveColumns } from './tableColumns.js';\nimport {\n runPlainText,\n computeColumnAggregate,\n formatAggregateValue,\n AGGREGATE_SHORT_LABELS,\n} from './tableView.js';\nimport { TableHeaderRow } from './TableHeaderRow.jsx';\nimport { PlusIcon } from '../../react/icons.jsx';\n\nexport function TableBlock({ id }) {\n const store = useEditorStore();\n const inlineRegistry = useInlineRegistry();\n const block = useBlock(id);\n // Local, non-persisted view state — a filter query per column id. Never\n // written to the document (no store operation, no undo step, not synced\n // to collaborators): hiding a row from THIS view is display-only, same\n // \"don't touch real content for a view concern\" reasoning as preview\n // mode's own hidden-block filtering. Resets on reload/navigating away —\n // a documented v1 limitation, not an oversight.\n const [filters, setFilters] = useState({});\n const handleFilterChange = useCallback((columnId, value) => {\n setFilters((prev) =>\n value\n ? { ...prev, [columnId]: value }\n : Object.fromEntries(Object.entries(prev).filter(([k]) => k !== columnId)),\n );\n }, []);\n\n const handleAddRow = useCallback(() => {\n const lastRowId = block?.contentIds?.[block.contentIds.length - 1];\n if (lastRowId) insertRowAfter(store, lastRowId);\n }, [store, block]);\n\n const className = useBlockClassName('be-table-wrapper', block);\n\n const activeFilters = useMemo(() => Object.entries(filters).filter(([, q]) => q), [filters]);\n\n // Cell run lookup shared by both filtering (below) and the footer\n // aggregates — reads directly off the live store rather than through\n // React state, so it's always exactly what's currently in the document.\n const cellRun = useCallback(\n (rowId, colIndex) => {\n const row = store.getBlock(rowId);\n const cell = row && store.getBlock(row.contentIds[colIndex]);\n return cell ? store.getRun(cell.contentIds[0]) : null;\n },\n [store],\n );\n\n if (!block) return null;\n\n const firstRow = store.getBlock(block.contentIds[0]);\n const columns = resolveColumns(block, firstRow?.contentIds?.length ?? 0);\n\n // Every active filter must match (AND, not OR) — a row missing entirely\n // from one filtered column's criteria is hidden regardless of how well\n // it matches any other column's.\n const visibleRowIds =\n activeFilters.length === 0\n ? block.contentIds\n : block.contentIds.filter((rowId) =>\n activeFilters.every(([columnId, query]) => {\n const colIndex = columns.findIndex((c) => c.id === columnId);\n if (colIndex === -1) return true;\n const text = runPlainText(cellRun(rowId, colIndex), inlineRegistry);\n return text.toLowerCase().includes(query.toLowerCase());\n }),\n );\n\n const hasAggregates = columns.some((c) => c.aggregate && c.aggregate !== 'none');\n\n return (\n // be-table-scroll is a second, OUTER scroll boundary around\n // be-table-wrapper's own overflow-x:auto: a fixed-layout table whose\n // columns sum wider than the page can otherwise force its ancestors\n // (this block's row content, .be-surface, ...) to grow to fit it\n // instead of actually scrolling inside be-table-wrapper — depending on\n // the host app's own surrounding layout, that can bubble all the way\n // up to the whole page scrolling horizontally. This wrapper's own\n // max-width:100% + overflow-x:auto is a hard stop that can't be\n // out-grown by anything inside it, regardless of what's going on\n // further up the tree.\n <div className=\"be-table-scroll\">\n <div className={className} data-block-id={id}>\n <table className=\"be-table\">\n {/*\n A <colgroup> is what makes column resizing work at all: with\n table-layout: fixed (see CSS), every <col>'s own width applies\n uniformly to that column across the header row AND every body\n row's cell at that index — one <col> per column is the single\n source of truth for its rendered width, so TableCellBlock/\n TableRowBlock never need their own column-width prop-threading.\n data-col-index is how the header's own resize-drag handler finds\n and live-updates the right <col> imperatively while dragging (see\n ColumnHeaderCell), without touching React state on every\n mousemove.\n */}\n <colgroup>\n {columns.map((column, i) => (\n <col key={column.id} data-col-index={i} style={{ width: column.width }} />\n ))}\n <col className=\"be-table-header-spacer-col\" />\n </colgroup>\n <TableHeaderRow\n tableId={id}\n columns={columns}\n filters={filters}\n onFilterChange={handleFilterChange}\n />\n <tbody>\n <BlockChildren parentId={id} filterIds={visibleRowIds} />\n </tbody>\n {hasAggregates && (\n <tfoot>\n <tr className=\"be-table-footer-row\">\n {columns.map((column, colIndex) => {\n const runs = visibleRowIds.map((rowId) => cellRun(rowId, colIndex));\n const value = computeColumnAggregate(\n runs,\n column.type,\n column.aggregate,\n inlineRegistry,\n );\n return (\n <td key={column.id} className=\"be-table-footer-cell\">\n {value != null && (\n <>\n <span className=\"be-table-footer-label\">\n {AGGREGATE_SHORT_LABELS[column.aggregate]}\n </span>\n {formatAggregateValue(value)}\n </>\n )}\n </td>\n );\n })}\n <td className=\"be-table-footer-spacer\" aria-hidden=\"true\" />\n </tr>\n </tfoot>\n )}\n </table>\n <button\n type=\"button\"\n className=\"be-table-add-row\"\n contentEditable={false}\n onClick={handleAddRow}\n >\n <PlusIcon size={14} /> Add row\n </button>\n </div>\n </div>\n );\n}\n","import { useCallback } from 'react';\nimport { BlockChildren } from '../../react/BlockChildren.jsx';\nimport { useBlock } from '../../react/useBlock.js';\nimport { useEditorStore, useBlockClassName } from '../../react/EditorProvider.jsx';\nimport { deleteRow } from './tableEditCommands.js';\nimport { XIcon } from '../../react/icons.jsx';\n\n// Reuses the exact same container/tree-walking mechanism as every other\n// non-leaf block (page, layout column, list item children) — the only\n// difference is the wrapping <tr> tag.\nexport function TableRowBlock({ id }) {\n const store = useEditorStore();\n const block = useBlock(id);\n const className = useBlockClassName('be-table-row', block);\n const handleDeleteRow = useCallback(() => deleteRow(store, id), [store, id]);\n\n return (\n <tr className={className} data-block-id={id}>\n <BlockChildren parentId={id} />\n <td className=\"be-table-row-actions\" contentEditable={false}>\n <button\n type=\"button\"\n className=\"be-table-delete-row\"\n onClick={handleDeleteRow}\n aria-label=\"Delete row\"\n title=\"Delete row\"\n >\n <XIcon size={14} />\n </button>\n </td>\n </tr>\n );\n}\n","import { focusRunEnd } from '../../react/focusRun.js';\nimport { resolveAdjacentFocusTarget } from '../shared/navigationCommands.js';\nimport { insertSiblingAfterAndFocus } from '../shared/blockCommands.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\n\nfunction locateCell(store, cellId) {\n const cell = store.getBlock(cellId);\n const row = store.getBlock(cell.parentId);\n const table = store.getBlock(row.parentId);\n return {\n table,\n row,\n rowIndex: table.contentIds.indexOf(row.id),\n colIndex: row.contentIds.indexOf(cellId),\n };\n}\n\n/**\n * Resolves the target cell id when moving from `cellId` in `direction`\n * ('left' | 'right' | 'up' | 'down'). Pure, no side effects — returns null\n * at any of the table's edges (first/last cell of a row, top/bottom of a\n * column), leaving what to do about that boundary to the caller\n * (moveToAdjacentCell).\n *\n * 'up'/'down' stay in the same column and return null at the table's\n * top/bottom edge — moving out of the table into a sibling block above/below\n * it is a follow-up (same cross-container caveat as navigationCommands.js).\n */\nexport function resolveAdjacentCellTarget(store, cellId, direction) {\n const { table, row, rowIndex, colIndex } = locateCell(store, cellId);\n\n if (direction === 'left' || direction === 'right') {\n const delta = direction === 'right' ? 1 : -1;\n const nextColIndex = colIndex + delta;\n if (nextColIndex >= 0 && nextColIndex < row.contentIds.length) {\n return row.contentIds[nextColIndex];\n }\n\n const nextRowIndex = rowIndex + delta;\n if (nextRowIndex < 0 || nextRowIndex >= table.contentIds.length) return null; // at the table's very first/last cell\n\n const targetRow = store.getBlock(table.contentIds[nextRowIndex]);\n const targetColIndex = direction === 'right' ? 0 : targetRow.contentIds.length - 1;\n return targetRow.contentIds[targetColIndex];\n }\n\n const delta = direction === 'down' ? 1 : -1;\n const targetRowIndex = rowIndex + delta;\n if (targetRowIndex < 0 || targetRowIndex >= table.contentIds.length) return null;\n const targetRow = store.getBlock(table.contentIds[targetRowIndex]);\n return (\n targetRow.contentIds[colIndex] ?? targetRow.contentIds[targetRow.contentIds.length - 1] ?? null\n );\n}\n\n/**\n * Tab past the table's very last cell exits it entirely — focuses whatever\n * block already follows the table (entering it the same way arrow-key\n * navigation between top-level blocks does), or, if the table is the last\n * block in its container, creates a fresh blank paragraph after it and\n * focuses that. Either way Tab always lands somewhere, never a silent\n * no-op that leaves the user stuck at the end of a document that happens\n * to end in a table.\n */\nfunction exitTableForward(store, tableId) {\n const targetRunId = resolveAdjacentFocusTarget(store, tableId, 'down');\n if (targetRunId) {\n focusRunEnd(targetRunId);\n return;\n }\n insertSiblingAfterAndFocus(store, tableId, createTextLeafBlock('paragraph'));\n}\n\n/** Moves DOM focus to the adjacent cell resolved by resolveAdjacentCellTarget, or exits the table on Tab past its last cell (see exitTableForward). */\nexport function moveToAdjacentCell(store, cellId, direction) {\n const targetCellId = resolveAdjacentCellTarget(store, cellId, direction);\n if (targetCellId) {\n const targetCell = store.getBlock(targetCellId);\n const runId = targetCell?.contentIds?.[0];\n if (runId) focusRunEnd(runId);\n return;\n }\n\n if (direction === 'right') {\n const { table } = locateCell(store, cellId);\n exitTableForward(store, table.id);\n }\n // 'left' at the very first cell, and 'up'/'down' at the table's\n // top/bottom edge, remain a no-op (see resolveAdjacentCellTarget's doc\n // comment on that scope).\n}\n","import { useCallback } from 'react';\nimport { EditableBlockContent } from '../../react/EditableBlockContent.jsx';\nimport { useBlock } from '../../react/useBlock.js';\nimport { useEditorStore, useBlockClassName } from '../../react/EditorProvider.jsx';\nimport { moveToAdjacentCell } from './tableNavigation.js';\nimport { resolveBlockDir } from '../shared/resolveBlockDir.js';\n\n// Deliberately near-identical to ParagraphBlock: a cell is a leaf block\n// whose contentIds are run ids, exactly like a paragraph — it gets\n// formatting/selection/serialization for free from the same run machinery.\n//\n// No Backspace-at-start handling: a cell merging into an adjacent cell has\n// no sensible meaning (no \"merge cells\" in v1), so native no-op is already\n// correct default behavior — not an omission.\nexport function TableCellBlock({ id }) {\n const store = useEditorStore();\n const block = useBlock(id);\n\n const handleTab = useCallback(() => moveToAdjacentCell(store, id, 'right'), [store, id]);\n const handleShiftTab = useCallback(() => moveToAdjacentCell(store, id, 'left'), [store, id]);\n const handleArrowUp = useCallback(() => moveToAdjacentCell(store, id, 'up'), [store, id]);\n const handleArrowDown = useCallback(() => moveToAdjacentCell(store, id, 'down'), [store, id]);\n // Enter moves down a row (spreadsheet-familiar), matching Tab's row-wrap convention.\n const handleEnter = useCallback(() => moveToAdjacentCell(store, id, 'down'), [store, id]);\n\n const className = useBlockClassName('be-table-cell', block);\n\n if (!block) return null;\n const dir = resolveBlockDir(store, block);\n\n return (\n <td className={className} data-block-id={id} dir={dir}>\n <EditableBlockContent\n blockId={id}\n runIds={block.contentIds}\n dir={dir}\n onTab={handleTab}\n onShiftTab={handleShiftTab}\n onArrowUp={handleArrowUp}\n onArrowDown={handleArrowDown}\n onEnter={handleEnter}\n />\n </td>\n );\n}\n","import { genId } from '../../utils/idGen.js';\nimport { createDefaultColumns, createCellForColumn } from './tableColumns.js';\n\nfunction createRow(parentId, columns) {\n const rowId = genId();\n const cellBlocks = [];\n const runs = [];\n const contentIds = [];\n for (const column of columns) {\n const cell = createCellForColumn(rowId, column);\n cellBlocks.push(cell.block);\n runs.push(cell.run);\n contentIds.push(cell.block.id);\n }\n return {\n block: { id: rowId, type: 'tableRow', parentId, contentIds, props: {} },\n blocks: cellBlocks,\n runs,\n };\n}\n\n/** factory(parentId) -> {block, runs, subtreeBlocks} for a fresh rows x cols table. */\nexport function createTableBlock({ rows = 2, cols = 2 } = {}) {\n return function factory(parentId) {\n const tableId = genId();\n const columns = createDefaultColumns(cols);\n const subtreeBlocks = [];\n const allRuns = [];\n const rowIds = [];\n\n for (let r = 0; r < rows; r += 1) {\n const row = createRow(tableId, columns);\n subtreeBlocks.push(row.block, ...row.blocks);\n allRuns.push(...row.runs);\n rowIds.push(row.block.id);\n }\n\n const block = { id: tableId, type: 'table', parentId, contentIds: rowIds, props: { columns } };\n return { block, runs: allRuns, subtreeBlocks };\n };\n}\n","import { TableBlock } from './TableBlock.jsx';\nimport { defineBlock } from '../../registry/define.js';\nimport { TableRowBlock } from './TableRowBlock.jsx';\nimport { TableCellBlock } from './TableCellBlock.jsx';\nimport { runToHTML, runToPlainText, runsToMarkdown, escapeHTML } from '../../inline/marks.js';\nimport { domInlineToRuns } from '../../inline/runOps.js';\nimport { genId } from '../../utils/idGen.js';\nimport { trimSlashQueryAndInsertAfter } from '../shared/blockCommands.js';\nimport { createTableBlock } from './createTableBlock.js';\nimport { resolveColumns } from './tableColumns.js';\nimport { TableIcon } from '../../react/icons.jsx';\n\n// --- tableCell: near-identical to paragraph's toHTML/fromHTML/toPlainText ---\n\nfunction cellToHTML(block, ctx) {\n const runs = block.contentIds.map((runId) => ctx.store.getRun(runId));\n return `<td>${runs.map((r) => runToHTML(r, ctx)).join('')}</td>`;\n}\n\nfunction cellToPlainText(block, ctx) {\n return block.contentIds.map((runId) => runToPlainText(ctx.store.getRun(runId), ctx)).join('');\n}\n\n// GFM table cells can't contain a literal \"|\" (breaks the row) or a real\n// newline (breaks the table entirely) — escape/replace those on top of the\n// normal inline-marks escaping runsToMarkdown already does.\nfunction cellToMarkdown(block, ctx) {\n const raw = runsToMarkdown(\n block.contentIds.map((runId) => ctx.store.getRun(runId)),\n ctx,\n );\n return raw.replace(/\\|/g, '\\\\|').replace(/\\r?\\n/g, '<br>');\n}\n\nfunction cellFromHTML(node, ctx) {\n if (node.tagName !== 'TD' && node.tagName !== 'TH') return null;\n const runs = domInlineToRuns(node, ctx);\n const block = {\n id: genId(),\n type: 'tableCell',\n parentId: null,\n contentIds: runs.map((r) => r.id),\n props: {},\n };\n return { block, runs };\n}\n\n// --- tableRow: pure container, recurses into cells via the registry ---\n\nfunction rowToHTML(block, ctx) {\n const cellsHTML = block.contentIds\n .map((cellId) => {\n const cellBlock = ctx.store.getBlock(cellId);\n return ctx.registry.get(cellBlock.type).toHTML(cellBlock, ctx);\n })\n .join('');\n return `<tr>${cellsHTML}</tr>`;\n}\n\nfunction rowToPlainText(block, ctx) {\n return block.contentIds\n .map((cellId) => {\n const cellBlock = ctx.store.getBlock(cellId);\n return ctx.registry.get(cellBlock.type).toPlainText(cellBlock, ctx);\n })\n .join('\\t');\n}\n\nfunction rowToMarkdown(block, ctx) {\n const cells = block.contentIds.map((cellId) => {\n const cellBlock = ctx.store.getBlock(cellId);\n return ctx.registry.get(cellBlock.type).toMarkdown(cellBlock, ctx);\n });\n return `| ${cells.join(' | ')} |`;\n}\n\nfunction rowFromHTML(node, ctx) {\n if (node.tagName !== 'TR') return null;\n const cellNodes = [...node.children].filter((c) => c.tagName === 'TD' || c.tagName === 'TH');\n const rowId = genId();\n const cellBlocks = [];\n const runs = [];\n const contentIds = [];\n for (const cellNode of cellNodes) {\n const result = ctx.registry.get('tableCell').fromHTML(cellNode, ctx);\n if (!result) continue;\n result.block.parentId = rowId;\n cellBlocks.push(result.block);\n runs.push(...result.runs);\n contentIds.push(result.block.id);\n }\n const block = { id: rowId, type: 'tableRow', parentId: null, contentIds, props: {} };\n return { block, runs, subtreeBlocks: cellBlocks };\n}\n\n// --- table: container of rows ---\n\nfunction tableToHTML(block, ctx) {\n const firstRow = block.contentIds[0] && ctx.store.getBlock(block.contentIds[0]);\n const columns = resolveColumns(block, firstRow?.contentIds?.length ?? 0);\n const theadHTML = columns.length\n ? `<thead><tr>${columns.map((c) => `<th>${escapeHTML(c.label ?? '')}</th>`).join('')}</tr></thead>`\n : '';\n\n const rowsHTML = block.contentIds\n .map((rowId) => {\n const rowBlock = ctx.store.getBlock(rowId);\n return ctx.registry.get(rowBlock.type).toHTML(rowBlock, ctx);\n })\n .join('');\n return `<table>${theadHTML}<tbody>${rowsHTML}</tbody></table>`;\n}\n\nfunction tableToPlainText(block, ctx) {\n return block.contentIds\n .map((rowId) => {\n const rowBlock = ctx.store.getBlock(rowId);\n return ctx.registry.get(rowBlock.type).toPlainText(rowBlock, ctx);\n })\n .join('\\n');\n}\n\n// GFM table syntax: a header row (from props.columns — every contentIds\n// row is a genuine data row, never consumed as the header, same as\n// tableToHTML's separate <thead>/<tbody> split above), a separator row,\n// then each data row. Column TYPE (select/date/etc.) has no Markdown\n// representation of its own — only the label makes it into the header;\n// each cell's own value still renders via cellToMarkdown regardless of\n// its column's type.\nfunction tableToMarkdown(block, ctx) {\n const firstRow = block.contentIds[0] && ctx.store.getBlock(block.contentIds[0]);\n const columns = resolveColumns(block, firstRow?.contentIds?.length ?? 0);\n if (columns.length === 0) return '';\n const headerRow = `| ${columns.map((c) => (c.label ?? '').replace(/\\|/g, '\\\\|')).join(' | ')} |`;\n const separatorRow = `| ${columns.map(() => '---').join(' | ')} |`;\n const bodyRows = block.contentIds\n .map((rowId) => {\n const rowBlock = ctx.store.getBlock(rowId);\n return ctx.registry.get(rowBlock.type).toMarkdown(rowBlock, ctx);\n })\n .join('\\n');\n return bodyRows ? `${headerRow}\\n${separatorRow}\\n${bodyRows}` : `${headerRow}\\n${separatorRow}`;\n}\n\nfunction tableFromHTML(node, ctx) {\n if (node.tagName !== 'TABLE') return null;\n\n // A <thead> row holds column labels, not data — it must never be parsed\n // as a body row too (querySelectorAll('tr') would otherwise match it as\n // well as every <tbody> row, double-counting it). Its own labels are read\n // separately, into props.columns; external HTML with no <thead> at all\n // (pasted from another app) just gets none, and TableBlock/tableToHTML's\n // resolveColumns fallback generates sensible defaults for it.\n const theadRow = node.querySelector('thead tr');\n const bodyRowNodes = node.querySelector('tbody')\n ? [...node.querySelectorAll('tbody tr')]\n : [...node.querySelectorAll('tr')].filter((tr) => tr !== theadRow);\n\n const tableId = genId();\n const subtreeBlocks = [];\n const runs = [];\n const rowIds = [];\n for (const rowNode of bodyRowNodes) {\n const result = ctx.registry.get('tableRow').fromHTML(rowNode, ctx);\n if (!result) continue;\n result.block.parentId = tableId;\n for (const cellBlock of result.subtreeBlocks) cellBlock.parentId = result.block.id;\n subtreeBlocks.push(result.block, ...result.subtreeBlocks);\n runs.push(...result.runs);\n rowIds.push(result.block.id);\n }\n\n const props = {};\n if (theadRow) {\n const headerCells = [...theadRow.children].filter(\n (c) => c.tagName === 'TH' || c.tagName === 'TD',\n );\n props.columns = headerCells.map((cell) => ({ id: genId(), label: cell.textContent ?? '' }));\n }\n\n const block = { id: tableId, type: 'table', parentId: null, contentIds: rowIds, props };\n return { block, runs, subtreeBlocks };\n}\n\nexport const tableCellBlockType = defineBlock({\n name: 'tableCell',\n contentModel: 'runs',\n component: TableCellBlock,\n defaultProps: {},\n toHTML: cellToHTML,\n toPlainText: cellToPlainText,\n toMarkdown: cellToMarkdown,\n fromHTML: cellFromHTML,\n});\n\nexport const tableRowBlockType = defineBlock({\n name: 'tableRow',\n contentModel: 'blocks',\n component: TableRowBlock,\n defaultProps: {},\n toHTML: rowToHTML,\n toPlainText: rowToPlainText,\n toMarkdown: rowToMarkdown,\n fromHTML: rowFromHTML,\n});\n\nexport const tableBlockType = defineBlock({\n name: 'table',\n contentModel: 'blocks',\n component: TableBlock,\n defaultProps: {},\n toHTML: tableToHTML,\n toPlainText: tableToPlainText,\n toMarkdown: tableToMarkdown,\n fromHTML: tableFromHTML,\n slashCommand: {\n label: 'Table',\n icon: TableIcon,\n keywords: ['table', 'grid'],\n run: (store, ctx) =>\n trimSlashQueryAndInsertAfter(store, ctx, createTableBlock({ rows: 2, cols: 2 })),\n },\n});\n","import { BlockChildren } from '../../react/BlockChildren.jsx';\nimport { useBlock } from '../../react/useBlock.js';\nimport { useBlockClassName } from '../../react/EditorProvider.jsx';\n\nexport function LayoutBlock({ id }) {\n const block = useBlock(id);\n const className = useBlockClassName('be-layout', block);\n return (\n <div className={className} data-block-id={id} style={{ display: 'flex', gap: '1em' }}>\n <BlockChildren parentId={id} />\n </div>\n );\n}\n","import { BlockChildren } from '../../react/BlockChildren.jsx';\nimport { useBlock } from '../../react/useBlock.js';\nimport { useBlockClassName } from '../../react/EditorProvider.jsx';\n\n// Identical container mechanism to Page — a column just holds arbitrary\n// child blocks via contentIds, same as the document root does.\nexport function LayoutColumnBlock({ id }) {\n const block = useBlock(id);\n const className = useBlockClassName('be-layout-column', block);\n return (\n <div className={className} data-block-id={id}>\n <BlockChildren parentId={id} />\n </div>\n );\n}\n","import { genId } from '../../utils/idGen.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\n\n/** factory(parentId) -> {block, runs, subtreeBlocks} for a fresh N-column layout. */\nexport function createLayoutBlock({ columns = 2 } = {}) {\n return function factory(parentId) {\n const layoutId = genId();\n const subtreeBlocks = [];\n const allRuns = [];\n const columnIds = [];\n\n for (let c = 0; c < columns; c += 1) {\n const columnId = genId();\n // seed each column with one empty paragraph so there's somewhere to type\n const { block: paragraphBlock, runs } = createTextLeafBlock('paragraph')(columnId);\n const columnBlock = {\n id: columnId,\n type: 'layoutColumn',\n parentId: layoutId,\n contentIds: [paragraphBlock.id],\n props: {},\n };\n subtreeBlocks.push(columnBlock, paragraphBlock);\n allRuns.push(...runs);\n columnIds.push(columnId);\n }\n\n const block = { id: layoutId, type: 'layout', parentId, contentIds: columnIds, props: {} };\n return { block, runs: allRuns, subtreeBlocks };\n };\n}\n","import { LayoutBlock } from './LayoutBlock.jsx';\nimport { defineBlock } from '../../registry/define.js';\nimport { LayoutColumnBlock } from './LayoutColumnBlock.jsx';\nimport { trimSlashQueryAndInsertAfter } from '../shared/blockCommands.js';\nimport { createLayoutBlock } from './createLayoutBlock.js';\nimport { ColumnsIcon } from '../../react/icons.jsx';\n\nfunction containerToHTML(tagOpen, tagClose) {\n return (block, ctx) =>\n `${tagOpen}${block.contentIds\n .map((childId) => {\n const child = ctx.store.getBlock(childId);\n return ctx.registry.get(child.type).toHTML(child, ctx);\n })\n .join('')}${tagClose}`;\n}\n\nfunction containerToPlainText(block, ctx) {\n return block.contentIds\n .map((childId) => {\n const child = ctx.store.getBlock(childId);\n return ctx.registry.get(child.type).toPlainText(child, ctx);\n })\n .join('\\n');\n}\n\n// Markdown has no native side-by-side-columns syntax — columns are just\n// stacked one after another, each child still going through its own real\n// toMarkdown (not toPlainText) so formatting nested inside a layout isn't\n// silently lost.\nfunction containerToMarkdown(block, ctx) {\n return block.contentIds\n .map((childId) => {\n const child = ctx.store.getBlock(childId);\n const entry = ctx.registry.get(child.type);\n return (entry.toMarkdown ?? entry.toPlainText)(child, ctx);\n })\n .join('\\n\\n');\n}\n\nexport const layoutColumnBlockType = defineBlock({\n name: 'layoutColumn',\n contentModel: 'blocks',\n component: LayoutColumnBlock,\n defaultProps: {},\n toHTML: containerToHTML('<div>', '</div>'),\n toPlainText: containerToPlainText,\n toMarkdown: containerToMarkdown,\n // no fromHTML: a bare column has no distinct HTML representation of its\n // own outside a parent `layout`'s markup; layout.fromHTML would construct\n // both together if/when generic multi-column HTML import is added.\n});\n\nexport const layoutBlockType = defineBlock({\n name: 'layout',\n contentModel: 'blocks',\n component: LayoutBlock,\n defaultProps: {},\n toHTML: containerToHTML('<div style=\"display:flex;gap:1em\">', '</div>'),\n toPlainText: containerToPlainText,\n toMarkdown: containerToMarkdown,\n slashCommands: [2, 3, 4, 5].map((columns) => ({\n label: `${columns} columns`,\n icon: ColumnsIcon,\n keywords: ['layout', 'columns', 'column', String(columns)],\n run: (store, ctx) => trimSlashQueryAndInsertAfter(store, ctx, createLayoutBlock({ columns })),\n })),\n});\n","import { useBlock } from '../../react/useBlock.js';\nimport { useBlockClassName } from '../../react/EditorProvider.jsx';\n\n// tabIndex={-1}: not in the normal Tab order, but focusable via .focus() —\n// needed so setSelectedBlockId (EditorProvider) can actually move DOM focus\n// here when it selects this block, keeping the surface's own keydown\n// listener capturing the next Backspace/Delete even after whatever\n// previously had focus (e.g. an adjacent empty paragraph) has just been\n// removed from the DOM entirely.\nexport function DividerBlock({ id }) {\n const block = useBlock(id);\n const className = useBlockClassName('be-divider', block);\n return <hr className={className} data-block-id={id} contentEditable={false} tabIndex={-1} />;\n}\n","import { DividerBlock } from './DividerBlock.jsx';\nimport { defineBlock } from '../../registry/define.js';\nimport { genId } from '../../utils/idGen.js';\nimport { insertSiblingAfter, insertSiblingAfterAndFocus } from '../shared/blockCommands.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\nimport { updateRun } from '../../store/operations.js';\nimport { DividerIcon } from '../../react/icons.jsx';\n\nfunction createDividerBlock() {\n return function factory(parentId) {\n return {\n block: { id: genId(), type: 'divider', parentId, contentIds: [], props: {} },\n runs: [],\n };\n };\n}\n\nfunction toHTML() {\n return '<hr />';\n}\n\nfunction toPlainText() {\n return '---';\n}\n\nfunction toMarkdown() {\n return '---';\n}\n\nfunction fromHTML(node) {\n if (node.tagName !== 'HR') return null;\n return {\n block: { id: genId(), type: 'divider', parentId: null, contentIds: [], props: {} },\n runs: [],\n };\n}\n\nexport const dividerBlockType = defineBlock({\n name: 'divider',\n contentModel: 'void',\n component: DividerBlock,\n defaultProps: {},\n toHTML,\n toPlainText,\n toMarkdown,\n fromHTML,\n slashCommand: {\n label: 'Divider',\n icon: DividerIcon,\n keywords: ['divider', 'hr', 'separator', 'line'],\n run: (store, { blockId, runId, sliceStart, sliceEnd }) => {\n const run = store.getRun(runId);\n const value = run?.value ?? '';\n store.applyOperation(\n updateRun(runId, { value: value.slice(0, sliceStart) + value.slice(sliceEnd) }),\n );\n\n // seed a paragraph right after so there's always somewhere to type\n // past the divider — it has no run of its own to focus into.\n const dividerId = insertSiblingAfter(store, blockId, createDividerBlock());\n insertSiblingAfterAndFocus(store, dividerId, createTextLeafBlock('paragraph'));\n return dividerId;\n },\n },\n});\n","import { useCallback, useMemo, useRef, useState } from 'react';\nimport { BlockChildren } from '../../react/BlockChildren.jsx';\nimport { useBlock } from '../../react/useBlock.js';\nimport { useEditorStore, useBlockClassName } from '../../react/EditorProvider.jsx';\nimport { useOutsideClickAndEscape } from '../../react/useOutsideClickAndEscape.js';\nimport { updateBlockProps } from '../../store/operations.js';\nimport { DEFAULT_CALLOUT_ICON, DEFAULT_CALLOUT_COLOR } from './createCalloutBlock.js';\n\nexport const CALLOUT_COLORS = [\n { value: 'gray', label: 'Gray' },\n { value: 'blue', label: 'Blue' },\n { value: 'green', label: 'Green' },\n { value: 'yellow', label: 'Yellow' },\n { value: 'orange', label: 'Orange' },\n { value: 'red', label: 'Red' },\n { value: 'purple', label: 'Purple' },\n { value: 'pink', label: 'Pink' },\n];\n\n/**\n * A plain container (contentIds hold child block ids, exactly like\n * layoutColumn/page) wrapped in a colored card with an editable icon — same\n * mechanism used for \"callout\": no bespoke text/run handling\n * of its own, so every child block (paragraph, list, another callout, ...)\n * gets full selection/copy/paste/format/undo support for free from the\n * shared container machinery, the same way layout columns already do.\n *\n * \"Title\" and \"description\" (see the CSS: `.be-callout-content > :first-\n * child` vs the rest) aren't a separate data shape — they're just the\n * first child block rendered bold vs. every child after it rendered\n * muted/smaller. That keeps the callout exactly as flexible as before (any\n * number of arbitrary child blocks, not a fixed two-field shape) while\n * still matching the title+description card look, since a callout's first\n * line reads as its heading in practice anyway.\n *\n * The icon is a plain text input rather than a dedicated emoji picker for\n * now (item 7 in the requested list) — swap this for that picker once it\n * exists; typing/pasting any emoji directly already works today.\n */\nexport function CalloutBlock({ id }) {\n const store = useEditorStore();\n const block = useBlock(id);\n const [editingIcon, setEditingIcon] = useState(false);\n const [isColorPickerOpen, setIsColorPickerOpen] = useState(false);\n const colorTriggerRef = useRef(null);\n const colorPickerRef = useRef(null);\n const colorOutsideRefs = useMemo(() => [colorTriggerRef, colorPickerRef], []);\n\n const closeColorPicker = useCallback(() => setIsColorPickerOpen(false), []);\n useOutsideClickAndEscape(colorOutsideRefs, isColorPickerOpen, closeColorPicker);\n\n const icon = block?.props?.icon ?? DEFAULT_CALLOUT_ICON;\n const color = block?.props?.color ?? DEFAULT_CALLOUT_COLOR;\n\n const commitIcon = useCallback(\n (event) => {\n const next = event.target.value.trim();\n if (next) store.applyOperation(updateBlockProps(id, { icon: next }));\n setEditingIcon(false);\n },\n [store, id],\n );\n\n const handleIconKeyDown = useCallback((event) => {\n if (event.key === 'Enter') event.currentTarget.blur();\n if (event.key === 'Escape') setEditingIcon(false);\n }, []);\n\n const handleColorChange = useCallback(\n (next) => {\n store.applyOperation(updateBlockProps(id, { color: next }));\n setIsColorPickerOpen(false);\n },\n [store, id],\n );\n\n const className = useBlockClassName('be-callout', block);\n\n if (!block) return null;\n\n return (\n <div className={className} data-block-id={id} data-color={color}>\n <div className=\"be-callout-icon-wrap\">\n {editingIcon ? (\n <input\n type=\"text\"\n className=\"be-callout-icon-input\"\n defaultValue={icon}\n autoFocus\n onBlur={commitIcon}\n onKeyDown={handleIconKeyDown}\n aria-label=\"Callout icon (paste or type an emoji)\"\n />\n ) : (\n <button\n type=\"button\"\n className=\"be-callout-icon\"\n onClick={() => setEditingIcon(true)}\n aria-label=\"Change callout icon\"\n title=\"Change icon\"\n >\n {icon}\n </button>\n )}\n </div>\n\n <div className=\"be-callout-content\">\n <BlockChildren parentId={id} />\n </div>\n\n <div className=\"be-callout-color-wrap\" contentEditable={false}>\n <button\n ref={colorTriggerRef}\n type=\"button\"\n className=\"be-callout-color-trigger\"\n aria-label=\"Callout color\"\n aria-haspopup=\"true\"\n aria-expanded={isColorPickerOpen}\n title=\"Callout color\"\n onClick={() => setIsColorPickerOpen((open) => !open)}\n >\n <span className={`be-callout-color-dot be-callout-color-dot-${color}`} />\n </button>\n {isColorPickerOpen && (\n <div\n ref={colorPickerRef}\n className=\"be-callout-color-picker\"\n role=\"menu\"\n aria-label=\"Callout color\"\n >\n {CALLOUT_COLORS.map((c) => (\n <button\n key={c.value}\n type=\"button\"\n role=\"menuitem\"\n className={`be-callout-color-option be-callout-color-option-${c.value}${\n c.value === color ? ' be-callout-color-option-active' : ''\n }`}\n title={c.label}\n aria-label={c.label}\n onClick={() => handleColorChange(c.value)}\n />\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { CalloutBlock } from './CalloutBlock.jsx';\nimport { defineBlock } from '../../registry/define.js';\nimport { trimSlashQueryAndInsertAfter } from '../shared/blockCommands.js';\nimport { createCalloutBlock, DEFAULT_CALLOUT_ICON } from './createCalloutBlock.js';\nimport { CalloutIcon } from '../../react/icons.jsx';\n\nfunction childrenToHTML(block, ctx) {\n return block.contentIds\n .map((childId) => {\n const child = ctx.store.getBlock(childId);\n return ctx.registry.get(child.type).toHTML(child, ctx);\n })\n .join('');\n}\n\nfunction toHTML(block, ctx) {\n const icon = block.props?.icon ?? DEFAULT_CALLOUT_ICON;\n return `<div class=\"callout\" data-icon=\"${icon}\"><div class=\"callout-icon\">${icon}</div><div class=\"callout-content\">${childrenToHTML(block, ctx)}</div></div>`;\n}\n\nfunction toPlainText(block, ctx) {\n const icon = block.props?.icon ?? DEFAULT_CALLOUT_ICON;\n const inner = block.contentIds\n .map((childId) => {\n const child = ctx.store.getBlock(childId);\n return ctx.registry.get(child.type).toPlainText(child, ctx);\n })\n .join('\\n');\n return `${icon} ${inner}`;\n}\n\n// No native Markdown callout/aside syntax — a blockquote with the icon\n// prefixed on its first line is the closest common convention (GitHub's\n// own \"> [!NOTE]\"-style alerts are a similar idea), and degrades gracefully\n// to a plain quote in any renderer that doesn't recognize alert syntax.\nfunction toMarkdown(block, ctx) {\n const icon = block.props?.icon ?? DEFAULT_CALLOUT_ICON;\n const lines = block.contentIds\n .map((childId) => {\n const child = ctx.store.getBlock(childId);\n const entry = ctx.registry.get(child.type);\n return (entry.toMarkdown ?? entry.toPlainText)(child, ctx);\n })\n .join('\\n')\n .split('\\n');\n return lines.map((line, i) => `> ${i === 0 ? `${icon} ` : ''}${line}`).join('\\n');\n}\n\nexport const calloutBlockType = defineBlock({\n name: 'callout',\n contentModel: 'blocks',\n component: CalloutBlock,\n defaultProps: { icon: DEFAULT_CALLOUT_ICON },\n toHTML,\n toPlainText,\n toMarkdown,\n // No fromHTML: same precedent as layoutColumn — there's no standard\n // external HTML shape for a \"callout\" box, so plain-HTML paste doesn't\n // need to reconstruct one. Same-editor copy/paste is already lossless\n // via the generic block-subtree JSON clipboard path\n // (captureSubtree in clipboard/serialize.js), which walks\n // contentIds generically and needs no per-type awareness at all.\n slashCommand: {\n label: 'Callout',\n icon: CalloutIcon,\n keywords: ['callout', 'aside', 'note', 'info', 'tip', 'warning'],\n run: (store, ctx) => trimSlashQueryAndInsertAfter(store, ctx, createCalloutBlock()),\n },\n});\n","import { useCallback } from 'react';\nimport { EditableBlockContent } from '../../react/EditableBlockContent.jsx';\nimport { useBlock } from '../../react/useBlock.js';\nimport {\n useEditorStore,\n useSelectedBlock,\n useBlockClassName,\n} from '../../react/EditorProvider.jsx';\nimport { insertSiblingSplitAtCaretAndFocus } from '../shared/blockCommands.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\nimport { mergeWithPreviousOrDelete } from '../shared/mergeCommands.js';\nimport { isRunsEmpty } from '../shared/blockEmpty.js';\nimport { focusAfterMerge } from '../shared/focusAfterMerge.js';\nimport { focusAdjacentBlock } from '../shared/navigationCommands.js';\nimport { resolveBlockDir } from '../shared/resolveBlockDir.js';\n\n/**\n * A leaf block, exactly like ParagraphBlock/HeadingBlock (contentIds are\n * its own run ids, not child blocks) — the only difference is presentation\n * (a <blockquote> tag with a left border). Enter exits the quote into a\n * plain paragraph sibling, matching heading's own convention — a quote\n * is a single formatted block,\n * not a container you keep typing new lines into via Enter.\n */\nexport function BlockquoteBlock({ id }) {\n const store = useEditorStore();\n const block = useBlock(id);\n const { setSelectedBlockId } = useSelectedBlock();\n\n const handleEnter = useCallback(() => {\n insertSiblingSplitAtCaretAndFocus(\n store,\n id,\n block?.contentIds ?? [],\n createTextLeafBlock('paragraph'),\n );\n }, [store, id, block]);\n\n const handleBackspaceAtStart = useCallback(() => {\n const focusBlockId = mergeWithPreviousOrDelete(store, id);\n focusAfterMerge(store, focusBlockId, id, setSelectedBlockId);\n }, [store, id, setSelectedBlockId]);\n\n const handleArrowUp = useCallback(() => focusAdjacentBlock(store, id, 'up'), [store, id]);\n const handleArrowDown = useCallback(() => focusAdjacentBlock(store, id, 'down'), [store, id]);\n\n const className = useBlockClassName('be-blockquote', block);\n\n if (!block) return null;\n const isEmpty = isRunsEmpty(store, block.contentIds);\n const dir = resolveBlockDir(store, block);\n\n return (\n <blockquote\n className={className}\n data-block-id={id}\n data-empty={isEmpty ? '' : undefined}\n data-placeholder=\"Empty quote\"\n dir={dir}\n >\n <EditableBlockContent\n blockId={id}\n runIds={block.contentIds}\n dir={dir}\n onEnter={handleEnter}\n onBackspaceAtStart={handleBackspaceAtStart}\n onArrowUp={handleArrowUp}\n onArrowDown={handleArrowDown}\n />\n </blockquote>\n );\n}\n","import { BlockquoteBlock } from './BlockquoteBlock.jsx';\nimport { defineBlock } from '../../registry/define.js';\nimport { runToHTML, runToPlainText, runsToMarkdown } from '../../inline/marks.js';\nimport { domInlineToRuns } from '../../inline/runOps.js';\nimport { genId } from '../../utils/idGen.js';\nimport { trimSlashQueryAndInsertAfter } from '../shared/blockCommands.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\nimport { QuoteIcon } from '../../react/icons.jsx';\n\nfunction toHTML(block, ctx) {\n const runs = block.contentIds.map((runId) => ctx.store.getRun(runId));\n return `<p>${runs.map((r) => runToHTML(r, ctx)).join('')}</p>`;\n}\n\nfunction toPlainText(block, ctx) {\n return block.contentIds.map((runId) => runToPlainText(ctx.store.getRun(runId), ctx)).join('');\n}\n\n// Consecutive blockquote sibling blocks (one per line, this editor's own\n// model — see clipboard/serialize.js's toHTML grouping) each get their own\n// leading \"> \" here; the top-level exportDocumentMarkdown joiner knows not\n// to insert a blank line between consecutive blockquote siblings, so they\n// read back as one continuous quote instead of separate ones.\nfunction toMarkdown(block, ctx) {\n const text = runsToMarkdown(\n block.contentIds.map((runId) => ctx.store.getRun(runId)),\n ctx,\n );\n return `> ${text}`;\n}\n\nfunction fromHTML(node, ctx) {\n if (node.tagName !== 'BLOCKQUOTE') return null;\n const runs = domInlineToRuns(node, ctx);\n const block = {\n id: genId(),\n type: 'blockquote',\n parentId: null,\n contentIds: runs.map((r) => r.id),\n props: {},\n };\n return { block, runs };\n}\n\nexport const blockquoteBlockType = defineBlock({\n name: 'blockquote',\n contentModel: 'runs',\n component: BlockquoteBlock,\n defaultProps: {},\n toHTML,\n toPlainText,\n toMarkdown,\n fromHTML,\n slashCommand: {\n label: 'Quote',\n icon: QuoteIcon,\n keywords: ['quote', 'blockquote', 'citation'],\n run: (store, ctx) =>\n trimSlashQueryAndInsertAfter(store, ctx, createTextLeafBlock('blockquote')),\n },\n});\n","import { useCallback } from 'react';\nimport { EditableBlockContent } from '../../react/EditableBlockContent.jsx';\nimport { Select } from '../../react/Select.jsx';\nimport { useBlock } from '../../react/useBlock.js';\nimport {\n useEditorStore,\n useBlockClassName,\n useShowLineNumbers,\n} from '../../react/EditorProvider.jsx';\nimport { mergeWithPreviousOrDelete } from '../shared/mergeCommands.js';\nimport { isRunsEmpty } from '../shared/blockEmpty.js';\nimport { focusRunEnd, focusRunAtOffset } from '../../react/focusRun.js';\nimport { resolveCollapsedCaret } from '../../react/selectionResolve.js';\nimport { updateRun, updateBlockProps } from '../../store/operations.js';\nimport { focusAdjacentBlock } from '../shared/navigationCommands.js';\nimport { deleteBlockAndFocusSibling } from '../shared/blockActions.js';\nimport { TrashIcon } from '../../react/icons.jsx';\n\nexport const LANGUAGES = [\n 'plaintext',\n 'javascript',\n 'python',\n 'html',\n 'css',\n 'json',\n 'bash',\n 'sql',\n];\nconst LANGUAGE_OPTIONS = LANGUAGES.map((lang) => ({ value: lang, label: lang }));\n\n/**\n * Inserts literal text at the live caret within `blockId`'s own run,\n * splicing directly into that run's value — used for Enter (a real \"\\n\",\n * not a block split: a code block is multi-line *within one block*, like a\n * <textarea>) and Tab (two literal spaces, since\n * Tab inside code should never trigger indent-list/next-cell navigation).\n * Deliberately simple (single-run splice, no split-into-marks handling)\n * because code content is plain text — no rich inline formatting is\n * offered for it in this UI.\n */\nfunction insertLiteralTextAtCaret(store, blockId, text) {\n const caret = resolveCollapsedCaret();\n if (!caret || caret.blockId !== blockId) return;\n const run = store.getRun(caret.runId);\n if (!run || run.type !== 'text') return;\n const value = run.value ?? '';\n const newValue = value.slice(0, caret.offset) + text + value.slice(caret.offset);\n store.applyOperation(updateRun(run.id, { value: newValue }));\n focusRunAtOffset(run.id, caret.offset + text.length);\n}\n\n/**\n * A leaf block (own runs, same mechanism as paragraph/heading) rendered\n * inside a <pre><code> so embedded \"\\n\" characters actually break lines\n * (white-space: pre-wrap, see the CSS) — the only block type where Enter\n * doesn't split into a new sibling. Backspace-at-start still goes through\n * the ordinary shared mergeWithPreviousOrDelete: code is deliberately NOT\n * in MERGEABLE_TEXT_TYPES (concatenating code text into a plain paragraph,\n * or vice versa, has no sensible meaning — same exclusion as table/\n * listItem), so a *non-empty* code block simply won't merge into its\n * previous sibling; an *empty* one is still removed outright, landing\n * focus on whatever came before it.\n *\n * No syntax highlighting (tokenizing/coloring code) is performed — that\n * needs a highlighter library, which the zero-runtime-dependency\n * constraint on this package rules out. `props.language` is kept as plain\n * metadata (round-trips through copy/paste and serialization) for a host\n * app to feed into its own highlighter if it has one.\n */\nexport function CodeBlock({ id }) {\n const store = useEditorStore();\n const block = useBlock(id);\n const showLineNumbers = useShowLineNumbers();\n\n const handleEnter = useCallback(() => insertLiteralTextAtCaret(store, id, '\\n'), [store, id]);\n const handleTab = useCallback(() => insertLiteralTextAtCaret(store, id, ' '), [store, id]);\n\n const handleBackspaceAtStart = useCallback(() => {\n const focusBlockId = mergeWithPreviousOrDelete(store, id);\n if (!focusBlockId || focusBlockId === id) return;\n const focusBlock = store.getBlock(focusBlockId);\n const lastRunId = focusBlock?.contentIds?.[focusBlock.contentIds.length - 1];\n if (lastRunId) focusRunEnd(lastRunId);\n }, [store, id]);\n\n const handleArrowUp = useCallback(() => focusAdjacentBlock(store, id, 'up'), [store, id]);\n const handleArrowDown = useCallback(() => focusAdjacentBlock(store, id, 'down'), [store, id]);\n\n const handleLanguageChange = useCallback(\n (language) => store.applyOperation(updateBlockProps(id, { language })),\n [store, id],\n );\n\n const handleDelete = useCallback(() => deleteBlockAndFocusSibling(store, id), [store, id]);\n\n const className = useBlockClassName('be-code-block', block);\n\n if (!block) return null;\n const language = block.props?.language ?? 'plaintext';\n const isEmpty = isRunsEmpty(store, block.contentIds);\n // Display-only — derived fresh from the block's own text on every render,\n // never stored. Counts '\\n's inserted by handleEnter above (this block's\n // multi-line-within-one-run model), not separate line blocks.\n const lineCount = showLineNumbers\n ? (block.contentIds\n .map((runId) => store.getRun(runId)?.value ?? '')\n .join('')\n .match(/\\n/g)?.length ?? 0) + 1\n : 0;\n\n return (\n <div className={className} data-block-id={id}>\n <div className=\"be-code-block-header\" contentEditable={false}>\n <Select\n className=\"be-code-block-language\"\n value={language}\n options={LANGUAGE_OPTIONS}\n onChange={handleLanguageChange}\n ariaLabel=\"Code language\"\n />\n <button\n type=\"button\"\n className=\"be-code-block-delete\"\n onClick={handleDelete}\n aria-label=\"Delete code block\"\n title=\"Delete code block\"\n >\n <TrashIcon size={14} />\n </button>\n </div>\n {/*\n Deliberately always dir=\"ltr\", never resolveBlockDir — code syntax\n (brackets, operators, punctuation) is structurally LTR regardless of\n what language a comment/string literal happens to be written in;\n letting it inherit an RTL document default would scramble the\n visual order of the code itself, not just the prose inside it. Every\n real code editor (VS Code included) forces LTR for code for the\n same reason.\n */}\n <div className=\"be-code-block-body\">\n {showLineNumbers && (\n <div className=\"be-code-block-gutter\" contentEditable={false} aria-hidden=\"true\">\n {Array.from({ length: lineCount }, (_, i) => (\n <span key={i}>{i + 1}</span>\n ))}\n </div>\n )}\n <pre className=\"be-code-block-pre\" dir=\"ltr\">\n <code data-empty={isEmpty ? '' : undefined} data-placeholder=\"Empty code block\">\n <EditableBlockContent\n blockId={id}\n runIds={block.contentIds}\n dir=\"ltr\"\n onEnter={handleEnter}\n onTab={handleTab}\n onBackspaceAtStart={handleBackspaceAtStart}\n onArrowUp={handleArrowUp}\n onArrowDown={handleArrowDown}\n />\n </code>\n </pre>\n </div>\n </div>\n );\n}\n","import { CodeBlock } from './CodeBlock.jsx';\nimport { defineBlock } from '../../registry/define.js';\nimport { runToHTML, runToPlainText, escapeHTML } from '../../inline/marks.js';\nimport { genId } from '../../utils/idGen.js';\nimport { trimSlashQueryAndInsertAfter } from '../shared/blockCommands.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\nimport { CodeIcon } from '../../react/icons.jsx';\n\nfunction toHTML(block, ctx) {\n const runs = block.contentIds.map((runId) => ctx.store.getRun(runId));\n const language = block.props?.language;\n const langAttr =\n language && language !== 'plaintext' ? ` data-language=\"${escapeHTML(language)}\"` : '';\n return `<pre><code${langAttr}>${runs.map((r) => runToHTML(r, ctx)).join('')}</code></pre>`;\n}\n\nfunction toPlainText(block, ctx) {\n return block.contentIds.map((runId) => runToPlainText(ctx.store.getRun(runId), ctx)).join('');\n}\n\n// A fenced code block, not runToMarkdown-per-run — code content is\n// rendered verbatim (marks inside a code block have no meaning here\n// anyway; CodeBlock never applies bold/italic to its own runs), so this\n// reads the raw run values directly rather than going through the\n// inline-marks Markdown path plain text already avoids the same way.\nfunction toMarkdown(block, ctx) {\n const language = block.props?.language;\n const fenceLang = language && language !== 'plaintext' ? language : '';\n const code = block.contentIds.map((runId) => ctx.store.getRun(runId)?.value ?? '').join('');\n return `\\`\\`\\`${fenceLang}\\n${code}\\n\\`\\`\\``;\n}\n\nfunction fromHTML(node, ctx) {\n if (node.tagName !== 'PRE') return null;\n const codeEl = node.querySelector('code') ?? node;\n const language = codeEl.getAttribute?.('data-language');\n const runId = genId();\n const block = {\n id: genId(),\n type: 'code',\n parentId: null,\n contentIds: [runId],\n props: language ? { language } : {},\n };\n return { block, runs: [{ id: runId, type: 'text', value: codeEl.textContent ?? '', marks: {} }] };\n}\n\nexport const codeBlockType = defineBlock({\n name: 'code',\n contentModel: 'runs',\n component: CodeBlock,\n defaultProps: { language: 'plaintext' },\n toHTML,\n toPlainText,\n toMarkdown,\n fromHTML,\n slashCommand: {\n label: 'Code',\n icon: CodeIcon,\n keywords: ['code', 'codeblock', 'snippet', 'pre'],\n run: (store, ctx) => trimSlashQueryAndInsertAfter(store, ctx, createTextLeafBlock('code')),\n },\n});\n","import { removeBlock, insertBlock } from '../../store/operations.js';\nimport { isContentlessBlock } from '../shared/contentless.js';\nimport { isRunsEmpty } from '../shared/blockEmpty.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\n\nexport function isBlankTitle(store, titleRunIds) {\n return (\n titleRunIds.length === 0 ||\n (titleRunIds.length === 1 && (store.getRun(titleRunIds[0])?.value ?? '') === '')\n );\n}\n\n/**\n * True when this toggle heading's body has no real content at all — either\n * no children (shouldn't normally happen; createToggleHeadingBlock always\n * seeds one) or just its single seeded blank paragraph, still untouched.\n * Anything more (a second child, or the sole child holding real text/other\n * content) counts as \"has content\".\n */\nfunction isBodyEmpty(store, block) {\n const childIds = block.contentIds ?? [];\n if (childIds.length === 0) return true;\n if (childIds.length > 1) return false;\n const onlyChild = store.getBlock(childIds[0]);\n return (\n Boolean(onlyChild) && onlyChild.type === 'paragraph' && isRunsEmpty(store, onlyChild.contentIds)\n );\n}\n\nfunction applyOps(store, ops) {\n if (typeof store.performBatch === 'function') store.performBatch(ops);\n else for (const op of ops) store.applyOperation(op);\n}\n\n/**\n * Backspace-at-start for a toggle heading's own title. A toggle heading is\n * only ever removable when it's *entirely* blank — title empty AND its\n * body is empty too (see isBodyEmpty) — since createToggleHeadingBlock\n * always seeds one blank paragraph child, checking for literally zero\n * children (the previous version of this check) could never be true in\n * practice, making an empty toggle heading permanently undeletable via\n * Backspace. isBodyEmpty treats \"just the untouched seeded paragraph\" the\n * same as \"no children\" to fix that.\n *\n * No merge-into-previous-sibling behavior at all (unlike plain paragraph/\n * heading, which concatenate text into whatever's before them): a toggle\n * heading isn't in MERGEABLE_TEXT_TYPES, since \"concatenate this section's\n * title into a plain paragraph\" has no well-defined meaning once it may be\n * carrying nested children — matches the same non-mergeable precedent as\n * table/listItem/callout.\n */\nexport function mergeToggleHeadingOrNoop(store, blockId) {\n const block = store.getBlock(blockId);\n if (!block) return null;\n const parent = store.getBlock(block.parentId);\n const index = parent.contentIds.indexOf(blockId);\n const titleRunIds = block.props.titleRunIds ?? [];\n const empty = isBlankTitle(store, titleRunIds) && isBodyEmpty(store, block);\n\n if (index <= 0) {\n if (!empty) return null; // real content somewhere, nothing before it: no-op, as every other editor does\n\n if (parent.contentIds.length > 1) {\n applyOps(store, [removeBlock(blockId)]);\n return { focusBlockId: store.getBlock(parent.id).contentIds[0], needsRefocus: true };\n }\n\n // sole block in its container: replace with a blank paragraph so\n // there's still somewhere to type, same \"never leave nothing to click\n // into\" fallback as mergeWithPreviousOrDelete/ensureRootNonEmpty.\n const { block: fallbackBlock, runs } = createTextLeafBlock('paragraph')(parent.id);\n applyOps(store, [\n insertBlock(fallbackBlock, parent.id, index, { blocks: [fallbackBlock], runs }),\n removeBlock(blockId),\n ]);\n return { focusBlockId: fallbackBlock.id, needsRefocus: true };\n }\n\n const prevId = parent.contentIds[index - 1];\n const prev = store.getBlock(prevId);\n\n // An entirely-empty CURRENT toggle heading goes first, even next to a\n // non-editable previous sibling — see the matching comment in\n // shared/mergeCommands.js for why this ordering matters.\n if (empty) {\n applyOps(store, [removeBlock(blockId)]);\n return { focusBlockId: prevId, needsRefocus: true };\n }\n\n if (isContentlessBlock(store, prev)) {\n applyOps(store, [removeBlock(prevId)]);\n return { focusBlockId: blockId, needsRefocus: false };\n }\n\n return null;\n}\n","import { useCallback } from 'react';\nimport { useBlock } from '../../react/useBlock.js';\nimport { EditableBlockContent } from '../../react/EditableBlockContent.jsx';\nimport { BlockChildren } from '../../react/BlockChildren.jsx';\nimport {\n useEditorStore,\n useSelectedBlock,\n useBlockClassName,\n} from '../../react/EditorProvider.jsx';\nimport {\n insertSiblingSplitAtCaretAndFocus,\n insertFirstChildSplitAtCaretAndFocus,\n} from '../shared/blockCommands.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\nimport { mergeToggleHeadingOrNoop } from './mergeCommands.js';\nimport { isRunsEmpty } from '../shared/blockEmpty.js';\nimport { focusAfterMerge } from '../shared/focusAfterMerge.js';\nimport { updateBlockProps, insertBlock } from '../../store/operations.js';\nimport { focusAdjacentBlock } from '../shared/navigationCommands.js';\nimport { resolveBlockDir } from '../shared/resolveBlockDir.js';\nimport { focusRunEnd } from '../../react/focusRun.js';\nimport { ChevronRightIcon, ChevronDownIcon } from '../../react/icons.jsx';\n\nfunction applyOps(store, ops) {\n if (typeof store.performBatch === 'function') store.performBatch(ops);\n else for (const op of ops) store.applyOperation(op);\n}\n\n/**\n * A heading whose section can be collapsed — same title+children split as\n * ListItemBlock (own text in props.titleRunIds, nested content in\n * contentIds), so collapsing is a purely local re-render (this component\n * conditionally skips <BlockChildren>) rather than needing any sibling-\n * range computation. Deliberately a distinct block type from `heading`\n * (not a retrofit) to avoid touching that type's existing leaf shape\n * (contentIds = its own runs) — heading is used throughout the merge/\n * split/serialize code as a plain leaf, and changing that shape would\n * ripple into all of it.\n */\nexport function ToggleHeadingBlock({ id }) {\n const store = useEditorStore();\n const block = useBlock(id);\n const { setSelectedBlockId } = useSelectedBlock();\n\n const handleEnter = useCallback(() => {\n const titleRunIds = block?.props?.titleRunIds ?? [];\n const hasNestedChildren = (block?.contentIds?.length ?? 0) > 0;\n const factory = createTextLeafBlock('paragraph');\n if (hasNestedChildren) {\n insertFirstChildSplitAtCaretAndFocus(store, id, titleRunIds, factory);\n } else {\n insertSiblingSplitAtCaretAndFocus(store, id, titleRunIds, factory);\n }\n }, [store, id, block]);\n\n const handleBackspaceAtStart = useCallback(() => {\n const result = mergeToggleHeadingOrNoop(store, id);\n if (!result || !result.needsRefocus) return;\n focusAfterMerge(store, result.focusBlockId, id, setSelectedBlockId);\n }, [store, id, setSelectedBlockId]);\n\n const handleArrowUp = useCallback(() => focusAdjacentBlock(store, id, 'up'), [store, id]);\n const handleArrowDown = useCallback(() => focusAdjacentBlock(store, id, 'down'), [store, id]);\n\n const toggleCollapsed = useCallback(() => {\n const hasChildren = (block?.contentIds?.length ?? 0) > 0;\n if (!hasChildren) {\n // A childless toggle heading has nothing to expand/collapse yet —\n // this was previously a disabled dead end. Clicking now bootstraps\n // the first (empty) child and expands, same fix as the toggle list\n // item's own marker.\n const { block: childBlock, runs } = createTextLeafBlock('paragraph')(id);\n applyOps(store, [\n insertBlock(childBlock, id, 0, { blocks: [childBlock], runs }),\n updateBlockProps(id, { collapsed: false }),\n ]);\n focusRunEnd(childBlock.contentIds[0]);\n return;\n }\n store.applyOperation(updateBlockProps(id, { collapsed: !block?.props?.collapsed }));\n }, [store, id, block?.contentIds, block?.props?.collapsed]);\n\n const className = useBlockClassName('be-toggle-heading', block);\n\n if (!block) return null;\n const { level = 2, collapsed, titleRunIds = [] } = block.props;\n const hasNestedChildren = block.contentIds.length > 0;\n const Tag = `h${level}`;\n const dir = resolveBlockDir(store, block);\n\n return (\n <div className={className} data-block-id={id} dir={dir}>\n <div className=\"be-toggle-heading-row\">\n <button\n type=\"button\"\n className=\"be-toggle-heading-marker\"\n onClick={toggleCollapsed}\n aria-expanded={!collapsed}\n aria-label={\n !hasNestedChildren\n ? 'Add content to section'\n : collapsed\n ? 'Expand section'\n : 'Collapse section'\n }\n >\n {collapsed ? <ChevronRightIcon /> : <ChevronDownIcon />}\n </button>\n <Tag\n className={`be-heading be-heading-${level} be-toggle-heading-title`}\n data-empty={isRunsEmpty(store, titleRunIds) ? '' : undefined}\n data-placeholder={`Toggle heading ${level}`}\n >\n <EditableBlockContent\n blockId={id}\n runIds={titleRunIds}\n dir={dir}\n onEnter={handleEnter}\n onBackspaceAtStart={handleBackspaceAtStart}\n onArrowUp={handleArrowUp}\n onArrowDown={handleArrowDown}\n />\n </Tag>\n </div>\n {!collapsed && (\n <div className=\"be-toggle-heading-children\">\n <BlockChildren parentId={id} />\n </div>\n )}\n </div>\n );\n}\n","import { genId } from '../../utils/idGen.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\n\n/**\n * factory(parentId, initialRuns?) -> {block, runs, subtreeBlocks} for a\n * toggle heading — its own text lives in props.titleRunIds (same\n * title+children split as listItem), while contentIds holds the section's\n * nested content, rendered only while props.collapsed is false. Seeded\n * with one empty paragraph child (same convention as callout/layout's\n * columns) so there's always at least one place to type into right away —\n * critical here specifically, since Enter on the title only ever inserts a\n * *first child* when the toggle heading already has children (see\n * ToggleHeadingBlock's handleEnter); without a seeded child, there'd be no\n * way to get content under a brand-new toggle heading at all.\n */\nexport function createToggleHeadingBlock({ level = 2, collapsed = false } = {}) {\n return function factory(parentId, initialRuns) {\n const blockId = genId();\n const runs = initialRuns?.length\n ? initialRuns\n : [{ id: genId(), type: 'text', value: '', marks: {} }];\n const { block: childBlock, runs: childRuns } = createTextLeafBlock('paragraph')(blockId);\n return {\n block: {\n id: blockId,\n type: 'toggleHeading',\n parentId,\n contentIds: [childBlock.id],\n props: { level, collapsed, titleRunIds: runs.map((r) => r.id) },\n },\n runs: [...runs, ...childRuns],\n subtreeBlocks: [childBlock],\n };\n };\n}\n","import { ToggleHeadingBlock } from './ToggleHeadingBlock.jsx';\nimport { defineBlock } from '../../registry/define.js';\nimport { runToHTML, runToPlainText, runsToMarkdown } from '../../inline/marks.js';\nimport { domInlineToRuns } from '../../inline/runOps.js';\nimport { genId } from '../../utils/idGen.js';\nimport { trimSlashQueryAndInsertAfter } from '../shared/blockCommands.js';\nimport { createToggleHeadingBlock } from './createToggleHeadingBlock.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\nimport { ChevronRightIcon } from '../../react/icons.jsx';\n\n/**\n * <details>/<summary> is a genuine semantic match for a toggle heading —\n * `open` reflects the expanded state natively, so this round-trips through\n * any HTML consumer that understands plain HTML5 disclosure widgets, not\n * just this editor.\n */\nfunction toHTML(block, ctx) {\n const { titleRunIds = [], level = 2, collapsed } = block.props;\n const titleHTML = titleRunIds.map((runId) => runToHTML(ctx.store.getRun(runId), ctx)).join('');\n const childrenHTML = block.contentIds\n .map((childId) => {\n const child = ctx.store.getBlock(childId);\n return ctx.registry.get(child.type).toHTML(child, ctx);\n })\n .join('');\n return `<details${collapsed ? '' : ' open'}><summary><h${level}>${titleHTML}</h${level}></summary>${childrenHTML}</details>`;\n}\n\nfunction toPlainText(block, ctx) {\n const { titleRunIds = [] } = block.props;\n const title = titleRunIds.map((runId) => runToPlainText(ctx.store.getRun(runId), ctx)).join('');\n const children = block.contentIds\n .map((childId) => {\n const child = ctx.store.getBlock(childId);\n return ctx.registry.get(child.type).toPlainText(child, ctx);\n })\n .join('\\n');\n return children ? `${title}\\n${children}` : title;\n}\n\n// No native Markdown disclosure widget — degrades to a plain heading\n// followed by its children, same \"no exact equivalent, fall back to\n// something readable\" choice listItem's own toMarkdown makes for a\n// collapsed toggle list item.\nfunction toMarkdown(block, ctx) {\n const { titleRunIds = [], level = 2 } = block.props;\n const title = runsToMarkdown(\n titleRunIds.map((runId) => ctx.store.getRun(runId)),\n ctx,\n );\n const heading = `${'#'.repeat(Math.min(6, level))} ${title}`;\n const children = block.contentIds\n .map((childId) => {\n const child = ctx.store.getBlock(childId);\n const entry = ctx.registry.get(child.type);\n return (entry.toMarkdown ?? entry.toPlainText)(child, ctx);\n })\n .join('\\n\\n');\n return children ? `${heading}\\n\\n${children}` : heading;\n}\n\n/** Only reconstructs top-level <p> children on paste (matches blockquote's fromHTML scope) — deeper nested block types fall back to a single blank paragraph. */\nfunction fromHTML(node, ctx) {\n if (node.tagName !== 'DETAILS') return null;\n const summary = [...node.children].find((c) => c.tagName === 'SUMMARY');\n const headingEl = summary?.querySelector('h1,h2,h3,h4,h5,h6');\n const level = headingEl ? Math.min(6, Math.max(1, Number(headingEl.tagName[1]))) : 2;\n const titleRuns = headingEl\n ? domInlineToRuns(headingEl, ctx)\n : [{ id: genId(), type: 'text', value: '', marks: {} }];\n\n const blockId = genId();\n const childBlocks = [];\n const childRuns = [];\n const contentIds = [];\n for (const child of node.children) {\n if (child === summary || child.tagName !== 'P') continue;\n const runs = domInlineToRuns(child, ctx);\n const pBlock = {\n id: genId(),\n type: 'paragraph',\n parentId: blockId,\n contentIds: runs.map((r) => r.id),\n props: {},\n };\n childBlocks.push(pBlock);\n childRuns.push(...runs);\n contentIds.push(pBlock.id);\n }\n if (contentIds.length === 0) {\n const { block: fallback, runs } = createTextLeafBlock('paragraph')(blockId);\n childBlocks.push(fallback);\n childRuns.push(...runs);\n contentIds.push(fallback.id);\n }\n\n const block = {\n id: blockId,\n type: 'toggleHeading',\n parentId: null,\n contentIds,\n props: {\n level,\n collapsed: !node.hasAttribute('open'),\n titleRunIds: titleRuns.map((r) => r.id),\n },\n };\n return { block, runs: [...titleRuns, ...childRuns], subtreeBlocks: childBlocks };\n}\n\nexport const toggleHeadingBlockType = defineBlock({\n name: 'toggleHeading',\n contentModel: 'blocks',\n component: ToggleHeadingBlock,\n defaultProps: { level: 2, collapsed: false, titleRunIds: [] },\n toHTML,\n toPlainText,\n toMarkdown,\n fromHTML,\n slashCommands: [1, 2, 3].map((level) => ({\n label: `Toggle heading ${level}`,\n icon: ChevronRightIcon,\n // Deliberately does NOT include \"h1\"/\"h2\"/\"h3\" — those short forms\n // already belong exclusively to the plain heading commands (see\n // heading/index.js); duplicating them here would make \"/h3\" ambiguous\n // between \"Heading 3\" and \"Toggle heading 3\".\n keywords: ['toggle', 'heading', 'collapse', 'section'],\n run: (store, ctx) =>\n trimSlashQueryAndInsertAfter(store, ctx, createToggleHeadingBlock({ level })),\n })),\n});\n","import { useCallback, useEffect, useState } from 'react';\nimport { Modal } from '../../react/Modal.jsx';\nimport { updateBlockProps, setBlockRuns } from '../../store/operations.js';\nimport { genId } from '../../utils/idGen.js';\nimport { XIcon } from '../../react/icons.jsx';\n\nconst COLORS = [\n { label: 'Blue', value: '#2b6fd6' },\n { label: 'Green', value: '#2f9e44' },\n { label: 'Red', value: '#e03131' },\n { label: 'Purple', value: '#9c36b5' },\n { label: 'Gray', value: '#495057' },\n { label: 'Black', value: '#1a1a1a' },\n];\n\nfunction applyOps(store, ops) {\n if (typeof store.performBatch === 'function') store.performBatch(ops);\n else for (const op of ops) store.applyOperation(op);\n}\n\n/**\n * One-stop editor for a button block: label text, link URL, pill color,\n * and an open-ended list of custom key/value attributes (rendered as\n * data-* attributes on the button's own DOM node — see ButtonBlock — so a\n * host app can hook its own CSS/JS onto a button by whatever attribute\n * name it likes, without this package needing to know what for).\n *\n * Renaming the label here replaces the block's runs with a single plain\n * text run (see the save handler) — the inline contentEditable label\n * (click directly into the button's text) is still there and still keeps\n * full rich-text/marks support; this is just a faster, consolidated way to\n * set everything about the button in one place, matching how every other\n * \"edit this block's settings\" affordance in this package works.\n */\nexport function ButtonEditModal({ isOpen, onClose, store, blockId }) {\n const [label, setLabel] = useState('');\n const [href, setHref] = useState('');\n const [color, setColor] = useState(COLORS[0].value);\n const [attrs, setAttrs] = useState([{ key: '', value: '' }]);\n\n useEffect(() => {\n if (!isOpen) return;\n const block = store.getBlock(blockId);\n if (!block) return;\n const text = block.contentIds.map((runId) => store.getRun(runId)?.value ?? '').join('');\n const existingAttrs = block.props?.customAttrs ?? [];\n setLabel(text);\n setHref(block.props?.href ?? '');\n setColor(block.props?.color ?? COLORS[0].value);\n setAttrs([...existingAttrs, { key: '', value: '' }]);\n }, [isOpen, blockId, store]);\n\n const updateAttrRow = useCallback((index, patch) => {\n setAttrs((rows) => {\n const next = rows.map((row, i) => (i === index ? { ...row, ...patch } : row));\n const last = next[next.length - 1];\n if (last.key.trim() || last.value.trim()) next.push({ key: '', value: '' }); // always keep one trailing blank row to add more\n return next;\n });\n }, []);\n\n const removeAttrRow = useCallback((index) => {\n setAttrs((rows) => rows.filter((_, i) => i !== index));\n }, []);\n\n const handleSave = useCallback(() => {\n const newRun = { id: genId(), type: 'text', value: label, marks: {} };\n const customAttrs = attrs.filter((row) => row.key.trim());\n\n applyOps(store, [\n setBlockRuns(blockId, [newRun]),\n updateBlockProps(blockId, { href: href.trim(), color, customAttrs }),\n ]);\n onClose();\n }, [store, blockId, label, href, color, attrs, onClose]);\n\n return (\n <Modal isOpen={isOpen} onClose={onClose} title=\"Edit button\">\n <label className=\"be-modal-field\">\n <span>Label</span>\n <input\n type=\"text\"\n value={label}\n onChange={(event) => setLabel(event.target.value)}\n placeholder=\"Button\"\n />\n </label>\n\n <label className=\"be-modal-field\">\n <span>Link URL</span>\n <input\n type=\"url\"\n value={href}\n onChange={(event) => setHref(event.target.value)}\n placeholder=\"https://example.com\"\n />\n </label>\n\n <div className=\"be-modal-field\">\n <span>Color</span>\n <div className=\"be-modal-color-row\">\n {COLORS.map((c) => (\n <button\n key={c.value}\n type=\"button\"\n className={`be-modal-color-swatch${color === c.value ? ' be-modal-color-swatch-active' : ''}`}\n style={{ backgroundColor: c.value }}\n title={c.label}\n aria-label={c.label}\n onClick={() => setColor(c.value)}\n />\n ))}\n </div>\n </div>\n\n <div className=\"be-modal-field\">\n <span>Custom attributes</span>\n {attrs.map((row, index) => (\n <div className=\"be-modal-attr-row\" key={index}>\n <input\n type=\"text\"\n placeholder=\"name\"\n value={row.key}\n onChange={(event) => updateAttrRow(index, { key: event.target.value })}\n />\n <input\n type=\"text\"\n placeholder=\"value\"\n value={row.value}\n onChange={(event) => updateAttrRow(index, { value: event.target.value })}\n />\n {(row.key || row.value) && (\n <button\n type=\"button\"\n className=\"be-modal-attr-remove\"\n onClick={() => removeAttrRow(index)}\n aria-label=\"Remove attribute\"\n >\n <XIcon size={14} />\n </button>\n )}\n </div>\n ))}\n </div>\n\n <div className=\"be-modal-actions\">\n <button type=\"button\" className=\"be-modal-cancel\" onClick={onClose}>\n Cancel\n </button>\n <button type=\"button\" className=\"be-modal-save\" onClick={handleSave}>\n Save\n </button>\n </div>\n </Modal>\n );\n}\n","import { useCallback, useState } from 'react';\nimport { EditableBlockContent } from '../../react/EditableBlockContent.jsx';\nimport { useBlock } from '../../react/useBlock.js';\nimport {\n useEditorStore,\n useSelectedBlock,\n useBlockClassName,\n} from '../../react/EditorProvider.jsx';\nimport { insertSiblingSplitAtCaretAndFocus } from '../shared/blockCommands.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\nimport { mergeWithPreviousOrDelete } from '../shared/mergeCommands.js';\nimport { isRunsEmpty } from '../shared/blockEmpty.js';\nimport { focusAfterMerge } from '../shared/focusAfterMerge.js';\nimport { focusAdjacentBlock } from '../shared/navigationCommands.js';\nimport { resolveBlockDir } from '../shared/resolveBlockDir.js';\nimport { ButtonEditModal } from './ButtonEditModal.jsx';\n\nconst DEFAULT_COLOR = '#2b6fd6';\n\n/**\n * A leaf block (own runs, same mechanism as paragraph/heading) styled as a\n * clickable button, with `href`/`color`/`customAttrs` props. Editing the\n * label inline (click into the text, type, format, etc.) and *activating*\n * the button (following its link) are kept as two entirely separate\n * controls — a plain click inside the label only ever places the caret,\n * the same as any other block's text, and never navigates; the small\n * \"open ↗\" button is the only thing that does. The \"⚙\" button opens a\n * one-stop modal for label/link/color/custom-attributes (see\n * ButtonEditModal) as a faster consolidated alternative to editing the\n * label inline and there being nowhere else to set the rest.\n *\n * `customAttrs` (arbitrary name/value pairs from the modal) render as\n * data-* attributes directly on the pill element, not as raw injected\n * HTML/JS — a host app can hook its own CSS or event delegation onto\n * whatever attribute name it likes without this package needing to know\n * what for, without any injection risk.\n *\n * Enter creates a plain paragraph sibling (not another button), matching\n * heading's own convention — a run of several consecutive buttons from\n * repeated Enter isn't a sensible default.\n */\nexport function ButtonBlock({ id }) {\n const store = useEditorStore();\n const block = useBlock(id);\n const { setSelectedBlockId } = useSelectedBlock();\n const [isEditModalOpen, setIsEditModalOpen] = useState(false);\n\n const handleEnter = useCallback(() => {\n insertSiblingSplitAtCaretAndFocus(\n store,\n id,\n block?.contentIds ?? [],\n createTextLeafBlock('paragraph'),\n );\n }, [store, id, block]);\n\n const handleBackspaceAtStart = useCallback(() => {\n const focusBlockId = mergeWithPreviousOrDelete(store, id);\n focusAfterMerge(store, focusBlockId, id, setSelectedBlockId);\n }, [store, id, setSelectedBlockId]);\n\n const handleArrowUp = useCallback(() => focusAdjacentBlock(store, id, 'up'), [store, id]);\n const handleArrowDown = useCallback(() => focusAdjacentBlock(store, id, 'down'), [store, id]);\n\n const openLink = useCallback(() => {\n const href = block?.props?.href;\n if (href) window.open(href, '_blank', 'noopener,noreferrer');\n }, [block?.props?.href]);\n\n const className = useBlockClassName('be-button-block', block);\n\n if (!block) return null;\n const href = block.props?.href ?? '';\n const color = block.props?.color ?? DEFAULT_COLOR;\n const customAttrs = block.props?.customAttrs ?? [];\n const isEmpty = isRunsEmpty(store, block.contentIds);\n\n const dataAttrs = {};\n for (const { key, value } of customAttrs) {\n if (key.trim()) dataAttrs[`data-${key.trim()}`] = value;\n }\n const dir = resolveBlockDir(store, block);\n\n return (\n <div className={className} data-block-id={id} dir={dir}>\n <div className=\"be-button-block-pill\" style={{ backgroundColor: color }} {...dataAttrs}>\n <span\n className=\"be-button-block-label\"\n data-empty={isEmpty ? '' : undefined}\n data-placeholder=\"Button\"\n >\n <EditableBlockContent\n blockId={id}\n runIds={block.contentIds}\n dir={dir}\n onEnter={handleEnter}\n onBackspaceAtStart={handleBackspaceAtStart}\n onArrowUp={handleArrowUp}\n onArrowDown={handleArrowDown}\n />\n </span>\n <button\n type=\"button\"\n className=\"be-button-block-open\"\n onClick={openLink}\n disabled={!href}\n title={href || 'No link set'}\n aria-label=\"Open link\"\n >\n ↗\n </button>\n <button\n type=\"button\"\n className=\"be-button-block-settings\"\n onClick={() => setIsEditModalOpen(true)}\n aria-label=\"Edit button\"\n title=\"Edit label, link, color…\"\n >\n ⚙\n </button>\n </div>\n <ButtonEditModal\n isOpen={isEditModalOpen}\n onClose={() => setIsEditModalOpen(false)}\n store={store}\n blockId={id}\n />\n </div>\n );\n}\n","import { genId } from '../../utils/idGen.js';\n\n/**\n * factory(parentId, initialRuns?) -> {block, runs} for a button — a plain\n * leaf (contentIds are its own run ids, exactly like paragraph/heading),\n * plus a `href` prop. Not in MERGEABLE_TEXT_TYPES (see mergeCommands.js):\n * concatenating a button's label into a preceding paragraph would silently\n * drop its href, so it's excluded the same way table/listItem/callout are.\n */\nexport function createButtonBlock({\n href = '',\n label = 'Button',\n color = '',\n customAttrs = [],\n} = {}) {\n return function factory(parentId, initialRuns) {\n const blockId = genId();\n const runs = initialRuns?.length\n ? initialRuns\n : [{ id: genId(), type: 'text', value: label, marks: {} }];\n return {\n block: {\n id: blockId,\n type: 'button',\n parentId,\n contentIds: runs.map((r) => r.id),\n props: { href, color, customAttrs },\n },\n runs,\n };\n };\n}\n","import { ButtonBlock } from './ButtonBlock.jsx';\nimport { defineBlock } from '../../registry/define.js';\nimport { runToHTML, runToPlainText, runsToMarkdown, escapeAttr } from '../../inline/marks.js';\nimport { domInlineToRuns } from '../../inline/runOps.js';\nimport { genId } from '../../utils/idGen.js';\nimport { trimSlashQueryAndInsertAfter } from '../shared/blockCommands.js';\nimport { createButtonBlock } from './createButtonBlock.js';\nimport { ButtonIcon } from '../../react/icons.jsx';\n\n// Distinctive class (not just a bare <a>) so this never collides with an\n// ordinary link pasted from elsewhere — walkDomToBlocks's generic matcher\n// loop only claims an anchor as a button when this exact marker is present;\n// any other <a> falls through to the normal inline-link-within-a-paragraph\n// handling, which is what plain link pasting should do.\nconst MARKER_CLASS = 'be-button-block-link';\n\nfunction toHTML(block, ctx) {\n const runs = block.contentIds.map((runId) => ctx.store.getRun(runId));\n const href = block.props?.href ?? '';\n const color = block.props?.color;\n const style = color ? ` style=\"background-color:${escapeAttr(color)}\"` : '';\n const customAttrs = block.props?.customAttrs ?? [];\n const attrHTML = customAttrs\n .filter((a) => a.key?.trim())\n .map((a) => ` data-${escapeAttr(a.key.trim())}=\"${escapeAttr(a.value ?? '')}\"`)\n .join('');\n return `<a class=\"${MARKER_CLASS}\" href=\"${escapeAttr(href)}\"${style}${attrHTML}>${runs.map((r) => runToHTML(r, ctx)).join('')}</a>`;\n}\n\nfunction toPlainText(block, ctx) {\n return block.contentIds.map((runId) => runToPlainText(ctx.store.getRun(runId), ctx)).join('');\n}\n\nfunction toMarkdown(block, ctx) {\n const href = block.props?.href ?? '';\n const text = runsToMarkdown(\n block.contentIds.map((runId) => ctx.store.getRun(runId)),\n ctx,\n );\n return `[${text || href}](${href})`;\n}\n\nfunction fromHTML(node, ctx) {\n if (node.tagName !== 'A' || !node.classList.contains(MARKER_CLASS)) return null;\n const runs = domInlineToRuns(node, ctx);\n const customAttrs = [];\n for (const attr of node.attributes) {\n if (attr.name.startsWith('data-'))\n customAttrs.push({ key: attr.name.slice(5), value: attr.value });\n }\n const block = {\n id: genId(),\n type: 'button',\n parentId: null,\n contentIds: runs.map((r) => r.id),\n props: {\n href: node.getAttribute('href') ?? '',\n color: node.style?.backgroundColor || undefined,\n customAttrs,\n },\n };\n return { block, runs };\n}\n\nexport const buttonBlockType = defineBlock({\n name: 'button',\n contentModel: 'runs',\n component: ButtonBlock,\n defaultProps: { href: '', color: '', customAttrs: [] },\n toHTML,\n toPlainText,\n toMarkdown,\n fromHTML,\n slashCommand: {\n label: 'Button',\n icon: ButtonIcon,\n keywords: ['button', 'link', 'cta', 'action'],\n run: (store, ctx) => trimSlashQueryAndInsertAfter(store, ctx, createButtonBlock()),\n },\n});\n","import { genId } from '../../utils/idGen.js';\n\nfunction readFileAsDataURL(file) {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result);\n reader.onerror = () => reject(reader.error);\n reader.readAsDataURL(file);\n });\n}\n\nexport function formatBytes(bytes) {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nexport function kindForMimeType(mimeType) {\n if (mimeType?.startsWith('image/')) return 'image';\n if (mimeType?.startsWith('video/')) return 'video';\n if (mimeType?.startsWith('audio/')) return 'audio';\n return 'file';\n}\n\n/**\n * Resolves a raw `File` to `{ src, name, mimeType }` — a `data:` URL (or\n * wherever `uploadFile` sends it) — same `uploadFile`/`maxFileSize`\n * contract as `useFileUpload`'s own doc comment. This is the ONE place\n * that actually does that resolution; both `EmbedBlock`'s own upload\n * dropzone/file-input/drag-drop AND `useClipboardHandlers`' \"paste an\n * image straight from the clipboard\" path call through here, so a host's\n * configured `uploadFile`/`maxFileSize` behaves identically no matter\n * which of those triggered it.\n *\n * `kind` is passed in rather than derived from `file.type` here — an\n * existing `EmbedBlock` instance already has its own fixed kind (e.g. an\n * \"image\" block stays \"image\" for its whole lifetime, even if someone\n * drops a mismatched file type into it — HTML5 drag/drop doesn't enforce\n * an `accept` filter), so callers with an existing block pass that block's\n * own kind through unchanged. `resolveFileToEmbedInsert` (below), which\n * has no pre-existing block to take a kind from, derives it from the\n * file's own `type` instead via `kindForMimeType`.\n *\n * Throws (with a human-readable `.message`) on an oversized file (no\n * `uploadFile` configured) or a rejected `uploadFile` call — callers\n * decide how to surface that (EmbedBlock shows it inline; a multi-file\n * paste skips just the failed one and keeps the rest, see\n * useClipboardHandlers).\n */\nexport async function resolveFileToSrc(file, { uploadFile, maxFileSize, kind }) {\n if (uploadFile) {\n const result = await uploadFile(file, { kind });\n return {\n src: result.src,\n name: result.name ?? file.name,\n mimeType: result.mimeType ?? file.type,\n };\n }\n if (maxFileSize && file.size > maxFileSize) {\n throw new Error(\n `This file is ${formatBytes(file.size)} — larger than the ${formatBytes(maxFileSize)} limit.`,\n );\n }\n const src = await readFileAsDataURL(file);\n return { src, name: file.name, mimeType: file.type };\n}\n\n/**\n * Same resolution as `resolveFileToSrc`, packaged as a ready-to-insert\n * `{ block, runs, subtreeBlocks }` — the shape every clipboard/paste\n * insertion path already expects (see `insertBlock`/`deserializeClipboard`\n * call sites). `kind` is derived from the file's own `type` (see its own\n * doc comment on `resolveFileToSrc` for why that differs from EmbedBlock's\n * own call site) — used by `useClipboardHandlers`' file-paste path, which\n * has no pre-existing embed block to inherit a kind from.\n */\nexport async function resolveFileToEmbedInsert(file, uploadConfig) {\n const kind = kindForMimeType(file.type);\n const { src, name, mimeType } = await resolveFileToSrc(file, { ...uploadConfig, kind });\n return {\n block: {\n id: genId(),\n type: 'embed',\n parentId: null,\n contentIds: [],\n props: { kind, src, name, mimeType, align: 'left', width: 100 },\n },\n runs: [],\n subtreeBlocks: [],\n };\n}\n","/**\n * Pattern-based URL → iframe-embed-URL resolution for a handful of common\n * providers — deliberately NOT a real oEmbed client (no network fetch, no\n * discovery/autodiscovery, no provider metadata like title/thumbnail).\n * Every provider here has a stable, documented iframe embed URL shape that\n * can be derived from the original URL alone, so this stays true to the\n * package's zero-runtime-dependency, no-backend design — same reasoning as\n * `uploadFile` being optional rather than baking in a fetch call.\n *\n * Returns `{ provider, embedUrl }` on a match, `null` otherwise. Order\n * matters only in that more specific patterns should precede more general\n * ones; today's list has no such overlap.\n */\nconst PROVIDERS = [\n {\n name: 'youtube',\n test: /(?:youtube\\.com\\/watch\\?(?:.*&)?v=|youtu\\.be\\/|youtube\\.com\\/shorts\\/|youtube\\.com\\/embed\\/)([\\w-]{6,})/,\n embed: (m) => `https://www.youtube.com/embed/${m[1]}`,\n },\n {\n name: 'vimeo',\n test: /vimeo\\.com\\/(?:video\\/)?(\\d+)/,\n embed: (m) => `https://player.vimeo.com/video/${m[1]}`,\n },\n {\n name: 'loom',\n test: /loom\\.com\\/share\\/([\\w-]+)/,\n embed: (m) => `https://www.loom.com/embed/${m[1]}`,\n },\n {\n name: 'figma',\n test: /figma\\.com\\/(?:file|design|proto)\\/[\\w-]+/,\n embed: (_m, url) =>\n `https://www.figma.com/embed?embed_host=noteloom&url=${encodeURIComponent(url)}`,\n },\n {\n name: 'codepen',\n test: /codepen\\.io\\/([\\w-]+)\\/pen\\/([\\w-]+)/,\n embed: (m) => `https://codepen.io/${m[1]}/embed/${m[2]}?default-tab=result`,\n },\n {\n name: 'spotify',\n test: /open\\.spotify\\.com\\/(track|album|playlist|episode|show)\\/([\\w]+)/,\n embed: (m) => `https://open.spotify.com/embed/${m[1]}/${m[2]}`,\n },\n];\n\nexport function resolveOEmbedUrl(rawUrl) {\n if (!rawUrl) return null;\n for (const provider of PROVIDERS) {\n const match = rawUrl.match(provider.test);\n if (match) return { provider: provider.name, embedUrl: provider.embed(match, rawUrl) };\n }\n return null;\n}\n","import { useCallback, useRef, useState } from 'react';\nimport { useBlock } from '../../react/useBlock.js';\nimport { useEditorStore, useBlockClassName, useFileUpload } from '../../react/EditorProvider.jsx';\nimport { updateBlockProps } from '../../store/operations.js';\nimport { Modal } from '../../react/Modal.jsx';\nimport {\n PaperclipIcon,\n AlignLeftIcon,\n AlignCenterIcon,\n AlignRightIcon,\n LinkIcon,\n} from '../../react/icons.jsx';\nimport { resolveFileToSrc } from './resolveFileEmbed.js';\nimport { resolveOEmbedUrl } from './oembedProviders.js';\n\nconst KIND_LABEL = {\n image: 'image',\n video: 'video',\n audio: 'audio',\n file: 'file',\n oembed: 'embed',\n};\nconst KIND_ACCEPT = { image: 'image/*', video: 'video/*', audio: 'audio/*', file: '*/*' };\nconst MIN_WIDTH = 20;\nconst MAX_WIDTH = 100;\nconst ALIGN_OPTIONS = [\n { value: 'left', Icon: AlignLeftIcon, label: 'Align left' },\n { value: 'center', Icon: AlignCenterIcon, label: 'Align center' },\n { value: 'right', Icon: AlignRightIcon, label: 'Align right' },\n];\n\nfunction clampWidth(pct) {\n return Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, Math.round(pct)));\n}\n\nfunction EmbedPreview({ kind, src, name, alt, provider }) {\n // Deliberately never falls back to `name` (the uploaded file's raw\n // filename, e.g. \"IMG_2481.HEIC\", or a pasted URL string) — neither is\n // meaningful alt text, and silently presenting one as if it were a real\n // description is worse than an empty (but at least honest) alt.\n if (kind === 'image') return <img className=\"be-embed-image\" src={src} alt={alt || ''} />;\n if (kind === 'video') return <video className=\"be-embed-video\" src={src} controls />;\n if (kind === 'audio') return <audio className=\"be-embed-audio\" src={src} controls />;\n if (kind === 'oembed') {\n return (\n <iframe\n className=\"be-embed-oembed\"\n src={src}\n title={provider ? `${provider} embed` : 'embed'}\n // A fixed provider allowlist (see oembedProviders.js), never an\n // arbitrary user-supplied origin, is what makes allow-scripts safe\n // here — every embed URL is derived from a known provider's own\n // documented iframe shape, same trust boundary as loading their\n // official embed.js would be.\n sandbox=\"allow-scripts allow-same-origin allow-presentation allow-popups\"\n allow=\"autoplay; encrypted-media; picture-in-picture; fullscreen\"\n allowFullScreen\n loading=\"lazy\"\n />\n );\n }\n return (\n <a\n className=\"be-embed-file-link\"\n href={src}\n download={name || undefined}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <PaperclipIcon size={14} /> {name || src}\n </a>\n );\n}\n\n/**\n * A pure \"widget\" block — no runs/text at all (contentIds always []), same\n * shape as DividerBlock — so it participates in cross-block select/copy/\n * cut/delete for free via the exact same generic mechanisms already\n * exercised by divider: it's \"contentless\" the same way, so backspacing\n * into it from a following block clears it as the nearest obstacle,\n * matching every other contentless block (see mergeWithPreviousOrDelete).\n *\n * This package ships no backend of its own, so a picked/dropped file's\n * destination is entirely up to the host: `EditorProvider`'s `uploadFile`\n * option (see `useFileUpload`'s own doc comment for the full contract —\n * local disk, S3, any other cloud storage) is called with the raw `File`\n * when configured. Without it, a file is read via `FileReader` straight\n * into a `data:` URL and stored directly in `props.src` — keeps the\n * document fully self-contained (works offline, round-trips through copy/\n * paste and undo/redo like any other prop) at the cost of bloating the\n * document for large media, which is also why THAT path (and only that\n * path) respects `maxFileSize`, rejecting anything over it with a clear\n * error instead of silently ballooning the document.\n *\n * `isUploading`/`uploadError` are local, ephemeral UI state (not stored on\n * the block) — a real network upload can take a while and can fail, so the\n * dropzone shows a \"Uploading…\" state meanwhile and a dismissible error\n * message on failure, instead of leaving a click that just silently does\n * nothing until it eventually resolves.\n *\n * `align` positions the whole widget within the line (a flex row on\n * `.be-embed-preview`, a common media alignment pattern). `width` is a\n * percentage, dragged via `.be-embed-resize-handle` — only image/video\n * kinds get the handle (an audio player or a file-download pill don't have\n * a meaningful \"shrink the visual\" concept the same way). The drag itself\n * only updates local state (`dragWidth`) for a live preview; the store is\n * only written once, on mouseup, so dragging doesn't spam undo history\n * with one step per pixel of mouse movement.\n */\nexport function EmbedBlock({ id }) {\n const store = useEditorStore();\n const block = useBlock(id);\n const { uploadFile, maxFileSize } = useFileUpload();\n const [urlInput, setUrlInput] = useState('');\n const [isDragOver, setIsDragOver] = useState(false);\n const [dragWidth, setDragWidth] = useState(null);\n const [isAltTextOpen, setIsAltTextOpen] = useState(false);\n const [altDraft, setAltDraft] = useState('');\n const [isUploading, setIsUploading] = useState(false);\n const [uploadError, setUploadError] = useState(null);\n const previewRef = useRef(null);\n const frameRef = useRef(null);\n\n const setMedia = useCallback(\n (patch) => store.applyOperation(updateBlockProps(id, patch)),\n [store, id],\n );\n\n const openAltText = useCallback(() => {\n setAltDraft(block?.props?.alt ?? '');\n setIsAltTextOpen(true);\n }, [block?.props?.alt]);\n const closeAltText = useCallback(() => setIsAltTextOpen(false), []);\n const saveAltText = useCallback(\n (event) => {\n event.preventDefault();\n setMedia({ alt: altDraft.trim() });\n setIsAltTextOpen(false);\n },\n [altDraft, setMedia],\n );\n\n // The one path every file (picked or dropped) goes through — see\n // useFileUpload's own doc comment for uploadFile's contract and\n // maxFileSize's scope (the in-document data: URL fallback only).\n const acceptFile = useCallback(\n async (file, kind) => {\n setUploadError(null);\n setIsUploading(true);\n try {\n const { src, name, mimeType } = await resolveFileToSrc(file, {\n uploadFile,\n maxFileSize,\n kind,\n });\n setMedia({ src, name, mimeType });\n } catch (err) {\n setUploadError(err?.message || 'Upload failed. Please try again.');\n } finally {\n setIsUploading(false);\n }\n },\n [uploadFile, maxFileSize, setMedia],\n );\n\n const handleFileChange = useCallback(\n (event) => {\n const file = event.target.files?.[0];\n event.target.value = ''; // lets picking the exact same file again re-fire onChange\n if (file) acceptFile(file, block?.props?.kind ?? 'file');\n },\n [acceptFile, block?.props?.kind],\n );\n\n const handleDrop = useCallback(\n (event) => {\n event.preventDefault();\n setIsDragOver(false);\n const file = event.dataTransfer.files?.[0];\n if (file) acceptFile(file, block?.props?.kind ?? 'file');\n },\n [acceptFile, block?.props?.kind],\n );\n\n const handleDragOver = useCallback((event) => {\n event.preventDefault();\n setIsDragOver(true);\n }, []);\n\n const handleDragLeave = useCallback(() => setIsDragOver(false), []);\n\n // A pasted URL matching a known provider (see oembedProviders.js) always\n // wins, regardless of which slash command created this block — pasting a\n // YouTube link into an \"/image\" block's dropzone should still produce a\n // real player, not a broken <img src=\"https://youtube.com/watch?...\">.\n const commitUrl = useCallback(() => {\n const trimmed = urlInput.trim();\n if (!trimmed) return;\n const oembed = resolveOEmbedUrl(trimmed);\n if (oembed) {\n setMedia({\n kind: 'oembed',\n src: oembed.embedUrl,\n name: trimmed,\n mimeType: '',\n provider: oembed.provider,\n originalUrl: trimmed,\n });\n } else {\n setMedia({ src: trimmed, name: trimmed });\n }\n setUrlInput('');\n }, [urlInput, setMedia]);\n\n const clearMedia = useCallback(\n () => setMedia({ src: '', name: '', mimeType: '', provider: '', originalUrl: '' }),\n [setMedia],\n );\n\n const handleResizeStart = useCallback(\n (event) => {\n event.preventDefault();\n const containerEl = previewRef.current;\n const frameEl = frameRef.current;\n if (!containerEl || !frameEl) return;\n const containerWidth = containerEl.getBoundingClientRect().width;\n const startWidth = frameEl.getBoundingClientRect().width;\n const startX = event.clientX;\n\n const computePct = (moveEvent) =>\n clampWidth(((startWidth + (moveEvent.clientX - startX)) / containerWidth) * 100);\n\n const handleMouseMove = (moveEvent) => setDragWidth(computePct(moveEvent));\n const handleMouseUp = (upEvent) => {\n document.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('mouseup', handleMouseUp);\n setMedia({ width: computePct(upEvent) });\n setDragWidth(null);\n };\n document.addEventListener('mousemove', handleMouseMove);\n document.addEventListener('mouseup', handleMouseUp);\n },\n [setMedia],\n );\n\n // The handle's `role=\"slider\"` was previously mouse-only — announced as\n // an operable slider to assistive tech, but Tab never reached it and\n // arrow keys did nothing, an actively misleading gap for a keyboard-only\n // user. Left/Right (Shift for a finer 1% step) and Home/End now actually\n // work, matching what the ARIA role already promised.\n const handleResizeKeyDown = useCallback(\n (event) => {\n const current = block?.props?.width ?? 100;\n const step = event.shiftKey ? 1 : 5;\n let next;\n if (event.key === 'ArrowLeft' || event.key === 'ArrowDown') next = clampWidth(current - step);\n else if (event.key === 'ArrowRight' || event.key === 'ArrowUp')\n next = clampWidth(current + step);\n else if (event.key === 'Home') next = MIN_WIDTH;\n else if (event.key === 'End') next = MAX_WIDTH;\n else return;\n event.preventDefault();\n setMedia({ width: next });\n },\n [block?.props?.width, setMedia],\n );\n\n const className = useBlockClassName('be-embed', block);\n\n if (!block) return null;\n const {\n kind = 'file',\n src,\n name,\n alt = '',\n align = 'left',\n width = 100,\n provider = '',\n originalUrl = '',\n } = block.props;\n const canResize = kind === 'image' || kind === 'video' || kind === 'oembed';\n const effectiveWidth = dragWidth ?? width;\n const isOEmbed = kind === 'oembed';\n\n return (\n // tabIndex={-1}: focusable via .focus() (see setSelectedBlockId in\n // EditorProvider.jsx) without joining the normal Tab order — keeps the\n // surface's keydown listener capturing subsequent Backspace/Delete\n // presses once this block becomes selected, even when whatever\n // previously had focus was just removed from the DOM entirely.\n <div\n className={className}\n data-block-id={id}\n data-kind={kind}\n contentEditable={false}\n tabIndex={-1}\n >\n {src ? (\n <div ref={previewRef} className={`be-embed-preview be-embed-align-${align}`}>\n <div\n ref={frameRef}\n className=\"be-embed-frame\"\n style={canResize ? { width: `${effectiveWidth}%` } : undefined}\n >\n <div className=\"be-embed-toolbar\" contentEditable={false}>\n {ALIGN_OPTIONS.map(({ value, Icon, label }) => (\n <button\n key={value}\n type=\"button\"\n className={`be-embed-toolbar-btn${align === value ? ' be-embed-toolbar-btn-active' : ''}`}\n title={label}\n aria-label={label}\n aria-pressed={align === value}\n onClick={() => setMedia({ align: value })}\n >\n <Icon size={14} />\n </button>\n ))}\n {kind === 'image' && (\n <button\n type=\"button\"\n className=\"be-embed-toolbar-btn be-embed-alt-text-btn\"\n onClick={openAltText}\n >\n Alt text\n </button>\n )}\n {isOEmbed && originalUrl && (\n <a\n className=\"be-embed-toolbar-btn be-embed-open-original\"\n href={originalUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n title=\"Open original link\"\n aria-label=\"Open original link\"\n >\n <LinkIcon size={14} />\n </a>\n )}\n <button\n type=\"button\"\n className=\"be-embed-remove\"\n onClick={clearMedia}\n aria-label={`Remove ${KIND_LABEL[kind]}`}\n >\n Remove\n </button>\n </div>\n <EmbedPreview kind={kind} src={src} name={name} alt={alt} provider={provider} />\n {canResize && (\n <div\n className=\"be-embed-resize-handle\"\n onMouseDown={handleResizeStart}\n onKeyDown={handleResizeKeyDown}\n role=\"slider\"\n tabIndex={0}\n aria-label={`Resize ${KIND_LABEL[kind]}`}\n aria-valuemin={MIN_WIDTH}\n aria-valuemax={MAX_WIDTH}\n aria-valuenow={effectiveWidth}\n />\n )}\n </div>\n </div>\n ) : (\n <div\n className={`be-embed-dropzone${isDragOver ? ' be-embed-dropzone-active' : ''}`}\n onDrop={isOEmbed || isUploading ? undefined : handleDrop}\n onDragOver={isOEmbed || isUploading ? undefined : handleDragOver}\n onDragLeave={handleDragLeave}\n >\n {isUploading ? (\n <span className=\"be-embed-uploading\">Uploading…</span>\n ) : (\n <>\n {!isOEmbed && (\n <>\n <label className=\"be-embed-upload-btn\">\n Upload {KIND_LABEL[kind]}\n <input\n type=\"file\"\n accept={KIND_ACCEPT[kind]}\n onChange={handleFileChange}\n hidden\n />\n </label>\n <span className=\"be-embed-dropzone-hint\">\n or drop a file, or paste a URL below\n </span>\n </>\n )}\n <div className=\"be-embed-url-row\">\n <input\n type=\"text\"\n className=\"be-embed-url-input\"\n placeholder={\n isOEmbed\n ? 'Paste a YouTube, Vimeo, Loom, Figma, CodePen, or Spotify link'\n : `https://... ${KIND_LABEL[kind]} URL`\n }\n value={urlInput}\n onChange={(event) => setUrlInput(event.target.value)}\n onKeyDown={(event) => event.key === 'Enter' && commitUrl()}\n />\n <button type=\"button\" className=\"be-embed-url-commit\" onClick={commitUrl}>\n Embed\n </button>\n </div>\n </>\n )}\n {uploadError && (\n <div className=\"be-embed-upload-error\" role=\"alert\">\n {uploadError}\n <button type=\"button\" onClick={() => setUploadError(null)} aria-label=\"Dismiss error\">\n ×\n </button>\n </div>\n )}\n </div>\n )}\n <Modal isOpen={isAltTextOpen} onClose={closeAltText} title=\"Alt text\">\n <form onSubmit={saveAltText}>\n <label className=\"be-modal-field\">\n <span>Describe this image for screen readers</span>\n <input\n type=\"text\"\n value={altDraft}\n onChange={(event) => setAltDraft(event.target.value)}\n placeholder=\"e.g. A hand-drawn diagram of the release process\"\n autoFocus\n />\n </label>\n <div className=\"be-modal-actions\">\n <button type=\"button\" className=\"be-modal-cancel\" onClick={closeAltText}>\n Cancel\n </button>\n <button type=\"submit\" className=\"be-modal-save\">\n Save\n </button>\n </div>\n </form>\n </Modal>\n </div>\n );\n}\n","import { genId } from '../../utils/idGen.js';\n\n/**\n * factory(parentId) -> {block, runs} for a media embed — a pure \"widget\"\n * block with no runs at all (contentIds always []), same shape as divider:\n * `kind` is one of 'image' | 'video' | 'audio' | 'file' | 'oembed'; `src`\n * is either an external URL, a data: URL (for a locally-uploaded file —\n * see EmbedBlock.jsx for why there's no upload-to-a-server path in a\n * zero-runtime-dependency package with no backend), or (for 'oembed') the\n * resolved iframe embed URL from `oembedProviders.js`; `name` is the\n * original filename or the URL itself, used as download name / link text\n * depending on kind — deliberately NOT used as alt text (a raw filename\n * like \"IMG_2481.HEIC\" isn't a meaningful image description). `alt` is\n * the real, separately-authored description (image kind only — see\n * EmbedBlock's \"Alt text\" toolbar button), empty by default. `align`\n * ('left' | 'center' | 'right') positions the whole widget within the\n * line; `width` (a percentage, 20-100) is meaningful for image/video/\n * oembed kinds — see EmbedBlock's resize handle. `provider` and\n * `originalUrl` are 'oembed'-only: which pattern matched (e.g.\n * \"youtube\") and the URL the user actually pasted, kept separately from\n * `src` (the derived iframe URL) for display/copy/export purposes.\n */\nexport function createEmbedBlock({\n kind = 'file',\n src = '',\n name = '',\n alt = '',\n mimeType = '',\n align = 'left',\n width = 100,\n provider = '',\n originalUrl = '',\n} = {}) {\n return function factory(parentId) {\n return {\n block: {\n id: genId(),\n type: 'embed',\n parentId,\n contentIds: [],\n props: { kind, src, name, alt, mimeType, align, width, provider, originalUrl },\n },\n runs: [],\n };\n };\n}\n","import { EmbedBlock } from './EmbedBlock.jsx';\nimport { defineBlock } from '../../registry/define.js';\nimport { genId } from '../../utils/idGen.js';\nimport { escapeAttr, escapeHTML } from '../../inline/marks.js';\nimport { insertSiblingAfter, insertSiblingAfterAndFocus } from '../shared/blockCommands.js';\nimport { createTextLeafBlock } from '../shared/leafBlockFactory.js';\nimport { createEmbedBlock } from './createEmbedBlock.js';\nimport { updateRun } from '../../store/operations.js';\nimport { ImageIcon, VideoIcon, AudioIcon, PaperclipIcon, LinkIcon } from '../../react/icons.jsx';\n\nconst KIND_ICONS = {\n image: ImageIcon,\n video: VideoIcon,\n audio: AudioIcon,\n file: PaperclipIcon,\n oembed: LinkIcon,\n};\n\n// Distinctive marker class for the 'file' kind's <a> — same reasoning as\n// the button block: an ordinary pasted link must never be mistaken for a\n// file embed.\nconst FILE_MARKER_CLASS = 'be-embed-file-link';\n\n// Same idea for 'oembed' (YouTube/Vimeo/Loom/Figma/CodePen/Spotify, see\n// oembedProviders.js) — the exported <a> stands in for the iframe (which\n// doesn't round-trip meaningfully through plain HTML clipboard/export), so\n// it needs its own marker to be recognized coming back in via fromHTML.\nconst OEMBED_MARKER_CLASS = 'be-embed-oembed-link';\n\n// Only image/video kinds ever carry a non-default align/width (see\n// EmbedBlock's resize handle/alignment toolbar) — the inline `style`\n// attribute is only ever emitted for those, and only when it actually\n// differs from the default, so a plain default-aligned embed's HTML output\n// is byte-identical to before this existed.\nfunction alignWidthStyle(kind, align, width) {\n if (kind !== 'image' && kind !== 'video' && kind !== 'oembed') return '';\n const declarations = [];\n if (width !== 100) declarations.push(`width:${width}%`);\n if (align === 'center')\n declarations.push('display:block', 'margin-left:auto', 'margin-right:auto');\n else if (align === 'right') declarations.push('display:block', 'margin-left:auto');\n return declarations.length ? ` style=\"${declarations.join(';')}\"` : '';\n}\n\nfunction parseAlignWidth(node) {\n const styleWidth = node.style?.width;\n const width = styleWidth && styleWidth.endsWith('%') ? parseInt(styleWidth, 10) : 100;\n let align = 'left';\n if (node.style?.marginLeft === 'auto' && node.style?.marginRight === 'auto') align = 'center';\n else if (node.style?.marginLeft === 'auto') align = 'right';\n return { align, width: Number.isFinite(width) ? width : 100 };\n}\n\nfunction toHTML(block) {\n const {\n kind,\n src,\n name,\n alt = '',\n align = 'left',\n width = 100,\n provider = '',\n originalUrl = '',\n } = block.props;\n if (!src) return '<p></p>'; // nothing embedded yet: nothing meaningful to export\n const style = alignWidthStyle(kind, align, width);\n // Deliberately `alt`, never `name` (the uploaded file's raw filename) —\n // same \"don't silently present a filename as if it were real alt text\"\n // rationale as EmbedBlock.jsx's own EmbedPreview.\n if (kind === 'image') return `<img src=\"${escapeAttr(src)}\" alt=\"${escapeAttr(alt)}\"${style}>`;\n if (kind === 'video') return `<video src=\"${escapeAttr(src)}\" controls${style}></video>`;\n if (kind === 'audio') return `<audio src=\"${escapeAttr(src)}\" controls></audio>`;\n if (kind === 'oembed') {\n // An <a>, not the <iframe> itself — a raw iframe doesn't paste\n // meaningfully into most other HTML consumers, and a plain link that\n // still round-trips back into THIS editor (via the marker class,\n // fromHTML below) is more useful than a broken third-party embed. Full\n // in-app copy/paste (APP_MIME) carries the real block/props and never\n // goes through this path at all.\n return `<a class=\"${OEMBED_MARKER_CLASS}\" href=\"${escapeAttr(originalUrl || src)}\" data-embed-url=\"${escapeAttr(src)}\" data-embed-provider=\"${escapeAttr(provider)}\">${escapeHTML(originalUrl || src)}</a>`;\n }\n return `<a class=\"${FILE_MARKER_CLASS}\" href=\"${escapeAttr(src)}\">${escapeHTML(name || src)}</a>`;\n}\n\nfunction toPlainText(block) {\n const { kind, src, name, originalUrl = '' } = block.props;\n if (!src) return '';\n if (kind === 'oembed') return `[embed: ${originalUrl || src}]`;\n return `[${kind}: ${name || src}]`;\n}\n\nfunction toMarkdown(block) {\n const { kind, src, name, alt = '', originalUrl = '' } = block.props;\n if (!src) return '';\n if (kind === 'image') return ``;\n if (kind === 'oembed') return `[${originalUrl || src}](${originalUrl || src})`;\n return `[${name || src}](${src})`; // video/audio/file: Markdown has no native player syntax, a link is the honest fallback\n}\n\nfunction fromHTML(node) {\n if (node.tagName === 'IMG') {\n // A pasted <img>'s own alt attribute is real alt text (however good or\n // bad it is at the source) — carried into props.alt, kept separate\n // from `name` (which has no meaningful value here; there's no \"raw\n // filename\" for an externally pasted image the way there is for a\n // locally uploaded file).\n return blockOf('image', node.getAttribute('src') ?? '', '', {\n ...parseAlignWidth(node),\n alt: node.getAttribute('alt') ?? '',\n });\n }\n if (node.tagName === 'VIDEO') {\n return blockOf('video', node.getAttribute('src') ?? '', '', parseAlignWidth(node));\n }\n if (node.tagName === 'AUDIO') {\n return blockOf('audio', node.getAttribute('src') ?? '', '');\n }\n if (node.tagName === 'A' && node.classList.contains(OEMBED_MARKER_CLASS)) {\n return blockOf('oembed', node.getAttribute('data-embed-url') ?? '', '', {\n ...parseAlignWidth(node),\n provider: node.getAttribute('data-embed-provider') ?? '',\n originalUrl: node.getAttribute('href') ?? '',\n });\n }\n if (node.tagName === 'A' && node.classList.contains(FILE_MARKER_CLASS)) {\n return blockOf('file', node.getAttribute('href') ?? '', node.textContent ?? '');\n }\n return null;\n}\n\nfunction blockOf(\n kind,\n src,\n name,\n { align = 'left', width = 100, alt = '', provider = '', originalUrl = '' } = {},\n) {\n return {\n block: {\n id: genId(),\n type: 'embed',\n parentId: null,\n contentIds: [],\n props: { kind, src, name, alt, align, width, provider, originalUrl },\n },\n runs: [],\n };\n}\n\n/** Same pattern as divider's slash command: an embed has no run of its own to focus into, so seed and focus a following paragraph. */\nfunction insertEmbedCommand(kind) {\n return (store, { blockId, runId, sliceStart, sliceEnd }) => {\n const run = store.getRun(runId);\n const value = run?.value ?? '';\n store.applyOperation(\n updateRun(runId, { value: value.slice(0, sliceStart) + value.slice(sliceEnd) }),\n );\n const embedId = insertSiblingAfter(store, blockId, createEmbedBlock({ kind }));\n insertSiblingAfterAndFocus(store, embedId, createTextLeafBlock('paragraph'));\n return embedId;\n };\n}\n\nexport const embedBlockType = defineBlock({\n name: 'embed',\n contentModel: 'void',\n component: EmbedBlock,\n defaultProps: {\n kind: 'file',\n src: '',\n name: '',\n alt: '',\n mimeType: '',\n align: 'left',\n width: 100,\n provider: '',\n originalUrl: '',\n },\n toHTML,\n toPlainText,\n toMarkdown,\n fromHTML,\n slashCommands: [\n ...['image', 'video', 'audio', 'file'].map((kind) => ({\n label: kind.charAt(0).toUpperCase() + kind.slice(1),\n icon: KIND_ICONS[kind],\n keywords: ['embed', 'upload', 'insert', kind],\n run: insertEmbedCommand(kind),\n })),\n {\n label: 'Embed link',\n icon: KIND_ICONS.oembed,\n // A YouTube/Vimeo/Loom/Figma/CodePen/Spotify link pasted into an\n // image/video/file block's own URL field is also auto-detected (see\n // EmbedBlock.jsx's commitUrl) — this command just gets there in one\n // step instead of via \"/video\" first.\n keywords: ['embed', 'link', 'youtube', 'vimeo', 'loom', 'figma', 'codepen', 'spotify'],\n run: insertEmbedCommand('oembed'),\n },\n ],\n});\n","/**\n * A short-lived signal for \"the inline run with this id was JUST inserted\n * from the slash/@ menu and its own picker should open immediately\" (e.g.\n * a select/custom-select/mention chip opening straight into its search\n * input instead of leaving the caret in the trailing text run past it) —\n * see insertInlineRunAtCursor's `autoOpen` option.\n *\n * Deliberately NOT part of the run's persisted `data` — that would leak an\n * ephemeral UI intent into the document itself, surviving reloads, undo/\n * redo, and collaboration sync, none of which should reopen a picker that\n * already closed once. A run's id is consumed at most once, by whichever\n * component instance mounts first for it (its own initial mount right\n * after insertion) — a later remount of the same run id (undo/redo\n * re-creating it, a collaborating peer receiving it) finds nothing\n * pending and mounts closed, as normal.\n */\nconst pendingRunIds = new Set();\n\nexport function markPendingAutoOpen(runId) {\n pendingRunIds.add(runId);\n}\n\nexport function consumePendingAutoOpen(runId) {\n if (!pendingRunIds.has(runId)) return false;\n pendingRunIds.delete(runId);\n return true;\n}\n","import { insertSiblingAfterAndFocus } from '../../blocks/shared/blockCommands.js';\nimport { createTextLeafBlock } from '../../blocks/shared/leafBlockFactory.js';\nimport { focusRunEnd } from '../../react/focusRun.js';\n\n/**\n * Used after picking a value on a freshly-inserted select/custom-select\n * chip (see SelectInlineNode/CustomSelectInlineNode's own handleChange) —\n * completes the postponed \"land the caret right after the chip\" step that\n * a normal (non-auto-opening) insertion already does immediately via\n * `insertInlineRunAtCursor`'s own `focusRunEnd(afterRun.id)`. An\n * auto-opening insertion deliberately skips that at insertion time (see\n * insertInlineRunAtCursor's `autoOpen` option) so the picker can take\n * focus instead — this is that same trailing-run focus, just deferred\n * until the picker interaction actually finishes.\n *\n * Resolves the target by walking `chipRunId`'s own position in `blockId`'s\n * own run array and taking whatever comes right after it — this is the\n * SAME block the chip lives in, not a different sibling block. That run\n * array is `contentIds` for a plain leaf block (paragraph, heading,\n * tableCell, ...), but `props.titleRunIds` for a listItem/toggleHeading,\n * whose own `contentIds` instead holds nested child blocks — same\n * dual-path convention `REPLACE_RUN_SPAN`/`SET_BLOCK_RUNS` already use in\n * EditorStore.js (checking `titleRunIds` first is what actually fixes list\n * items here: `chipRunId` is never IN `contentIds` for one, since that\n * array holds nested list-item block ids, not runs, so the old\n * contentIds-only lookup always failed and fell through to the \"create a\n * new paragraph\" fallback below for every single list item).\n *\n * `insertInlineRunAtCursor` always creates that trailing run (empty string\n * if the chip was inserted at the very end of the existing text), so it's\n * there to find under normal circumstances; the \"no trailing run at all\"\n * branch below is a defensive fallback for the case something else\n * removed it in between (a fresh paragraph is inserted and focused\n * instead, so there's always somewhere typeable — never a stranded caret\n * on the chip's own non-text trigger button).\n */\nexport function focusAfterChip(store, blockId, chipRunId) {\n const block = store.getBlock(blockId);\n const runIds = block?.props?.titleRunIds ?? block?.contentIds ?? [];\n const chipIndex = runIds.indexOf(chipRunId);\n const afterRunId = chipIndex >= 0 ? runIds[chipIndex + 1] : undefined;\n if (afterRunId) {\n focusRunEnd(afterRunId);\n return;\n }\n insertSiblingAfterAndFocus(store, blockId, createTextLeafBlock('paragraph'));\n}\n","import { useCallback, useRef } from 'react';\nimport { useRun } from '../../react/useBlock.js';\nimport { useEditorStore } from '../../react/EditorProvider.jsx';\nimport { updateRun } from '../../store/operations.js';\nimport { Select } from '../../react/Select.jsx';\nimport { consumePendingAutoOpen } from '../../react/pendingAutoOpen.js';\nimport { focusAfterChip } from '../shared/advanceAfterPick.js';\n\n/**\n * An atomic inline \"chip\" mixed directly into running text — e.g. a\n * diagnosis/complaint picker inside a paragraph, exactly like the old\n * notevo schema's inline `type: 'select'` runs. `EditableBlockContent`\n * mounts this into an imperatively-managed host element that carries\n * `data-run-id`/`contentEditable={false}` itself (via a React portal) — this\n * component only renders its own inner content/styling.\n *\n * Renders the shared searchable `Select` combobox — no inline add/remove-\n * option UI. A chip inserted via the `/select` command starts with an empty\n * options list (see index.js's slashCommand); populating/editing that list\n * is left to a host app's own options-source integration (see\n * createSelectFieldType for a full, named/reusable version of that idea),\n * to be revisited later.\n */\nexport function SelectInlineNode({ id, blockId }) {\n const store = useEditorStore();\n const run = useRun(id);\n // Consumed at most once per mount — see pendingAutoOpen.js. A plain\n // `useRef(null)` (not a lazy useState initializer) so the one-time\n // consumption survives React StrictMode's dev-only double-invocation of\n // component bodies without being triggered twice. Also doubles as \"was\n // this chip inserted via the slash/@ menu\" for handleChange below — a\n // chip picked up on an existing document (not just-inserted) doesn't\n // auto-advance on every later edit, only the fresh-insertion flow does.\n const autoOpenRef = useRef(null);\n if (autoOpenRef.current === null) autoOpenRef.current = consumePendingAutoOpen(id);\n\n const handleChange = useCallback(\n (selectedValue) => {\n store.applyOperation(updateRun(id, { data: { ...run?.data, selectedValue } }));\n // Completes the \"insert -> auto-open -> pick\" flow this chip started\n // with: picking a value lands the caret right after the chip, in the\n // SAME paragraph — the trailing-run focus a normal (non-auto-opening)\n // insertion already does immediately, just deferred until now so the\n // picker could take focus first.\n if (autoOpenRef.current) focusAfterChip(store, blockId, id);\n },\n [store, id, run?.data, blockId],\n );\n\n if (!run) return null;\n const { options = [], selectedValue = '', placeholder = 'Select…' } = run.data ?? {};\n\n return (\n <span\n className=\"be-inline-select\"\n // preventDefault too, not just stopPropagation: the browser's default\n // mousedown action collapses the surrounding paragraph's text\n // selection/caret to wherever was clicked, even for a click that\n // lands on a nested non-text control like the Select's trigger\n // button or its search input — without this, that default caret-\n // collapse wins the timing race against Select's own\n // inputRef.current.focus() (called from a useEffect once the\n // popover mounts), so the very first character typed lands back in\n // the paragraph instead of the search box (same rationale as\n // FloatingToolbar's identical onMouseDown preventDefault).\n onMouseDown={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n // React re-dispatches bubbling synthetic events along the *React*\n // tree, not the physical DOM tree — since this chip is mounted via a\n // portal, a keydown on the Select below would otherwise still reach\n // EditableBlockContent's own onKeyDown and can be misread as e.g.\n // \"Backspace next to this chip\", deleting the whole chip instead of\n // just interacting with the dropdown.\n onKeyDown={(event) => event.stopPropagation()}\n >\n <Select\n value={selectedValue}\n options={options}\n onChange={handleChange}\n placeholder={placeholder}\n ariaLabel=\"Select an option\"\n autoOpen={autoOpenRef.current}\n />\n </span>\n );\n}\n","import { genId } from '../../utils/idGen.js';\nimport { replaceRunSpan } from '../../store/operations.js';\nimport { focusRunEnd } from '../../react/focusRun.js';\nimport { markPendingAutoOpen } from '../../react/pendingAutoOpen.js';\n\n/**\n * Splices a newly-created inline run in at the *exact* cursor position\n * (sliceStart/sliceEnd bracket the \"/query\" text that triggered it) —\n * splitting the triggering run into three: whatever came before the \"/\",\n * the new atomic chip, and whatever came after the cursor. This is what\n * makes the chip land where you actually typed \"/\", not always at the end\n * of the block — a run with only \"before\" text and no \"after\" (cursor was\n * at the end) still gets an empty trailing run so there's somewhere to\n * keep typing past the chip. The \"before\" run keeps the original run's id\n * so its DOM span isn't remounted.\n *\n * `autoOpen` (default false) skips moving the caret into the trailing text\n * run altogether and instead marks the new chip's id to open its own\n * picker immediately on mount (see pendingAutoOpen.js) — used by\n * select/custom-select/mention types, where \"focus is now on some plain\n * text past the chip\" is a worse landing spot than \"the picker you just\n * asked for is already open, ready to search.\" Left off for types with no\n * such picker to open (checkbox, date), which keep the original behavior.\n */\nexport function insertInlineRunAtCursor(\n store,\n { blockId, runId, sliceStart, sliceEnd },\n createInlineRun,\n { autoOpen = false } = {},\n) {\n const currentRun = store.getRun(runId);\n const value = currentRun?.value ?? '';\n const beforeText = value.slice(0, sliceStart);\n const afterText = value.slice(sliceEnd);\n\n const inlineRun = createInlineRun();\n const beforeRun = { ...currentRun, value: beforeText };\n const afterRun = { id: genId(), type: 'text', value: afterText, marks: { ...currentRun?.marks } };\n\n store.applyOperation(replaceRunSpan(blockId, [runId], [beforeRun, inlineRun, afterRun]));\n if (autoOpen) {\n markPendingAutoOpen(inlineRun.id);\n } else {\n focusRunEnd(afterRun.id);\n }\n}\n","import { SelectInlineNode } from './SelectInlineNode.jsx';\nimport { defineInline } from '../../registry/define.js';\nimport { genId } from '../../utils/idGen.js';\nimport { insertInlineRunAtCursor } from '../shared/insertInlineRun.js';\nimport { SelectIcon } from '../../react/icons.jsx';\n\nfunction escapeAttr(str) {\n return String(str).replace(/&/g, '&').replace(/\"/g, '"');\n}\n\nfunction selectedLabel(run) {\n const { options = [], selectedValue = '' } = run.data ?? {};\n return options.find((opt) => opt.value === selectedValue)?.label ?? '';\n}\n\nfunction toHTML(run) {\n const label = selectedLabel(run) || run.data?.placeholder || '';\n return `<span data-inline-type=\"select\" data-selected-value=\"${escapeAttr(run.data?.selectedValue ?? '')}\">${label}</span>`;\n}\n\nfunction toPlainText(run) {\n return selectedLabel(run);\n}\n\n/**\n * Only claims nodes carrying our own `data-inline-type=\"select\"` marker —\n * i.e. lossless same-editor round-trips (the app-specific clipboard JSON\n * path already round-trips runs directly without going through HTML at\n * all; this fromHTML exists for the text/html clipboard fallback). Foreign\n * HTML from another app has no such marker and correctly falls through to\n * plain text, since there's no way to know what a \"select\" from another\n * app's DOM even means.\n */\nfunction fromHTML(node) {\n if (node.getAttribute?.('data-inline-type') !== 'select') return null;\n return {\n id: genId(),\n type: 'select',\n value: '',\n marks: {},\n data: {\n options: [],\n selectedValue: node.getAttribute('data-selected-value') ?? '',\n },\n };\n}\n\nexport const selectInlineType = defineInline({\n name: 'select',\n component: SelectInlineNode,\n toHTML,\n toPlainText,\n fromHTML,\n slashCommand: {\n label: 'Select',\n icon: SelectIcon,\n keywords: ['select', 'dropdown', 'choice', 'picker'],\n run: (store, { blockId, runId, sliceStart, sliceEnd }) =>\n insertInlineRunAtCursor(\n store,\n { blockId, runId, sliceStart, sliceEnd },\n () => ({\n id: genId(),\n type: 'select',\n value: '',\n marks: {},\n data: { options: [], selectedValue: '', placeholder: 'Select…' },\n }),\n { autoOpen: true },\n ),\n },\n});\n","import { useCallback } from 'react';\nimport { useRun } from '../../react/useBlock.js';\nimport { useEditorStore } from '../../react/EditorProvider.jsx';\nimport { updateRun } from '../../store/operations.js';\n\n/**\n * An atomic date chip — a real <input type=\"date\">, proving the inline\n * mechanism generalizes to arbitrary native controls, not just <select>\n * (see selectInlineType). `EditableBlockContent` mounts this into an\n * imperatively-managed host element that carries `data-run-id`/\n * `contentEditable={false}` itself (via a React portal) — this component\n * only renders its own inner content/styling.\n */\nexport function DateInlineNode({ id }) {\n const store = useEditorStore();\n const run = useRun(id);\n\n const handleChange = useCallback(\n (event) => {\n store.applyOperation(updateRun(id, { data: { ...run?.data, isoDate: event.target.value } }));\n },\n [store, id, run?.data],\n );\n\n if (!run) return null;\n const { isoDate = '' } = run.data ?? {};\n\n return (\n <span\n className=\"be-inline-date\"\n onMouseDown={(event) => event.stopPropagation()}\n // See SelectInlineNode's onKeyDown comment: without this, a keydown on\n // the date input (e.g. Backspace while editing it) still reaches\n // EditableBlockContent's onKeyDown via React's portal-following\n // synthetic bubbling, and can be misread as deleting this whole chip.\n onKeyDown={(event) => event.stopPropagation()}\n >\n <input type=\"date\" value={isoDate} onChange={handleChange} />\n </span>\n );\n}\n","import { DateInlineNode } from './DateInlineNode.jsx';\nimport { defineInline } from '../../registry/define.js';\nimport { genId } from '../../utils/idGen.js';\nimport { insertInlineRunAtCursor } from '../shared/insertInlineRun.js';\nimport { DateIcon } from '../../react/icons.jsx';\n\nfunction escapeAttr(str) {\n return String(str).replace(/&/g, '&').replace(/\"/g, '"');\n}\n\nfunction formatDate(isoDate) {\n if (!isoDate) return '';\n const parsed = new Date(`${isoDate}T00:00:00`);\n if (Number.isNaN(parsed.getTime())) return isoDate;\n return parsed.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });\n}\n\nfunction toHTML(run) {\n const isoDate = run.data?.isoDate ?? '';\n return `<span data-inline-type=\"date\" data-iso-date=\"${escapeAttr(isoDate)}\">${formatDate(isoDate)}</span>`;\n}\n\nfunction toPlainText(run) {\n return formatDate(run.data?.isoDate ?? '');\n}\n\n/** Only claims our own `data-inline-type=\"date\"` marker — see select's fromHTML for why. */\nfunction fromHTML(node) {\n if (node.getAttribute?.('data-inline-type') !== 'date') return null;\n return {\n id: genId(),\n type: 'date',\n value: '',\n marks: {},\n data: { isoDate: node.getAttribute('data-iso-date') ?? '' },\n };\n}\n\nfunction todayIso() {\n return new Date().toISOString().slice(0, 10);\n}\n\nexport const dateInlineType = defineInline({\n name: 'date',\n component: DateInlineNode,\n toHTML,\n toPlainText,\n fromHTML,\n slashCommand: {\n label: 'Date',\n icon: DateIcon,\n keywords: ['date', 'when', 'schedule', 'calendar'],\n run: (store, { blockId, runId, sliceStart, sliceEnd }) =>\n insertInlineRunAtCursor(store, { blockId, runId, sliceStart, sliceEnd }, () => ({\n id: genId(),\n type: 'date',\n value: '',\n marks: {},\n data: { isoDate: todayIso() },\n })),\n },\n});\n","import { useCallback } from 'react';\nimport { useRun } from '../../react/useBlock.js';\nimport { useEditorStore } from '../../react/EditorProvider.jsx';\nimport { updateRun } from '../../store/operations.js';\n\n/**\n * An atomic checkbox-with-label chip — pairs a toggle with its own free-text\n * label (e.g. \"Diagnosis confirmed ☑\") in one unit, distinct from a to-do\n * list item's `props.checked` (that's block-level state for a whole line;\n * this is inline content mixed into running text or, more commonly, a\n * table cell — see the \"checkbox\" table column type).\n */\nexport function CheckboxInlineNode({ id }) {\n const store = useEditorStore();\n const run = useRun(id);\n\n const handleCheckedChange = useCallback(\n (event) => {\n store.applyOperation(\n updateRun(id, { data: { ...run?.data, checked: event.target.checked } }),\n );\n },\n [store, id, run?.data],\n );\n\n const handleLabelChange = useCallback(\n (event) => {\n store.applyOperation(updateRun(id, { data: { ...run?.data, label: event.target.value } }));\n },\n [store, id, run?.data],\n );\n\n if (!run) return null;\n const { checked = false, label = '' } = run.data ?? {};\n\n return (\n <span\n className=\"be-inline-checkbox\"\n onMouseDown={(event) => event.stopPropagation()}\n // See SelectInlineNode's onKeyDown comment for why this is needed.\n onKeyDown={(event) => event.stopPropagation()}\n >\n <input\n type=\"checkbox\"\n className=\"be-inline-checkbox-input\"\n checked={checked}\n onChange={handleCheckedChange}\n />\n <input\n type=\"text\"\n className=\"be-inline-checkbox-label\"\n value={label}\n onChange={handleLabelChange}\n placeholder=\"Label…\"\n />\n </span>\n );\n}\n","import { CheckboxInlineNode } from './CheckboxInlineNode.jsx';\nimport { defineInline } from '../../registry/define.js';\nimport { genId } from '../../utils/idGen.js';\nimport { insertInlineRunAtCursor } from '../shared/insertInlineRun.js';\nimport { CheckboxIcon } from '../../react/icons.jsx';\n\nfunction escapeHTML(str) {\n return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n}\n\nfunction escapeAttr(str) {\n return escapeHTML(str).replace(/\"/g, '"');\n}\n\nfunction toHTML(run) {\n const { checked = false, label = '' } = run.data ?? {};\n return `<span data-inline-type=\"checkbox\" data-checked=\"${checked}\">${checked ? '☑' : '☐'} ${escapeHTML(label)}</span>`;\n}\n\nfunction toPlainText(run) {\n const { checked = false, label = '' } = run.data ?? {};\n return `${checked ? '[x]' : '[ ]'} ${label}`.trim();\n}\n\n/** Only claims our own `data-inline-type=\"checkbox\"` marker — see select's fromHTML for why. */\nfunction fromHTML(node) {\n if (node.getAttribute?.('data-inline-type') !== 'checkbox') return null;\n return {\n id: genId(),\n type: 'checkbox',\n value: '',\n marks: {},\n data: {\n checked: node.getAttribute('data-checked') === 'true',\n label: (node.textContent ?? '').replace(/^[☑☐]\\s*/, ''),\n },\n };\n}\n\nexport const checkboxInlineType = defineInline({\n name: 'checkbox',\n component: CheckboxInlineNode,\n toHTML,\n toPlainText,\n fromHTML,\n slashCommand: {\n label: 'Checkbox',\n icon: CheckboxIcon,\n keywords: ['checkbox', 'todo', 'check', 'toggle'],\n run: (store, { blockId, runId, sliceStart, sliceEnd }) =>\n insertInlineRunAtCursor(store, { blockId, runId, sliceStart, sliceEnd }, () => ({\n id: genId(),\n type: 'checkbox',\n value: '',\n marks: {},\n data: { checked: false, label: '' },\n })),\n },\n});\n","import { useCallback } from 'react';\nimport { useRun, useBlock } from '../../react/useBlock.js';\nimport { useEditorStore } from '../../react/EditorProvider.jsx';\nimport { updateRun } from '../../store/operations.js';\nimport { resolveColumns } from '../../blocks/table/tableColumns.js';\nimport { pickTagColor } from '../../blocks/table/tagColors.js';\nimport { Select } from '../../react/Select.jsx';\n\n/**\n * The atomic chip for a table's \"select\" column type — deliberately a\n * *different* inline type from the general-purpose `select` (used for\n * ad-hoc dropdown chips mixed into paragraph text), not a reuse of it. The\n * general one owns its options per-run with its own add/remove-option UI,\n * which is right for an independent inline chip but wrong for a table\n * column: every cell in a \"select\" column should offer the *same* choices\n * and stay in sync when an option is added, renamed, or removed. That\n * shared list lives on the table's own `props.columns[i].options` (see\n * tableColumns.js) — configured once from the column header's menu, not\n * per cell — so this component is intentionally table-aware (it resolves\n * its own containing cell -> row -> table via `blockId`, a coupling the\n * general inline types don't need and don't have).\n *\n * `useBlock(tableId)` (not a one-off `store.getBlock`) is what makes this\n * re-render when the column's options change elsewhere (the header menu)\n * even though this run itself didn't change.\n */\nexport function TableSelectInlineNode({ id, blockId }) {\n const store = useEditorStore();\n const run = useRun(id);\n\n const cell = blockId ? store.getBlock(blockId) : null;\n const row = cell ? store.getBlock(cell.parentId) : null;\n const tableId = row?.parentId ?? null;\n const table = useBlock(tableId);\n\n const colIndex = row ? row.contentIds.indexOf(blockId) : -1;\n const columns = table && row ? resolveColumns(table, row.contentIds.length) : [];\n // Fallback for options created before per-option colors existed: derive\n // one by position rather than leaving it uncolored, same convention as\n // TableHeaderRow's own SelectOptionsManager swatch fallback.\n const options = (columns[colIndex]?.options ?? []).map((option, i) => ({\n ...option,\n color: option.color ?? pickTagColor(i),\n }));\n\n const handleChange = useCallback(\n (selectedValue, option) => {\n store.applyOperation(\n updateRun(id, { data: { selectedValue, selectedLabel: option?.label ?? '' } }),\n );\n },\n [store, id],\n );\n\n if (!run) return null;\n const { selectedValue = '' } = run.data ?? {};\n\n return (\n <span\n className=\"be-inline-table-select\"\n // preventDefault too, not just stopPropagation — see SelectInlineNode's\n // onMouseDown comment: without it, the browser's default caret-\n // collapse-to-click-position wins the race against Select's own\n // focus() call, and the first typed character lands in the\n // surrounding cell/paragraph instead of the search box.\n onMouseDown={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n // See SelectInlineNode's onKeyDown comment for why this is needed.\n onKeyDown={(event) => event.stopPropagation()}\n >\n <Select\n value={selectedValue}\n options={options}\n onChange={handleChange}\n placeholder=\"Select…\"\n ariaLabel=\"Select an option\"\n variant=\"tag\"\n />\n </span>\n );\n}\n","import { TableSelectInlineNode } from './TableSelectInlineNode.jsx';\nimport { defineInline } from '../../registry/define.js';\nimport { genId } from '../../utils/idGen.js';\n\nfunction escapeHTML(str) {\n return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n}\n\nfunction escapeAttr(str) {\n return escapeHTML(str).replace(/\"/g, '"');\n}\n\n// `run.data.selectedLabel` is a denormalized cache of the currently\n// selected option's label (kept in sync by TableSelectInlineNode's\n// onChange and by setColumnOptions whenever the column's shared options\n// change) — deliberately redundant with the column's own options list, so\n// toHTML/toPlainText/fromHTML never need table/column context (which\n// serialization call sites don't have) to render a sensible value.\nfunction toHTML(run) {\n const { selectedValue = '', selectedLabel = '' } = run.data ?? {};\n return `<span data-inline-type=\"tableSelect\" data-selected-value=\"${escapeAttr(selectedValue)}\">${escapeHTML(selectedLabel)}</span>`;\n}\n\nfunction toPlainText(run) {\n return run.data?.selectedLabel ?? '';\n}\n\n/**\n * Only claims nodes carrying our own `data-inline-type=\"tableSelect\"`\n * marker (see select's fromHTML for why). The reconstructed run has no\n * knowledge of which column it'll end up in on paste — the pasted label\n * is taken at face value, and its `selectedValue` will only match an\n * actual column option again if the destination table happens to have one\n * with the same id, which is possible but not guaranteed for a same-editor\n * paste; a cross-editor paste always lands as an unmatched value anyway.\n */\nfunction fromHTML(node) {\n if (node.getAttribute?.('data-inline-type') !== 'tableSelect') return null;\n return {\n id: genId(),\n type: 'tableSelect',\n value: '',\n marks: {},\n data: {\n selectedValue: node.getAttribute('data-selected-value') ?? '',\n selectedLabel: node.textContent ?? '',\n },\n };\n}\n\nexport const tableSelectInlineType = defineInline({\n name: 'tableSelect',\n component: TableSelectInlineNode,\n toHTML,\n toPlainText,\n fromHTML,\n // No slashCommand: unlike select/date/custom field types, this type is never\n // inserted ad-hoc into a paragraph — it only exists inside a table cell\n // whose column type has been set to \"select\" (see setColumnType).\n});\n","/**\n * Not an atomic run type at all — an emoji is inserted as plain text (the\n * literal unicode character), exactly as selectable/deletable/editable as\n * anything else typed there, not a persistent chip. So there's no\n * `component`/`toHTML`/`fromHTML`/`slashCommands` here — emoji has its own\n * dedicated \":\" trigger (see useEmojiMenuTrigger + emojiCommands.js)\n * instead of contributing to the shared \"/\" slash-command list, so this\n * entry is registered only for consistency/discoverability (host code that\n * enumerates `inlineRegistry` sees an 'emoji' entry) even though it\n * currently does nothing on its own.\n */\nexport const emojiInlineType = { name: 'emoji', kind: 'inline' };\n","// noteloom/starter-kit — the built-in block + inline set as an `extensions`\n// array, so `useEditor({ extensions: [...starterKit(), myBlock] })` is the\n// recommended way to say \"the usual editor, plus my own thing\". Calling\n// `useEditor()` with no args still registers exactly this same set.\n//\n// Also re-exported from the main `noteloom` entry.\n\n// Re-exported so the whole extension-authoring workflow is one import.\nexport {\n defineBlock,\n defineInline,\n defineExtension,\n registerExtensions,\n} from './registry/define.js';\n\nimport {\n paragraphBlockType,\n headingBlockType,\n listItemBlockType,\n tableBlockType,\n tableRowBlockType,\n tableCellBlockType,\n layoutBlockType,\n layoutColumnBlockType,\n dividerBlockType,\n calloutBlockType,\n blockquoteBlockType,\n codeBlockType,\n toggleHeadingBlockType,\n buttonBlockType,\n embedBlockType,\n canvasBlockType,\n} from './blocks/index.js';\nimport {\n selectInlineType,\n dateInlineType,\n checkboxInlineType,\n tableSelectInlineType,\n emojiInlineType,\n} from './inlineTypes/index.js';\n\n// Each built-in is already a defineBlock()/defineInline() result (see its own\n// src/blocks|inlineTypes/*/index.js), so `starterKit()` is just \"all of them,\n// minus anything excluded\". `emoji` is the one marker-only entry — no\n// component, tagged by hand in its own file.\nconst ALL = [\n paragraphBlockType,\n headingBlockType,\n listItemBlockType,\n tableBlockType,\n tableRowBlockType,\n tableCellBlockType,\n layoutBlockType,\n layoutColumnBlockType,\n dividerBlockType,\n calloutBlockType,\n blockquoteBlockType,\n codeBlockType,\n toggleHeadingBlockType,\n buttonBlockType,\n embedBlockType,\n canvasBlockType,\n selectInlineType,\n dateInlineType,\n checkboxInlineType,\n tableSelectInlineType,\n emojiInlineType,\n];\n\n/**\n * Returns a fresh array of `defineBlock()` / `defineInline()` results for every\n * built-in type. `exclude` drops types by name — `starterKit({ exclude:\n * ['canvas'] })` for the usual editor minus the heavy drawing block.\n */\nexport function starterKit({ exclude = [] } = {}) {\n const drop = new Set(exclude);\n return ALL.filter((def) => !drop.has(def.name));\n}\n"],"names":["isRunBlank","run","isRunsEmpty","store","runIds","id","isContentlessBlock","block","hasRuns","hasTitleRuns","_b","_a","LinkEditModal","isOpen","initialHref","initialTarget","hasExistingLink","onSave","onRemove","onClose","href","setHref","useState","target","setTarget","useEffect","trimmedHref","handleSubmit","useCallback","event","jsx","Modal","jsxs","useAutoAdjustedPosition","menuRef","top","left","position","setPosition","useLayoutEffect","rect","clampedLeft","clampLeftToViewport","clampedTop","clampTopToViewport","LinkHoverCard","containerRef","hovered","setHovered","isModalOpen","setIsModalOpen","hideTimerRef","useRef","cardRef","clearHideTimer","scheduleHide","prev","container","handleMouseOver","runEl","runId","handleMouseOut","openModal","closeModal","saveLink","updateRun","removeLink","nextMarks","link","isCardOpen","Fragment","createPortal","PencilIcon","XIcon","CommentPopoverHeader","title","FOCUSABLE_SELECTOR","CommentPopover","authorId","pinned","setPinned","popoverRef","previouslyFocusedRef","setHoveredCommentId","useHoveredComment","findCommentRun","el","commentIds","_c","found","handleClick","handlePointerDown","handleKeyDown","closePopover","didFocusRef","threads","thread","CommentThreadCard","syncEmptyAttr","runs","wrapper","marksToStyle","marks","setHostText","host","displayValue","onlyChild","TextRunSpan","onValueSynced","useRun","hoveredCommentId","value","stripEmptyRunPlaceholder","EMPTY_RUN_PLACEHOLDER","style","_d","_e","findAdjacentAtomicRunId","containerEl","getRun","backward","selection","anchorNode","anchorOffset","neighborAtomicId","caretRunId","idx","neighborId","neighborRun","child","findWhollySelectedAtomicRunId","range","resolveRangeBoundary","node","offset","childIndex","charOffset","computeRunsAfterRangeDeletion","start","end","children","n","touchesAtomic","nextRuns","insertionIndex","beforeStart","afterEnd","isStartChild","isEndChild","survivor","prefix","suffix","genId","isCaretAtContainerStart","firstChild","probe","maxStartOffset","isCaretAtContainerEnd","lastChild","textLength","findAdjacentContentlessSiblingId","blockId","direction","parent","index","adjacentIndex","adjacentId","RunNode","inlineRegistry","entry","Component","getOrCreateHost","hostsMap","EditableBlockContent","dir","onEnter","onBackspaceAtStart","onDeleteAtEnd","onArrowUp","onArrowDown","onTab","onShiftTab","onAutoformat","useEditorStore","useInlineRegistry","commentAuthorId","useCommentAuthorId","getSelectedBlockId","setSelectedBlockId","useSelectedBlock","isComposingRef","hostsRef","liveIds","previous","expectedNext","handleInput","currentRuns","changed","onlyValueChanges","reconcileDomToRuns","i","setBlockRuns","syncEmptyFromStore","handleCompositionStart","handleCompositionEnd","removeRun","selectOrDeleteContentlessNeighbor","removeBlock","handleBeforeInput","inputType","isDelete","isReplaceTyped","targetRanges","result","focusRunId","focusAtStart","typedRun","finalRuns","landingRunId","wholeId","atomicId","ensureRootNonEmpty","rootId","root","createTextLeafBlock","insertBlock","UNWRAP_WHEN_SOLE_CHILD_EMPTIED","MERGEABLE_TEXT_TYPES","canMergeTypes","prevType","blockType","mergeWithPreviousOrDelete","isEmpty","isBlankRun","applyOps","unwrapEmptyContainer","fallbackBlock","prevId","mergedContentIds","setBlockContentIds","grandParent","nextId","fallbackId","ops","op","focusAfterMerge","focusBlockId","currentBlockId","lastRunId","resolveBlockLastRun","focusRunEnd","resolveBlockDir","RULES","m","applyMarkdownShortcut","rule","match","strippedValue","convertBlockType","focusRunStart","EXITABLE_PARENT_TYPES","ParagraphBlock","useBlock","handleEnter","isLastChild","insertSiblingAfterAndFocus","insertSiblingSplitAtCaretAndFocus","handleBackspaceAtStart","isSoleChild","titleRunIds","lastTitleRunId","handleArrowUp","focusAdjacentBlock","handleArrowDown","handleAutoformat","className","useBlockClassName","TAG_TO_MARK","domInlineToRuns","ctx","activeMarks","walk","markName","toHTML","r","runToHTML","toPlainText","runToPlainText","toMarkdown","runsToMarkdown","fromHTML","paragraphBlockType","defineBlock","TextIcon","trimSlashQueryAndInsertAfter","HeadingBlock","level","Tag","HEADING_ICONS","Heading1Icon","Heading2Icon","Heading3Icon","TAG_TO_LEVEL","text","headingBlockType","EMPTY_CONTENT_IDS","useBlockChildren","parentId","subscribe","onStoreChange","getSnapshot","useSyncExternalStore","BlockErrorBoundary","__publicField","error","info","s","BlockRenderer","memo","registry","useBlockRegistry","useMenuKeyboardNav","triggerRef","wasOpenRef","menu","items","focusItem","list","clamped","currentIndex","LIVE_REGION_ID","getOrCreateLiveRegion","region","announce","message","DEFAULT_CALLOUT_ICON","DEFAULT_CALLOUT_COLOR","createCalloutBlock","icon","color","calloutId","paragraphBlock","TEXT_FAMILY_TARGETS","BulletedListIcon","NumberedListIcon","CheckboxIcon","ChevronRightIcon","QuoteIcon","CalloutIcon","CodeIcon","TEXT_FAMILY_TYPES","t","isTurnIntoEligible","type","getOwnRunIds","turnBlockInto","props","convertOps","newBlockId","TurnIntoSubmenu","onSelect","menuClassName","itemClassName","setIsOpen","setRect","setMenuRef","close","useOutsideClickAndEscape","open","handleSelect","handleTriggerKeyDown","handleSubmenuKeyDown","Icon","duplicateBlock","original","subtree","captureSubtree","subtreeBlocks","remapSubtreeIds","focusBlockStart","moveBlockUp","moveBlock","moveBlockDown","deleteBlockAndFocusSibling","targetId","BlockGutterRow","isMenuOpen","setIsMenuOpen","turnIntoMenuRef","outsideRefs","useMemo","selectedBlockRange","useBlockRangeSelection","isRangeSelected","closeMenu","openMenu","handleAdd","handleDuplicate","handleMoveUp","handleMoveDown","handleDelete","isHidden","handleToggleHidden","updateBlockProps","isRtl","handleToggleDir","handleTurnInto","PlusIcon","GripVerticalIcon","CopyIcon","ArrowUpIcon","ArrowDownIcon","EyeIcon","EyeOffIcon","AlignLeftIcon","AlignRightIcon","TrashIcon","BlockChildren","isTopLevel","filterIds","contentIds","isPreviewMode","usePreviewMode","baseIds","visibleIds","childId","ALPHA_START","ROMAN_TABLE","toAlpha","out","toRoman","rest","symbol","isPlainMarkerItem","listItemDepth","depth","current","orderedItemIndex","siblingIds","pos","count","sibling","orderedMarkerText","BULLET_GLYPHS","bulletMarkerText","createListItemBlock","ordered","checked","collapsed","initialRuns","allRuns","childBlock","childRuns","indentListItem","outdentListItem","currentParent","grandParentId","parentIndex","isBlankTitle","isBodyEmpty","childIds","mergeListItemOrOutdent","empty","mergedTitleRunIds","exitListItemToParagraph","ListItemBlock","hasNestedChildren","isTodo","isToggle","factory","insertFirstChildSplitAtCaretAndFocus","handleTab","handleShiftTab","toggleChecked","toggleCollapsed","titleText","ChevronDownIcon","titleHTML","childrenHTML","nested","marker","childrenMd","line","fromLiNode","liNode","inlineNodes","nestedListNodes","titleRuns","childBlocks","listNode","li","listItemBlockType","COLUMN_TYPES","DEFAULT_COLUMN_TYPE","DEFAULT_COLUMN_WIDTH","MIN_COLUMN_WIDTH","defaultColumnLabel","createDefaultColumns","_","resolveColumns","table","colCount","columns","c","width","blankRunForType","createCellForColumn","column","convertRunToType","newType","parsed","isoDate","runPlainText","sortKeyForColumn","columnType","compareValues","a","b","na","nb","sortRowIdsByColumn","rows","withKeys","rowId","isEmptyKey","key","aEmpty","bEmpty","cmp","AGGREGATE_TYPES","AGGREGATE_LABELS","AGGREGATE_SHORT_LABELS","computeColumnAggregate","aggregateType","texts","numbers","formatAggregateValue","removeTableAndFocusSibling","tableIndex","fallbackParagraphId","parentAfter","siblingId","insertRowAfter","row","rowIndex","newRowId","cellBlocks","cell","newRow","deleteRow","updatedTable","targetRowIndex","targetRowId","insertColumnAfter","tableId","colIndex","currentColumns","newColumn","firstNewCellId","nextColumns","deleteColumn","firstRow","updatedFirstRow","targetColIndex","targetCellId","setColumnWidth","renameColumn","label","sortTableByColumn","orderedIds","setColumnAggregate","aggregate","cellRunsForColumn","cellId","buildSelectColumnConversion","cellRuns","options","optionByLabel","option","newRuns","setColumnType","oldRun","newRun","setColumnOptions","optionById","o","selectedValue","nextSelectedValue","nextSelectedLabel","FIELD_TYPES_KEY","useFieldTypes","computeInset","vv","inset","useVirtualKeyboardInset","setInset","handleChange","ESTIMATED_POPOVER_HEIGHT","LIST_HEIGHT","ROW_HEIGHT_FALLBACK","OVERSCAN","matchesQuery","query","Select","onChange","placeholder","ariaLabel","variant","selectedLabel","selectedColor","onManageOptions","manageOptionsLabel","mention","autoOpen","setQuery","activeIndex","setActiveIndex","keyboardInset","asyncOptions","setAsyncOptions","isLoading","setIsLoading","loadError","setLoadError","rootRef","buttonRef","inputRef","listRef","firstRowRef","isTag","isDynamic","rowHeight","setRowHeight","scrollTop","setScrollTop","staticSelected","selected","filtered","maxScrollTop","clampedScrollTop","startIndex","visibleCount","endIndex","visibleOptions","topPadding","bottomPadding","measured","cancelled","timer","adjustedLeft","useHorizontalAutoAdjustedLeft","itemTop","itemBottom","viewTop","viewHeight","viewBottom","nextScrollTop","selectOption","handleSearchKeyDown","localIndex","TAG_COLORS","pickTagColor","TYPE_LABELS","AGGREGATE_OPTIONS","TYPE_OPTIONS","MAX_COLUMN_WIDTH_HINT","ColumnFieldTypePicker","fieldTypes","openCreate","useFieldTypeEditor","handlePick","fieldTypeId","fieldType","ft","SelectOptionsManager","draft","setDraft","handleRename","optionValue","handleRemove","ColumnHeaderCell","filterValue","onFilterChange","dragWidth","setDragWidth","thRef","rightLeft","useAutoAdjustedRightLeft","handleLabelChange","handleInsertLeft","handleInsertRight","handleTypeChange","handleSortAsc","handleSortDesc","handleAggregateChange","handleResizeStart","col","startWidth","startX","computeWidth","moveEvent","handleMouseMove","handleMouseUp","upEvent","handleResizeKeyDown","step","next","TableHeaderRow","filters","TableBlock","setFilters","handleFilterChange","columnId","k","handleAddRow","lastRowId","activeFilters","q","cellRun","visibleRowIds","hasAggregates","TableRowBlock","handleDeleteRow","locateCell","resolveAdjacentCellTarget","delta","nextColIndex","nextRowIndex","targetRow","exitTableForward","targetRunId","resolveAdjacentFocusTarget","moveToAdjacentCell","targetCell","TableCellBlock","createRow","createTableBlock","cols","rowIds","cellToHTML","cellToPlainText","cellToMarkdown","cellFromHTML","rowToHTML","cellBlock","rowToPlainText","rowToMarkdown","rowFromHTML","cellNodes","cellNode","tableToHTML","theadHTML","escapeHTML","rowsHTML","rowBlock","tableToPlainText","tableToMarkdown","headerRow","separatorRow","bodyRows","tableFromHTML","theadRow","bodyRowNodes","tr","rowNode","headerCells","tableCellBlockType","tableRowBlockType","tableBlockType","TableIcon","LayoutBlock","LayoutColumnBlock","createLayoutBlock","layoutId","columnIds","columnBlock","containerToHTML","tagOpen","tagClose","containerToPlainText","containerToMarkdown","layoutColumnBlockType","layoutBlockType","ColumnsIcon","DividerBlock","createDividerBlock","dividerBlockType","DividerIcon","sliceStart","sliceEnd","dividerId","insertSiblingAfter","CALLOUT_COLORS","CalloutBlock","editingIcon","setEditingIcon","isColorPickerOpen","setIsColorPickerOpen","colorTriggerRef","colorPickerRef","colorOutsideRefs","closeColorPicker","commitIcon","handleIconKeyDown","handleColorChange","childrenToHTML","inner","calloutBlockType","BlockquoteBlock","blockquoteBlockType","LANGUAGES","LANGUAGE_OPTIONS","lang","insertLiteralTextAtCaret","caret","resolveCollapsedCaret","newValue","focusRunAtOffset","CodeBlock","showLineNumbers","useShowLineNumbers","focusBlock","handleLanguageChange","language","lineCount","fenceLang","code","codeEl","codeBlockType","mergeToggleHeadingOrNoop","ToggleHeadingBlock","createToggleHeadingBlock","heading","summary","headingEl","pBlock","fallback","toggleHeadingBlockType","COLORS","ButtonEditModal","setLabel","setColor","attrs","setAttrs","existingAttrs","updateAttrRow","patch","last","removeAttrRow","handleSave","customAttrs","DEFAULT_COLOR","ButtonBlock","isEditModalOpen","setIsEditModalOpen","openLink","dataAttrs","createButtonBlock","MARKER_CLASS","escapeAttr","attrHTML","attr","buttonBlockType","ButtonIcon","readFileAsDataURL","file","resolve","reject","reader","formatBytes","bytes","kindForMimeType","mimeType","resolveFileToSrc","uploadFile","maxFileSize","kind","resolveFileToEmbedInsert","uploadConfig","src","name","PROVIDERS","_m","url","resolveOEmbedUrl","rawUrl","provider","KIND_LABEL","KIND_ACCEPT","MIN_WIDTH","MAX_WIDTH","ALIGN_OPTIONS","AlignCenterIcon","clampWidth","pct","EmbedPreview","alt","PaperclipIcon","EmbedBlock","useFileUpload","urlInput","setUrlInput","isDragOver","setIsDragOver","isAltTextOpen","setIsAltTextOpen","altDraft","setAltDraft","isUploading","setIsUploading","uploadError","setUploadError","previewRef","frameRef","setMedia","openAltText","closeAltText","saveAltText","acceptFile","err","handleFileChange","handleDrop","handleDragOver","handleDragLeave","commitUrl","trimmed","oembed","clearMedia","frameEl","containerWidth","computePct","align","originalUrl","canResize","effectiveWidth","isOEmbed","LinkIcon","createEmbedBlock","KIND_ICONS","ImageIcon","VideoIcon","AudioIcon","FILE_MARKER_CLASS","OEMBED_MARKER_CLASS","alignWidthStyle","declarations","parseAlignWidth","styleWidth","blockOf","insertEmbedCommand","embedId","embedBlockType","pendingRunIds","markPendingAutoOpen","consumePendingAutoOpen","focusAfterChip","chipRunId","chipIndex","afterRunId","SelectInlineNode","autoOpenRef","insertInlineRunAtCursor","createInlineRun","currentRun","beforeText","afterText","inlineRun","beforeRun","afterRun","replaceRunSpan","str","opt","selectInlineType","defineInline","SelectIcon","DateInlineNode","formatDate","todayIso","dateInlineType","DateIcon","CheckboxInlineNode","handleCheckedChange","checkboxInlineType","TableSelectInlineNode","tableSelectInlineType","emojiInlineType","ALL","canvasBlockType","starterKit","exclude","drop","def"],"mappings":"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"}
|