@nuucognition/ncm-ui 0.1.0-dev.1 → 0.1.1-beta.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/README.md +90 -0
- package/dist/blocks/admonition/index.d.ts +2 -3
- package/dist/blocks/admonition/index.js +63 -12
- package/dist/blocks/aside/index.d.ts +2 -3
- package/dist/blocks/aside/index.js +63 -12
- package/dist/blocks/attribution/index.d.ts +2 -3
- package/dist/blocks/blockquote/index.d.ts +5 -4
- package/dist/blocks/blockquote/index.js +52 -7
- package/dist/blocks/chart/index.d.ts +2 -3
- package/dist/blocks/code/index.d.ts +2 -3
- package/dist/blocks/code/index.js +2 -2
- package/dist/blocks/container/index.d.ts +2 -3
- package/dist/blocks/container/index.js +50 -5
- package/dist/blocks/custom-code/index.d.ts +2 -3
- package/dist/blocks/dataview/index.d.ts +2 -3
- package/dist/blocks/definition/index.d.ts +2 -3
- package/dist/blocks/definition/index.js +63 -12
- package/dist/blocks/embed/index.d.ts +2 -3
- package/dist/blocks/embedding/index.d.ts +2 -3
- package/dist/blocks/embedding/index.js +50 -5
- package/dist/blocks/figure/index.d.ts +2 -3
- package/dist/blocks/figure/index.js +50 -5
- package/dist/blocks/footnote/index.d.ts +2 -3
- package/dist/blocks/footnote/index.js +63 -12
- package/dist/blocks/frontmatter/index.d.ts +2 -3
- package/dist/blocks/header/index.d.ts +2 -3
- package/dist/blocks/header/index.js +50 -5
- package/dist/blocks/horizontal-rule/index.d.ts +2 -3
- package/dist/blocks/html/index.d.ts +3 -4
- package/dist/blocks/index.d.ts +1 -2
- package/dist/blocks/index.js +63 -12
- package/dist/blocks/latex/index.d.ts +2 -3
- package/dist/blocks/link/index.d.ts +2 -3
- package/dist/blocks/list/index.d.ts +2 -3
- package/dist/blocks/list/index.js +57 -7
- package/dist/blocks/math/index.d.ts +2 -3
- package/dist/blocks/mermaid/index.d.ts +2 -3
- package/dist/blocks/page-breaker/index.d.ts +2 -3
- package/dist/blocks/paragraph/index.d.ts +2 -3
- package/dist/blocks/paragraph/index.js +50 -5
- package/dist/blocks/spoiler/index.d.ts +2 -3
- package/dist/blocks/spoiler/index.js +63 -12
- package/dist/blocks/table/index.d.ts +2 -3
- package/dist/blocks/table/index.js +50 -5
- package/dist/blocks/task-list/index.d.ts +2 -3
- package/dist/blocks/task-list/index.js +52 -6
- package/dist/components/index.d.ts +34 -4
- package/dist/components/index.js +101 -14
- package/dist/components/ncm-block.d.ts +2 -3
- package/dist/components/ncm-block.js +63 -12
- package/dist/components/ncm-document.d.ts +4 -4
- package/dist/components/ncm-document.js +63 -12
- package/dist/context/index.d.ts +2 -3
- package/dist/hooks/index.d.ts +1 -2
- package/dist/hooks/index.js +63 -12
- package/dist/hooks/use-block-renderer.js +63 -12
- package/dist/hooks/use-ncm-config.d.ts +1 -2
- package/dist/index.d.ts +3 -4
- package/dist/index.js +102 -15
- package/dist/inline/index.d.ts +4 -4
- package/dist/inline/index.js +51 -6
- package/dist/lib/defaults.js +63 -12
- package/dist/{references-Bs5wJybr.d.ts → references-BYW5pnj_.d.ts} +4 -4
- package/dist/styles/nuu.css +304 -42
- package/dist/styles/paper.css +62 -1
- package/dist/{use-ncm-config-D0doMYTH.d.ts → use-ncm-config-CnntcShj.d.ts} +55 -4
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { createContext, useContext, useMemo, useRef, useId, useCallback, useState,
|
|
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
|
-
|
|
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
|
-
|
|
654
|
+
EmbedImage,
|
|
654
655
|
{
|
|
655
|
-
|
|
656
|
-
|
|
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")
|
|
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
|
}
|
|
@@ -893,7 +938,7 @@ function CodeBlock({ block, className }) {
|
|
|
893
938
|
"data-ncm-language": block.language,
|
|
894
939
|
className: cn("relative", className),
|
|
895
940
|
children: [
|
|
896
|
-
codeConfig.copyButton
|
|
941
|
+
codeConfig.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
|
|
897
942
|
/* @__PURE__ */ jsx(CustomRenderer, { code: block.content, language: block.language }),
|
|
898
943
|
languageLabel
|
|
899
944
|
]
|
|
@@ -912,7 +957,7 @@ function CodeBlock({ block, className }) {
|
|
|
912
957
|
"data-ncm-language": block.language,
|
|
913
958
|
className: cn("relative", className),
|
|
914
959
|
children: [
|
|
915
|
-
codeConfig?.copyButton
|
|
960
|
+
codeConfig?.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
|
|
916
961
|
/* @__PURE__ */ jsx("pre", { "data-ncm-code-pre": "", children: /* @__PURE__ */ jsxs("div", { className: "flex", children: [
|
|
917
962
|
codeConfig?.lineNumbers && /* @__PURE__ */ jsx(LineNumbers, { count: lineCount }),
|
|
918
963
|
/* @__PURE__ */ jsx("code", { "data-ncm-code": "", className: "flex-1", children: /* @__PURE__ */ jsx(DefaultShikiRenderer, { code: block.content, language: block.language }) })
|
|
@@ -1387,10 +1432,12 @@ function LinkBlock({ block, className }) {
|
|
|
1387
1432
|
function ListBlock({ block, className }) {
|
|
1388
1433
|
const isOrdered = block.type === "list_ordered";
|
|
1389
1434
|
const Tag = isOrdered ? "ol" : "ul";
|
|
1435
|
+
const start = isOrdered && typeof block.marker === "number" && block.marker !== 1 ? block.marker : void 0;
|
|
1390
1436
|
return /* @__PURE__ */ jsx(
|
|
1391
1437
|
Tag,
|
|
1392
1438
|
{
|
|
1393
1439
|
role: "list",
|
|
1440
|
+
start,
|
|
1394
1441
|
"data-ncm-block": block.id,
|
|
1395
1442
|
"data-ncm-stable": block.stableId,
|
|
1396
1443
|
"data-ncm-type": block.type,
|
|
@@ -1402,6 +1449,9 @@ function ListBlock({ block, className }) {
|
|
|
1402
1449
|
}
|
|
1403
1450
|
);
|
|
1404
1451
|
}
|
|
1452
|
+
function ItemContent({ content }) {
|
|
1453
|
+
return content.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" });
|
|
1454
|
+
}
|
|
1405
1455
|
function nestedItemIdKey(id) {
|
|
1406
1456
|
if (!id) {
|
|
1407
1457
|
return void 0;
|
|
@@ -1418,7 +1468,7 @@ function ListItems({ items, itemIds, ordered }) {
|
|
|
1418
1468
|
return /* @__PURE__ */ jsx(Fragment, { children: items.map((item, index) => {
|
|
1419
1469
|
const key = nestedItemIdKey(itemIds?.[index]) ?? `item-${index}`;
|
|
1420
1470
|
if (typeof item === "string") {
|
|
1421
|
-
return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(
|
|
1471
|
+
return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(ItemContent, { content: item }) }, key);
|
|
1422
1472
|
}
|
|
1423
1473
|
if (isTypedNestedList(item)) {
|
|
1424
1474
|
return /* @__PURE__ */ jsx(NestedTypedList, { list: item }, key);
|
|
@@ -1428,7 +1478,7 @@ function ListItems({ items, itemIds, ordered }) {
|
|
|
1428
1478
|
const content = typeof first === "string" ? first : "";
|
|
1429
1479
|
const nestedContent = processNestedItems(rest, ordered);
|
|
1430
1480
|
return /* @__PURE__ */ jsxs("li", { "data-ncm-list-item": "", children: [
|
|
1431
|
-
/* @__PURE__ */ jsx(
|
|
1481
|
+
/* @__PURE__ */ jsx(ItemContent, { content }),
|
|
1432
1482
|
nestedContent
|
|
1433
1483
|
] }, key);
|
|
1434
1484
|
}
|
|
@@ -1587,6 +1637,7 @@ function TableBlock({ block, className }) {
|
|
|
1587
1637
|
function TaskItems({ items }) {
|
|
1588
1638
|
return /* @__PURE__ */ jsx(Fragment, { children: items.map((item) => {
|
|
1589
1639
|
const status = item.checked ? "Completed" : "Incomplete";
|
|
1640
|
+
const text = serializeInlineContent(item.content);
|
|
1590
1641
|
return /* @__PURE__ */ jsxs(
|
|
1591
1642
|
"li",
|
|
1592
1643
|
{
|
|
@@ -1613,7 +1664,7 @@ function TaskItems({ items }) {
|
|
|
1613
1664
|
":",
|
|
1614
1665
|
" "
|
|
1615
1666
|
] }),
|
|
1616
|
-
/* @__PURE__ */ jsx(InlineContent, { content:
|
|
1667
|
+
text.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content: text }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" })
|
|
1617
1668
|
] })
|
|
1618
1669
|
] }),
|
|
1619
1670
|
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
|
|
@@ -1865,6 +1916,42 @@ function NcmDocument({
|
|
|
1865
1916
|
}
|
|
1866
1917
|
);
|
|
1867
1918
|
}
|
|
1919
|
+
function NcmBlockPreview({
|
|
1920
|
+
source,
|
|
1921
|
+
expectedType,
|
|
1922
|
+
theme = "nuu",
|
|
1923
|
+
config,
|
|
1924
|
+
className
|
|
1925
|
+
}) {
|
|
1926
|
+
const parsed = useMemo(() => {
|
|
1927
|
+
try {
|
|
1928
|
+
const doc = parseNcm(source, {
|
|
1929
|
+
preset: "ncm-full",
|
|
1930
|
+
allowMissingFrontmatter: true,
|
|
1931
|
+
rawHtml: true
|
|
1932
|
+
});
|
|
1933
|
+
const all = doc.blocks ?? [];
|
|
1934
|
+
const blocks = expectedType ? all.filter((b) => b.type === expectedType) : all;
|
|
1935
|
+
return { blocks, failed: blocks.length === 0 };
|
|
1936
|
+
} catch {
|
|
1937
|
+
return { blocks: [], failed: true };
|
|
1938
|
+
}
|
|
1939
|
+
}, [source, expectedType]);
|
|
1940
|
+
if (parsed.failed) {
|
|
1941
|
+
return /* @__PURE__ */ jsx(
|
|
1942
|
+
"div",
|
|
1943
|
+
{
|
|
1944
|
+
"data-ncm-parse-warning": "",
|
|
1945
|
+
"data-ncm-theme": theme,
|
|
1946
|
+
className: `ncm-theme-${theme}${className ? ` ${className}` : ""}`,
|
|
1947
|
+
role: "status",
|
|
1948
|
+
children: expectedType ? `Cannot be parsed as ${expectedType}` : "Cannot be parsed"
|
|
1949
|
+
}
|
|
1950
|
+
);
|
|
1951
|
+
}
|
|
1952
|
+
const document2 = /* @__PURE__ */ jsx(NcmDocument, { blocks: parsed.blocks, theme, className });
|
|
1953
|
+
return config ? /* @__PURE__ */ jsx(NcmProvider, { config, children: document2 }) : document2;
|
|
1954
|
+
}
|
|
1868
1955
|
|
|
1869
1956
|
// src/hooks/use-block-renderer.ts
|
|
1870
1957
|
function useBlockRenderer(blockType) {
|
|
@@ -1884,4 +1971,4 @@ function useCustomCodeRenderer(language) {
|
|
|
1884
1971
|
return customCodeRenderers[language];
|
|
1885
1972
|
}
|
|
1886
1973
|
|
|
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 };
|
|
1974
|
+
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 };
|
package/dist/inline/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { b as InlineToken } from '../inline-DwUYUmk4.js';
|
|
2
|
-
import * as
|
|
2
|
+
import * as react from 'react';
|
|
3
3
|
import { ReactNode } from 'react';
|
|
4
|
-
import { d as ReferenceKind } from '../references-
|
|
4
|
+
import { d as ReferenceKind } from '../references-BYW5pnj_.js';
|
|
5
5
|
import '@nuucognition/ncm';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -41,7 +41,7 @@ interface InlineContentProps {
|
|
|
41
41
|
* Emits semantic HTML and `data-ncm-token` attributes; visual styling is owned
|
|
42
42
|
* by the parent document's stylesheet (nuu.css or paper.css).
|
|
43
43
|
*/
|
|
44
|
-
declare function InlineContent({ content, className, disableBionic, disableBeeline, }: InlineContentProps):
|
|
44
|
+
declare function InlineContent({ content, className, disableBionic, disableBeeline, }: InlineContentProps): react.JSX.Element;
|
|
45
45
|
interface RenderReadingTextOptions {
|
|
46
46
|
bionic?: boolean;
|
|
47
47
|
bionicRatio?: number;
|
|
@@ -103,6 +103,6 @@ interface ReferenceMarkerProps {
|
|
|
103
103
|
* so it never spills outside the reading pane — measured lazily, only for the
|
|
104
104
|
* marker actually being hovered/focused, so the common case stays JS-free.
|
|
105
105
|
*/
|
|
106
|
-
declare function ReferenceMarker({ kind, number, children }: ReferenceMarkerProps):
|
|
106
|
+
declare function ReferenceMarker({ kind, number, children }: ReferenceMarkerProps): react.JSX.Element;
|
|
107
107
|
|
|
108
108
|
export { InlineContent, type InlineContentProps, ReferenceMarker, type ReferenceMarkerProps, type RenderReadingTextOptions, parseInline, renderBeelineText, renderBionicText, renderReadingText };
|
package/dist/inline/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { createContext, useId, useRef, useCallback, useMemo,
|
|
2
|
+
import { createContext, useId, useRef, useCallback, useMemo, useState, useEffect, useContext } from 'react';
|
|
3
3
|
import { extractExtension, embedTypeFromExtension } from '@nuucognition/mesh-core';
|
|
4
4
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
import '@nuucognition/ncm';
|
|
@@ -466,9 +466,10 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
|
|
|
466
466
|
case "image": {
|
|
467
467
|
const src = config.inline?.resolveAssetPath?.(token.src) ?? token.src;
|
|
468
468
|
return /* @__PURE__ */ jsx(
|
|
469
|
-
|
|
469
|
+
EmbedImage,
|
|
470
470
|
{
|
|
471
|
-
"data-ncm-token": "image",
|
|
471
|
+
attrs: { "data-ncm-token": "image" },
|
|
472
|
+
target: token.src,
|
|
472
473
|
src,
|
|
473
474
|
alt: token.alt,
|
|
474
475
|
title: token.title
|
|
@@ -502,10 +503,13 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
|
|
|
502
503
|
}
|
|
503
504
|
if (embedType === "image") {
|
|
504
505
|
return /* @__PURE__ */ jsx(
|
|
505
|
-
|
|
506
|
+
EmbedImage,
|
|
506
507
|
{
|
|
507
|
-
|
|
508
|
-
|
|
508
|
+
attrs: {
|
|
509
|
+
"data-ncm-token": "wiki_embed",
|
|
510
|
+
"data-ncm-wikiembed-type": embedType
|
|
511
|
+
},
|
|
512
|
+
target: token.target,
|
|
509
513
|
src: url,
|
|
510
514
|
alt: token.display ?? token.target,
|
|
511
515
|
className: config.embeddings?.imageClassName
|
|
@@ -536,6 +540,22 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
|
|
|
536
540
|
}
|
|
537
541
|
);
|
|
538
542
|
}
|
|
543
|
+
const onEmbedClick = config.embeddings?.onEmbedClick;
|
|
544
|
+
if (onEmbedClick) {
|
|
545
|
+
const handleClick = (e) => {
|
|
546
|
+
onEmbedClick(token.target, result, e);
|
|
547
|
+
};
|
|
548
|
+
return /* @__PURE__ */ jsx(
|
|
549
|
+
"button",
|
|
550
|
+
{
|
|
551
|
+
type: "button",
|
|
552
|
+
"data-ncm-token": "wiki_embed",
|
|
553
|
+
"data-ncm-wikiembed-type": embedType,
|
|
554
|
+
onClick: handleClick,
|
|
555
|
+
children: token.display ?? token.target
|
|
556
|
+
}
|
|
557
|
+
);
|
|
558
|
+
}
|
|
539
559
|
return /* @__PURE__ */ jsx(
|
|
540
560
|
"a",
|
|
541
561
|
{
|
|
@@ -554,6 +574,31 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
|
|
|
554
574
|
return null;
|
|
555
575
|
}
|
|
556
576
|
}
|
|
577
|
+
function EmbedImage({ attrs, target, src, alt, title, className }) {
|
|
578
|
+
const config = useNcmConfig();
|
|
579
|
+
const Fallback = config.embeddings?.renderImageError;
|
|
580
|
+
const [failedSrc, setFailedSrc] = useState(null);
|
|
581
|
+
useEffect(() => {
|
|
582
|
+
setFailedSrc(null);
|
|
583
|
+
}, [src]);
|
|
584
|
+
if (!Fallback) {
|
|
585
|
+
return /* @__PURE__ */ jsx("img", { ...attrs, src, alt, title, className });
|
|
586
|
+
}
|
|
587
|
+
if (failedSrc === src) {
|
|
588
|
+
return /* @__PURE__ */ jsx(Fallback, { target, src, alt, retry: () => setFailedSrc(null) });
|
|
589
|
+
}
|
|
590
|
+
return /* @__PURE__ */ jsx(
|
|
591
|
+
"img",
|
|
592
|
+
{
|
|
593
|
+
...attrs,
|
|
594
|
+
src,
|
|
595
|
+
alt,
|
|
596
|
+
title,
|
|
597
|
+
className,
|
|
598
|
+
onError: () => setFailedSrc(src)
|
|
599
|
+
}
|
|
600
|
+
);
|
|
601
|
+
}
|
|
557
602
|
function renderReadingText(content, opts) {
|
|
558
603
|
if (!content) return /* @__PURE__ */ jsx(Fragment, { children: content });
|
|
559
604
|
const { bionic = false, beeline = false } = opts;
|
package/dist/lib/defaults.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
690
|
+
EmbedImage,
|
|
690
691
|
{
|
|
691
|
-
|
|
692
|
-
|
|
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")
|
|
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
|
}
|
|
@@ -923,7 +968,7 @@ function CodeBlock({ block, className }) {
|
|
|
923
968
|
"data-ncm-language": block.language,
|
|
924
969
|
className: cn("relative", className),
|
|
925
970
|
children: [
|
|
926
|
-
codeConfig.copyButton
|
|
971
|
+
codeConfig.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
|
|
927
972
|
/* @__PURE__ */ jsx(CustomRenderer, { code: block.content, language: block.language }),
|
|
928
973
|
languageLabel
|
|
929
974
|
]
|
|
@@ -942,7 +987,7 @@ function CodeBlock({ block, className }) {
|
|
|
942
987
|
"data-ncm-language": block.language,
|
|
943
988
|
className: cn("relative", className),
|
|
944
989
|
children: [
|
|
945
|
-
codeConfig?.copyButton
|
|
990
|
+
codeConfig?.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
|
|
946
991
|
/* @__PURE__ */ jsx("pre", { "data-ncm-code-pre": "", children: /* @__PURE__ */ jsxs("div", { className: "flex", children: [
|
|
947
992
|
codeConfig?.lineNumbers && /* @__PURE__ */ jsx(LineNumbers, { count: lineCount }),
|
|
948
993
|
/* @__PURE__ */ jsx("code", { "data-ncm-code": "", className: "flex-1", children: /* @__PURE__ */ jsx(DefaultShikiRenderer, { code: block.content, language: block.language }) })
|
|
@@ -1394,10 +1439,12 @@ function LinkBlock({ block, className }) {
|
|
|
1394
1439
|
function ListBlock({ block, className }) {
|
|
1395
1440
|
const isOrdered = block.type === "list_ordered";
|
|
1396
1441
|
const Tag = isOrdered ? "ol" : "ul";
|
|
1442
|
+
const start = isOrdered && typeof block.marker === "number" && block.marker !== 1 ? block.marker : void 0;
|
|
1397
1443
|
return /* @__PURE__ */ jsx(
|
|
1398
1444
|
Tag,
|
|
1399
1445
|
{
|
|
1400
1446
|
role: "list",
|
|
1447
|
+
start,
|
|
1401
1448
|
"data-ncm-block": block.id,
|
|
1402
1449
|
"data-ncm-stable": block.stableId,
|
|
1403
1450
|
"data-ncm-type": block.type,
|
|
@@ -1409,6 +1456,9 @@ function ListBlock({ block, className }) {
|
|
|
1409
1456
|
}
|
|
1410
1457
|
);
|
|
1411
1458
|
}
|
|
1459
|
+
function ItemContent({ content }) {
|
|
1460
|
+
return content.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" });
|
|
1461
|
+
}
|
|
1412
1462
|
function nestedItemIdKey(id) {
|
|
1413
1463
|
if (!id) {
|
|
1414
1464
|
return void 0;
|
|
@@ -1425,7 +1475,7 @@ function ListItems({ items, itemIds, ordered }) {
|
|
|
1425
1475
|
return /* @__PURE__ */ jsx(Fragment, { children: items.map((item, index) => {
|
|
1426
1476
|
const key = nestedItemIdKey(itemIds?.[index]) ?? `item-${index}`;
|
|
1427
1477
|
if (typeof item === "string") {
|
|
1428
|
-
return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(
|
|
1478
|
+
return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(ItemContent, { content: item }) }, key);
|
|
1429
1479
|
}
|
|
1430
1480
|
if (isTypedNestedList(item)) {
|
|
1431
1481
|
return /* @__PURE__ */ jsx(NestedTypedList, { list: item }, key);
|
|
@@ -1435,7 +1485,7 @@ function ListItems({ items, itemIds, ordered }) {
|
|
|
1435
1485
|
const content = typeof first === "string" ? first : "";
|
|
1436
1486
|
const nestedContent = processNestedItems(rest, ordered);
|
|
1437
1487
|
return /* @__PURE__ */ jsxs("li", { "data-ncm-list-item": "", children: [
|
|
1438
|
-
/* @__PURE__ */ jsx(
|
|
1488
|
+
/* @__PURE__ */ jsx(ItemContent, { content }),
|
|
1439
1489
|
nestedContent
|
|
1440
1490
|
] }, key);
|
|
1441
1491
|
}
|
|
@@ -1594,6 +1644,7 @@ function TableBlock({ block, className }) {
|
|
|
1594
1644
|
function TaskItems({ items }) {
|
|
1595
1645
|
return /* @__PURE__ */ jsx(Fragment, { children: items.map((item) => {
|
|
1596
1646
|
const status = item.checked ? "Completed" : "Incomplete";
|
|
1647
|
+
const text = serializeInlineContent(item.content);
|
|
1597
1648
|
return /* @__PURE__ */ jsxs(
|
|
1598
1649
|
"li",
|
|
1599
1650
|
{
|
|
@@ -1620,7 +1671,7 @@ function TaskItems({ items }) {
|
|
|
1620
1671
|
":",
|
|
1621
1672
|
" "
|
|
1622
1673
|
] }),
|
|
1623
|
-
/* @__PURE__ */ jsx(InlineContent, { content:
|
|
1674
|
+
text.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content: text }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" })
|
|
1624
1675
|
] })
|
|
1625
1676
|
] }),
|
|
1626
1677
|
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
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { Block } from '@nuucognition/ncm';
|
|
4
4
|
|
|
@@ -37,7 +37,7 @@ interface NcmReferencesProviderProps {
|
|
|
37
37
|
children: ReactNode;
|
|
38
38
|
}
|
|
39
39
|
/** Document-root provider — runs the numbering pre-pass over `blocks`. */
|
|
40
|
-
declare function NcmReferencesProvider({ blocks, children }: NcmReferencesProviderProps):
|
|
40
|
+
declare function NcmReferencesProvider({ blocks, children }: NcmReferencesProviderProps): react.JSX.Element;
|
|
41
41
|
interface BlockReferenceScopeProps {
|
|
42
42
|
/** Block id; resolves the base offset from the document pre-pass. */
|
|
43
43
|
blockId?: string;
|
|
@@ -48,7 +48,7 @@ interface BlockReferenceScopeProps {
|
|
|
48
48
|
* on every render and hands out sequential numbers as markers render. Resetting
|
|
49
49
|
* each render keeps numbering idempotent under React re-renders / StrictMode.
|
|
50
50
|
*/
|
|
51
|
-
declare function BlockReferenceScope({ blockId, children }: BlockReferenceScopeProps):
|
|
51
|
+
declare function BlockReferenceScope({ blockId, children }: BlockReferenceScopeProps): react.JSX.Element;
|
|
52
52
|
/** Read the active per-block reference scope, if any. */
|
|
53
53
|
declare function useBlockReferenceScope(): BlockReferenceScopeValue | null;
|
|
54
54
|
/**
|
|
@@ -58,6 +58,6 @@ declare function useBlockReferenceScope(): BlockReferenceScopeValue | null;
|
|
|
58
58
|
*/
|
|
59
59
|
declare function InertReferenceScope({ children }: {
|
|
60
60
|
children: ReactNode;
|
|
61
|
-
}):
|
|
61
|
+
}): react.JSX.Element;
|
|
62
62
|
|
|
63
63
|
export { BlockReferenceScope as B, InertReferenceScope as I, NcmReferencesProvider as N, type ReferenceCounts as R, type BlockReferenceScopeProps as a, type BlockReferenceScopeValue as b, type NcmReferencesProviderProps as c, type ReferenceKind as d, computeReferenceBases as e, useBlockReferenceScope as u };
|