@incremark/react 0.2.6 → 0.3.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.en.md +216 -47
- package/dist/index.d.ts +99 -28
- package/dist/index.js +594 -243
- package/package.json +19 -6
package/dist/index.js
CHANGED
|
@@ -193,17 +193,7 @@ function useTypewriter(options) {
|
|
|
193
193
|
}, [sourceBlocks, transformer]);
|
|
194
194
|
const blocks = useMemo(() => {
|
|
195
195
|
if (!typewriterEnabled || !transformer) {
|
|
196
|
-
|
|
197
|
-
for (const block of completedBlocks) {
|
|
198
|
-
result.push({ ...block, stableId: block.id });
|
|
199
|
-
}
|
|
200
|
-
for (let i = 0; i < pendingBlocks.length; i++) {
|
|
201
|
-
result.push({
|
|
202
|
-
...pendingBlocks[i],
|
|
203
|
-
stableId: `pending-${i}`
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
return result;
|
|
196
|
+
return [...completedBlocks, ...pendingBlocks];
|
|
207
197
|
}
|
|
208
198
|
return displayBlocks.map((db, index) => {
|
|
209
199
|
const isPending = !db.isDisplayComplete;
|
|
@@ -220,7 +210,6 @@ function useTypewriter(options) {
|
|
|
220
210
|
}
|
|
221
211
|
const block = {
|
|
222
212
|
id: db.id,
|
|
223
|
-
stableId: db.id,
|
|
224
213
|
status: db.isDisplayComplete ? "completed" : "pending",
|
|
225
214
|
isLastPending,
|
|
226
215
|
node,
|
|
@@ -452,8 +441,8 @@ function useDevTools(incremark, options = {}) {
|
|
|
452
441
|
devtoolsRef.current = devtools;
|
|
453
442
|
incremark.parser.setOnChange((state) => {
|
|
454
443
|
const blocks = [
|
|
455
|
-
...state.completedBlocks
|
|
456
|
-
...state.pendingBlocks
|
|
444
|
+
...state.completedBlocks,
|
|
445
|
+
...state.pendingBlocks
|
|
457
446
|
];
|
|
458
447
|
devtools.update({
|
|
459
448
|
blocks,
|
|
@@ -547,6 +536,44 @@ function useBlockTransformer(sourceBlocks, options = {}) {
|
|
|
547
536
|
};
|
|
548
537
|
}
|
|
549
538
|
|
|
539
|
+
// src/hooks/useLocale.ts
|
|
540
|
+
import { useContext as useContext2 } from "react";
|
|
541
|
+
|
|
542
|
+
// src/components/ConfigProvider.tsx
|
|
543
|
+
import { createContext as createContext2, useMemo as useMemo3 } from "react";
|
|
544
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
545
|
+
var LocaleContext = createContext2(null);
|
|
546
|
+
function ConfigProvider({ children, locale = enShared }) {
|
|
547
|
+
const contextValue = useMemo3(() => ({ locale }), [locale]);
|
|
548
|
+
return /* @__PURE__ */ jsx2(LocaleContext.Provider, { value: contextValue, children });
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// src/hooks/useLocale.ts
|
|
552
|
+
function useLocale() {
|
|
553
|
+
const context = useContext2(LocaleContext);
|
|
554
|
+
if (!context) {
|
|
555
|
+
const t2 = (key) => {
|
|
556
|
+
const keys = key.split(".");
|
|
557
|
+
let value = enShared;
|
|
558
|
+
for (const k of keys) {
|
|
559
|
+
value = value?.[k];
|
|
560
|
+
}
|
|
561
|
+
return value || key;
|
|
562
|
+
};
|
|
563
|
+
return { t: t2 };
|
|
564
|
+
}
|
|
565
|
+
const { locale } = context;
|
|
566
|
+
const t = (key) => {
|
|
567
|
+
const keys = key.split(".");
|
|
568
|
+
let value = locale;
|
|
569
|
+
for (const k of keys) {
|
|
570
|
+
value = value?.[k];
|
|
571
|
+
}
|
|
572
|
+
return value || key;
|
|
573
|
+
};
|
|
574
|
+
return { t };
|
|
575
|
+
}
|
|
576
|
+
|
|
550
577
|
// src/components/IncremarkInline.tsx
|
|
551
578
|
import React3 from "react";
|
|
552
579
|
import {
|
|
@@ -557,7 +584,7 @@ import {
|
|
|
557
584
|
|
|
558
585
|
// src/components/IncremarkHtmlElement.tsx
|
|
559
586
|
import React2 from "react";
|
|
560
|
-
import { jsx as
|
|
587
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
561
588
|
var INLINE_ELEMENTS = [
|
|
562
589
|
"a",
|
|
563
590
|
"abbr",
|
|
@@ -679,22 +706,22 @@ function toReactProps(attrs) {
|
|
|
679
706
|
function renderChildren(children) {
|
|
680
707
|
if (!children || children.length === 0) return null;
|
|
681
708
|
if (hasOnlyInlineChildren(children)) {
|
|
682
|
-
return /* @__PURE__ */
|
|
709
|
+
return /* @__PURE__ */ jsx3(IncremarkInline, { nodes: children });
|
|
683
710
|
}
|
|
684
711
|
return children.map((child, idx) => {
|
|
685
712
|
if (child.type === "htmlElement") {
|
|
686
|
-
return /* @__PURE__ */
|
|
713
|
+
return /* @__PURE__ */ jsx3(IncremarkHtmlElement, { node: child }, idx);
|
|
687
714
|
}
|
|
688
715
|
if (child.type === "text") {
|
|
689
|
-
return /* @__PURE__ */
|
|
716
|
+
return /* @__PURE__ */ jsx3(React2.Fragment, { children: child.value }, idx);
|
|
690
717
|
}
|
|
691
718
|
if (["strong", "emphasis", "inlineCode", "link", "image", "break"].includes(child.type)) {
|
|
692
|
-
return /* @__PURE__ */
|
|
719
|
+
return /* @__PURE__ */ jsx3(IncremarkInline, { nodes: [child] }, idx);
|
|
693
720
|
}
|
|
694
721
|
if (child.type === "paragraph") {
|
|
695
|
-
return /* @__PURE__ */
|
|
722
|
+
return /* @__PURE__ */ jsx3("p", { children: /* @__PURE__ */ jsx3(IncremarkInline, { nodes: child.children }) }, idx);
|
|
696
723
|
}
|
|
697
|
-
return /* @__PURE__ */
|
|
724
|
+
return /* @__PURE__ */ jsx3("div", { className: "incremark-unknown-child", children: child.type }, idx);
|
|
698
725
|
});
|
|
699
726
|
}
|
|
700
727
|
var IncremarkHtmlElement = ({ node }) => {
|
|
@@ -702,13 +729,13 @@ var IncremarkHtmlElement = ({ node }) => {
|
|
|
702
729
|
const Tag = tagName;
|
|
703
730
|
const reactProps = toReactProps(attrs);
|
|
704
731
|
if (isVoidElement(tagName)) {
|
|
705
|
-
return /* @__PURE__ */
|
|
732
|
+
return /* @__PURE__ */ jsx3(Tag, { ...reactProps, className: `incremark-html-element incremark-${tagName} ${reactProps.className || ""}` });
|
|
706
733
|
}
|
|
707
|
-
return /* @__PURE__ */
|
|
734
|
+
return /* @__PURE__ */ jsx3(Tag, { ...reactProps, className: `incremark-html-element incremark-${tagName} ${reactProps.className || ""}`, children: renderChildren(children) });
|
|
708
735
|
};
|
|
709
736
|
|
|
710
737
|
// src/components/IncremarkInline.tsx
|
|
711
|
-
import { Fragment, jsx as
|
|
738
|
+
import { Fragment, jsx as jsx4, jsxs } from "react/jsx-runtime";
|
|
712
739
|
function isHtmlElementNode(node) {
|
|
713
740
|
return node.type === "htmlElement";
|
|
714
741
|
}
|
|
@@ -721,45 +748,45 @@ function isLinkReference(node) {
|
|
|
721
748
|
var IncremarkInline = ({ nodes }) => {
|
|
722
749
|
if (!nodes || nodes.length === 0) return null;
|
|
723
750
|
const { definitions, footnoteDefinitions } = useDefinitions();
|
|
724
|
-
return /* @__PURE__ */
|
|
751
|
+
return /* @__PURE__ */ jsx4(Fragment, { children: nodes.map((node, i) => {
|
|
725
752
|
if (node.type === "text") {
|
|
726
753
|
const textNode = node;
|
|
727
754
|
if (hasChunks(node) && textNode.chunks && textNode.chunks.length > 0) {
|
|
728
755
|
return /* @__PURE__ */ jsxs(React3.Fragment, { children: [
|
|
729
756
|
getStableText(textNode),
|
|
730
|
-
textNode.chunks.map((chunk) => /* @__PURE__ */
|
|
757
|
+
textNode.chunks.map((chunk) => /* @__PURE__ */ jsx4("span", { "data-chunk-key": chunk.createdAt, className: "incremark-fade-in", children: chunk.text }, chunk.createdAt))
|
|
731
758
|
] }, i);
|
|
732
759
|
}
|
|
733
|
-
return /* @__PURE__ */
|
|
760
|
+
return /* @__PURE__ */ jsx4(React3.Fragment, { children: node.value }, i);
|
|
734
761
|
}
|
|
735
762
|
if (isHtmlElementNode(node)) {
|
|
736
|
-
return /* @__PURE__ */
|
|
763
|
+
return /* @__PURE__ */ jsx4(IncremarkHtmlElement, { node }, i);
|
|
737
764
|
}
|
|
738
765
|
if (isHtmlNode(node)) {
|
|
739
|
-
return /* @__PURE__ */
|
|
766
|
+
return /* @__PURE__ */ jsx4(
|
|
740
767
|
"span",
|
|
741
768
|
{
|
|
742
|
-
|
|
769
|
+
className: "incremark-inline-html",
|
|
743
770
|
dangerouslySetInnerHTML: { __html: node.value }
|
|
744
771
|
},
|
|
745
772
|
i
|
|
746
773
|
);
|
|
747
774
|
}
|
|
748
775
|
if (node.type === "strong") {
|
|
749
|
-
return /* @__PURE__ */
|
|
776
|
+
return /* @__PURE__ */ jsx4("strong", { children: /* @__PURE__ */ jsx4(IncremarkInline, { nodes: node.children }) }, i);
|
|
750
777
|
}
|
|
751
778
|
if (node.type === "emphasis") {
|
|
752
|
-
return /* @__PURE__ */
|
|
779
|
+
return /* @__PURE__ */ jsx4("em", { children: /* @__PURE__ */ jsx4(IncremarkInline, { nodes: node.children }) }, i);
|
|
753
780
|
}
|
|
754
781
|
if (node.type === "inlineCode") {
|
|
755
|
-
return /* @__PURE__ */
|
|
782
|
+
return /* @__PURE__ */ jsx4("code", { className: "incremark-inline-code", children: node.value }, i);
|
|
756
783
|
}
|
|
757
784
|
if (node.type === "link") {
|
|
758
|
-
return /* @__PURE__ */
|
|
785
|
+
return /* @__PURE__ */ jsx4("a", { href: node.url, target: "_blank", rel: "noopener noreferrer", children: /* @__PURE__ */ jsx4(IncremarkInline, { nodes: node.children }) }, i);
|
|
759
786
|
}
|
|
760
787
|
if (node.type === "image") {
|
|
761
788
|
const imageNode = node;
|
|
762
|
-
return /* @__PURE__ */
|
|
789
|
+
return /* @__PURE__ */ jsx4(
|
|
763
790
|
"img",
|
|
764
791
|
{
|
|
765
792
|
src: imageNode.url,
|
|
@@ -773,7 +800,7 @@ var IncremarkInline = ({ nodes }) => {
|
|
|
773
800
|
if (isImageReference(node)) {
|
|
774
801
|
const definition = definitions[node.identifier];
|
|
775
802
|
if (definition) {
|
|
776
|
-
return /* @__PURE__ */
|
|
803
|
+
return /* @__PURE__ */ jsx4(
|
|
777
804
|
"img",
|
|
778
805
|
{
|
|
779
806
|
src: definition.url,
|
|
@@ -795,14 +822,14 @@ var IncremarkInline = ({ nodes }) => {
|
|
|
795
822
|
if (isLinkReference(node)) {
|
|
796
823
|
const definition = definitions[node.identifier];
|
|
797
824
|
if (definition) {
|
|
798
|
-
return /* @__PURE__ */
|
|
825
|
+
return /* @__PURE__ */ jsx4(
|
|
799
826
|
"a",
|
|
800
827
|
{
|
|
801
828
|
href: definition.url,
|
|
802
829
|
title: definition.title || void 0,
|
|
803
830
|
target: "_blank",
|
|
804
831
|
rel: "noopener noreferrer",
|
|
805
|
-
children: /* @__PURE__ */
|
|
832
|
+
children: /* @__PURE__ */ jsx4(IncremarkInline, { nodes: node.children })
|
|
806
833
|
},
|
|
807
834
|
i
|
|
808
835
|
);
|
|
@@ -818,78 +845,83 @@ var IncremarkInline = ({ nodes }) => {
|
|
|
818
845
|
if (node.type === "footnoteReference") {
|
|
819
846
|
const footnoteRef = node;
|
|
820
847
|
const hasDefinition = footnoteDefinitions[footnoteRef.identifier];
|
|
821
|
-
return /* @__PURE__ */
|
|
848
|
+
return /* @__PURE__ */ jsx4("sup", { className: "incremark-footnote-ref", children: /* @__PURE__ */ jsx4("a", { href: `#fn-${footnoteRef.identifier}`, id: `fnref-${footnoteRef.identifier}`, children: hasDefinition ? `[${footnoteRef.identifier}]` : `[^${footnoteRef.identifier}]` }) }, i);
|
|
822
849
|
}
|
|
823
850
|
if (node.type === "break") {
|
|
824
|
-
return /* @__PURE__ */
|
|
851
|
+
return /* @__PURE__ */ jsx4("br", {}, i);
|
|
825
852
|
}
|
|
826
853
|
if (node.type === "delete") {
|
|
827
|
-
return /* @__PURE__ */
|
|
854
|
+
return /* @__PURE__ */ jsx4("del", { children: /* @__PURE__ */ jsx4(IncremarkInline, { nodes: node.children }) }, i);
|
|
828
855
|
}
|
|
829
|
-
return /* @__PURE__ */
|
|
856
|
+
return /* @__PURE__ */ jsx4("span", { children: node.value || "" }, i);
|
|
830
857
|
}) });
|
|
831
858
|
};
|
|
832
859
|
|
|
833
860
|
// src/components/IncremarkHeading.tsx
|
|
834
|
-
import { jsx as
|
|
861
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
835
862
|
var IncremarkHeading = ({ node }) => {
|
|
836
863
|
const Tag = `h${node.depth}`;
|
|
837
|
-
return /* @__PURE__ */
|
|
864
|
+
return /* @__PURE__ */ jsx5(Tag, { className: `incremark-heading h${node.depth}`, children: /* @__PURE__ */ jsx5(IncremarkInline, { nodes: node.children }) });
|
|
838
865
|
};
|
|
839
866
|
|
|
840
867
|
// src/components/IncremarkParagraph.tsx
|
|
841
|
-
import { jsx as
|
|
868
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
842
869
|
var IncremarkParagraph = ({ node }) => {
|
|
843
|
-
return /* @__PURE__ */
|
|
870
|
+
return /* @__PURE__ */ jsx6("p", { className: "incremark-paragraph", children: /* @__PURE__ */ jsx6(IncremarkInline, { nodes: node.children }) });
|
|
844
871
|
};
|
|
845
872
|
|
|
846
873
|
// src/components/IncremarkCode.tsx
|
|
847
|
-
import
|
|
848
|
-
|
|
849
|
-
|
|
874
|
+
import React7 from "react";
|
|
875
|
+
|
|
876
|
+
// src/components/IncremarkCodeMermaid.tsx
|
|
877
|
+
import { useState as useState5, useEffect as useEffect4, useRef as useRef5, useCallback as useCallback5 } from "react";
|
|
878
|
+
import { GravityMermaid, LucideCode, LucideEye, LucideCopy, LucideCopyCheck } from "@incremark/icons";
|
|
879
|
+
import { isClipboardAvailable } from "@incremark/shared";
|
|
880
|
+
|
|
881
|
+
// src/components/SvgIcon.tsx
|
|
882
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
883
|
+
var SvgIcon = ({
|
|
884
|
+
svg,
|
|
885
|
+
sizeClass,
|
|
886
|
+
className
|
|
887
|
+
}) => {
|
|
888
|
+
return /* @__PURE__ */ jsx7(
|
|
889
|
+
"span",
|
|
890
|
+
{
|
|
891
|
+
className: `incremark-icon ${sizeClass || ""} ${className || ""}`.trim(),
|
|
892
|
+
dangerouslySetInnerHTML: { __html: svg },
|
|
893
|
+
"aria-hidden": "true"
|
|
894
|
+
}
|
|
895
|
+
);
|
|
896
|
+
};
|
|
897
|
+
|
|
898
|
+
// src/components/IncremarkCodeMermaid.tsx
|
|
899
|
+
import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
900
|
+
var IncremarkCodeMermaid = ({
|
|
850
901
|
node,
|
|
851
|
-
|
|
852
|
-
fallbackTheme = "github-dark",
|
|
853
|
-
disableHighlight = false,
|
|
854
|
-
mermaidDelay = 500,
|
|
855
|
-
customCodeBlocks,
|
|
856
|
-
blockStatus = "completed",
|
|
857
|
-
codeBlockConfigs
|
|
902
|
+
mermaidDelay = 500
|
|
858
903
|
}) => {
|
|
859
904
|
const [copied, setCopied] = useState5(false);
|
|
860
|
-
const
|
|
861
|
-
const [isHighlighting, setIsHighlighting] = useState5(false);
|
|
905
|
+
const { t } = useLocale();
|
|
862
906
|
const [mermaidSvg, setMermaidSvg] = useState5("");
|
|
863
907
|
const [mermaidLoading, setMermaidLoading] = useState5(false);
|
|
864
908
|
const [mermaidViewMode, setMermaidViewMode] = useState5("preview");
|
|
865
909
|
const mermaidRef = useRef5(null);
|
|
866
|
-
const highlighterRef = useRef5(null);
|
|
867
910
|
const mermaidTimerRef = useRef5(null);
|
|
868
|
-
const
|
|
869
|
-
const loadedThemesRef = useRef5(/* @__PURE__ */ new Set());
|
|
870
|
-
const language = node.lang || "text";
|
|
911
|
+
const copyTimeoutRef = useRef5(null);
|
|
871
912
|
const code = node.value;
|
|
872
|
-
const isMermaid = language === "mermaid";
|
|
873
|
-
const CustomCodeBlock = React4.useMemo(() => {
|
|
874
|
-
const component = customCodeBlocks?.[language];
|
|
875
|
-
if (!component) return null;
|
|
876
|
-
const config = codeBlockConfigs?.[language];
|
|
877
|
-
if (config?.takeOver) {
|
|
878
|
-
return component;
|
|
879
|
-
}
|
|
880
|
-
if (blockStatus !== "completed") {
|
|
881
|
-
return null;
|
|
882
|
-
}
|
|
883
|
-
return component;
|
|
884
|
-
}, [customCodeBlocks, language, blockStatus, codeBlockConfigs]);
|
|
885
913
|
const toggleMermaidView = useCallback5(() => {
|
|
886
914
|
setMermaidViewMode((prev) => prev === "preview" ? "source" : "preview");
|
|
887
915
|
}, []);
|
|
888
916
|
const copyCode = useCallback5(async () => {
|
|
917
|
+
if (!isClipboardAvailable()) return;
|
|
889
918
|
try {
|
|
890
919
|
await navigator.clipboard.writeText(code);
|
|
891
920
|
setCopied(true);
|
|
892
|
-
|
|
921
|
+
if (copyTimeoutRef.current) {
|
|
922
|
+
clearTimeout(copyTimeoutRef.current);
|
|
923
|
+
}
|
|
924
|
+
copyTimeoutRef.current = setTimeout(() => setCopied(false), 2e3);
|
|
893
925
|
} catch {
|
|
894
926
|
}
|
|
895
927
|
}, [code]);
|
|
@@ -902,7 +934,8 @@ var IncremarkCode = ({
|
|
|
902
934
|
mermaidRef.current.initialize({
|
|
903
935
|
startOnLoad: false,
|
|
904
936
|
theme: "dark",
|
|
905
|
-
securityLevel: "loose"
|
|
937
|
+
securityLevel: "loose",
|
|
938
|
+
suppressErrorRendering: true
|
|
906
939
|
});
|
|
907
940
|
}
|
|
908
941
|
const mermaid = mermaidRef.current;
|
|
@@ -916,7 +949,7 @@ var IncremarkCode = ({
|
|
|
916
949
|
}
|
|
917
950
|
}, [code]);
|
|
918
951
|
const scheduleRenderMermaid = useCallback5(() => {
|
|
919
|
-
if (!
|
|
952
|
+
if (!code) return;
|
|
920
953
|
if (mermaidTimerRef.current) {
|
|
921
954
|
clearTimeout(mermaidTimerRef.current);
|
|
922
955
|
}
|
|
@@ -924,66 +957,293 @@ var IncremarkCode = ({
|
|
|
924
957
|
mermaidTimerRef.current = setTimeout(() => {
|
|
925
958
|
doRenderMermaid();
|
|
926
959
|
}, mermaidDelay);
|
|
927
|
-
}, [
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
960
|
+
}, [code, mermaidDelay, doRenderMermaid]);
|
|
961
|
+
useEffect4(() => {
|
|
962
|
+
scheduleRenderMermaid();
|
|
963
|
+
}, [scheduleRenderMermaid]);
|
|
964
|
+
useEffect4(() => {
|
|
965
|
+
return () => {
|
|
966
|
+
if (mermaidTimerRef.current) {
|
|
967
|
+
clearTimeout(mermaidTimerRef.current);
|
|
968
|
+
}
|
|
969
|
+
if (copyTimeoutRef.current) {
|
|
970
|
+
clearTimeout(copyTimeoutRef.current);
|
|
971
|
+
}
|
|
972
|
+
};
|
|
973
|
+
}, []);
|
|
974
|
+
return /* @__PURE__ */ jsxs2("div", { className: "incremark-mermaid", children: [
|
|
975
|
+
/* @__PURE__ */ jsxs2("div", { className: "mermaid-header", children: [
|
|
976
|
+
/* @__PURE__ */ jsxs2("span", { className: "language", children: [
|
|
977
|
+
/* @__PURE__ */ jsx8(SvgIcon, { svg: GravityMermaid, className: "language-icon" }),
|
|
978
|
+
"MERMAID"
|
|
979
|
+
] }),
|
|
980
|
+
/* @__PURE__ */ jsxs2("div", { className: "mermaid-actions", children: [
|
|
981
|
+
/* @__PURE__ */ jsx8(
|
|
982
|
+
"button",
|
|
983
|
+
{
|
|
984
|
+
className: "code-btn",
|
|
985
|
+
onClick: toggleMermaidView,
|
|
986
|
+
type: "button",
|
|
987
|
+
disabled: !mermaidSvg,
|
|
988
|
+
"aria-label": mermaidViewMode === "preview" ? t("mermaid.viewSource") : t("mermaid.preview"),
|
|
989
|
+
title: mermaidViewMode === "preview" ? "View Source" : "Preview",
|
|
990
|
+
children: /* @__PURE__ */ jsx8(SvgIcon, { svg: mermaidViewMode === "preview" ? LucideCode : LucideEye })
|
|
991
|
+
}
|
|
992
|
+
),
|
|
993
|
+
/* @__PURE__ */ jsx8(
|
|
994
|
+
"button",
|
|
995
|
+
{
|
|
996
|
+
className: "code-btn",
|
|
997
|
+
onClick: copyCode,
|
|
998
|
+
type: "button",
|
|
999
|
+
"aria-label": copied ? t("mermaid.copied") : t("mermaid.copy"),
|
|
1000
|
+
title: copied ? "Copied!" : "Copy",
|
|
1001
|
+
children: /* @__PURE__ */ jsx8(SvgIcon, { svg: copied ? LucideCopyCheck : LucideCopy })
|
|
1002
|
+
}
|
|
1003
|
+
)
|
|
1004
|
+
] })
|
|
1005
|
+
] }),
|
|
1006
|
+
/* @__PURE__ */ jsx8("div", { className: "mermaid-content", children: mermaidLoading && !mermaidSvg ? /* @__PURE__ */ jsx8("div", { className: "mermaid-loading", children: /* @__PURE__ */ jsx8("pre", { className: "mermaid-source-code", children: code }) }) : mermaidViewMode === "source" ? /* @__PURE__ */ jsx8("pre", { className: "mermaid-source-code", children: code }) : mermaidSvg ? /* @__PURE__ */ jsx8("div", { className: "mermaid-svg", dangerouslySetInnerHTML: { __html: mermaidSvg } }) : /* @__PURE__ */ jsx8("pre", { className: "mermaid-source-code", children: code }) })
|
|
1007
|
+
] });
|
|
1008
|
+
};
|
|
1009
|
+
|
|
1010
|
+
// src/components/IncremarkCodeDefault.tsx
|
|
1011
|
+
import { useState as useState6, useEffect as useEffect5, useCallback as useCallback6, useRef as useRef6 } from "react";
|
|
1012
|
+
import { LucideCopy as LucideCopy2, LucideCopyCheck as LucideCopyCheck2 } from "@incremark/icons";
|
|
1013
|
+
import { isClipboardAvailable as isClipboardAvailable2 } from "@incremark/shared";
|
|
1014
|
+
|
|
1015
|
+
// src/hooks/useShiki.ts
|
|
1016
|
+
import React5 from "react";
|
|
1017
|
+
var ShikiManager = class _ShikiManager {
|
|
1018
|
+
static instance = null;
|
|
1019
|
+
/** 存储 highlighter 实例,key 为主题名称 */
|
|
1020
|
+
highlighters = /* @__PURE__ */ new Map();
|
|
1021
|
+
constructor() {
|
|
1022
|
+
}
|
|
1023
|
+
static getInstance() {
|
|
1024
|
+
if (!_ShikiManager.instance) {
|
|
1025
|
+
_ShikiManager.instance = new _ShikiManager();
|
|
932
1026
|
}
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
1027
|
+
return _ShikiManager.instance;
|
|
1028
|
+
}
|
|
1029
|
+
/**
|
|
1030
|
+
* 获取或创建 highlighter
|
|
1031
|
+
* @param theme 主题名称
|
|
1032
|
+
* @returns highlighter 实例
|
|
1033
|
+
*/
|
|
1034
|
+
async getHighlighter(theme) {
|
|
1035
|
+
if (this.highlighters.has(theme)) {
|
|
1036
|
+
return this.highlighters.get(theme);
|
|
936
1037
|
}
|
|
937
|
-
|
|
1038
|
+
const { createHighlighter } = await import("shiki");
|
|
1039
|
+
const highlighter = await createHighlighter({
|
|
1040
|
+
themes: [theme],
|
|
1041
|
+
langs: []
|
|
1042
|
+
});
|
|
1043
|
+
const info = {
|
|
1044
|
+
highlighter,
|
|
1045
|
+
loadedLanguages: /* @__PURE__ */ new Set(),
|
|
1046
|
+
loadedThemes: /* @__PURE__ */ new Set([theme])
|
|
1047
|
+
};
|
|
1048
|
+
this.highlighters.set(theme, info);
|
|
1049
|
+
return info;
|
|
1050
|
+
}
|
|
1051
|
+
/**
|
|
1052
|
+
* 加载语言(按需)
|
|
1053
|
+
* @param theme 主题名称
|
|
1054
|
+
* @param lang 语言名称
|
|
1055
|
+
*/
|
|
1056
|
+
async loadLanguage(theme, lang) {
|
|
1057
|
+
const info = this.highlighters.get(theme);
|
|
1058
|
+
if (!info || info.loadedLanguages.has(lang)) return;
|
|
938
1059
|
try {
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
1060
|
+
await info.highlighter.loadLanguage(lang);
|
|
1061
|
+
info.loadedLanguages.add(lang);
|
|
1062
|
+
} catch {
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
/**
|
|
1066
|
+
* 加载主题(按需)
|
|
1067
|
+
* @param theme 主题名称
|
|
1068
|
+
*/
|
|
1069
|
+
async loadTheme(theme) {
|
|
1070
|
+
const info = this.highlighters.get(theme);
|
|
1071
|
+
if (!info || info.loadedThemes.has(theme)) return;
|
|
1072
|
+
try {
|
|
1073
|
+
await info.highlighter.loadTheme(theme);
|
|
1074
|
+
info.loadedThemes.add(theme);
|
|
1075
|
+
} catch {
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
/**
|
|
1079
|
+
* 高亮代码
|
|
1080
|
+
* @param theme 主题名称
|
|
1081
|
+
* @param code 代码内容
|
|
1082
|
+
* @param lang 语言名称
|
|
1083
|
+
* @param fallbackTheme 回退主题
|
|
1084
|
+
* @returns 高亮后的 HTML
|
|
1085
|
+
*/
|
|
1086
|
+
async codeToHtml(theme, code, lang, fallbackTheme) {
|
|
1087
|
+
const info = this.highlighters.get(theme);
|
|
1088
|
+
if (!info) throw new Error("Highlighter not found");
|
|
1089
|
+
const actualLang = info.loadedLanguages.has(lang) ? lang : "text";
|
|
1090
|
+
const actualTheme = info.loadedThemes.has(theme) ? theme : fallbackTheme;
|
|
1091
|
+
return info.highlighter.codeToHtml(code, {
|
|
1092
|
+
lang: actualLang,
|
|
1093
|
+
theme: actualTheme
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
/**
|
|
1097
|
+
* 清理所有 highlighter(应用退出或需要重置时调用)
|
|
1098
|
+
*/
|
|
1099
|
+
disposeAll() {
|
|
1100
|
+
for (const [, info] of this.highlighters) {
|
|
1101
|
+
if (info.highlighter?.dispose) {
|
|
1102
|
+
info.highlighter.dispose();
|
|
946
1103
|
}
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
1104
|
+
}
|
|
1105
|
+
this.highlighters.clear();
|
|
1106
|
+
}
|
|
1107
|
+
};
|
|
1108
|
+
var shikiManagerInstance = null;
|
|
1109
|
+
function getShikiManager() {
|
|
1110
|
+
if (!shikiManagerInstance) {
|
|
1111
|
+
shikiManagerInstance = ShikiManager.getInstance();
|
|
1112
|
+
}
|
|
1113
|
+
return shikiManagerInstance;
|
|
1114
|
+
}
|
|
1115
|
+
function useShiki(theme) {
|
|
1116
|
+
const [isHighlighting, setIsHighlighting] = React5.useState(false);
|
|
1117
|
+
const highlighterInfoRef = React5.useRef(null);
|
|
1118
|
+
const getHighlighter = React5.useCallback(async () => {
|
|
1119
|
+
if (!highlighterInfoRef.current) {
|
|
1120
|
+
highlighterInfoRef.current = await getShikiManager().getHighlighter(theme);
|
|
1121
|
+
}
|
|
1122
|
+
return highlighterInfoRef.current;
|
|
1123
|
+
}, [theme]);
|
|
1124
|
+
const highlight = React5.useCallback(async (code, lang, fallbackTheme) => {
|
|
1125
|
+
setIsHighlighting(true);
|
|
1126
|
+
try {
|
|
1127
|
+
const info = await getHighlighter();
|
|
1128
|
+
const manager = getShikiManager();
|
|
1129
|
+
if (!info.loadedLanguages.has(lang) && lang !== "text") {
|
|
1130
|
+
await manager.loadLanguage(theme, lang);
|
|
955
1131
|
}
|
|
956
|
-
if (!
|
|
957
|
-
|
|
958
|
-
await highlighter.loadTheme(theme);
|
|
959
|
-
loadedThemesRef.current.add(theme);
|
|
960
|
-
} catch {
|
|
961
|
-
}
|
|
1132
|
+
if (!info.loadedThemes.has(theme)) {
|
|
1133
|
+
await manager.loadTheme(theme);
|
|
962
1134
|
}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
});
|
|
967
|
-
setHighlightedHtml(html);
|
|
968
|
-
} catch {
|
|
969
|
-
setHighlightedHtml("");
|
|
1135
|
+
return await manager.codeToHtml(theme, code, lang, fallbackTheme);
|
|
1136
|
+
} catch (e) {
|
|
1137
|
+
throw e;
|
|
970
1138
|
} finally {
|
|
971
1139
|
setIsHighlighting(false);
|
|
972
1140
|
}
|
|
973
|
-
}, [
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1141
|
+
}, [getHighlighter, theme]);
|
|
1142
|
+
return {
|
|
1143
|
+
isHighlighting,
|
|
1144
|
+
highlight
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
// src/components/IncremarkCodeDefault.tsx
|
|
1149
|
+
import { jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1150
|
+
var IncremarkCodeDefault = ({
|
|
1151
|
+
node,
|
|
1152
|
+
theme = "github-dark",
|
|
1153
|
+
fallbackTheme = "github-dark",
|
|
1154
|
+
disableHighlight = false
|
|
1155
|
+
}) => {
|
|
1156
|
+
const [copied, setCopied] = useState6(false);
|
|
1157
|
+
const [highlightedHtml, setHighlightedHtml] = useState6("");
|
|
1158
|
+
const language = node.lang || "text";
|
|
1159
|
+
const code = node.value;
|
|
1160
|
+
const { t } = useLocale();
|
|
1161
|
+
const { isHighlighting, highlight } = useShiki(theme);
|
|
1162
|
+
const copyTimeoutRef = useRef6(null);
|
|
1163
|
+
const copyCode = useCallback6(async () => {
|
|
1164
|
+
if (!isClipboardAvailable2()) return;
|
|
1165
|
+
try {
|
|
1166
|
+
await navigator.clipboard.writeText(code);
|
|
1167
|
+
setCopied(true);
|
|
1168
|
+
if (copyTimeoutRef.current) {
|
|
1169
|
+
clearTimeout(copyTimeoutRef.current);
|
|
1170
|
+
}
|
|
1171
|
+
copyTimeoutRef.current = setTimeout(() => setCopied(false), 2e3);
|
|
1172
|
+
} catch {
|
|
1173
|
+
}
|
|
1174
|
+
}, [code]);
|
|
1175
|
+
useEffect5(() => {
|
|
978
1176
|
return () => {
|
|
979
|
-
if (
|
|
980
|
-
clearTimeout(
|
|
1177
|
+
if (copyTimeoutRef.current) {
|
|
1178
|
+
clearTimeout(copyTimeoutRef.current);
|
|
981
1179
|
}
|
|
982
1180
|
};
|
|
983
1181
|
}, []);
|
|
1182
|
+
const doHighlight = useCallback6(async () => {
|
|
1183
|
+
if (!code || disableHighlight) {
|
|
1184
|
+
setHighlightedHtml("");
|
|
1185
|
+
return;
|
|
1186
|
+
}
|
|
1187
|
+
try {
|
|
1188
|
+
const html = await highlight(code, language, fallbackTheme);
|
|
1189
|
+
setHighlightedHtml(html);
|
|
1190
|
+
} catch {
|
|
1191
|
+
setHighlightedHtml("");
|
|
1192
|
+
}
|
|
1193
|
+
}, [code, language, fallbackTheme, disableHighlight, highlight]);
|
|
1194
|
+
useEffect5(() => {
|
|
1195
|
+
doHighlight();
|
|
1196
|
+
}, [doHighlight]);
|
|
1197
|
+
return /* @__PURE__ */ jsxs3("div", { className: "incremark-code", children: [
|
|
1198
|
+
/* @__PURE__ */ jsxs3("div", { className: "code-header", children: [
|
|
1199
|
+
/* @__PURE__ */ jsx9("span", { className: "language", children: language }),
|
|
1200
|
+
/* @__PURE__ */ jsx9(
|
|
1201
|
+
"button",
|
|
1202
|
+
{
|
|
1203
|
+
className: "code-btn",
|
|
1204
|
+
onClick: copyCode,
|
|
1205
|
+
type: "button",
|
|
1206
|
+
"aria-label": copied ? t("code.copied") : t("code.copy"),
|
|
1207
|
+
title: copied ? "Copied!" : "Copy",
|
|
1208
|
+
children: /* @__PURE__ */ jsx9(SvgIcon, { svg: copied ? LucideCopyCheck2 : LucideCopy2 })
|
|
1209
|
+
}
|
|
1210
|
+
)
|
|
1211
|
+
] }),
|
|
1212
|
+
/* @__PURE__ */ jsx9("div", { className: "code-content", children: isHighlighting && !highlightedHtml ? /* @__PURE__ */ jsx9("div", { className: "code-loading", children: /* @__PURE__ */ jsx9("pre", { children: /* @__PURE__ */ jsx9("code", { children: code }) }) }) : highlightedHtml ? /* @__PURE__ */ jsx9("div", { className: "shiki-wrapper", dangerouslySetInnerHTML: { __html: highlightedHtml } }) : /* @__PURE__ */ jsx9("pre", { className: "code-fallback", children: /* @__PURE__ */ jsx9("code", { children: code }) }) })
|
|
1213
|
+
] });
|
|
1214
|
+
};
|
|
1215
|
+
|
|
1216
|
+
// src/components/IncremarkCode.tsx
|
|
1217
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1218
|
+
var IncremarkCode = ({
|
|
1219
|
+
node,
|
|
1220
|
+
theme = "github-dark",
|
|
1221
|
+
fallbackTheme = "github-dark",
|
|
1222
|
+
disableHighlight = false,
|
|
1223
|
+
mermaidDelay = 500,
|
|
1224
|
+
customCodeBlocks,
|
|
1225
|
+
blockStatus = "completed",
|
|
1226
|
+
codeBlockConfigs,
|
|
1227
|
+
defaultCodeComponent: DefaultCodeComponent = IncremarkCodeDefault
|
|
1228
|
+
}) => {
|
|
1229
|
+
const language = node.lang || "text";
|
|
1230
|
+
const code = node.value;
|
|
1231
|
+
const isMermaid = language === "mermaid";
|
|
1232
|
+
const CustomCodeBlock = React7.useMemo(() => {
|
|
1233
|
+
const component = customCodeBlocks?.[language];
|
|
1234
|
+
if (!component) return null;
|
|
1235
|
+
const config = codeBlockConfigs?.[language];
|
|
1236
|
+
if (config?.takeOver) {
|
|
1237
|
+
return component;
|
|
1238
|
+
}
|
|
1239
|
+
if (blockStatus !== "completed") {
|
|
1240
|
+
return null;
|
|
1241
|
+
}
|
|
1242
|
+
return component;
|
|
1243
|
+
}, [customCodeBlocks, language, blockStatus, codeBlockConfigs]);
|
|
984
1244
|
if (CustomCodeBlock) {
|
|
985
1245
|
const config = codeBlockConfigs?.[language];
|
|
986
|
-
return /* @__PURE__ */
|
|
1246
|
+
return /* @__PURE__ */ jsx10(
|
|
987
1247
|
CustomCodeBlock,
|
|
988
1248
|
{
|
|
989
1249
|
codeStr: code,
|
|
@@ -994,38 +1254,28 @@ var IncremarkCode = ({
|
|
|
994
1254
|
);
|
|
995
1255
|
}
|
|
996
1256
|
if (isMermaid) {
|
|
997
|
-
return /* @__PURE__ */
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
className: "code-btn",
|
|
1005
|
-
onClick: toggleMermaidView,
|
|
1006
|
-
type: "button",
|
|
1007
|
-
disabled: !mermaidSvg,
|
|
1008
|
-
children: mermaidViewMode === "preview" ? "\u6E90\u7801" : "\u9884\u89C8"
|
|
1009
|
-
}
|
|
1010
|
-
),
|
|
1011
|
-
/* @__PURE__ */ jsx6("button", { className: "code-btn", onClick: copyCode, type: "button", children: copied ? "\u2713 \u5DF2\u590D\u5236" : "\u590D\u5236" })
|
|
1012
|
-
] })
|
|
1013
|
-
] }),
|
|
1014
|
-
/* @__PURE__ */ jsx6("div", { className: "mermaid-content", children: mermaidLoading && !mermaidSvg ? /* @__PURE__ */ jsx6("div", { className: "mermaid-loading", children: /* @__PURE__ */ jsx6("pre", { className: "mermaid-source-code", children: code }) }) : mermaidViewMode === "source" ? /* @__PURE__ */ jsx6("pre", { className: "mermaid-source-code", children: code }) : mermaidSvg ? /* @__PURE__ */ jsx6("div", { className: "mermaid-svg", dangerouslySetInnerHTML: { __html: mermaidSvg } }) : /* @__PURE__ */ jsx6("pre", { className: "mermaid-source-code", children: code }) })
|
|
1015
|
-
] });
|
|
1257
|
+
return /* @__PURE__ */ jsx10(
|
|
1258
|
+
IncremarkCodeMermaid,
|
|
1259
|
+
{
|
|
1260
|
+
node,
|
|
1261
|
+
mermaidDelay
|
|
1262
|
+
}
|
|
1263
|
+
);
|
|
1016
1264
|
}
|
|
1017
|
-
return /* @__PURE__ */
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1265
|
+
return /* @__PURE__ */ jsx10(
|
|
1266
|
+
DefaultCodeComponent,
|
|
1267
|
+
{
|
|
1268
|
+
node,
|
|
1269
|
+
theme,
|
|
1270
|
+
fallbackTheme,
|
|
1271
|
+
disableHighlight
|
|
1272
|
+
}
|
|
1273
|
+
);
|
|
1024
1274
|
};
|
|
1025
1275
|
|
|
1026
1276
|
// src/components/IncremarkList.tsx
|
|
1027
|
-
import
|
|
1028
|
-
import { jsx as
|
|
1277
|
+
import React8 from "react";
|
|
1278
|
+
import { jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1029
1279
|
function getItemInlineContent(item) {
|
|
1030
1280
|
const firstChild = item.children[0];
|
|
1031
1281
|
if (firstChild?.type === "paragraph") {
|
|
@@ -1044,13 +1294,13 @@ function getItemBlockChildren(item) {
|
|
|
1044
1294
|
var IncremarkList = ({ node }) => {
|
|
1045
1295
|
const Tag = node.ordered ? "ol" : "ul";
|
|
1046
1296
|
const isTaskList = node.children?.some((item) => item.checked !== null && item.checked !== void 0);
|
|
1047
|
-
return /* @__PURE__ */
|
|
1297
|
+
return /* @__PURE__ */ jsx11(Tag, { className: `incremark-list ${isTaskList ? "task-list" : ""}`, start: node.start || void 0, children: node.children?.map((item, index) => {
|
|
1048
1298
|
const isTaskItem = item.checked !== null && item.checked !== void 0;
|
|
1049
1299
|
const inlineContent = getItemInlineContent(item);
|
|
1050
1300
|
const blockChildren = getItemBlockChildren(item);
|
|
1051
1301
|
if (isTaskItem) {
|
|
1052
|
-
return /* @__PURE__ */
|
|
1053
|
-
/* @__PURE__ */
|
|
1302
|
+
return /* @__PURE__ */ jsx11("li", { className: "incremark-list-item task-item", children: /* @__PURE__ */ jsxs4("label", { className: "task-label", children: [
|
|
1303
|
+
/* @__PURE__ */ jsx11(
|
|
1054
1304
|
"input",
|
|
1055
1305
|
{
|
|
1056
1306
|
type: "checkbox",
|
|
@@ -1059,43 +1309,43 @@ var IncremarkList = ({ node }) => {
|
|
|
1059
1309
|
className: "checkbox"
|
|
1060
1310
|
}
|
|
1061
1311
|
),
|
|
1062
|
-
/* @__PURE__ */
|
|
1312
|
+
/* @__PURE__ */ jsx11("span", { className: "task-content", children: /* @__PURE__ */ jsx11(IncremarkInline, { nodes: inlineContent }) })
|
|
1063
1313
|
] }) }, index);
|
|
1064
1314
|
}
|
|
1065
|
-
return /* @__PURE__ */
|
|
1066
|
-
/* @__PURE__ */
|
|
1067
|
-
blockChildren.map((child, childIndex) => /* @__PURE__ */
|
|
1315
|
+
return /* @__PURE__ */ jsxs4("li", { className: "incremark-list-item", children: [
|
|
1316
|
+
/* @__PURE__ */ jsx11(IncremarkInline, { nodes: inlineContent }),
|
|
1317
|
+
blockChildren.map((child, childIndex) => /* @__PURE__ */ jsx11(React8.Fragment, { children: /* @__PURE__ */ jsx11(IncremarkRenderer, { node: child }) }, childIndex))
|
|
1068
1318
|
] }, index);
|
|
1069
1319
|
}) });
|
|
1070
1320
|
};
|
|
1071
1321
|
|
|
1072
1322
|
// src/components/IncremarkBlockquote.tsx
|
|
1073
|
-
import
|
|
1074
|
-
import { jsx as
|
|
1323
|
+
import React9 from "react";
|
|
1324
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1075
1325
|
var IncremarkBlockquote = ({ node }) => {
|
|
1076
|
-
return /* @__PURE__ */
|
|
1326
|
+
return /* @__PURE__ */ jsx12("blockquote", { className: "incremark-blockquote", children: node.children.map((child, index) => /* @__PURE__ */ jsx12(React9.Fragment, { children: /* @__PURE__ */ jsx12(IncremarkRenderer, { node: child }) }, index)) });
|
|
1077
1327
|
};
|
|
1078
1328
|
|
|
1079
1329
|
// src/components/IncremarkTable.tsx
|
|
1080
|
-
import { jsx as
|
|
1330
|
+
import { jsx as jsx13, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1081
1331
|
function getCellContent(cell) {
|
|
1082
1332
|
return cell.children;
|
|
1083
1333
|
}
|
|
1084
1334
|
var IncremarkTable = ({ node }) => {
|
|
1085
|
-
return /* @__PURE__ */
|
|
1086
|
-
/* @__PURE__ */
|
|
1335
|
+
return /* @__PURE__ */ jsx13("div", { className: "incremark-table-wrapper", children: /* @__PURE__ */ jsxs5("table", { className: "incremark-table", children: [
|
|
1336
|
+
/* @__PURE__ */ jsx13("thead", { children: node.children?.[0] && /* @__PURE__ */ jsx13("tr", { children: node.children[0].children.map((cell, cellIndex) => /* @__PURE__ */ jsx13(
|
|
1087
1337
|
"th",
|
|
1088
1338
|
{
|
|
1089
|
-
|
|
1090
|
-
children: /* @__PURE__ */
|
|
1339
|
+
className: `incremark-table-align-${node.align?.[cellIndex] || "left"}`,
|
|
1340
|
+
children: /* @__PURE__ */ jsx13(IncremarkInline, { nodes: getCellContent(cell) })
|
|
1091
1341
|
},
|
|
1092
1342
|
cellIndex
|
|
1093
1343
|
)) }) }),
|
|
1094
|
-
/* @__PURE__ */
|
|
1344
|
+
/* @__PURE__ */ jsx13("tbody", { children: node.children?.slice(1).map((row, rowIndex) => /* @__PURE__ */ jsx13("tr", { children: row.children.map((cell, cellIndex) => /* @__PURE__ */ jsx13(
|
|
1095
1345
|
"td",
|
|
1096
1346
|
{
|
|
1097
|
-
|
|
1098
|
-
children: /* @__PURE__ */
|
|
1347
|
+
className: `incremark-table-align-${node.align?.[cellIndex] || "left"}`,
|
|
1348
|
+
children: /* @__PURE__ */ jsx13(IncremarkInline, { nodes: getCellContent(cell) })
|
|
1099
1349
|
},
|
|
1100
1350
|
cellIndex
|
|
1101
1351
|
)) }, rowIndex)) })
|
|
@@ -1103,25 +1353,25 @@ var IncremarkTable = ({ node }) => {
|
|
|
1103
1353
|
};
|
|
1104
1354
|
|
|
1105
1355
|
// src/components/IncremarkThematicBreak.tsx
|
|
1106
|
-
import { jsx as
|
|
1356
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1107
1357
|
var IncremarkThematicBreak = () => {
|
|
1108
|
-
return /* @__PURE__ */
|
|
1358
|
+
return /* @__PURE__ */ jsx14("hr", { className: "incremark-hr" });
|
|
1109
1359
|
};
|
|
1110
1360
|
|
|
1111
1361
|
// src/components/IncremarkMath.tsx
|
|
1112
|
-
import { useState as
|
|
1113
|
-
import { jsx as
|
|
1362
|
+
import { useState as useState7, useEffect as useEffect6, useRef as useRef7, useCallback as useCallback7 } from "react";
|
|
1363
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1114
1364
|
var IncremarkMath = ({
|
|
1115
1365
|
node,
|
|
1116
1366
|
renderDelay = 300
|
|
1117
1367
|
}) => {
|
|
1118
|
-
const [renderedHtml, setRenderedHtml] =
|
|
1119
|
-
const [isLoading, setIsLoading] =
|
|
1120
|
-
const katexRef =
|
|
1121
|
-
const renderTimerRef =
|
|
1368
|
+
const [renderedHtml, setRenderedHtml] = useState7("");
|
|
1369
|
+
const [isLoading, setIsLoading] = useState7(false);
|
|
1370
|
+
const katexRef = useRef7(null);
|
|
1371
|
+
const renderTimerRef = useRef7(null);
|
|
1122
1372
|
const isInline = node.type === "inlineMath";
|
|
1123
1373
|
const formula = node.value;
|
|
1124
|
-
const doRender =
|
|
1374
|
+
const doRender = useCallback7(async () => {
|
|
1125
1375
|
if (!formula) return;
|
|
1126
1376
|
try {
|
|
1127
1377
|
if (!katexRef.current) {
|
|
@@ -1141,7 +1391,7 @@ var IncremarkMath = ({
|
|
|
1141
1391
|
setIsLoading(false);
|
|
1142
1392
|
}
|
|
1143
1393
|
}, [formula, isInline]);
|
|
1144
|
-
const scheduleRender =
|
|
1394
|
+
const scheduleRender = useCallback7(() => {
|
|
1145
1395
|
if (!formula) {
|
|
1146
1396
|
setRenderedHtml("");
|
|
1147
1397
|
return;
|
|
@@ -1154,10 +1404,10 @@ var IncremarkMath = ({
|
|
|
1154
1404
|
doRender();
|
|
1155
1405
|
}, renderDelay);
|
|
1156
1406
|
}, [formula, renderDelay, doRender]);
|
|
1157
|
-
|
|
1407
|
+
useEffect6(() => {
|
|
1158
1408
|
scheduleRender();
|
|
1159
1409
|
}, [scheduleRender]);
|
|
1160
|
-
|
|
1410
|
+
useEffect6(() => {
|
|
1161
1411
|
return () => {
|
|
1162
1412
|
if (renderTimerRef.current) {
|
|
1163
1413
|
clearTimeout(renderTimerRef.current);
|
|
@@ -1165,13 +1415,13 @@ var IncremarkMath = ({
|
|
|
1165
1415
|
};
|
|
1166
1416
|
}, []);
|
|
1167
1417
|
if (isInline) {
|
|
1168
|
-
return /* @__PURE__ */
|
|
1418
|
+
return /* @__PURE__ */ jsx15("span", { className: "incremark-math-inline", children: renderedHtml && !isLoading ? /* @__PURE__ */ jsx15("span", { dangerouslySetInnerHTML: { __html: renderedHtml } }) : /* @__PURE__ */ jsx15("code", { className: "math-source", children: formula }) });
|
|
1169
1419
|
}
|
|
1170
|
-
return /* @__PURE__ */
|
|
1420
|
+
return /* @__PURE__ */ jsx15("div", { className: "incremark-math-block", children: renderedHtml && !isLoading ? /* @__PURE__ */ jsx15("div", { className: "math-rendered", dangerouslySetInnerHTML: { __html: renderedHtml } }) : /* @__PURE__ */ jsx15("pre", { className: "math-source-block", children: /* @__PURE__ */ jsx15("code", { children: formula }) }) });
|
|
1171
1421
|
};
|
|
1172
1422
|
|
|
1173
1423
|
// src/components/IncremarkContainer.tsx
|
|
1174
|
-
import { jsx as
|
|
1424
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
1175
1425
|
function parseOptions(attributes) {
|
|
1176
1426
|
if (!attributes) return {};
|
|
1177
1427
|
const options = {};
|
|
@@ -1189,22 +1439,22 @@ var IncremarkContainer = ({ node, customContainers }) => {
|
|
|
1189
1439
|
const options = parseOptions(node.attributes);
|
|
1190
1440
|
const CustomContainer = customContainers?.[containerName];
|
|
1191
1441
|
if (CustomContainer) {
|
|
1192
|
-
return /* @__PURE__ */
|
|
1442
|
+
return /* @__PURE__ */ jsx16(CustomContainer, { name: containerName, options, children: node.children?.map((child, index) => /* @__PURE__ */ jsx16(IncremarkRenderer, { node: child }, index)) });
|
|
1193
1443
|
}
|
|
1194
|
-
return /* @__PURE__ */
|
|
1444
|
+
return /* @__PURE__ */ jsx16("div", { className: `incremark-container incremark-container-${containerName}`, children: node.children && node.children.length > 0 && /* @__PURE__ */ jsx16("div", { className: "incremark-container-content", children: node.children.map((child, index) => /* @__PURE__ */ jsx16(IncremarkRenderer, { node: child }, index)) }) });
|
|
1195
1445
|
};
|
|
1196
1446
|
|
|
1197
1447
|
// src/components/IncremarkDefault.tsx
|
|
1198
|
-
import { jsx as
|
|
1448
|
+
import { jsx as jsx17, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1199
1449
|
var IncremarkDefault = ({ node }) => {
|
|
1200
|
-
return /* @__PURE__ */
|
|
1201
|
-
/* @__PURE__ */
|
|
1202
|
-
/* @__PURE__ */
|
|
1450
|
+
return /* @__PURE__ */ jsxs6("div", { className: "incremark-default", children: [
|
|
1451
|
+
/* @__PURE__ */ jsx17("span", { className: "type-badge", children: node.type }),
|
|
1452
|
+
/* @__PURE__ */ jsx17("pre", { children: JSON.stringify(node, null, 2) })
|
|
1203
1453
|
] });
|
|
1204
1454
|
};
|
|
1205
1455
|
|
|
1206
1456
|
// src/components/IncremarkRenderer.tsx
|
|
1207
|
-
import { jsx as
|
|
1457
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
1208
1458
|
var defaultComponents = {
|
|
1209
1459
|
heading: IncremarkHeading,
|
|
1210
1460
|
paragraph: IncremarkParagraph,
|
|
@@ -1240,10 +1490,10 @@ var IncremarkRenderer = ({
|
|
|
1240
1490
|
return null;
|
|
1241
1491
|
}
|
|
1242
1492
|
if (isHtmlNode2(node)) {
|
|
1243
|
-
return /* @__PURE__ */
|
|
1493
|
+
return /* @__PURE__ */ jsx18("pre", { className: "incremark-html-code", children: /* @__PURE__ */ jsx18("code", { children: node.value }) });
|
|
1244
1494
|
}
|
|
1245
1495
|
if (isContainerNode(node)) {
|
|
1246
|
-
return /* @__PURE__ */
|
|
1496
|
+
return /* @__PURE__ */ jsx18(
|
|
1247
1497
|
IncremarkContainer,
|
|
1248
1498
|
{
|
|
1249
1499
|
node,
|
|
@@ -1252,26 +1502,27 @@ var IncremarkRenderer = ({
|
|
|
1252
1502
|
);
|
|
1253
1503
|
}
|
|
1254
1504
|
if (node.type === "code") {
|
|
1255
|
-
return /* @__PURE__ */
|
|
1505
|
+
return /* @__PURE__ */ jsx18(
|
|
1256
1506
|
IncremarkCode,
|
|
1257
1507
|
{
|
|
1258
1508
|
node,
|
|
1259
1509
|
customCodeBlocks,
|
|
1260
1510
|
codeBlockConfigs,
|
|
1261
|
-
blockStatus
|
|
1511
|
+
blockStatus,
|
|
1512
|
+
defaultCodeComponent: components?.["code"]
|
|
1262
1513
|
}
|
|
1263
1514
|
);
|
|
1264
1515
|
}
|
|
1265
1516
|
const Component = getComponent(node.type, components);
|
|
1266
|
-
return /* @__PURE__ */
|
|
1517
|
+
return /* @__PURE__ */ jsx18(Component, { node });
|
|
1267
1518
|
};
|
|
1268
1519
|
|
|
1269
1520
|
// src/components/IncremarkFootnotes.tsx
|
|
1270
|
-
import
|
|
1271
|
-
import { jsx as
|
|
1521
|
+
import React11 from "react";
|
|
1522
|
+
import { jsx as jsx19, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1272
1523
|
var IncremarkFootnotes = () => {
|
|
1273
1524
|
const { footnoteDefinitions, footnoteReferenceOrder } = useDefinitions();
|
|
1274
|
-
const orderedFootnotes =
|
|
1525
|
+
const orderedFootnotes = React11.useMemo(() => {
|
|
1275
1526
|
return footnoteReferenceOrder.map((identifier) => ({
|
|
1276
1527
|
identifier,
|
|
1277
1528
|
definition: footnoteDefinitions[identifier]
|
|
@@ -1280,22 +1531,22 @@ var IncremarkFootnotes = () => {
|
|
|
1280
1531
|
if (orderedFootnotes.length === 0) {
|
|
1281
1532
|
return null;
|
|
1282
1533
|
}
|
|
1283
|
-
return /* @__PURE__ */
|
|
1284
|
-
/* @__PURE__ */
|
|
1285
|
-
/* @__PURE__ */
|
|
1534
|
+
return /* @__PURE__ */ jsxs7("section", { className: "incremark-footnotes", children: [
|
|
1535
|
+
/* @__PURE__ */ jsx19("hr", { className: "incremark-footnotes-divider" }),
|
|
1536
|
+
/* @__PURE__ */ jsx19("ol", { className: "incremark-footnotes-list", children: orderedFootnotes.map((item, index) => /* @__PURE__ */ jsxs7(
|
|
1286
1537
|
"li",
|
|
1287
1538
|
{
|
|
1288
1539
|
id: `fn-${item.identifier}`,
|
|
1289
1540
|
className: "incremark-footnote-item",
|
|
1290
1541
|
children: [
|
|
1291
|
-
/* @__PURE__ */
|
|
1292
|
-
/* @__PURE__ */
|
|
1542
|
+
/* @__PURE__ */ jsxs7("div", { className: "incremark-footnote-content", children: [
|
|
1543
|
+
/* @__PURE__ */ jsxs7("span", { className: "incremark-footnote-number", children: [
|
|
1293
1544
|
index + 1,
|
|
1294
1545
|
"."
|
|
1295
1546
|
] }),
|
|
1296
|
-
/* @__PURE__ */
|
|
1547
|
+
/* @__PURE__ */ jsx19("div", { className: "incremark-footnote-body", children: item.definition.children.map((child, childIndex) => /* @__PURE__ */ jsx19(IncremarkRenderer, { node: child }, childIndex)) })
|
|
1297
1548
|
] }),
|
|
1298
|
-
/* @__PURE__ */
|
|
1549
|
+
/* @__PURE__ */ jsx19(
|
|
1299
1550
|
"a",
|
|
1300
1551
|
{
|
|
1301
1552
|
href: `#fnref-${item.identifier}`,
|
|
@@ -1312,13 +1563,13 @@ var IncremarkFootnotes = () => {
|
|
|
1312
1563
|
};
|
|
1313
1564
|
|
|
1314
1565
|
// src/components/IncremarkContainerProvider.tsx
|
|
1315
|
-
import { jsx as
|
|
1566
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
1316
1567
|
var IncremarkContainerProvider = ({ children, definitions }) => {
|
|
1317
|
-
return /* @__PURE__ */
|
|
1568
|
+
return /* @__PURE__ */ jsx20(DefinitionsContext.Provider, { value: definitions, children });
|
|
1318
1569
|
};
|
|
1319
1570
|
|
|
1320
1571
|
// src/components/Incremark.tsx
|
|
1321
|
-
import { jsx as
|
|
1572
|
+
import { jsx as jsx21, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1322
1573
|
var Incremark = (props) => {
|
|
1323
1574
|
const {
|
|
1324
1575
|
blocks: propsBlocks,
|
|
@@ -1328,11 +1579,13 @@ var Incremark = (props) => {
|
|
|
1328
1579
|
customCodeBlocks,
|
|
1329
1580
|
showBlockStatus = true,
|
|
1330
1581
|
className = "",
|
|
1582
|
+
pendingClass = "incremark-pending",
|
|
1583
|
+
completedClass = "incremark-completed",
|
|
1331
1584
|
incremark
|
|
1332
1585
|
} = props;
|
|
1333
1586
|
if (incremark) {
|
|
1334
1587
|
const { blocks: blocks2, isDisplayComplete: isDisplayComplete2, _definitionsContextValue } = incremark;
|
|
1335
|
-
return /* @__PURE__ */
|
|
1588
|
+
return /* @__PURE__ */ jsx21(IncremarkContainerProvider, { definitions: _definitionsContextValue, children: /* @__PURE__ */ jsx21(
|
|
1336
1589
|
IncremarkInternal,
|
|
1337
1590
|
{
|
|
1338
1591
|
blocks: blocks2,
|
|
@@ -1341,13 +1594,15 @@ var Incremark = (props) => {
|
|
|
1341
1594
|
customCodeBlocks,
|
|
1342
1595
|
showBlockStatus,
|
|
1343
1596
|
className,
|
|
1597
|
+
pendingClass,
|
|
1598
|
+
completedClass,
|
|
1344
1599
|
isDisplayComplete: isDisplayComplete2
|
|
1345
1600
|
}
|
|
1346
1601
|
) });
|
|
1347
1602
|
}
|
|
1348
1603
|
const blocks = propsBlocks || [];
|
|
1349
1604
|
const isDisplayComplete = propsIsDisplayComplete;
|
|
1350
|
-
return /* @__PURE__ */
|
|
1605
|
+
return /* @__PURE__ */ jsx21(
|
|
1351
1606
|
IncremarkInternal,
|
|
1352
1607
|
{
|
|
1353
1608
|
blocks,
|
|
@@ -1356,6 +1611,8 @@ var Incremark = (props) => {
|
|
|
1356
1611
|
customCodeBlocks,
|
|
1357
1612
|
showBlockStatus,
|
|
1358
1613
|
className,
|
|
1614
|
+
pendingClass,
|
|
1615
|
+
completedClass,
|
|
1359
1616
|
isDisplayComplete
|
|
1360
1617
|
}
|
|
1361
1618
|
);
|
|
@@ -1368,9 +1625,11 @@ var IncremarkInternal = ({
|
|
|
1368
1625
|
codeBlockConfigs,
|
|
1369
1626
|
showBlockStatus,
|
|
1370
1627
|
className,
|
|
1628
|
+
pendingClass,
|
|
1629
|
+
completedClass,
|
|
1371
1630
|
isDisplayComplete
|
|
1372
1631
|
}) => {
|
|
1373
|
-
return /* @__PURE__ */
|
|
1632
|
+
return /* @__PURE__ */ jsxs8("div", { className: `incremark ${className}`, children: [
|
|
1374
1633
|
blocks.map((block) => {
|
|
1375
1634
|
if (block.node.type === "definition" || block.node.type === "footnoteDefinition") {
|
|
1376
1635
|
return null;
|
|
@@ -1378,11 +1637,11 @@ var IncremarkInternal = ({
|
|
|
1378
1637
|
const isPending = block.status === "pending";
|
|
1379
1638
|
const classes = [
|
|
1380
1639
|
"incremark-block",
|
|
1381
|
-
isPending ?
|
|
1640
|
+
isPending ? pendingClass : completedClass,
|
|
1382
1641
|
showBlockStatus && "incremark-show-status",
|
|
1383
1642
|
block.isLastPending && "incremark-last-pending"
|
|
1384
1643
|
].filter(Boolean).join(" ");
|
|
1385
|
-
return /* @__PURE__ */
|
|
1644
|
+
return /* @__PURE__ */ jsx21("div", { className: classes, children: /* @__PURE__ */ jsx21(
|
|
1386
1645
|
IncremarkRenderer,
|
|
1387
1646
|
{
|
|
1388
1647
|
node: block.node,
|
|
@@ -1392,22 +1651,112 @@ var IncremarkInternal = ({
|
|
|
1392
1651
|
codeBlockConfigs,
|
|
1393
1652
|
blockStatus: block.status
|
|
1394
1653
|
}
|
|
1395
|
-
) }, block.
|
|
1654
|
+
) }, block.id);
|
|
1396
1655
|
}),
|
|
1397
|
-
isDisplayComplete && /* @__PURE__ */
|
|
1656
|
+
isDisplayComplete && /* @__PURE__ */ jsx21(IncremarkFootnotes, {})
|
|
1398
1657
|
] });
|
|
1399
1658
|
};
|
|
1400
1659
|
|
|
1660
|
+
// src/components/IncremarkContent.tsx
|
|
1661
|
+
import { useEffect as useEffect7, useRef as useRef8, useMemo as useMemo4, useCallback as useCallback8 } from "react";
|
|
1662
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
1663
|
+
var IncremarkContent = (props) => {
|
|
1664
|
+
const {
|
|
1665
|
+
stream,
|
|
1666
|
+
content,
|
|
1667
|
+
components,
|
|
1668
|
+
customContainers,
|
|
1669
|
+
customCodeBlocks,
|
|
1670
|
+
codeBlockConfigs,
|
|
1671
|
+
isFinished = false,
|
|
1672
|
+
incremarkOptions,
|
|
1673
|
+
showBlockStatus,
|
|
1674
|
+
pendingClass
|
|
1675
|
+
} = props;
|
|
1676
|
+
const initialOptionsRef = useRef8({
|
|
1677
|
+
gfm: true,
|
|
1678
|
+
htmlTree: true,
|
|
1679
|
+
containers: true,
|
|
1680
|
+
math: true,
|
|
1681
|
+
...incremarkOptions
|
|
1682
|
+
});
|
|
1683
|
+
const { blocks, append, finalize, render, reset, isDisplayComplete, markdown, typewriter, _definitionsContextValue } = useIncremark(initialOptionsRef.current);
|
|
1684
|
+
useEffect7(() => {
|
|
1685
|
+
if (incremarkOptions?.typewriter) {
|
|
1686
|
+
typewriter.setOptions(incremarkOptions.typewriter);
|
|
1687
|
+
}
|
|
1688
|
+
}, [incremarkOptions?.typewriter, typewriter]);
|
|
1689
|
+
const isStreamMode = useMemo4(() => typeof stream === "function", [stream]);
|
|
1690
|
+
const prevContentRef = useRef8(void 0);
|
|
1691
|
+
const isStreamingRef = useRef8(false);
|
|
1692
|
+
const handleStreamInput = useCallback8(async () => {
|
|
1693
|
+
if (!stream || isStreamingRef.current) return;
|
|
1694
|
+
isStreamingRef.current = true;
|
|
1695
|
+
try {
|
|
1696
|
+
const streamGen = stream();
|
|
1697
|
+
for await (const chunk of streamGen) {
|
|
1698
|
+
append(chunk);
|
|
1699
|
+
}
|
|
1700
|
+
finalize();
|
|
1701
|
+
} catch (error) {
|
|
1702
|
+
console.error("Stream error: ", error);
|
|
1703
|
+
finalize();
|
|
1704
|
+
} finally {
|
|
1705
|
+
isStreamingRef.current = false;
|
|
1706
|
+
}
|
|
1707
|
+
}, [stream, append, finalize]);
|
|
1708
|
+
const handleContentInput = useCallback8((newContent, oldContent) => {
|
|
1709
|
+
if (!newContent) {
|
|
1710
|
+
if (oldContent) {
|
|
1711
|
+
reset();
|
|
1712
|
+
}
|
|
1713
|
+
return;
|
|
1714
|
+
}
|
|
1715
|
+
if (newContent?.startsWith(oldContent ?? "")) {
|
|
1716
|
+
const delta = newContent.slice((oldContent || "").length);
|
|
1717
|
+
append(delta);
|
|
1718
|
+
} else {
|
|
1719
|
+
render(newContent);
|
|
1720
|
+
}
|
|
1721
|
+
}, [append, render, reset]);
|
|
1722
|
+
useEffect7(() => {
|
|
1723
|
+
if (isStreamMode) {
|
|
1724
|
+
handleStreamInput();
|
|
1725
|
+
} else {
|
|
1726
|
+
handleContentInput(content, prevContentRef.current);
|
|
1727
|
+
}
|
|
1728
|
+
prevContentRef.current = content;
|
|
1729
|
+
}, [content, isStreamMode, handleStreamInput, handleContentInput]);
|
|
1730
|
+
useEffect7(() => {
|
|
1731
|
+
if (isFinished && content === markdown) {
|
|
1732
|
+
finalize();
|
|
1733
|
+
}
|
|
1734
|
+
}, [isFinished, content, markdown, finalize]);
|
|
1735
|
+
return /* @__PURE__ */ jsx22(IncremarkContainerProvider, { definitions: _definitionsContextValue, children: /* @__PURE__ */ jsx22(
|
|
1736
|
+
Incremark,
|
|
1737
|
+
{
|
|
1738
|
+
blocks,
|
|
1739
|
+
isDisplayComplete,
|
|
1740
|
+
showBlockStatus,
|
|
1741
|
+
pendingClass,
|
|
1742
|
+
components,
|
|
1743
|
+
customContainers,
|
|
1744
|
+
customCodeBlocks,
|
|
1745
|
+
codeBlockConfigs
|
|
1746
|
+
}
|
|
1747
|
+
) });
|
|
1748
|
+
};
|
|
1749
|
+
|
|
1401
1750
|
// src/components/AutoScrollContainer.tsx
|
|
1402
1751
|
import {
|
|
1403
|
-
useRef as
|
|
1404
|
-
useEffect as
|
|
1405
|
-
useCallback as
|
|
1406
|
-
useState as
|
|
1752
|
+
useRef as useRef9,
|
|
1753
|
+
useEffect as useEffect8,
|
|
1754
|
+
useCallback as useCallback9,
|
|
1755
|
+
useState as useState8,
|
|
1407
1756
|
forwardRef,
|
|
1408
1757
|
useImperativeHandle
|
|
1409
1758
|
} from "react";
|
|
1410
|
-
import { jsx as
|
|
1759
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
1411
1760
|
var AutoScrollContainer = forwardRef(
|
|
1412
1761
|
({
|
|
1413
1762
|
children,
|
|
@@ -1417,17 +1766,17 @@ var AutoScrollContainer = forwardRef(
|
|
|
1417
1766
|
style,
|
|
1418
1767
|
className
|
|
1419
1768
|
}, ref) => {
|
|
1420
|
-
const containerRef =
|
|
1421
|
-
const [isUserScrolledUp, setIsUserScrolledUp] =
|
|
1422
|
-
const lastScrollTopRef =
|
|
1423
|
-
const lastScrollHeightRef =
|
|
1424
|
-
const isNearBottom =
|
|
1769
|
+
const containerRef = useRef9(null);
|
|
1770
|
+
const [isUserScrolledUp, setIsUserScrolledUp] = useState8(false);
|
|
1771
|
+
const lastScrollTopRef = useRef9(0);
|
|
1772
|
+
const lastScrollHeightRef = useRef9(0);
|
|
1773
|
+
const isNearBottom = useCallback9(() => {
|
|
1425
1774
|
const container = containerRef.current;
|
|
1426
1775
|
if (!container) return true;
|
|
1427
1776
|
const { scrollTop, scrollHeight, clientHeight } = container;
|
|
1428
1777
|
return scrollHeight - scrollTop - clientHeight <= threshold;
|
|
1429
1778
|
}, [threshold]);
|
|
1430
|
-
const scrollToBottom =
|
|
1779
|
+
const scrollToBottom = useCallback9(
|
|
1431
1780
|
(force = false) => {
|
|
1432
1781
|
const container = containerRef.current;
|
|
1433
1782
|
if (!container) return;
|
|
@@ -1439,12 +1788,12 @@ var AutoScrollContainer = forwardRef(
|
|
|
1439
1788
|
},
|
|
1440
1789
|
[isUserScrolledUp, behavior]
|
|
1441
1790
|
);
|
|
1442
|
-
const hasScrollbar =
|
|
1791
|
+
const hasScrollbar = useCallback9(() => {
|
|
1443
1792
|
const container = containerRef.current;
|
|
1444
1793
|
if (!container) return false;
|
|
1445
1794
|
return container.scrollHeight > container.clientHeight;
|
|
1446
1795
|
}, []);
|
|
1447
|
-
const handleScroll =
|
|
1796
|
+
const handleScroll = useCallback9(() => {
|
|
1448
1797
|
const container = containerRef.current;
|
|
1449
1798
|
if (!container) return;
|
|
1450
1799
|
const { scrollTop, scrollHeight, clientHeight } = container;
|
|
@@ -1466,14 +1815,14 @@ var AutoScrollContainer = forwardRef(
|
|
|
1466
1815
|
lastScrollTopRef.current = scrollTop;
|
|
1467
1816
|
lastScrollHeightRef.current = scrollHeight;
|
|
1468
1817
|
}, [isNearBottom]);
|
|
1469
|
-
|
|
1818
|
+
useEffect8(() => {
|
|
1470
1819
|
const container = containerRef.current;
|
|
1471
1820
|
if (container) {
|
|
1472
1821
|
lastScrollTopRef.current = container.scrollTop;
|
|
1473
1822
|
lastScrollHeightRef.current = container.scrollHeight;
|
|
1474
1823
|
}
|
|
1475
1824
|
}, []);
|
|
1476
|
-
|
|
1825
|
+
useEffect8(() => {
|
|
1477
1826
|
const container = containerRef.current;
|
|
1478
1827
|
if (!container || !enabled) return;
|
|
1479
1828
|
const observer = new MutationObserver(() => {
|
|
@@ -1505,16 +1854,12 @@ var AutoScrollContainer = forwardRef(
|
|
|
1505
1854
|
}),
|
|
1506
1855
|
[scrollToBottom, isUserScrolledUp]
|
|
1507
1856
|
);
|
|
1508
|
-
return /* @__PURE__ */
|
|
1857
|
+
return /* @__PURE__ */ jsx23(
|
|
1509
1858
|
"div",
|
|
1510
1859
|
{
|
|
1511
1860
|
ref: containerRef,
|
|
1512
1861
|
className: `auto-scroll-container ${className || ""}`.trim(),
|
|
1513
|
-
style
|
|
1514
|
-
overflowY: "auto",
|
|
1515
|
-
height: "100%",
|
|
1516
|
-
...style
|
|
1517
|
-
},
|
|
1862
|
+
style,
|
|
1518
1863
|
onScroll: handleScroll,
|
|
1519
1864
|
children
|
|
1520
1865
|
}
|
|
@@ -1524,21 +1869,21 @@ var AutoScrollContainer = forwardRef(
|
|
|
1524
1869
|
AutoScrollContainer.displayName = "AutoScrollContainer";
|
|
1525
1870
|
|
|
1526
1871
|
// src/ThemeProvider.tsx
|
|
1527
|
-
import { useEffect as
|
|
1872
|
+
import { useEffect as useEffect9, useRef as useRef10 } from "react";
|
|
1528
1873
|
import { applyTheme } from "@incremark/theme";
|
|
1529
|
-
import { jsx as
|
|
1874
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
1530
1875
|
var ThemeProvider = ({
|
|
1531
1876
|
theme,
|
|
1532
1877
|
children,
|
|
1533
1878
|
className = ""
|
|
1534
1879
|
}) => {
|
|
1535
|
-
const containerRef =
|
|
1536
|
-
|
|
1880
|
+
const containerRef = useRef10(null);
|
|
1881
|
+
useEffect9(() => {
|
|
1537
1882
|
if (containerRef.current) {
|
|
1538
1883
|
applyTheme(containerRef.current, theme);
|
|
1539
1884
|
}
|
|
1540
1885
|
}, [theme]);
|
|
1541
|
-
return /* @__PURE__ */
|
|
1886
|
+
return /* @__PURE__ */ jsx24("div", { ref: containerRef, className: `incremark-theme-provider ${className}`.trim(), children });
|
|
1542
1887
|
};
|
|
1543
1888
|
|
|
1544
1889
|
// src/index.ts
|
|
@@ -1564,12 +1909,15 @@ import {
|
|
|
1564
1909
|
mergeTheme,
|
|
1565
1910
|
applyTheme as applyTheme2
|
|
1566
1911
|
} from "@incremark/theme";
|
|
1912
|
+
import { en as enShared, zhCN as zhCNShared } from "@incremark/shared";
|
|
1567
1913
|
export {
|
|
1568
1914
|
AutoScrollContainer,
|
|
1569
1915
|
BlockTransformer2 as BlockTransformer,
|
|
1916
|
+
ConfigProvider,
|
|
1570
1917
|
DefinitionsProvider,
|
|
1571
1918
|
Incremark,
|
|
1572
1919
|
IncremarkContainerProvider,
|
|
1920
|
+
IncremarkContent,
|
|
1573
1921
|
IncremarkFootnotes,
|
|
1574
1922
|
IncremarkHtmlElement,
|
|
1575
1923
|
IncremarkInline,
|
|
@@ -1585,6 +1933,7 @@ export {
|
|
|
1585
1933
|
darkTheme,
|
|
1586
1934
|
defaultPlugins2 as defaultPlugins,
|
|
1587
1935
|
defaultTheme,
|
|
1936
|
+
enShared as en,
|
|
1588
1937
|
generateCSSVars,
|
|
1589
1938
|
imagePlugin,
|
|
1590
1939
|
mathPlugin,
|
|
@@ -1595,7 +1944,9 @@ export {
|
|
|
1595
1944
|
useBlockTransformer,
|
|
1596
1945
|
useDefinitions,
|
|
1597
1946
|
useDevTools,
|
|
1598
|
-
useIncremark
|
|
1947
|
+
useIncremark,
|
|
1948
|
+
useLocale,
|
|
1949
|
+
zhCNShared as zhCN
|
|
1599
1950
|
};
|
|
1600
1951
|
/**
|
|
1601
1952
|
* @file Definitions Context - 管理 Markdown 引用定义
|