@wow-two-beta/ui 0.0.18 → 0.0.20
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/{chunk-D7XIPKDJ.js → chunk-RK6VB3II.js} +859 -4
- package/dist/chunk-RK6VB3II.js.map +1 -0
- package/dist/{chunk-3P7DZCDS.js → chunk-WRPLV6H2.js} +553 -4
- package/dist/chunk-WRPLV6H2.js.map +1 -0
- package/dist/display/dataGrid/DataGrid.d.ts +34 -0
- package/dist/display/dataGrid/DataGrid.d.ts.map +1 -0
- package/dist/display/dataGrid/index.d.ts +2 -0
- package/dist/display/dataGrid/index.d.ts.map +1 -0
- package/dist/display/diffViewer/DiffViewer.d.ts +17 -0
- package/dist/display/diffViewer/DiffViewer.d.ts.map +1 -0
- package/dist/display/diffViewer/index.d.ts +2 -0
- package/dist/display/diffViewer/index.d.ts.map +1 -0
- package/dist/display/heatmapCalendar/HeatmapCalendar.d.ts +21 -0
- package/dist/display/heatmapCalendar/HeatmapCalendar.d.ts.map +1 -0
- package/dist/display/heatmapCalendar/index.d.ts +2 -0
- package/dist/display/heatmapCalendar/index.d.ts.map +1 -0
- package/dist/display/index.d.ts +5 -0
- package/dist/display/index.d.ts.map +1 -1
- package/dist/display/index.js +1 -1
- package/dist/display/nodeEditor/NodeEditor.d.ts +32 -0
- package/dist/display/nodeEditor/NodeEditor.d.ts.map +1 -0
- package/dist/display/nodeEditor/index.d.ts +2 -0
- package/dist/display/nodeEditor/index.d.ts.map +1 -0
- package/dist/display/sparkline/Sparkline.d.ts +22 -0
- package/dist/display/sparkline/Sparkline.d.ts.map +1 -0
- package/dist/display/sparkline/index.d.ts +2 -0
- package/dist/display/sparkline/index.d.ts.map +1 -0
- package/dist/forms/codeEditor/CodeEditor.d.ts +20 -0
- package/dist/forms/codeEditor/CodeEditor.d.ts.map +1 -0
- package/dist/forms/codeEditor/index.d.ts +2 -0
- package/dist/forms/codeEditor/index.d.ts.map +1 -0
- package/dist/forms/index.d.ts +3 -0
- package/dist/forms/index.d.ts.map +1 -1
- package/dist/forms/index.js +1 -1
- package/dist/forms/jsonEditor/JSONEditor.d.ts +22 -0
- package/dist/forms/jsonEditor/JSONEditor.d.ts.map +1 -0
- package/dist/forms/jsonEditor/index.d.ts +2 -0
- package/dist/forms/jsonEditor/index.d.ts.map +1 -0
- package/dist/forms/markdownEditor/MarkdownEditor.d.ts +20 -0
- package/dist/forms/markdownEditor/MarkdownEditor.d.ts.map +1 -0
- package/dist/forms/markdownEditor/index.d.ts +2 -0
- package/dist/forms/markdownEditor/index.d.ts.map +1 -0
- package/dist/index.js +2 -2
- package/package.json +2 -1
- package/dist/chunk-3P7DZCDS.js.map +0 -1
- package/dist/chunk-D7XIPKDJ.js.map +0 -1
|
@@ -11,7 +11,8 @@ import { cn } from './chunk-KZ4VFY2T.js';
|
|
|
11
11
|
import * as React from 'react';
|
|
12
12
|
import { forwardRef, useRef, useImperativeHandle, useState, Children, isValidElement, cloneElement, useId as useId$1, createContext, useMemo, useCallback, useEffect, useContext } from 'react';
|
|
13
13
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
14
|
-
import { Minus, Plus, EyeOff, Eye, Search, X, Check, Upload, ChevronDown, Calendar as Calendar$1, Clock, UploadCloud, ChevronLeft,
|
|
14
|
+
import { Minus, Plus, EyeOff, Eye, Search, X, Check, Upload, ChevronDown, Calendar as Calendar$1, Clock, UploadCloud, ChevronRight, Copy, ChevronLeft, Heading1, Heading2, Bold, Italic, Code, Link2, List, Quote } from 'lucide-react';
|
|
15
|
+
import { marked } from 'marked';
|
|
15
16
|
|
|
16
17
|
var Label = forwardRef(
|
|
17
18
|
({ className, required, htmlFor, id, children, ...props }, ref) => {
|
|
@@ -4492,7 +4493,555 @@ var WizardFooter = forwardRef(
|
|
|
4492
4493
|
Wizard.Steps = WizardSteps;
|
|
4493
4494
|
Wizard.Step = WizardStep;
|
|
4494
4495
|
Wizard.Footer = WizardFooter;
|
|
4496
|
+
var CodeEditor = forwardRef(
|
|
4497
|
+
function CodeEditor2({
|
|
4498
|
+
value: valueProp,
|
|
4499
|
+
defaultValue,
|
|
4500
|
+
onValueChange,
|
|
4501
|
+
language,
|
|
4502
|
+
tabSize = 2,
|
|
4503
|
+
useTabs = false,
|
|
4504
|
+
disabled,
|
|
4505
|
+
readOnly,
|
|
4506
|
+
invalid,
|
|
4507
|
+
minHeight = "12rem",
|
|
4508
|
+
placeholder,
|
|
4509
|
+
className,
|
|
4510
|
+
onKeyDown,
|
|
4511
|
+
onScroll,
|
|
4512
|
+
...rest
|
|
4513
|
+
}, forwardedRef) {
|
|
4514
|
+
const [value, setValue] = useControlled({
|
|
4515
|
+
controlled: valueProp,
|
|
4516
|
+
default: defaultValue ?? "",
|
|
4517
|
+
onChange: onValueChange
|
|
4518
|
+
});
|
|
4519
|
+
const textareaRef = useRef(null);
|
|
4520
|
+
const gutterRef = useRef(null);
|
|
4521
|
+
const [scrollTop, setScrollTop] = useState(0);
|
|
4522
|
+
useImperativeHandle(forwardedRef, () => textareaRef.current);
|
|
4523
|
+
const lineCount = useMemo(() => value.split("\n").length, [value]);
|
|
4524
|
+
const indentChar = useTabs ? " " : " ".repeat(tabSize);
|
|
4525
|
+
const insertAtSelection = useCallback(
|
|
4526
|
+
(insert, selStart, selEnd) => {
|
|
4527
|
+
const next = value.slice(0, selStart) + insert + value.slice(selEnd);
|
|
4528
|
+
setValue(next);
|
|
4529
|
+
return selStart + insert.length;
|
|
4530
|
+
},
|
|
4531
|
+
[value, setValue]
|
|
4532
|
+
);
|
|
4533
|
+
const handleKeyDown = (e) => {
|
|
4534
|
+
onKeyDown?.(e);
|
|
4535
|
+
if (e.defaultPrevented || disabled || readOnly) return;
|
|
4536
|
+
const ta = e.currentTarget;
|
|
4537
|
+
const start = ta.selectionStart;
|
|
4538
|
+
const end = ta.selectionEnd;
|
|
4539
|
+
if (e.key === "Tab") {
|
|
4540
|
+
e.preventDefault();
|
|
4541
|
+
if (start === end) {
|
|
4542
|
+
if (e.shiftKey) {
|
|
4543
|
+
const lineStart = value.lastIndexOf("\n", start - 1) + 1;
|
|
4544
|
+
const lineSlice = value.slice(lineStart, start);
|
|
4545
|
+
const match = useTabs ? /^\t/ : new RegExp(`^ {1,${tabSize}}`);
|
|
4546
|
+
const m = match.exec(lineSlice);
|
|
4547
|
+
if (m) {
|
|
4548
|
+
const next = value.slice(0, lineStart) + lineSlice.slice(m[0].length) + value.slice(start);
|
|
4549
|
+
setValue(next);
|
|
4550
|
+
requestAnimationFrame(() => {
|
|
4551
|
+
if (textareaRef.current) {
|
|
4552
|
+
const newPos = start - m[0].length;
|
|
4553
|
+
textareaRef.current.selectionStart = newPos;
|
|
4554
|
+
textareaRef.current.selectionEnd = newPos;
|
|
4555
|
+
}
|
|
4556
|
+
});
|
|
4557
|
+
}
|
|
4558
|
+
} else {
|
|
4559
|
+
const newPos = insertAtSelection(indentChar, start, end);
|
|
4560
|
+
requestAnimationFrame(() => {
|
|
4561
|
+
if (textareaRef.current) {
|
|
4562
|
+
textareaRef.current.selectionStart = newPos;
|
|
4563
|
+
textareaRef.current.selectionEnd = newPos;
|
|
4564
|
+
}
|
|
4565
|
+
});
|
|
4566
|
+
}
|
|
4567
|
+
} else {
|
|
4568
|
+
const before = value.slice(0, start);
|
|
4569
|
+
const between = value.slice(start, end);
|
|
4570
|
+
const after = value.slice(end);
|
|
4571
|
+
const lineStartOffset = before.lastIndexOf("\n") + 1;
|
|
4572
|
+
const blockStart = before.slice(0, lineStartOffset);
|
|
4573
|
+
const block = before.slice(lineStartOffset) + between;
|
|
4574
|
+
if (e.shiftKey) {
|
|
4575
|
+
const re = useTabs ? /^\t/gm : new RegExp(`^ {1,${tabSize}}`, "gm");
|
|
4576
|
+
const next = blockStart + block.replace(re, "") + after;
|
|
4577
|
+
setValue(next);
|
|
4578
|
+
} else {
|
|
4579
|
+
const next = blockStart + block.replace(/^/gm, indentChar) + after;
|
|
4580
|
+
setValue(next);
|
|
4581
|
+
}
|
|
4582
|
+
}
|
|
4583
|
+
}
|
|
4584
|
+
};
|
|
4585
|
+
const state = invalid ? "invalid" : "default";
|
|
4586
|
+
const gutterText = useMemo(
|
|
4587
|
+
() => Array.from({ length: lineCount }, (_, i) => String(i + 1)).join("\n"),
|
|
4588
|
+
[lineCount]
|
|
4589
|
+
);
|
|
4590
|
+
return /* @__PURE__ */ jsxs(
|
|
4591
|
+
"div",
|
|
4592
|
+
{
|
|
4593
|
+
"data-state": state,
|
|
4594
|
+
"data-language": language || void 0,
|
|
4595
|
+
"data-disabled": disabled || void 0,
|
|
4596
|
+
"data-readonly": readOnly || void 0,
|
|
4597
|
+
className: cn(
|
|
4598
|
+
"relative flex overflow-hidden rounded-md border border-input bg-card text-card-foreground font-mono text-sm shadow-sm",
|
|
4599
|
+
"focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/40",
|
|
4600
|
+
state === "invalid" && "border-destructive focus-within:border-destructive focus-within:ring-destructive/40",
|
|
4601
|
+
disabled && "cursor-not-allowed opacity-60",
|
|
4602
|
+
className
|
|
4603
|
+
),
|
|
4604
|
+
style: { minHeight },
|
|
4605
|
+
children: [
|
|
4606
|
+
/* @__PURE__ */ jsx(
|
|
4607
|
+
"div",
|
|
4608
|
+
{
|
|
4609
|
+
ref: gutterRef,
|
|
4610
|
+
"aria-hidden": "true",
|
|
4611
|
+
className: "select-none whitespace-pre overflow-hidden border-r border-border bg-muted/40 px-3 py-2 text-right text-muted-foreground tabular-nums",
|
|
4612
|
+
style: { transform: `translateY(${-scrollTop}px)` },
|
|
4613
|
+
children: gutterText
|
|
4614
|
+
}
|
|
4615
|
+
),
|
|
4616
|
+
/* @__PURE__ */ jsx(
|
|
4617
|
+
"textarea",
|
|
4618
|
+
{
|
|
4619
|
+
...rest,
|
|
4620
|
+
ref: composeRefs(forwardedRef, textareaRef),
|
|
4621
|
+
value,
|
|
4622
|
+
onChange: (e) => setValue(e.target.value),
|
|
4623
|
+
onKeyDown: handleKeyDown,
|
|
4624
|
+
onScroll: (e) => {
|
|
4625
|
+
setScrollTop(e.currentTarget.scrollTop);
|
|
4626
|
+
onScroll?.(e);
|
|
4627
|
+
},
|
|
4628
|
+
disabled,
|
|
4629
|
+
readOnly,
|
|
4630
|
+
spellCheck: false,
|
|
4631
|
+
placeholder,
|
|
4632
|
+
"aria-invalid": invalid || void 0,
|
|
4633
|
+
className: "block flex-1 resize-none whitespace-pre overflow-auto bg-transparent px-3 py-2 outline-none placeholder:text-subtle-foreground disabled:cursor-not-allowed"
|
|
4634
|
+
}
|
|
4635
|
+
)
|
|
4636
|
+
]
|
|
4637
|
+
}
|
|
4638
|
+
);
|
|
4639
|
+
}
|
|
4640
|
+
);
|
|
4641
|
+
var wrap = (before, after) => ({ value, start, end }) => {
|
|
4642
|
+
const sel = value.slice(start, end);
|
|
4643
|
+
const next = value.slice(0, start) + before + sel + after + value.slice(end);
|
|
4644
|
+
const selStart = start + before.length;
|
|
4645
|
+
return { value: next, selStart, selEnd: selStart + sel.length };
|
|
4646
|
+
};
|
|
4647
|
+
var linePrefix = (prefix) => ({ value, start, end }) => {
|
|
4648
|
+
const lineStart = value.lastIndexOf("\n", start - 1) + 1;
|
|
4649
|
+
const trailing = value.slice(end).indexOf("\n");
|
|
4650
|
+
const lineEnd = trailing === -1 ? value.length : end + trailing;
|
|
4651
|
+
const block = value.slice(lineStart, lineEnd);
|
|
4652
|
+
const updated = block.split("\n").map((l) => prefix + l).join("\n");
|
|
4653
|
+
const next = value.slice(0, lineStart) + updated + value.slice(lineEnd);
|
|
4654
|
+
return { value: next, selStart: lineStart + prefix.length, selEnd: lineStart + updated.length };
|
|
4655
|
+
};
|
|
4656
|
+
var ACTIONS = [
|
|
4657
|
+
{ key: "h1", label: "Heading 1", icon: /* @__PURE__ */ jsx(Icon, { icon: Heading1, size: 14 }), apply: linePrefix("# ") },
|
|
4658
|
+
{ key: "h2", label: "Heading 2", icon: /* @__PURE__ */ jsx(Icon, { icon: Heading2, size: 14 }), apply: linePrefix("## ") },
|
|
4659
|
+
{ key: "bold", label: "Bold", icon: /* @__PURE__ */ jsx(Icon, { icon: Bold, size: 14 }), apply: wrap("**", "**") },
|
|
4660
|
+
{ key: "italic", label: "Italic", icon: /* @__PURE__ */ jsx(Icon, { icon: Italic, size: 14 }), apply: wrap("*", "*") },
|
|
4661
|
+
{ key: "code", label: "Inline code", icon: /* @__PURE__ */ jsx(Icon, { icon: Code, size: 14 }), apply: wrap("`", "`") },
|
|
4662
|
+
{ key: "link", label: "Link", icon: /* @__PURE__ */ jsx(Icon, { icon: Link2, size: 14 }), apply: wrap("[", "](https://)") },
|
|
4663
|
+
{ key: "list", label: "List", icon: /* @__PURE__ */ jsx(Icon, { icon: List, size: 14 }), apply: linePrefix("- ") },
|
|
4664
|
+
{ key: "quote", label: "Blockquote", icon: /* @__PURE__ */ jsx(Icon, { icon: Quote, size: 14 }), apply: linePrefix("> ") }
|
|
4665
|
+
];
|
|
4666
|
+
var MarkdownEditor = forwardRef(
|
|
4667
|
+
function MarkdownEditor2({
|
|
4668
|
+
value: valueProp,
|
|
4669
|
+
defaultValue,
|
|
4670
|
+
onValueChange,
|
|
4671
|
+
view: viewProp,
|
|
4672
|
+
defaultView,
|
|
4673
|
+
onViewChange,
|
|
4674
|
+
renderPreview,
|
|
4675
|
+
disabled,
|
|
4676
|
+
readOnly,
|
|
4677
|
+
invalid,
|
|
4678
|
+
minHeight = "18rem",
|
|
4679
|
+
placeholder,
|
|
4680
|
+
className,
|
|
4681
|
+
...rest
|
|
4682
|
+
}, forwardedRef) {
|
|
4683
|
+
const [value, setValue] = useControlled({
|
|
4684
|
+
controlled: valueProp,
|
|
4685
|
+
default: defaultValue ?? "",
|
|
4686
|
+
onChange: onValueChange
|
|
4687
|
+
});
|
|
4688
|
+
const [view, setView] = useControlled({
|
|
4689
|
+
controlled: viewProp,
|
|
4690
|
+
default: defaultView ?? "split",
|
|
4691
|
+
onChange: onViewChange
|
|
4692
|
+
});
|
|
4693
|
+
const textareaRef = useRef(null);
|
|
4694
|
+
const groupId = useId$1();
|
|
4695
|
+
useImperativeHandle(forwardedRef, () => textareaRef.current);
|
|
4696
|
+
const previewHtml = useMemo(() => {
|
|
4697
|
+
if (renderPreview) return null;
|
|
4698
|
+
try {
|
|
4699
|
+
return marked.parse(value, { async: false });
|
|
4700
|
+
} catch {
|
|
4701
|
+
return "<p>Failed to render preview.</p>";
|
|
4702
|
+
}
|
|
4703
|
+
}, [value, renderPreview]);
|
|
4704
|
+
const applyAction = (action) => {
|
|
4705
|
+
const ta = textareaRef.current;
|
|
4706
|
+
if (!ta) return;
|
|
4707
|
+
const next = action.apply({
|
|
4708
|
+
value,
|
|
4709
|
+
start: ta.selectionStart ?? value.length,
|
|
4710
|
+
end: ta.selectionEnd ?? value.length
|
|
4711
|
+
});
|
|
4712
|
+
setValue(next.value);
|
|
4713
|
+
requestAnimationFrame(() => {
|
|
4714
|
+
ta.focus();
|
|
4715
|
+
ta.selectionStart = next.selStart;
|
|
4716
|
+
ta.selectionEnd = next.selEnd;
|
|
4717
|
+
});
|
|
4718
|
+
};
|
|
4719
|
+
const showEdit = view === "split" || view === "edit";
|
|
4720
|
+
const showPreview = view === "split" || view === "preview";
|
|
4721
|
+
const state = invalid ? "invalid" : "default";
|
|
4722
|
+
return /* @__PURE__ */ jsxs(
|
|
4723
|
+
"div",
|
|
4724
|
+
{
|
|
4725
|
+
"data-state": state,
|
|
4726
|
+
className: cn(
|
|
4727
|
+
"flex flex-col overflow-hidden rounded-md border border-input bg-card text-card-foreground shadow-sm",
|
|
4728
|
+
state === "invalid" && "border-destructive",
|
|
4729
|
+
disabled && "opacity-60",
|
|
4730
|
+
className
|
|
4731
|
+
),
|
|
4732
|
+
style: { minHeight },
|
|
4733
|
+
children: [
|
|
4734
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 border-b border-border bg-muted/40 px-2 py-1", children: [
|
|
4735
|
+
/* @__PURE__ */ jsx("div", { role: "toolbar", "aria-label": "Markdown formatting", className: "flex items-center gap-0.5", children: ACTIONS.map((a) => /* @__PURE__ */ jsx(
|
|
4736
|
+
"button",
|
|
4737
|
+
{
|
|
4738
|
+
type: "button",
|
|
4739
|
+
"aria-label": a.label,
|
|
4740
|
+
disabled: disabled || readOnly,
|
|
4741
|
+
onClick: () => applyAction(a),
|
|
4742
|
+
className: "inline-flex h-7 w-7 items-center justify-center rounded-sm text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
|
|
4743
|
+
children: a.icon
|
|
4744
|
+
},
|
|
4745
|
+
a.key
|
|
4746
|
+
)) }),
|
|
4747
|
+
/* @__PURE__ */ jsx("div", { role: "radiogroup", "aria-label": "View mode", className: "ml-auto flex items-center gap-0.5 rounded-md bg-card p-0.5 ring-1 ring-border", children: ["edit", "split", "preview"].map((v) => /* @__PURE__ */ jsx(
|
|
4748
|
+
"button",
|
|
4749
|
+
{
|
|
4750
|
+
type: "button",
|
|
4751
|
+
role: "radio",
|
|
4752
|
+
"aria-checked": view === v,
|
|
4753
|
+
onClick: () => setView(v),
|
|
4754
|
+
className: cn(
|
|
4755
|
+
"inline-flex h-6 items-center rounded px-2 text-xs font-medium transition-colors",
|
|
4756
|
+
view === v ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:text-foreground"
|
|
4757
|
+
),
|
|
4758
|
+
children: v
|
|
4759
|
+
},
|
|
4760
|
+
v
|
|
4761
|
+
)) })
|
|
4762
|
+
] }),
|
|
4763
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 divide-x divide-border", style: { minHeight: 0 }, children: [
|
|
4764
|
+
showEdit && /* @__PURE__ */ jsx(
|
|
4765
|
+
"textarea",
|
|
4766
|
+
{
|
|
4767
|
+
...rest,
|
|
4768
|
+
ref: textareaRef,
|
|
4769
|
+
id: groupId,
|
|
4770
|
+
value,
|
|
4771
|
+
placeholder,
|
|
4772
|
+
disabled,
|
|
4773
|
+
readOnly,
|
|
4774
|
+
spellCheck: false,
|
|
4775
|
+
"aria-invalid": invalid || void 0,
|
|
4776
|
+
onChange: (e) => setValue(e.target.value),
|
|
4777
|
+
className: cn(
|
|
4778
|
+
"flex-1 resize-none whitespace-pre-wrap break-words bg-transparent p-3 font-mono text-sm outline-none placeholder:text-subtle-foreground disabled:cursor-not-allowed",
|
|
4779
|
+
showPreview && "border-r-0"
|
|
4780
|
+
)
|
|
4781
|
+
}
|
|
4782
|
+
),
|
|
4783
|
+
showPreview && /* @__PURE__ */ jsx(
|
|
4784
|
+
"div",
|
|
4785
|
+
{
|
|
4786
|
+
"aria-live": "polite",
|
|
4787
|
+
"aria-label": "Preview",
|
|
4788
|
+
className: "prose prose-sm flex-1 overflow-auto bg-background p-3 text-sm text-foreground",
|
|
4789
|
+
children: renderPreview ? renderPreview(value) : /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: previewHtml ?? "" } })
|
|
4790
|
+
}
|
|
4791
|
+
)
|
|
4792
|
+
] })
|
|
4793
|
+
]
|
|
4794
|
+
}
|
|
4795
|
+
);
|
|
4796
|
+
}
|
|
4797
|
+
);
|
|
4798
|
+
function describeType(v) {
|
|
4799
|
+
if (v === null) return "null";
|
|
4800
|
+
if (Array.isArray(v)) return "array";
|
|
4801
|
+
return typeof v;
|
|
4802
|
+
}
|
|
4803
|
+
function pathToString(path) {
|
|
4804
|
+
return path.map((p) => typeof p === "number" ? `[${p}]` : path.indexOf(p) === 0 ? p : `.${p}`).join("");
|
|
4805
|
+
}
|
|
4806
|
+
function setAtPath(root, path, next) {
|
|
4807
|
+
if (path.length === 0) return next;
|
|
4808
|
+
const [head, ...rest] = path;
|
|
4809
|
+
if (Array.isArray(root)) {
|
|
4810
|
+
const idx = head;
|
|
4811
|
+
const copy = root.slice();
|
|
4812
|
+
copy[idx] = setAtPath(root[idx], rest, next);
|
|
4813
|
+
return copy;
|
|
4814
|
+
}
|
|
4815
|
+
if (root && typeof root === "object") {
|
|
4816
|
+
const key = head;
|
|
4817
|
+
return { ...root, [key]: setAtPath(root[key], rest, next) };
|
|
4818
|
+
}
|
|
4819
|
+
return root;
|
|
4820
|
+
}
|
|
4821
|
+
var JSONEditor = forwardRef(function JSONEditor2({
|
|
4822
|
+
value: valueProp,
|
|
4823
|
+
defaultValue,
|
|
4824
|
+
onValueChange,
|
|
4825
|
+
mode: modeProp,
|
|
4826
|
+
defaultMode = "tree",
|
|
4827
|
+
onModeChange,
|
|
4828
|
+
disabled,
|
|
4829
|
+
readOnly,
|
|
4830
|
+
invalid,
|
|
4831
|
+
indent = 2,
|
|
4832
|
+
minHeight = "14rem",
|
|
4833
|
+
className,
|
|
4834
|
+
...rest
|
|
4835
|
+
}, ref) {
|
|
4836
|
+
const [value, setValue] = useControlled({
|
|
4837
|
+
controlled: valueProp,
|
|
4838
|
+
default: defaultValue ?? {},
|
|
4839
|
+
onChange: onValueChange
|
|
4840
|
+
});
|
|
4841
|
+
const [mode, setMode] = useControlled({
|
|
4842
|
+
controlled: modeProp,
|
|
4843
|
+
default: defaultMode,
|
|
4844
|
+
onChange: onModeChange
|
|
4845
|
+
});
|
|
4846
|
+
const updateAt = (path, next) => {
|
|
4847
|
+
setValue(setAtPath(value, path, next));
|
|
4848
|
+
};
|
|
4849
|
+
return /* @__PURE__ */ jsxs(
|
|
4850
|
+
"div",
|
|
4851
|
+
{
|
|
4852
|
+
ref,
|
|
4853
|
+
"data-state": invalid ? "invalid" : "default",
|
|
4854
|
+
className: cn(
|
|
4855
|
+
"flex flex-col overflow-hidden rounded-md border border-input bg-card text-card-foreground shadow-sm",
|
|
4856
|
+
invalid && "border-destructive",
|
|
4857
|
+
disabled && "opacity-60",
|
|
4858
|
+
className
|
|
4859
|
+
),
|
|
4860
|
+
style: { minHeight },
|
|
4861
|
+
...rest,
|
|
4862
|
+
children: [
|
|
4863
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1 border-b border-border bg-muted/40 px-2 py-1", children: /* @__PURE__ */ jsx("div", { role: "radiogroup", "aria-label": "JSON mode", className: "flex items-center gap-0.5 rounded-md bg-card p-0.5 ring-1 ring-border", children: ["tree", "text"].map((m) => /* @__PURE__ */ jsx(
|
|
4864
|
+
"button",
|
|
4865
|
+
{
|
|
4866
|
+
type: "button",
|
|
4867
|
+
role: "radio",
|
|
4868
|
+
"aria-checked": mode === m,
|
|
4869
|
+
onClick: () => setMode(m),
|
|
4870
|
+
className: cn(
|
|
4871
|
+
"inline-flex h-6 items-center rounded px-2 text-xs font-medium transition-colors",
|
|
4872
|
+
mode === m ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:text-foreground"
|
|
4873
|
+
),
|
|
4874
|
+
children: m
|
|
4875
|
+
},
|
|
4876
|
+
m
|
|
4877
|
+
)) }) }),
|
|
4878
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-auto", style: { minHeight: 0 }, children: mode === "tree" ? /* @__PURE__ */ jsx(TreeView, { value, updateAt, disabled, readOnly }) : /* @__PURE__ */ jsx(TextView, { value, setValue, disabled, readOnly, indent }) })
|
|
4879
|
+
]
|
|
4880
|
+
}
|
|
4881
|
+
);
|
|
4882
|
+
});
|
|
4883
|
+
function TreeView({ value, updateAt, disabled, readOnly }) {
|
|
4884
|
+
return /* @__PURE__ */ jsx("ul", { role: "tree", className: "font-mono text-sm", children: /* @__PURE__ */ jsx(TreeNode, { keyName: null, value, path: [], updateAt, disabled, readOnly, depth: 0 }) });
|
|
4885
|
+
}
|
|
4886
|
+
function TreeNode({ keyName, value, path, updateAt, disabled, readOnly, depth }) {
|
|
4887
|
+
const type = describeType(value);
|
|
4888
|
+
const isObject = type === "object" || type === "array";
|
|
4889
|
+
const [open, setOpen] = useState(depth < 2);
|
|
4890
|
+
const [editing, setEditing] = useState(false);
|
|
4891
|
+
const [draft, setDraft] = useState("");
|
|
4892
|
+
const startEdit = () => {
|
|
4893
|
+
if (disabled || readOnly || isObject) return;
|
|
4894
|
+
setEditing(true);
|
|
4895
|
+
setDraft(typeof value === "string" ? value : String(value));
|
|
4896
|
+
};
|
|
4897
|
+
const commitEdit = () => {
|
|
4898
|
+
setEditing(false);
|
|
4899
|
+
if (typeof value === "number") {
|
|
4900
|
+
const n = Number(draft);
|
|
4901
|
+
if (!Number.isNaN(n)) updateAt(path, n);
|
|
4902
|
+
} else if (typeof value === "boolean") {
|
|
4903
|
+
if (draft === "true" || draft === "false") updateAt(path, draft === "true");
|
|
4904
|
+
} else if (value === null) {
|
|
4905
|
+
if (draft === "null") updateAt(path, null);
|
|
4906
|
+
} else {
|
|
4907
|
+
updateAt(path, draft);
|
|
4908
|
+
}
|
|
4909
|
+
};
|
|
4910
|
+
const onKey = (e) => {
|
|
4911
|
+
if (e.key === "Enter") commitEdit();
|
|
4912
|
+
if (e.key === "Escape") setEditing(false);
|
|
4913
|
+
};
|
|
4914
|
+
const copyPath = () => {
|
|
4915
|
+
const text = pathToString(path);
|
|
4916
|
+
if (typeof navigator !== "undefined" && navigator.clipboard) {
|
|
4917
|
+
navigator.clipboard.writeText(text).catch(() => {
|
|
4918
|
+
});
|
|
4919
|
+
}
|
|
4920
|
+
};
|
|
4921
|
+
const entries = isObject ? Array.isArray(value) ? value.map((v, i) => [i, v]) : Object.entries(value) : [];
|
|
4922
|
+
return /* @__PURE__ */ jsxs("li", { role: "treeitem", "aria-expanded": isObject ? open : void 0, className: "px-1", children: [
|
|
4923
|
+
/* @__PURE__ */ jsxs("div", { className: "group flex items-start gap-1 py-0.5", style: { paddingLeft: depth * 16 }, children: [
|
|
4924
|
+
isObject ? /* @__PURE__ */ jsx(
|
|
4925
|
+
"button",
|
|
4926
|
+
{
|
|
4927
|
+
type: "button",
|
|
4928
|
+
"aria-label": open ? "Collapse" : "Expand",
|
|
4929
|
+
onClick: () => setOpen((o) => !o),
|
|
4930
|
+
className: "inline-flex h-5 w-5 items-center justify-center text-muted-foreground hover:text-foreground",
|
|
4931
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: ChevronRight, size: 12, className: cn("transition-transform", open && "rotate-90") })
|
|
4932
|
+
}
|
|
4933
|
+
) : /* @__PURE__ */ jsx("span", { className: "inline-block h-5 w-5" }),
|
|
4934
|
+
keyName !== null && /* @__PURE__ */ jsxs("span", { className: "text-foreground", children: [
|
|
4935
|
+
typeof keyName === "string" ? `"${keyName}"` : keyName,
|
|
4936
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: ": " })
|
|
4937
|
+
] }),
|
|
4938
|
+
isObject ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: Array.isArray(value) ? `Array(${entries.length})` : `Object(${entries.length})` }) : editing ? /* @__PURE__ */ jsx(
|
|
4939
|
+
"input",
|
|
4940
|
+
{
|
|
4941
|
+
autoFocus: true,
|
|
4942
|
+
value: draft,
|
|
4943
|
+
onChange: (e) => setDraft(e.target.value),
|
|
4944
|
+
onKeyDown: onKey,
|
|
4945
|
+
onBlur: commitEdit,
|
|
4946
|
+
className: "h-5 rounded-sm bg-background px-1 text-sm font-mono outline-none ring-2 ring-ring"
|
|
4947
|
+
}
|
|
4948
|
+
) : /* @__PURE__ */ jsx(
|
|
4949
|
+
"button",
|
|
4950
|
+
{
|
|
4951
|
+
type: "button",
|
|
4952
|
+
onClick: startEdit,
|
|
4953
|
+
className: cn(
|
|
4954
|
+
"cursor-text rounded-sm px-1 text-left transition-colors",
|
|
4955
|
+
!disabled && !readOnly && "hover:bg-muted",
|
|
4956
|
+
type === "string" && "text-info",
|
|
4957
|
+
type === "number" && "text-warning",
|
|
4958
|
+
type === "boolean" && "text-success",
|
|
4959
|
+
type === "null" && "text-muted-foreground italic"
|
|
4960
|
+
),
|
|
4961
|
+
children: type === "string" ? `"${value}"` : String(value)
|
|
4962
|
+
}
|
|
4963
|
+
),
|
|
4964
|
+
/* @__PURE__ */ jsx(
|
|
4965
|
+
"button",
|
|
4966
|
+
{
|
|
4967
|
+
type: "button",
|
|
4968
|
+
"aria-label": `Copy path ${pathToString(path) || "root"}`,
|
|
4969
|
+
onClick: copyPath,
|
|
4970
|
+
className: "ml-auto opacity-0 transition-opacity group-hover:opacity-100 inline-flex h-5 w-5 items-center justify-center rounded text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
4971
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: Copy, size: 11 })
|
|
4972
|
+
}
|
|
4973
|
+
)
|
|
4974
|
+
] }),
|
|
4975
|
+
isObject && open && /* @__PURE__ */ jsx("ul", { role: "group", children: entries.map(([k, v]) => /* @__PURE__ */ jsx(
|
|
4976
|
+
TreeNode,
|
|
4977
|
+
{
|
|
4978
|
+
keyName: k,
|
|
4979
|
+
value: v,
|
|
4980
|
+
path: [...path, k],
|
|
4981
|
+
updateAt,
|
|
4982
|
+
disabled,
|
|
4983
|
+
readOnly,
|
|
4984
|
+
depth: depth + 1
|
|
4985
|
+
},
|
|
4986
|
+
String(k)
|
|
4987
|
+
)) })
|
|
4988
|
+
] });
|
|
4989
|
+
}
|
|
4990
|
+
function TextView({ value, setValue, disabled, readOnly, indent }) {
|
|
4991
|
+
const initial = useMemo(() => safeStringify(value, indent), [value, indent]);
|
|
4992
|
+
const [draft, setDraft] = useState(initial);
|
|
4993
|
+
const [error, setError] = useState(null);
|
|
4994
|
+
const dirty = useRef(false);
|
|
4995
|
+
useEffect(() => {
|
|
4996
|
+
if (!dirty.current) setDraft(initial);
|
|
4997
|
+
}, [initial]);
|
|
4998
|
+
const commit = () => {
|
|
4999
|
+
try {
|
|
5000
|
+
const parsed = JSON.parse(draft);
|
|
5001
|
+
setError(null);
|
|
5002
|
+
setValue(parsed);
|
|
5003
|
+
dirty.current = false;
|
|
5004
|
+
} catch (err) {
|
|
5005
|
+
setError(err instanceof Error ? err.message : "Invalid JSON");
|
|
5006
|
+
}
|
|
5007
|
+
};
|
|
5008
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col", children: [
|
|
5009
|
+
/* @__PURE__ */ jsx(
|
|
5010
|
+
"textarea",
|
|
5011
|
+
{
|
|
5012
|
+
value: draft,
|
|
5013
|
+
disabled,
|
|
5014
|
+
readOnly,
|
|
5015
|
+
spellCheck: false,
|
|
5016
|
+
onChange: (e) => {
|
|
5017
|
+
dirty.current = true;
|
|
5018
|
+
setDraft(e.target.value);
|
|
5019
|
+
},
|
|
5020
|
+
onBlur: commit,
|
|
5021
|
+
onKeyDown: (e) => {
|
|
5022
|
+
if (e.key === "Escape") {
|
|
5023
|
+
setDraft(initial);
|
|
5024
|
+
setError(null);
|
|
5025
|
+
dirty.current = false;
|
|
5026
|
+
}
|
|
5027
|
+
},
|
|
5028
|
+
className: cn(
|
|
5029
|
+
"flex-1 resize-none whitespace-pre bg-transparent p-3 font-mono text-sm outline-none placeholder:text-subtle-foreground disabled:cursor-not-allowed",
|
|
5030
|
+
error && "text-foreground"
|
|
5031
|
+
)
|
|
5032
|
+
}
|
|
5033
|
+
),
|
|
5034
|
+
error && /* @__PURE__ */ jsx("div", { role: "alert", className: "border-t border-destructive bg-destructive-soft px-3 py-2 text-xs text-destructive", children: error })
|
|
5035
|
+
] });
|
|
5036
|
+
}
|
|
5037
|
+
function safeStringify(value, indent) {
|
|
5038
|
+
try {
|
|
5039
|
+
return JSON.stringify(value, null, indent);
|
|
5040
|
+
} catch {
|
|
5041
|
+
return "";
|
|
5042
|
+
}
|
|
5043
|
+
}
|
|
4495
5044
|
|
|
4496
|
-
export { Calendar, CharacterCount, Checkbox, CheckboxField, CheckboxGroup, ChoiceCard, ColorArea, ColorField, ColorPicker, ColorSlider, ColorSwatch, ColorSwatchPicker, ColorWheel, Combobox, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxSeparator, CurrencyInput, DateField, DatePicker, DateRangePicker, Editable, EditableCancel, EditableInput, EditablePreview, EditableSubmit, EmailInput, Fieldset, FilePicker, FileUpload, FormErrorMessage, FormField, FormHelperText, InputAddon, InputGroup, Label, LabeledInput, Legend, Listbox, ListboxEmpty, ListboxGroup, ListboxItem, ListboxSeparator, MaskedInput, MultiSelect, MultiSelectContent, MultiSelectItem, MultiSelectTags, MultiSelectTrigger, NumberInput, PasswordInput, PasswordStrength, PercentInput, PinInput, Radio, RadioField, RadioGroup, RangeCalendar, SearchInput, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Slider, Stepper, StepperList, StepperPanel, StepperStep, Switch, SwitchField, TagsInput, TelInput, TextInput, Textarea, TimeField, TimePicker, UrlInput, Wizard, WizardFooter, WizardStep, WizardSteps, colorSwatchVariants, useWizard };
|
|
4497
|
-
//# sourceMappingURL=chunk-
|
|
4498
|
-
//# sourceMappingURL=chunk-
|
|
5045
|
+
export { Calendar, CharacterCount, Checkbox, CheckboxField, CheckboxGroup, ChoiceCard, CodeEditor, ColorArea, ColorField, ColorPicker, ColorSlider, ColorSwatch, ColorSwatchPicker, ColorWheel, Combobox, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxSeparator, CurrencyInput, DateField, DatePicker, DateRangePicker, Editable, EditableCancel, EditableInput, EditablePreview, EditableSubmit, EmailInput, Fieldset, FilePicker, FileUpload, FormErrorMessage, FormField, FormHelperText, InputAddon, InputGroup, JSONEditor, Label, LabeledInput, Legend, Listbox, ListboxEmpty, ListboxGroup, ListboxItem, ListboxSeparator, MarkdownEditor, MaskedInput, MultiSelect, MultiSelectContent, MultiSelectItem, MultiSelectTags, MultiSelectTrigger, NumberInput, PasswordInput, PasswordStrength, PercentInput, PinInput, Radio, RadioField, RadioGroup, RangeCalendar, SearchInput, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Slider, Stepper, StepperList, StepperPanel, StepperStep, Switch, SwitchField, TagsInput, TelInput, TextInput, Textarea, TimeField, TimePicker, UrlInput, Wizard, WizardFooter, WizardStep, WizardSteps, colorSwatchVariants, useWizard };
|
|
5046
|
+
//# sourceMappingURL=chunk-WRPLV6H2.js.map
|
|
5047
|
+
//# sourceMappingURL=chunk-WRPLV6H2.js.map
|