quoin-editor 0.1.0 → 0.2.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/dist/index.cjs CHANGED
@@ -32,16 +32,30 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
32
32
  var src_exports = {};
33
33
  __export(src_exports, {
34
34
  BlockCanvas: () => BlockCanvas,
35
+ FilePickerButton: () => FilePickerButton,
35
36
  QuoinProvider: () => QuoinProvider,
36
37
  TEXT_COMMANDS: () => TEXT_COMMANDS,
38
+ UploadField: () => UploadField,
39
+ applyEdit: () => applyEdit,
37
40
  blockByType: () => blockByType,
41
+ caretRect: () => caretRect,
42
+ continueList: () => continueList,
38
43
  coreBlocks: () => coreBlocks,
39
44
  defineBlock: () => defineBlock,
45
+ formatShortcut: () => formatShortcut,
46
+ indentList: () => indentList,
47
+ insertCommand: () => insertCommand,
48
+ lineAt: () => lineAt,
49
+ linkPaste: () => linkPaste,
40
50
  paletteBlocks: () => paletteBlocks,
51
+ shouldOpenPalette: () => shouldOpenPalette,
52
+ toggleLinePrefix: () => toggleLinePrefix,
41
53
  useAutoGrow: () => useAutoGrow,
42
54
  useAutosave: () => useAutosave,
43
55
  useBlockList: () => useBlockList,
44
- useQuoin: () => useQuoin
56
+ useMarkdownKeymap: () => useMarkdownKeymap,
57
+ useQuoin: () => useQuoin,
58
+ wrapSelection: () => wrapSelection
45
59
  });
46
60
  module.exports = __toCommonJS(src_exports);
47
61
 
@@ -181,12 +195,7 @@ function Button({
181
195
 
182
196
  // src/upload/FilePickerButton.tsx
183
197
  var import_jsx_runtime3 = require("react/jsx-runtime");
184
- function FilePickerButton({
185
- label,
186
- accept,
187
- disabled,
188
- onPick
189
- }) {
198
+ function FilePickerButton({ label, accept, disabled, onPick }) {
190
199
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "relative inline-flex rounded-md has-[:focus-visible]:ring-[3px] has-[:focus-visible]:ring-ring/50", children: [
191
200
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Button, { asChild: true, variant: "outline", size: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { "aria-hidden": "true", className: disabled ? "pointer-events-none opacity-50" : void 0, children: [
192
201
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.Upload, { "aria-hidden": "true" }),
@@ -1144,7 +1153,10 @@ function MarkdownBlockEditor({ data, onChange, onInsertBlock, onDone }) {
1144
1153
  const palette = useSlashPalette(ref);
1145
1154
  const [shortcutsOpen, setShortcutsOpen] = React5.useState(false);
1146
1155
  const set = (patch) => onChange({ ...data, ...patch });
1147
- const commit = (next) => onChange({ ...data, markdown: next });
1156
+ const commit = React5.useCallback(
1157
+ (next) => onChange({ ...data, markdown: next }),
1158
+ [data, onChange]
1159
+ );
1148
1160
  const keymap = useMarkdownKeymap({ commit, onOpenPalette: palette.openAtCaret });
1149
1161
  function reopenBox() {
1150
1162
  const el = ref.current;
@@ -1390,12 +1402,7 @@ var import_react = require("react");
1390
1402
  // src/upload/UploadField.tsx
1391
1403
  var React6 = __toESM(require("react"), 1);
1392
1404
  var import_jsx_runtime15 = require("react/jsx-runtime");
1393
- function UploadField({
1394
- category,
1395
- label,
1396
- accept,
1397
- onUploaded
1398
- }) {
1405
+ function UploadField({ category, label, accept, onUploaded }) {
1399
1406
  const { upload, onError } = useQuoin();
1400
1407
  const [busy, setBusy] = React6.useState(false);
1401
1408
  const [error, setError] = React6.useState(null);
@@ -1605,6 +1612,7 @@ function newBlockId() {
1605
1612
 
1606
1613
  // src/hooks/useBlockList.ts
1607
1614
  var removalSeq = 0;
1615
+ var UNDO_DEPTH = 20;
1608
1616
  function reducer(state, action) {
1609
1617
  switch (action.type) {
1610
1618
  case "insertAt": {
@@ -1623,6 +1631,11 @@ function reducer(state, action) {
1623
1631
  if (index === -1) return state;
1624
1632
  const removals = new Map(state.removals);
1625
1633
  removals.set(action.token, { block: state.blocks[index], index });
1634
+ while (removals.size > UNDO_DEPTH) {
1635
+ const oldest = removals.keys().next();
1636
+ if (oldest.done) break;
1637
+ removals.delete(oldest.value);
1638
+ }
1626
1639
  return { blocks: state.blocks.filter((b) => b.id !== action.id), removals };
1627
1640
  }
1628
1641
  case "undo": {
@@ -1860,18 +1873,48 @@ function BlockEditor({
1860
1873
  }
1861
1874
 
1862
1875
  // src/canvas/source-offset.ts
1876
+ function caretPositionAt(x, y) {
1877
+ const doc = document;
1878
+ const position = doc.caretPositionFromPoint?.(x, y);
1879
+ if (position) return position;
1880
+ const range = doc.caretRangeFromPoint?.(x, y);
1881
+ return range ? { offsetNode: range.startContainer, offset: range.startOffset } : null;
1882
+ }
1883
+ function renderedOffsetAt(container, x, y) {
1884
+ const position = caretPositionAt(x, y);
1885
+ if (!position || position.offsetNode.nodeType !== Node.TEXT_NODE) return null;
1886
+ if (!container.contains(position.offsetNode)) return null;
1887
+ const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT);
1888
+ let before = 0;
1889
+ while (walker.nextNode()) {
1890
+ if (walker.currentNode === position.offsetNode) return before + position.offset;
1891
+ before += walker.currentNode.textContent?.length ?? 0;
1892
+ }
1893
+ return null;
1894
+ }
1863
1895
  var PROBE_LENGTHS = [40, 20, 8];
1864
- function sourceOffsetFor(source, clickedText) {
1865
- const text = clickedText.replace(/\s+/g, " ").trim();
1866
- if (text === "") return 0;
1867
- const whole = source.indexOf(text);
1868
- if (whole !== -1) return whole;
1896
+ function search(source, probe) {
1897
+ const literal = probe.clickedText.trim();
1898
+ if (literal === "" || literal === probe.rendered.trim()) return source.length;
1899
+ const candidates = [literal, literal.replace(/\s+/g, " ")];
1900
+ for (const text of candidates) {
1901
+ const whole = source.indexOf(text);
1902
+ if (whole !== -1) return whole;
1903
+ }
1869
1904
  for (const length of PROBE_LENGTHS) {
1870
- if (text.length < length) continue;
1871
- const at = source.indexOf(text.slice(0, length));
1872
- if (at !== -1) return at;
1905
+ for (const text of candidates) {
1906
+ if (text.length < length) continue;
1907
+ const at = source.indexOf(text.slice(0, length));
1908
+ if (at !== -1) return at;
1909
+ }
1910
+ }
1911
+ return source.length;
1912
+ }
1913
+ function sourceOffsetFor(source, probe) {
1914
+ if (probe.renderedOffset !== null && probe.rendered === source) {
1915
+ return Math.max(0, Math.min(probe.renderedOffset, source.length));
1873
1916
  }
1874
- return 0;
1917
+ return search(source, probe);
1875
1918
  }
1876
1919
 
1877
1920
  // src/canvas/BlockCard.tsx
@@ -1892,14 +1935,14 @@ function BlockCardImpl({
1892
1935
  onUpdate,
1893
1936
  onInsertBlock
1894
1937
  }) {
1895
- const { blockTypes } = useQuoin();
1938
+ const { blockTypes, onError } = useQuoin();
1896
1939
  const definition = blockByType(blockTypes, block.type);
1897
1940
  const Preview = definition?.preview;
1898
1941
  const [editing, setEditing] = React8.useState(editingByDefault && !readOnly);
1899
1942
  const editButtonRef = React8.useRef(null);
1900
1943
  const editorContainerRef = React8.useRef(null);
1901
1944
  const returnFocusOnClose = React8.useRef(false);
1902
- const clickedTextRef = React8.useRef(null);
1945
+ const clickedRef = React8.useRef(null);
1903
1946
  const scrollTopRef = React8.useRef(null);
1904
1947
  const handleInsertBlock = React8.useCallback(
1905
1948
  (type) => onInsertBlock?.(index + 1, type),
@@ -1943,8 +1986,8 @@ function BlockCardImpl({
1943
1986
  'textarea, input, [role="combobox"]'
1944
1987
  );
1945
1988
  if (!field) return;
1946
- const clicked = clickedTextRef.current;
1947
- clickedTextRef.current = null;
1989
+ const clicked = clickedRef.current;
1990
+ clickedRef.current = null;
1948
1991
  if (clicked === null || !(field instanceof HTMLTextAreaElement)) {
1949
1992
  field.focus();
1950
1993
  if (field instanceof HTMLTextAreaElement) {
@@ -1969,6 +2012,12 @@ function BlockCardImpl({
1969
2012
  returnFocusOnClose.current = false;
1970
2013
  editButtonRef.current?.focus();
1971
2014
  }, [editing]);
2015
+ const reportedType = React8.useRef(null);
2016
+ React8.useEffect(() => {
2017
+ if (definition || reportedType.current === block.type) return;
2018
+ reportedType.current = block.type;
2019
+ onError(new Error(`No block type is registered for "${block.type}".`));
2020
+ }, [definition, block.type, onError]);
1972
2021
  if (definition?.alwaysEditing && !readOnly) {
1973
2022
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1974
2023
  BlockEditor,
@@ -2008,7 +2057,7 @@ function BlockCardImpl({
2008
2057
  }
2009
2058
  );
2010
2059
  }
2011
- const rest = Preview ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Preview, { data: block.data, blockId: block.id }) : definition ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "py-1 text-sm text-muted-foreground", children: definition.label }) : null;
2060
+ const rest = Preview ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Preview, { data: block.data, blockId: block.id }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "py-1 text-sm text-muted-foreground", children: definition?.label ?? block.type });
2012
2061
  if (readOnly) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: rest });
2013
2062
  return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "group/card relative", children: [
2014
2063
  /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
@@ -2018,7 +2067,11 @@ function BlockCardImpl({
2018
2067
  const target = e.target;
2019
2068
  if (target.closest(INTERACTIVE_SELECTOR)) return;
2020
2069
  if (hasSelectionWithin(e.currentTarget)) return;
2021
- clickedTextRef.current = target.textContent ?? "";
2070
+ clickedRef.current = {
2071
+ rendered: e.currentTarget.textContent ?? "",
2072
+ clickedText: target.textContent ?? "",
2073
+ renderedOffset: renderedOffsetAt(e.currentTarget, e.clientX, e.clientY)
2074
+ };
2022
2075
  scrollTopRef.current = (document.scrollingElement ?? document.documentElement).scrollTop;
2023
2076
  setEditing(true);
2024
2077
  },
@@ -2167,6 +2220,16 @@ function DocumentStarter({
2167
2220
  ] });
2168
2221
  }
2169
2222
 
2223
+ // src/canvas/ReadOnlyCanvas.tsx
2224
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2225
+ function ReadOnlyCanvas({
2226
+ blocks,
2227
+ onUpdate,
2228
+ root
2229
+ }) {
2230
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { ...root, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("ul", { className: "flex flex-col", children: blocks.map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { "data-block-index": i, className: "rounded-lg px-2 py-1", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(BlockCard, { block: b, index: i, editingByDefault: false, readOnly: true, onUpdate }) }) }, b.id)) }) });
2231
+ }
2232
+
2170
2233
  // src/canvas/reorder-indices.ts
2171
2234
  function reorderIndices(ids, activeId, overId) {
2172
2235
  if (overId === null || activeId === overId) return null;
@@ -2196,7 +2259,7 @@ function sameBlocks(a, b) {
2196
2259
  var import_sortable = require("@dnd-kit/sortable");
2197
2260
  var import_utilities = require("@dnd-kit/utilities");
2198
2261
  var import_lucide_react12 = require("lucide-react");
2199
- var import_jsx_runtime25 = require("react/jsx-runtime");
2262
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2200
2263
  var GUTTER = [
2201
2264
  "flex items-center justify-end gap-0.5 pb-1",
2202
2265
  "lg:absolute lg:right-full lg:top-1 lg:justify-start lg:pb-0 lg:pr-1",
@@ -2210,16 +2273,16 @@ function SortableBlock({
2210
2273
  children
2211
2274
  }) {
2212
2275
  const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = (0, import_sortable.useSortable)({ id });
2213
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
2276
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
2214
2277
  "div",
2215
2278
  {
2216
2279
  ref: setNodeRef,
2217
2280
  style: { transform: import_utilities.CSS.Transform.toString(transform), transition },
2218
2281
  className: cn("group/block relative", isDragging && "z-10 opacity-80"),
2219
2282
  children: [
2220
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: GUTTER, children: [
2283
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: GUTTER, children: [
2221
2284
  actions,
2222
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2285
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2223
2286
  Button,
2224
2287
  {
2225
2288
  type: "button",
@@ -2230,17 +2293,17 @@ function SortableBlock({
2230
2293
  "aria-label": `Reorder block ${index + 1}`,
2231
2294
  ...attributes,
2232
2295
  ...listeners,
2233
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.GripVertical, { "aria-hidden": "true" })
2296
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react12.GripVertical, { "aria-hidden": "true" })
2234
2297
  }
2235
2298
  )
2236
2299
  ] }),
2237
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2300
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2238
2301
  "div",
2239
2302
  {
2240
2303
  "data-block-index": index,
2241
2304
  className: cn(
2242
2305
  "rounded-lg px-2 py-1 transition-colors",
2243
- isDragging ? "bg-card shadow-[var(--shadow-md)]" : "group-hover/block:bg-muted/40"
2306
+ isDragging ? "bg-popover shadow-md" : "group-hover/block:bg-muted/40"
2244
2307
  ),
2245
2308
  children
2246
2309
  }
@@ -2250,11 +2313,23 @@ function SortableBlock({
2250
2313
  );
2251
2314
  }
2252
2315
 
2316
+ // src/canvas/unacknowledged.ts
2317
+ var UNACKNOWLEDGED_LIMIT = 64;
2318
+ function remember(outstanding, blocks) {
2319
+ outstanding.add(blocks);
2320
+ while (outstanding.size > UNACKNOWLEDGED_LIMIT) {
2321
+ const oldest = outstanding.values().next();
2322
+ if (oldest.done) return;
2323
+ outstanding.delete(oldest.value);
2324
+ }
2325
+ }
2326
+
2253
2327
  // src/canvas/BlockCanvas.tsx
2254
- var import_jsx_runtime26 = require("react/jsx-runtime");
2328
+ var import_jsx_runtime27 = require("react/jsx-runtime");
2255
2329
  function Canvas({
2256
2330
  blocks,
2257
2331
  onChange,
2332
+ onDelete,
2258
2333
  blockTypes,
2259
2334
  readOnly,
2260
2335
  className,
@@ -2272,22 +2347,32 @@ function Canvas({
2272
2347
  const [seedSelection, setSeedSelection] = React11.useState(null);
2273
2348
  const listRef = React11.useRef(null);
2274
2349
  const pendingDeleteIndexRef = React11.useRef(null);
2350
+ const removedRef = React11.useRef(null);
2275
2351
  const announcements = React11.useMemo(
2276
2352
  () => buildAnnouncements(list.blocks, blockTypes),
2277
2353
  [list.blocks, blockTypes]
2278
2354
  );
2279
2355
  const lastEmitted = React11.useRef(blocks);
2280
2356
  const lastSupplied = React11.useRef(blocks);
2357
+ const unacknowledged = React11.useRef(/* @__PURE__ */ new Set());
2281
2358
  React11.useEffect(() => {
2282
2359
  if (list.blocks === lastEmitted.current) return;
2283
2360
  lastEmitted.current = list.blocks;
2361
+ remember(unacknowledged.current, list.blocks);
2284
2362
  onChange(list.blocks);
2285
- }, [list.blocks, onChange]);
2363
+ const removed = removedRef.current;
2364
+ removedRef.current = null;
2365
+ if (removed) onDelete?.(removed.block, removed.index);
2366
+ }, [list.blocks, onChange, onDelete]);
2286
2367
  React11.useEffect(() => {
2287
2368
  const previous = lastSupplied.current;
2288
2369
  lastSupplied.current = blocks;
2289
- if (blocks === lastEmitted.current) return;
2370
+ if (unacknowledged.current.has(blocks)) {
2371
+ if (blocks === lastEmitted.current) unacknowledged.current.clear();
2372
+ return;
2373
+ }
2290
2374
  if (sameBlocks(blocks, previous) || sameBlocks(blocks, list.blocks)) return;
2375
+ unacknowledged.current.clear();
2291
2376
  lastEmitted.current = blocks;
2292
2377
  reset(blocks);
2293
2378
  }, [blocks, reset]);
@@ -2300,7 +2385,10 @@ function Canvas({
2300
2385
  [insertAt, blockTypes]
2301
2386
  );
2302
2387
  function handleDelete(index, id2) {
2388
+ const block = list.blocks[index];
2303
2389
  pendingDeleteIndexRef.current = index;
2390
+ if (block) removedRef.current = { block, index };
2391
+ setNewBlockId((current) => current === id2 ? null : current);
2304
2392
  remove(id2);
2305
2393
  }
2306
2394
  React11.useEffect(() => {
@@ -2327,12 +2415,10 @@ function Canvas({
2327
2415
  role: ariaLabel ? "group" : void 0,
2328
2416
  "aria-label": ariaLabel
2329
2417
  };
2330
- if (readOnly) {
2331
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { ...rootProps, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("ul", { className: "flex flex-col", children: list.blocks.map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { "data-block-index": i, className: "rounded-lg px-2 py-1", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BlockCard, { block: b, index: i, editingByDefault: false, readOnly: true, onUpdate: update }) }) }, b.id)) }) });
2332
- }
2333
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { ...rootProps, children: [
2334
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BlockInserter, { index: 0, onInsert: insertPlain, label: "Insert a block at the start" }),
2335
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2418
+ if (readOnly) return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ReadOnlyCanvas, { blocks: list.blocks, onUpdate: update, root: rootProps });
2419
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { ...rootProps, children: [
2420
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(BlockInserter, { index: 0, onInsert: insertPlain, label: "Insert a block at the start" }),
2421
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2336
2422
  import_core.DndContext,
2337
2423
  {
2338
2424
  id: dndId,
@@ -2341,13 +2427,13 @@ function Canvas({
2341
2427
  modifiers: [import_modifiers.restrictToVerticalAxis],
2342
2428
  accessibility: { announcements },
2343
2429
  onDragEnd: handleDragEnd,
2344
- children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_sortable2.SortableContext, { items: list.blocks.map((b) => b.id), strategy: import_sortable2.verticalListSortingStrategy, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("ul", { className: "flex flex-col", children: list.blocks.map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("li", { children: [
2345
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2430
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_sortable2.SortableContext, { items: list.blocks.map((b) => b.id), strategy: import_sortable2.verticalListSortingStrategy, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("ul", { className: "flex flex-col", children: list.blocks.map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("li", { children: [
2431
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2346
2432
  SortableBlock,
2347
2433
  {
2348
2434
  id: b.id,
2349
2435
  index: i,
2350
- actions: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2436
+ actions: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2351
2437
  BlockActionsMenu,
2352
2438
  {
2353
2439
  index: i,
@@ -2357,7 +2443,7 @@ function Canvas({
2357
2443
  onDelete: () => handleDelete(i, b.id)
2358
2444
  }
2359
2445
  ),
2360
- children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2446
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2361
2447
  BlockCard,
2362
2448
  {
2363
2449
  block: b,
@@ -2370,7 +2456,7 @@ function Canvas({
2370
2456
  )
2371
2457
  }
2372
2458
  ),
2373
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2459
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2374
2460
  BlockInserter,
2375
2461
  {
2376
2462
  index: i + 1,
@@ -2381,7 +2467,7 @@ function Canvas({
2381
2467
  ] }, b.id)) }) })
2382
2468
  }
2383
2469
  ),
2384
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2470
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2385
2471
  DocumentStarter,
2386
2472
  {
2387
2473
  autoFocus: list.blocks.length === 0,
@@ -2397,6 +2483,7 @@ function Canvas({
2397
2483
  function BlockCanvas({
2398
2484
  blocks,
2399
2485
  onChange,
2486
+ onDelete,
2400
2487
  blockTypes = coreBlocks,
2401
2488
  upload,
2402
2489
  resolveAssetUrl,
@@ -2410,11 +2497,12 @@ function BlockCanvas({
2410
2497
  () => ({ blockTypes, upload, resolveAssetUrl, onError }),
2411
2498
  [blockTypes, upload, resolveAssetUrl, onError]
2412
2499
  );
2413
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(QuoinProvider, { value: config, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2500
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(QuoinProvider, { value: config, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2414
2501
  Canvas,
2415
2502
  {
2416
2503
  blocks,
2417
2504
  onChange,
2505
+ onDelete,
2418
2506
  blockTypes,
2419
2507
  readOnly,
2420
2508
  className,
@@ -2491,15 +2579,29 @@ function useAutosave({
2491
2579
  // Annotate the CommonJS export names for ESM import in node:
2492
2580
  0 && (module.exports = {
2493
2581
  BlockCanvas,
2582
+ FilePickerButton,
2494
2583
  QuoinProvider,
2495
2584
  TEXT_COMMANDS,
2585
+ UploadField,
2586
+ applyEdit,
2496
2587
  blockByType,
2588
+ caretRect,
2589
+ continueList,
2497
2590
  coreBlocks,
2498
2591
  defineBlock,
2592
+ formatShortcut,
2593
+ indentList,
2594
+ insertCommand,
2595
+ lineAt,
2596
+ linkPaste,
2499
2597
  paletteBlocks,
2598
+ shouldOpenPalette,
2599
+ toggleLinePrefix,
2500
2600
  useAutoGrow,
2501
2601
  useAutosave,
2502
2602
  useBlockList,
2503
- useQuoin
2603
+ useMarkdownKeymap,
2604
+ useQuoin,
2605
+ wrapSelection
2504
2606
  });
2505
2607
  //# sourceMappingURL=index.cjs.map