quoin-editor 2.0.3 → 2.0.5

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 (77) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +11 -11
  3. package/dist/ai.cjs +34 -34
  4. package/dist/ai.js +3 -3
  5. package/dist/catalogue.cjs +21 -21
  6. package/dist/catalogue.js +12 -12
  7. package/dist/{chunk-BNTRGV4A.js → chunk-2BPXVQBP.js} +3 -3
  8. package/dist/{chunk-BNTRGV4A.js.map → chunk-2BPXVQBP.js.map} +1 -1
  9. package/dist/{chunk-MGN332NY.cjs → chunk-2QKFRKOP.cjs} +1 -1
  10. package/dist/{chunk-3B5VEXVQ.cjs → chunk-3HW3WRYC.cjs} +2 -2
  11. package/dist/{chunk-5URH2Y2L.cjs → chunk-3INFNIGN.cjs} +19 -19
  12. package/dist/{chunk-WMM56LIB.js → chunk-4G645EYO.js} +3 -3
  13. package/dist/{chunk-WMM56LIB.js.map → chunk-4G645EYO.js.map} +1 -1
  14. package/dist/{chunk-LCGOFL7S.js → chunk-556PFYES.js} +4 -4
  15. package/dist/{chunk-LCGOFL7S.js.map → chunk-556PFYES.js.map} +1 -1
  16. package/dist/{chunk-BCCFJINI.cjs → chunk-7J63427U.cjs} +64 -64
  17. package/dist/{chunk-YHAVXOAA.js → chunk-A2IQHMIH.js} +4 -4
  18. package/dist/{chunk-YHAVXOAA.js.map → chunk-A2IQHMIH.js.map} +1 -1
  19. package/dist/{chunk-VQDQBMQY.js → chunk-AJT54OMZ.js} +4 -4
  20. package/dist/{chunk-VQDQBMQY.js.map → chunk-AJT54OMZ.js.map} +1 -1
  21. package/dist/{chunk-SQHEZ3JY.cjs → chunk-BE2YHZXA.cjs} +2 -2
  22. package/dist/{chunk-DZ5XR4O6.cjs → chunk-EBSDPHPS.cjs} +105 -105
  23. package/dist/{chunk-MDIXI7DM.js → chunk-EIWPJWY3.js} +3 -3
  24. package/dist/{chunk-MDIXI7DM.js.map → chunk-EIWPJWY3.js.map} +1 -1
  25. package/dist/{chunk-C4SRLMQJ.js → chunk-F2ZK6Z52.js} +3 -3
  26. package/dist/{chunk-C4SRLMQJ.js.map → chunk-F2ZK6Z52.js.map} +1 -1
  27. package/dist/{chunk-FGVTDIHT.js → chunk-G6NBQYMM.js} +4 -4
  28. package/dist/chunk-G6NBQYMM.js.map +1 -0
  29. package/dist/{chunk-H3TRVI44.cjs → chunk-JGEDJYIV.cjs} +50 -50
  30. package/dist/{chunk-55MN4QZU.cjs → chunk-JZF6UQH5.cjs} +4 -4
  31. package/dist/{chunk-UWCU6PJY.cjs → chunk-KHRVCTQQ.cjs} +30 -30
  32. package/dist/{chunk-NLRSAOCK.js → chunk-LU3T3JB4.js} +5 -5
  33. package/dist/{chunk-NLRSAOCK.js.map → chunk-LU3T3JB4.js.map} +1 -1
  34. package/dist/{chunk-NAMZA4NW.cjs → chunk-N7BSFDDM.cjs} +14 -14
  35. package/dist/{chunk-YWYTLNAO.js → chunk-NHNW5DK3.js} +4 -4
  36. package/dist/{chunk-YWYTLNAO.js.map → chunk-NHNW5DK3.js.map} +1 -1
  37. package/dist/{chunk-4EJJ4ZNC.cjs → chunk-NUQ64S5B.cjs} +18 -18
  38. package/dist/{chunk-QVWNUUMJ.js → chunk-QLVX7MPS.js} +3 -3
  39. package/dist/{chunk-QVWNUUMJ.js.map → chunk-QLVX7MPS.js.map} +1 -1
  40. package/dist/{chunk-77THE3KY.js → chunk-W376L2GM.js} +5 -5
  41. package/dist/{chunk-77THE3KY.js.map → chunk-W376L2GM.js.map} +1 -1
  42. package/dist/{chunk-OMUXPNCX.cjs → chunk-WDBFGX3U.cjs} +26 -26
  43. package/dist/{chunk-RNYETN6X.js → chunk-XE3IYW5B.js} +4 -4
  44. package/dist/{chunk-RNYETN6X.js.map → chunk-XE3IYW5B.js.map} +1 -1
  45. package/dist/{chunk-SDFJZNYB.cjs → chunk-YYW33WUL.cjs} +3 -3
  46. package/dist/comments.cjs +30 -30
  47. package/dist/comments.js +3 -3
  48. package/dist/diagram.cjs +6 -6
  49. package/dist/diagram.js +3 -3
  50. package/dist/embed.cjs +5 -5
  51. package/dist/embed.js +3 -3
  52. package/dist/emoji.cjs +6 -6
  53. package/dist/emoji.js +3 -3
  54. package/dist/find.cjs +7 -7
  55. package/dist/find.js +3 -3
  56. package/dist/headless.cjs +11 -11
  57. package/dist/headless.js +1 -1
  58. package/dist/highlight.cjs +3 -3
  59. package/dist/highlight.js +2 -2
  60. package/dist/index.cjs +23 -23
  61. package/dist/index.js +2 -2
  62. package/dist/math.cjs +6 -6
  63. package/dist/math.js +4 -4
  64. package/dist/mention.cjs +6 -6
  65. package/dist/mention.js +4 -4
  66. package/dist/presence.cjs +12 -12
  67. package/dist/presence.js +3 -3
  68. package/dist/source.cjs +2 -2
  69. package/dist/source.js +2 -2
  70. package/dist/stats.cjs +6 -6
  71. package/dist/stats.js +3 -3
  72. package/dist/table.cjs +22 -22
  73. package/dist/table.js +3 -3
  74. package/dist/toc.cjs +6 -6
  75. package/dist/toc.js +3 -3
  76. package/package.json +1 -1
  77. package/dist/chunk-FGVTDIHT.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  Every release of `quoin-editor` is listed here, newest first, in the spirit of [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). From 1.0.0 the package follows [semantic versioning](https://semver.org/): a breaking change waits for the next major version. Until then, Quoin was 0.x and a minor version could contain breaking changes; those known at release were marked "Breaking". The 0.x sections are kept as they were released, "Docs" headings included. Moving from 0.4 to 1.0, and from 1.x to 2.0, is covered step by step in [MIGRATION.md](MIGRATION.md). Review finding ids such as F-17 are those of the 0.4.0 review in [#73](https://github.com/AmineSeboui/quoin-editor/issues/73).
4
4
 
5
+ ## 2.0.5 (2026-11-11)
6
+
7
+ ### Changed
8
+ - The guide is at <https://quoincloud.com/docs/editor/> now, beside the documentation for the collaboration server, and the README and every link this package prints point there. The old addresses still answer, with a notice that takes the reader across, so nothing a consumer wrote is broken. Nothing else in this release: the package's code is identical to 2.0.4, and npm serves the README of whichever version was published last, which is the only reason for the version number.
9
+
10
+ ## 2.0.4 (2026-11-10)
11
+
12
+ ### Fixed
13
+ - An upload a host answers with an empty key fails the way one that answers with no key already did, so the block says so rather than sitting empty with nothing reported. The guard asked whether the key was a string, and an empty string is one.
14
+ - A quote block is a `blockquote` in the canvas, as it already was in the HTML the engine renders. It was a `div` whose accessible name said "Quote", so a reader moving by quotation found nothing.
15
+
5
16
  ## 2.0.3 (2026-11-09)
6
17
 
7
18
  ### Fixed
package/README.md CHANGED
@@ -6,7 +6,7 @@ Quoin is a rich markdown editor and block editor for React. Every text block sta
6
6
 
7
7
  [![npm](https://img.shields.io/npm/v/quoin-editor)](https://www.npmjs.com/package/quoin-editor) [![CI](https://github.com/AmineSeboui/quoin-editor/actions/workflows/ci.yml/badge.svg)](https://github.com/AmineSeboui/quoin-editor/actions/workflows/ci.yml) [![licence](https://img.shields.io/npm/l/quoin-editor)](LICENSE)
8
8
 
9
- [Live demo](https://amineseboui.github.io/quoin-editor/) | [Docs](https://amineseboui.github.io/quoin-editor/docs/getting-started/) | [Changelog](CHANGELOG.md)
9
+ [Live demo](https://amineseboui.github.io/quoin-editor/) | [Docs](https://quoincloud.com/docs/editor/getting-started) | [Changelog](CHANGELOG.md)
10
10
 
11
11
  ![A heading typed with a hash and a space, a bulleted list, two words made bold from the toolbar, a callout inserted from the slash menu and dragged into place, while the panel beside shows the markdown onChange hands back](demo/public/quoin-demo.gif)
12
12
 
@@ -14,13 +14,13 @@ Quoin is a rich markdown editor and block editor for React. Every text block sta
14
14
  - **Typed blocks you control like an input.** A document is `QuoinBlock[]`, plain JSON, passed as `blocks` and returned through `onChange`, so saving, versioning and validation stay in your code.
15
15
  - **Notion-style UI included, MIT.** Slash menu, bubble toolbar, block menu, drag handles, a mobile toolbar and a shortcuts dialog, with no account and no paid tier.
16
16
  - **Custom blocks as plain React.** `defineBlock` takes an editor, a preview, or both, as React components; no schema language to learn.
17
- - **Accessible, with tested keyboard and screen reader support.** In CI, axe runs over the canvas and its menus in light and dark mode, a document is written with the keyboard alone, and moves and deletions are announced. [What is not checked yet](https://amineseboui.github.io/quoin-editor/docs/accessibility/#what-is-not-checked-yet).
17
+ - **Accessible, with tested keyboard and screen reader support.** In CI, axe runs over the canvas and its menus in light and dark mode, a document is written with the keyboard alone, and moves and deletions are announced. [What is not checked yet](https://quoincloud.com/docs/editor/accessibility#what-is-not-checked-yet).
18
18
 
19
19
  ## Write together, with AI
20
20
 
21
21
  ![Two editors side by side, Ada and Grace: Ada adds a task while her caret shows in Grace's copy, Grace renames the heading and ticks a task, and Ada drags a block that moves in both](demo/public/quoin-collaboration.gif)
22
22
 
23
- **Real-time collaboration.** Each person sees the other's typing, ticked tasks and moved blocks arrive as they happen, with a named caret showing where they are. Quoin syncs through your own Yjs provider, and comment threads stay anchored to the text they discuss. [Try it live](https://amineseboui.github.io/quoin-editor/collaboration/)
23
+ **Real-time collaboration.** Each person sees the other's typing, ticked tasks and moved blocks arrive as they happen, with a named caret showing where they are. Quoin syncs through your own Yjs provider, and comment threads stay anchored to the text they discuss. [Try it live](https://amineseboui.github.io/quoin-editor/collaboration/), or let [Quoin Cloud](https://quoincloud.com) host the server the provider talks to.
24
24
 
25
25
  ![A draft line with spelling mistakes is selected, Ask AI is opened from the toolbar and Fix spelling and grammar streams a corrected line that is accepted, then Continue writing adds a sentence below](demo/public/quoin-ai.gif)
26
26
 
@@ -124,14 +124,14 @@ Sources, checked on 2026-11-05: Tiptap [persistence][tt-store], [markdown][tt-md
124
124
 
125
125
  ## Learn more
126
126
 
127
- - [The controlled contract](https://amineseboui.github.io/quoin-editor/docs/contract/): loading, autosave, discarding, undoing a deletion
128
- - [Theming](https://amineseboui.github.io/quoin-editor/docs/theming/): `--quoin-` tokens, dark mode, cascade layers, Tailwind
129
- - [Custom blocks](https://amineseboui.github.io/quoin-editor/docs/custom-blocks/) and [uploads](https://amineseboui.github.io/quoin-editor/docs/uploads/)
130
- - [Extensions](https://amineseboui.github.io/quoin-editor/docs/extensions/): every opt-in feature, and writing your own
131
- - [Collaboration](https://amineseboui.github.io/quoin-editor/docs/collaboration/), [comments](https://amineseboui.github.io/quoin-editor/docs/comments/) and [AI](https://amineseboui.github.io/quoin-editor/docs/ai/)
132
- - [Server rendering](https://amineseboui.github.io/quoin-editor/docs/server-rendering/): read-only, `QuoinView`, `QuoinDiff`, `toDocx`
133
- - [Accessibility](https://amineseboui.github.io/quoin-editor/docs/accessibility/): what each test suite checks, and what it does not yet
134
- - [FAQ](https://amineseboui.github.io/quoin-editor/docs/faq/): the package name, stability, React versions, and [upgrading to 2.0](MIGRATION.md#migrating-from-1x-to-20)
127
+ - [The controlled contract](https://quoincloud.com/docs/editor/contract): loading, autosave, discarding, undoing a deletion
128
+ - [Theming](https://quoincloud.com/docs/editor/theming): `--quoin-` tokens, dark mode, cascade layers, Tailwind
129
+ - [Custom blocks](https://quoincloud.com/docs/editor/custom-blocks) and [uploads](https://quoincloud.com/docs/editor/uploads)
130
+ - [Extensions](https://quoincloud.com/docs/editor/extensions): every opt-in feature, and writing your own
131
+ - [Collaboration](https://quoincloud.com/docs/editor/collaboration), [comments](https://quoincloud.com/docs/editor/comments) and [AI](https://quoincloud.com/docs/editor/ai)
132
+ - [Server rendering](https://quoincloud.com/docs/editor/server-rendering): read-only, `QuoinView`, `QuoinDiff`, `toDocx`
133
+ - [Accessibility](https://quoincloud.com/docs/editor/accessibility): what each test suite checks, and what it does not yet
134
+ - [FAQ](https://quoincloud.com/docs/editor/faq): the package name, stability, React versions, and [upgrading to 2.0](MIGRATION.md#migrating-from-1x-to-20)
135
135
 
136
136
  ## Sponsors
137
137
 
package/dist/ai.cjs CHANGED
@@ -2,9 +2,9 @@
2
2
  'use strict';
3
3
 
4
4
  var chunkLE5XMIFJ_cjs = require('./chunk-LE5XMIFJ.cjs');
5
- var chunk3B5VEXVQ_cjs = require('./chunk-3B5VEXVQ.cjs');
6
- var chunkDZ5XR4O6_cjs = require('./chunk-DZ5XR4O6.cjs');
7
- var chunkMGN332NY_cjs = require('./chunk-MGN332NY.cjs');
5
+ var chunk3HW3WRYC_cjs = require('./chunk-3HW3WRYC.cjs');
6
+ var chunkEBSDPHPS_cjs = require('./chunk-EBSDPHPS.cjs');
7
+ var chunk2QKFRKOP_cjs = require('./chunk-2QKFRKOP.cjs');
8
8
  var chunkZWTIRGY5_cjs = require('./chunk-ZWTIRGY5.cjs');
9
9
  require('./chunk-A6PGQVTR.cjs');
10
10
  var chunkFK7EBZPX_cjs = require('./chunk-FK7EBZPX.cjs');
@@ -377,7 +377,7 @@ async function read(editor, link, run, stream, request) {
377
377
  } catch (error) {
378
378
  if (!live()) return;
379
379
  end("error");
380
- link.report(chunkDZ5XR4O6_cjs.toError(error));
380
+ link.report(chunkEBSDPHPS_cjs.toError(error));
381
381
  }
382
382
  }
383
383
  function startStream(editor, link, stream, request, replace) {
@@ -474,7 +474,7 @@ function aiSlashItems(labels, stream) {
474
474
  title: labels.askAi,
475
475
  description: labels.askAiDescription,
476
476
  group: "ai",
477
- icon: chunkDZ5XR4O6_cjs.Sparkles,
477
+ icon: chunkEBSDPHPS_cjs.Sparkles,
478
478
  keywords: KEYWORDS,
479
479
  run: ({ controller }) => void openFor(controller)
480
480
  },
@@ -482,7 +482,7 @@ function aiSlashItems(labels, stream) {
482
482
  id: "ai-continue",
483
483
  title: labels.actions.continue,
484
484
  group: "ai",
485
- icon: chunkDZ5XR4O6_cjs.PenLine,
485
+ icon: chunkEBSDPHPS_cjs.PenLine,
486
486
  keywords: [...KEYWORDS, "continue"],
487
487
  run: ({ controller }) => {
488
488
  if (openFor(controller)) askFrom({ controller, stream}, "continue");
@@ -493,14 +493,14 @@ function aiSlashItems(labels, stream) {
493
493
  var aiBubbleItem = (labels) => ({
494
494
  id: "ai",
495
495
  title: labels.askAi,
496
- icon: chunkDZ5XR4O6_cjs.Sparkles,
496
+ icon: chunkEBSDPHPS_cjs.Sparkles,
497
497
  available: (state) => aiState(state).ghost === null,
498
498
  run: (controller) => void openFor(controller)
499
499
  });
500
500
  var aiBlockMenuItem = (labels) => ({
501
501
  id: "ai",
502
502
  label: labels.askAi,
503
- icon: chunkDZ5XR4O6_cjs.Sparkles,
503
+ icon: chunkEBSDPHPS_cjs.Sparkles,
504
504
  available: (state, blockIds) => targetOfBlocks(state, blockIds) !== null,
505
505
  run: (controller, blockIds) => {
506
506
  const target = targetOfBlocks(controller.editor.state, blockIds);
@@ -605,12 +605,12 @@ function AiBar({ env, ghost, gone, barId }) {
605
605
  const [next, setNext] = react.useState("");
606
606
  const { phase } = ghost;
607
607
  const focusPrimary = () => content.current?.querySelector(`[${PRIMARY}]`)?.focus();
608
- chunkMGN332NY_cjs.useIsomorphicLayoutEffect(() => {
608
+ chunk2QKFRKOP_cjs.useIsomorphicLayoutEffect(() => {
609
609
  const active = content.current?.ownerDocument.activeElement;
610
610
  inside.current = active == null || active === active.ownerDocument.body;
611
611
  if (inside.current) focusPrimary();
612
612
  }, []);
613
- chunkMGN332NY_cjs.useIsomorphicLayoutEffect(() => {
613
+ chunk2QKFRKOP_cjs.useIsomorphicLayoutEffect(() => {
614
614
  const active = content.current?.ownerDocument.activeElement;
615
615
  if (inside.current && !content.current?.contains(active ?? null)) focusPrimary();
616
616
  }, [phase, ghost.key]);
@@ -658,21 +658,21 @@ function AiBar({ env, ghost, gone, barId }) {
658
658
  children: [
659
659
  phase === "streaming" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
660
660
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: labels.writing }),
661
- /* @__PURE__ */ jsxRuntime.jsx(chunkDZ5XR4O6_cjs.Button, { ...primary, size: "sm", variant: "outline", onClick: () => stop(editor), children: labels.stop })
661
+ /* @__PURE__ */ jsxRuntime.jsx(chunkEBSDPHPS_cjs.Button, { ...primary, size: "sm", variant: "outline", onClick: () => stop(editor), children: labels.stop })
662
662
  ] }),
663
663
  phase === "error" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
664
664
  /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "text-sm text-destructive", children: labels.failed }),
665
- /* @__PURE__ */ jsxRuntime.jsx(chunkDZ5XR4O6_cjs.Button, { ...primary, size: "sm", onClick: () => retry(editor, stream), children: labels.retry }),
666
- /* @__PURE__ */ jsxRuntime.jsx(chunkDZ5XR4O6_cjs.Button, { size: "sm", variant: "ghost", onClick: onDiscard, children: labels.discard })
665
+ /* @__PURE__ */ jsxRuntime.jsx(chunkEBSDPHPS_cjs.Button, { ...primary, size: "sm", onClick: () => retry(editor, stream), children: labels.retry }),
666
+ /* @__PURE__ */ jsxRuntime.jsx(chunkEBSDPHPS_cjs.Button, { size: "sm", variant: "ghost", onClick: onDiscard, children: labels.discard })
667
667
  ] }),
668
668
  (phase === "done" || phase === "stopped") && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
669
669
  phase === "stopped" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: labels.stopped }),
670
670
  gone && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "w-full text-xs text-muted-foreground", children: labels.targetGone }),
671
- /* @__PURE__ */ jsxRuntime.jsx(chunkDZ5XR4O6_cjs.Button, { ...primary, size: "sm", onClick: onAccept, children: labels.accept }),
672
- /* @__PURE__ */ jsxRuntime.jsx(chunkDZ5XR4O6_cjs.Button, { size: "sm", variant: "ghost", onClick: onDiscard, children: labels.discard }),
673
- /* @__PURE__ */ jsxRuntime.jsx(chunkDZ5XR4O6_cjs.Button, { size: "sm", variant: "ghost", onClick: () => retry(editor, stream), children: labels.retry }),
671
+ /* @__PURE__ */ jsxRuntime.jsx(chunkEBSDPHPS_cjs.Button, { ...primary, size: "sm", onClick: onAccept, children: labels.accept }),
672
+ /* @__PURE__ */ jsxRuntime.jsx(chunkEBSDPHPS_cjs.Button, { size: "sm", variant: "ghost", onClick: onDiscard, children: labels.discard }),
673
+ /* @__PURE__ */ jsxRuntime.jsx(chunkEBSDPHPS_cjs.Button, { size: "sm", variant: "ghost", onClick: () => retry(editor, stream), children: labels.retry }),
674
674
  /* @__PURE__ */ jsxRuntime.jsx("form", { className: "w-full", onSubmit: onFollowUp, children: /* @__PURE__ */ jsxRuntime.jsx(
675
- chunkDZ5XR4O6_cjs.Input,
675
+ chunkEBSDPHPS_cjs.Input,
676
676
  {
677
677
  "aria-label": labels.followUp,
678
678
  placeholder: labels.followUp,
@@ -711,7 +711,7 @@ function fillGhost(ghost, markdown) {
711
711
  if (piece.indent > 0) element.style.setProperty("--quoin-ai-indent", String(piece.indent));
712
712
  const region = chunkFK7EBZPX_cjs.primaryRegion(schema, piece);
713
713
  if (region === null) element.textContent = chunkFK7EBZPX_cjs.toPlainText([codec.toQuoin(piece)], { schema });
714
- else chunkMGN332NY_cjs.renderInline(element, piece.regions[region], []);
714
+ else chunk2QKFRKOP_cjs.renderInline(element, piece.regions[region], []);
715
715
  drawn2.push(element);
716
716
  }
717
717
  }
@@ -788,7 +788,7 @@ function clipAside(layer, text, areas, scale) {
788
788
  function useGhostPlace(controller, layer, block, region) {
789
789
  const placeNow = react.useRef(() => {
790
790
  });
791
- chunkMGN332NY_cjs.useIsomorphicLayoutEffect(() => {
791
+ chunk2QKFRKOP_cjs.useIsomorphicLayoutEffect(() => {
792
792
  const root = controller.root;
793
793
  const element = layer.current;
794
794
  const view = root?.ownerDocument.defaultView;
@@ -827,7 +827,7 @@ function AiGhost({ env, ghost, target, gone, barId }) {
827
827
  const layer = react.useRef(null);
828
828
  const drawn2 = react.useRef(null);
829
829
  const place2 = useGhostPlace(env.controller, layer, target.to.block, target.to.region);
830
- chunkMGN332NY_cjs.useIsomorphicLayoutEffect(() => {
830
+ chunk2QKFRKOP_cjs.useIsomorphicLayoutEffect(() => {
831
831
  const element = drawn2.current;
832
832
  if (element === null) return;
833
833
  element.setAttribute("inert", "");
@@ -841,7 +841,7 @@ function AiGhost({ env, ghost, target, gone, barId }) {
841
841
  }
842
842
  function useTargetAnchor(controller, target) {
843
843
  const latest = react.useRef(target);
844
- chunkMGN332NY_cjs.useIsomorphicLayoutEffect(() => {
844
+ chunk2QKFRKOP_cjs.useIsomorphicLayoutEffect(() => {
845
845
  latest.current = target;
846
846
  });
847
847
  return react.useMemo(() => {
@@ -850,8 +850,8 @@ function useTargetAnchor(controller, target) {
850
850
  return { block: to.block, region: to.region, from: to.offset, to: to.offset };
851
851
  };
852
852
  return {
853
- current: chunkDZ5XR4O6_cjs.virtualAnchor(
854
- () => chunkDZ5XR4O6_cjs.rangeRect(controller, end()),
853
+ current: chunkEBSDPHPS_cjs.virtualAnchor(
854
+ () => chunkEBSDPHPS_cjs.rangeRect(controller, end()),
855
855
  () => controller.registry.get(end().block, end().region)
856
856
  )
857
857
  };
@@ -905,7 +905,7 @@ function AiMenu({ env, target, fromSpace }) {
905
905
  };
906
906
  const fieldLabel = asking === "tone" ? labels.tonePrompt : asking === "translate" ? labels.translatePrompt : labels.prompt;
907
907
  return /* @__PURE__ */ jsxRuntime.jsxs(
908
- chunkDZ5XR4O6_cjs.Popover,
908
+ chunkEBSDPHPS_cjs.Popover,
909
909
  {
910
910
  open: true,
911
911
  modal: false,
@@ -913,9 +913,9 @@ function AiMenu({ env, target, fromSpace }) {
913
913
  if (!next) closeMenu(controller.editor);
914
914
  },
915
915
  children: [
916
- /* @__PURE__ */ jsxRuntime.jsx(chunkDZ5XR4O6_cjs.PopoverAnchor, { virtualRef: anchor }),
916
+ /* @__PURE__ */ jsxRuntime.jsx(chunkEBSDPHPS_cjs.PopoverAnchor, { virtualRef: anchor }),
917
917
  /* @__PURE__ */ jsxRuntime.jsxs(
918
- chunkDZ5XR4O6_cjs.PopoverContent,
918
+ chunkEBSDPHPS_cjs.PopoverContent,
919
919
  {
920
920
  "aria-label": labels.askAi,
921
921
  side: "bottom",
@@ -932,7 +932,7 @@ function AiMenu({ env, target, fromSpace }) {
932
932
  },
933
933
  children: [
934
934
  /* @__PURE__ */ jsxRuntime.jsx(
935
- chunkDZ5XR4O6_cjs.Input,
935
+ chunkEBSDPHPS_cjs.Input,
936
936
  {
937
937
  ref: field,
938
938
  role: "combobox",
@@ -956,7 +956,7 @@ function AiMenu({ env, target, fromSpace }) {
956
956
  id: optionId(index),
957
957
  role: "option",
958
958
  "aria-selected": index === current,
959
- className: chunkDZ5XR4O6_cjs.cn(chunkDZ5XR4O6_cjs.MENU_ITEM, index === current && "bg-accent text-accent-foreground"),
959
+ className: chunkEBSDPHPS_cjs.cn(chunkEBSDPHPS_cjs.MENU_ITEM, index === current && "bg-accent text-accent-foreground"),
960
960
  onMouseDown: (event) => event.preventDefault(),
961
961
  onClick: () => choose(choice),
962
962
  children: choice.label
@@ -976,15 +976,15 @@ var goneOf = (state) => {
976
976
  };
977
977
  var plainText = (markdown) => chunkFK7EBZPX_cjs.toPlainText(chunkI7X7B3WD_cjs.fromMarkdown(markdown));
978
978
  function AiOverlay({ controller, stream, labels }) {
979
- const { onError } = chunkDZ5XR4O6_cjs.useQuoin();
979
+ const { onError } = chunkEBSDPHPS_cjs.useQuoin();
980
980
  const link = linkOf(controller.editor);
981
- chunkMGN332NY_cjs.useIsomorphicLayoutEffect(() => {
981
+ chunk2QKFRKOP_cjs.useIsomorphicLayoutEffect(() => {
982
982
  link.report = onError;
983
983
  link.ended = (phase, output) => controller.announce((phase === "done" ? labels.written : labels.halted)(plainText(output)));
984
984
  }, [link, onError, controller, labels]);
985
- const value = chunkMGN332NY_cjs.useEditorState(controller, aiState);
986
- const gone = chunkMGN332NY_cjs.useEditorState(controller, goneOf);
987
- const readOnly = chunkMGN332NY_cjs.useReadOnly(controller);
985
+ const value = chunk2QKFRKOP_cjs.useEditorState(controller, aiState);
986
+ const gone = chunk2QKFRKOP_cjs.useEditorState(controller, goneOf);
987
+ const readOnly = chunk2QKFRKOP_cjs.useReadOnly(controller);
988
988
  const env = react.useMemo(() => ({ controller, stream, labels }), [controller, stream, labels]);
989
989
  const barId = react.useId();
990
990
  const showing = value.ghost !== null;
@@ -1003,7 +1003,7 @@ function AiOverlay({ controller, stream, labels }) {
1003
1003
  const root = controller.root;
1004
1004
  if (!root) return;
1005
1005
  let away = true;
1006
- return chunk3B5VEXVQ_cjs.watchCanvasFocus(controller, root.ownerDocument, (inside, node) => {
1006
+ return chunk3HW3WRYC_cjs.watchCanvasFocus(controller, root.ownerDocument, (inside, node) => {
1007
1007
  if (!inside) away = true;
1008
1008
  else if (root.contains(node)) {
1009
1009
  if (away) noteFocus(controller.editor);
package/dist/ai.js CHANGED
@@ -1,8 +1,8 @@
1
1
  'use client';
2
2
  import { clipBoxes } from './chunk-MQUCCSWG.js';
3
- import { watchCanvasFocus } from './chunk-C4SRLMQJ.js';
4
- import { Sparkles, PenLine, useQuoin, Popover, PopoverAnchor, PopoverContent, Input, cn, MENU_ITEM, virtualAnchor, rangeRect, Button, toError } from './chunk-FGVTDIHT.js';
5
- import { useIsomorphicLayoutEffect, useEditorState, useReadOnly, renderInline } from './chunk-BNTRGV4A.js';
3
+ import { watchCanvasFocus } from './chunk-F2ZK6Z52.js';
4
+ import { Sparkles, PenLine, useQuoin, Popover, PopoverAnchor, PopoverContent, Input, cn, MENU_ITEM, virtualAnchor, rangeRect, Button, toError } from './chunk-G6NBQYMM.js';
5
+ import { useIsomorphicLayoutEffect, useEditorState, useReadOnly, renderInline } from './chunk-2BPXVQBP.js';
6
6
  import { mergeLabels } from './chunk-DLQCTGC3.js';
7
7
  import './chunk-HDJ653LM.js';
8
8
  import { createPluginKey, defineExtension, isCollapsed, regionLength, primaryRegion, getPluginState, Transaction, toPlainText, selectedBlockIds, orderedRange, comparePos, sliceFromSelection, textSelection, deleteRange, pasteAtCaret, toMarkdown, descendantsEnd, freshBlocks, insertBlocksStep, capIndents, endOf } from './chunk-5RBMZGKV.js';
@@ -1,21 +1,21 @@
1
1
  'use client';
2
2
  'use strict';
3
3
 
4
- var chunk4EJJ4ZNC_cjs = require('./chunk-4EJJ4ZNC.cjs');
5
- var chunkOMUXPNCX_cjs = require('./chunk-OMUXPNCX.cjs');
6
- var chunk5URH2Y2L_cjs = require('./chunk-5URH2Y2L.cjs');
7
- var chunkSQHEZ3JY_cjs = require('./chunk-SQHEZ3JY.cjs');
4
+ var chunkNUQ64S5B_cjs = require('./chunk-NUQ64S5B.cjs');
5
+ var chunkWDBFGX3U_cjs = require('./chunk-WDBFGX3U.cjs');
6
+ var chunk3INFNIGN_cjs = require('./chunk-3INFNIGN.cjs');
7
+ var chunkBE2YHZXA_cjs = require('./chunk-BE2YHZXA.cjs');
8
8
  require('./chunk-2SWLD6R5.cjs');
9
- var chunkBCCFJINI_cjs = require('./chunk-BCCFJINI.cjs');
10
- var chunkH3TRVI44_cjs = require('./chunk-H3TRVI44.cjs');
11
- var chunkUWCU6PJY_cjs = require('./chunk-UWCU6PJY.cjs');
12
- require('./chunk-55MN4QZU.cjs');
9
+ var chunk7J63427U_cjs = require('./chunk-7J63427U.cjs');
10
+ var chunkJGEDJYIV_cjs = require('./chunk-JGEDJYIV.cjs');
11
+ var chunkKHRVCTQQ_cjs = require('./chunk-KHRVCTQQ.cjs');
12
+ require('./chunk-JZF6UQH5.cjs');
13
13
  require('./chunk-YEDPBYO5.cjs');
14
- var chunkSDFJZNYB_cjs = require('./chunk-SDFJZNYB.cjs');
15
- var chunkNAMZA4NW_cjs = require('./chunk-NAMZA4NW.cjs');
14
+ var chunkYYW33WUL_cjs = require('./chunk-YYW33WUL.cjs');
15
+ var chunkN7BSFDDM_cjs = require('./chunk-N7BSFDDM.cjs');
16
16
  require('./chunk-LM3DHROX.cjs');
17
- require('./chunk-DZ5XR4O6.cjs');
18
- require('./chunk-MGN332NY.cjs');
17
+ require('./chunk-EBSDPHPS.cjs');
18
+ require('./chunk-2QKFRKOP.cjs');
19
19
  require('./chunk-ZWTIRGY5.cjs');
20
20
  require('./chunk-A6PGQVTR.cjs');
21
21
  require('./chunk-FK7EBZPX.cjs');
@@ -32,15 +32,15 @@ function createCatalogue(features2) {
32
32
 
33
33
  // src/catalogue.ts
34
34
  var features = {
35
- table: chunkBCCFJINI_cjs.tableExtension,
36
- embed: chunkH3TRVI44_cjs.embedExtension,
37
- math: chunkUWCU6PJY_cjs.mathExtension,
38
- diagram: chunkSDFJZNYB_cjs.diagramExtension,
39
- toc: chunkNAMZA4NW_cjs.tocExtension,
40
- mention: chunk4EJJ4ZNC_cjs.mentionExtension,
41
- emoji: chunkOMUXPNCX_cjs.emojiExtension,
42
- find: chunk5URH2Y2L_cjs.findExtension,
43
- stats: chunkSQHEZ3JY_cjs.statsExtension
35
+ table: chunk7J63427U_cjs.tableExtension,
36
+ embed: chunkJGEDJYIV_cjs.embedExtension,
37
+ math: chunkKHRVCTQQ_cjs.mathExtension,
38
+ diagram: chunkYYW33WUL_cjs.diagramExtension,
39
+ toc: chunkN7BSFDDM_cjs.tocExtension,
40
+ mention: chunkNUQ64S5B_cjs.mentionExtension,
41
+ emoji: chunkWDBFGX3U_cjs.emojiExtension,
42
+ find: chunk3INFNIGN_cjs.findExtension,
43
+ stats: chunkBE2YHZXA_cjs.statsExtension
44
44
  };
45
45
  var catalogue = createCatalogue(features);
46
46
 
package/dist/catalogue.js CHANGED
@@ -1,19 +1,19 @@
1
1
  'use client';
2
- import { mentionExtension } from './chunk-77THE3KY.js';
3
- import { emojiExtension } from './chunk-YHAVXOAA.js';
4
- import { findExtension } from './chunk-RNYETN6X.js';
5
- import { statsExtension } from './chunk-QVWNUUMJ.js';
2
+ import { mentionExtension } from './chunk-W376L2GM.js';
3
+ import { emojiExtension } from './chunk-A2IQHMIH.js';
4
+ import { findExtension } from './chunk-XE3IYW5B.js';
5
+ import { statsExtension } from './chunk-QLVX7MPS.js';
6
6
  import './chunk-KTUOPDVO.js';
7
- import { tableExtension } from './chunk-LCGOFL7S.js';
8
- import { embedExtension } from './chunk-VQDQBMQY.js';
9
- import { mathExtension } from './chunk-NLRSAOCK.js';
10
- import './chunk-WMM56LIB.js';
7
+ import { tableExtension } from './chunk-556PFYES.js';
8
+ import { embedExtension } from './chunk-AJT54OMZ.js';
9
+ import { mathExtension } from './chunk-LU3T3JB4.js';
10
+ import './chunk-4G645EYO.js';
11
11
  import './chunk-LSI4RMTY.js';
12
- import { diagramExtension } from './chunk-MDIXI7DM.js';
13
- import { tocExtension } from './chunk-YWYTLNAO.js';
12
+ import { diagramExtension } from './chunk-EIWPJWY3.js';
13
+ import { tocExtension } from './chunk-NHNW5DK3.js';
14
14
  import './chunk-DBOZFNWU.js';
15
- import './chunk-FGVTDIHT.js';
16
- import './chunk-BNTRGV4A.js';
15
+ import './chunk-G6NBQYMM.js';
16
+ import './chunk-2BPXVQBP.js';
17
17
  import './chunk-DLQCTGC3.js';
18
18
  import './chunk-HDJ653LM.js';
19
19
  import './chunk-5RBMZGKV.js';
@@ -3152,7 +3152,7 @@ var MarkdownBlock = (props) => {
3152
3152
  /* @__PURE__ */ jsx(TextRegion, { block, label: "Task" })
3153
3153
  ] });
3154
3154
  case "quote":
3155
- return /* @__PURE__ */ jsx("div", { className: "quoin-quote", children: /* @__PURE__ */ jsx(TextRegion, { block, label: "Quote" }) });
3155
+ return /* @__PURE__ */ jsx("blockquote", { className: "quoin-quote", children: /* @__PURE__ */ jsx(TextRegion, { block, label: "Quote" }) });
3156
3156
  default:
3157
3157
  return /* @__PURE__ */ jsx(TextRegion, { block, label: "Paragraph" });
3158
3158
  }
@@ -3321,5 +3321,5 @@ function EditorView({
3321
3321
  }
3322
3322
 
3323
3323
  export { BlockErrorContext, CALLOUT_TONES, EditableRegion, EditorView, NATIVE_INTERACTION, NODE_ENTRY, TaskCheckbox, ToggleChevron, ViewController, arrowAsWritten, calloutTone, caretClientRect, caretFromPoint, createAutoScroll, dispatchSelection, domMapOf, domToPos, drawnBlockCount, focusOwners, handleCopy, hostKey, inlineDirection, isComposingKey, isOnFirstLine, isOnLastLine, lineEdgeRect, listen, moveToNeighbour, neighbourBlock, onBlock, posToDom, regionInline, renderInline, textDiff, useBlockDomId, useEditorState, useIsomorphicLayoutEffect, useOrderedNumber, useQuoinEditor, useReadOnly, useRegionDomId, useToggleOpen, useViewController, visibleBlockIndexes, wholeState };
3324
- //# sourceMappingURL=chunk-BNTRGV4A.js.map
3325
- //# sourceMappingURL=chunk-BNTRGV4A.js.map
3324
+ //# sourceMappingURL=chunk-2BPXVQBP.js.map
3325
+ //# sourceMappingURL=chunk-2BPXVQBP.js.map