@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
|
@@ -473,9 +473,10 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
|
|
|
473
473
|
case "image": {
|
|
474
474
|
const src = config.inline?.resolveAssetPath?.(token.src) ?? token.src;
|
|
475
475
|
return /* @__PURE__ */ jsx(
|
|
476
|
-
|
|
476
|
+
EmbedImage,
|
|
477
477
|
{
|
|
478
|
-
"data-ncm-token": "image",
|
|
478
|
+
attrs: { "data-ncm-token": "image" },
|
|
479
|
+
target: token.src,
|
|
479
480
|
src,
|
|
480
481
|
alt: token.alt,
|
|
481
482
|
title: token.title
|
|
@@ -509,10 +510,13 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
|
|
|
509
510
|
}
|
|
510
511
|
if (embedType === "image") {
|
|
511
512
|
return /* @__PURE__ */ jsx(
|
|
512
|
-
|
|
513
|
+
EmbedImage,
|
|
513
514
|
{
|
|
514
|
-
|
|
515
|
-
|
|
515
|
+
attrs: {
|
|
516
|
+
"data-ncm-token": "wiki_embed",
|
|
517
|
+
"data-ncm-wikiembed-type": embedType
|
|
518
|
+
},
|
|
519
|
+
target: token.target,
|
|
516
520
|
src: url,
|
|
517
521
|
alt: token.display ?? token.target,
|
|
518
522
|
className: config.embeddings?.imageClassName
|
|
@@ -543,6 +547,22 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
|
|
|
543
547
|
}
|
|
544
548
|
);
|
|
545
549
|
}
|
|
550
|
+
const onEmbedClick = config.embeddings?.onEmbedClick;
|
|
551
|
+
if (onEmbedClick) {
|
|
552
|
+
const handleClick = (e) => {
|
|
553
|
+
onEmbedClick(token.target, result, e);
|
|
554
|
+
};
|
|
555
|
+
return /* @__PURE__ */ jsx(
|
|
556
|
+
"button",
|
|
557
|
+
{
|
|
558
|
+
type: "button",
|
|
559
|
+
"data-ncm-token": "wiki_embed",
|
|
560
|
+
"data-ncm-wikiembed-type": embedType,
|
|
561
|
+
onClick: handleClick,
|
|
562
|
+
children: token.display ?? token.target
|
|
563
|
+
}
|
|
564
|
+
);
|
|
565
|
+
}
|
|
546
566
|
return /* @__PURE__ */ jsx(
|
|
547
567
|
"a",
|
|
548
568
|
{
|
|
@@ -561,6 +581,31 @@ function TokenRenderer({ token, disableBionic, disableBeeline }) {
|
|
|
561
581
|
return null;
|
|
562
582
|
}
|
|
563
583
|
}
|
|
584
|
+
function EmbedImage({ attrs, target, src, alt, title, className }) {
|
|
585
|
+
const config = useNcmConfig();
|
|
586
|
+
const Fallback = config.embeddings?.renderImageError;
|
|
587
|
+
const [failedSrc, setFailedSrc] = useState(null);
|
|
588
|
+
useEffect(() => {
|
|
589
|
+
setFailedSrc(null);
|
|
590
|
+
}, [src]);
|
|
591
|
+
if (!Fallback) {
|
|
592
|
+
return /* @__PURE__ */ jsx("img", { ...attrs, src, alt, title, className });
|
|
593
|
+
}
|
|
594
|
+
if (failedSrc === src) {
|
|
595
|
+
return /* @__PURE__ */ jsx(Fallback, { target, src, alt, retry: () => setFailedSrc(null) });
|
|
596
|
+
}
|
|
597
|
+
return /* @__PURE__ */ jsx(
|
|
598
|
+
"img",
|
|
599
|
+
{
|
|
600
|
+
...attrs,
|
|
601
|
+
src,
|
|
602
|
+
alt,
|
|
603
|
+
title,
|
|
604
|
+
className,
|
|
605
|
+
onError: () => setFailedSrc(src)
|
|
606
|
+
}
|
|
607
|
+
);
|
|
608
|
+
}
|
|
564
609
|
function renderReadingText(content, opts) {
|
|
565
610
|
if (!content) return /* @__PURE__ */ jsx(Fragment, { children: content });
|
|
566
611
|
const { bionic = false, beeline = false } = opts;
|
|
@@ -617,6 +662,7 @@ function BlockShell({
|
|
|
617
662
|
function TaskItems({ items }) {
|
|
618
663
|
return /* @__PURE__ */ jsx(Fragment, { children: items.map((item) => {
|
|
619
664
|
const status = item.checked ? "Completed" : "Incomplete";
|
|
665
|
+
const text = serializeInlineContent(item.content);
|
|
620
666
|
return /* @__PURE__ */ jsxs(
|
|
621
667
|
"li",
|
|
622
668
|
{
|
|
@@ -643,7 +689,7 @@ function TaskItems({ items }) {
|
|
|
643
689
|
":",
|
|
644
690
|
" "
|
|
645
691
|
] }),
|
|
646
|
-
/* @__PURE__ */ jsx(InlineContent, { content:
|
|
692
|
+
text.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content: text }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" })
|
|
647
693
|
] })
|
|
648
694
|
] }),
|
|
649
695
|
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
|
|
@@ -2,10 +2,10 @@ import * as react from 'react';
|
|
|
2
2
|
import { HTMLAttributes, ReactNode } from 'react';
|
|
3
3
|
import { Block } from '@nuucognition/ncm';
|
|
4
4
|
export { NcmBlock, NcmBlockProps } from './ncm-block.js';
|
|
5
|
-
|
|
6
|
-
import '
|
|
5
|
+
import { N as NcmConfig } from '../use-ncm-config-CnntcShj.js';
|
|
6
|
+
import { NcmTheme } from './ncm-document.js';
|
|
7
|
+
export { NcmDocument, NcmDocumentProps } from './ncm-document.js';
|
|
7
8
|
import '../renderers-C5f41FCy.js';
|
|
8
|
-
import '../use-ncm-config-D0doMYTH.js';
|
|
9
9
|
import '@nuucognition/mesh-core';
|
|
10
10
|
|
|
11
11
|
type BlockShellTag = "aside" | "details" | "div" | "dl" | "figure" | "section" | "ul";
|
|
@@ -596,4 +596,34 @@ declare function ChildBlocks({ as, blocks, ...props }: ChildBlocksProps): react.
|
|
|
596
596
|
onTransitionStartCapture?: react.TransitionEventHandler<HTMLElement> | undefined;
|
|
597
597
|
}, HTMLElement>;
|
|
598
598
|
|
|
599
|
-
|
|
599
|
+
interface NcmBlockPreviewProps {
|
|
600
|
+
/** The block's markdown source, verbatim. */
|
|
601
|
+
source: string;
|
|
602
|
+
/**
|
|
603
|
+
* The NCM block type the source is expected to parse as. When set and the
|
|
604
|
+
* parse produces no block of this type, the preview shows the parse warning
|
|
605
|
+
* instead of falling back to whatever did parse. Absent, every parsed block
|
|
606
|
+
* renders.
|
|
607
|
+
*/
|
|
608
|
+
expectedType?: string;
|
|
609
|
+
theme?: NcmTheme;
|
|
610
|
+
/** Optional provider config (renderers, code, inline …), mounted internally. */
|
|
611
|
+
config?: NcmConfig;
|
|
612
|
+
className?: string;
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* The one-block reader preview.
|
|
616
|
+
*
|
|
617
|
+
* Give it a source string, get the ncm-ui rendering back — or a quiet
|
|
618
|
+
* "cannot be parsed" state when the source does not parse as the expected
|
|
619
|
+
* block type. Self-sufficient by design: it mounts its own provider, so a
|
|
620
|
+
* host can render it anywhere (the NUU Editor's node views render it through
|
|
621
|
+
* the `previewProviders` seam, outside any app provider tree).
|
|
622
|
+
*
|
|
623
|
+
* Parse options mirror the playground gallery's (`ncm-full`, raw HTML,
|
|
624
|
+
* frontmatter optional), so the preview and the gallery agree on what a
|
|
625
|
+
* block's source means.
|
|
626
|
+
*/
|
|
627
|
+
declare function NcmBlockPreview({ source, expectedType, theme, config, className, }: NcmBlockPreviewProps): react.JSX.Element;
|
|
628
|
+
|
|
629
|
+
export { BlockShell, type BlockShellProps, ChildBlocks, type ChildBlocksProps, NcmBlockPreview, type NcmBlockPreviewProps, NcmTheme, blockDataAttributes, blockKey };
|
package/dist/components/index.js
CHANGED
|
@@ -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
|
-
|
|
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;
|
|
@@ -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")
|
|
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
|
}
|
|
@@ -887,7 +932,7 @@ function CodeBlock({ block, className }) {
|
|
|
887
932
|
"data-ncm-language": block.language,
|
|
888
933
|
className: cn("relative", className),
|
|
889
934
|
children: [
|
|
890
|
-
codeConfig.copyButton
|
|
935
|
+
codeConfig.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
|
|
891
936
|
/* @__PURE__ */ jsx(CustomRenderer, { code: block.content, language: block.language }),
|
|
892
937
|
languageLabel
|
|
893
938
|
]
|
|
@@ -906,7 +951,7 @@ function CodeBlock({ block, className }) {
|
|
|
906
951
|
"data-ncm-language": block.language,
|
|
907
952
|
className: cn("relative", className),
|
|
908
953
|
children: [
|
|
909
|
-
codeConfig?.copyButton
|
|
954
|
+
codeConfig?.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
|
|
910
955
|
/* @__PURE__ */ jsx("pre", { "data-ncm-code-pre": "", children: /* @__PURE__ */ jsxs("div", { className: "flex", children: [
|
|
911
956
|
codeConfig?.lineNumbers && /* @__PURE__ */ jsx(LineNumbers, { count: lineCount }),
|
|
912
957
|
/* @__PURE__ */ jsx("code", { "data-ncm-code": "", className: "flex-1", children: /* @__PURE__ */ jsx(DefaultShikiRenderer, { code: block.content, language: block.language }) })
|
|
@@ -1358,10 +1403,12 @@ function LinkBlock({ block, className }) {
|
|
|
1358
1403
|
function ListBlock({ block, className }) {
|
|
1359
1404
|
const isOrdered = block.type === "list_ordered";
|
|
1360
1405
|
const Tag = isOrdered ? "ol" : "ul";
|
|
1406
|
+
const start = isOrdered && typeof block.marker === "number" && block.marker !== 1 ? block.marker : void 0;
|
|
1361
1407
|
return /* @__PURE__ */ jsx(
|
|
1362
1408
|
Tag,
|
|
1363
1409
|
{
|
|
1364
1410
|
role: "list",
|
|
1411
|
+
start,
|
|
1365
1412
|
"data-ncm-block": block.id,
|
|
1366
1413
|
"data-ncm-stable": block.stableId,
|
|
1367
1414
|
"data-ncm-type": block.type,
|
|
@@ -1373,6 +1420,9 @@ function ListBlock({ block, className }) {
|
|
|
1373
1420
|
}
|
|
1374
1421
|
);
|
|
1375
1422
|
}
|
|
1423
|
+
function ItemContent({ content }) {
|
|
1424
|
+
return content.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" });
|
|
1425
|
+
}
|
|
1376
1426
|
function nestedItemIdKey(id) {
|
|
1377
1427
|
if (!id) {
|
|
1378
1428
|
return void 0;
|
|
@@ -1389,7 +1439,7 @@ function ListItems({ items, itemIds, ordered }) {
|
|
|
1389
1439
|
return /* @__PURE__ */ jsx(Fragment, { children: items.map((item, index) => {
|
|
1390
1440
|
const key = nestedItemIdKey(itemIds?.[index]) ?? `item-${index}`;
|
|
1391
1441
|
if (typeof item === "string") {
|
|
1392
|
-
return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(
|
|
1442
|
+
return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(ItemContent, { content: item }) }, key);
|
|
1393
1443
|
}
|
|
1394
1444
|
if (isTypedNestedList(item)) {
|
|
1395
1445
|
return /* @__PURE__ */ jsx(NestedTypedList, { list: item }, key);
|
|
@@ -1399,7 +1449,7 @@ function ListItems({ items, itemIds, ordered }) {
|
|
|
1399
1449
|
const content = typeof first === "string" ? first : "";
|
|
1400
1450
|
const nestedContent = processNestedItems(rest, ordered);
|
|
1401
1451
|
return /* @__PURE__ */ jsxs("li", { "data-ncm-list-item": "", children: [
|
|
1402
|
-
/* @__PURE__ */ jsx(
|
|
1452
|
+
/* @__PURE__ */ jsx(ItemContent, { content }),
|
|
1403
1453
|
nestedContent
|
|
1404
1454
|
] }, key);
|
|
1405
1455
|
}
|
|
@@ -1558,6 +1608,7 @@ function TableBlock({ block, className }) {
|
|
|
1558
1608
|
function TaskItems({ items }) {
|
|
1559
1609
|
return /* @__PURE__ */ jsx(Fragment, { children: items.map((item) => {
|
|
1560
1610
|
const status = item.checked ? "Completed" : "Incomplete";
|
|
1611
|
+
const text = serializeInlineContent(item.content);
|
|
1561
1612
|
return /* @__PURE__ */ jsxs(
|
|
1562
1613
|
"li",
|
|
1563
1614
|
{
|
|
@@ -1584,7 +1635,7 @@ function TaskItems({ items }) {
|
|
|
1584
1635
|
":",
|
|
1585
1636
|
" "
|
|
1586
1637
|
] }),
|
|
1587
|
-
/* @__PURE__ */ jsx(InlineContent, { content:
|
|
1638
|
+
text.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content: text }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" })
|
|
1588
1639
|
] })
|
|
1589
1640
|
] }),
|
|
1590
1641
|
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
|
|
@@ -1836,5 +1887,41 @@ function NcmDocument({
|
|
|
1836
1887
|
}
|
|
1837
1888
|
);
|
|
1838
1889
|
}
|
|
1890
|
+
function NcmBlockPreview({
|
|
1891
|
+
source,
|
|
1892
|
+
expectedType,
|
|
1893
|
+
theme = "nuu",
|
|
1894
|
+
config,
|
|
1895
|
+
className
|
|
1896
|
+
}) {
|
|
1897
|
+
const parsed = useMemo(() => {
|
|
1898
|
+
try {
|
|
1899
|
+
const doc = parseNcm(source, {
|
|
1900
|
+
preset: "ncm-full",
|
|
1901
|
+
allowMissingFrontmatter: true,
|
|
1902
|
+
rawHtml: true
|
|
1903
|
+
});
|
|
1904
|
+
const all = doc.blocks ?? [];
|
|
1905
|
+
const blocks = expectedType ? all.filter((b) => b.type === expectedType) : all;
|
|
1906
|
+
return { blocks, failed: blocks.length === 0 };
|
|
1907
|
+
} catch {
|
|
1908
|
+
return { blocks: [], failed: true };
|
|
1909
|
+
}
|
|
1910
|
+
}, [source, expectedType]);
|
|
1911
|
+
if (parsed.failed) {
|
|
1912
|
+
return /* @__PURE__ */ jsx(
|
|
1913
|
+
"div",
|
|
1914
|
+
{
|
|
1915
|
+
"data-ncm-parse-warning": "",
|
|
1916
|
+
"data-ncm-theme": theme,
|
|
1917
|
+
className: `ncm-theme-${theme}${className ? ` ${className}` : ""}`,
|
|
1918
|
+
role: "status",
|
|
1919
|
+
children: expectedType ? `Cannot be parsed as ${expectedType}` : "Cannot be parsed"
|
|
1920
|
+
}
|
|
1921
|
+
);
|
|
1922
|
+
}
|
|
1923
|
+
const document2 = /* @__PURE__ */ jsx(NcmDocument, { blocks: parsed.blocks, theme, className });
|
|
1924
|
+
return config ? /* @__PURE__ */ jsx(NcmProvider, { config, children: document2 }) : document2;
|
|
1925
|
+
}
|
|
1839
1926
|
|
|
1840
|
-
export { BlockShell, ChildBlocks, NcmBlock, NcmDocument, blockDataAttributes, blockKey };
|
|
1927
|
+
export { BlockShell, ChildBlocks, NcmBlock, NcmBlockPreview, NcmDocument, blockDataAttributes, blockKey };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import * as
|
|
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):
|
|
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
|
-
|
|
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
|
-
|
|
615
|
+
EmbedImage,
|
|
615
616
|
{
|
|
616
|
-
|
|
617
|
-
|
|
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")
|
|
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
|
}
|
|
@@ -848,7 +893,7 @@ function CodeBlock({ block, className }) {
|
|
|
848
893
|
"data-ncm-language": block.language,
|
|
849
894
|
className: cn("relative", className),
|
|
850
895
|
children: [
|
|
851
|
-
codeConfig.copyButton
|
|
896
|
+
codeConfig.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
|
|
852
897
|
/* @__PURE__ */ jsx(CustomRenderer, { code: block.content, language: block.language }),
|
|
853
898
|
languageLabel
|
|
854
899
|
]
|
|
@@ -867,7 +912,7 @@ function CodeBlock({ block, className }) {
|
|
|
867
912
|
"data-ncm-language": block.language,
|
|
868
913
|
className: cn("relative", className),
|
|
869
914
|
children: [
|
|
870
|
-
codeConfig?.copyButton
|
|
915
|
+
codeConfig?.copyButton === true && /* @__PURE__ */ jsx(CopyButton, { content: block.content }),
|
|
871
916
|
/* @__PURE__ */ jsx("pre", { "data-ncm-code-pre": "", children: /* @__PURE__ */ jsxs("div", { className: "flex", children: [
|
|
872
917
|
codeConfig?.lineNumbers && /* @__PURE__ */ jsx(LineNumbers, { count: lineCount }),
|
|
873
918
|
/* @__PURE__ */ jsx("code", { "data-ncm-code": "", className: "flex-1", children: /* @__PURE__ */ jsx(DefaultShikiRenderer, { code: block.content, language: block.language }) })
|
|
@@ -1319,10 +1364,12 @@ function LinkBlock({ block, className }) {
|
|
|
1319
1364
|
function ListBlock({ block, className }) {
|
|
1320
1365
|
const isOrdered = block.type === "list_ordered";
|
|
1321
1366
|
const Tag = isOrdered ? "ol" : "ul";
|
|
1367
|
+
const start = isOrdered && typeof block.marker === "number" && block.marker !== 1 ? block.marker : void 0;
|
|
1322
1368
|
return /* @__PURE__ */ jsx(
|
|
1323
1369
|
Tag,
|
|
1324
1370
|
{
|
|
1325
1371
|
role: "list",
|
|
1372
|
+
start,
|
|
1326
1373
|
"data-ncm-block": block.id,
|
|
1327
1374
|
"data-ncm-stable": block.stableId,
|
|
1328
1375
|
"data-ncm-type": block.type,
|
|
@@ -1334,6 +1381,9 @@ function ListBlock({ block, className }) {
|
|
|
1334
1381
|
}
|
|
1335
1382
|
);
|
|
1336
1383
|
}
|
|
1384
|
+
function ItemContent({ content }) {
|
|
1385
|
+
return content.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" });
|
|
1386
|
+
}
|
|
1337
1387
|
function nestedItemIdKey(id) {
|
|
1338
1388
|
if (!id) {
|
|
1339
1389
|
return void 0;
|
|
@@ -1350,7 +1400,7 @@ function ListItems({ items, itemIds, ordered }) {
|
|
|
1350
1400
|
return /* @__PURE__ */ jsx(Fragment, { children: items.map((item, index) => {
|
|
1351
1401
|
const key = nestedItemIdKey(itemIds?.[index]) ?? `item-${index}`;
|
|
1352
1402
|
if (typeof item === "string") {
|
|
1353
|
-
return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(
|
|
1403
|
+
return /* @__PURE__ */ jsx("li", { "data-ncm-list-item": "", children: /* @__PURE__ */ jsx(ItemContent, { content: item }) }, key);
|
|
1354
1404
|
}
|
|
1355
1405
|
if (isTypedNestedList(item)) {
|
|
1356
1406
|
return /* @__PURE__ */ jsx(NestedTypedList, { list: item }, key);
|
|
@@ -1360,7 +1410,7 @@ function ListItems({ items, itemIds, ordered }) {
|
|
|
1360
1410
|
const content = typeof first === "string" ? first : "";
|
|
1361
1411
|
const nestedContent = processNestedItems(rest, ordered);
|
|
1362
1412
|
return /* @__PURE__ */ jsxs("li", { "data-ncm-list-item": "", children: [
|
|
1363
|
-
/* @__PURE__ */ jsx(
|
|
1413
|
+
/* @__PURE__ */ jsx(ItemContent, { content }),
|
|
1364
1414
|
nestedContent
|
|
1365
1415
|
] }, key);
|
|
1366
1416
|
}
|
|
@@ -1519,6 +1569,7 @@ function TableBlock({ block, className }) {
|
|
|
1519
1569
|
function TaskItems({ items }) {
|
|
1520
1570
|
return /* @__PURE__ */ jsx(Fragment, { children: items.map((item) => {
|
|
1521
1571
|
const status = item.checked ? "Completed" : "Incomplete";
|
|
1572
|
+
const text = serializeInlineContent(item.content);
|
|
1522
1573
|
return /* @__PURE__ */ jsxs(
|
|
1523
1574
|
"li",
|
|
1524
1575
|
{
|
|
@@ -1545,7 +1596,7 @@ function TaskItems({ items }) {
|
|
|
1545
1596
|
":",
|
|
1546
1597
|
" "
|
|
1547
1598
|
] }),
|
|
1548
|
-
/* @__PURE__ */ jsx(InlineContent, { content:
|
|
1599
|
+
text.length > 0 ? /* @__PURE__ */ jsx(InlineContent, { content: text }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xA0" })
|
|
1549
1600
|
] })
|
|
1550
1601
|
] }),
|
|
1551
1602
|
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,8 +1,8 @@
|
|
|
1
|
-
import * as
|
|
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 {
|
|
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):
|
|
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 };
|