@particle-academy/react-fancy 2.4.0 → 2.6.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/{diagram.serializers-OK4HP7AB.js → diagram.serializers-6RPUO46U.js} +11 -11
- package/dist/diagram.serializers-6RPUO46U.js.map +1 -0
- package/dist/index.cjs +403 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +210 -3
- package/dist/index.d.ts +210 -3
- package/dist/index.js +390 -46
- package/dist/index.js.map +1 -1
- package/docs/AccordionPanel.md +135 -0
- package/docs/Action.md +1 -1
- package/docs/ContentRenderer.md +26 -1
- package/package.json +1 -1
- package/dist/diagram.serializers-OK4HP7AB.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -186,9 +186,9 @@ function deserializeERD(input) {
|
|
|
186
186
|
const toEntity = entities.find((e) => e.name === toName);
|
|
187
187
|
if (fromEntity && toEntity) {
|
|
188
188
|
relations.push({
|
|
189
|
-
id: `${fromEntity.id}_${toEntity.id}`,
|
|
190
|
-
from: fromEntity.id,
|
|
191
|
-
to: toEntity.id,
|
|
189
|
+
id: `${fromEntity.id ?? fromEntity.name}_${toEntity.id ?? toEntity.name}`,
|
|
190
|
+
from: fromEntity.id ?? fromEntity.name,
|
|
191
|
+
to: toEntity.id ?? toEntity.name,
|
|
192
192
|
type: parseERDMarker(marker),
|
|
193
193
|
label
|
|
194
194
|
});
|
|
@@ -265,9 +265,9 @@ function deserializeUML(input) {
|
|
|
265
265
|
if (fromEntity && toEntity) {
|
|
266
266
|
const type = fromCard === "1" && toCard === "1" ? "one-to-one" : fromCard === "1" && toCard === "*" ? "one-to-many" : "many-to-many";
|
|
267
267
|
relations.push({
|
|
268
|
-
id: `${fromEntity.id}_${toEntity.id}`,
|
|
269
|
-
from: fromEntity.id,
|
|
270
|
-
to: toEntity.id,
|
|
268
|
+
id: `${fromEntity.id ?? fromEntity.name}_${toEntity.id ?? toEntity.name}`,
|
|
269
|
+
from: fromEntity.id ?? fromEntity.name,
|
|
270
|
+
to: toEntity.id ?? toEntity.name,
|
|
271
271
|
type,
|
|
272
272
|
label
|
|
273
273
|
});
|
|
@@ -303,9 +303,9 @@ function deserializeDFD(input) {
|
|
|
303
303
|
const toEntity = entities.find((e) => e.name === toName);
|
|
304
304
|
if (fromEntity && toEntity) {
|
|
305
305
|
relations.push({
|
|
306
|
-
id: `${fromEntity.id}_${toEntity.id}`,
|
|
307
|
-
from: fromEntity.id,
|
|
308
|
-
to: toEntity.id,
|
|
306
|
+
id: `${fromEntity.id ?? fromEntity.name}_${toEntity.id ?? toEntity.name}`,
|
|
307
|
+
from: fromEntity.id ?? fromEntity.name,
|
|
308
|
+
to: toEntity.id ?? toEntity.name,
|
|
309
309
|
type: "one-to-many",
|
|
310
310
|
label
|
|
311
311
|
});
|
|
@@ -322,6 +322,80 @@ function cn(...inputs) {
|
|
|
322
322
|
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
323
323
|
}
|
|
324
324
|
|
|
325
|
+
// src/utils/sanitize.ts
|
|
326
|
+
var DANGEROUS_TAGS = /* @__PURE__ */ new Set([
|
|
327
|
+
"script",
|
|
328
|
+
"style",
|
|
329
|
+
"iframe",
|
|
330
|
+
"object",
|
|
331
|
+
"embed",
|
|
332
|
+
"link",
|
|
333
|
+
"meta",
|
|
334
|
+
"base",
|
|
335
|
+
"form"
|
|
336
|
+
]);
|
|
337
|
+
var URL_ATTRS = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "xlink:href"]);
|
|
338
|
+
var SAFE_PROTOCOL = /^(?:https?:|mailto:|tel:|sms:|ftp:|#|\/|\.\/|\.\.\/|[^:]*$)/i;
|
|
339
|
+
function sanitizeHref(href) {
|
|
340
|
+
if (href == null) return void 0;
|
|
341
|
+
const trimmed = href.trim();
|
|
342
|
+
if (!trimmed) return void 0;
|
|
343
|
+
return SAFE_PROTOCOL.test(trimmed) ? trimmed : void 0;
|
|
344
|
+
}
|
|
345
|
+
function stripDangerousAttrs(el) {
|
|
346
|
+
const names = [];
|
|
347
|
+
for (let i = 0; i < el.attributes.length; i++) {
|
|
348
|
+
names.push(el.attributes[i].name);
|
|
349
|
+
}
|
|
350
|
+
for (const name of names) {
|
|
351
|
+
const lower = name.toLowerCase();
|
|
352
|
+
if (lower.startsWith("on")) {
|
|
353
|
+
el.removeAttribute(name);
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
if (URL_ATTRS.has(lower)) {
|
|
357
|
+
const sanitized = sanitizeHref(el.getAttribute(name));
|
|
358
|
+
if (sanitized === void 0) {
|
|
359
|
+
el.removeAttribute(name);
|
|
360
|
+
} else {
|
|
361
|
+
el.setAttribute(name, sanitized);
|
|
362
|
+
}
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
if (lower === "srcdoc") {
|
|
366
|
+
el.removeAttribute(name);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
function walk(el, removeQueue) {
|
|
371
|
+
const tag = el.tagName.toLowerCase();
|
|
372
|
+
if (DANGEROUS_TAGS.has(tag)) {
|
|
373
|
+
removeQueue.push(el);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
stripDangerousAttrs(el);
|
|
377
|
+
const children = Array.from(el.children);
|
|
378
|
+
for (const child of children) {
|
|
379
|
+
walk(child, removeQueue);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
function sanitizeHtml(html) {
|
|
383
|
+
if (typeof window === "undefined" || typeof DOMParser === "undefined") {
|
|
384
|
+
return html;
|
|
385
|
+
}
|
|
386
|
+
const doc = new DOMParser().parseFromString(`<body>${html}</body>`, "text/html");
|
|
387
|
+
const body = doc.body;
|
|
388
|
+
if (!body) return html;
|
|
389
|
+
const removeQueue = [];
|
|
390
|
+
for (const child of Array.from(body.children)) {
|
|
391
|
+
walk(child, removeQueue);
|
|
392
|
+
}
|
|
393
|
+
for (const el of removeQueue) {
|
|
394
|
+
el.parentNode?.removeChild(el);
|
|
395
|
+
}
|
|
396
|
+
return body.innerHTML;
|
|
397
|
+
}
|
|
398
|
+
|
|
325
399
|
// src/data/emoji-data.ts
|
|
326
400
|
var EMOJI_CATEGORY_ORDER = [
|
|
327
401
|
"smileys",
|
|
@@ -2721,7 +2795,8 @@ var Action = react.forwardRef(
|
|
|
2721
2795
|
children != null && /* @__PURE__ */ jsxRuntime.jsx("span", { children }),
|
|
2722
2796
|
trailingElements
|
|
2723
2797
|
] });
|
|
2724
|
-
const
|
|
2798
|
+
const safeHref = sanitizeHref(href);
|
|
2799
|
+
const buttonEl = safeHref && !disabled ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: safeHref, className: classes, "data-react-fancy-action": "", children: content }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2725
2800
|
"button",
|
|
2726
2801
|
{
|
|
2727
2802
|
ref,
|
|
@@ -2791,6 +2866,283 @@ var Action = react.forwardRef(
|
|
|
2791
2866
|
}
|
|
2792
2867
|
);
|
|
2793
2868
|
Action.displayName = "Action";
|
|
2869
|
+
function useControllableState(controlledValue, defaultValue, onChange) {
|
|
2870
|
+
const [uncontrolledValue, setUncontrolledValue] = react.useState(defaultValue);
|
|
2871
|
+
const isControlled = controlledValue !== void 0;
|
|
2872
|
+
const value = isControlled ? controlledValue : uncontrolledValue;
|
|
2873
|
+
const onChangeRef = react.useRef(onChange);
|
|
2874
|
+
onChangeRef.current = onChange;
|
|
2875
|
+
const setValue = react.useCallback(
|
|
2876
|
+
(next) => {
|
|
2877
|
+
const nextValue = typeof next === "function" ? next(value) : next;
|
|
2878
|
+
if (!isControlled) {
|
|
2879
|
+
setUncontrolledValue(nextValue);
|
|
2880
|
+
}
|
|
2881
|
+
onChangeRef.current?.(nextValue);
|
|
2882
|
+
},
|
|
2883
|
+
[isControlled, value]
|
|
2884
|
+
);
|
|
2885
|
+
return [value, setValue];
|
|
2886
|
+
}
|
|
2887
|
+
var AccordionPanelContext = react.createContext(null);
|
|
2888
|
+
function useAccordionPanel() {
|
|
2889
|
+
const ctx = react.useContext(AccordionPanelContext);
|
|
2890
|
+
if (!ctx) {
|
|
2891
|
+
throw new Error(
|
|
2892
|
+
"AccordionPanel components must be used inside <AccordionPanel>"
|
|
2893
|
+
);
|
|
2894
|
+
}
|
|
2895
|
+
return ctx;
|
|
2896
|
+
}
|
|
2897
|
+
var AccordionSectionContext = react.createContext(null);
|
|
2898
|
+
function useAccordionSection() {
|
|
2899
|
+
const ctx = react.useContext(AccordionSectionContext);
|
|
2900
|
+
if (!ctx) {
|
|
2901
|
+
throw new Error(
|
|
2902
|
+
"<AccordionPanel.Trigger> must be rendered inside <AccordionPanel.Section>"
|
|
2903
|
+
);
|
|
2904
|
+
}
|
|
2905
|
+
return ctx;
|
|
2906
|
+
}
|
|
2907
|
+
function AccordionPanelSection({
|
|
2908
|
+
id,
|
|
2909
|
+
pinned = false,
|
|
2910
|
+
className,
|
|
2911
|
+
openClassName,
|
|
2912
|
+
closedClassName,
|
|
2913
|
+
children
|
|
2914
|
+
}) {
|
|
2915
|
+
const panel = useAccordionPanel();
|
|
2916
|
+
const { orientation, isOpen, toggle, registerSection } = panel;
|
|
2917
|
+
react.useEffect(() => registerSection(id), [id, registerSection]);
|
|
2918
|
+
const open = pinned || isOpen(id);
|
|
2919
|
+
const sectionCtx = react.useMemo(
|
|
2920
|
+
() => ({
|
|
2921
|
+
id,
|
|
2922
|
+
open,
|
|
2923
|
+
pinned,
|
|
2924
|
+
orientation,
|
|
2925
|
+
toggle: () => toggle(id)
|
|
2926
|
+
}),
|
|
2927
|
+
[id, open, pinned, orientation, toggle]
|
|
2928
|
+
);
|
|
2929
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AccordionSectionContext.Provider, { value: sectionCtx, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2930
|
+
"div",
|
|
2931
|
+
{
|
|
2932
|
+
"data-react-fancy-accordion-section": "",
|
|
2933
|
+
"data-state": open ? "open" : "closed",
|
|
2934
|
+
"data-pinned": pinned ? "" : void 0,
|
|
2935
|
+
"data-orientation": orientation,
|
|
2936
|
+
className: cn(
|
|
2937
|
+
"flex shrink-0 items-center gap-1",
|
|
2938
|
+
orientation === "horizontal" ? "flex-row" : "flex-col",
|
|
2939
|
+
className,
|
|
2940
|
+
open ? openClassName : closedClassName
|
|
2941
|
+
),
|
|
2942
|
+
children
|
|
2943
|
+
}
|
|
2944
|
+
) });
|
|
2945
|
+
}
|
|
2946
|
+
AccordionPanelSection.displayName = "AccordionPanelSection";
|
|
2947
|
+
function renderSlot(slot, state) {
|
|
2948
|
+
return typeof slot === "function" ? slot(state) : slot;
|
|
2949
|
+
}
|
|
2950
|
+
function AccordionPanelTrigger({
|
|
2951
|
+
children,
|
|
2952
|
+
className,
|
|
2953
|
+
"aria-label": ariaLabel
|
|
2954
|
+
}) {
|
|
2955
|
+
const { id, open, orientation, toggle } = useAccordionSection();
|
|
2956
|
+
const state = { id, open, orientation, toggle };
|
|
2957
|
+
if (children !== void 0) {
|
|
2958
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2959
|
+
"div",
|
|
2960
|
+
{
|
|
2961
|
+
"data-react-fancy-accordion-trigger": "",
|
|
2962
|
+
"data-state": open ? "open" : "closed",
|
|
2963
|
+
"data-orientation": orientation,
|
|
2964
|
+
className,
|
|
2965
|
+
children: renderSlot(children, state)
|
|
2966
|
+
}
|
|
2967
|
+
);
|
|
2968
|
+
}
|
|
2969
|
+
if (open) {
|
|
2970
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2971
|
+
"button",
|
|
2972
|
+
{
|
|
2973
|
+
type: "button",
|
|
2974
|
+
onClick: toggle,
|
|
2975
|
+
"aria-label": ariaLabel ?? "Collapse section",
|
|
2976
|
+
"data-react-fancy-accordion-trigger": "",
|
|
2977
|
+
"data-state": "open",
|
|
2978
|
+
"data-orientation": orientation,
|
|
2979
|
+
className: cn(
|
|
2980
|
+
"group relative flex shrink-0 items-center justify-center cursor-pointer",
|
|
2981
|
+
"text-zinc-500 dark:text-zinc-500",
|
|
2982
|
+
"hover:text-zinc-900 dark:hover:text-zinc-100",
|
|
2983
|
+
orientation === "horizontal" ? "w-px self-stretch hover:w-3 mx-1" : "h-px self-stretch hover:h-3 my-1",
|
|
2984
|
+
"before:absolute before:inset-0 before:bg-zinc-200 dark:before:bg-zinc-700",
|
|
2985
|
+
orientation === "horizontal" ? "before:w-px before:left-1/2 before:-translate-x-1/2" : "before:h-px before:top-1/2 before:-translate-y-1/2",
|
|
2986
|
+
"transition-all duration-150",
|
|
2987
|
+
className
|
|
2988
|
+
),
|
|
2989
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2990
|
+
ChevronIcon,
|
|
2991
|
+
{
|
|
2992
|
+
orientation,
|
|
2993
|
+
purpose: "collapse",
|
|
2994
|
+
className: "relative opacity-0 group-hover:opacity-100 transition-opacity"
|
|
2995
|
+
}
|
|
2996
|
+
)
|
|
2997
|
+
}
|
|
2998
|
+
);
|
|
2999
|
+
}
|
|
3000
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3001
|
+
"button",
|
|
3002
|
+
{
|
|
3003
|
+
type: "button",
|
|
3004
|
+
onClick: toggle,
|
|
3005
|
+
"aria-label": ariaLabel ?? "Expand section",
|
|
3006
|
+
"data-react-fancy-accordion-trigger": "",
|
|
3007
|
+
"data-state": "closed",
|
|
3008
|
+
"data-orientation": orientation,
|
|
3009
|
+
className: cn(
|
|
3010
|
+
"flex shrink-0 items-center justify-center rounded-md",
|
|
3011
|
+
"text-zinc-400 dark:text-zinc-500",
|
|
3012
|
+
"hover:text-zinc-900 dark:hover:text-zinc-100",
|
|
3013
|
+
"hover:bg-zinc-100 dark:hover:bg-zinc-800",
|
|
3014
|
+
"transition-colors cursor-pointer",
|
|
3015
|
+
orientation === "horizontal" ? "h-8 w-6 mx-0.5" : "w-8 h-6 my-0.5",
|
|
3016
|
+
className
|
|
3017
|
+
),
|
|
3018
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronIcon, { orientation, purpose: "expand" })
|
|
3019
|
+
}
|
|
3020
|
+
);
|
|
3021
|
+
}
|
|
3022
|
+
AccordionPanelTrigger.displayName = "AccordionPanelTrigger";
|
|
3023
|
+
function ChevronIcon({
|
|
3024
|
+
orientation,
|
|
3025
|
+
purpose,
|
|
3026
|
+
className
|
|
3027
|
+
}) {
|
|
3028
|
+
const transform = orientation === "horizontal" ? "rotate(180deg)" : purpose === "expand" ? "rotate(90deg)" : "rotate(270deg)";
|
|
3029
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3030
|
+
"svg",
|
|
3031
|
+
{
|
|
3032
|
+
viewBox: "0 0 16 16",
|
|
3033
|
+
width: "12",
|
|
3034
|
+
height: "12",
|
|
3035
|
+
fill: "none",
|
|
3036
|
+
stroke: "currentColor",
|
|
3037
|
+
strokeWidth: "2",
|
|
3038
|
+
strokeLinecap: "round",
|
|
3039
|
+
strokeLinejoin: "round",
|
|
3040
|
+
style: { transform },
|
|
3041
|
+
className,
|
|
3042
|
+
"aria-hidden": "true",
|
|
3043
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "6 4 10 8 6 12" })
|
|
3044
|
+
}
|
|
3045
|
+
);
|
|
3046
|
+
}
|
|
3047
|
+
function AccordionPanelContent({
|
|
3048
|
+
children,
|
|
3049
|
+
className
|
|
3050
|
+
}) {
|
|
3051
|
+
const { open, orientation } = useAccordionSection();
|
|
3052
|
+
if (!open) return null;
|
|
3053
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3054
|
+
"div",
|
|
3055
|
+
{
|
|
3056
|
+
"data-react-fancy-accordion-content": "",
|
|
3057
|
+
"data-orientation": orientation,
|
|
3058
|
+
className: cn(
|
|
3059
|
+
"flex items-center gap-1",
|
|
3060
|
+
orientation === "horizontal" ? "flex-row" : "flex-col",
|
|
3061
|
+
className
|
|
3062
|
+
),
|
|
3063
|
+
children
|
|
3064
|
+
}
|
|
3065
|
+
);
|
|
3066
|
+
}
|
|
3067
|
+
AccordionPanelContent.displayName = "AccordionPanelContent";
|
|
3068
|
+
function AccordionPanelRoot({
|
|
3069
|
+
orientation = "horizontal",
|
|
3070
|
+
value: controlledValue,
|
|
3071
|
+
defaultValue,
|
|
3072
|
+
onValueChange,
|
|
3073
|
+
className,
|
|
3074
|
+
children
|
|
3075
|
+
}) {
|
|
3076
|
+
const [openIds, setOpenIds] = useControllableState(
|
|
3077
|
+
controlledValue,
|
|
3078
|
+
defaultValue ?? [],
|
|
3079
|
+
onValueChange
|
|
3080
|
+
);
|
|
3081
|
+
const openSet = react.useMemo(() => new Set(openIds), [openIds]);
|
|
3082
|
+
const isOpen = react.useCallback((id) => openSet.has(id), [openSet]);
|
|
3083
|
+
const open = react.useCallback(
|
|
3084
|
+
(id) => {
|
|
3085
|
+
setOpenIds(openSet.has(id) ? openIds ?? [] : [...openIds ?? [], id]);
|
|
3086
|
+
},
|
|
3087
|
+
[openSet, openIds, setOpenIds]
|
|
3088
|
+
);
|
|
3089
|
+
const close = react.useCallback(
|
|
3090
|
+
(id) => {
|
|
3091
|
+
setOpenIds((openIds ?? []).filter((x) => x !== id));
|
|
3092
|
+
},
|
|
3093
|
+
[openIds, setOpenIds]
|
|
3094
|
+
);
|
|
3095
|
+
const toggle = react.useCallback(
|
|
3096
|
+
(id) => {
|
|
3097
|
+
setOpenIds(
|
|
3098
|
+
openSet.has(id) ? (openIds ?? []).filter((x) => x !== id) : [...openIds ?? [], id]
|
|
3099
|
+
);
|
|
3100
|
+
},
|
|
3101
|
+
[openSet, openIds, setOpenIds]
|
|
3102
|
+
);
|
|
3103
|
+
const [sectionIds, setSectionIds] = react.useState([]);
|
|
3104
|
+
const orderRef = react.useRef([]);
|
|
3105
|
+
const registerSection = react.useCallback((id) => {
|
|
3106
|
+
if (!orderRef.current.includes(id)) {
|
|
3107
|
+
orderRef.current = [...orderRef.current, id];
|
|
3108
|
+
setSectionIds(orderRef.current);
|
|
3109
|
+
}
|
|
3110
|
+
return () => {
|
|
3111
|
+
orderRef.current = orderRef.current.filter((x) => x !== id);
|
|
3112
|
+
setSectionIds(orderRef.current);
|
|
3113
|
+
};
|
|
3114
|
+
}, []);
|
|
3115
|
+
const ctx = react.useMemo(
|
|
3116
|
+
() => ({
|
|
3117
|
+
orientation,
|
|
3118
|
+
isOpen,
|
|
3119
|
+
toggle,
|
|
3120
|
+
open,
|
|
3121
|
+
close,
|
|
3122
|
+
sectionIds,
|
|
3123
|
+
registerSection
|
|
3124
|
+
}),
|
|
3125
|
+
[orientation, isOpen, toggle, open, close, sectionIds, registerSection]
|
|
3126
|
+
);
|
|
3127
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AccordionPanelContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3128
|
+
"div",
|
|
3129
|
+
{
|
|
3130
|
+
"data-react-fancy-accordion-panel": "",
|
|
3131
|
+
"data-orientation": orientation,
|
|
3132
|
+
className: cn(
|
|
3133
|
+
"inline-flex items-stretch",
|
|
3134
|
+
orientation === "horizontal" ? "flex-row" : "flex-col",
|
|
3135
|
+
className
|
|
3136
|
+
),
|
|
3137
|
+
children
|
|
3138
|
+
}
|
|
3139
|
+
) });
|
|
3140
|
+
}
|
|
3141
|
+
AccordionPanelRoot.displayName = "AccordionPanel";
|
|
3142
|
+
var AccordionPanel = AccordionPanelRoot;
|
|
3143
|
+
AccordionPanel.Section = AccordionPanelSection;
|
|
3144
|
+
AccordionPanel.Trigger = AccordionPanelTrigger;
|
|
3145
|
+
AccordionPanel.Content = AccordionPanelContent;
|
|
2794
3146
|
|
|
2795
3147
|
// src/components/inputs/inputs.utils.ts
|
|
2796
3148
|
var inputSizeClasses = {
|
|
@@ -3677,24 +4029,6 @@ var Select = react.forwardRef(
|
|
|
3677
4029
|
}
|
|
3678
4030
|
);
|
|
3679
4031
|
Select.displayName = "Select";
|
|
3680
|
-
function useControllableState(controlledValue, defaultValue, onChange) {
|
|
3681
|
-
const [uncontrolledValue, setUncontrolledValue] = react.useState(defaultValue);
|
|
3682
|
-
const isControlled = controlledValue !== void 0;
|
|
3683
|
-
const value = isControlled ? controlledValue : uncontrolledValue;
|
|
3684
|
-
const onChangeRef = react.useRef(onChange);
|
|
3685
|
-
onChangeRef.current = onChange;
|
|
3686
|
-
const setValue = react.useCallback(
|
|
3687
|
-
(next) => {
|
|
3688
|
-
const nextValue = typeof next === "function" ? next(value) : next;
|
|
3689
|
-
if (!isControlled) {
|
|
3690
|
-
setUncontrolledValue(nextValue);
|
|
3691
|
-
}
|
|
3692
|
-
onChangeRef.current?.(nextValue);
|
|
3693
|
-
},
|
|
3694
|
-
[isControlled, value]
|
|
3695
|
-
);
|
|
3696
|
-
return [value, setValue];
|
|
3697
|
-
}
|
|
3698
4032
|
var Checkbox = react.forwardRef(
|
|
3699
4033
|
({
|
|
3700
4034
|
size = "md",
|
|
@@ -10387,13 +10721,15 @@ function mergeExtensions(instanceExtensions) {
|
|
|
10387
10721
|
}
|
|
10388
10722
|
return merged;
|
|
10389
10723
|
}
|
|
10390
|
-
function toHtml(value, outputFormat) {
|
|
10724
|
+
function toHtml(value, outputFormat, unsafe) {
|
|
10391
10725
|
if (!value) return "";
|
|
10392
|
-
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
|
|
10726
|
+
const raw = (() => {
|
|
10727
|
+
if (outputFormat === "html") return value;
|
|
10728
|
+
const format = detectFormat(value);
|
|
10729
|
+
if (format === "html") return value;
|
|
10730
|
+
return marked.marked.parse(value, { async: false }).trim();
|
|
10731
|
+
})();
|
|
10732
|
+
return unsafe ? raw : sanitizeHtml(raw);
|
|
10397
10733
|
}
|
|
10398
10734
|
function EditorRoot({
|
|
10399
10735
|
children,
|
|
@@ -10404,12 +10740,13 @@ function EditorRoot({
|
|
|
10404
10740
|
outputFormat = "html",
|
|
10405
10741
|
lineSpacing = 1.6,
|
|
10406
10742
|
placeholder,
|
|
10407
|
-
extensions: instanceExtensions
|
|
10743
|
+
extensions: instanceExtensions,
|
|
10744
|
+
unsafe = false
|
|
10408
10745
|
}) {
|
|
10409
10746
|
const contentRef = react.useRef(null);
|
|
10410
10747
|
const [, setValue] = useControllableState(controlledValue, defaultValue, onChange);
|
|
10411
10748
|
const initialHtml = react.useMemo(
|
|
10412
|
-
() => toHtml(controlledValue ?? defaultValue, outputFormat),
|
|
10749
|
+
() => toHtml(controlledValue ?? defaultValue, outputFormat, unsafe),
|
|
10413
10750
|
// Only compute once on mount — don't re-run when value changes from user input
|
|
10414
10751
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
10415
10752
|
[]
|
|
@@ -10494,7 +10831,11 @@ var Editor = Object.assign(EditorRoot, {
|
|
|
10494
10831
|
Toolbar: ToolbarWithSeparator,
|
|
10495
10832
|
Content: EditorContent
|
|
10496
10833
|
});
|
|
10497
|
-
function RenderedContent({
|
|
10834
|
+
function RenderedContent({
|
|
10835
|
+
html,
|
|
10836
|
+
extensions: instanceExtensions,
|
|
10837
|
+
unsafe = false
|
|
10838
|
+
}) {
|
|
10498
10839
|
const extensions = react.useMemo(
|
|
10499
10840
|
() => mergeExtensions(instanceExtensions),
|
|
10500
10841
|
[instanceExtensions]
|
|
@@ -10503,15 +10844,16 @@ function RenderedContent({ html, extensions: instanceExtensions }) {
|
|
|
10503
10844
|
() => parseSegments(html, extensions),
|
|
10504
10845
|
[html, extensions]
|
|
10505
10846
|
);
|
|
10847
|
+
const renderHtml = (content) => unsafe ? content : sanitizeHtml(content);
|
|
10506
10848
|
if (segments.length === 1 && segments[0].type === "html") {
|
|
10507
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: segments[0].content } });
|
|
10849
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: renderHtml(segments[0].content) } });
|
|
10508
10850
|
}
|
|
10509
10851
|
if (segments.length === 0) {
|
|
10510
10852
|
return null;
|
|
10511
10853
|
}
|
|
10512
10854
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: segments.map((segment, i) => {
|
|
10513
10855
|
if (segment.type === "html") {
|
|
10514
|
-
return segment.content ? /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: segment.content } }, i) : null;
|
|
10856
|
+
return segment.content ? /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: renderHtml(segment.content) } }, i) : null;
|
|
10515
10857
|
}
|
|
10516
10858
|
const ext = extensions.find(
|
|
10517
10859
|
(e) => e.tag.toLowerCase() === segment.tag
|
|
@@ -10529,7 +10871,8 @@ function ContentRenderer({
|
|
|
10529
10871
|
format = "auto",
|
|
10530
10872
|
lineSpacing = 1.6,
|
|
10531
10873
|
className,
|
|
10532
|
-
extensions: instanceExtensions
|
|
10874
|
+
extensions: instanceExtensions,
|
|
10875
|
+
unsafe = false
|
|
10533
10876
|
}) {
|
|
10534
10877
|
const extensions = react.useMemo(
|
|
10535
10878
|
() => mergeExtensions(instanceExtensions),
|
|
@@ -10537,11 +10880,9 @@ function ContentRenderer({
|
|
|
10537
10880
|
);
|
|
10538
10881
|
const html = react.useMemo(() => {
|
|
10539
10882
|
const resolvedFormat = format === "auto" ? detectFormat(value) : format;
|
|
10540
|
-
|
|
10541
|
-
|
|
10542
|
-
|
|
10543
|
-
return value;
|
|
10544
|
-
}, [value, format]);
|
|
10883
|
+
const raw = resolvedFormat === "markdown" ? marked.marked.parse(value, { async: false }) : value;
|
|
10884
|
+
return unsafe ? raw : sanitizeHtml(raw);
|
|
10885
|
+
}, [value, format, unsafe]);
|
|
10545
10886
|
const hasExtensions = extensions.length > 0;
|
|
10546
10887
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
10547
10888
|
"div",
|
|
@@ -10549,7 +10890,7 @@ function ContentRenderer({
|
|
|
10549
10890
|
"data-react-fancy-content-renderer": "",
|
|
10550
10891
|
style: { lineHeight: lineSpacing },
|
|
10551
10892
|
className: cn("text-sm", proseClasses, className),
|
|
10552
|
-
children: hasExtensions ? /* @__PURE__ */ jsxRuntime.jsx(RenderedContent, { html, extensions }) : /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: html } })
|
|
10893
|
+
children: hasExtensions ? /* @__PURE__ */ jsxRuntime.jsx(RenderedContent, { html, extensions, unsafe }) : /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: html } })
|
|
10553
10894
|
}
|
|
10554
10895
|
);
|
|
10555
10896
|
}
|
|
@@ -11920,9 +12261,12 @@ var VERTICAL_GAP = 60;
|
|
|
11920
12261
|
function getEntityHeight(fieldCount) {
|
|
11921
12262
|
return HEADER_HEIGHT2 + Math.max(fieldCount, 1) * FIELD_HEIGHT2;
|
|
11922
12263
|
}
|
|
12264
|
+
function resolveEntityId(entity) {
|
|
12265
|
+
return entity.id ?? entity.name;
|
|
12266
|
+
}
|
|
11923
12267
|
function computeDiagramLayout(schema) {
|
|
11924
12268
|
const positions = /* @__PURE__ */ new Map();
|
|
11925
|
-
const entityIds = new Set(schema.entities.map(
|
|
12269
|
+
const entityIds = new Set(schema.entities.map(resolveEntityId));
|
|
11926
12270
|
const incoming = /* @__PURE__ */ new Map();
|
|
11927
12271
|
for (const id of entityIds) {
|
|
11928
12272
|
incoming.set(id, /* @__PURE__ */ new Set());
|
|
@@ -11943,7 +12287,7 @@ function computeDiagramLayout(schema) {
|
|
|
11943
12287
|
}
|
|
11944
12288
|
}
|
|
11945
12289
|
if (queue.length === 0 && entityIds.size > 0) {
|
|
11946
|
-
const firstId = schema.entities[0]
|
|
12290
|
+
const firstId = resolveEntityId(schema.entities[0]);
|
|
11947
12291
|
rowAssignment.set(firstId, 0);
|
|
11948
12292
|
assigned.add(firstId);
|
|
11949
12293
|
queue.push(firstId);
|
|
@@ -11983,7 +12327,7 @@ function computeDiagramLayout(schema) {
|
|
|
11983
12327
|
}
|
|
11984
12328
|
const fieldCounts = /* @__PURE__ */ new Map();
|
|
11985
12329
|
for (const entity of schema.entities) {
|
|
11986
|
-
fieldCounts.set(entity
|
|
12330
|
+
fieldCounts.set(resolveEntityId(entity), entity.fields?.length ?? 0);
|
|
11987
12331
|
}
|
|
11988
12332
|
const sortedRows = Array.from(rows.keys()).sort((a, b) => a - b);
|
|
11989
12333
|
let currentY = 0;
|
|
@@ -12180,7 +12524,7 @@ function FolderIcon({ open }) {
|
|
|
12180
12524
|
}
|
|
12181
12525
|
return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", className: "shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M1.5 3a1 1 0 011-1h3l1.5 1.5H13a1 1 0 011 1v8a1 1 0 01-1 1H2.5a1 1 0 01-1-1V3z", fill: "#fbbf24" }) });
|
|
12182
12526
|
}
|
|
12183
|
-
function
|
|
12527
|
+
function ChevronIcon2({ open }) {
|
|
12184
12528
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
12185
12529
|
"svg",
|
|
12186
12530
|
{
|
|
@@ -12362,7 +12706,7 @@ function TreeNode({ node, depth }) {
|
|
|
12362
12706
|
),
|
|
12363
12707
|
style: { paddingLeft },
|
|
12364
12708
|
children: [
|
|
12365
|
-
isFolder && /* @__PURE__ */ jsxRuntime.jsx(
|
|
12709
|
+
isFolder && /* @__PURE__ */ jsxRuntime.jsx(ChevronIcon2, { open: isExpanded }),
|
|
12366
12710
|
!isFolder && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-3.5 shrink-0" }),
|
|
12367
12711
|
showIcons && (node.icon ?? (isFolder ? /* @__PURE__ */ jsxRuntime.jsx(FolderIcon, { open: isExpanded }) : /* @__PURE__ */ jsxRuntime.jsx(FileIcon, { ext: node.ext ?? node.label.split(".").pop() }))),
|
|
12368
12712
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: node.label })
|
|
@@ -12492,6 +12836,10 @@ var TreeNav = Object.assign(TreeNavRoot, {
|
|
|
12492
12836
|
});
|
|
12493
12837
|
|
|
12494
12838
|
exports.Accordion = Accordion;
|
|
12839
|
+
exports.AccordionPanel = AccordionPanel;
|
|
12840
|
+
exports.AccordionPanelContent = AccordionPanelContent;
|
|
12841
|
+
exports.AccordionPanelSection = AccordionPanelSection;
|
|
12842
|
+
exports.AccordionPanelTrigger = AccordionPanelTrigger;
|
|
12495
12843
|
exports.Action = Action;
|
|
12496
12844
|
exports.Autocomplete = Autocomplete;
|
|
12497
12845
|
exports.Avatar = Avatar;
|
|
@@ -12565,9 +12913,13 @@ exports.registerExtensions = registerExtensions;
|
|
|
12565
12913
|
exports.registerIconSet = registerIconSet;
|
|
12566
12914
|
exports.registerIcons = registerIcons;
|
|
12567
12915
|
exports.resolve = resolve;
|
|
12916
|
+
exports.sanitizeHref = sanitizeHref;
|
|
12917
|
+
exports.sanitizeHtml = sanitizeHtml;
|
|
12568
12918
|
exports.search = search;
|
|
12569
12919
|
exports.skinTones = skinTones;
|
|
12570
12920
|
exports.useAccordion = useAccordion;
|
|
12921
|
+
exports.useAccordionPanel = useAccordionPanel;
|
|
12922
|
+
exports.useAccordionSection = useAccordionSection;
|
|
12571
12923
|
exports.useAnimation = useAnimation;
|
|
12572
12924
|
exports.useCanvas = useCanvas;
|
|
12573
12925
|
exports.useCarousel = useCarousel;
|