@petrarca/sonnet-playground 0.2.0 → 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/dist/PlayAdvancedComponents-ZYK66UII.js +8 -0
- package/dist/PlayColorPalette-IWECRZUS.js +8 -0
- package/dist/PlayCoreComponents-F2OFSQZK.js +8 -0
- package/dist/PlayDataComponents-BA3NA225.js +8 -0
- package/dist/PlayFormComponents-MZC7CNES.js +8 -0
- package/dist/PlayFormWidgets-IWJJQ5XL.js +8 -0
- package/dist/PlayForms-FOF3XE6G.js +7 -0
- package/dist/PlayGraph-RHFIDAS3.js +7 -0
- package/dist/PlayJsonEditor-SYZYEJEA.js +7 -0
- package/dist/PlayShellApi-3T4FZPEV.js +8 -0
- package/dist/PlayShellApi-3T4FZPEV.js.map +1 -0
- package/dist/PlayTypography-T6SMPHUB.js +8 -0
- package/dist/PlayTypography-T6SMPHUB.js.map +1 -0
- package/dist/chunk-4S2ITDB3.js +322 -0
- package/dist/chunk-4S2ITDB3.js.map +1 -0
- package/dist/chunk-4Y4JFKAK.js +240 -0
- package/dist/chunk-4Y4JFKAK.js.map +1 -0
- package/dist/{chunk-QIETZUEN.js → chunk-6DZ3TSV4.js} +66 -71
- package/dist/chunk-6DZ3TSV4.js.map +1 -0
- package/dist/{chunk-CYNK2P2Q.js → chunk-7IBZEHLI.js} +14 -13
- package/dist/chunk-7IBZEHLI.js.map +1 -0
- package/dist/chunk-C2EZ2ECG.js +40 -0
- package/dist/chunk-C2EZ2ECG.js.map +1 -0
- package/dist/{chunk-A3IK3CVW.js → chunk-DA3BIB5N.js} +24 -25
- package/dist/{chunk-A3IK3CVW.js.map → chunk-DA3BIB5N.js.map} +1 -1
- package/dist/{chunk-TZGJH7YS.js → chunk-DKLALDHR.js} +325 -331
- package/dist/chunk-DKLALDHR.js.map +1 -0
- package/dist/chunk-DZB6WFHA.js +401 -0
- package/dist/chunk-DZB6WFHA.js.map +1 -0
- package/dist/{chunk-KAT24CQQ.js → chunk-FZ3ZC7VM.js} +8 -6
- package/dist/chunk-FZ3ZC7VM.js.map +1 -0
- package/dist/chunk-MT4ILA37.js +563 -0
- package/dist/chunk-MT4ILA37.js.map +1 -0
- package/dist/chunk-QCK2M4KD.js +907 -0
- package/dist/chunk-QCK2M4KD.js.map +1 -0
- package/dist/{chunk-PGI54O43.js → chunk-SBKZRIJC.js} +39 -44
- package/dist/chunk-SBKZRIJC.js.map +1 -0
- package/dist/index.d.ts +10 -6
- package/dist/index.js +41 -17
- package/dist/index.js.map +1 -1
- package/dist/pages/index.d.ts +15 -11
- package/dist/pages/index.js +20 -12
- package/package.json +6 -6
- package/dist/PlayColorPalette-UFMTJTUB.js +0 -8
- package/dist/PlayCoreComponents-7QCDFQLT.js +0 -7
- package/dist/PlayDataComponents-GZSRTW4F.js +0 -7
- package/dist/PlayFormComponents-RJB6WZHD.js +0 -7
- package/dist/PlayFormWidgets-OFV7TJKH.js +0 -7
- package/dist/PlayForms-24XX5DC6.js +0 -7
- package/dist/PlayGraph-FLGLSUWV.js +0 -8
- package/dist/PlayJsonEditor-4L5INQPU.js +0 -7
- package/dist/PlayTypography-ID6DLFZD.js +0 -8
- package/dist/chunk-5V27QDAY.js +0 -617
- package/dist/chunk-5V27QDAY.js.map +0 -1
- package/dist/chunk-CYNK2P2Q.js.map +0 -1
- package/dist/chunk-FTN2A5YL.js +0 -20
- package/dist/chunk-FTN2A5YL.js.map +0 -1
- package/dist/chunk-GYKEPHHA.js +0 -1154
- package/dist/chunk-GYKEPHHA.js.map +0 -1
- package/dist/chunk-KAT24CQQ.js.map +0 -1
- package/dist/chunk-P7I5IDXA.js +0 -432
- package/dist/chunk-P7I5IDXA.js.map +0 -1
- package/dist/chunk-PGI54O43.js.map +0 -1
- package/dist/chunk-QIETZUEN.js.map +0 -1
- package/dist/chunk-TZGJH7YS.js.map +0 -1
- /package/dist/{PlayColorPalette-UFMTJTUB.js.map → PlayAdvancedComponents-ZYK66UII.js.map} +0 -0
- /package/dist/{PlayCoreComponents-7QCDFQLT.js.map → PlayColorPalette-IWECRZUS.js.map} +0 -0
- /package/dist/{PlayDataComponents-GZSRTW4F.js.map → PlayCoreComponents-F2OFSQZK.js.map} +0 -0
- /package/dist/{PlayFormComponents-RJB6WZHD.js.map → PlayDataComponents-BA3NA225.js.map} +0 -0
- /package/dist/{PlayFormWidgets-OFV7TJKH.js.map → PlayFormComponents-MZC7CNES.js.map} +0 -0
- /package/dist/{PlayForms-24XX5DC6.js.map → PlayFormWidgets-IWJJQ5XL.js.map} +0 -0
- /package/dist/{PlayGraph-FLGLSUWV.js.map → PlayForms-FOF3XE6G.js.map} +0 -0
- /package/dist/{PlayJsonEditor-4L5INQPU.js.map → PlayGraph-RHFIDAS3.js.map} +0 -0
- /package/dist/{PlayTypography-ID6DLFZD.js.map → PlayJsonEditor-SYZYEJEA.js.map} +0 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PlaygroundSection
|
|
3
|
+
} from "./chunk-C2EZ2ECG.js";
|
|
4
|
+
|
|
5
|
+
// src/pages/PlayAdvancedComponents.tsx
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
import {
|
|
8
|
+
TreeView,
|
|
9
|
+
Button,
|
|
10
|
+
Separator,
|
|
11
|
+
Stepper,
|
|
12
|
+
StepperContent,
|
|
13
|
+
StepperDescription,
|
|
14
|
+
StepperIndicator,
|
|
15
|
+
StepperItem,
|
|
16
|
+
StepperList,
|
|
17
|
+
StepperNext,
|
|
18
|
+
StepperPrev,
|
|
19
|
+
StepperSeparator,
|
|
20
|
+
StepperTitle,
|
|
21
|
+
StepperTrigger
|
|
22
|
+
} from "@petrarca/sonnet-ui";
|
|
23
|
+
import { useTreeExpansion } from "@petrarca/sonnet-core/hooks";
|
|
24
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
25
|
+
function PlayAdvancedComponents() {
|
|
26
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
27
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
28
|
+
/* @__PURE__ */ jsx("h1", { children: "Advanced Components" }),
|
|
29
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Multi-step workflows and hierarchical data structures." })
|
|
30
|
+
] }),
|
|
31
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
32
|
+
/* @__PURE__ */ jsx(
|
|
33
|
+
PlaygroundSection,
|
|
34
|
+
{
|
|
35
|
+
title: "Stepper",
|
|
36
|
+
description: "Dice UI Stepper \u2014 horizontal, controlled via built-in Prev/Next or external state.",
|
|
37
|
+
variant: "card",
|
|
38
|
+
children: /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
39
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
40
|
+
/* @__PURE__ */ jsx("h4", { className: "mb-4", children: "Interactive (built-in navigation)" }),
|
|
41
|
+
/* @__PURE__ */ jsxs(Stepper, { defaultValue: "step-1", className: "max-w-lg", children: [
|
|
42
|
+
/* @__PURE__ */ jsx(StepperList, { className: "gap-2", children: ["step-1", "step-2", "step-3"].map((value, i) => /* @__PURE__ */ jsxs(StepperItem, { value, children: [
|
|
43
|
+
/* @__PURE__ */ jsxs(StepperTrigger, { children: [
|
|
44
|
+
/* @__PURE__ */ jsx(StepperIndicator, {}),
|
|
45
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-16", children: [
|
|
46
|
+
/* @__PURE__ */ jsxs(StepperTitle, { children: [
|
|
47
|
+
"Step ",
|
|
48
|
+
i + 1
|
|
49
|
+
] }),
|
|
50
|
+
/* @__PURE__ */ jsx(StepperDescription, { children: "Description" })
|
|
51
|
+
] })
|
|
52
|
+
] }),
|
|
53
|
+
/* @__PURE__ */ jsx(StepperSeparator, {})
|
|
54
|
+
] }, value)) }),
|
|
55
|
+
/* @__PURE__ */ jsx(StepperContent, { value: "step-1", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Content for step 1." }) }),
|
|
56
|
+
/* @__PURE__ */ jsx(StepperContent, { value: "step-2", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Content for step 2." }) }),
|
|
57
|
+
/* @__PURE__ */ jsx(StepperContent, { value: "step-3", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Content for step 3." }) }),
|
|
58
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between max-w-lg", children: [
|
|
59
|
+
/* @__PURE__ */ jsx(StepperPrev, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", children: "Back" }) }),
|
|
60
|
+
/* @__PURE__ */ jsx(StepperNext, { asChild: true, children: /* @__PURE__ */ jsx(Button, { size: "sm", children: "Next" }) })
|
|
61
|
+
] })
|
|
62
|
+
] })
|
|
63
|
+
] }),
|
|
64
|
+
/* @__PURE__ */ jsx(Separator, {}),
|
|
65
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
66
|
+
/* @__PURE__ */ jsx("h4", { className: "mb-4", children: "Non-interactive (controlled)" }),
|
|
67
|
+
/* @__PURE__ */ jsx(StepperControlled, {})
|
|
68
|
+
] })
|
|
69
|
+
] })
|
|
70
|
+
}
|
|
71
|
+
),
|
|
72
|
+
/* @__PURE__ */ jsx(
|
|
73
|
+
PlaygroundSection,
|
|
74
|
+
{
|
|
75
|
+
title: "TreeView",
|
|
76
|
+
description: "Generic accessible tree component with expand/collapse, keyboard navigation (ArrowUp/Down/Left/Right, Enter/Space), and optional row selection.",
|
|
77
|
+
variant: "card",
|
|
78
|
+
children: /* @__PURE__ */ jsx(TreeViewDemo, {})
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
] })
|
|
82
|
+
] });
|
|
83
|
+
}
|
|
84
|
+
var CONTROLLED_STEPS = [
|
|
85
|
+
{ value: "account", title: "Account", description: "Your details" },
|
|
86
|
+
{ value: "profile", title: "Profile", description: "About you" },
|
|
87
|
+
{ value: "review", title: "Review", description: "Confirm" }
|
|
88
|
+
];
|
|
89
|
+
function StepperControlled() {
|
|
90
|
+
const [step, setStep] = useState("account");
|
|
91
|
+
return /* @__PURE__ */ jsxs(
|
|
92
|
+
Stepper,
|
|
93
|
+
{
|
|
94
|
+
value: step,
|
|
95
|
+
onValueChange: setStep,
|
|
96
|
+
nonInteractive: true,
|
|
97
|
+
className: "max-w-lg",
|
|
98
|
+
children: [
|
|
99
|
+
/* @__PURE__ */ jsx(StepperList, { className: "gap-2", children: CONTROLLED_STEPS.map((s) => /* @__PURE__ */ jsxs(StepperItem, { value: s.value, children: [
|
|
100
|
+
/* @__PURE__ */ jsxs(StepperTrigger, { children: [
|
|
101
|
+
/* @__PURE__ */ jsx(StepperIndicator, {}),
|
|
102
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-16", children: [
|
|
103
|
+
/* @__PURE__ */ jsx(StepperTitle, { children: s.title }),
|
|
104
|
+
/* @__PURE__ */ jsx(StepperDescription, { children: s.description })
|
|
105
|
+
] })
|
|
106
|
+
] }),
|
|
107
|
+
/* @__PURE__ */ jsx(StepperSeparator, {})
|
|
108
|
+
] }, s.value)) }),
|
|
109
|
+
CONTROLLED_STEPS.map((s) => /* @__PURE__ */ jsx(StepperContent, { value: s.value, children: /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
110
|
+
"Content for ",
|
|
111
|
+
s.title,
|
|
112
|
+
"."
|
|
113
|
+
] }) }, s.value)),
|
|
114
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between max-w-lg", children: [
|
|
115
|
+
/* @__PURE__ */ jsx(
|
|
116
|
+
Button,
|
|
117
|
+
{
|
|
118
|
+
variant: "outline",
|
|
119
|
+
size: "sm",
|
|
120
|
+
disabled: step === CONTROLLED_STEPS[0].value,
|
|
121
|
+
onClick: () => {
|
|
122
|
+
const i = CONTROLLED_STEPS.findIndex((s) => s.value === step);
|
|
123
|
+
if (i > 0) setStep(CONTROLLED_STEPS[i - 1].value);
|
|
124
|
+
},
|
|
125
|
+
children: "Back"
|
|
126
|
+
}
|
|
127
|
+
),
|
|
128
|
+
/* @__PURE__ */ jsx(
|
|
129
|
+
Button,
|
|
130
|
+
{
|
|
131
|
+
size: "sm",
|
|
132
|
+
disabled: step === CONTROLLED_STEPS[CONTROLLED_STEPS.length - 1].value,
|
|
133
|
+
onClick: () => {
|
|
134
|
+
const i = CONTROLLED_STEPS.findIndex((s) => s.value === step);
|
|
135
|
+
if (i < CONTROLLED_STEPS.length - 1)
|
|
136
|
+
setStep(CONTROLLED_STEPS[i + 1].value);
|
|
137
|
+
},
|
|
138
|
+
children: "Next"
|
|
139
|
+
}
|
|
140
|
+
)
|
|
141
|
+
] })
|
|
142
|
+
]
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
var TREE_NODES = [
|
|
147
|
+
{
|
|
148
|
+
id: "fruits",
|
|
149
|
+
data: { label: "Fruits" },
|
|
150
|
+
hasChildren: true,
|
|
151
|
+
children: [
|
|
152
|
+
{
|
|
153
|
+
id: "citrus",
|
|
154
|
+
data: { label: "Citrus" },
|
|
155
|
+
hasChildren: true,
|
|
156
|
+
children: [
|
|
157
|
+
{ id: "lemon", data: { label: "Lemon" }, hasChildren: false },
|
|
158
|
+
{ id: "orange", data: { label: "Orange" }, hasChildren: false }
|
|
159
|
+
]
|
|
160
|
+
},
|
|
161
|
+
{ id: "apple", data: { label: "Apple" }, hasChildren: false },
|
|
162
|
+
{ id: "banana", data: { label: "Banana" }, hasChildren: false }
|
|
163
|
+
]
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
id: "vegetables",
|
|
167
|
+
data: { label: "Vegetables" },
|
|
168
|
+
hasChildren: true,
|
|
169
|
+
children: [
|
|
170
|
+
{ id: "carrot", data: { label: "Carrot" }, hasChildren: false },
|
|
171
|
+
{ id: "broccoli", data: { label: "Broccoli" }, hasChildren: false }
|
|
172
|
+
]
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
id: "grains",
|
|
176
|
+
data: { label: "Grains" },
|
|
177
|
+
hasChildren: false
|
|
178
|
+
}
|
|
179
|
+
];
|
|
180
|
+
function TreeViewDemo() {
|
|
181
|
+
const { expandedIds, onExpand, onCollapse } = useTreeExpansion();
|
|
182
|
+
const [selectedIds, setSelectedIds] = useState(/* @__PURE__ */ new Set());
|
|
183
|
+
const [lastClicked, setLastClicked] = useState(null);
|
|
184
|
+
const handleSelectionChange = (id, selected) => setSelectedIds((prev) => {
|
|
185
|
+
const next = new Set(prev);
|
|
186
|
+
if (selected) next.add(id);
|
|
187
|
+
else next.delete(id);
|
|
188
|
+
return next;
|
|
189
|
+
});
|
|
190
|
+
return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-8", children: [
|
|
191
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
192
|
+
/* @__PURE__ */ jsx("h4", { className: "mb-3", children: "Default (click to activate)" }),
|
|
193
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-3", children: "Keyboard: ArrowUp/Down to move, ArrowRight to expand, ArrowLeft to collapse or go to parent, Enter/Space to activate." }),
|
|
194
|
+
/* @__PURE__ */ jsx(
|
|
195
|
+
TreeView,
|
|
196
|
+
{
|
|
197
|
+
nodes: TREE_NODES,
|
|
198
|
+
expandedIds,
|
|
199
|
+
onExpand,
|
|
200
|
+
onCollapse,
|
|
201
|
+
onNodeClick: (node) => setLastClicked(node.id),
|
|
202
|
+
onNodeActivate: (node) => setLastClicked(node.id),
|
|
203
|
+
renderNode: (node) => /* @__PURE__ */ jsx("span", { className: "text-sm", children: node.data.label }),
|
|
204
|
+
className: "max-w-xs"
|
|
205
|
+
}
|
|
206
|
+
),
|
|
207
|
+
lastClicked && /* @__PURE__ */ jsxs("p", { className: "mt-3 text-xs text-muted-foreground", children: [
|
|
208
|
+
"Last activated: ",
|
|
209
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono", children: lastClicked })
|
|
210
|
+
] })
|
|
211
|
+
] }),
|
|
212
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
213
|
+
/* @__PURE__ */ jsx("h4", { className: "mb-3", children: "With row selection" }),
|
|
214
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-3", children: "Checkboxes appear when onSelectionChange is provided. State is independent of expand/collapse." }),
|
|
215
|
+
/* @__PURE__ */ jsx(
|
|
216
|
+
TreeView,
|
|
217
|
+
{
|
|
218
|
+
nodes: TREE_NODES,
|
|
219
|
+
expandedIds,
|
|
220
|
+
onExpand,
|
|
221
|
+
onCollapse,
|
|
222
|
+
selectedIds,
|
|
223
|
+
onSelectionChange: handleSelectionChange,
|
|
224
|
+
renderNode: (node) => /* @__PURE__ */ jsx("span", { className: "text-sm", children: node.data.label }),
|
|
225
|
+
className: "max-w-xs"
|
|
226
|
+
}
|
|
227
|
+
),
|
|
228
|
+
selectedIds.size > 0 && /* @__PURE__ */ jsxs("p", { className: "mt-3 text-xs text-muted-foreground", children: [
|
|
229
|
+
"Selected:",
|
|
230
|
+
" ",
|
|
231
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono", children: [...selectedIds].join(", ") })
|
|
232
|
+
] })
|
|
233
|
+
] })
|
|
234
|
+
] });
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export {
|
|
238
|
+
PlayAdvancedComponents
|
|
239
|
+
};
|
|
240
|
+
//# sourceMappingURL=chunk-4Y4JFKAK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pages/PlayAdvancedComponents.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport {\n TreeView,\n type TreeNode,\n Button,\n Separator,\n Stepper,\n StepperContent,\n StepperDescription,\n StepperIndicator,\n StepperItem,\n StepperList,\n StepperNext,\n StepperPrev,\n StepperSeparator,\n StepperTitle,\n StepperTrigger,\n} from \"@petrarca/sonnet-ui\";\nimport { useTreeExpansion } from \"@petrarca/sonnet-core/hooks\";\nimport { PlaygroundSection } from \"../PlaygroundSection\";\n\n/**\n * PlayAdvancedComponents — Stepper and TreeView demos.\n *\n * Split from PlayCoreComponents to keep files manageable.\n */\nexport default function PlayAdvancedComponents() {\n return (\n <div className=\"space-y-6\">\n <div>\n <h1>Advanced Components</h1>\n <p className=\"text-sm text-muted-foreground mt-1\">\n Multi-step workflows and hierarchical data structures.\n </p>\n </div>\n\n <div className=\"space-y-6\">\n {/* Stepper */}\n <PlaygroundSection\n title=\"Stepper\"\n description=\"Dice UI Stepper — horizontal, controlled via built-in Prev/Next or external state.\"\n variant=\"card\"\n >\n <div className=\"space-y-6\">\n {/* Interactive — uses built-in StepperPrev / StepperNext */}\n <div>\n <h4 className=\"mb-4\">Interactive (built-in navigation)</h4>\n <Stepper defaultValue=\"step-1\" className=\"max-w-lg\">\n <StepperList className=\"gap-2\">\n {[\"step-1\", \"step-2\", \"step-3\"].map((value, i) => (\n <StepperItem key={value} value={value}>\n <StepperTrigger>\n <StepperIndicator />\n <div className=\"flex flex-col min-w-16\">\n <StepperTitle>Step {i + 1}</StepperTitle>\n <StepperDescription>Description</StepperDescription>\n </div>\n </StepperTrigger>\n <StepperSeparator />\n </StepperItem>\n ))}\n </StepperList>\n <StepperContent value=\"step-1\">\n <p className=\"text-sm text-muted-foreground\">\n Content for step 1.\n </p>\n </StepperContent>\n <StepperContent value=\"step-2\">\n <p className=\"text-sm text-muted-foreground\">\n Content for step 2.\n </p>\n </StepperContent>\n <StepperContent value=\"step-3\">\n <p className=\"text-sm text-muted-foreground\">\n Content for step 3.\n </p>\n </StepperContent>\n <div className=\"flex justify-between max-w-lg\">\n <StepperPrev asChild>\n <Button variant=\"outline\" size=\"sm\">\n Back\n </Button>\n </StepperPrev>\n <StepperNext asChild>\n <Button size=\"sm\">Next</Button>\n </StepperNext>\n </div>\n </Stepper>\n </div>\n\n <Separator />\n\n {/* Non-interactive — controlled externally */}\n <div>\n <h4 className=\"mb-4\">Non-interactive (controlled)</h4>\n <StepperControlled />\n </div>\n </div>\n </PlaygroundSection>\n\n {/* TreeView */}\n <PlaygroundSection\n title=\"TreeView\"\n description=\"Generic accessible tree component with expand/collapse, keyboard navigation (ArrowUp/Down/Left/Right, Enter/Space), and optional row selection.\"\n variant=\"card\"\n >\n <TreeViewDemo />\n </PlaygroundSection>\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Stepper — controlled demo\n// ---------------------------------------------------------------------------\n\nconst CONTROLLED_STEPS = [\n { value: \"account\", title: \"Account\", description: \"Your details\" },\n { value: \"profile\", title: \"Profile\", description: \"About you\" },\n { value: \"review\", title: \"Review\", description: \"Confirm\" },\n];\n\nfunction StepperControlled() {\n const [step, setStep] = useState(\"account\");\n return (\n <Stepper\n value={step}\n onValueChange={setStep}\n nonInteractive\n className=\"max-w-lg\"\n >\n <StepperList className=\"gap-2\">\n {CONTROLLED_STEPS.map((s) => (\n <StepperItem key={s.value} value={s.value}>\n <StepperTrigger>\n <StepperIndicator />\n <div className=\"flex flex-col min-w-16\">\n <StepperTitle>{s.title}</StepperTitle>\n <StepperDescription>{s.description}</StepperDescription>\n </div>\n </StepperTrigger>\n <StepperSeparator />\n </StepperItem>\n ))}\n </StepperList>\n {CONTROLLED_STEPS.map((s) => (\n <StepperContent key={s.value} value={s.value}>\n <p className=\"text-sm text-muted-foreground\">\n Content for {s.title}.\n </p>\n </StepperContent>\n ))}\n <div className=\"flex justify-between max-w-lg\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={step === CONTROLLED_STEPS[0].value}\n onClick={() => {\n const i = CONTROLLED_STEPS.findIndex((s) => s.value === step);\n if (i > 0) setStep(CONTROLLED_STEPS[i - 1].value);\n }}\n >\n Back\n </Button>\n <Button\n size=\"sm\"\n disabled={\n step === CONTROLLED_STEPS[CONTROLLED_STEPS.length - 1].value\n }\n onClick={() => {\n const i = CONTROLLED_STEPS.findIndex((s) => s.value === step);\n if (i < CONTROLLED_STEPS.length - 1)\n setStep(CONTROLLED_STEPS[i + 1].value);\n }}\n >\n Next\n </Button>\n </div>\n </Stepper>\n );\n}\n\n// ---------------------------------------------------------------------------\n// TreeView demo\n// ---------------------------------------------------------------------------\n\ninterface DemoData extends Record<string, unknown> {\n label: string;\n}\n\nconst TREE_NODES: TreeNode<DemoData>[] = [\n {\n id: \"fruits\",\n data: { label: \"Fruits\" },\n hasChildren: true,\n children: [\n {\n id: \"citrus\",\n data: { label: \"Citrus\" },\n hasChildren: true,\n children: [\n { id: \"lemon\", data: { label: \"Lemon\" }, hasChildren: false },\n { id: \"orange\", data: { label: \"Orange\" }, hasChildren: false },\n ],\n },\n { id: \"apple\", data: { label: \"Apple\" }, hasChildren: false },\n { id: \"banana\", data: { label: \"Banana\" }, hasChildren: false },\n ],\n },\n {\n id: \"vegetables\",\n data: { label: \"Vegetables\" },\n hasChildren: true,\n children: [\n { id: \"carrot\", data: { label: \"Carrot\" }, hasChildren: false },\n { id: \"broccoli\", data: { label: \"Broccoli\" }, hasChildren: false },\n ],\n },\n {\n id: \"grains\",\n data: { label: \"Grains\" },\n hasChildren: false,\n },\n];\n\nfunction TreeViewDemo() {\n const { expandedIds, onExpand, onCollapse } = useTreeExpansion();\n const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());\n const [lastClicked, setLastClicked] = useState<string | null>(null);\n\n const handleSelectionChange = (id: string, selected: boolean) =>\n setSelectedIds((prev) => {\n const next = new Set(prev);\n if (selected) next.add(id);\n else next.delete(id);\n return next;\n });\n\n return (\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-8\">\n {/* Without selection */}\n <div>\n <h4 className=\"mb-3\">Default (click to activate)</h4>\n <p className=\"text-sm text-muted-foreground mb-3\">\n Keyboard: ArrowUp/Down to move, ArrowRight to expand, ArrowLeft to\n collapse or go to parent, Enter/Space to activate.\n </p>\n <TreeView<DemoData>\n nodes={TREE_NODES}\n expandedIds={expandedIds}\n onExpand={onExpand}\n onCollapse={onCollapse}\n onNodeClick={(node) => setLastClicked(node.id)}\n onNodeActivate={(node) => setLastClicked(node.id)}\n renderNode={(node) => (\n <span className=\"text-sm\">{node.data.label}</span>\n )}\n className=\"max-w-xs\"\n />\n {lastClicked && (\n <p className=\"mt-3 text-xs text-muted-foreground\">\n Last activated: <span className=\"font-mono\">{lastClicked}</span>\n </p>\n )}\n </div>\n\n {/* With row selection */}\n <div>\n <h4 className=\"mb-3\">With row selection</h4>\n <p className=\"text-sm text-muted-foreground mb-3\">\n Checkboxes appear when onSelectionChange is provided. State is\n independent of expand/collapse.\n </p>\n <TreeView<DemoData>\n nodes={TREE_NODES}\n expandedIds={expandedIds}\n onExpand={onExpand}\n onCollapse={onCollapse}\n selectedIds={selectedIds}\n onSelectionChange={handleSelectionChange}\n renderNode={(node) => (\n <span className=\"text-sm\">{node.data.label}</span>\n )}\n className=\"max-w-xs\"\n />\n {selectedIds.size > 0 && (\n <p className=\"mt-3 text-xs text-muted-foreground\">\n Selected:{\" \"}\n <span className=\"font-mono\">{[...selectedIds].join(\", \")}</span>\n </p>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;AAAA,SAAS,gBAAgB;AACzB;AAAA,EACE;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,wBAAwB;AAW3B,SACE,KADF;AAHS,SAAR,yBAA0C;AAC/C,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,yBAAC,SACC;AAAA,0BAAC,QAAG,iCAAmB;AAAA,MACvB,oBAAC,OAAE,WAAU,sCAAqC,oEAElD;AAAA,OACF;AAAA,IAEA,qBAAC,SAAI,WAAU,aAEb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAM;AAAA,UACN,aAAY;AAAA,UACZ,SAAQ;AAAA,UAER,+BAAC,SAAI,WAAU,aAEb;AAAA,iCAAC,SACC;AAAA,kCAAC,QAAG,WAAU,QAAO,+CAAiC;AAAA,cACtD,qBAAC,WAAQ,cAAa,UAAS,WAAU,YACvC;AAAA,oCAAC,eAAY,WAAU,SACpB,WAAC,UAAU,UAAU,QAAQ,EAAE,IAAI,CAAC,OAAO,MAC1C,qBAAC,eAAwB,OACvB;AAAA,uCAAC,kBACC;AAAA,wCAAC,oBAAiB;AAAA,oBAClB,qBAAC,SAAI,WAAU,0BACb;AAAA,2CAAC,gBAAa;AAAA;AAAA,wBAAM,IAAI;AAAA,yBAAE;AAAA,sBAC1B,oBAAC,sBAAmB,yBAAW;AAAA,uBACjC;AAAA,qBACF;AAAA,kBACA,oBAAC,oBAAiB;AAAA,qBARF,KASlB,CACD,GACH;AAAA,gBACA,oBAAC,kBAAe,OAAM,UACpB,8BAAC,OAAE,WAAU,iCAAgC,iCAE7C,GACF;AAAA,gBACA,oBAAC,kBAAe,OAAM,UACpB,8BAAC,OAAE,WAAU,iCAAgC,iCAE7C,GACF;AAAA,gBACA,oBAAC,kBAAe,OAAM,UACpB,8BAAC,OAAE,WAAU,iCAAgC,iCAE7C,GACF;AAAA,gBACA,qBAAC,SAAI,WAAU,iCACb;AAAA,sCAAC,eAAY,SAAO,MAClB,8BAAC,UAAO,SAAQ,WAAU,MAAK,MAAK,kBAEpC,GACF;AAAA,kBACA,oBAAC,eAAY,SAAO,MAClB,8BAAC,UAAO,MAAK,MAAK,kBAAI,GACxB;AAAA,mBACF;AAAA,iBACF;AAAA,eACF;AAAA,YAEA,oBAAC,aAAU;AAAA,YAGX,qBAAC,SACC;AAAA,kCAAC,QAAG,WAAU,QAAO,0CAA4B;AAAA,cACjD,oBAAC,qBAAkB;AAAA,eACrB;AAAA,aACF;AAAA;AAAA,MACF;AAAA,MAGA;AAAA,QAAC;AAAA;AAAA,UACC,OAAM;AAAA,UACN,aAAY;AAAA,UACZ,SAAQ;AAAA,UAER,8BAAC,gBAAa;AAAA;AAAA,MAChB;AAAA,OACF;AAAA,KACF;AAEJ;AAMA,IAAM,mBAAmB;AAAA,EACvB,EAAE,OAAO,WAAW,OAAO,WAAW,aAAa,eAAe;AAAA,EAClE,EAAE,OAAO,WAAW,OAAO,WAAW,aAAa,YAAY;AAAA,EAC/D,EAAE,OAAO,UAAU,OAAO,UAAU,aAAa,UAAU;AAC7D;AAEA,SAAS,oBAAoB;AAC3B,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,SAAS;AAC1C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,MACP,eAAe;AAAA,MACf,gBAAc;AAAA,MACd,WAAU;AAAA,MAEV;AAAA,4BAAC,eAAY,WAAU,SACpB,2BAAiB,IAAI,CAAC,MACrB,qBAAC,eAA0B,OAAO,EAAE,OAClC;AAAA,+BAAC,kBACC;AAAA,gCAAC,oBAAiB;AAAA,YAClB,qBAAC,SAAI,WAAU,0BACb;AAAA,kCAAC,gBAAc,YAAE,OAAM;AAAA,cACvB,oBAAC,sBAAoB,YAAE,aAAY;AAAA,eACrC;AAAA,aACF;AAAA,UACA,oBAAC,oBAAiB;AAAA,aARF,EAAE,KASpB,CACD,GACH;AAAA,QACC,iBAAiB,IAAI,CAAC,MACrB,oBAAC,kBAA6B,OAAO,EAAE,OACrC,+BAAC,OAAE,WAAU,iCAAgC;AAAA;AAAA,UAC9B,EAAE;AAAA,UAAM;AAAA,WACvB,KAHmB,EAAE,KAIvB,CACD;AAAA,QACD,qBAAC,SAAI,WAAU,iCACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,UAAU,SAAS,iBAAiB,CAAC,EAAE;AAAA,cACvC,SAAS,MAAM;AACb,sBAAM,IAAI,iBAAiB,UAAU,CAAC,MAAM,EAAE,UAAU,IAAI;AAC5D,oBAAI,IAAI,EAAG,SAAQ,iBAAiB,IAAI,CAAC,EAAE,KAAK;AAAA,cAClD;AAAA,cACD;AAAA;AAAA,UAED;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,UACE,SAAS,iBAAiB,iBAAiB,SAAS,CAAC,EAAE;AAAA,cAEzD,SAAS,MAAM;AACb,sBAAM,IAAI,iBAAiB,UAAU,CAAC,MAAM,EAAE,UAAU,IAAI;AAC5D,oBAAI,IAAI,iBAAiB,SAAS;AAChC,0BAAQ,iBAAiB,IAAI,CAAC,EAAE,KAAK;AAAA,cACzC;AAAA,cACD;AAAA;AAAA,UAED;AAAA,WACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAUA,IAAM,aAAmC;AAAA,EACvC;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,EAAE,OAAO,SAAS;AAAA,IACxB,aAAa;AAAA,IACb,UAAU;AAAA,MACR;AAAA,QACE,IAAI;AAAA,QACJ,MAAM,EAAE,OAAO,SAAS;AAAA,QACxB,aAAa;AAAA,QACb,UAAU;AAAA,UACR,EAAE,IAAI,SAAS,MAAM,EAAE,OAAO,QAAQ,GAAG,aAAa,MAAM;AAAA,UAC5D,EAAE,IAAI,UAAU,MAAM,EAAE,OAAO,SAAS,GAAG,aAAa,MAAM;AAAA,QAChE;AAAA,MACF;AAAA,MACA,EAAE,IAAI,SAAS,MAAM,EAAE,OAAO,QAAQ,GAAG,aAAa,MAAM;AAAA,MAC5D,EAAE,IAAI,UAAU,MAAM,EAAE,OAAO,SAAS,GAAG,aAAa,MAAM;AAAA,IAChE;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,EAAE,OAAO,aAAa;AAAA,IAC5B,aAAa;AAAA,IACb,UAAU;AAAA,MACR,EAAE,IAAI,UAAU,MAAM,EAAE,OAAO,SAAS,GAAG,aAAa,MAAM;AAAA,MAC9D,EAAE,IAAI,YAAY,MAAM,EAAE,OAAO,WAAW,GAAG,aAAa,MAAM;AAAA,IACpE;AAAA,EACF;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,EAAE,OAAO,SAAS;AAAA,IACxB,aAAa;AAAA,EACf;AACF;AAEA,SAAS,eAAe;AACtB,QAAM,EAAE,aAAa,UAAU,WAAW,IAAI,iBAAiB;AAC/D,QAAM,CAAC,aAAa,cAAc,IAAI,SAAsB,oBAAI,IAAI,CAAC;AACrE,QAAM,CAAC,aAAa,cAAc,IAAI,SAAwB,IAAI;AAElE,QAAM,wBAAwB,CAAC,IAAY,aACzC,eAAe,CAAC,SAAS;AACvB,UAAM,OAAO,IAAI,IAAI,IAAI;AACzB,QAAI,SAAU,MAAK,IAAI,EAAE;AAAA,QACpB,MAAK,OAAO,EAAE;AACnB,WAAO;AAAA,EACT,CAAC;AAEH,SACE,qBAAC,SAAI,WAAU,yCAEb;AAAA,yBAAC,SACC;AAAA,0BAAC,QAAG,WAAU,QAAO,yCAA2B;AAAA,MAChD,oBAAC,OAAE,WAAU,sCAAqC,mIAGlD;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,UACA,aAAa,CAAC,SAAS,eAAe,KAAK,EAAE;AAAA,UAC7C,gBAAgB,CAAC,SAAS,eAAe,KAAK,EAAE;AAAA,UAChD,YAAY,CAAC,SACX,oBAAC,UAAK,WAAU,WAAW,eAAK,KAAK,OAAM;AAAA,UAE7C,WAAU;AAAA;AAAA,MACZ;AAAA,MACC,eACC,qBAAC,OAAE,WAAU,sCAAqC;AAAA;AAAA,QAChC,oBAAC,UAAK,WAAU,aAAa,uBAAY;AAAA,SAC3D;AAAA,OAEJ;AAAA,IAGA,qBAAC,SACC;AAAA,0BAAC,QAAG,WAAU,QAAO,gCAAkB;AAAA,MACvC,oBAAC,OAAE,WAAU,sCAAqC,4GAGlD;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,mBAAmB;AAAA,UACnB,YAAY,CAAC,SACX,oBAAC,UAAK,WAAU,WAAW,eAAK,KAAK,OAAM;AAAA,UAE7C,WAAU;AAAA;AAAA,MACZ;AAAA,MACC,YAAY,OAAO,KAClB,qBAAC,OAAE,WAAU,sCAAqC;AAAA;AAAA,QACtC;AAAA,QACV,oBAAC,UAAK,WAAU,aAAa,WAAC,GAAG,WAAW,EAAE,KAAK,IAAI,GAAE;AAAA,SAC3D;AAAA,OAEJ;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -405,22 +405,19 @@ function usePlayFormsState() {
|
|
|
405
405
|
const [dataCollapsed, setDataCollapsed] = useState(false);
|
|
406
406
|
const [lastDiff, setLastDiff] = useState(null);
|
|
407
407
|
const toggleDataPanel = useCallback(() => setDataCollapsed((v) => !v), []);
|
|
408
|
-
const loadSchemaPreset = useCallback(
|
|
409
|
-
(value)
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
},
|
|
422
|
-
[setSchemaText, setActiveSchema]
|
|
423
|
-
);
|
|
408
|
+
const loadSchemaPreset = useCallback((value) => {
|
|
409
|
+
if (!value || !sampleSchemas[value]) return;
|
|
410
|
+
const text = JSON.stringify(sampleSchemas[value], null, 2);
|
|
411
|
+
setSchemaText(text);
|
|
412
|
+
setActiveSchema(sampleSchemas[value]);
|
|
413
|
+
setSchemaError("");
|
|
414
|
+
setFormData({});
|
|
415
|
+
setDataText("{}");
|
|
416
|
+
const pairedUi = value === "row_layout" ? ROW_LAYOUT_UISCHEMA : {};
|
|
417
|
+
setUiSchemaText(JSON.stringify(pairedUi, null, 2));
|
|
418
|
+
setActiveUiSchema(pairedUi);
|
|
419
|
+
setUiSchemaError("");
|
|
420
|
+
}, []);
|
|
424
421
|
const loadUiSchemaPreset = useCallback(
|
|
425
422
|
(value) => {
|
|
426
423
|
if (!value) return;
|
|
@@ -480,6 +477,28 @@ function tryParseAndLoad(text, onSuccess, onError) {
|
|
|
480
477
|
onError("Invalid JSON - cannot load to form");
|
|
481
478
|
}
|
|
482
479
|
}
|
|
480
|
+
function PanelArrowButton({
|
|
481
|
+
label,
|
|
482
|
+
onClick,
|
|
483
|
+
mirrored = false
|
|
484
|
+
}) {
|
|
485
|
+
return /* @__PURE__ */ jsx(SimpleTooltip, { label, children: /* @__PURE__ */ jsx(
|
|
486
|
+
Button,
|
|
487
|
+
{
|
|
488
|
+
variant: "default",
|
|
489
|
+
size: "icon",
|
|
490
|
+
className: "absolute -right-5 top-1/2 -translate-y-1/2 z-[100]",
|
|
491
|
+
onClick,
|
|
492
|
+
children: /* @__PURE__ */ jsx(
|
|
493
|
+
ArrowRight,
|
|
494
|
+
{
|
|
495
|
+
size: 20,
|
|
496
|
+
className: mirrored ? "scale-x-[-1]" : void 0
|
|
497
|
+
}
|
|
498
|
+
)
|
|
499
|
+
}
|
|
500
|
+
) });
|
|
501
|
+
}
|
|
483
502
|
function SchemaEditorColumn({
|
|
484
503
|
state
|
|
485
504
|
}) {
|
|
@@ -603,19 +622,10 @@ function SchemaEditorColumn({
|
|
|
603
622
|
}
|
|
604
623
|
) }),
|
|
605
624
|
/* @__PURE__ */ jsx(
|
|
606
|
-
|
|
625
|
+
PanelArrowButton,
|
|
607
626
|
{
|
|
608
627
|
label: state.activeTab === "schema" ? "Load Schema to Form" : "Load UI Schema to Form",
|
|
609
|
-
|
|
610
|
-
Button,
|
|
611
|
-
{
|
|
612
|
-
variant: "default",
|
|
613
|
-
size: "icon",
|
|
614
|
-
className: "absolute -right-5 top-1/2 -translate-y-1/2 z-[100]",
|
|
615
|
-
onClick: state.activeTab === "schema" ? handleLoadSchemaToForm : handleLoadUiSchemaToForm,
|
|
616
|
-
children: /* @__PURE__ */ jsx(ArrowRight, { size: 20 })
|
|
617
|
-
}
|
|
618
|
-
)
|
|
628
|
+
onClick: state.activeTab === "schema" ? handleLoadSchemaToForm : handleLoadUiSchemaToForm
|
|
619
629
|
}
|
|
620
630
|
)
|
|
621
631
|
]
|
|
@@ -708,7 +718,7 @@ function FormColumn({
|
|
|
708
718
|
}
|
|
709
719
|
)
|
|
710
720
|
] }),
|
|
711
|
-
state.validationErrors.length > 0 && /* @__PURE__ */ jsx("div", { style: { marginTop: "4px" }, children: state.validationErrors.map((err, idx) => /* @__PURE__ */ jsx("p", { className: "text-xs text-
|
|
721
|
+
state.validationErrors.length > 0 && /* @__PURE__ */ jsx("div", { style: { marginTop: "4px" }, children: state.validationErrors.map((err, idx) => /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: err }, idx)) })
|
|
712
722
|
] }),
|
|
713
723
|
/* @__PURE__ */ jsxs(
|
|
714
724
|
"div",
|
|
@@ -743,16 +753,14 @@ function FormColumn({
|
|
|
743
753
|
]
|
|
744
754
|
}
|
|
745
755
|
) }),
|
|
746
|
-
!state.dataCollapsed && /* @__PURE__ */ jsx(
|
|
747
|
-
|
|
756
|
+
!state.dataCollapsed && /* @__PURE__ */ jsx(
|
|
757
|
+
PanelArrowButton,
|
|
748
758
|
{
|
|
749
|
-
|
|
750
|
-
size: "icon",
|
|
751
|
-
className: "absolute -right-5 top-1/2 -translate-y-1/2 z-[100]",
|
|
759
|
+
label: "Load JSON Data into Form",
|
|
752
760
|
onClick: handleLoadDataToForm,
|
|
753
|
-
|
|
761
|
+
mirrored: true
|
|
754
762
|
}
|
|
755
|
-
)
|
|
763
|
+
)
|
|
756
764
|
]
|
|
757
765
|
}
|
|
758
766
|
);
|
|
@@ -842,44 +850,31 @@ function DataColumn({
|
|
|
842
850
|
}
|
|
843
851
|
function PlayForms() {
|
|
844
852
|
const state = usePlayFormsState();
|
|
845
|
-
return /* @__PURE__ */ jsxs(
|
|
846
|
-
"div",
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
{
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
display: "flex",
|
|
868
|
-
gap: "1.5rem"
|
|
869
|
-
},
|
|
870
|
-
children: [
|
|
871
|
-
/* @__PURE__ */ jsx(SchemaEditorColumn, { state }),
|
|
872
|
-
/* @__PURE__ */ jsx(FormColumn, { state }),
|
|
873
|
-
/* @__PURE__ */ jsx(DataColumn, { state })
|
|
874
|
-
]
|
|
875
|
-
}
|
|
876
|
-
)
|
|
877
|
-
]
|
|
878
|
-
}
|
|
879
|
-
);
|
|
853
|
+
return /* @__PURE__ */ jsxs("div", { className: "w-full flex flex-col gap-3 h-[calc(100vh-8rem)]", children: [
|
|
854
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
855
|
+
/* @__PURE__ */ jsx("h1", { children: "Forms Playground" }),
|
|
856
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-3", children: "Test and experiment with JsonSchemaFormRenderer. Edit the JSON Schema on the left, then load it into the form." })
|
|
857
|
+
] }),
|
|
858
|
+
/* @__PURE__ */ jsxs(
|
|
859
|
+
"div",
|
|
860
|
+
{
|
|
861
|
+
style: {
|
|
862
|
+
flex: 1,
|
|
863
|
+
minHeight: 0,
|
|
864
|
+
display: "flex",
|
|
865
|
+
gap: "1.5rem"
|
|
866
|
+
},
|
|
867
|
+
children: [
|
|
868
|
+
/* @__PURE__ */ jsx(SchemaEditorColumn, { state }),
|
|
869
|
+
/* @__PURE__ */ jsx(FormColumn, { state }),
|
|
870
|
+
/* @__PURE__ */ jsx(DataColumn, { state })
|
|
871
|
+
]
|
|
872
|
+
}
|
|
873
|
+
)
|
|
874
|
+
] });
|
|
880
875
|
}
|
|
881
876
|
|
|
882
877
|
export {
|
|
883
878
|
PlayForms
|
|
884
879
|
};
|
|
885
|
-
//# sourceMappingURL=chunk-
|
|
880
|
+
//# sourceMappingURL=chunk-6DZ3TSV4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pages/PlayForms.tsx"],"sourcesContent":["/**\n * Playground page for testing JsonSchemaFormRenderer\n * Accessible at /playground/forms\n */\n\nimport { useState, useCallback } from \"react\";\nimport type { FormDiff } from \"@petrarca/sonnet-core/schema\";\nimport {\n SimpleStack,\n SimpleGroup,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Card,\n Badge,\n SimpleTooltip,\n Button,\n} from \"@petrarca/sonnet-ui\";\nimport {\n FormSelect,\n FormCheckbox,\n JsonSchemaFormRenderer,\n type UISchema,\n} from \"@petrarca/sonnet-forms\";\nimport { JsonEditor } from \"@petrarca/sonnet-ui/json-editor\";\nimport {\n ArrowRight,\n ChevronLeft,\n ChevronRight as ChevronRightIcon,\n} from \"lucide-react\";\nimport type { JsonSchema } from \"@petrarca/sonnet-core/schema\";\n\n// Sample schemas\nconst SAMPLE_SCHEMA: JsonSchema = {\n title: \"Practitioner\",\n type: \"object\",\n properties: {\n name: { type: \"string\", title: \"Full Name\" },\n npi: { type: \"string\", title: \"NPI\" },\n specialty: {\n type: \"string\",\n title: \"Specialty\",\n enum: [\"cardiology\", \"neurology\", \"oncology\", \"radiology\", \"general\"],\n },\n notes: {\n type: \"string\",\n title: \"Notes\",\n \"x-ui-widget\": \"textarea\",\n },\n years_experience: {\n type: \"integer\",\n title: \"Years of Experience\",\n minimum: 0,\n maximum: 60,\n },\n active: { type: \"boolean\", title: \"Active\" },\n },\n required: [\"name\", \"npi\"],\n};\n\n// Nested object (1:1)\nconst NESTED_OBJECT_SCHEMA: JsonSchema = {\n title: \"Patient\",\n type: \"object\",\n properties: {\n family_name: { type: \"string\", title: \"Family Name\" },\n given_name: { type: \"string\", title: \"Given Name\" },\n birth_date: { type: \"string\", title: \"Date of Birth\", format: \"date\" },\n contact: {\n type: \"object\",\n title: \"Contact\",\n properties: {\n phone: { type: \"string\", title: \"Phone\" },\n email: { type: \"string\", title: \"Email\", format: \"email\" },\n address: { type: \"string\", title: \"Address\" },\n city: { type: \"string\", title: \"City\" },\n country: {\n type: \"string\",\n title: \"Country\",\n enum: [\"DE\", \"AT\", \"CH\", \"US\", \"GB\"],\n },\n },\n required: [\"phone\"],\n },\n },\n required: [\"family_name\", \"given_name\"],\n};\n\n// Array of objects (1:n)\nconst ARRAY_OF_OBJECTS_SCHEMA: JsonSchema = {\n title: \"Medication Request\",\n type: \"object\",\n properties: {\n patient_id: { type: \"string\", title: \"Patient ID\" },\n prescriber: { type: \"string\", title: \"Prescriber\" },\n medications: {\n type: \"array\",\n title: \"Medications\",\n \"x-ui-options\": {\n addLabel: \"Add Medication\",\n emptyMessage: \"No medications added\",\n orderable: true,\n },\n items: {\n type: \"object\",\n properties: {\n drug_name: { type: \"string\", title: \"Drug Name\" },\n dose: { type: \"string\", title: \"Dose\" },\n route: {\n type: \"string\",\n title: \"Route\",\n enum: [\"oral\", \"IV\", \"subcutaneous\", \"topical\", \"inhaled\"],\n },\n frequency: { type: \"string\", title: \"Frequency\" },\n active: { type: \"boolean\", title: \"Active\" },\n },\n required: [\"drug_name\", \"dose\"],\n },\n minItems: 1,\n maxItems: 10,\n },\n },\n required: [\"patient_id\", \"prescriber\"],\n};\n\n// $ref with $defs\nconst REF_SCHEMA: JsonSchema = {\n title: \"Care Plan\",\n type: \"object\",\n $defs: {\n period: {\n type: \"object\",\n properties: {\n start: { type: \"string\", title: \"Start Date\", format: \"date\" },\n end: { type: \"string\", title: \"End Date\", format: \"date\" },\n },\n required: [\"start\"],\n },\n },\n properties: {\n patient_id: { type: \"string\", title: \"Patient ID\" },\n title: { type: \"string\", title: \"Plan Title\" },\n validity: {\n $ref: \"#/$defs/period\",\n title: \"Validity Period\",\n },\n activities: {\n type: \"array\",\n title: \"Activities\",\n \"x-ui-options\": {\n addLabel: \"Add Activity\",\n orderable: true,\n },\n items: {\n type: \"object\",\n properties: {\n description: { type: \"string\", title: \"Description\" },\n schedule: {\n $ref: \"#/$defs/period\",\n title: \"Schedule\",\n },\n },\n required: [\"description\"],\n },\n maxItems: 5,\n },\n },\n required: [\"patient_id\", \"title\"],\n};\n\n// Horizontal array layout -- inline grid rows\nconst HORIZONTAL_ARRAY_SCHEMA: JsonSchema = {\n title: \"Observation Panel\",\n type: \"object\",\n properties: {\n subject: { type: \"string\", title: \"Subject ID\" },\n observations: {\n type: \"array\",\n title: \"Observations\",\n \"x-ui-layout\": {\n direction: \"horizontal\",\n columns: \"1fr 1fr 1fr 80px\",\n gap: 8,\n compact: true,\n },\n \"x-ui-options\": {\n addLabel: \"Add Observation\",\n emptyMessage: \"No observations recorded\",\n orderable: true,\n },\n items: {\n type: \"object\",\n properties: {\n code: {\n type: \"string\",\n title: \"LOINC Code\",\n enum: [\"8310-5\", \"8867-4\", \"9279-1\", \"29463-7\"],\n },\n value: { type: \"string\", title: \"Value\" },\n unit: {\n type: \"string\",\n title: \"Unit\",\n enum: [\"Cel\", \"/min\", \"kg\", \"mmHg\", \"%\"],\n },\n abnormal: { type: \"boolean\", title: \"Abnormal\" },\n },\n required: [\"code\", \"value\"],\n },\n minItems: 0,\n maxItems: 20,\n },\n },\n required: [\"subject\"],\n};\n\n// Horizontal array layout -- full-height rows, no compact sizing\nconst HORIZONTAL_FULL_SCHEMA: JsonSchema = {\n title: \"Allergy List\",\n type: \"object\",\n properties: {\n patient_id: { type: \"string\", title: \"Patient ID\" },\n allergies: {\n type: \"array\",\n title: \"Allergies\",\n \"x-ui-layout\": {\n direction: \"horizontal\",\n columns: \"2fr 1fr 1fr\",\n gap: 12,\n },\n \"x-ui-options\": {\n addLabel: \"Add Allergy\",\n emptyMessage: \"No allergies recorded\",\n orderable: true,\n },\n items: {\n type: \"object\",\n properties: {\n substance: { type: \"string\", title: \"Substance\" },\n severity: {\n type: \"string\",\n title: \"Severity\",\n enum: [\"mild\", \"moderate\", \"severe\"],\n },\n reaction: { type: \"string\", title: \"Reaction\" },\n },\n required: [\"substance\"],\n },\n },\n },\n required: [\"patient_id\"],\n};\n\n// Mixed: flat fields + nested object + array with variants\nconst MIXED_SCHEMA: JsonSchema = {\n title: \"Healthcare Organization\",\n type: \"object\",\n properties: {\n name: { type: \"string\", title: \"Name\" },\n type: {\n type: \"string\",\n title: \"Type\",\n enum: [\"hospital\", \"clinic\", \"lab\", \"pharmacy\"],\n },\n active: { type: \"boolean\", title: \"Active\" },\n location: {\n type: \"object\",\n title: \"Location\",\n \"x-ui-options\": { variant: \"card\" },\n properties: {\n address: { type: \"string\", title: \"Address\" },\n city: { type: \"string\", title: \"City\" },\n postal_code: { type: \"string\", title: \"Postal Code\" },\n country: {\n type: \"string\",\n title: \"Country\",\n enum: [\"DE\", \"AT\", \"CH\", \"US\", \"GB\"],\n },\n },\n required: [\"address\", \"city\"],\n },\n contacts: {\n type: \"array\",\n title: \"Contacts\",\n \"x-ui-options\": {\n addLabel: \"Add Contact\",\n orderable: true,\n emptyMessage: \"No contacts defined\",\n },\n items: {\n type: \"object\",\n properties: {\n name: { type: \"string\", title: \"Name\" },\n role: {\n type: \"string\",\n title: \"Role\",\n enum: [\"admin\", \"clinical\", \"billing\", \"technical\"],\n },\n email: { type: \"string\", title: \"Email\", format: \"email\" },\n phone: { type: \"string\", title: \"Phone\" },\n },\n required: [\"name\", \"email\"],\n },\n minItems: 1,\n },\n },\n required: [\"name\", \"type\"],\n};\n\n// Row layout: fields grouped into multi-column rows via x-ui-layout.rows\nconst ROW_LAYOUT_SCHEMA: JsonSchema = {\n title: \"Practitioner Registration\",\n type: \"object\",\n properties: {\n given_name: { type: \"string\", title: \"Given Name\" },\n family_name: { type: \"string\", title: \"Family Name\" },\n npi: { type: \"string\", title: \"NPI\" },\n specialty: {\n type: \"string\",\n title: \"Specialty\",\n enum: [\"cardiology\", \"neurology\", \"oncology\", \"radiology\", \"general\"],\n },\n email: { type: \"string\", title: \"Email\", format: \"email\" },\n phone: { type: \"string\", title: \"Phone\" },\n start_date: { type: \"string\", title: \"Start Date\" },\n end_date: { type: \"string\", title: \"End Date\" },\n notes: { type: \"string\", title: \"Notes\", \"x-ui-widget\": \"textarea\" },\n active: { type: \"boolean\", title: \"Active\" },\n },\n required: [\"given_name\", \"family_name\", \"npi\"],\n};\n\n// x-ui-layout is a top-level meta-key, not a per-field UISchema.\n// The renderer reads it via index access so the cast is safe here.\nconst ROW_LAYOUT_UISCHEMA: Record<string, UISchema> = {\n \"x-ui-layout\": {\n rows: [\n { fields: [\"given_name\", \"family_name\"], columns: \"1fr 1fr\" },\n { fields: [\"npi\", \"specialty\"], columns: \"1fr 1fr\" },\n { fields: [\"email\", \"phone\"], columns: \"1fr 1fr\" },\n { fields: [\"start_date\", \"end_date\"], columns: \"1fr 1fr\" },\n ],\n } as unknown as UISchema,\n};\n\nconst sampleSchemas: Record<string, JsonSchema> = {\n flat: SAMPLE_SCHEMA,\n nested_object: NESTED_OBJECT_SCHEMA,\n array_of_objects: ARRAY_OF_OBJECTS_SCHEMA,\n ref_defs: REF_SCHEMA,\n mixed: MIXED_SCHEMA,\n horizontal_array: HORIZONTAL_ARRAY_SCHEMA,\n horizontal_full: HORIZONTAL_FULL_SCHEMA,\n row_layout: ROW_LAYOUT_SCHEMA,\n};\n\n// Sample UI Schemas\nconst sampleUiSchemas: Record<string, string> = {\n empty: \"{}\",\n hideLabels: JSON.stringify(\n {\n \"x-ui-globalOptions\": {\n label: false,\n },\n },\n null,\n 2,\n ),\n disableAll: JSON.stringify(\n {\n \"x-ui-globalOptions\": {\n disabled: true,\n },\n },\n null,\n 2,\n ),\n readonlyAll: JSON.stringify(\n {\n \"x-ui-globalOptions\": {\n readonly: true,\n },\n },\n null,\n 2,\n ),\n fieldOverride: JSON.stringify(\n {\n \"x-ui-globalOptions\": {\n disabled: true,\n },\n name: {\n \"x-ui-options\": {\n disabled: false, // Override: enable this field\n },\n },\n },\n null,\n 2,\n ),\n customWidget: JSON.stringify(\n {\n description: {\n \"x-ui-widget\": \"textarea\",\n \"x-ui-options\": {\n rows: 5,\n },\n },\n },\n null,\n 2,\n ),\n};\n\n// -- State hook ----------------------------------------------------------\n\nfunction usePlayFormsState() {\n const [schemaText, setSchemaText] = useState(\n JSON.stringify(SAMPLE_SCHEMA, null, 2),\n );\n const [uiSchemaText, setUiSchemaText] = useState(\"{}\");\n const [activeSchema, setActiveSchema] = useState<JsonSchema | null>(\n SAMPLE_SCHEMA,\n );\n const [activeUiSchema, setActiveUiSchema] = useState<\n Record<string, UISchema>\n >({});\n const [dataText, setDataText] = useState(\"{}\");\n const [formData, setFormData] = useState<Record<string, unknown>>({});\n const [validationErrors, setValidationErrors] = useState<string[]>([]);\n const [isValid, setIsValid] = useState(true);\n const [schemaError, setSchemaError] = useState(\"\");\n const [uiSchemaError, setUiSchemaError] = useState(\"\");\n const [dataError, setDataError] = useState(\"\");\n const [activeTab, setActiveTab] = useState(\"schema\");\n const [deferStateUpdates, setDeferStateUpdates] = useState(false);\n const [dataCollapsed, setDataCollapsed] = useState(false);\n const [lastDiff, setLastDiff] = useState<FormDiff | null>(null);\n const toggleDataPanel = useCallback(() => setDataCollapsed((v) => !v), []);\n\n const loadSchemaPreset = useCallback((value: string | null) => {\n if (!value || !sampleSchemas[value]) return;\n const text = JSON.stringify(sampleSchemas[value], null, 2);\n setSchemaText(text);\n setActiveSchema(sampleSchemas[value]);\n setSchemaError(\"\");\n setFormData({});\n setDataText(\"{}\");\n const pairedUi = value === \"row_layout\" ? ROW_LAYOUT_UISCHEMA : {};\n setUiSchemaText(JSON.stringify(pairedUi, null, 2));\n setActiveUiSchema(pairedUi);\n setUiSchemaError(\"\");\n }, []);\n\n const loadUiSchemaPreset = useCallback(\n (value: string | null) => {\n if (!value) return;\n setUiSchemaText(sampleUiSchemas[value]);\n setUiSchemaError(\"\");\n },\n [setUiSchemaText],\n );\n\n return {\n schemaText,\n uiSchemaText,\n activeSchema,\n activeUiSchema,\n dataText,\n formData,\n validationErrors,\n isValid,\n schemaError,\n uiSchemaError,\n dataError,\n activeTab,\n deferStateUpdates,\n dataCollapsed,\n lastDiff,\n setSchemaText,\n setUiSchemaText,\n setActiveSchema,\n setActiveUiSchema,\n setDataText,\n setFormData,\n setValidationErrors,\n setIsValid,\n setSchemaError,\n setUiSchemaError,\n setDataError,\n setActiveTab,\n setDeferStateUpdates,\n toggleDataPanel,\n setLastDiff,\n loadSchemaPreset,\n loadUiSchemaPreset,\n };\n}\n\n// -- JSON parse helpers --------------------------------------------------\n\nfunction tryParseAndSet(\n value: string,\n setError: (e: string) => void,\n errorMessage = \"Invalid JSON\",\n) {\n try {\n JSON.parse(value);\n setError(\"\");\n } catch {\n setError(errorMessage);\n }\n}\n\nfunction tryParseAndLoad<T>(\n text: string,\n onSuccess: (parsed: T) => void,\n onError: (msg: string) => void,\n) {\n try {\n onSuccess(JSON.parse(text));\n onError(\"\");\n } catch {\n onError(\"Invalid JSON - cannot load to form\");\n }\n}\n\n// -- Shared panel arrow button -------------------------------------------\n\ninterface PanelArrowButtonProps {\n label: string;\n onClick: () => void;\n mirrored?: boolean;\n}\n\nfunction PanelArrowButton({\n label,\n onClick,\n mirrored = false,\n}: PanelArrowButtonProps) {\n return (\n <SimpleTooltip label={label}>\n <Button\n variant=\"default\"\n size=\"icon\"\n className=\"absolute -right-5 top-1/2 -translate-y-1/2 z-[100]\"\n onClick={onClick}\n >\n <ArrowRight\n size={20}\n className={mirrored ? \"scale-x-[-1]\" : undefined}\n />\n </Button>\n </SimpleTooltip>\n );\n}\n\n// -- Left column: Schema / UI Schema editors -----------------------------\n\nfunction SchemaEditorColumn({\n state,\n}: {\n state: ReturnType<typeof usePlayFormsState>;\n}) {\n const handleSchemaTextChange = (value: string) => {\n state.setSchemaText(value);\n tryParseAndSet(value, state.setSchemaError);\n };\n\n const handleUiSchemaTextChange = (value: string) => {\n state.setUiSchemaText(value);\n tryParseAndSet(value, state.setUiSchemaError);\n };\n\n const handleLoadSchemaToForm = () => {\n tryParseAndLoad<JsonSchema>(\n state.schemaText,\n (parsed) => {\n state.setActiveSchema(parsed);\n state.setFormData({});\n state.setDataText(\"{}\");\n state.setValidationErrors([]);\n state.setIsValid(true);\n state.setLastDiff(null);\n },\n state.setSchemaError,\n );\n };\n\n const handleLoadUiSchemaToForm = () => {\n tryParseAndLoad<Record<string, UISchema>>(\n state.uiSchemaText,\n state.setActiveUiSchema,\n state.setUiSchemaError,\n );\n };\n\n return (\n <div\n style={{\n flex: 1,\n position: \"relative\",\n display: \"flex\",\n flexDirection: \"column\",\n minWidth: 0,\n }}\n >\n <Card className=\"border shadow-sm p-4 flex-1 min-h-0 flex flex-col\">\n <Tabs\n value={state.activeTab}\n onValueChange={state.setActiveTab}\n style={{\n flex: 1,\n minHeight: 0,\n display: \"flex\",\n flexDirection: \"column\",\n }}\n >\n <TabsList className=\"mb-1\">\n <TabsTrigger value=\"schema\">JSON Schema</TabsTrigger>\n <TabsTrigger value=\"uischema\">UI Schema</TabsTrigger>\n </TabsList>\n\n <TabsContent\n value=\"schema\"\n className=\"flex-1 min-h-0 flex flex-col mt-0\"\n >\n <FormSelect\n placeholder=\"Load example schema...\"\n options={SCHEMA_PRESET_OPTIONS}\n onChange={state.loadSchemaPreset}\n className=\"text-xs\"\n wrapperClassName=\"mb-2\"\n />\n {state.schemaError && (\n <Badge variant=\"destructive\" className=\"text-xs mb-2\">\n {state.schemaError}\n </Badge>\n )}\n <JsonEditor\n value={state.schemaText}\n editablePaths={[\"/\"]}\n onChange={handleSchemaTextChange}\n height=\"100%\"\n className=\"flex-1 min-h-0 rounded-md border overflow-hidden\"\n />\n </TabsContent>\n\n <TabsContent\n value=\"uischema\"\n className=\"flex-1 min-h-0 flex flex-col mt-0\"\n >\n <FormSelect\n placeholder=\"Load example...\"\n options={UISCHEMA_PRESET_OPTIONS}\n onChange={state.loadUiSchemaPreset}\n className=\"text-xs\"\n wrapperClassName=\"mb-2\"\n />\n {state.uiSchemaError && (\n <Badge variant=\"destructive\" className=\"text-xs mb-2\">\n {state.uiSchemaError}\n </Badge>\n )}\n <JsonEditor\n value={state.uiSchemaText}\n editablePaths={[\"/\"]}\n onChange={handleUiSchemaTextChange}\n height=\"100%\"\n className=\"flex-1 min-h-0 rounded-md border overflow-hidden\"\n />\n </TabsContent>\n </Tabs>\n </Card>\n\n <PanelArrowButton\n label={\n state.activeTab === \"schema\"\n ? \"Load Schema to Form\"\n : \"Load UI Schema to Form\"\n }\n onClick={\n state.activeTab === \"schema\"\n ? handleLoadSchemaToForm\n : handleLoadUiSchemaToForm\n }\n />\n </div>\n );\n}\n\n// Preset option arrays (static, avoids re-creation).\nconst SCHEMA_PRESET_OPTIONS = [\n { value: \"flat\", label: \"Practitioner (flat fields)\" },\n { value: \"nested_object\", label: \"Patient (nested object)\" },\n { value: \"array_of_objects\", label: \"Medication Request (array)\" },\n { value: \"ref_defs\", label: \"Care Plan ($ref / $defs)\" },\n { value: \"mixed\", label: \"Organization (mixed)\" },\n { value: \"horizontal_array\", label: \"Observations (horizontal, compact)\" },\n { value: \"horizontal_full\", label: \"Allergies (horizontal, full height)\" },\n { value: \"row_layout\", label: \"Registration (row layout)\" },\n];\n\nconst UISCHEMA_PRESET_OPTIONS = [\n { value: \"empty\", label: \"Empty (no customization)\" },\n { value: \"hideLabels\", label: \"Hide all labels\" },\n { value: \"disableAll\", label: \"Disable all fields\" },\n { value: \"readonlyAll\", label: \"Readonly all fields\" },\n { value: \"fieldOverride\", label: \"Field-level override\" },\n { value: \"customWidget\", label: \"Custom widget\" },\n];\n\n// -- Middle column: Rendered form ----------------------------------------\n\nfunction FormColumn({\n state,\n}: {\n state: ReturnType<typeof usePlayFormsState>;\n}) {\n const handleUpdate = (\n data: Record<string, unknown>,\n _changedFields: Record<string, unknown>,\n diff: FormDiff,\n ) => {\n state.setDataText(JSON.stringify(data, null, 2));\n state.setFormData(data);\n state.setLastDiff(diff);\n };\n\n const handleCancel = () => {\n state.setFormData({});\n state.setDataText(\"{}\");\n state.setValidationErrors([]);\n state.setIsValid(true);\n state.setLastDiff(null);\n };\n\n const handleValidationChange = (errors: string[], valid: boolean) => {\n state.setValidationErrors(errors);\n state.setIsValid(valid);\n };\n\n const handleLoadDataToForm = () => {\n tryParseAndLoad(state.dataText, state.setFormData, state.setDataError);\n };\n\n return (\n <div\n style={{\n flex: 1,\n position: \"relative\",\n display: \"flex\",\n flexDirection: \"column\",\n minWidth: 0,\n }}\n >\n <Card className=\"border shadow-sm p-4 flex-1 min-h-0 flex flex-col\">\n <SimpleStack\n gap=\"md\"\n style={{\n flex: 1,\n minHeight: 0,\n display: \"flex\",\n flexDirection: \"column\",\n }}\n >\n <div>\n <p className=\"text-sm font-semibold mb-1\">Rendered Form</p>\n <SimpleGroup gap=\"xs\" align=\"center\" className=\"mb-1\">\n <Badge\n variant={state.isValid ? \"default\" : \"destructive\"}\n className=\"text-xs\"\n >\n {state.isValid ? \"Valid\" : \"Invalid\"}\n </Badge>\n <FormCheckbox\n label=\"Defer state updates (change on blur)\"\n checked={state.deferStateUpdates}\n onChange={(checked) => {\n if (checked !== \"indeterminate\") {\n state.setDeferStateUpdates(checked);\n }\n }}\n />\n </SimpleGroup>\n {state.validationErrors.length > 0 && (\n <div style={{ marginTop: \"4px\" }}>\n {state.validationErrors.map((err, idx) => (\n <p key={idx} className=\"text-xs text-destructive\">\n {err}\n </p>\n ))}\n </div>\n )}\n </div>\n\n <div\n style={{\n flex: 1,\n minHeight: 0,\n overflowY: \"auto\",\n paddingRight: \"4px\",\n }}\n >\n {state.activeSchema && (\n <JsonSchemaFormRenderer\n schema={state.activeSchema}\n data={state.formData}\n onUpdate={handleUpdate}\n onCancel={handleCancel}\n onValidationChange={handleValidationChange}\n showActions={true}\n deferStateUpdates={state.deferStateUpdates}\n saveLabel=\"Save Changes\"\n cancelLabel=\"Reset\"\n showExtraProperties={true}\n uiSchema={state.activeUiSchema}\n />\n )}\n {!state.activeSchema && (\n <p className=\"text-sm text-muted-foreground text-center mt-8\">\n Edit the JSON Schema on the left and click the arrow to load it\n </p>\n )}\n </div>\n </SimpleStack>\n </Card>\n\n {!state.dataCollapsed && (\n <PanelArrowButton\n label=\"Load JSON Data into Form\"\n onClick={handleLoadDataToForm}\n mirrored\n />\n )}\n </div>\n );\n}\n\n// -- Right column: JSON data + diff --------------------------------------\n\nfunction DataColumn({\n state,\n}: {\n state: ReturnType<typeof usePlayFormsState>;\n}) {\n const handleDataTextChange = (value: string) => {\n state.setDataText(value);\n tryParseAndSet(value, state.setDataError);\n };\n\n return (\n <div\n style={{\n flex: state.dataCollapsed ? \"0 0 2.25rem\" : 1,\n display: \"flex\",\n flexDirection: \"column\",\n minWidth: 0,\n gap: \"0.75rem\",\n transition: \"flex 200ms ease\",\n }}\n >\n <Card\n className=\"border shadow-sm min-h-0 flex flex-col overflow-hidden\"\n style={{ flex: \"1 1 50%\" }}\n >\n <div className=\"flex items-center justify-between px-4 py-3 shrink-0\">\n {!state.dataCollapsed && (\n <p className=\"text-sm font-semibold\">JSON Data</p>\n )}\n <SimpleTooltip\n label={\n state.dataCollapsed ? \"Expand JSON data\" : \"Collapse JSON data\"\n }\n >\n <Button\n variant=\"ghost\"\n size=\"compact\"\n onClick={state.toggleDataPanel}\n className=\"ml-auto\"\n >\n {state.dataCollapsed ? (\n <ChevronLeft className=\"h-4 w-4\" />\n ) : (\n <ChevronRightIcon className=\"h-4 w-4\" />\n )}\n </Button>\n </SimpleTooltip>\n </div>\n\n {!state.dataCollapsed && (\n <div className=\"flex-1 min-h-0 flex flex-col px-4 pb-4\">\n {state.dataError && (\n <Badge variant=\"destructive\" className=\"text-xs mb-2\">\n {state.dataError}\n </Badge>\n )}\n <JsonEditor\n value={state.dataText}\n editablePaths={[\"/\"]}\n onChange={handleDataTextChange}\n height=\"100%\"\n className=\"flex-1 min-h-0 rounded-md border overflow-hidden\"\n />\n </div>\n )}\n </Card>\n\n {!state.dataCollapsed && (\n <Card\n className=\"border shadow-sm min-h-0 flex flex-col overflow-hidden\"\n style={{ flex: \"1 1 50%\" }}\n >\n <div className=\"flex items-center justify-between px-4 py-3 shrink-0\">\n <p className=\"text-sm font-semibold\">Diff</p>\n </div>\n <div className=\"flex-1 min-h-0 flex flex-col px-4 pb-4\">\n <JsonEditor\n value={JSON.stringify(state.lastDiff ?? [], null, 2)}\n editablePaths={[\"/\"]}\n height=\"100%\"\n className=\"flex-1 min-h-0 rounded-md border overflow-hidden\"\n />\n </div>\n </Card>\n )}\n </div>\n );\n}\n\n// -- Main component ------------------------------------------------------\n\nexport default function PlayForms() {\n const state = usePlayFormsState();\n\n return (\n <div className=\"w-full flex flex-col gap-3 h-[calc(100vh-8rem)]\">\n <div>\n <h1>Forms Playground</h1>\n <p className=\"text-sm text-muted-foreground mb-3\">\n Test and experiment with JsonSchemaFormRenderer. Edit the JSON Schema\n on the left, then load it into the form.\n </p>\n </div>\n\n <div\n style={{\n flex: 1,\n minHeight: 0,\n display: \"flex\",\n gap: \"1.5rem\",\n }}\n >\n <SchemaEditorColumn state={state} />\n <FormColumn state={state} />\n <DataColumn state={state} />\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|