@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
@@ -26,7 +26,7 @@ function CustomCodeBlock({ block, className }) {
26
26
  "data-block-id": block.id,
27
27
  "data-ncm-custom-code": "",
28
28
  "data-ncm-language": block.language,
29
- className: cn("overflow-x-auto", className),
29
+ className: cn("overflow-x-auto overflow-y-hidden", className),
30
30
  children: [
31
31
  /* @__PURE__ */ jsx("div", { className: "mb-2 text-xs font-medium text-muted-foreground", children: block.language }),
32
32
  /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: block.content }) })
@@ -650,9 +650,10 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
650
650
  case "image": {
651
651
  const src = config.inline?.resolveAssetPath?.(token.src) ?? token.src;
652
652
  return /* @__PURE__ */ jsx(
653
- "img",
653
+ EmbedImage,
654
654
  {
655
- "data-ncm-token": "image",
655
+ attrs: { "data-ncm-token": "image" },
656
+ target: token.src,
656
657
  src,
657
658
  alt: token.alt,
658
659
  title: token.title
@@ -686,10 +687,13 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
686
687
  }
687
688
  if (embedType === "image") {
688
689
  return /* @__PURE__ */ jsx(
689
- "img",
690
+ EmbedImage,
690
691
  {
691
- "data-ncm-token": "wiki_embed",
692
- "data-ncm-wikiembed-type": embedType,
692
+ attrs: {
693
+ "data-ncm-token": "wiki_embed",
694
+ "data-ncm-wikiembed-type": embedType
695
+ },
696
+ target: token.target,
693
697
  src: url,
694
698
  alt: token.display ?? token.target,
695
699
  className: config.embeddings?.imageClassName
@@ -720,6 +724,22 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
720
724
  }
721
725
  );
722
726
  }
727
+ const onEmbedClick = config.embeddings?.onEmbedClick;
728
+ if (onEmbedClick) {
729
+ const handleClick = (e) => {
730
+ onEmbedClick(token.target, result, e);
731
+ };
732
+ return /* @__PURE__ */ jsx(
733
+ "button",
734
+ {
735
+ type: "button",
736
+ "data-ncm-token": "wiki_embed",
737
+ "data-ncm-wikiembed-type": embedType,
738
+ onClick: handleClick,
739
+ children: token.display ?? token.target
740
+ }
741
+ );
742
+ }
723
743
  return /* @__PURE__ */ jsx(
724
744
  "a",
725
745
  {
@@ -738,6 +758,31 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
738
758
  return null;
739
759
  }
740
760
  }
761
+ function EmbedImage({ attrs, target, src, alt, title, className }) {
762
+ const config = useNcmConfig();
763
+ const Fallback = config.embeddings?.renderImageError;
764
+ const [failedSrc, setFailedSrc] = useState(null);
765
+ useEffect(() => {
766
+ setFailedSrc(null);
767
+ }, [src]);
768
+ if (!Fallback) {
769
+ return /* @__PURE__ */ jsx("img", { ...attrs, src, alt, title, className });
770
+ }
771
+ if (failedSrc === src) {
772
+ return /* @__PURE__ */ jsx(Fallback, { target, src, alt, retry: () => setFailedSrc(null) });
773
+ }
774
+ return /* @__PURE__ */ jsx(
775
+ "img",
776
+ {
777
+ ...attrs,
778
+ src,
779
+ alt,
780
+ title,
781
+ className,
782
+ onError: () => setFailedSrc(src)
783
+ }
784
+ );
785
+ }
741
786
  function renderReadingText(content, opts) {
742
787
  if (!content) return /* @__PURE__ */ jsx(Fragment, { children: content });
743
788
  const { bionic = false, beeline = false } = opts;
@@ -773,7 +818,7 @@ function renderReadingText(content, opts) {
773
818
  return /* @__PURE__ */ jsx(Fragment, { children: pieces });
774
819
  }
775
820
  function BlockquoteBlock({ block, className }) {
776
- const lines = block.content.split("\n").filter((line) => line.trim() !== "");
821
+ const lines = block.content.split("\n");
777
822
  return /* @__PURE__ */ jsx(
778
823
  "blockquote",
779
824
  {
@@ -783,7 +828,7 @@ function BlockquoteBlock({ block, className }) {
783
828
  "data-block-id": block.id,
784
829
  "data-ncm-blockquote": "",
785
830
  className,
786
- children: lines.length <= 1 ? /* @__PURE__ */ jsx(InlineContent, { content: block.content }) : lines.map((line, index) => /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx(InlineContent, { content: line }) }, index))
831
+ 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))
787
832
  }
788
833
  );
789
834
  }
@@ -798,7 +843,8 @@ function ChartBlock({ block, className }) {
798
843
  "data-ncm-chart": "",
799
844
  "data-ncm-chart-type": block.chartType ?? "unknown",
800
845
  className: cn(
801
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
846
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
847
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
802
848
  className
803
849
  ),
804
850
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -923,7 +969,7 @@ function CodeBlock({ block, className }) {
923
969
  "data-ncm-language": block.language,
924
970
  className: cn("relative", className),
925
971
  children: [
926
- codeConfig.copyButton !== false && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
972
+ codeConfig.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
927
973
  /* @__PURE__ */ jsx(CustomRenderer, { code: block.content, language: block.language }),
928
974
  languageLabel
929
975
  ]
@@ -942,7 +988,7 @@ function CodeBlock({ block, className }) {
942
988
  "data-ncm-language": block.language,
943
989
  className: cn("relative", className),
944
990
  children: [
945
- codeConfig?.copyButton !== false && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
991
+ codeConfig?.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
946
992
  /* @__PURE__ */ jsx("pre", { "data-ncm-code-pre": "", children: /* @__PURE__ */ jsxs("div", { className: "flex", children: [
947
993
  codeConfig?.lineNumbers && /* @__PURE__ */ jsx(LineNumbers, { count: lineCount }),
948
994
  /* @__PURE__ */ jsx("code", { "data-ncm-code": "", className: "flex-1", children: /* @__PURE__ */ jsx(DefaultShikiRenderer, { code: block.content, language: block.language }) })
@@ -978,7 +1024,8 @@ function DataviewBlock({ block, className }) {
978
1024
  "data-ncm-dataview": "",
979
1025
  "data-ncm-query-type": block.queryType,
980
1026
  className: cn(
981
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1027
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
1028
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
982
1029
  className
983
1030
  ),
984
1031
  children: /* @__PURE__ */ jsx("code", { children: block.query })
@@ -1317,7 +1364,8 @@ function HtmlBlock({ block, className }) {
1317
1364
  "data-block-id": block.id,
1318
1365
  "data-ncm-html": "",
1319
1366
  className: cn(
1320
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1367
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
1368
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1321
1369
  className
1322
1370
  ),
1323
1371
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -1355,7 +1403,7 @@ function LatexDisplayBlock({ block, className }) {
1355
1403
  "data-ncm-type": block.type,
1356
1404
  "data-block-id": block.id,
1357
1405
  "data-ncm-latex-display": "",
1358
- className: cn("overflow-x-auto", className),
1406
+ className: cn("overflow-x-auto overflow-y-hidden", className),
1359
1407
  dangerouslySetInnerHTML: { __html: html }
1360
1408
  }
1361
1409
  );
@@ -1370,7 +1418,7 @@ function LatexDisplayBlock({ block, className }) {
1370
1418
  "data-ncm-type": block.type,
1371
1419
  "data-block-id": block.id,
1372
1420
  "data-ncm-latex-display": "",
1373
- className: cn("overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm", className),
1421
+ className: cn("overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm", className),
1374
1422
  children: /* @__PURE__ */ jsx("code", { children: block.content })
1375
1423
  }
1376
1424
  );
@@ -1394,10 +1442,12 @@ function LinkBlock({ block, className }) {
1394
1442
  function ListBlock({ block, className }) {
1395
1443
  const isOrdered = block.type === "list_ordered";
1396
1444
  const Tag = isOrdered ? "ol" : "ul";
1445
+ const start = isOrdered && typeof block.marker === "number" && block.marker !== 1 ? block.marker : void 0;
1397
1446
  return /* @__PURE__ */ jsx(
1398
1447
  Tag,
1399
1448
  {
1400
1449
  role: "list",
1450
+ start,
1401
1451
  "data-ncm-block": block.id,
1402
1452
  "data-ncm-stable": block.stableId,
1403
1453
  "data-ncm-type": block.type,
@@ -1409,6 +1459,9 @@ function ListBlock({ block, className }) {
1409
1459
  }
1410
1460
  );
1411
1461
  }
1462
+ function ItemContent({ content }) {
1463
+ return content.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" });
1464
+ }
1412
1465
  function nestedItemIdKey(id) {
1413
1466
  if (!id) {
1414
1467
  return void 0;
@@ -1425,7 +1478,7 @@ function ListItems({ items, itemIds, ordered }) {
1425
1478
  return /* @__PURE__ */ jsx(Fragment, { children: items.map((item, index) => {
1426
1479
  const key = nestedItemIdKey(itemIds?.[index]) ?? `item-${index}`;
1427
1480
  if (typeof item === "string") {
1428
- return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(InlineContent, { content: item }) }, key);
1481
+ return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(ItemContent, { content: item }) }, key);
1429
1482
  }
1430
1483
  if (isTypedNestedList(item)) {
1431
1484
  return /* @__PURE__ */ jsx(NestedTypedList, { list: item }, key);
@@ -1435,7 +1488,7 @@ function ListItems({ items, itemIds, ordered }) {
1435
1488
  const content = typeof first === "string" ? first : "";
1436
1489
  const nestedContent = processNestedItems(rest, ordered);
1437
1490
  return /* @__PURE__ */ jsxs("li", { "data-ncm-list-item": "", children: [
1438
- /* @__PURE__ */ jsx(InlineContent, { content }),
1491
+ /* @__PURE__ */ jsx(ItemContent, { content }),
1439
1492
  nestedContent
1440
1493
  ] }, key);
1441
1494
  }
@@ -1485,7 +1538,7 @@ function MathBlock({ block, className }) {
1485
1538
  "data-ncm-type": block.type,
1486
1539
  "data-block-id": block.id,
1487
1540
  "data-ncm-math": "",
1488
- className: cn("overflow-x-auto", className),
1541
+ className: cn("overflow-x-auto overflow-y-hidden", className),
1489
1542
  dangerouslySetInnerHTML: { __html: html }
1490
1543
  }
1491
1544
  );
@@ -1501,7 +1554,8 @@ function MathBlock({ block, className }) {
1501
1554
  "data-block-id": block.id,
1502
1555
  "data-ncm-math": "",
1503
1556
  className: cn(
1504
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1557
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
1558
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1505
1559
  className
1506
1560
  ),
1507
1561
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -1519,7 +1573,8 @@ function MermaidBlock({ block, className }) {
1519
1573
  "data-ncm-mermaid": "",
1520
1574
  "data-ncm-diagram-type": block.diagramType,
1521
1575
  className: cn(
1522
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1576
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
1577
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1523
1578
  className
1524
1579
  ),
1525
1580
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -1580,7 +1635,7 @@ function TableBlock({ block, className }) {
1580
1635
  "data-ncm-type": block.type,
1581
1636
  "data-block-id": block.id,
1582
1637
  "data-ncm-table": "",
1583
- className: cn("w-full overflow-x-auto", className),
1638
+ className: cn("w-full overflow-x-auto overflow-y-hidden", className),
1584
1639
  children: /* @__PURE__ */ jsxs("table", { role: "table", "data-ncm-table-element": "", children: [
1585
1640
  /* @__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)) }) }),
1586
1641
  /* @__PURE__ */ jsx("tbody", { children: block.rows.map((row, rowIndex) => {
@@ -1594,6 +1649,7 @@ function TableBlock({ block, className }) {
1594
1649
  function TaskItems({ items }) {
1595
1650
  return /* @__PURE__ */ jsx(Fragment, { children: items.map((item) => {
1596
1651
  const status = item.checked ? "Completed" : "Incomplete";
1652
+ const text = serializeInlineContent(item.content);
1597
1653
  return /* @__PURE__ */ jsxs(
1598
1654
  "li",
1599
1655
  {
@@ -1620,7 +1676,7 @@ function TaskItems({ items }) {
1620
1676
  ":",
1621
1677
  " "
1622
1678
  ] }),
1623
- /* @__PURE__ */ jsx(InlineContent, { content: serializeInlineContent(item.content) })
1679
+ text.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content: text }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" })
1624
1680
  ] })
1625
1681
  ] }),
1626
1682
  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
@@ -1665,7 +1721,7 @@ function FallbackBlock({ block, className }) {
1665
1721
  "data-block-id": block.id,
1666
1722
  "data-ncm-fallback": "",
1667
1723
  className: cn(
1668
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1724
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1669
1725
  className
1670
1726
  )
1671
1727
  },
@@ -1,5 +1,4 @@
1
- export { u as useNcmConfig } from '../use-ncm-config-D0doMYTH.js';
2
- import 'react/jsx-runtime';
1
+ export { u as useNcmConfig } from '../use-ncm-config-CnntcShj.js';
3
2
  import 'react';
4
3
  import '@nuucognition/mesh-core';
5
4
  import '@nuucognition/ncm';
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- export { C as CodeConfig, E as EmbeddingsConfig, I as InlineConfig, N as NcmConfig, a as NcmProvider, b as NcmProviderProps, u as useNcmConfig } from './use-ncm-config-D0doMYTH.js';
2
- export { B as BlockReferenceScope, a as BlockReferenceScopeProps, b as BlockReferenceScopeValue, I as InertReferenceScope, N as NcmReferencesProvider, c as NcmReferencesProviderProps, R as ReferenceCounts, d as ReferenceKind, e as computeReferenceBases, u as useBlockReferenceScope } from './references-Bs5wJybr.js';
1
+ export { C as CodeConfig, E as EmbeddingsConfig, I as ImageErrorProps, a as InlineConfig, N as NcmConfig, b as NcmProvider, c as NcmProviderProps, u as useNcmConfig } from './use-ncm-config-CnntcShj.js';
2
+ export { B as BlockReferenceScope, a as BlockReferenceScopeProps, b as BlockReferenceScopeValue, I as InertReferenceScope, N as NcmReferencesProvider, c as NcmReferencesProviderProps, R as ReferenceCounts, d as ReferenceKind, e as computeReferenceBases, u as useBlockReferenceScope } from './references-BYW5pnj_.js';
3
3
  export { B as BlockRenderer, a as BlockRendererProps, b as BlockRendererRegistry, C as CompleteBlockRendererRegistry, E as EmbeddingRendererProps, c as EmbeddingRendererRegistry, K as KeyedBlockType } from './renderers-C5f41FCy.js';
4
4
  export { B as BoldToken, C as CodeToken, I as ImageToken, a as InlineRefToken, b as InlineToken, c as ItalicToken, L as LatexToken, d as LinkToken, S as StrikethroughToken, T as TextToken } from './inline-DwUYUmk4.js';
5
- export { BlockShell, BlockShellProps, ChildBlocks, ChildBlocksProps, blockDataAttributes, blockKey } from './components/index.js';
5
+ export { BlockShell, BlockShellProps, ChildBlocks, ChildBlocksProps, NcmBlockPreview, NcmBlockPreviewProps, blockDataAttributes, blockKey } from './components/index.js';
6
6
  export { NcmBlock, NcmBlockProps } from './components/ncm-block.js';
7
7
  export { NcmDocument, NcmDocumentProps, NcmTheme } from './components/ncm-document.js';
8
8
  export { AdmonitionBlock, AdmonitionBlockProps } from './blocks/admonition/index.js';
@@ -36,7 +36,6 @@ export { InlineContent, InlineContentProps, ReferenceMarker, ReferenceMarkerProp
36
36
  export { useBlockRenderer, useCustomCodeRenderer } from './hooks/use-block-renderer.js';
37
37
  export { defaultRenderers } from './lib/defaults.js';
38
38
  export { cn } from './lib/utils.js';
39
- import 'react/jsx-runtime';
40
39
  import 'react';
41
40
  import '@nuucognition/mesh-core';
42
41
  import '@nuucognition/ncm';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
- import { createContext, useContext, useMemo, useRef, useId, useCallback, useState, createElement, useEffect, Component } from 'react';
2
+ import { createContext, useContext, useMemo, useRef, useId, useCallback, useState, useEffect, createElement, Component } from 'react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
- import { serializeInlineContent, sanitizeHtml, isTypedNestedList } from '@nuucognition/ncm';
4
+ import { serializeInlineContent, sanitizeHtml, isTypedNestedList, parseNcm } from '@nuucognition/ncm';
5
5
  import { clsx } from 'clsx';
6
6
  import { twMerge } from 'tailwind-merge';
7
7
  import { extractExtension, embedTypeFromExtension } from '@nuucognition/mesh-core';
@@ -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;
@@ -743,7 +788,7 @@ function renderBeelineText(content) {
743
788
  return renderReadingText(content, { beeline: true });
744
789
  }
745
790
  function BlockquoteBlock({ block, className }) {
746
- const lines = block.content.split("\n").filter((line) => line.trim() !== "");
791
+ const lines = block.content.split("\n");
747
792
  return /* @__PURE__ */ jsx(
748
793
  "blockquote",
749
794
  {
@@ -753,7 +798,7 @@ function BlockquoteBlock({ block, className }) {
753
798
  "data-block-id": block.id,
754
799
  "data-ncm-blockquote": "",
755
800
  className,
756
- children: lines.length <= 1 ? /* @__PURE__ */ jsx(InlineContent, { content: block.content }) : lines.map((line, index) => /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx(InlineContent, { content: line }) }, index))
801
+ 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))
757
802
  }
758
803
  );
759
804
  }
@@ -768,7 +813,8 @@ function ChartBlock({ block, className }) {
768
813
  "data-ncm-chart": "",
769
814
  "data-ncm-chart-type": block.chartType ?? "unknown",
770
815
  className: cn(
771
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
816
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
817
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
772
818
  className
773
819
  ),
774
820
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -893,7 +939,7 @@ function CodeBlock({ block, className }) {
893
939
  "data-ncm-language": block.language,
894
940
  className: cn("relative", className),
895
941
  children: [
896
- codeConfig.copyButton !== false && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
942
+ codeConfig.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
897
943
  /* @__PURE__ */ jsx(CustomRenderer, { code: block.content, language: block.language }),
898
944
  languageLabel
899
945
  ]
@@ -912,7 +958,7 @@ function CodeBlock({ block, className }) {
912
958
  "data-ncm-language": block.language,
913
959
  className: cn("relative", className),
914
960
  children: [
915
- codeConfig?.copyButton !== false && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
961
+ codeConfig?.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
916
962
  /* @__PURE__ */ jsx("pre", { "data-ncm-code-pre": "", children: /* @__PURE__ */ jsxs("div", { className: "flex", children: [
917
963
  codeConfig?.lineNumbers && /* @__PURE__ */ jsx(LineNumbers, { count: lineCount }),
918
964
  /* @__PURE__ */ jsx("code", { "data-ncm-code": "", className: "flex-1", children: /* @__PURE__ */ jsx(DefaultShikiRenderer, { code: block.content, language: block.language }) })
@@ -948,7 +994,8 @@ function DataviewBlock({ block, className }) {
948
994
  "data-ncm-dataview": "",
949
995
  "data-ncm-query-type": block.queryType,
950
996
  className: cn(
951
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
997
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
998
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
952
999
  className
953
1000
  ),
954
1001
  children: /* @__PURE__ */ jsx("code", { children: block.query })
@@ -1287,7 +1334,8 @@ function HtmlBlock({ block, className }) {
1287
1334
  "data-block-id": block.id,
1288
1335
  "data-ncm-html": "",
1289
1336
  className: cn(
1290
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1337
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
1338
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1291
1339
  className
1292
1340
  ),
1293
1341
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -1348,7 +1396,7 @@ function LatexDisplayBlock({ block, className }) {
1348
1396
  "data-ncm-type": block.type,
1349
1397
  "data-block-id": block.id,
1350
1398
  "data-ncm-latex-display": "",
1351
- className: cn("overflow-x-auto", className),
1399
+ className: cn("overflow-x-auto overflow-y-hidden", className),
1352
1400
  dangerouslySetInnerHTML: { __html: html }
1353
1401
  }
1354
1402
  );
@@ -1363,7 +1411,7 @@ function LatexDisplayBlock({ block, className }) {
1363
1411
  "data-ncm-type": block.type,
1364
1412
  "data-block-id": block.id,
1365
1413
  "data-ncm-latex-display": "",
1366
- className: cn("overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm", className),
1414
+ className: cn("overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm", className),
1367
1415
  children: /* @__PURE__ */ jsx("code", { children: block.content })
1368
1416
  }
1369
1417
  );
@@ -1387,10 +1435,12 @@ function LinkBlock({ block, className }) {
1387
1435
  function ListBlock({ block, className }) {
1388
1436
  const isOrdered = block.type === "list_ordered";
1389
1437
  const Tag = isOrdered ? "ol" : "ul";
1438
+ const start = isOrdered && typeof block.marker === "number" && block.marker !== 1 ? block.marker : void 0;
1390
1439
  return /* @__PURE__ */ jsx(
1391
1440
  Tag,
1392
1441
  {
1393
1442
  role: "list",
1443
+ start,
1394
1444
  "data-ncm-block": block.id,
1395
1445
  "data-ncm-stable": block.stableId,
1396
1446
  "data-ncm-type": block.type,
@@ -1402,6 +1452,9 @@ function ListBlock({ block, className }) {
1402
1452
  }
1403
1453
  );
1404
1454
  }
1455
+ function ItemContent({ content }) {
1456
+ return content.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" });
1457
+ }
1405
1458
  function nestedItemIdKey(id) {
1406
1459
  if (!id) {
1407
1460
  return void 0;
@@ -1418,7 +1471,7 @@ function ListItems({ items, itemIds, ordered }) {
1418
1471
  return /* @__PURE__ */ jsx(Fragment, { children: items.map((item, index) => {
1419
1472
  const key = nestedItemIdKey(itemIds?.[index]) ?? `item-${index}`;
1420
1473
  if (typeof item === "string") {
1421
- return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(InlineContent, { content: item }) }, key);
1474
+ return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(ItemContent, { content: item }) }, key);
1422
1475
  }
1423
1476
  if (isTypedNestedList(item)) {
1424
1477
  return /* @__PURE__ */ jsx(NestedTypedList, { list: item }, key);
@@ -1428,7 +1481,7 @@ function ListItems({ items, itemIds, ordered }) {
1428
1481
  const content = typeof first === "string" ? first : "";
1429
1482
  const nestedContent = processNestedItems(rest, ordered);
1430
1483
  return /* @__PURE__ */ jsxs("li", { "data-ncm-list-item": "", children: [
1431
- /* @__PURE__ */ jsx(InlineContent, { content }),
1484
+ /* @__PURE__ */ jsx(ItemContent, { content }),
1432
1485
  nestedContent
1433
1486
  ] }, key);
1434
1487
  }
@@ -1478,7 +1531,7 @@ function MathBlock({ block, className }) {
1478
1531
  "data-ncm-type": block.type,
1479
1532
  "data-block-id": block.id,
1480
1533
  "data-ncm-math": "",
1481
- className: cn("overflow-x-auto", className),
1534
+ className: cn("overflow-x-auto overflow-y-hidden", className),
1482
1535
  dangerouslySetInnerHTML: { __html: html }
1483
1536
  }
1484
1537
  );
@@ -1494,7 +1547,8 @@ function MathBlock({ block, className }) {
1494
1547
  "data-block-id": block.id,
1495
1548
  "data-ncm-math": "",
1496
1549
  className: cn(
1497
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1550
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
1551
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1498
1552
  className
1499
1553
  ),
1500
1554
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -1512,7 +1566,8 @@ function MermaidBlock({ block, className }) {
1512
1566
  "data-ncm-mermaid": "",
1513
1567
  "data-ncm-diagram-type": block.diagramType,
1514
1568
  className: cn(
1515
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1569
+ // `overflow-y-hidden` pairs with `overflow-x-auto` on purpose see the note in `lib/defaults.ts`.
1570
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1516
1571
  className
1517
1572
  ),
1518
1573
  children: /* @__PURE__ */ jsx("code", { children: block.content })
@@ -1573,7 +1628,7 @@ function TableBlock({ block, className }) {
1573
1628
  "data-ncm-type": block.type,
1574
1629
  "data-block-id": block.id,
1575
1630
  "data-ncm-table": "",
1576
- className: cn("w-full overflow-x-auto", className),
1631
+ className: cn("w-full overflow-x-auto overflow-y-hidden", className),
1577
1632
  children: /* @__PURE__ */ jsxs("table", { role: "table", "data-ncm-table-element": "", children: [
1578
1633
  /* @__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)) }) }),
1579
1634
  /* @__PURE__ */ jsx("tbody", { children: block.rows.map((row, rowIndex) => {
@@ -1587,6 +1642,7 @@ function TableBlock({ block, className }) {
1587
1642
  function TaskItems({ items }) {
1588
1643
  return /* @__PURE__ */ jsx(Fragment, { children: items.map((item) => {
1589
1644
  const status = item.checked ? "Completed" : "Incomplete";
1645
+ const text = serializeInlineContent(item.content);
1590
1646
  return /* @__PURE__ */ jsxs(
1591
1647
  "li",
1592
1648
  {
@@ -1613,7 +1669,7 @@ function TaskItems({ items }) {
1613
1669
  ":",
1614
1670
  " "
1615
1671
  ] }),
1616
- /* @__PURE__ */ jsx(InlineContent, { content: serializeInlineContent(item.content) })
1672
+ text.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content: text }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" })
1617
1673
  ] })
1618
1674
  ] }),
1619
1675
  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
@@ -1658,7 +1714,7 @@ function FallbackBlock({ block, className }) {
1658
1714
  "data-block-id": block.id,
1659
1715
  "data-ncm-fallback": "",
1660
1716
  className: cn(
1661
- "overflow-x-auto rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1717
+ "overflow-x-auto overflow-y-hidden rounded-lg border border-border bg-muted p-4 font-mono text-sm",
1662
1718
  className
1663
1719
  )
1664
1720
  },
@@ -1714,7 +1770,7 @@ function CustomCodeBlock({ block, className }) {
1714
1770
  "data-block-id": block.id,
1715
1771
  "data-ncm-custom-code": "",
1716
1772
  "data-ncm-language": block.language,
1717
- className: cn("overflow-x-auto", className),
1773
+ className: cn("overflow-x-auto overflow-y-hidden", className),
1718
1774
  children: [
1719
1775
  /* @__PURE__ */ jsx("div", { className: "mb-2 text-xs font-medium text-muted-foreground", children: block.language }),
1720
1776
  /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: block.content }) })
@@ -1865,6 +1921,42 @@ function NcmDocument({
1865
1921
  }
1866
1922
  );
1867
1923
  }
1924
+ function NcmBlockPreview({
1925
+ source,
1926
+ expectedType,
1927
+ theme = "nuu",
1928
+ config,
1929
+ className
1930
+ }) {
1931
+ const parsed = useMemo(() => {
1932
+ try {
1933
+ const doc = parseNcm(source, {
1934
+ preset: "ncm-full",
1935
+ allowMissingFrontmatter: true,
1936
+ rawHtml: true
1937
+ });
1938
+ const all = doc.blocks ?? [];
1939
+ const blocks = expectedType ? all.filter((b) => b.type === expectedType) : all;
1940
+ return { blocks, failed: blocks.length === 0 };
1941
+ } catch {
1942
+ return { blocks: [], failed: true };
1943
+ }
1944
+ }, [source, expectedType]);
1945
+ if (parsed.failed) {
1946
+ return /* @__PURE__ */ jsx(
1947
+ "div",
1948
+ {
1949
+ "data-ncm-parse-warning": "",
1950
+ "data-ncm-theme": theme,
1951
+ className: `ncm-theme-${theme}${className ? ` ${className}` : ""}`,
1952
+ role: "status",
1953
+ children: expectedType ? `Cannot be parsed as ${expectedType}` : "Cannot be parsed"
1954
+ }
1955
+ );
1956
+ }
1957
+ const document2 = /* @__PURE__ */ jsx(NcmDocument, { blocks: parsed.blocks, theme, className });
1958
+ return config ? /* @__PURE__ */ jsx(NcmProvider, { config, children: document2 }) : document2;
1959
+ }
1868
1960
 
1869
1961
  // src/hooks/use-block-renderer.ts
1870
1962
  function useBlockRenderer(blockType) {
@@ -1884,4 +1976,4 @@ function useCustomCodeRenderer(language) {
1884
1976
  return customCodeRenderers[language];
1885
1977
  }
1886
1978
 
1887
- export { AdmonitionBlock, AsideBlock, AttributionBlock, BlockReferenceScope, BlockShell, BlockquoteBlock, ChartBlock, ChildBlocks, CodeBlock, ContainerBlock, CustomCodeBlock, DataviewBlock, DefinitionBlock, EmbeddingBlock, FigureBlock, FootnoteBlock, FrontmatterBlock, HeaderBlock, HorizontalRuleBlock, HtmlBlock, InertReferenceScope, InlineContent, LatexDisplayBlock, LinkBlock, ListBlock, MathBlock, MermaidBlock, NcmBlock, NcmDocument, NcmProvider, NcmReferencesProvider, PageBreakerBlock, ParagraphBlock, ReferenceMarker, SanitizedHtmlBlock, SpoilerBlock, TableBlock, TaskListBlock, blockDataAttributes, blockKey, cn, computeReferenceBases, defaultRenderers, parseInline, renderBeelineText, renderBionicText, renderReadingText, useBlockReferenceScope, useBlockRenderer, useCustomCodeRenderer, useNcmConfig };
1979
+ export { AdmonitionBlock, AsideBlock, AttributionBlock, BlockReferenceScope, BlockShell, BlockquoteBlock, ChartBlock, ChildBlocks, CodeBlock, ContainerBlock, CustomCodeBlock, DataviewBlock, DefinitionBlock, EmbeddingBlock, FigureBlock, FootnoteBlock, FrontmatterBlock, HeaderBlock, HorizontalRuleBlock, HtmlBlock, InertReferenceScope, InlineContent, LatexDisplayBlock, LinkBlock, ListBlock, MathBlock, MermaidBlock, NcmBlock, NcmBlockPreview, NcmDocument, NcmProvider, NcmReferencesProvider, PageBreakerBlock, ParagraphBlock, ReferenceMarker, SanitizedHtmlBlock, SpoilerBlock, TableBlock, TaskListBlock, blockDataAttributes, blockKey, cn, computeReferenceBases, defaultRenderers, parseInline, renderBeelineText, renderBionicText, renderReadingText, useBlockReferenceScope, useBlockRenderer, useCustomCodeRenderer, useNcmConfig };