@particle-academy/react-fancy 4.7.0 → 4.8.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/dist/index.cjs +101 -69
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +101 -69
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2141,6 +2141,7 @@ function getIconResolutionVersion() {
|
|
|
2141
2141
|
return lucideVersion;
|
|
2142
2142
|
}
|
|
2143
2143
|
function resolveFromLucide(name) {
|
|
2144
|
+
if (typeof window === "undefined") return null;
|
|
2144
2145
|
if (!lucideModule) {
|
|
2145
2146
|
ensureLucideLoaded();
|
|
2146
2147
|
return null;
|
|
@@ -11590,6 +11591,71 @@ function mergeExtensions(instanceExtensions) {
|
|
|
11590
11591
|
}
|
|
11591
11592
|
return merged;
|
|
11592
11593
|
}
|
|
11594
|
+
function RenderedContent({
|
|
11595
|
+
html,
|
|
11596
|
+
extensions: instanceExtensions,
|
|
11597
|
+
unsafe = false
|
|
11598
|
+
}) {
|
|
11599
|
+
const extensions = react.useMemo(
|
|
11600
|
+
() => mergeExtensions(instanceExtensions),
|
|
11601
|
+
[instanceExtensions]
|
|
11602
|
+
);
|
|
11603
|
+
const segments = react.useMemo(
|
|
11604
|
+
() => parseSegments(html, extensions),
|
|
11605
|
+
[html, extensions]
|
|
11606
|
+
);
|
|
11607
|
+
const renderHtml = (content) => unsafe ? content : sanitizeHtml(content);
|
|
11608
|
+
if (segments.length === 1 && segments[0].type === "html") {
|
|
11609
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: renderHtml(segments[0].content) } });
|
|
11610
|
+
}
|
|
11611
|
+
if (segments.length === 0) {
|
|
11612
|
+
return null;
|
|
11613
|
+
}
|
|
11614
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: segments.map((segment, i) => {
|
|
11615
|
+
if (segment.type === "html") {
|
|
11616
|
+
return segment.content ? /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: renderHtml(segment.content) } }, i) : null;
|
|
11617
|
+
}
|
|
11618
|
+
const ext = extensions.find(
|
|
11619
|
+
(e) => e.tag.toLowerCase() === segment.tag
|
|
11620
|
+
);
|
|
11621
|
+
if (!ext) return null;
|
|
11622
|
+
const Component = ext.component;
|
|
11623
|
+
const isBlock = ext.block !== false;
|
|
11624
|
+
const Wrapper = isBlock ? "div" : "span";
|
|
11625
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Wrapper, { "data-render-extension": segment.tag, children: /* @__PURE__ */ jsxRuntime.jsx(Component, { content: segment.content, attributes: segment.attributes }) }, i);
|
|
11626
|
+
}) });
|
|
11627
|
+
}
|
|
11628
|
+
RenderedContent.displayName = "RenderedContent";
|
|
11629
|
+
function ContentRenderer({
|
|
11630
|
+
value,
|
|
11631
|
+
format = "auto",
|
|
11632
|
+
lineSpacing = 1.6,
|
|
11633
|
+
className,
|
|
11634
|
+
extensions: instanceExtensions,
|
|
11635
|
+
unsafe = false
|
|
11636
|
+
}) {
|
|
11637
|
+
const extensions = react.useMemo(
|
|
11638
|
+
() => mergeExtensions(instanceExtensions),
|
|
11639
|
+
[instanceExtensions]
|
|
11640
|
+
);
|
|
11641
|
+
const html = react.useMemo(() => {
|
|
11642
|
+
const safe = value ?? "";
|
|
11643
|
+
const resolvedFormat = format === "auto" ? detectFormat(safe) : format;
|
|
11644
|
+
const raw = resolvedFormat === "markdown" ? marked.marked.parse(safe, { async: false }) : safe;
|
|
11645
|
+
return unsafe ? raw : sanitizeHtml(raw);
|
|
11646
|
+
}, [value, format, unsafe]);
|
|
11647
|
+
const hasExtensions = extensions.length > 0;
|
|
11648
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
11649
|
+
"div",
|
|
11650
|
+
{
|
|
11651
|
+
"data-react-fancy-content-renderer": "",
|
|
11652
|
+
style: { lineHeight: lineSpacing },
|
|
11653
|
+
className: cn("text-sm", proseClasses, className),
|
|
11654
|
+
children: hasExtensions ? /* @__PURE__ */ jsxRuntime.jsx(RenderedContent, { html, extensions, unsafe }) : /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: html } })
|
|
11655
|
+
}
|
|
11656
|
+
);
|
|
11657
|
+
}
|
|
11658
|
+
ContentRenderer.displayName = "ContentRenderer";
|
|
11593
11659
|
function toHtml(value, outputFormat, unsafe) {
|
|
11594
11660
|
if (!value) return "";
|
|
11595
11661
|
const raw = (() => {
|
|
@@ -11609,16 +11675,22 @@ function EditorRoot({
|
|
|
11609
11675
|
outputFormat = "html",
|
|
11610
11676
|
lineSpacing = 1.6,
|
|
11611
11677
|
placeholder,
|
|
11678
|
+
mode: modeProp,
|
|
11612
11679
|
extensions: instanceExtensions,
|
|
11613
11680
|
unsafe = false
|
|
11614
11681
|
}) {
|
|
11615
11682
|
const contentRef = react.useRef(null);
|
|
11616
|
-
const [, setValue] = useControllableState(controlledValue, defaultValue, onChange);
|
|
11683
|
+
const [value, setValue] = useControllableState(controlledValue, defaultValue, onChange);
|
|
11684
|
+
const mode = useFieldMode(modeProp);
|
|
11685
|
+
const isView = mode === "view";
|
|
11617
11686
|
const initialHtml = react.useMemo(
|
|
11618
|
-
() => toHtml(
|
|
11619
|
-
//
|
|
11687
|
+
() => toHtml(value, outputFormat, unsafe),
|
|
11688
|
+
// Seed the contentEditable from the LIVE value when (re)entering edit mode.
|
|
11689
|
+
// EditorContent reads this once on mount, and it only mounts in edit mode —
|
|
11690
|
+
// so this captures the current value on view→edit, not a stale mount snapshot,
|
|
11691
|
+
// and does NOT re-run on every keystroke.
|
|
11620
11692
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
11621
|
-
[]
|
|
11693
|
+
[isView, outputFormat, unsafe]
|
|
11622
11694
|
);
|
|
11623
11695
|
const extensions = react.useMemo(
|
|
11624
11696
|
() => mergeExtensions(instanceExtensions),
|
|
@@ -11681,10 +11753,35 @@ function EditorRoot({
|
|
|
11681
11753
|
_initialHtml: initialHtml,
|
|
11682
11754
|
_onInput: handleInput
|
|
11683
11755
|
};
|
|
11756
|
+
if (isView) {
|
|
11757
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
11758
|
+
"div",
|
|
11759
|
+
{
|
|
11760
|
+
"data-react-fancy-editor": "",
|
|
11761
|
+
"data-mode": "view",
|
|
11762
|
+
className: cn(
|
|
11763
|
+
"overflow-hidden rounded-xl border border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900",
|
|
11764
|
+
className
|
|
11765
|
+
),
|
|
11766
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
11767
|
+
ContentRenderer,
|
|
11768
|
+
{
|
|
11769
|
+
value,
|
|
11770
|
+
format: outputFormat,
|
|
11771
|
+
lineSpacing,
|
|
11772
|
+
extensions: instanceExtensions,
|
|
11773
|
+
unsafe,
|
|
11774
|
+
className: "px-4 py-3"
|
|
11775
|
+
}
|
|
11776
|
+
)
|
|
11777
|
+
}
|
|
11778
|
+
);
|
|
11779
|
+
}
|
|
11684
11780
|
return /* @__PURE__ */ jsxRuntime.jsx(EditorContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
11685
11781
|
"div",
|
|
11686
11782
|
{
|
|
11687
11783
|
"data-react-fancy-editor": "",
|
|
11784
|
+
"data-mode": "edit",
|
|
11688
11785
|
className: cn(
|
|
11689
11786
|
"overflow-hidden rounded-xl border border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900",
|
|
11690
11787
|
className
|
|
@@ -11700,71 +11797,6 @@ var Editor = Object.assign(EditorRoot, {
|
|
|
11700
11797
|
Toolbar: ToolbarWithSeparator,
|
|
11701
11798
|
Content: EditorContent
|
|
11702
11799
|
});
|
|
11703
|
-
function RenderedContent({
|
|
11704
|
-
html,
|
|
11705
|
-
extensions: instanceExtensions,
|
|
11706
|
-
unsafe = false
|
|
11707
|
-
}) {
|
|
11708
|
-
const extensions = react.useMemo(
|
|
11709
|
-
() => mergeExtensions(instanceExtensions),
|
|
11710
|
-
[instanceExtensions]
|
|
11711
|
-
);
|
|
11712
|
-
const segments = react.useMemo(
|
|
11713
|
-
() => parseSegments(html, extensions),
|
|
11714
|
-
[html, extensions]
|
|
11715
|
-
);
|
|
11716
|
-
const renderHtml = (content) => unsafe ? content : sanitizeHtml(content);
|
|
11717
|
-
if (segments.length === 1 && segments[0].type === "html") {
|
|
11718
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: renderHtml(segments[0].content) } });
|
|
11719
|
-
}
|
|
11720
|
-
if (segments.length === 0) {
|
|
11721
|
-
return null;
|
|
11722
|
-
}
|
|
11723
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: segments.map((segment, i) => {
|
|
11724
|
-
if (segment.type === "html") {
|
|
11725
|
-
return segment.content ? /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: renderHtml(segment.content) } }, i) : null;
|
|
11726
|
-
}
|
|
11727
|
-
const ext = extensions.find(
|
|
11728
|
-
(e) => e.tag.toLowerCase() === segment.tag
|
|
11729
|
-
);
|
|
11730
|
-
if (!ext) return null;
|
|
11731
|
-
const Component = ext.component;
|
|
11732
|
-
const isBlock = ext.block !== false;
|
|
11733
|
-
const Wrapper = isBlock ? "div" : "span";
|
|
11734
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Wrapper, { "data-render-extension": segment.tag, children: /* @__PURE__ */ jsxRuntime.jsx(Component, { content: segment.content, attributes: segment.attributes }) }, i);
|
|
11735
|
-
}) });
|
|
11736
|
-
}
|
|
11737
|
-
RenderedContent.displayName = "RenderedContent";
|
|
11738
|
-
function ContentRenderer({
|
|
11739
|
-
value,
|
|
11740
|
-
format = "auto",
|
|
11741
|
-
lineSpacing = 1.6,
|
|
11742
|
-
className,
|
|
11743
|
-
extensions: instanceExtensions,
|
|
11744
|
-
unsafe = false
|
|
11745
|
-
}) {
|
|
11746
|
-
const extensions = react.useMemo(
|
|
11747
|
-
() => mergeExtensions(instanceExtensions),
|
|
11748
|
-
[instanceExtensions]
|
|
11749
|
-
);
|
|
11750
|
-
const html = react.useMemo(() => {
|
|
11751
|
-
const safe = value ?? "";
|
|
11752
|
-
const resolvedFormat = format === "auto" ? detectFormat(safe) : format;
|
|
11753
|
-
const raw = resolvedFormat === "markdown" ? marked.marked.parse(safe, { async: false }) : safe;
|
|
11754
|
-
return unsafe ? raw : sanitizeHtml(raw);
|
|
11755
|
-
}, [value, format, unsafe]);
|
|
11756
|
-
const hasExtensions = extensions.length > 0;
|
|
11757
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
11758
|
-
"div",
|
|
11759
|
-
{
|
|
11760
|
-
"data-react-fancy-content-renderer": "",
|
|
11761
|
-
style: { lineHeight: lineSpacing },
|
|
11762
|
-
className: cn("text-sm", proseClasses, className),
|
|
11763
|
-
children: hasExtensions ? /* @__PURE__ */ jsxRuntime.jsx(RenderedContent, { html, extensions, unsafe }) : /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: html } })
|
|
11764
|
-
}
|
|
11765
|
-
);
|
|
11766
|
-
}
|
|
11767
|
-
ContentRenderer.displayName = "ContentRenderer";
|
|
11768
11800
|
var MenuContext = react.createContext(null);
|
|
11769
11801
|
function useMenu() {
|
|
11770
11802
|
const ctx = react.useContext(MenuContext);
|