quoin-editor 1.8.0 → 2.0.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.
Files changed (86) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/MIGRATION.md +137 -23
  3. package/README.md +8 -2
  4. package/dist/ai.cjs +34 -34
  5. package/dist/ai.js +3 -3
  6. package/dist/catalogue.cjs +21 -21
  7. package/dist/catalogue.js +12 -12
  8. package/dist/{chunk-VWYPO6SX.js → chunk-2UKI26JA.js} +5 -5
  9. package/dist/chunk-2UKI26JA.js.map +1 -0
  10. package/dist/{chunk-B3OBM6I4.cjs → chunk-4PIJC4FD.cjs} +16 -16
  11. package/dist/{chunk-5OZX2LV4.js → chunk-5X52BAZB.js} +5 -5
  12. package/dist/{chunk-5OZX2LV4.js.map → chunk-5X52BAZB.js.map} +1 -1
  13. package/dist/{chunk-PVFSJXYQ.cjs → chunk-5YAJZSTI.cjs} +18 -18
  14. package/dist/{chunk-53CNYRVQ.cjs → chunk-66OPHDFA.cjs} +50 -50
  15. package/dist/{chunk-EZX37R5D.js → chunk-6BVE46K7.js} +4 -4
  16. package/dist/{chunk-EZX37R5D.js.map → chunk-6BVE46K7.js.map} +1 -1
  17. package/dist/{chunk-MMS4D4MK.cjs → chunk-77CNOLHY.cjs} +3 -3
  18. package/dist/{chunk-DXUDBPG5.js → chunk-B4VCDJSA.js} +5 -5
  19. package/dist/{chunk-DXUDBPG5.js.map → chunk-B4VCDJSA.js.map} +1 -1
  20. package/dist/{chunk-4MCYQHFL.cjs → chunk-BYYCD54G.cjs} +2 -2
  21. package/dist/{chunk-BA5WXBGE.cjs → chunk-CJVJNMOB.cjs} +107 -101
  22. package/dist/{chunk-TQHFGSTT.cjs → chunk-D6CIIWCU.cjs} +30 -30
  23. package/dist/{chunk-NCDMQCZR.js → chunk-EU5IGKMP.js} +3 -3
  24. package/dist/{chunk-NCDMQCZR.js.map → chunk-EU5IGKMP.js.map} +1 -1
  25. package/dist/{chunk-7X3T7VXV.cjs → chunk-HOSDMHK6.cjs} +25 -25
  26. package/dist/{chunk-XKYNINUX.cjs → chunk-IKZSCTRF.cjs} +3 -3
  27. package/dist/{chunk-D4L5FINK.js → chunk-IW4TMECB.js} +3 -3
  28. package/dist/{chunk-D4L5FINK.js.map → chunk-IW4TMECB.js.map} +1 -1
  29. package/dist/{chunk-MRHDPXQ7.js → chunk-J2SVYBTC.js} +6 -6
  30. package/dist/chunk-J2SVYBTC.js.map +1 -0
  31. package/dist/{chunk-PHQMHXNG.js → chunk-KQPZTSW3.js} +4 -4
  32. package/dist/{chunk-PHQMHXNG.js.map → chunk-KQPZTSW3.js.map} +1 -1
  33. package/dist/{chunk-YVPZDTVZ.cjs → chunk-LEICOZYK.cjs} +2 -2
  34. package/dist/{chunk-SP4F5F6V.js → chunk-M77A3EGD.js} +3 -3
  35. package/dist/{chunk-SP4F5F6V.js.map → chunk-M77A3EGD.js.map} +1 -1
  36. package/dist/{chunk-VM567D6O.js → chunk-MAS4AEF4.js} +4 -4
  37. package/dist/{chunk-VM567D6O.js.map → chunk-MAS4AEF4.js.map} +1 -1
  38. package/dist/{chunk-EZWJRBQT.cjs → chunk-NFO3W644.cjs} +19 -19
  39. package/dist/{chunk-MSWA5ZZM.js → chunk-NL5J77VD.js} +202 -202
  40. package/dist/chunk-NL5J77VD.js.map +1 -0
  41. package/dist/{chunk-53FJFYBR.cjs → chunk-V4WQG7FR.cjs} +64 -64
  42. package/dist/{chunk-WOGCD7JN.js → chunk-YABGWOAV.js} +3 -3
  43. package/dist/{chunk-WOGCD7JN.js.map → chunk-YABGWOAV.js.map} +1 -1
  44. package/dist/{chunk-P6HC7RUN.cjs → chunk-Z6LAARPB.cjs} +199 -204
  45. package/dist/{chunk-Y4EJ6UBV.js → chunk-ZN5DHNSL.js} +15 -9
  46. package/dist/chunk-ZN5DHNSL.js.map +1 -0
  47. package/dist/comments.cjs +30 -30
  48. package/dist/comments.js +3 -3
  49. package/dist/diagram.cjs +6 -6
  50. package/dist/diagram.js +3 -3
  51. package/dist/embed.cjs +5 -5
  52. package/dist/embed.js +3 -3
  53. package/dist/emoji.cjs +6 -6
  54. package/dist/emoji.js +3 -3
  55. package/dist/find.cjs +7 -7
  56. package/dist/find.js +3 -3
  57. package/dist/headless.cjs +11 -31
  58. package/dist/headless.d.cts +4 -41
  59. package/dist/headless.d.ts +4 -41
  60. package/dist/headless.js +1 -1
  61. package/dist/highlight.cjs +3 -3
  62. package/dist/highlight.js +2 -2
  63. package/dist/index.cjs +23 -43
  64. package/dist/index.d.cts +1 -1
  65. package/dist/index.d.ts +1 -1
  66. package/dist/index.js +2 -2
  67. package/dist/math.cjs +6 -6
  68. package/dist/math.js +4 -4
  69. package/dist/mention.cjs +6 -6
  70. package/dist/mention.js +4 -4
  71. package/dist/presence.cjs +12 -12
  72. package/dist/presence.js +3 -3
  73. package/dist/source.cjs +2 -2
  74. package/dist/source.js +2 -2
  75. package/dist/stats.cjs +6 -6
  76. package/dist/stats.js +3 -3
  77. package/dist/styles.css +2 -2
  78. package/dist/table.cjs +22 -22
  79. package/dist/table.js +3 -3
  80. package/dist/toc.cjs +6 -6
  81. package/dist/toc.js +3 -3
  82. package/package.json +1 -1
  83. package/dist/chunk-MRHDPXQ7.js.map +0 -1
  84. package/dist/chunk-MSWA5ZZM.js.map +0 -1
  85. package/dist/chunk-VWYPO6SX.js.map +0 -1
  86. package/dist/chunk-Y4EJ6UBV.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkP6HC7RUN_cjs = require('./chunk-P6HC7RUN.cjs');
3
+ var chunkZ6LAARPB_cjs = require('./chunk-Z6LAARPB.cjs');
4
4
  var chunkZWTIRGY5_cjs = require('./chunk-ZWTIRGY5.cjs');
5
5
  var chunkA6PGQVTR_cjs = require('./chunk-A6PGQVTR.cjs');
6
6
  var chunkFK7EBZPX_cjs = require('./chunk-FK7EBZPX.cjs');
@@ -820,7 +820,7 @@ function selectNode(controller, blockId) {
820
820
  const { editor } = controller;
821
821
  const { selection } = editor.state;
822
822
  if (selection?.kind === "node" && selection.block === blockId) return;
823
- chunkP6HC7RUN_cjs.dispatchSelection(controller, chunkFK7EBZPX_cjs.nodeSelection(blockId));
823
+ chunkZ6LAARPB_cjs.dispatchSelection(controller, chunkFK7EBZPX_cjs.nodeSelection(blockId));
824
824
  }
825
825
  function focusNode(controller, blockId) {
826
826
  selectNode(controller, blockId);
@@ -1526,7 +1526,7 @@ function codeToParagraph(blockId) {
1526
1526
  };
1527
1527
  }
1528
1528
  function leaveCode(controller, blockId, direction, addsLine = false) {
1529
- const moved = chunkP6HC7RUN_cjs.moveToNeighbour(controller, blockId, direction);
1529
+ const moved = chunkZ6LAARPB_cjs.moveToNeighbour(controller, blockId, direction);
1530
1530
  if (!moved && !(addsLine && controller.run(insertBlocks([{ type: "MARKDOWN" }], "text", blockId)))) return false;
1531
1531
  controller.focus();
1532
1532
  return true;
@@ -1638,7 +1638,7 @@ function revealCaret(area, drawn, mark) {
1638
1638
  const left = atLineStart ? null : caretLeft(drawn, caret);
1639
1639
  mark.style.top = `${(parseFloat(style.paddingTop) || 0) + line * (parseFloat(style.lineHeight) || 0)}px`;
1640
1640
  mark.style.left = `${left ?? 0}px`;
1641
- mark.scrollIntoView({ block: "nearest", inline: "nearest" });
1641
+ mark.scrollIntoView?.({ block: "nearest", inline: "nearest" });
1642
1642
  }
1643
1643
 
1644
1644
  // src/blocks/code/run-code-action.ts
@@ -1651,7 +1651,7 @@ function travel({ controller, blockId, area }, command) {
1651
1651
  const before = area.value;
1652
1652
  controller.run(command);
1653
1653
  const { selection } = controller.editor.state;
1654
- const edit2 = chunkP6HC7RUN_cjs.textDiff(before, area.value);
1654
+ const edit2 = chunkZ6LAARPB_cjs.textDiff(before, area.value);
1655
1655
  if (selection?.kind !== "node" || selection.block !== blockId) controller.focus();
1656
1656
  else if (edit2 !== null) area.setSelectionRange(edit2.from + edit2.insert.length, edit2.from + edit2.insert.length);
1657
1657
  return true;
@@ -1736,11 +1736,11 @@ function CodeEditor({ block, controller, field, focusControls }) {
1736
1736
  useTypeIntoCode(controller, blockId, field, edit2);
1737
1737
  const onKeyDown = (event) => {
1738
1738
  const area = event.currentTarget;
1739
- if (chunkP6HC7RUN_cjs.isComposingKey(controller, event.nativeEvent)) return;
1739
+ if (chunkZ6LAARPB_cjs.isComposingKey(controller, event.nativeEvent)) return;
1740
1740
  const action = codeKeyAction(event, fieldOf(area), controller.isMac);
1741
1741
  if (action !== null && runCodeAction(action, { controller, blockId, area, edit: edit2, focusControls })) event.preventDefault();
1742
1742
  };
1743
- return /* @__PURE__ */ jsxRuntime.jsx("div", { ...{ [chunkP6HC7RUN_cjs.NATIVE_INTERACTION]: "" }, dir: "ltr", className: "quoin-code-scroll", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "quoin-code-lines", children: [
1743
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ...{ [chunkZ6LAARPB_cjs.NATIVE_INTERACTION]: "" }, dir: "ltr", className: "quoin-code-scroll", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "quoin-code-lines", children: [
1744
1744
  /* @__PURE__ */ jsxRuntime.jsx(
1745
1745
  HighlightOverlay,
1746
1746
  {
@@ -1810,7 +1810,7 @@ var Button = React7__namespace.forwardRef(function Button2({ className, variant
1810
1810
  var COPIED_FOR_MS = 1500;
1811
1811
  function CopyCodeButton({ code, controller }) {
1812
1812
  const labels = useLabels();
1813
- const readOnly = chunkP6HC7RUN_cjs.useReadOnly(controller);
1813
+ const readOnly = chunkZ6LAARPB_cjs.useReadOnly(controller);
1814
1814
  const [copied, setCopied] = React7.useState(false);
1815
1815
  React7.useEffect(() => {
1816
1816
  if (!copied) return;
@@ -1893,7 +1893,7 @@ var preventDefault = (event) => event.preventDefault();
1893
1893
 
1894
1894
  // src/blocks/text/set-block-attrs.ts
1895
1895
  function setBlockAttrs(controller, blockId, patch) {
1896
- if (!controller.readOnly) controller.run(chunkP6HC7RUN_cjs.onBlock(blockId, chunkFK7EBZPX_cjs.setAttrs(patch)));
1896
+ if (!controller.readOnly) controller.run(chunkZ6LAARPB_cjs.onBlock(blockId, chunkFK7EBZPX_cjs.setAttrs(patch)));
1897
1897
  }
1898
1898
  var FIELD = `quoin-code-language quoin-code-control ${FOCUS_RING}`;
1899
1899
  var CONTENT = `${MENU_CONTENT} flex max-h-64 w-48 flex-col overflow-y-hidden`;
@@ -1909,8 +1909,8 @@ function LanguageCombobox({ blockId, controller, language: language2, field, onD
1909
1909
  const options = draft === null ? [] : languageOptions(draft === shown ? "" : draft, labels.plainText);
1910
1910
  const open = options.length > 0;
1911
1911
  const optionId = (index) => `${listboxId}-${index}`;
1912
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(() => {
1913
- list.current?.querySelector('[aria-selected="true"]')?.scrollIntoView({ block: "nearest" });
1912
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(() => {
1913
+ list.current?.querySelector('[aria-selected="true"]')?.scrollIntoView?.({ block: "nearest" });
1914
1914
  }, [active]);
1915
1915
  const close = () => {
1916
1916
  setDraft(null);
@@ -1935,7 +1935,7 @@ function LanguageCombobox({ blockId, controller, language: language2, field, onD
1935
1935
  onDone();
1936
1936
  };
1937
1937
  const onKeyDown = (event) => {
1938
- if (chunkP6HC7RUN_cjs.isComposingKey(controller, event.nativeEvent)) return;
1938
+ if (chunkZ6LAARPB_cjs.isComposingKey(controller, event.nativeEvent)) return;
1939
1939
  if (event.key === "ArrowDown" || event.key === "ArrowUp") {
1940
1940
  event.preventDefault();
1941
1941
  const step = event.key === "ArrowDown" ? 1 : -1;
@@ -2009,7 +2009,7 @@ function LanguageCombobox({ blockId, controller, language: language2, field, onD
2009
2009
  }
2010
2010
  var CodeBlock = ({ block, controller }) => {
2011
2011
  const labels = useLabels();
2012
- const readOnly = chunkP6HC7RUN_cjs.useReadOnly(controller);
2012
+ const readOnly = chunkZ6LAARPB_cjs.useReadOnly(controller);
2013
2013
  const languageField = React7.useRef(null);
2014
2014
  const codeField = React7.useRef(null);
2015
2015
  const code = chunkI7X7B3WD_cjs.str(block.attrs.code);
@@ -2111,7 +2111,7 @@ function selectHandlers(controller, blockId, root, onSelect) {
2111
2111
  return {
2112
2112
  onKeyDown(event) {
2113
2113
  const key = event.nativeEvent;
2114
- if (chunkP6HC7RUN_cjs.isComposingKey(controller, key)) return;
2114
+ if (chunkZ6LAARPB_cjs.isComposingKey(controller, key)) return;
2115
2115
  if (event.key === "Escape") select();
2116
2116
  else if (!(event.metaKey || event.ctrlKey) || event.target.matches("input:not([type=file])") || !controller.edit(() => controller.editor.handleKey(key)))
2117
2117
  return;
@@ -2333,7 +2333,7 @@ var uploadFile = (controller, blockId, file, host) => uploadInto(
2333
2333
  var anyFile = () => true;
2334
2334
  var FileBlock = ({ block, controller }) => {
2335
2335
  const labels = useLabels();
2336
- const readOnly = chunkP6HC7RUN_cjs.useReadOnly(controller);
2336
+ const readOnly = chunkZ6LAARPB_cjs.useReadOnly(controller);
2337
2337
  const root = React7.useRef(null);
2338
2338
  const filled = hasFile(block.attrs);
2339
2339
  useNodeKeys(controller, block.id, !readOnly, !filled, root);
@@ -2485,7 +2485,7 @@ function useRovingFocus() {
2485
2485
  },
2486
2486
  [syncTabStop]
2487
2487
  );
2488
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(syncTabStop);
2488
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(syncTabStop);
2489
2489
  const onFocus = (event) => {
2490
2490
  if (!owns(event.target)) return;
2491
2491
  current.current = event.target;
@@ -2504,7 +2504,7 @@ function useRovingFocus() {
2504
2504
  // src/menus/floating/use-focus-key.ts
2505
2505
  var isFocusKey = (event) => event.key === "F10" && event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey;
2506
2506
  function useFocusKey(controller, focus) {
2507
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(() => {
2507
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(() => {
2508
2508
  const intercept = (event) => {
2509
2509
  if (!isFocusKey(event)) return false;
2510
2510
  event.preventDefault();
@@ -2516,11 +2516,11 @@ function useFocusKey(controller, focus) {
2516
2516
  }
2517
2517
  function NodeToolbar(props) {
2518
2518
  const { blockId, controller, label, anchor, items, next, buttonRefs, children, popover } = props;
2519
- const state = chunkP6HC7RUN_cjs.useEditorState(controller, chunkP6HC7RUN_cjs.wholeState);
2519
+ const state = chunkZ6LAARPB_cjs.useEditorState(controller, chunkZ6LAARPB_cjs.wholeState);
2520
2520
  const roving = useRovingFocus();
2521
2521
  useFocusKey(controller, roving.focusCurrent);
2522
2522
  const onKeyDown = (event) => {
2523
- if (!roving.owns(event.target) || chunkP6HC7RUN_cjs.isComposingKey(controller, event.nativeEvent)) return;
2523
+ if (!roving.owns(event.target) || chunkZ6LAARPB_cjs.isComposingKey(controller, event.nativeEvent)) return;
2524
2524
  const tab = event.key === "Tab" && !event.altKey && !event.ctrlKey && !event.metaKey;
2525
2525
  const ahead = tab && !event.shiftKey && next !== void 0 ? blockPart(controller, blockId, next) : void 0;
2526
2526
  if (ahead !== void 0) ahead.focus();
@@ -2601,8 +2601,8 @@ var selectedBlock = (type, filled) => ({ doc, selection }) => {
2601
2601
  return block?.type === type && filled(block.attrs) ? block.id : null;
2602
2602
  };
2603
2603
  function useToolbarBlock(controller, selected, keptFor = null) {
2604
- const blockId = chunkP6HC7RUN_cjs.useEditorState(controller, selected);
2605
- const readOnly = chunkP6HC7RUN_cjs.useReadOnly(controller);
2604
+ const blockId = chunkZ6LAARPB_cjs.useEditorState(controller, selected);
2605
+ const readOnly = chunkZ6LAARPB_cjs.useReadOnly(controller);
2606
2606
  const settled = useSelectionSettled(controller);
2607
2607
  return blockId !== null && !readOnly && (settled || keptFor === blockId) ? blockId : null;
2608
2608
  }
@@ -2681,7 +2681,7 @@ function ResizeHandles({ blockId, controller, frame, percent, centred, onPreview
2681
2681
  const value = percent ?? drawn;
2682
2682
  const write = (widthPercent) => setBlockAttrs(controller, blockId, { widthPercent });
2683
2683
  const onKeyDown = (event) => {
2684
- if (chunkP6HC7RUN_cjs.isComposingKey(controller, event.nativeEvent)) return;
2684
+ if (chunkZ6LAARPB_cjs.isComposingKey(controller, event.nativeEvent)) return;
2685
2685
  const next = keyedWidth(event.key, value);
2686
2686
  if (event.key === "Escape") controller.focus();
2687
2687
  else if (next === null) return;
@@ -2723,7 +2723,7 @@ function ResizeHandles({ blockId, controller, frame, percent, centred, onPreview
2723
2723
  "aria-valuetext": labels.widthValue(value),
2724
2724
  "data-side": side,
2725
2725
  className: "quoin-image-handle",
2726
- ...{ [chunkP6HC7RUN_cjs.NATIVE_INTERACTION]: "" },
2726
+ ...{ [chunkZ6LAARPB_cjs.NATIVE_INTERACTION]: "" },
2727
2727
  ...bubblePart(controller),
2728
2728
  onKeyDown,
2729
2729
  onPointerDown: onPointerDown(side),
@@ -2796,7 +2796,7 @@ function ImageFigure({ block, controller, readOnly }) {
2796
2796
  )
2797
2797
  ] }),
2798
2798
  (!readOnly || (regions.caption?.length ?? 0) > 0) && /* @__PURE__ */ jsxRuntime.jsx(
2799
- chunkP6HC7RUN_cjs.EditableRegion,
2799
+ chunkZ6LAARPB_cjs.EditableRegion,
2800
2800
  {
2801
2801
  block: id,
2802
2802
  region: "caption",
@@ -2959,7 +2959,7 @@ function useImageKeys(controller, blockId, picture, editable, root) {
2959
2959
  }
2960
2960
  var ImageBlock = ({ block, controller }) => {
2961
2961
  const labels = useLabels();
2962
- const readOnly = chunkP6HC7RUN_cjs.useReadOnly(controller);
2962
+ const readOnly = chunkZ6LAARPB_cjs.useReadOnly(controller);
2963
2963
  const root = React7.useRef(null);
2964
2964
  const picture = hasPicture(block.attrs);
2965
2965
  useImageKeys(controller, block.id, picture, !readOnly, root);
@@ -2972,17 +2972,17 @@ var ImageBlock = ({ block, controller }) => {
2972
2972
  "aria-label": labels.blockNames.image,
2973
2973
  contentEditable: false,
2974
2974
  className: "quoin-image",
2975
- ...picture ? { [chunkP6HC7RUN_cjs.NODE_ENTRY]: "" } : void 0,
2975
+ ...picture ? { [chunkZ6LAARPB_cjs.NODE_ENTRY]: "" } : void 0,
2976
2976
  children: picture ? /* @__PURE__ */ jsxRuntime.jsx(ImageFigure, { block, controller, readOnly }) : empty
2977
2977
  }
2978
2978
  );
2979
2979
  };
2980
2980
  function useOutsidePress(element, ownerDocument, onPress) {
2981
2981
  const latest = React7.useRef(onPress);
2982
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(() => {
2982
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(() => {
2983
2983
  latest.current = onPress;
2984
2984
  });
2985
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(() => {
2985
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(() => {
2986
2986
  const doc = ownerDocument();
2987
2987
  const inside = (target) => element.current?.contains(target) === true;
2988
2988
  let touched = null;
@@ -2997,7 +2997,7 @@ function useOutsidePress(element, ownerDocument, onPress) {
2997
2997
  if (touched !== null && !inside(event.target)) latest.current(touched);
2998
2998
  touched = null;
2999
2999
  };
3000
- return chunkP6HC7RUN_cjs.listen(doc, { pointerdown: down, click }, true);
3000
+ return chunkZ6LAARPB_cjs.listen(doc, { pointerdown: down, click }, true);
3001
3001
  }, [element, ownerDocument]);
3002
3002
  }
3003
3003
  function storeAlt(controller, blockId, opened, patch) {
@@ -3005,7 +3005,7 @@ function storeAlt(controller, blockId, opened, patch) {
3005
3005
  const attrs = chunkI7X7B3WD_cjs.blockById(editor.state.doc, blockId)?.attrs ?? {};
3006
3006
  const changed = chunkI7X7B3WD_cjs.str(attrs.alt) !== opened.alt || attrs.decorative === true !== opened.decorative;
3007
3007
  if (controller.readOnly || controller.root === null || changed) return;
3008
- chunkP6HC7RUN_cjs.onBlock(blockId, chunkFK7EBZPX_cjs.setAttrs(patch))(editor.state, (tr) => editor.dispatch(tr));
3008
+ chunkZ6LAARPB_cjs.onBlock(blockId, chunkFK7EBZPX_cjs.setAttrs(patch))(editor.state, (tr) => editor.dispatch(tr));
3009
3009
  }
3010
3010
  function AltTextPopover({ blockId, controller, anchor, opener, alt, decorative, onClose }) {
3011
3011
  const labels = useLabels();
@@ -3047,7 +3047,7 @@ function AltTextPopover({ blockId, controller, anchor, opener, alt, decorative,
3047
3047
  close(true);
3048
3048
  };
3049
3049
  const onKeyDown = (event) => {
3050
- if (event.key !== "Tab" || chunkP6HC7RUN_cjs.isComposingKey(controller, event.nativeEvent)) return;
3050
+ if (event.key !== "Tab" || chunkZ6LAARPB_cjs.isComposingKey(controller, event.nativeEvent)) return;
3051
3051
  const controls = [...event.currentTarget.elements];
3052
3052
  const next = controls[controls.indexOf(event.target) + (event.shiftKey ? -1 : 1)];
3053
3053
  event.preventDefault();
@@ -3075,7 +3075,7 @@ function AltTextPopover({ blockId, controller, anchor, opener, alt, decorative,
3075
3075
  onCloseAutoFocus: preventDefault,
3076
3076
  onEscapeKeyDown: (event) => {
3077
3077
  event.preventDefault();
3078
- if (!chunkP6HC7RUN_cjs.isComposingKey(controller, event)) close(false);
3078
+ if (!chunkZ6LAARPB_cjs.isComposingKey(controller, event)) close(false);
3079
3079
  },
3080
3080
  ...bubblePart(controller),
3081
3081
  children: /* @__PURE__ */ jsxRuntime.jsxs("form", { noValidate: true, className: "quoin-image-alt", onSubmit: save, onKeyDown, children: [
@@ -3171,7 +3171,7 @@ function ImageToolbarOverlay({ controller }) {
3171
3171
  }
3172
3172
  function ImageToolbar({ blockId, controller, editingAlt, onEditAlt }) {
3173
3173
  const { labels, resolveAssetUrl } = useQuoin();
3174
- const state = chunkP6HC7RUN_cjs.useEditorState(controller, chunkP6HC7RUN_cjs.wholeState);
3174
+ const state = chunkZ6LAARPB_cjs.useEditorState(controller, chunkZ6LAARPB_cjs.wholeState);
3175
3175
  const picker = useReplacePicker(controller, blockId, uploadImage, "image/*");
3176
3176
  const altButton = React7.useRef(null);
3177
3177
  const anchor = usePartAnchor(controller, blockId, ".quoin-image-frame");
@@ -3403,13 +3403,13 @@ function CalloutToneMenu({ blockId, controller, tone }) {
3403
3403
  }
3404
3404
  var CalloutBlock = ({ block, controller }) => {
3405
3405
  const labels = useLabels();
3406
- const readOnly = chunkP6HC7RUN_cjs.useReadOnly(controller);
3406
+ const readOnly = chunkZ6LAARPB_cjs.useReadOnly(controller);
3407
3407
  const tone = calloutTone(block.attrs.tone);
3408
3408
  const icon = calloutIcon(block.attrs, tone);
3409
3409
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("quoin-callout group/callout flex items-start gap-2", TONE[tone]), "data-tone": tone, children: [
3410
3410
  readOnly ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "flex size-6 items-center justify-center text-base", children: icon }) : /* @__PURE__ */ jsxRuntime.jsx(CalloutIconMenu, { blockId: block.id, controller, icon }),
3411
3411
  /* @__PURE__ */ jsxRuntime.jsx(
3412
- chunkP6HC7RUN_cjs.EditableRegion,
3412
+ chunkZ6LAARPB_cjs.EditableRegion,
3413
3413
  {
3414
3414
  block: block.id,
3415
3415
  region: "body",
@@ -3478,22 +3478,22 @@ var headingStyles = (level) => `quoin-heading mb-1 font-semibold leading-tight i
3478
3478
  function Heading({ block }) {
3479
3479
  const labels = useLabels();
3480
3480
  const level = chunkI7X7B3WD_cjs.headingLevel(block.attrs.level);
3481
- return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "heading", "aria-level": level, className: headingStyles(level), children: /* @__PURE__ */ jsxRuntime.jsx(chunkP6HC7RUN_cjs.EditableRegion, { block: block.id, region: REGION, label: labels.heading(level) }) });
3481
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "heading", "aria-level": level, className: headingStyles(level), children: /* @__PURE__ */ jsxRuntime.jsx(chunkZ6LAARPB_cjs.EditableRegion, { block: block.id, region: REGION, label: labels.heading(level) }) });
3482
3482
  }
3483
3483
  function NumberedItem({ block, controller }) {
3484
3484
  const labels = useLabels();
3485
- const number = chunkP6HC7RUN_cjs.useOrderedNumber(controller, block.id);
3485
+ const number = chunkZ6LAARPB_cjs.useOrderedNumber(controller, block.id);
3486
3486
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "quoin-list-item", "data-list": "ordered", children: [
3487
3487
  /* @__PURE__ */ jsxRuntime.jsx(ListMarker, { list: "ordered", number, depth: block.indent }),
3488
- /* @__PURE__ */ jsxRuntime.jsx(chunkP6HC7RUN_cjs.EditableRegion, { block: block.id, region: REGION, label: labels.numberedItem(number) })
3488
+ /* @__PURE__ */ jsxRuntime.jsx(chunkZ6LAARPB_cjs.EditableRegion, { block: block.id, region: REGION, label: labels.numberedItem(number) })
3489
3489
  ] });
3490
3490
  }
3491
3491
  function TaskItem({ block, controller }) {
3492
3492
  const labels = useLabels();
3493
- const hostId = chunkP6HC7RUN_cjs.useRegionDomId(block.id, REGION);
3493
+ const hostId = chunkZ6LAARPB_cjs.useRegionDomId(block.id, REGION);
3494
3494
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "quoin-task", "data-checked": block.attrs.checked === true, children: [
3495
- /* @__PURE__ */ jsxRuntime.jsx(chunkP6HC7RUN_cjs.TaskCheckbox, { block, controller, label: labels.task, labelledBy: hostId }),
3496
- /* @__PURE__ */ jsxRuntime.jsx(chunkP6HC7RUN_cjs.EditableRegion, { id: hostId, block: block.id, region: REGION, label: labels.task })
3495
+ /* @__PURE__ */ jsxRuntime.jsx(chunkZ6LAARPB_cjs.TaskCheckbox, { block, controller, label: labels.task, labelledBy: hostId }),
3496
+ /* @__PURE__ */ jsxRuntime.jsx(chunkZ6LAARPB_cjs.EditableRegion, { id: hostId, block: block.id, region: REGION, label: labels.task })
3497
3497
  ] });
3498
3498
  }
3499
3499
  var MarkdownBlock = (props) => {
@@ -3505,16 +3505,16 @@ var MarkdownBlock = (props) => {
3505
3505
  case "bullet":
3506
3506
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "quoin-list-item", "data-list": "bullet", children: [
3507
3507
  /* @__PURE__ */ jsxRuntime.jsx(ListMarker, { list: "bullet", depth: block.indent }),
3508
- /* @__PURE__ */ jsxRuntime.jsx(chunkP6HC7RUN_cjs.EditableRegion, { block: block.id, region: REGION, label: labels.bulletItem })
3508
+ /* @__PURE__ */ jsxRuntime.jsx(chunkZ6LAARPB_cjs.EditableRegion, { block: block.id, region: REGION, label: labels.bulletItem })
3509
3509
  ] });
3510
3510
  case "ordered":
3511
3511
  return /* @__PURE__ */ jsxRuntime.jsx(NumberedItem, { ...props });
3512
3512
  case "task":
3513
3513
  return /* @__PURE__ */ jsxRuntime.jsx(TaskItem, { ...props });
3514
3514
  case "quote":
3515
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "quoin-quote", children: /* @__PURE__ */ jsxRuntime.jsx(chunkP6HC7RUN_cjs.EditableRegion, { block: block.id, region: REGION, label: labels.quote }) });
3515
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "quoin-quote", children: /* @__PURE__ */ jsxRuntime.jsx(chunkZ6LAARPB_cjs.EditableRegion, { block: block.id, region: REGION, label: labels.quote }) });
3516
3516
  default:
3517
- return /* @__PURE__ */ jsxRuntime.jsx(chunkP6HC7RUN_cjs.EditableRegion, { block: block.id, region: REGION, label: labels.paragraph });
3517
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkZ6LAARPB_cjs.EditableRegion, { block: block.id, region: REGION, label: labels.paragraph });
3518
3518
  }
3519
3519
  };
3520
3520
 
@@ -3525,16 +3525,16 @@ function nestedBlockIds({ doc }, blockId) {
3525
3525
  return doc.blocks.slice(index + 1, chunkFK7EBZPX_cjs.descendantsEnd(doc, index)).map((block) => block.id);
3526
3526
  }
3527
3527
  function useNestedBlocks(controller, blockId) {
3528
- return chunkP6HC7RUN_cjs.useEditorState(controller, (state) => nestedBlockIds(state, blockId), chunkI7X7B3WD_cjs.sameItems);
3528
+ return chunkZ6LAARPB_cjs.useEditorState(controller, (state) => nestedBlockIds(state, blockId), chunkI7X7B3WD_cjs.sameItems);
3529
3529
  }
3530
3530
  var ToggleBlock = ({ block, controller }) => {
3531
3531
  const labels = useLabels();
3532
- const domId = chunkP6HC7RUN_cjs.useBlockDomId();
3532
+ const domId = chunkZ6LAARPB_cjs.useBlockDomId();
3533
3533
  const nested = useNestedBlocks(controller, block.id);
3534
- const open = chunkP6HC7RUN_cjs.useToggleOpen(controller, block);
3534
+ const open = chunkZ6LAARPB_cjs.useToggleOpen(controller, block);
3535
3535
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "quoin-toggle", "data-open": open, children: [
3536
3536
  /* @__PURE__ */ jsxRuntime.jsx(
3537
- chunkP6HC7RUN_cjs.ToggleChevron,
3537
+ chunkZ6LAARPB_cjs.ToggleChevron,
3538
3538
  {
3539
3539
  block,
3540
3540
  controller,
@@ -3542,7 +3542,7 @@ var ToggleBlock = ({ block, controller }) => {
3542
3542
  controls: nested.length === 0 ? void 0 : nested.map(domId).join(" ")
3543
3543
  }
3544
3544
  ),
3545
- /* @__PURE__ */ jsxRuntime.jsx(chunkP6HC7RUN_cjs.EditableRegion, { block: block.id, region: "text", label: labels.toggle })
3545
+ /* @__PURE__ */ jsxRuntime.jsx(chunkZ6LAARPB_cjs.EditableRegion, { block: block.id, region: "text", label: labels.toggle })
3546
3546
  ] });
3547
3547
  };
3548
3548
 
@@ -3573,6 +3573,7 @@ function drawnInPlace(definitions, type) {
3573
3573
  }
3574
3574
  var drawsType = (definitions, type) => !Object.hasOwn(inPlaceRenderers, type) || chunkA6PGQVTR_cjs.blockByType(definitions, type) !== void 0;
3575
3575
  var opensEditor = (definitions, type) => drawnInPlace(definitions, type) || !drawnAsText(definitions, type, false) && chunkA6PGQVTR_cjs.blockByType(definitions, type)?.editor !== void 0;
3576
+ var definedWithoutEditor = (definitions) => Object.keys(inPlaceRenderers).filter((type) => hostDefines(definitions, type) && !opensEditor(definitions, type));
3576
3577
 
3577
3578
  // src/gutter/turn-into-targets.ts
3578
3579
  var HEADING_ICONS = [Heading1, Heading2, Heading3];
@@ -3638,7 +3639,7 @@ function ActionItem({ kit, controller, action, blockIds }) {
3638
3639
  );
3639
3640
  }
3640
3641
  function BlockMenuItems({ kit, controller, blocks, styled, title, actions }) {
3641
- const state = chunkP6HC7RUN_cjs.useEditorState(controller, chunkP6HC7RUN_cjs.wholeState);
3642
+ const state = chunkZ6LAARPB_cjs.useEditorState(controller, chunkZ6LAARPB_cjs.wholeState);
3642
3643
  const blockIds = blocks.map((block) => block.id);
3643
3644
  const shown = actions.filter((action) => action.available?.(state, blockIds) ?? true);
3644
3645
  const anyText = styled.some((block) => chunkFK7EBZPX_cjs.isTextFlow(state.schema, block));
@@ -3683,7 +3684,7 @@ var CONTEXT_KIT = {
3683
3684
  SubTrigger: ContextMenuSubTrigger
3684
3685
  };
3685
3686
  var GUTTER_BLOCK = "data-quoin-gutter-block";
3686
- var OWN_MENU = `[${chunkP6HC7RUN_cjs.NATIVE_INTERACTION}], input, textarea, select`;
3687
+ var OWN_MENU = `[${chunkZ6LAARPB_cjs.NATIVE_INTERACTION}], input, textarea, select`;
3687
3688
  function contextBlock(controller, target) {
3688
3689
  const { state } = controller.editor;
3689
3690
  const gutter = target.closest(`[${GUTTER_BLOCK}]`)?.getAttribute(GUTTER_BLOCK);
@@ -3712,7 +3713,7 @@ function useContextMenuOpener(controller, store, trigger) {
3712
3713
  openBlockMenuAt(store, controller.editor.state, block, clientX, clientY);
3713
3714
  hidden.dispatchEvent(new MouseEvent("contextmenu", { bubbles: true, cancelable: true, clientX, clientY }));
3714
3715
  };
3715
- return chunkP6HC7RUN_cjs.listen(root, { mousedown: onMouseDown, contextmenu: onContextMenu });
3716
+ return chunkZ6LAARPB_cjs.listen(root, { mousedown: onMouseDown, contextmenu: onContextMenu });
3716
3717
  }, [controller, store, trigger]);
3717
3718
  }
3718
3719
 
@@ -3748,7 +3749,7 @@ function useLiveBlocks(controller, blockIds) {
3748
3749
  (state) => blockIds.flatMap((id) => chunkI7X7B3WD_cjs.blockById(state.doc, id) ?? []),
3749
3750
  [blockIds]
3750
3751
  );
3751
- return chunkP6HC7RUN_cjs.useEditorState(controller, select, chunkI7X7B3WD_cjs.sameItems);
3752
+ return chunkZ6LAARPB_cjs.useEditorState(controller, select, chunkI7X7B3WD_cjs.sameItems);
3752
3753
  }
3753
3754
  function useMenuBlocks(controller, store, menu) {
3754
3755
  const labels = useLabels();
@@ -3875,7 +3876,7 @@ var DragOverlay = React7.forwardRef(function DragOverlay2(_props, ref) {
3875
3876
  var DELETION_STEPS = /* @__PURE__ */ new Set(["removeBlocks", "setIndent"]);
3876
3877
  function drawnPosition(doc, blockId) {
3877
3878
  const index = doc.index.get(blockId) ?? 0;
3878
- return [chunkP6HC7RUN_cjs.drawnBlockCount(doc, 0, index) + 1, chunkP6HC7RUN_cjs.drawnBlockCount(doc)];
3879
+ return [chunkZ6LAARPB_cjs.drawnBlockCount(doc, 0, index) + 1, chunkZ6LAARPB_cjs.drawnBlockCount(doc)];
3879
3880
  }
3880
3881
  function blockMovedMessage(doc, blockId, labels) {
3881
3882
  return labels.blockMoved(...drawnPosition(doc, blockId));
@@ -3891,7 +3892,7 @@ function deletedCount(tr) {
3891
3892
  return tr.steps.reduce((deleted, step, i) => {
3892
3893
  const { index, count } = step.toJSON();
3893
3894
  if (step.stepType !== "removeBlocks" || typeof index !== "number" || typeof count !== "number") return deleted;
3894
- return deleted + chunkP6HC7RUN_cjs.drawnBlockCount(tr.docs[i], index, index + count);
3895
+ return deleted + chunkZ6LAARPB_cjs.drawnBlockCount(tr.docs[i], index, index + count);
3895
3896
  }, 0);
3896
3897
  }
3897
3898
  function insertedBlock(tr) {
@@ -3933,7 +3934,7 @@ function inlineEdges(shell, box, rtl) {
3933
3934
  function measure(controller, root, moved, rtl) {
3934
3935
  const { doc } = controller.editor.state;
3935
3936
  const origin = rootOrigin(root);
3936
- return chunkP6HC7RUN_cjs.visibleBlockIndexes(doc).flatMap((index) => {
3937
+ return chunkZ6LAARPB_cjs.visibleBlockIndexes(doc).flatMap((index) => {
3937
3938
  const { id, indent: indent3 } = doc.blocks[index];
3938
3939
  const shell = controller.blockElement(id);
3939
3940
  if (shell === void 0) return [];
@@ -4008,7 +4009,7 @@ function draggedBlocks(controller, blockId) {
4008
4009
  function followPress(press, root, view) {
4009
4010
  const { controller, store, overlay, handle: handle2, pointerId } = press;
4010
4011
  const doc = view.document;
4011
- const scroll = chunkP6HC7RUN_cjs.createAutoScroll(root, follow, SCROLL_EDGE);
4012
+ const scroll = chunkZ6LAARPB_cjs.createAutoScroll(root, follow, SCROLL_EDGE);
4012
4013
  let pointer = { x: press.x, y: press.y };
4013
4014
  let active = null;
4014
4015
  let unsubscribe = () => {
@@ -4083,9 +4084,9 @@ function followPress(press, root, view) {
4083
4084
  event.stopPropagation();
4084
4085
  finish();
4085
4086
  }
4086
- const unlistenDocument = chunkP6HC7RUN_cjs.listen(doc, { pointermove: onPointerMove, pointerup: onPointerUp, pointercancel: finish });
4087
- const unlistenBlur = chunkP6HC7RUN_cjs.listen(view, { blur: finish });
4088
- const unlistenKeys = chunkP6HC7RUN_cjs.listen(view, { keydown: onKeyDown }, true);
4087
+ const unlistenDocument = chunkZ6LAARPB_cjs.listen(doc, { pointermove: onPointerMove, pointerup: onPointerUp, pointercancel: finish });
4088
+ const unlistenBlur = chunkZ6LAARPB_cjs.listen(view, { blur: finish });
4089
+ const unlistenKeys = chunkZ6LAARPB_cjs.listen(view, { keydown: onKeyDown }, true);
4089
4090
  return finish;
4090
4091
  }
4091
4092
  function pressDragHandle(press) {
@@ -4220,7 +4221,7 @@ function place2(controller, root, gutter, block) {
4220
4221
  gutter.style.visibility = "";
4221
4222
  }
4222
4223
  function useGutterPosition(controller, gutter, block) {
4223
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(() => {
4224
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(() => {
4224
4225
  const element = gutter.current;
4225
4226
  const root = controller.root;
4226
4227
  const view = root?.ownerDocument.defaultView;
@@ -4252,7 +4253,7 @@ function blockAcross(controller, root, y) {
4252
4253
  }
4253
4254
  function useGutterTarget(controller, store, gutter) {
4254
4255
  const hovered = useCanvasUi(store, (state) => state.hoveredBlock);
4255
- const head = chunkP6HC7RUN_cjs.useEditorState(controller, headOf);
4256
+ const head = chunkZ6LAARPB_cjs.useEditorState(controller, headOf);
4256
4257
  const [focusWithin, setFocusWithin] = React7.useState(false);
4257
4258
  React7.useEffect(() => {
4258
4259
  const root = controller.root;
@@ -4270,7 +4271,7 @@ function useGutterTarget(controller, store, gutter) {
4270
4271
  const onFocusIn = () => setFocusWithin(true);
4271
4272
  const onFocusOut = (event) => setFocusWithin(root.contains(event.relatedTarget));
4272
4273
  setFocusWithin(root.contains(root.ownerDocument.activeElement));
4273
- return chunkP6HC7RUN_cjs.listen(root, { pointermove: onPointerMove, pointerleave: onPointerLeave, focusin: onFocusIn, focusout: onFocusOut });
4274
+ return chunkZ6LAARPB_cjs.listen(root, { pointermove: onPointerMove, pointerleave: onPointerLeave, focusin: onFocusIn, focusout: onFocusOut });
4274
4275
  }, [controller, store, gutter]);
4275
4276
  const fallback = focusWithin ? head : null;
4276
4277
  const target = hovered ?? fallback;
@@ -4363,7 +4364,7 @@ function pointInHost(host, { node, offset }) {
4363
4364
  return host.contains(node) ? { node, offset: Math.min(offset, nodeLength(node)) } : null;
4364
4365
  }
4365
4366
  function textRect(host, { from, to }) {
4366
- const map = chunkP6HC7RUN_cjs.domMapOf(host);
4367
+ const map = chunkZ6LAARPB_cjs.domMapOf(host);
4367
4368
  const range = host.ownerDocument.createRange();
4368
4369
  if (map === void 0 || typeof range.getBoundingClientRect !== "function") return null;
4369
4370
  const start = pointInHost(host, map.toDom(from, 1));
@@ -4376,7 +4377,7 @@ function textRect(host, { from, to }) {
4376
4377
  }
4377
4378
  function rangeRect(controller, range) {
4378
4379
  const host = controller.registry.get(range.block, range.region);
4379
- if (host === void 0 || !host.isConnected || controller.composingKey === chunkP6HC7RUN_cjs.hostKey(range.block, range.region)) {
4380
+ if (host === void 0 || !host.isConnected || controller.composingKey === chunkZ6LAARPB_cjs.hostKey(range.block, range.region)) {
4380
4381
  return null;
4381
4382
  }
4382
4383
  const rect = textRect(host, range);
@@ -4417,7 +4418,7 @@ function useSelectionAnchor(controller, state) {
4417
4418
  [controller, state]
4418
4419
  );
4419
4420
  const [side, setSide] = React7.useState("top");
4420
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(() => {
4421
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(() => {
4421
4422
  const rect = selectionRect(controller);
4422
4423
  if (rect) setSide(rect.top < ROOM_ABOVE ? "bottom" : "top");
4423
4424
  }, [controller, state]);
@@ -4499,7 +4500,7 @@ function TurnIntoDropdown({ controller, state }) {
4499
4500
  }
4500
4501
  var DIVIDER = "mx-0.5 h-5 w-px shrink-0 bg-border";
4501
4502
  function BubbleToolbar({ controller, labels, store, extraItems }) {
4502
- const state = chunkP6HC7RUN_cjs.useEditorState(controller, chunkP6HC7RUN_cjs.wholeState);
4503
+ const state = chunkZ6LAARPB_cjs.useEditorState(controller, chunkZ6LAARPB_cjs.wholeState);
4503
4504
  const { anchor, side } = useSelectionAnchor(controller, state);
4504
4505
  const roving = useRovingFocus();
4505
4506
  const items = React7.useMemo(() => bubbleItems(labels, () => store.set({ linkPopover: { open: true } })), [labels, store]);
@@ -4563,8 +4564,8 @@ var useFinePointer = () => useMediaQuery("(pointer: fine)", true);
4563
4564
  // src/menus/bubble/use-bubble-visibility.ts
4564
4565
  var hasTextRange = (state) => state.selection?.kind === "text" && !chunkFK7EBZPX_cjs.isCollapsed(state.selection) && chunkFK7EBZPX_cjs.markRanges(state).length > 0;
4565
4566
  function useBubbleVisibility(controller) {
4566
- const range = chunkP6HC7RUN_cjs.useEditorState(controller, hasTextRange);
4567
- const readOnly = chunkP6HC7RUN_cjs.useReadOnly(controller);
4567
+ const range = chunkZ6LAARPB_cjs.useEditorState(controller, hasTextRange);
4568
+ const readOnly = chunkZ6LAARPB_cjs.useReadOnly(controller);
4568
4569
  const fine = useFinePointer();
4569
4570
  const settled = useSelectionSettled(controller);
4570
4571
  return range && !readOnly && fine && settled;
@@ -4587,7 +4588,7 @@ function bubbleExtension() {
4587
4588
  // src/menus/link/link-at-selection.ts
4588
4589
  function linkAround(state, from, to = from) {
4589
4590
  if (from.block !== to.block || from.region !== to.region) return null;
4590
- const inline = chunkP6HC7RUN_cjs.regionInline(state, from.block, from.region) ?? [];
4591
+ const inline = chunkZ6LAARPB_cjs.regionInline(state, from.block, from.region) ?? [];
4591
4592
  const extent = chunkFK7EBZPX_cjs.markExtent(inline, from.offset, "link");
4592
4593
  if (extent === null || to.offset > extent.to) return null;
4593
4594
  const attrs = chunkI7X7B3WD_cjs.sliceInline(inline, extent.from, extent.to)[0]?.marks.find((mark) => mark.type === "link")?.attrs;
@@ -4610,7 +4611,7 @@ function linkElementAt(controller, target) {
4610
4611
  }
4611
4612
  function linkAtElement(controller, state, element) {
4612
4613
  const host = controller.registry.locate(element);
4613
- const offset = host === null ? null : chunkP6HC7RUN_cjs.domMapOf(host.element)?.fromDom(element, 0) ?? null;
4614
+ const offset = host === null ? null : chunkZ6LAARPB_cjs.domMapOf(host.element)?.fromDom(element, 0) ?? null;
4614
4615
  if (host === null || offset === null) return null;
4615
4616
  return linkAround(state, { block: host.block, region: host.region, offset });
4616
4617
  }
@@ -4663,7 +4664,7 @@ function caretLinkKey(state) {
4663
4664
  return link && [link.range.block, link.range.region, link.range.from, link.href].join("\0");
4664
4665
  }
4665
4666
  function useCaretInLink(controller, delay) {
4666
- const key = chunkP6HC7RUN_cjs.useEditorState(controller, caretLinkKey);
4667
+ const key = chunkZ6LAARPB_cjs.useEditorState(controller, caretLinkKey);
4667
4668
  const settled = useSelectionSettled(controller);
4668
4669
  return useRestedValue(settled ? key : null, delay) !== null;
4669
4670
  }
@@ -4697,7 +4698,7 @@ var URL_LENGTH = 48;
4697
4698
  var CARD = "flex w-auto items-center gap-0.5 py-1 ps-3 pe-1 shadow-md";
4698
4699
  var ADDRESS = "me-1 whitespace-nowrap text-sm text-muted-foreground";
4699
4700
  function LinkCard({ controller, labels, store, cardRef, element, onUnlinked }) {
4700
- const state = chunkP6HC7RUN_cjs.useEditorState(controller, chunkP6HC7RUN_cjs.wholeState);
4701
+ const state = chunkZ6LAARPB_cjs.useEditorState(controller, chunkZ6LAARPB_cjs.wholeState);
4701
4702
  const link = React7.useMemo(
4702
4703
  () => element === null ? linkAtSelection(state) : linkAtElement(controller, state, element),
4703
4704
  [controller, state, element]
@@ -4715,7 +4716,7 @@ function LinkCard({ controller, labels, store, cardRef, element, onUnlinked }) {
4715
4716
  const edit2 = () => {
4716
4717
  if (element !== null) {
4717
4718
  const selection = chunkFK7EBZPX_cjs.textSelection({ block, region, offset: from }, { block, region, offset: to });
4718
- chunkP6HC7RUN_cjs.dispatchSelection(controller, selection);
4719
+ chunkZ6LAARPB_cjs.dispatchSelection(controller, selection);
4719
4720
  }
4720
4721
  store.set({ linkPopover: { open: true } });
4721
4722
  };
@@ -4882,7 +4883,7 @@ function LinkOverlay({ controller }) {
4882
4883
  const labels = useLabels();
4883
4884
  const store = useCanvasUiStore();
4884
4885
  const popoverOpen = useCanvasUi(store, isPopoverOpen);
4885
- const readOnly = chunkP6HC7RUN_cjs.useReadOnly(controller);
4886
+ const readOnly = chunkZ6LAARPB_cjs.useReadOnly(controller);
4886
4887
  useLinkClicks(controller);
4887
4888
  React7.useEffect(() => {
4888
4889
  if (readOnly && store.get().linkPopover.open) store.set({ linkPopover: { open: false } });
@@ -5062,10 +5063,10 @@ function useRangeAnchor(controller, range) {
5062
5063
  const [side, setSide] = React7.useState("bottom");
5063
5064
  const latest = React7.useRef(range);
5064
5065
  const start = range === null ? null : `${range.block} ${range.region} ${range.from}`;
5065
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(() => {
5066
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(() => {
5066
5067
  latest.current = range;
5067
5068
  });
5068
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(() => {
5069
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(() => {
5069
5070
  const rect = latest.current && rangeRect(controller, latest.current);
5070
5071
  if (rect) setSide(sideFor(rect, window.innerHeight));
5071
5072
  }, [controller, start]);
@@ -5091,11 +5092,11 @@ function openCombobox(host, listboxId) {
5091
5092
  }
5092
5093
  function useComboboxHost(controller, block, region, listboxId, activeOptionId) {
5093
5094
  const host = React7.useRef(null);
5094
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(() => {
5095
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(() => {
5095
5096
  host.current = block === null || region === null ? null : controller.registry.get(block, region) ?? null;
5096
5097
  return host.current === null ? void 0 : openCombobox(host.current, listboxId);
5097
5098
  }, [controller, block, region, listboxId]);
5098
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(() => {
5099
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(() => {
5099
5100
  if (host.current !== null) restore(host.current, "aria-activedescendant", activeOptionId);
5100
5101
  }, [block, region, activeOptionId]);
5101
5102
  }
@@ -5141,10 +5142,10 @@ function handle(event, menu) {
5141
5142
  }
5142
5143
  function useSuggestionKeys(controller, open, menu) {
5143
5144
  const latest = React7.useRef(menu);
5144
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(() => {
5145
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(() => {
5145
5146
  latest.current = menu;
5146
5147
  });
5147
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(() => {
5148
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(() => {
5148
5149
  if (!open) return;
5149
5150
  const intercept = (event) => {
5150
5151
  const handled = handle(event, latest.current);
@@ -5165,10 +5166,10 @@ var isPromise = (value) => typeof value?.then === "function";
5165
5166
  function useSuggestionResults(source, query, onError) {
5166
5167
  const [answer, setAnswer] = React7.useState(FORGOTTEN);
5167
5168
  const report = React7.useRef(onError);
5168
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(() => {
5169
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(() => {
5169
5170
  report.current = onError;
5170
5171
  });
5171
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(() => {
5172
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(() => {
5172
5173
  if (query === null) {
5173
5174
  setAnswer(FORGOTTEN);
5174
5175
  return;
@@ -5212,9 +5213,9 @@ function useSuggestion({
5212
5213
  emptyLabel
5213
5214
  }) {
5214
5215
  const { labels, onError } = useQuoin();
5215
- const readOnly = chunkP6HC7RUN_cjs.useReadOnly(controller);
5216
+ const readOnly = chunkZ6LAARPB_cjs.useReadOnly(controller);
5216
5217
  const selectTrigger = React7.useCallback((state) => chunkFK7EBZPX_cjs.getPluginState(state, pluginKey).active, [pluginKey]);
5217
- const active = chunkP6HC7RUN_cjs.useEditorState(controller, selectTrigger);
5218
+ const active = chunkZ6LAARPB_cjs.useEditorState(controller, selectTrigger);
5218
5219
  const trigger = readOnly ? null : active;
5219
5220
  const results = useSuggestionResults(source, trigger?.query ?? null, onError);
5220
5221
  const sections = React7.useMemo(() => groupItems(results.items, groupOf2), [results.items, groupOf2]);
@@ -5284,8 +5285,8 @@ function SuggestionMenu(props) {
5284
5285
  const { trigger, sections, activeIndex, listboxId } = suggestion;
5285
5286
  const { anchor, side } = useRangeAnchor(controller, trigger);
5286
5287
  const listbox = React7.useRef(null);
5287
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(() => {
5288
- listbox.current?.querySelector('[aria-selected="true"]')?.scrollIntoView({ block: "nearest" });
5288
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(() => {
5289
+ listbox.current?.querySelector('[aria-selected="true"]')?.scrollIntoView?.({ block: "nearest" });
5289
5290
  }, [activeIndex, sections]);
5290
5291
  if (trigger === null) return null;
5291
5292
  const inEditor = (node) => node instanceof Node && controller.root?.contains(node) === true;
@@ -5363,7 +5364,7 @@ var TEXT_STEPS = /* @__PURE__ */ new Set(["replaceInline", "addMark", "removeMar
5363
5364
  var WHITESPACE3 = /\s/;
5364
5365
  var changesBlocks = (tr) => tr !== null && tr.steps.some((step) => !TEXT_STEPS.has(step.stepType));
5365
5366
  function withSpaceBefore(state, range) {
5366
- const inline = chunkP6HC7RUN_cjs.regionInline(state, range.block, range.region);
5367
+ const inline = chunkZ6LAARPB_cjs.regionInline(state, range.block, range.region);
5367
5368
  if (inline === void 0 || range.from === 0) return null;
5368
5369
  const text2 = chunkI7X7B3WD_cjs.inlineText(inline);
5369
5370
  const after = text2.charAt(range.to);
@@ -5551,7 +5552,7 @@ function placement(viewport) {
5551
5552
  function EditingTools({ controller }) {
5552
5553
  const labels = useLabels();
5553
5554
  const store = useCanvasUiStore();
5554
- const state = chunkP6HC7RUN_cjs.useEditorState(controller, chunkP6HC7RUN_cjs.wholeState);
5555
+ const state = chunkZ6LAARPB_cjs.useEditorState(controller, chunkZ6LAARPB_cjs.wholeState);
5555
5556
  const viewport = useVisualViewport();
5556
5557
  const roving = useRovingFocus();
5557
5558
  const items = React7.useMemo(() => mobileItems(labels, () => store.set({ linkPopover: { open: true } })), [labels, store]);
@@ -5875,7 +5876,7 @@ function runHistoryKey(controller, event) {
5875
5876
  }
5876
5877
  function useBlockIndex(controller, blockId) {
5877
5878
  const select = React7.useCallback((state) => state.doc.index.get(blockId) ?? -1, [blockId]);
5878
- return chunkP6HC7RUN_cjs.useEditorState(controller, select);
5879
+ return chunkZ6LAARPB_cjs.useEditorState(controller, select);
5879
5880
  }
5880
5881
  var FOCUSABLE = [
5881
5882
  "input:not([disabled])",
@@ -5902,8 +5903,8 @@ function useEditingFocus(root, editing, stop) {
5902
5903
  const leaveUnlessInside = (event) => {
5903
5904
  if (!inside.current.has(event)) stop();
5904
5905
  };
5905
- const unlistenCapture = chunkP6HC7RUN_cjs.listen(doc, { pointerdown: leaveForCanvas }, true);
5906
- const unlisten = chunkP6HC7RUN_cjs.listen(doc, { pointerdown: leaveUnlessInside, focusin: leaveUnlessInside });
5906
+ const unlistenCapture = chunkZ6LAARPB_cjs.listen(doc, { pointerdown: leaveForCanvas }, true);
5907
+ const unlisten = chunkZ6LAARPB_cjs.listen(doc, { pointerdown: leaveUnlessInside, focusin: leaveUnlessInside });
5907
5908
  return () => {
5908
5909
  unlistenCapture();
5909
5910
  unlisten();
@@ -5932,8 +5933,8 @@ function VoidEditor({ Editor, controller, ...props }) {
5932
5933
  }
5933
5934
  function VoidBlock({ block, controller, definition }) {
5934
5935
  const { blockTypes, labels } = useQuoin();
5935
- const { report } = React7.useContext(chunkP6HC7RUN_cjs.BlockErrorContext);
5936
- const readOnly = chunkP6HC7RUN_cjs.useReadOnly(controller);
5936
+ const { report } = React7.useContext(chunkZ6LAARPB_cjs.BlockErrorContext);
5937
+ const readOnly = chunkZ6LAARPB_cjs.useReadOnly(controller);
5937
5938
  const { editor: Editor, alwaysEditing = false } = definition;
5938
5939
  const name = blockTypeLabel(labels, block, blockTypes);
5939
5940
  const blockId = block.id;
@@ -5997,7 +5998,7 @@ function VoidBlock({ block, controller, definition }) {
5997
5998
  role: "group",
5998
5999
  "aria-label": name,
5999
6000
  tabIndex: editorShown ? -1 : void 0,
6000
- ...{ [chunkP6HC7RUN_cjs.NATIVE_INTERACTION]: editorShown ? "" : void 0 },
6001
+ ...{ [chunkZ6LAARPB_cjs.NATIVE_INTERACTION]: editorShown ? "" : void 0 },
6001
6002
  onKeyDown,
6002
6003
  ...focusHandlers,
6003
6004
  onClick,
@@ -6179,7 +6180,7 @@ function revealLinkedBlock(controller, hash) {
6179
6180
  const { editor } = controller;
6180
6181
  const { doc, schema } = editor.state;
6181
6182
  editor.dispatch(editor.createTransaction().setSelection(chunkFK7EBZPX_cjs.startOf(doc, schema, id)));
6182
- shell.scrollIntoView({ block: "center" });
6183
+ shell.scrollIntoView?.({ block: "center" });
6183
6184
  return true;
6184
6185
  }
6185
6186
  function useBlockLinkTarget(controller, focusOnMount) {
@@ -6216,7 +6217,7 @@ function deletions(codec, tr) {
6216
6217
  }
6217
6218
  function useDeleteReporter(controller, onDelete) {
6218
6219
  const latest = React7.useRef(onDelete);
6219
- chunkP6HC7RUN_cjs.useIsomorphicLayoutEffect(() => {
6220
+ chunkZ6LAARPB_cjs.useIsomorphicLayoutEffect(() => {
6220
6221
  latest.current = onDelete;
6221
6222
  });
6222
6223
  React7.useEffect(() => {
@@ -6237,7 +6238,7 @@ function useStructureAnnouncements(controller, labels) {
6237
6238
  });
6238
6239
  }, [controller, labels]);
6239
6240
  }
6240
- function useTypedInPlaceWarning(definitions, readOnly) {
6241
+ function useDefinitionWarnings(definitions, readOnly) {
6241
6242
  React7.useEffect(() => {
6242
6243
  if (readOnly) return;
6243
6244
  for (const type of definedTypedInPlace(definitions)) {
@@ -6245,6 +6246,11 @@ function useTypedInPlaceWarning(definitions, readOnly) {
6245
6246
  `the block type "${type}" has a definition of its own, which only a read-only canvas draws. An editable canvas keeps drawing ${type} blocks itself, since they are typed into in place.`
6246
6247
  );
6247
6248
  }
6249
+ for (const type of definedWithoutEditor(definitions)) {
6250
+ chunkA6PGQVTR_cjs.devWarn(
6251
+ `the block type "${type}" has a definition of its own whose preview replaces the one that edits it, so an editable canvas draws ${type} blocks nobody can write in. Quoin edits ${type} in its preview rather than in an editor: give your definition an editor of its own, or keep Quoin's and draw yours only where the canvas is read-only.`
6252
+ );
6253
+ }
6248
6254
  }, [definitions, readOnly]);
6249
6255
  }
6250
6256
  var GUTTER_ROOM = "ps-12";
@@ -6286,9 +6292,9 @@ var BlockCanvas = React7.forwardRef(function BlockCanvas2({
6286
6292
  () => collectUi(allExtensions, blockTypes, readOnly, () => latestOnError.current),
6287
6293
  [allExtensions, blockTypes, readOnly]
6288
6294
  );
6289
- useTypedInPlaceWarning(blockTypes, readOnly);
6295
+ useDefinitionWarnings(blockTypes, readOnly);
6290
6296
  const [focusOnMount] = React7.useState(autoFocus);
6291
- const controller = chunkP6HC7RUN_cjs.useQuoinEditor({
6297
+ const controller = chunkZ6LAARPB_cjs.useQuoinEditor({
6292
6298
  blocks,
6293
6299
  onChange,
6294
6300
  readOnly,
@@ -6332,7 +6338,7 @@ var BlockCanvas = React7.forwardRef(function BlockCanvas2({
6332
6338
  [controller, resolveAssetUrl]
6333
6339
  );
6334
6340
  return /* @__PURE__ */ jsxRuntime.jsx(QuoinProvider, { value: { blockTypes, upload, resolveAssetUrl, onError, highlight, controller, labels }, children: /* @__PURE__ */ jsxRuntime.jsx(VoidEditingContext.Provider, { value: voidEditing, children: /* @__PURE__ */ jsxRuntime.jsx(SlashItemsProvider, { value: slashItems, children: /* @__PURE__ */ jsxRuntime.jsx(BubbleItemsProvider, { value: ui.bubbleItems, children: /* @__PURE__ */ jsxRuntime.jsx(CanvasUiProvider, { value: uiStore, children: /* @__PURE__ */ jsxRuntime.jsxs(
6335
- chunkP6HC7RUN_cjs.EditorView,
6341
+ chunkZ6LAARPB_cjs.EditorView,
6336
6342
  {
6337
6343
  controller,
6338
6344
  renderers: ui.renderers,