@nuucognition/ncm-ui 0.1.0-dev.1 → 0.1.1-beta.1

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 (74) hide show
  1. package/README.md +90 -0
  2. package/dist/blocks/admonition/index.d.ts +2 -3
  3. package/dist/blocks/admonition/index.js +79 -23
  4. package/dist/blocks/aside/index.d.ts +2 -3
  5. package/dist/blocks/aside/index.js +79 -23
  6. package/dist/blocks/attribution/index.d.ts +2 -3
  7. package/dist/blocks/blockquote/index.d.ts +5 -4
  8. package/dist/blocks/blockquote/index.js +52 -7
  9. package/dist/blocks/chart/index.d.ts +2 -3
  10. package/dist/blocks/chart/index.js +2 -1
  11. package/dist/blocks/code/index.d.ts +2 -3
  12. package/dist/blocks/code/index.js +2 -2
  13. package/dist/blocks/container/index.d.ts +2 -3
  14. package/dist/blocks/container/index.js +50 -5
  15. package/dist/blocks/custom-code/index.d.ts +2 -3
  16. package/dist/blocks/custom-code/index.js +1 -1
  17. package/dist/blocks/dataview/index.d.ts +2 -3
  18. package/dist/blocks/dataview/index.js +2 -1
  19. package/dist/blocks/definition/index.d.ts +2 -3
  20. package/dist/blocks/definition/index.js +79 -23
  21. package/dist/blocks/embed/index.d.ts +2 -3
  22. package/dist/blocks/embedding/index.d.ts +2 -3
  23. package/dist/blocks/embedding/index.js +50 -5
  24. package/dist/blocks/figure/index.d.ts +2 -3
  25. package/dist/blocks/figure/index.js +50 -5
  26. package/dist/blocks/footnote/index.d.ts +2 -3
  27. package/dist/blocks/footnote/index.js +79 -23
  28. package/dist/blocks/frontmatter/index.d.ts +2 -3
  29. package/dist/blocks/header/index.d.ts +2 -3
  30. package/dist/blocks/header/index.js +50 -5
  31. package/dist/blocks/horizontal-rule/index.d.ts +2 -3
  32. package/dist/blocks/html/index.d.ts +3 -4
  33. package/dist/blocks/html/index.js +2 -1
  34. package/dist/blocks/index.d.ts +1 -2
  35. package/dist/blocks/index.js +79 -23
  36. package/dist/blocks/latex/index.d.ts +2 -3
  37. package/dist/blocks/latex/index.js +2 -2
  38. package/dist/blocks/link/index.d.ts +2 -3
  39. package/dist/blocks/list/index.d.ts +2 -3
  40. package/dist/blocks/list/index.js +57 -7
  41. package/dist/blocks/math/index.d.ts +2 -3
  42. package/dist/blocks/math/index.js +3 -2
  43. package/dist/blocks/mermaid/index.d.ts +2 -3
  44. package/dist/blocks/mermaid/index.js +2 -1
  45. package/dist/blocks/page-breaker/index.d.ts +2 -3
  46. package/dist/blocks/paragraph/index.d.ts +2 -3
  47. package/dist/blocks/paragraph/index.js +50 -5
  48. package/dist/blocks/spoiler/index.d.ts +2 -3
  49. package/dist/blocks/spoiler/index.js +79 -23
  50. package/dist/blocks/table/index.d.ts +2 -3
  51. package/dist/blocks/table/index.js +51 -6
  52. package/dist/blocks/task-list/index.d.ts +2 -3
  53. package/dist/blocks/task-list/index.js +52 -6
  54. package/dist/components/index.d.ts +34 -4
  55. package/dist/components/index.js +117 -25
  56. package/dist/components/ncm-block.d.ts +2 -3
  57. package/dist/components/ncm-block.js +79 -23
  58. package/dist/components/ncm-document.d.ts +4 -4
  59. package/dist/components/ncm-document.js +79 -23
  60. package/dist/context/index.d.ts +2 -3
  61. package/dist/hooks/index.d.ts +1 -2
  62. package/dist/hooks/index.js +79 -23
  63. package/dist/hooks/use-block-renderer.js +79 -23
  64. package/dist/hooks/use-ncm-config.d.ts +1 -2
  65. package/dist/index.d.ts +3 -4
  66. package/dist/index.js +118 -26
  67. package/dist/inline/index.d.ts +4 -4
  68. package/dist/inline/index.js +51 -6
  69. package/dist/lib/defaults.js +79 -23
  70. package/dist/{references-Bs5wJybr.d.ts → references-BYW5pnj_.d.ts} +4 -4
  71. package/dist/styles/nuu.css +329 -44
  72. package/dist/styles/paper.css +62 -1
  73. package/dist/{use-ncm-config-D0doMYTH.d.ts → use-ncm-config-CnntcShj.d.ts} +55 -4
  74. package/package.json +5 -5
@@ -4,7 +4,7 @@ import { clsx } from 'clsx';
4
4
  import { twMerge } from 'tailwind-merge';
5
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
6
  import { extractExtension, embedTypeFromExtension } from '@nuucognition/mesh-core';
7
- import { serializeInlineContent, isTypedNestedList } from '@nuucognition/ncm';
7
+ import { parseNcm, serializeInlineContent, isTypedNestedList } from '@nuucognition/ncm';
8
8
 
9
9
  // src/components/block-shell.tsx
10
10
  function cn(...inputs) {
@@ -614,9 +614,10 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
614
614
  case "image": {
615
615
  const src = config.inline?.resolveAssetPath?.(token.src) ?? token.src;
616
616
  return /* @__PURE__ */ jsx(
617
- "img",
617
+ EmbedImage,
618
618
  {
619
- "data-ncm-token": "image",
619
+ attrs: { "data-ncm-token": "image" },
620
+ target: token.src,
620
621
  src,
621
622
  alt: token.alt,
622
623
  title: token.title
@@ -650,10 +651,13 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
650
651
  }
651
652
  if (embedType === "image") {
652
653
  return /* @__PURE__ */ jsx(
653
- "img",
654
+ EmbedImage,
654
655
  {
655
- "data-ncm-token": "wiki_embed",
656
- "data-ncm-wikiembed-type": embedType,
656
+ attrs: {
657
+ "data-ncm-token": "wiki_embed",
658
+ "data-ncm-wikiembed-type": embedType
659
+ },
660
+ target: token.target,
657
661
  src: url,
658
662
  alt: token.display ?? token.target,
659
663
  className: config.embeddings?.imageClassName
@@ -684,6 +688,22 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
684
688
  }
685
689
  );
686
690
  }
691
+ const onEmbedClick = config.embeddings?.onEmbedClick;
692
+ if (onEmbedClick) {
693
+ const handleClick = (e) => {
694
+ onEmbedClick(token.target, result, e);
695
+ };
696
+ return /* @__PURE__ */ jsx(
697
+ "button",
698
+ {
699
+ type: "button",
700
+ "data-ncm-token": "wiki_embed",
701
+ "data-ncm-wikiembed-type": embedType,
702
+ onClick: handleClick,
703
+ children: token.display ?? token.target
704
+ }
705
+ );
706
+ }
687
707
  return /* @__PURE__ */ jsx(
688
708
  "a",
689
709
  {
@@ -702,6 +722,31 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
702
722
  return null;
703
723
  }
704
724
  }
725
+ function EmbedImage({ attrs, target, src, alt, title, className }) {
726
+ const config = useNcmConfig();
727
+ const Fallback = config.embeddings?.renderImageError;
728
+ const [failedSrc, setFailedSrc] = useState(null);
729
+ useEffect(() => {
730
+ setFailedSrc(null);
731
+ }, [src]);
732
+ if (!Fallback) {
733
+ return /* @__PURE__ */ jsx("img", { ...attrs, src, alt, title, className });
734
+ }
735
+ if (failedSrc === src) {
736
+ return /* @__PURE__ */ jsx(Fallback, { target, src, alt, retry: () => setFailedSrc(null) });
737
+ }
738
+ return /* @__PURE__ */ jsx(
739
+ "img",
740
+ {
741
+ ...attrs,
742
+ src,
743
+ alt,
744
+ title,
745
+ className,
746
+ onError: () => setFailedSrc(src)
747
+ }
748
+ );
749
+ }
705
750
  function renderReadingText(content, opts) {
706
751
  if (!content) return /* @__PURE__ */ jsx(Fragment, { children: content });
707
752
  const { bionic = false, beeline = false } = opts;
@@ -737,7 +782,7 @@ function renderReadingText(content, opts) {
737
782
  return /* @__PURE__ */ jsx(Fragment, { children: pieces });
738
783
  }
739
784
  function BlockquoteBlock({ block, className }) {
740
- const lines = block.content.split("\n").filter((line) => line.trim() !== "");
785
+ const lines = block.content.split("\n");
741
786
  return /* @__PURE__ */ jsx(
742
787
  "blockquote",
743
788
  {
@@ -747,7 +792,7 @@ function BlockquoteBlock({ block, className }) {
747
792
  "data-block-id": block.id,
748
793
  "data-ncm-blockquote": "",
749
794
  className,
750
- children: lines.length <= 1 ? /* @__PURE__ */ jsx(InlineContent, { content: block.content }) : lines.map((line, index) => /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx(InlineContent, { content: line }) }, index))
795
+ children: lines.length <= 1 ? /* @__PURE__ */ jsx(InlineContent, { content: block.content }) : lines.map((line, index) => /* @__PURE__ */ jsx("p", { children: line.trim().length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content: line }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" }) }, index))
751
796
  }
752
797
  );
753
798
  }
@@ -762,7 +807,8 @@ function ChartBlock({ block, className }) {
762
807
  "data-ncm-chart": "",
763
808
  "data-ncm-chart-type": block.chartType ?? "unknown",
764
809
  className: cn(
765
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
810
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
811
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
766
812
  className
767
813
  ),
768
814
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -887,7 +933,7 @@ function CodeBlock({ block, className }) {
887
933
  "data-ncm-language": block.language,
888
934
  className: cn("relative", className),
889
935
  children: [
890
- codeConfig.copyButton !== false && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
936
+ codeConfig.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
891
937
  /* @__PURE__ */ jsx(CustomRenderer, { code: block.content, language: block.language }),
892
938
  languageLabel
893
939
  ]
@@ -906,7 +952,7 @@ function CodeBlock({ block, className }) {
906
952
  "data-ncm-language": block.language,
907
953
  className: cn("relative", className),
908
954
  children: [
909
- codeConfig?.copyButton !== false && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
955
+ codeConfig?.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
910
956
  /* @__PURE__ */ jsx("pre", { "data-ncm-code-pre": "", children: /* @__PURE__ */ jsxs("div", { className: "flex", children: [
911
957
  codeConfig?.lineNumbers && /* @__PURE__ */ jsx(LineNumbers, { count: lineCount }),
912
958
  /* @__PURE__ */ jsx("code", { "data-ncm-code": "", className: "flex-1", children: /* @__PURE__ */ jsx(DefaultShikiRenderer, { code: block.content, language: block.language }) })
@@ -942,7 +988,8 @@ function DataviewBlock({ block, className }) {
942
988
  "data-ncm-dataview": "",
943
989
  "data-ncm-query-type": block.queryType,
944
990
  className: cn(
945
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
991
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
992
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
946
993
  className
947
994
  ),
948
995
  children: /* @__PURE__ */ jsx("code", { children: block.query })
@@ -1281,7 +1328,8 @@ function HtmlBlock({ block, className }) {
1281
1328
  "data-block-id": block.id,
1282
1329
  "data-ncm-html": "",
1283
1330
  className: cn(
1284
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1331
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
1332
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1285
1333
  className
1286
1334
  ),
1287
1335
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -1319,7 +1367,7 @@ function LatexDisplayBlock({ block, className }) {
1319
1367
  "data-ncm-type": block.type,
1320
1368
  "data-block-id": block.id,
1321
1369
  "data-ncm-latex-display": "",
1322
- className: cn("overflow-x-auto", className),
1370
+ className: cn("overflow-x-auto overflow-y-hidden", className),
1323
1371
  dangerouslySetInnerHTML: { __html: html }
1324
1372
  }
1325
1373
  );
@@ -1334,7 +1382,7 @@ function LatexDisplayBlock({ block, className }) {
1334
1382
  "data-ncm-type": block.type,
1335
1383
  "data-block-id": block.id,
1336
1384
  "data-ncm-latex-display": "",
1337
- className: cn("overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm", className),
1385
+ className: cn("overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm", className),
1338
1386
  children: /* @__PURE__ */ jsx("code", { children: block.content })
1339
1387
  }
1340
1388
  );
@@ -1358,10 +1406,12 @@ function LinkBlock({ block, className }) {
1358
1406
  function ListBlock({ block, className }) {
1359
1407
  const isOrdered = block.type === "list_ordered";
1360
1408
  const Tag = isOrdered ? "ol" : "ul";
1409
+ const start = isOrdered && typeof block.marker === "number" && block.marker !== 1 ? block.marker : void 0;
1361
1410
  return /* @__PURE__ */ jsx(
1362
1411
  Tag,
1363
1412
  {
1364
1413
  role: "list",
1414
+ start,
1365
1415
  "data-ncm-block": block.id,
1366
1416
  "data-ncm-stable": block.stableId,
1367
1417
  "data-ncm-type": block.type,
@@ -1373,6 +1423,9 @@ function ListBlock({ block, className }) {
1373
1423
  }
1374
1424
  );
1375
1425
  }
1426
+ function ItemContent({ content }) {
1427
+ return content.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" });
1428
+ }
1376
1429
  function nestedItemIdKey(id) {
1377
1430
  if (!id) {
1378
1431
  return void 0;
@@ -1389,7 +1442,7 @@ function ListItems({ items, itemIds, ordered }) {
1389
1442
  return /* @__PURE__ */ jsx(Fragment, { children: items.map((item, index) => {
1390
1443
  const key = nestedItemIdKey(itemIds?.[index]) ?? `item-${index}`;
1391
1444
  if (typeof item === "string") {
1392
- return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(InlineContent, { content: item }) }, key);
1445
+ return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(ItemContent, { content: item }) }, key);
1393
1446
  }
1394
1447
  if (isTypedNestedList(item)) {
1395
1448
  return /* @__PURE__ */ jsx(NestedTypedList, { list: item }, key);
@@ -1399,7 +1452,7 @@ function ListItems({ items, itemIds, ordered }) {
1399
1452
  const content = typeof first === "string" ? first : "";
1400
1453
  const nestedContent = processNestedItems(rest, ordered);
1401
1454
  return /* @__PURE__ */ jsxs("li", { "data-ncm-list-item": "", children: [
1402
- /* @__PURE__ */ jsx(InlineContent, { content }),
1455
+ /* @__PURE__ */ jsx(ItemContent, { content }),
1403
1456
  nestedContent
1404
1457
  ] }, key);
1405
1458
  }
@@ -1449,7 +1502,7 @@ function MathBlock({ block, className }) {
1449
1502
  "data-ncm-type": block.type,
1450
1503
  "data-block-id": block.id,
1451
1504
  "data-ncm-math": "",
1452
- className: cn("overflow-x-auto", className),
1505
+ className: cn("overflow-x-auto overflow-y-hidden", className),
1453
1506
  dangerouslySetInnerHTML: { __html: html }
1454
1507
  }
1455
1508
  );
@@ -1465,7 +1518,8 @@ function MathBlock({ block, className }) {
1465
1518
  "data-block-id": block.id,
1466
1519
  "data-ncm-math": "",
1467
1520
  className: cn(
1468
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1521
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
1522
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1469
1523
  className
1470
1524
  ),
1471
1525
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -1483,7 +1537,8 @@ function MermaidBlock({ block, className }) {
1483
1537
  "data-ncm-mermaid": "",
1484
1538
  "data-ncm-diagram-type": block.diagramType,
1485
1539
  className: cn(
1486
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1540
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
1541
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1487
1542
  className
1488
1543
  ),
1489
1544
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -1544,7 +1599,7 @@ function TableBlock({ block, className }) {
1544
1599
  "data-ncm-type": block.type,
1545
1600
  "data-block-id": block.id,
1546
1601
  "data-ncm-table": "",
1547
- className: cn("w-full overflow-x-auto", className),
1602
+ className: cn("w-full overflow-x-auto overflow-y-hidden", className),
1548
1603
  children: /* @__PURE__ */ jsxs("table", { role: "table", "data-ncm-table-element": "", children: [
1549
1604
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { "data-ncm-table-row": "", children: block.headers.map((header, index) => /* @__PURE__ */ jsx("th", { "data-ncm-table-header": "", children: /* @__PURE__ */ jsx(InlineContent, { content: header }) }, index)) }) }),
1550
1605
  /* @__PURE__ */ jsx("tbody", { children: block.rows.map((row, rowIndex) => {
@@ -1558,6 +1613,7 @@ function TableBlock({ block, className }) {
1558
1613
  function TaskItems({ items }) {
1559
1614
  return /* @__PURE__ */ jsx(Fragment, { children: items.map((item) => {
1560
1615
  const status = item.checked ? "Completed" : "Incomplete";
1616
+ const text = serializeInlineContent(item.content);
1561
1617
  return /* @__PURE__ */ jsxs(
1562
1618
  "li",
1563
1619
  {
@@ -1584,7 +1640,7 @@ function TaskItems({ items }) {
1584
1640
  ":",
1585
1641
  " "
1586
1642
  ] }),
1587
- /* @__PURE__ */ jsx(InlineContent, { content: serializeInlineContent(item.content) })
1643
+ text.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content: text }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" })
1588
1644
  ] })
1589
1645
  ] }),
1590
1646
  item.children ? /* @__PURE__ */ jsx("ul", { role: "list", "data-ncm-list-nested": "", className: "ml-6 list-none", children: /* @__PURE__ */ jsx(TaskItems, { items: item.children.items }) }) : null
@@ -1629,7 +1685,7 @@ function FallbackBlock({ block, className }) {
1629
1685
  "data-block-id": block.id,
1630
1686
  "data-ncm-fallback": "",
1631
1687
  className: cn(
1632
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1688
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1633
1689
  className
1634
1690
  )
1635
1691
  },
@@ -1685,7 +1741,7 @@ function CustomCodeBlock({ block, className }) {
1685
1741
  "data-block-id": block.id,
1686
1742
  "data-ncm-custom-code": "",
1687
1743
  "data-ncm-language": block.language,
1688
- className: cn("overflow-x-auto", className),
1744
+ className: cn("overflow-x-auto overflow-y-hidden", className),
1689
1745
  children: [
1690
1746
  /* @__PURE__ */ jsx("div", { className: "mb-2 text-xs font-medium text-muted-foreground", children: block.language }),
1691
1747
  /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: block.content }) })
@@ -1836,5 +1892,41 @@ function NcmDocument({
1836
1892
  }
1837
1893
  );
1838
1894
  }
1895
+ function NcmBlockPreview({
1896
+ source,
1897
+ expectedType,
1898
+ theme = "nuu",
1899
+ config,
1900
+ className
1901
+ }) {
1902
+ const parsed = useMemo(() => {
1903
+ try {
1904
+ const doc = parseNcm(source, {
1905
+ preset: "ncm-full",
1906
+ allowMissingFrontmatter: true,
1907
+ rawHtml: true
1908
+ });
1909
+ const all = doc.blocks ?? [];
1910
+ const blocks = expectedType ? all.filter((b) => b.type === expectedType) : all;
1911
+ return { blocks, failed: blocks.length === 0 };
1912
+ } catch {
1913
+ return { blocks: [], failed: true };
1914
+ }
1915
+ }, [source, expectedType]);
1916
+ if (parsed.failed) {
1917
+ return /* @__PURE__ */ jsx(
1918
+ "div",
1919
+ {
1920
+ "data-ncm-parse-warning": "",
1921
+ "data-ncm-theme": theme,
1922
+ className: `ncm-theme-${theme}${className ? ` ${className}` : ""}`,
1923
+ role: "status",
1924
+ children: expectedType ? `Cannot be parsed as ${expectedType}` : "Cannot be parsed"
1925
+ }
1926
+ );
1927
+ }
1928
+ const document2 = /* @__PURE__ */ jsx(NcmDocument, { blocks: parsed.blocks, theme, className });
1929
+ return config ? /* @__PURE__ */ jsx(NcmProvider, { config, children: document2 }) : document2;
1930
+ }
1839
1931
 
1840
- export { BlockShell, ChildBlocks, NcmBlock, NcmDocument, blockDataAttributes, blockKey };
1932
+ export { BlockShell, ChildBlocks, NcmBlock, NcmBlockPreview, NcmDocument, blockDataAttributes, blockKey };
@@ -1,7 +1,6 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
1
+ import * as react from 'react';
2
2
  import { Block } from '@nuucognition/ncm';
3
3
  import { b as BlockRendererRegistry } from '../renderers-C5f41FCy.js';
4
- import 'react';
5
4
 
6
5
  interface NcmBlockProps {
7
6
  block: Block;
@@ -23,6 +22,6 @@ interface NcmBlockProps {
23
22
  * />
24
23
  * ```
25
24
  */
26
- declare function NcmBlock({ block, className, renderers }: NcmBlockProps): react_jsx_runtime.JSX.Element;
25
+ declare function NcmBlock({ block, className, renderers }: NcmBlockProps): react.JSX.Element;
27
26
 
28
27
  export { NcmBlock, type NcmBlockProps };
@@ -575,9 +575,10 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
575
575
  case "image": {
576
576
  const src = config.inline?.resolveAssetPath?.(token.src) ?? token.src;
577
577
  return /* @__PURE__ */ jsx(
578
- "img",
578
+ EmbedImage,
579
579
  {
580
- "data-ncm-token": "image",
580
+ attrs: { "data-ncm-token": "image" },
581
+ target: token.src,
581
582
  src,
582
583
  alt: token.alt,
583
584
  title: token.title
@@ -611,10 +612,13 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
611
612
  }
612
613
  if (embedType === "image") {
613
614
  return /* @__PURE__ */ jsx(
614
- "img",
615
+ EmbedImage,
615
616
  {
616
- "data-ncm-token": "wiki_embed",
617
- "data-ncm-wikiembed-type": embedType,
617
+ attrs: {
618
+ "data-ncm-token": "wiki_embed",
619
+ "data-ncm-wikiembed-type": embedType
620
+ },
621
+ target: token.target,
618
622
  src: url,
619
623
  alt: token.display ?? token.target,
620
624
  className: config.embeddings?.imageClassName
@@ -645,6 +649,22 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
645
649
  }
646
650
  );
647
651
  }
652
+ const onEmbedClick = config.embeddings?.onEmbedClick;
653
+ if (onEmbedClick) {
654
+ const handleClick = (e) => {
655
+ onEmbedClick(token.target, result, e);
656
+ };
657
+ return /* @__PURE__ */ jsx(
658
+ "button",
659
+ {
660
+ type: "button",
661
+ "data-ncm-token": "wiki_embed",
662
+ "data-ncm-wikiembed-type": embedType,
663
+ onClick: handleClick,
664
+ children: token.display ?? token.target
665
+ }
666
+ );
667
+ }
648
668
  return /* @__PURE__ */ jsx(
649
669
  "a",
650
670
  {
@@ -663,6 +683,31 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
663
683
  return null;
664
684
  }
665
685
  }
686
+ function EmbedImage({ attrs, target, src, alt, title, className }) {
687
+ const config = useNcmConfig();
688
+ const Fallback = config.embeddings?.renderImageError;
689
+ const [failedSrc, setFailedSrc] = useState(null);
690
+ useEffect(() => {
691
+ setFailedSrc(null);
692
+ }, [src]);
693
+ if (!Fallback) {
694
+ return /* @__PURE__ */ jsx("img", { ...attrs, src, alt, title, className });
695
+ }
696
+ if (failedSrc === src) {
697
+ return /* @__PURE__ */ jsx(Fallback, { target, src, alt, retry: () => setFailedSrc(null) });
698
+ }
699
+ return /* @__PURE__ */ jsx(
700
+ "img",
701
+ {
702
+ ...attrs,
703
+ src,
704
+ alt,
705
+ title,
706
+ className,
707
+ onError: () => setFailedSrc(src)
708
+ }
709
+ );
710
+ }
666
711
  function renderReadingText(content, opts) {
667
712
  if (!content) return /* @__PURE__ */ jsx(Fragment, { children: content });
668
713
  const { bionic = false, beeline = false } = opts;
@@ -698,7 +743,7 @@ function renderReadingText(content, opts) {
698
743
  return /* @__PURE__ */ jsx(Fragment, { children: pieces });
699
744
  }
700
745
  function BlockquoteBlock({ block, className }) {
701
- const lines = block.content.split("\n").filter((line) => line.trim() !== "");
746
+ const lines = block.content.split("\n");
702
747
  return /* @__PURE__ */ jsx(
703
748
  "blockquote",
704
749
  {
@@ -708,7 +753,7 @@ function BlockquoteBlock({ block, className }) {
708
753
  "data-block-id": block.id,
709
754
  "data-ncm-blockquote": "",
710
755
  className,
711
- children: lines.length <= 1 ? /* @__PURE__ */ jsx(InlineContent, { content: block.content }) : lines.map((line, index) => /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx(InlineContent, { content: line }) }, index))
756
+ children: lines.length <= 1 ? /* @__PURE__ */ jsx(InlineContent, { content: block.content }) : lines.map((line, index) => /* @__PURE__ */ jsx("p", { children: line.trim().length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content: line }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" }) }, index))
712
757
  }
713
758
  );
714
759
  }
@@ -723,7 +768,8 @@ function ChartBlock({ block, className }) {
723
768
  "data-ncm-chart": "",
724
769
  "data-ncm-chart-type": block.chartType ?? "unknown",
725
770
  className: cn(
726
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
771
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
772
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
727
773
  className
728
774
  ),
729
775
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -848,7 +894,7 @@ function CodeBlock({ block, className }) {
848
894
  "data-ncm-language": block.language,
849
895
  className: cn("relative", className),
850
896
  children: [
851
- codeConfig.copyButton !== false && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
897
+ codeConfig.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
852
898
  /* @__PURE__ */ jsx(CustomRenderer, { code: block.content, language: block.language }),
853
899
  languageLabel
854
900
  ]
@@ -867,7 +913,7 @@ function CodeBlock({ block, className }) {
867
913
  "data-ncm-language": block.language,
868
914
  className: cn("relative", className),
869
915
  children: [
870
- codeConfig?.copyButton !== false && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
916
+ codeConfig?.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
871
917
  /* @__PURE__ */ jsx("pre", { "data-ncm-code-pre": "", children: /* @__PURE__ */ jsxs("div", { className: "flex", children: [
872
918
  codeConfig?.lineNumbers && /* @__PURE__ */ jsx(LineNumbers, { count: lineCount }),
873
919
  /* @__PURE__ */ jsx("code", { "data-ncm-code": "", className: "flex-1", children: /* @__PURE__ */ jsx(DefaultShikiRenderer, { code: block.content, language: block.language }) })
@@ -903,7 +949,8 @@ function DataviewBlock({ block, className }) {
903
949
  "data-ncm-dataview": "",
904
950
  "data-ncm-query-type": block.queryType,
905
951
  className: cn(
906
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
952
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
953
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
907
954
  className
908
955
  ),
909
956
  children: /* @__PURE__ */ jsx("code", { children: block.query })
@@ -1242,7 +1289,8 @@ function HtmlBlock({ block, className }) {
1242
1289
  "data-block-id": block.id,
1243
1290
  "data-ncm-html": "",
1244
1291
  className: cn(
1245
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1292
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
1293
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1246
1294
  className
1247
1295
  ),
1248
1296
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -1280,7 +1328,7 @@ function LatexDisplayBlock({ block, className }) {
1280
1328
  "data-ncm-type": block.type,
1281
1329
  "data-block-id": block.id,
1282
1330
  "data-ncm-latex-display": "",
1283
- className: cn("overflow-x-auto", className),
1331
+ className: cn("overflow-x-auto overflow-y-hidden", className),
1284
1332
  dangerouslySetInnerHTML: { __html: html }
1285
1333
  }
1286
1334
  );
@@ -1295,7 +1343,7 @@ function LatexDisplayBlock({ block, className }) {
1295
1343
  "data-ncm-type": block.type,
1296
1344
  "data-block-id": block.id,
1297
1345
  "data-ncm-latex-display": "",
1298
- className: cn("overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm", className),
1346
+ className: cn("overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm", className),
1299
1347
  children: /* @__PURE__ */ jsx("code", { children: block.content })
1300
1348
  }
1301
1349
  );
@@ -1319,10 +1367,12 @@ function LinkBlock({ block, className }) {
1319
1367
  function ListBlock({ block, className }) {
1320
1368
  const isOrdered = block.type === "list_ordered";
1321
1369
  const Tag = isOrdered ? "ol" : "ul";
1370
+ const start = isOrdered && typeof block.marker === "number" && block.marker !== 1 ? block.marker : void 0;
1322
1371
  return /* @__PURE__ */ jsx(
1323
1372
  Tag,
1324
1373
  {
1325
1374
  role: "list",
1375
+ start,
1326
1376
  "data-ncm-block": block.id,
1327
1377
  "data-ncm-stable": block.stableId,
1328
1378
  "data-ncm-type": block.type,
@@ -1334,6 +1384,9 @@ function ListBlock({ block, className }) {
1334
1384
  }
1335
1385
  );
1336
1386
  }
1387
+ function ItemContent({ content }) {
1388
+ return content.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" });
1389
+ }
1337
1390
  function nestedItemIdKey(id) {
1338
1391
  if (!id) {
1339
1392
  return void 0;
@@ -1350,7 +1403,7 @@ function ListItems({ items, itemIds, ordered }) {
1350
1403
  return /* @__PURE__ */ jsx(Fragment, { children: items.map((item, index) => {
1351
1404
  const key = nestedItemIdKey(itemIds?.[index]) ?? `item-${index}`;
1352
1405
  if (typeof item === "string") {
1353
- return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(InlineContent, { content: item }) }, key);
1406
+ return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(ItemContent, { content: item }) }, key);
1354
1407
  }
1355
1408
  if (isTypedNestedList(item)) {
1356
1409
  return /* @__PURE__ */ jsx(NestedTypedList, { list: item }, key);
@@ -1360,7 +1413,7 @@ function ListItems({ items, itemIds, ordered }) {
1360
1413
  const content = typeof first === "string" ? first : "";
1361
1414
  const nestedContent = processNestedItems(rest, ordered);
1362
1415
  return /* @__PURE__ */ jsxs("li", { "data-ncm-list-item": "", children: [
1363
- /* @__PURE__ */ jsx(InlineContent, { content }),
1416
+ /* @__PURE__ */ jsx(ItemContent, { content }),
1364
1417
  nestedContent
1365
1418
  ] }, key);
1366
1419
  }
@@ -1410,7 +1463,7 @@ function MathBlock({ block, className }) {
1410
1463
  "data-ncm-type": block.type,
1411
1464
  "data-block-id": block.id,
1412
1465
  "data-ncm-math": "",
1413
- className: cn("overflow-x-auto", className),
1466
+ className: cn("overflow-x-auto overflow-y-hidden", className),
1414
1467
  dangerouslySetInnerHTML: { __html: html }
1415
1468
  }
1416
1469
  );
@@ -1426,7 +1479,8 @@ function MathBlock({ block, className }) {
1426
1479
  "data-block-id": block.id,
1427
1480
  "data-ncm-math": "",
1428
1481
  className: cn(
1429
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1482
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
1483
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1430
1484
  className
1431
1485
  ),
1432
1486
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -1444,7 +1498,8 @@ function MermaidBlock({ block, className }) {
1444
1498
  "data-ncm-mermaid": "",
1445
1499
  "data-ncm-diagram-type": block.diagramType,
1446
1500
  className: cn(
1447
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1501
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
1502
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1448
1503
  className
1449
1504
  ),
1450
1505
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -1505,7 +1560,7 @@ function TableBlock({ block, className }) {
1505
1560
  "data-ncm-type": block.type,
1506
1561
  "data-block-id": block.id,
1507
1562
  "data-ncm-table": "",
1508
- className: cn("w-full overflow-x-auto", className),
1563
+ className: cn("w-full overflow-x-auto overflow-y-hidden", className),
1509
1564
  children: /* @__PURE__ */ jsxs("table", { role: "table", "data-ncm-table-element": "", children: [
1510
1565
  /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { "data-ncm-table-row": "", children: block.headers.map((header, index) => /* @__PURE__ */ jsx("th", { "data-ncm-table-header": "", children: /* @__PURE__ */ jsx(InlineContent, { content: header }) }, index)) }) }),
1511
1566
  /* @__PURE__ */ jsx("tbody", { children: block.rows.map((row, rowIndex) => {
@@ -1519,6 +1574,7 @@ function TableBlock({ block, className }) {
1519
1574
  function TaskItems({ items }) {
1520
1575
  return /* @__PURE__ */ jsx(Fragment, { children: items.map((item) => {
1521
1576
  const status = item.checked ? "Completed" : "Incomplete";
1577
+ const text = serializeInlineContent(item.content);
1522
1578
  return /* @__PURE__ */ jsxs(
1523
1579
  "li",
1524
1580
  {
@@ -1545,7 +1601,7 @@ function TaskItems({ items }) {
1545
1601
  ":",
1546
1602
  " "
1547
1603
  ] }),
1548
- /* @__PURE__ */ jsx(InlineContent, { content: serializeInlineContent(item.content) })
1604
+ text.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content: text }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" })
1549
1605
  ] })
1550
1606
  ] }),
1551
1607
  item.children ? /* @__PURE__ */ jsx("ul", { role: "list", "data-ncm-list-nested": "", className: "ml-6 list-none", children: /* @__PURE__ */ jsx(TaskItems, { items: item.children.items }) }) : null
@@ -1590,7 +1646,7 @@ function FallbackBlock({ block, className }) {
1590
1646
  "data-block-id": block.id,
1591
1647
  "data-ncm-fallback": "",
1592
1648
  className: cn(
1593
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1649
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1594
1650
  className
1595
1651
  )
1596
1652
  },
@@ -1646,7 +1702,7 @@ function CustomCodeBlock({ block, className }) {
1646
1702
  "data-block-id": block.id,
1647
1703
  "data-ncm-custom-code": "",
1648
1704
  "data-ncm-language": block.language,
1649
- className: cn("overflow-x-auto", className),
1705
+ className: cn("overflow-x-auto overflow-y-hidden", className),
1650
1706
  children: [
1651
1707
  /* @__PURE__ */ jsx("div", { className: "mb-2 text-xs font-medium text-muted-foreground", children: block.language }),
1652
1708
  /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: block.content }) })
@@ -1,8 +1,8 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { Block } from '@nuucognition/ncm';
1
+ import * as react from 'react';
3
2
  import { ReactNode } from 'react';
3
+ import { Block } from '@nuucognition/ncm';
4
4
  import { b as BlockRendererRegistry } from '../renderers-C5f41FCy.js';
5
- import { I as InlineConfig, E as EmbeddingsConfig } from '../use-ncm-config-D0doMYTH.js';
5
+ import { a as InlineConfig, E as EmbeddingsConfig } from '../use-ncm-config-CnntcShj.js';
6
6
  import '@nuucognition/mesh-core';
7
7
 
8
8
  type NcmTheme = "nuu" | "paper";
@@ -43,6 +43,6 @@ interface NcmDocumentProps {
43
43
  * <NcmDocument blocks={blocks} theme="paper" />
44
44
  * ```
45
45
  */
46
- declare function NcmDocument({ blocks, theme, className, renderers: propsRenderers, blockClassName, renderBlock, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, }: NcmDocumentProps): react_jsx_runtime.JSX.Element;
46
+ declare function NcmDocument({ blocks, theme, className, renderers: propsRenderers, blockClassName, renderBlock, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, }: NcmDocumentProps): react.JSX.Element;
47
47
 
48
48
  export { NcmDocument, type NcmDocumentProps, type NcmTheme };