@petrarca/sonnet-playground 0.2.0 → 0.4.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.
Files changed (75) hide show
  1. package/README.md +142 -0
  2. package/dist/PlayAdvancedComponents-ZYK66UII.js +8 -0
  3. package/dist/PlayColorPalette-IWECRZUS.js +8 -0
  4. package/dist/PlayCoreComponents-GXFMB24T.js +8 -0
  5. package/dist/PlayDataComponents-M4SJ4XEL.js +8 -0
  6. package/dist/PlayFormComponents-4E2A2Y2W.js +8 -0
  7. package/dist/PlayFormWidgets-IWJJQ5XL.js +8 -0
  8. package/dist/PlayForms-FOF3XE6G.js +7 -0
  9. package/dist/PlayGraph-3F56PREG.js +7 -0
  10. package/dist/PlayJsonEditor-SYZYEJEA.js +7 -0
  11. package/dist/PlayShellApi-5O6VYR2X.js +8 -0
  12. package/dist/PlayShellApi-5O6VYR2X.js.map +1 -0
  13. package/dist/PlayTypography-T6SMPHUB.js +8 -0
  14. package/dist/PlayTypography-T6SMPHUB.js.map +1 -0
  15. package/dist/chunk-32DDRRWU.js +617 -0
  16. package/dist/chunk-32DDRRWU.js.map +1 -0
  17. package/dist/chunk-4Y4JFKAK.js +240 -0
  18. package/dist/chunk-4Y4JFKAK.js.map +1 -0
  19. package/dist/{chunk-QIETZUEN.js → chunk-6DZ3TSV4.js} +66 -71
  20. package/dist/chunk-6DZ3TSV4.js.map +1 -0
  21. package/dist/{chunk-CYNK2P2Q.js → chunk-7IBZEHLI.js} +14 -13
  22. package/dist/chunk-7IBZEHLI.js.map +1 -0
  23. package/dist/chunk-C2EZ2ECG.js +40 -0
  24. package/dist/chunk-C2EZ2ECG.js.map +1 -0
  25. package/dist/chunk-CQ6PGFRV.js +341 -0
  26. package/dist/chunk-CQ6PGFRV.js.map +1 -0
  27. package/dist/{chunk-A3IK3CVW.js → chunk-DA3BIB5N.js} +24 -25
  28. package/dist/{chunk-A3IK3CVW.js.map → chunk-DA3BIB5N.js.map} +1 -1
  29. package/dist/chunk-DZB6WFHA.js +401 -0
  30. package/dist/chunk-DZB6WFHA.js.map +1 -0
  31. package/dist/{chunk-KAT24CQQ.js → chunk-FZ3ZC7VM.js} +8 -6
  32. package/dist/chunk-FZ3ZC7VM.js.map +1 -0
  33. package/dist/{chunk-PGI54O43.js → chunk-VOC5VZG2.js} +84 -46
  34. package/dist/chunk-VOC5VZG2.js.map +1 -0
  35. package/dist/{chunk-TZGJH7YS.js → chunk-YEBK2TUW.js} +325 -331
  36. package/dist/chunk-YEBK2TUW.js.map +1 -0
  37. package/dist/chunk-YOOWJORD.js +934 -0
  38. package/dist/chunk-YOOWJORD.js.map +1 -0
  39. package/dist/index.d.ts +10 -6
  40. package/dist/index.js +41 -17
  41. package/dist/index.js.map +1 -1
  42. package/dist/pages/index.d.ts +15 -11
  43. package/dist/pages/index.js +20 -12
  44. package/package.json +6 -6
  45. package/dist/PlayColorPalette-UFMTJTUB.js +0 -8
  46. package/dist/PlayCoreComponents-7QCDFQLT.js +0 -7
  47. package/dist/PlayDataComponents-GZSRTW4F.js +0 -7
  48. package/dist/PlayFormComponents-RJB6WZHD.js +0 -7
  49. package/dist/PlayFormWidgets-OFV7TJKH.js +0 -7
  50. package/dist/PlayForms-24XX5DC6.js +0 -7
  51. package/dist/PlayGraph-FLGLSUWV.js +0 -8
  52. package/dist/PlayJsonEditor-4L5INQPU.js +0 -7
  53. package/dist/PlayTypography-ID6DLFZD.js +0 -8
  54. package/dist/chunk-5V27QDAY.js +0 -617
  55. package/dist/chunk-5V27QDAY.js.map +0 -1
  56. package/dist/chunk-CYNK2P2Q.js.map +0 -1
  57. package/dist/chunk-FTN2A5YL.js +0 -20
  58. package/dist/chunk-FTN2A5YL.js.map +0 -1
  59. package/dist/chunk-GYKEPHHA.js +0 -1154
  60. package/dist/chunk-GYKEPHHA.js.map +0 -1
  61. package/dist/chunk-KAT24CQQ.js.map +0 -1
  62. package/dist/chunk-P7I5IDXA.js +0 -432
  63. package/dist/chunk-P7I5IDXA.js.map +0 -1
  64. package/dist/chunk-PGI54O43.js.map +0 -1
  65. package/dist/chunk-QIETZUEN.js.map +0 -1
  66. package/dist/chunk-TZGJH7YS.js.map +0 -1
  67. /package/dist/{PlayColorPalette-UFMTJTUB.js.map → PlayAdvancedComponents-ZYK66UII.js.map} +0 -0
  68. /package/dist/{PlayCoreComponents-7QCDFQLT.js.map → PlayColorPalette-IWECRZUS.js.map} +0 -0
  69. /package/dist/{PlayDataComponents-GZSRTW4F.js.map → PlayCoreComponents-GXFMB24T.js.map} +0 -0
  70. /package/dist/{PlayFormComponents-RJB6WZHD.js.map → PlayDataComponents-M4SJ4XEL.js.map} +0 -0
  71. /package/dist/{PlayFormWidgets-OFV7TJKH.js.map → PlayFormComponents-4E2A2Y2W.js.map} +0 -0
  72. /package/dist/{PlayForms-24XX5DC6.js.map → PlayFormWidgets-IWJJQ5XL.js.map} +0 -0
  73. /package/dist/{PlayGraph-FLGLSUWV.js.map → PlayForms-FOF3XE6G.js.map} +0 -0
  74. /package/dist/{PlayJsonEditor-4L5INQPU.js.map → PlayGraph-3F56PREG.js.map} +0 -0
  75. /package/dist/{PlayTypography-ID6DLFZD.js.map → PlayJsonEditor-SYZYEJEA.js.map} +0 -0
@@ -0,0 +1,401 @@
1
+ import {
2
+ ExampleBlock
3
+ } from "./chunk-C2EZ2ECG.js";
4
+
5
+ // src/pages/PlayFormWidgets.tsx
6
+ import {
7
+ useCallback,
8
+ useMemo,
9
+ useState
10
+ } from "react";
11
+ import { SimpleStack, Card } from "@petrarca/sonnet-ui";
12
+ import {
13
+ TextInputWidget,
14
+ TextareaWidget,
15
+ NumberWidget,
16
+ CheckboxWidget,
17
+ SelectWidget,
18
+ QuantityWidget,
19
+ DEFAULT_WIDGETS
20
+ } from "@petrarca/sonnet-forms";
21
+ import { jsx, jsxs } from "react/jsx-runtime";
22
+ var dummySchema = {
23
+ title: "Form Widgets Demo",
24
+ type: "object",
25
+ properties: {},
26
+ "x-entity": {
27
+ type: "entity",
28
+ label: "Demo",
29
+ relations: []
30
+ }
31
+ };
32
+ function makeQuantityHandler(set) {
33
+ return (v) => {
34
+ if (v != null && typeof v === "object" && !Array.isArray(v)) {
35
+ set(v);
36
+ }
37
+ };
38
+ }
39
+ function PlayFormWidgets() {
40
+ const [textValue, setTextValue] = useState("");
41
+ const [textareaValue, setTextareaValue] = useState("");
42
+ const [numberValue, setNumberValue] = useState(void 0);
43
+ const [checkboxValue, setCheckboxValue] = useState(false);
44
+ const [selectValue, setSelectValue] = useState("");
45
+ const [multiSelectValue, setMultiSelectValue] = useState([]);
46
+ const [multiSelectColorValue, setMultiSelectColorValue] = useState(
47
+ []
48
+ );
49
+ const [tempValue, setTempValue] = useState({
50
+ value: 37,
51
+ unit: "degC"
52
+ });
53
+ const [weightValue, setWeightValue] = useState({
54
+ value: void 0,
55
+ unit: "kg"
56
+ });
57
+ const [bpValue, setBpValue] = useState({
58
+ value: 72,
59
+ unit: "bpm"
60
+ });
61
+ const [priceValue, setPriceValue] = useState({
62
+ value: 49.99,
63
+ unit: "EUR"
64
+ });
65
+ const onTextChange = useCallback(
66
+ (v) => setTextValue(typeof v === "string" ? v : ""),
67
+ []
68
+ );
69
+ const onTextareaChange = useCallback(
70
+ (v) => setTextareaValue(typeof v === "string" ? v : ""),
71
+ []
72
+ );
73
+ const onNumberChange = useCallback(
74
+ (v) => setNumberValue(typeof v === "number" ? v : void 0),
75
+ []
76
+ );
77
+ const onCheckboxChange = useCallback(
78
+ (v) => setCheckboxValue(typeof v === "boolean" ? v : false),
79
+ []
80
+ );
81
+ const onSelectChange = useCallback(
82
+ (v) => setSelectValue(typeof v === "string" ? v : ""),
83
+ []
84
+ );
85
+ const onMultiSelectChange = useCallback(
86
+ (v) => setMultiSelectValue(Array.isArray(v) ? v : []),
87
+ []
88
+ );
89
+ const onMultiSelectColorChange = useCallback(
90
+ (v) => setMultiSelectColorValue(Array.isArray(v) ? v : []),
91
+ []
92
+ );
93
+ const onTempChange = useMemo(() => makeQuantityHandler(setTempValue), []);
94
+ const onWeightChange = useMemo(() => makeQuantityHandler(setWeightValue), []);
95
+ const onBpChange = useMemo(() => makeQuantityHandler(setBpValue), []);
96
+ const onPriceChange = useMemo(() => makeQuantityHandler(setPriceValue), []);
97
+ return /* @__PURE__ */ jsxs("div", { className: "w-full max-w-4xl space-y-6", children: [
98
+ /* @__PURE__ */ jsxs("div", { children: [
99
+ /* @__PURE__ */ jsx("h1", { children: "Basic Form Widgets Playground" }),
100
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-3", children: "Interactive demonstration of all basic form widgets" })
101
+ ] }),
102
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(SimpleStack, { gap: "md", style: { maxWidth: "900px" }, children: [
103
+ /* @__PURE__ */ jsx(Card, { className: "border shadow-sm p-4", children: /* @__PURE__ */ jsxs(SimpleStack, { gap: "sm", children: [
104
+ /* @__PURE__ */ jsx("h2", { children: "TextInputWidget" }),
105
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Single-line text input with support for various HTML input types (text, email, password, url, etc.)" }),
106
+ /* @__PURE__ */ jsx(
107
+ TextInputWidget,
108
+ {
109
+ id: "text-input-demo",
110
+ name: "textInput",
111
+ value: textValue,
112
+ onChange: onTextChange,
113
+ label: "Text Input",
114
+ description: "Enter some text",
115
+ placeholder: "Type here...",
116
+ propertySchema: { type: "string" },
117
+ schema: dummySchema,
118
+ registry: DEFAULT_WIDGETS
119
+ }
120
+ ),
121
+ /* @__PURE__ */ jsx(
122
+ TextInputWidget,
123
+ {
124
+ id: "text-input-email",
125
+ name: "emailInput",
126
+ value: textValue,
127
+ onChange: onTextChange,
128
+ label: "Email Input",
129
+ description: "Input type: email",
130
+ placeholder: "user@example.com",
131
+ propertySchema: { type: "string", format: "email" },
132
+ schema: dummySchema,
133
+ registry: DEFAULT_WIDGETS,
134
+ options: { inputType: "email" }
135
+ }
136
+ ),
137
+ /* @__PURE__ */ jsx("pre", { className: "text-[11px] bg-muted p-2 rounded overflow-x-auto", children: /* @__PURE__ */ jsx("code", { children: JSON.stringify({ value: textValue }, null, 2) }) })
138
+ ] }) }),
139
+ /* @__PURE__ */ jsx(Card, { className: "border shadow-sm p-4", children: /* @__PURE__ */ jsxs(SimpleStack, { gap: "sm", children: [
140
+ /* @__PURE__ */ jsx("h2", { children: "TextareaWidget" }),
141
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Multi-line text input with configurable rows and autosize support" }),
142
+ /* @__PURE__ */ jsx(
143
+ TextareaWidget,
144
+ {
145
+ id: "textarea-demo",
146
+ name: "textarea",
147
+ value: textareaValue,
148
+ onChange: onTextareaChange,
149
+ label: "Textarea",
150
+ description: "Enter multiple lines",
151
+ placeholder: "Type here...",
152
+ propertySchema: { type: "string" },
153
+ schema: dummySchema,
154
+ registry: DEFAULT_WIDGETS,
155
+ options: { rows: 4 }
156
+ }
157
+ ),
158
+ /* @__PURE__ */ jsx("pre", { className: "text-[11px] bg-muted p-2 rounded overflow-x-auto", children: /* @__PURE__ */ jsx("code", { children: JSON.stringify({ value: textareaValue }, null, 2) }) })
159
+ ] }) }),
160
+ /* @__PURE__ */ jsx(Card, { className: "border shadow-sm p-4", children: /* @__PURE__ */ jsxs(SimpleStack, { gap: "sm", children: [
161
+ /* @__PURE__ */ jsx("h2", { children: "NumberWidget" }),
162
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Number input with support for min, max, and step constraints" }),
163
+ /* @__PURE__ */ jsx(
164
+ NumberWidget,
165
+ {
166
+ id: "number-demo",
167
+ name: "number",
168
+ value: numberValue,
169
+ onChange: onNumberChange,
170
+ label: "Number Input",
171
+ description: "Enter a number (0-100, step: 5)",
172
+ placeholder: "0",
173
+ propertySchema: { type: "number", minimum: 0, maximum: 100 },
174
+ schema: dummySchema,
175
+ registry: DEFAULT_WIDGETS,
176
+ options: { step: 5 }
177
+ }
178
+ ),
179
+ /* @__PURE__ */ jsx("pre", { className: "text-[11px] bg-muted p-2 rounded overflow-x-auto", children: /* @__PURE__ */ jsx("code", { children: JSON.stringify({ value: numberValue }, null, 2) }) })
180
+ ] }) }),
181
+ /* @__PURE__ */ jsx(Card, { className: "border shadow-sm p-4", children: /* @__PURE__ */ jsxs(SimpleStack, { gap: "sm", children: [
182
+ /* @__PURE__ */ jsx("h2", { children: "CheckboxWidget" }),
183
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Boolean checkbox for true/false values" }),
184
+ /* @__PURE__ */ jsx(
185
+ CheckboxWidget,
186
+ {
187
+ id: "checkbox-demo",
188
+ name: "checkbox",
189
+ value: checkboxValue,
190
+ onChange: onCheckboxChange,
191
+ label: "Enable Feature",
192
+ description: "Check to enable",
193
+ propertySchema: { type: "boolean" },
194
+ schema: dummySchema,
195
+ registry: DEFAULT_WIDGETS
196
+ }
197
+ ),
198
+ /* @__PURE__ */ jsx("pre", { className: "text-[11px] bg-muted p-2 rounded overflow-x-auto", children: /* @__PURE__ */ jsx("code", { children: JSON.stringify({ value: checkboxValue }, null, 2) }) })
199
+ ] }) }),
200
+ /* @__PURE__ */ jsx(Card, { className: "border shadow-sm p-4", children: /* @__PURE__ */ jsxs(SimpleStack, { gap: "sm", children: [
201
+ /* @__PURE__ */ jsx("h2", { children: "SelectWidget" }),
202
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Dropdown select for enum values with single-select, multi-select, and custom badge colors" }),
203
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3 pt-2", children: [
204
+ /* @__PURE__ */ jsx(ExampleBlock, { label: "Single select", children: /* @__PURE__ */ jsx(
205
+ SelectWidget,
206
+ {
207
+ id: "select-demo",
208
+ name: "select",
209
+ value: selectValue,
210
+ onChange: onSelectChange,
211
+ label: "Select Status",
212
+ description: "Choose a status",
213
+ placeholder: "Select one...",
214
+ propertySchema: {
215
+ type: "string",
216
+ enum: ["active", "inactive", "pending", "archived"]
217
+ },
218
+ schema: dummySchema,
219
+ registry: DEFAULT_WIDGETS,
220
+ options: {
221
+ enumNames: {
222
+ active: "Active",
223
+ inactive: "Inactive",
224
+ pending: "Pending",
225
+ archived: "Archived"
226
+ },
227
+ searchable: true,
228
+ clearable: true
229
+ }
230
+ }
231
+ ) }),
232
+ /* @__PURE__ */ jsx(ExampleBlock, { label: "Multi select", children: /* @__PURE__ */ jsx(
233
+ SelectWidget,
234
+ {
235
+ id: "multiselect-demo",
236
+ name: "multiselect",
237
+ value: multiSelectValue,
238
+ onChange: onMultiSelectChange,
239
+ label: "Select Tags",
240
+ description: "Choose multiple tags",
241
+ placeholder: "Select tags...",
242
+ propertySchema: {
243
+ type: "array",
244
+ items: { type: "string" },
245
+ enum: [
246
+ "frontend",
247
+ "backend",
248
+ "database",
249
+ "devops",
250
+ "testing",
251
+ "security"
252
+ ]
253
+ },
254
+ schema: dummySchema,
255
+ registry: DEFAULT_WIDGETS,
256
+ options: { searchable: true, clearable: true }
257
+ }
258
+ ) }),
259
+ /* @__PURE__ */ jsx(ExampleBlock, { label: "Custom badge color", children: /* @__PURE__ */ jsx(
260
+ SelectWidget,
261
+ {
262
+ id: "multiselect-color-demo",
263
+ name: "multiselectColor",
264
+ value: multiSelectColorValue,
265
+ onChange: onMultiSelectColorChange,
266
+ label: "Select Categories",
267
+ description: "Custom grape-colored badges",
268
+ placeholder: "Select categories...",
269
+ propertySchema: {
270
+ type: "array",
271
+ items: { type: "string" },
272
+ enum: [
273
+ "feature",
274
+ "bugfix",
275
+ "enhancement",
276
+ "documentation",
277
+ "refactor"
278
+ ]
279
+ },
280
+ schema: dummySchema,
281
+ registry: DEFAULT_WIDGETS,
282
+ options: {
283
+ searchable: true,
284
+ clearable: true,
285
+ badgeColor: "grape",
286
+ enumNames: {
287
+ feature: "Feature",
288
+ bugfix: "Bug Fix",
289
+ enhancement: "Enhancement",
290
+ documentation: "Documentation",
291
+ refactor: "Refactor"
292
+ }
293
+ }
294
+ }
295
+ ) })
296
+ ] })
297
+ ] }) }),
298
+ /* @__PURE__ */ jsx(Card, { className: "border shadow-sm p-4", children: /* @__PURE__ */ jsxs(SimpleStack, { gap: "sm", children: [
299
+ /* @__PURE__ */ jsx("h2", { children: "QuantityWidget" }),
300
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Compound numeric value + unit selector. Multi-unit shows a dropdown, single-unit shows static text, prefix mode places the unit before the value." }),
301
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3 pt-2", children: [
302
+ /* @__PURE__ */ jsx(ExampleBlock, { label: "Multi-unit suffix (Temperature)", children: /* @__PURE__ */ jsx(
303
+ QuantityWidget,
304
+ {
305
+ id: "quantity-temp",
306
+ name: "temperature",
307
+ value: tempValue,
308
+ onChange: onTempChange,
309
+ label: "Temperature",
310
+ description: "Body temperature with per-unit validation",
311
+ placeholder: "0.0",
312
+ propertySchema: { type: "object" },
313
+ schema: dummySchema,
314
+ registry: DEFAULT_WIDGETS,
315
+ options: {
316
+ precision: 1,
317
+ units: [
318
+ { value: "degC", label: "C", min: 35, max: 42 },
319
+ { value: "degF", label: "F", min: 95, max: 108 }
320
+ ]
321
+ }
322
+ }
323
+ ) }),
324
+ /* @__PURE__ */ jsx(ExampleBlock, { label: "Single-unit suffix (Weight)", children: /* @__PURE__ */ jsx(
325
+ QuantityWidget,
326
+ {
327
+ id: "quantity-weight",
328
+ name: "weight",
329
+ value: weightValue,
330
+ onChange: onWeightChange,
331
+ label: "Weight",
332
+ description: "Single unit, global min/max from schema",
333
+ placeholder: "0",
334
+ propertySchema: {
335
+ type: "object",
336
+ minimum: 0,
337
+ maximum: 500
338
+ },
339
+ schema: dummySchema,
340
+ registry: DEFAULT_WIDGETS,
341
+ options: {
342
+ precision: 1,
343
+ units: [{ value: "kg", label: "kg" }]
344
+ }
345
+ }
346
+ ) }),
347
+ /* @__PURE__ */ jsx(ExampleBlock, { label: "Integer mode (Heart Rate)", children: /* @__PURE__ */ jsx(
348
+ QuantityWidget,
349
+ {
350
+ id: "quantity-hr",
351
+ name: "heartRate",
352
+ value: bpValue,
353
+ onChange: onBpChange,
354
+ label: "Heart Rate",
355
+ description: "Integer with per-unit validation (30-250 bpm)",
356
+ placeholder: "0",
357
+ propertySchema: { type: "object" },
358
+ schema: dummySchema,
359
+ registry: DEFAULT_WIDGETS,
360
+ options: {
361
+ precision: 0,
362
+ units: [
363
+ { value: "bpm", label: "bpm", min: 30, max: 250 }
364
+ ]
365
+ }
366
+ }
367
+ ) }),
368
+ /* @__PURE__ */ jsx(ExampleBlock, { label: "Multi-unit prefix (Currency)", children: /* @__PURE__ */ jsx(
369
+ QuantityWidget,
370
+ {
371
+ id: "quantity-price",
372
+ name: "price",
373
+ value: priceValue,
374
+ onChange: onPriceChange,
375
+ label: "Price",
376
+ description: "Currency symbol as prefix, multi-unit selector",
377
+ placeholder: "0.00",
378
+ propertySchema: { type: "object", minimum: 0 },
379
+ schema: dummySchema,
380
+ registry: DEFAULT_WIDGETS,
381
+ options: {
382
+ precision: 2,
383
+ unitPosition: "prefix",
384
+ units: [
385
+ { value: "EUR", label: "EUR" },
386
+ { value: "USD", label: "$" },
387
+ { value: "GBP", label: "GBP" }
388
+ ]
389
+ }
390
+ }
391
+ ) })
392
+ ] })
393
+ ] }) })
394
+ ] }) })
395
+ ] });
396
+ }
397
+
398
+ export {
399
+ PlayFormWidgets
400
+ };
401
+ //# sourceMappingURL=chunk-DZB6WFHA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pages/PlayFormWidgets.tsx"],"sourcesContent":["/**\n * Playground page for testing form widgets\n * Accessible at /playground/form-widgets\n */\n\nimport {\n type Dispatch,\n type SetStateAction,\n useCallback,\n useMemo,\n useState,\n} from \"react\";\nimport { SimpleStack, Card } from \"@petrarca/sonnet-ui\";\nimport { ExampleBlock } from \"../PlaygroundSection\";\nimport {\n TextInputWidget,\n TextareaWidget,\n NumberWidget,\n CheckboxWidget,\n SelectWidget,\n QuantityWidget,\n DEFAULT_WIDGETS,\n type QuantityValue,\n} from \"@petrarca/sonnet-forms\";\nimport type { JsonSchema } from \"@petrarca/sonnet-core/schema\";\n\nconst dummySchema: JsonSchema = {\n title: \"Form Widgets Demo\",\n type: \"object\",\n properties: {},\n \"x-entity\": {\n type: \"entity\",\n label: \"Demo\",\n relations: [],\n },\n};\n\nfunction makeQuantityHandler(\n set: Dispatch<SetStateAction<QuantityValue>>,\n): (v: unknown) => void {\n return (v: unknown) => {\n if (v != null && typeof v === \"object\" && !Array.isArray(v)) {\n set(v as QuantityValue);\n }\n };\n}\n\nexport default function PlayFormWidgets() {\n // State for each widget\n const [textValue, setTextValue] = useState<string>(\"\");\n const [textareaValue, setTextareaValue] = useState<string>(\"\");\n const [numberValue, setNumberValue] = useState<number | undefined>(undefined);\n const [checkboxValue, setCheckboxValue] = useState<boolean>(false);\n const [selectValue, setSelectValue] = useState<string>(\"\");\n const [multiSelectValue, setMultiSelectValue] = useState<string[]>([]);\n const [multiSelectColorValue, setMultiSelectColorValue] = useState<string[]>(\n [],\n );\n const [tempValue, setTempValue] = useState<QuantityValue>({\n value: 37.0,\n unit: \"degC\",\n });\n const [weightValue, setWeightValue] = useState<QuantityValue>({\n value: undefined,\n unit: \"kg\",\n });\n const [bpValue, setBpValue] = useState<QuantityValue>({\n value: 72,\n unit: \"bpm\",\n });\n const [priceValue, setPriceValue] = useState<QuantityValue>({\n value: 49.99,\n unit: \"EUR\",\n });\n\n // Narrowing adapters: WidgetProps.onChange is (value: unknown) => void.\n // All quantity adapters have stable identity (empty deps) -- the fallback\n // branch is dropped so the state setter is not captured in the closure.\n const onTextChange = useCallback(\n (v: unknown) => setTextValue(typeof v === \"string\" ? v : \"\"),\n [],\n );\n const onTextareaChange = useCallback(\n (v: unknown) => setTextareaValue(typeof v === \"string\" ? v : \"\"),\n [],\n );\n const onNumberChange = useCallback(\n (v: unknown) => setNumberValue(typeof v === \"number\" ? v : undefined),\n [],\n );\n const onCheckboxChange = useCallback(\n (v: unknown) => setCheckboxValue(typeof v === \"boolean\" ? v : false),\n [],\n );\n const onSelectChange = useCallback(\n (v: unknown) => setSelectValue(typeof v === \"string\" ? v : \"\"),\n [],\n );\n const onMultiSelectChange = useCallback(\n (v: unknown) =>\n setMultiSelectValue(Array.isArray(v) ? (v as string[]) : []),\n [],\n );\n const onMultiSelectColorChange = useCallback(\n (v: unknown) =>\n setMultiSelectColorValue(Array.isArray(v) ? (v as string[]) : []),\n [],\n );\n // Quantity adapters: QuantityWidget passes unknown, guard narrows to QuantityValue.\n const onTempChange = useMemo(() => makeQuantityHandler(setTempValue), []);\n const onWeightChange = useMemo(() => makeQuantityHandler(setWeightValue), []);\n const onBpChange = useMemo(() => makeQuantityHandler(setBpValue), []);\n const onPriceChange = useMemo(() => makeQuantityHandler(setPriceValue), []);\n\n return (\n <div className=\"w-full max-w-4xl space-y-6\">\n <div>\n <h1>Basic Form Widgets Playground</h1>\n <p className=\"text-sm text-muted-foreground mb-3\">\n Interactive demonstration of all basic form widgets\n </p>\n </div>\n\n <div>\n <SimpleStack gap=\"md\" style={{ maxWidth: \"900px\" }}>\n {/* TextInputWidget */}\n <Card className=\"border shadow-sm p-4\">\n <SimpleStack gap=\"sm\">\n <h2>TextInputWidget</h2>\n <p className=\"text-sm text-muted-foreground\">\n Single-line text input with support for various HTML input types\n (text, email, password, url, etc.)\n </p>\n\n <TextInputWidget\n id=\"text-input-demo\"\n name=\"textInput\"\n value={textValue}\n onChange={onTextChange}\n label=\"Text Input\"\n description=\"Enter some text\"\n placeholder=\"Type here...\"\n propertySchema={{ type: \"string\" }}\n schema={dummySchema}\n registry={DEFAULT_WIDGETS}\n />\n\n <TextInputWidget\n id=\"text-input-email\"\n name=\"emailInput\"\n value={textValue}\n onChange={onTextChange}\n label=\"Email Input\"\n description=\"Input type: email\"\n placeholder=\"user@example.com\"\n propertySchema={{ type: \"string\", format: \"email\" }}\n schema={dummySchema}\n registry={DEFAULT_WIDGETS}\n options={{ inputType: \"email\" }}\n />\n\n <pre className=\"text-[11px] bg-muted p-2 rounded overflow-x-auto\">\n <code>{JSON.stringify({ value: textValue }, null, 2)}</code>\n </pre>\n </SimpleStack>\n </Card>\n\n {/* TextareaWidget */}\n <Card className=\"border shadow-sm p-4\">\n <SimpleStack gap=\"sm\">\n <h2>TextareaWidget</h2>\n <p className=\"text-sm text-muted-foreground\">\n Multi-line text input with configurable rows and autosize\n support\n </p>\n\n <TextareaWidget\n id=\"textarea-demo\"\n name=\"textarea\"\n value={textareaValue}\n onChange={onTextareaChange}\n label=\"Textarea\"\n description=\"Enter multiple lines\"\n placeholder=\"Type here...\"\n propertySchema={{ type: \"string\" }}\n schema={dummySchema}\n registry={DEFAULT_WIDGETS}\n options={{ rows: 4 }}\n />\n\n <pre className=\"text-[11px] bg-muted p-2 rounded overflow-x-auto\">\n <code>{JSON.stringify({ value: textareaValue }, null, 2)}</code>\n </pre>\n </SimpleStack>\n </Card>\n\n {/* NumberWidget */}\n <Card className=\"border shadow-sm p-4\">\n <SimpleStack gap=\"sm\">\n <h2>NumberWidget</h2>\n <p className=\"text-sm text-muted-foreground\">\n Number input with support for min, max, and step constraints\n </p>\n\n <NumberWidget\n id=\"number-demo\"\n name=\"number\"\n value={numberValue}\n onChange={onNumberChange}\n label=\"Number Input\"\n description=\"Enter a number (0-100, step: 5)\"\n placeholder=\"0\"\n propertySchema={{ type: \"number\", minimum: 0, maximum: 100 }}\n schema={dummySchema}\n registry={DEFAULT_WIDGETS}\n options={{ step: 5 }}\n />\n\n <pre className=\"text-[11px] bg-muted p-2 rounded overflow-x-auto\">\n <code>{JSON.stringify({ value: numberValue }, null, 2)}</code>\n </pre>\n </SimpleStack>\n </Card>\n\n {/* CheckboxWidget */}\n <Card className=\"border shadow-sm p-4\">\n <SimpleStack gap=\"sm\">\n <h2>CheckboxWidget</h2>\n <p className=\"text-sm text-muted-foreground\">\n Boolean checkbox for true/false values\n </p>\n\n <CheckboxWidget\n id=\"checkbox-demo\"\n name=\"checkbox\"\n value={checkboxValue}\n onChange={onCheckboxChange}\n label=\"Enable Feature\"\n description=\"Check to enable\"\n propertySchema={{ type: \"boolean\" }}\n schema={dummySchema}\n registry={DEFAULT_WIDGETS}\n />\n\n <pre className=\"text-[11px] bg-muted p-2 rounded overflow-x-auto\">\n <code>{JSON.stringify({ value: checkboxValue }, null, 2)}</code>\n </pre>\n </SimpleStack>\n </Card>\n\n {/* SelectWidget - All Variations */}\n <Card className=\"border shadow-sm p-4\">\n <SimpleStack gap=\"sm\">\n <h2>SelectWidget</h2>\n <p className=\"text-sm text-muted-foreground\">\n Dropdown select for enum values with single-select,\n multi-select, and custom badge colors\n </p>\n\n <div className=\"grid grid-cols-2 gap-3 pt-2\">\n <ExampleBlock label=\"Single select\">\n <SelectWidget\n id=\"select-demo\"\n name=\"select\"\n value={selectValue}\n onChange={onSelectChange}\n label=\"Select Status\"\n description=\"Choose a status\"\n placeholder=\"Select one...\"\n propertySchema={{\n type: \"string\",\n enum: [\"active\", \"inactive\", \"pending\", \"archived\"],\n }}\n schema={dummySchema}\n registry={DEFAULT_WIDGETS}\n options={{\n enumNames: {\n active: \"Active\",\n inactive: \"Inactive\",\n pending: \"Pending\",\n archived: \"Archived\",\n },\n searchable: true,\n clearable: true,\n }}\n />\n </ExampleBlock>\n <ExampleBlock label=\"Multi select\">\n <SelectWidget\n id=\"multiselect-demo\"\n name=\"multiselect\"\n value={multiSelectValue}\n onChange={onMultiSelectChange}\n label=\"Select Tags\"\n description=\"Choose multiple tags\"\n placeholder=\"Select tags...\"\n propertySchema={{\n type: \"array\",\n items: { type: \"string\" },\n enum: [\n \"frontend\",\n \"backend\",\n \"database\",\n \"devops\",\n \"testing\",\n \"security\",\n ],\n }}\n schema={dummySchema}\n registry={DEFAULT_WIDGETS}\n options={{ searchable: true, clearable: true }}\n />\n </ExampleBlock>\n <ExampleBlock label=\"Custom badge color\">\n <SelectWidget\n id=\"multiselect-color-demo\"\n name=\"multiselectColor\"\n value={multiSelectColorValue}\n onChange={onMultiSelectColorChange}\n label=\"Select Categories\"\n description=\"Custom grape-colored badges\"\n placeholder=\"Select categories...\"\n propertySchema={{\n type: \"array\",\n items: { type: \"string\" },\n enum: [\n \"feature\",\n \"bugfix\",\n \"enhancement\",\n \"documentation\",\n \"refactor\",\n ],\n }}\n schema={dummySchema}\n registry={DEFAULT_WIDGETS}\n options={{\n searchable: true,\n clearable: true,\n badgeColor: \"grape\",\n enumNames: {\n feature: \"Feature\",\n bugfix: \"Bug Fix\",\n enhancement: \"Enhancement\",\n documentation: \"Documentation\",\n refactor: \"Refactor\",\n },\n }}\n />\n </ExampleBlock>\n </div>\n </SimpleStack>\n </Card>\n\n {/* QuantityWidget */}\n <Card className=\"border shadow-sm p-4\">\n <SimpleStack gap=\"sm\">\n <h2>QuantityWidget</h2>\n <p className=\"text-sm text-muted-foreground\">\n Compound numeric value + unit selector. Multi-unit shows a\n dropdown, single-unit shows static text, prefix mode places the\n unit before the value.\n </p>\n\n <div className=\"grid grid-cols-2 gap-3 pt-2\">\n <ExampleBlock label=\"Multi-unit suffix (Temperature)\">\n <QuantityWidget\n id=\"quantity-temp\"\n name=\"temperature\"\n value={tempValue}\n onChange={onTempChange}\n label=\"Temperature\"\n description=\"Body temperature with per-unit validation\"\n placeholder=\"0.0\"\n propertySchema={{ type: \"object\" }}\n schema={dummySchema}\n registry={DEFAULT_WIDGETS}\n options={{\n precision: 1,\n units: [\n { value: \"degC\", label: \"C\", min: 35, max: 42 },\n { value: \"degF\", label: \"F\", min: 95, max: 108 },\n ],\n }}\n />\n </ExampleBlock>\n <ExampleBlock label=\"Single-unit suffix (Weight)\">\n <QuantityWidget\n id=\"quantity-weight\"\n name=\"weight\"\n value={weightValue}\n onChange={onWeightChange}\n label=\"Weight\"\n description=\"Single unit, global min/max from schema\"\n placeholder=\"0\"\n propertySchema={{\n type: \"object\",\n minimum: 0,\n maximum: 500,\n }}\n schema={dummySchema}\n registry={DEFAULT_WIDGETS}\n options={{\n precision: 1,\n units: [{ value: \"kg\", label: \"kg\" }],\n }}\n />\n </ExampleBlock>\n <ExampleBlock label=\"Integer mode (Heart Rate)\">\n <QuantityWidget\n id=\"quantity-hr\"\n name=\"heartRate\"\n value={bpValue}\n onChange={onBpChange}\n label=\"Heart Rate\"\n description=\"Integer with per-unit validation (30-250 bpm)\"\n placeholder=\"0\"\n propertySchema={{ type: \"object\" }}\n schema={dummySchema}\n registry={DEFAULT_WIDGETS}\n options={{\n precision: 0,\n units: [\n { value: \"bpm\", label: \"bpm\", min: 30, max: 250 },\n ],\n }}\n />\n </ExampleBlock>\n <ExampleBlock label=\"Multi-unit prefix (Currency)\">\n <QuantityWidget\n id=\"quantity-price\"\n name=\"price\"\n value={priceValue}\n onChange={onPriceChange}\n label=\"Price\"\n description=\"Currency symbol as prefix, multi-unit selector\"\n placeholder=\"0.00\"\n propertySchema={{ type: \"object\", minimum: 0 }}\n schema={dummySchema}\n registry={DEFAULT_WIDGETS}\n options={{\n precision: 2,\n unitPosition: \"prefix\",\n units: [\n { value: \"EUR\", label: \"EUR\" },\n { value: \"USD\", label: \"$\" },\n { value: \"GBP\", label: \"GBP\" },\n ],\n }}\n />\n </ExampleBlock>\n </div>\n </SimpleStack>\n </Card>\n </SimpleStack>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;AAKA;AAAA,EAGE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,aAAa,YAAY;AAElC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AA6FD,SACE,KADF;AA1FN,IAAM,cAA0B;AAAA,EAC9B,OAAO;AAAA,EACP,MAAM;AAAA,EACN,YAAY,CAAC;AAAA,EACb,YAAY;AAAA,IACV,MAAM;AAAA,IACN,OAAO;AAAA,IACP,WAAW,CAAC;AAAA,EACd;AACF;AAEA,SAAS,oBACP,KACsB;AACtB,SAAO,CAAC,MAAe;AACrB,QAAI,KAAK,QAAQ,OAAO,MAAM,YAAY,CAAC,MAAM,QAAQ,CAAC,GAAG;AAC3D,UAAI,CAAkB;AAAA,IACxB;AAAA,EACF;AACF;AAEe,SAAR,kBAAmC;AAExC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAiB,EAAE;AACrD,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAiB,EAAE;AAC7D,QAAM,CAAC,aAAa,cAAc,IAAI,SAA6B,MAAS;AAC5E,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAkB,KAAK;AACjE,QAAM,CAAC,aAAa,cAAc,IAAI,SAAiB,EAAE;AACzD,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAmB,CAAC,CAAC;AACrE,QAAM,CAAC,uBAAuB,wBAAwB,IAAI;AAAA,IACxD,CAAC;AAAA,EACH;AACA,QAAM,CAAC,WAAW,YAAY,IAAI,SAAwB;AAAA,IACxD,OAAO;AAAA,IACP,MAAM;AAAA,EACR,CAAC;AACD,QAAM,CAAC,aAAa,cAAc,IAAI,SAAwB;AAAA,IAC5D,OAAO;AAAA,IACP,MAAM;AAAA,EACR,CAAC;AACD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAwB;AAAA,IACpD,OAAO;AAAA,IACP,MAAM;AAAA,EACR,CAAC;AACD,QAAM,CAAC,YAAY,aAAa,IAAI,SAAwB;AAAA,IAC1D,OAAO;AAAA,IACP,MAAM;AAAA,EACR,CAAC;AAKD,QAAM,eAAe;AAAA,IACnB,CAAC,MAAe,aAAa,OAAO,MAAM,WAAW,IAAI,EAAE;AAAA,IAC3D,CAAC;AAAA,EACH;AACA,QAAM,mBAAmB;AAAA,IACvB,CAAC,MAAe,iBAAiB,OAAO,MAAM,WAAW,IAAI,EAAE;AAAA,IAC/D,CAAC;AAAA,EACH;AACA,QAAM,iBAAiB;AAAA,IACrB,CAAC,MAAe,eAAe,OAAO,MAAM,WAAW,IAAI,MAAS;AAAA,IACpE,CAAC;AAAA,EACH;AACA,QAAM,mBAAmB;AAAA,IACvB,CAAC,MAAe,iBAAiB,OAAO,MAAM,YAAY,IAAI,KAAK;AAAA,IACnE,CAAC;AAAA,EACH;AACA,QAAM,iBAAiB;AAAA,IACrB,CAAC,MAAe,eAAe,OAAO,MAAM,WAAW,IAAI,EAAE;AAAA,IAC7D,CAAC;AAAA,EACH;AACA,QAAM,sBAAsB;AAAA,IAC1B,CAAC,MACC,oBAAoB,MAAM,QAAQ,CAAC,IAAK,IAAiB,CAAC,CAAC;AAAA,IAC7D,CAAC;AAAA,EACH;AACA,QAAM,2BAA2B;AAAA,IAC/B,CAAC,MACC,yBAAyB,MAAM,QAAQ,CAAC,IAAK,IAAiB,CAAC,CAAC;AAAA,IAClE,CAAC;AAAA,EACH;AAEA,QAAM,eAAe,QAAQ,MAAM,oBAAoB,YAAY,GAAG,CAAC,CAAC;AACxE,QAAM,iBAAiB,QAAQ,MAAM,oBAAoB,cAAc,GAAG,CAAC,CAAC;AAC5E,QAAM,aAAa,QAAQ,MAAM,oBAAoB,UAAU,GAAG,CAAC,CAAC;AACpE,QAAM,gBAAgB,QAAQ,MAAM,oBAAoB,aAAa,GAAG,CAAC,CAAC;AAE1E,SACE,qBAAC,SAAI,WAAU,8BACb;AAAA,yBAAC,SACC;AAAA,0BAAC,QAAG,2CAA6B;AAAA,MACjC,oBAAC,OAAE,WAAU,sCAAqC,iEAElD;AAAA,OACF;AAAA,IAEA,oBAAC,SACC,+BAAC,eAAY,KAAI,MAAK,OAAO,EAAE,UAAU,QAAQ,GAE/C;AAAA,0BAAC,QAAK,WAAU,wBACd,+BAAC,eAAY,KAAI,MACf;AAAA,4BAAC,QAAG,6BAAe;AAAA,QACnB,oBAAC,OAAE,WAAU,iCAAgC,iHAG7C;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU;AAAA,YACV,OAAM;AAAA,YACN,aAAY;AAAA,YACZ,aAAY;AAAA,YACZ,gBAAgB,EAAE,MAAM,SAAS;AAAA,YACjC,QAAQ;AAAA,YACR,UAAU;AAAA;AAAA,QACZ;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU;AAAA,YACV,OAAM;AAAA,YACN,aAAY;AAAA,YACZ,aAAY;AAAA,YACZ,gBAAgB,EAAE,MAAM,UAAU,QAAQ,QAAQ;AAAA,YAClD,QAAQ;AAAA,YACR,UAAU;AAAA,YACV,SAAS,EAAE,WAAW,QAAQ;AAAA;AAAA,QAChC;AAAA,QAEA,oBAAC,SAAI,WAAU,oDACb,8BAAC,UAAM,eAAK,UAAU,EAAE,OAAO,UAAU,GAAG,MAAM,CAAC,GAAE,GACvD;AAAA,SACF,GACF;AAAA,MAGA,oBAAC,QAAK,WAAU,wBACd,+BAAC,eAAY,KAAI,MACf;AAAA,4BAAC,QAAG,4BAAc;AAAA,QAClB,oBAAC,OAAE,WAAU,iCAAgC,+EAG7C;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU;AAAA,YACV,OAAM;AAAA,YACN,aAAY;AAAA,YACZ,aAAY;AAAA,YACZ,gBAAgB,EAAE,MAAM,SAAS;AAAA,YACjC,QAAQ;AAAA,YACR,UAAU;AAAA,YACV,SAAS,EAAE,MAAM,EAAE;AAAA;AAAA,QACrB;AAAA,QAEA,oBAAC,SAAI,WAAU,oDACb,8BAAC,UAAM,eAAK,UAAU,EAAE,OAAO,cAAc,GAAG,MAAM,CAAC,GAAE,GAC3D;AAAA,SACF,GACF;AAAA,MAGA,oBAAC,QAAK,WAAU,wBACd,+BAAC,eAAY,KAAI,MACf;AAAA,4BAAC,QAAG,0BAAY;AAAA,QAChB,oBAAC,OAAE,WAAU,iCAAgC,0EAE7C;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU;AAAA,YACV,OAAM;AAAA,YACN,aAAY;AAAA,YACZ,aAAY;AAAA,YACZ,gBAAgB,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,IAAI;AAAA,YAC3D,QAAQ;AAAA,YACR,UAAU;AAAA,YACV,SAAS,EAAE,MAAM,EAAE;AAAA;AAAA,QACrB;AAAA,QAEA,oBAAC,SAAI,WAAU,oDACb,8BAAC,UAAM,eAAK,UAAU,EAAE,OAAO,YAAY,GAAG,MAAM,CAAC,GAAE,GACzD;AAAA,SACF,GACF;AAAA,MAGA,oBAAC,QAAK,WAAU,wBACd,+BAAC,eAAY,KAAI,MACf;AAAA,4BAAC,QAAG,4BAAc;AAAA,QAClB,oBAAC,OAAE,WAAU,iCAAgC,oDAE7C;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,MAAK;AAAA,YACL,OAAO;AAAA,YACP,UAAU;AAAA,YACV,OAAM;AAAA,YACN,aAAY;AAAA,YACZ,gBAAgB,EAAE,MAAM,UAAU;AAAA,YAClC,QAAQ;AAAA,YACR,UAAU;AAAA;AAAA,QACZ;AAAA,QAEA,oBAAC,SAAI,WAAU,oDACb,8BAAC,UAAM,eAAK,UAAU,EAAE,OAAO,cAAc,GAAG,MAAM,CAAC,GAAE,GAC3D;AAAA,SACF,GACF;AAAA,MAGA,oBAAC,QAAK,WAAU,wBACd,+BAAC,eAAY,KAAI,MACf;AAAA,4BAAC,QAAG,0BAAY;AAAA,QAChB,oBAAC,OAAE,WAAU,iCAAgC,uGAG7C;AAAA,QAEA,qBAAC,SAAI,WAAU,+BACb;AAAA,8BAAC,gBAAa,OAAM,iBAClB;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU;AAAA,cACV,OAAM;AAAA,cACN,aAAY;AAAA,cACZ,aAAY;AAAA,cACZ,gBAAgB;AAAA,gBACd,MAAM;AAAA,gBACN,MAAM,CAAC,UAAU,YAAY,WAAW,UAAU;AAAA,cACpD;AAAA,cACA,QAAQ;AAAA,cACR,UAAU;AAAA,cACV,SAAS;AAAA,gBACP,WAAW;AAAA,kBACT,QAAQ;AAAA,kBACR,UAAU;AAAA,kBACV,SAAS;AAAA,kBACT,UAAU;AAAA,gBACZ;AAAA,gBACA,YAAY;AAAA,gBACZ,WAAW;AAAA,cACb;AAAA;AAAA,UACF,GACF;AAAA,UACA,oBAAC,gBAAa,OAAM,gBAClB;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU;AAAA,cACV,OAAM;AAAA,cACN,aAAY;AAAA,cACZ,aAAY;AAAA,cACZ,gBAAgB;AAAA,gBACd,MAAM;AAAA,gBACN,OAAO,EAAE,MAAM,SAAS;AAAA,gBACxB,MAAM;AAAA,kBACJ;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF;AAAA,cACA,QAAQ;AAAA,cACR,UAAU;AAAA,cACV,SAAS,EAAE,YAAY,MAAM,WAAW,KAAK;AAAA;AAAA,UAC/C,GACF;AAAA,UACA,oBAAC,gBAAa,OAAM,sBAClB;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU;AAAA,cACV,OAAM;AAAA,cACN,aAAY;AAAA,cACZ,aAAY;AAAA,cACZ,gBAAgB;AAAA,gBACd,MAAM;AAAA,gBACN,OAAO,EAAE,MAAM,SAAS;AAAA,gBACxB,MAAM;AAAA,kBACJ;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF;AAAA,cACA,QAAQ;AAAA,cACR,UAAU;AAAA,cACV,SAAS;AAAA,gBACP,YAAY;AAAA,gBACZ,WAAW;AAAA,gBACX,YAAY;AAAA,gBACZ,WAAW;AAAA,kBACT,SAAS;AAAA,kBACT,QAAQ;AAAA,kBACR,aAAa;AAAA,kBACb,eAAe;AAAA,kBACf,UAAU;AAAA,gBACZ;AAAA,cACF;AAAA;AAAA,UACF,GACF;AAAA,WACF;AAAA,SACF,GACF;AAAA,MAGA,oBAAC,QAAK,WAAU,wBACd,+BAAC,eAAY,KAAI,MACf;AAAA,4BAAC,QAAG,4BAAc;AAAA,QAClB,oBAAC,OAAE,WAAU,iCAAgC,+JAI7C;AAAA,QAEA,qBAAC,SAAI,WAAU,+BACb;AAAA,8BAAC,gBAAa,OAAM,mCAClB;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU;AAAA,cACV,OAAM;AAAA,cACN,aAAY;AAAA,cACZ,aAAY;AAAA,cACZ,gBAAgB,EAAE,MAAM,SAAS;AAAA,cACjC,QAAQ;AAAA,cACR,UAAU;AAAA,cACV,SAAS;AAAA,gBACP,WAAW;AAAA,gBACX,OAAO;AAAA,kBACL,EAAE,OAAO,QAAQ,OAAO,KAAK,KAAK,IAAI,KAAK,GAAG;AAAA,kBAC9C,EAAE,OAAO,QAAQ,OAAO,KAAK,KAAK,IAAI,KAAK,IAAI;AAAA,gBACjD;AAAA,cACF;AAAA;AAAA,UACF,GACF;AAAA,UACA,oBAAC,gBAAa,OAAM,+BAClB;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU;AAAA,cACV,OAAM;AAAA,cACN,aAAY;AAAA,cACZ,aAAY;AAAA,cACZ,gBAAgB;AAAA,gBACd,MAAM;AAAA,gBACN,SAAS;AAAA,gBACT,SAAS;AAAA,cACX;AAAA,cACA,QAAQ;AAAA,cACR,UAAU;AAAA,cACV,SAAS;AAAA,gBACP,WAAW;AAAA,gBACX,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,KAAK,CAAC;AAAA,cACtC;AAAA;AAAA,UACF,GACF;AAAA,UACA,oBAAC,gBAAa,OAAM,6BAClB;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU;AAAA,cACV,OAAM;AAAA,cACN,aAAY;AAAA,cACZ,aAAY;AAAA,cACZ,gBAAgB,EAAE,MAAM,SAAS;AAAA,cACjC,QAAQ;AAAA,cACR,UAAU;AAAA,cACV,SAAS;AAAA,gBACP,WAAW;AAAA,gBACX,OAAO;AAAA,kBACL,EAAE,OAAO,OAAO,OAAO,OAAO,KAAK,IAAI,KAAK,IAAI;AAAA,gBAClD;AAAA,cACF;AAAA;AAAA,UACF,GACF;AAAA,UACA,oBAAC,gBAAa,OAAM,gCAClB;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU;AAAA,cACV,OAAM;AAAA,cACN,aAAY;AAAA,cACZ,aAAY;AAAA,cACZ,gBAAgB,EAAE,MAAM,UAAU,SAAS,EAAE;AAAA,cAC7C,QAAQ;AAAA,cACR,UAAU;AAAA,cACV,SAAS;AAAA,gBACP,WAAW;AAAA,gBACX,cAAc;AAAA,gBACd,OAAO;AAAA,kBACL,EAAE,OAAO,OAAO,OAAO,MAAM;AAAA,kBAC7B,EAAE,OAAO,OAAO,OAAO,IAAI;AAAA,kBAC3B,EAAE,OAAO,OAAO,OAAO,MAAM;AAAA,gBAC/B;AAAA,cACF;AAAA;AAAA,UACF,GACF;AAAA,WACF;AAAA,SACF,GACF;AAAA,OACF,GACF;AAAA,KACF;AAEJ;","names":[]}
@@ -60,12 +60,14 @@ function PlayJsonEditor() {
60
60
  setParseError(e.message);
61
61
  }
62
62
  };
63
- return /* @__PURE__ */ jsxs("div", { children: [
64
- /* @__PURE__ */ jsx("h1", { children: "JSON Editor" }),
65
- /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-6", children: "A constrained JSON editor with selectively editable regions using JSON Pointer (RFC 6901). Blue-tinted regions are readonly, white regions are editable." }),
63
+ return /* @__PURE__ */ jsxs("div", { className: "w-full max-w-4xl space-y-6", children: [
64
+ /* @__PURE__ */ jsxs("div", { children: [
65
+ /* @__PURE__ */ jsx("h1", { children: "JSON Editor" }),
66
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "A constrained JSON editor with selectively editable regions using JSON Pointer (RFC 6901). Blue-tinted regions are readonly, white regions are editable." })
67
+ ] }),
66
68
  /* @__PURE__ */ jsxs("div", { className: "grid gap-6 lg:grid-cols-[1fr_320px]", children: [
67
69
  /* @__PURE__ */ jsxs("div", { children: [
68
- /* @__PURE__ */ jsx("h3", { className: "mb-2", children: "Patient Schema" }),
70
+ /* @__PURE__ */ jsx("h4", { className: "mb-2", children: "Patient Schema" }),
69
71
  /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground mb-3", children: [
70
72
  "Editable paths:",
71
73
  " ",
@@ -84,7 +86,7 @@ function PlayJsonEditor() {
84
86
  !parseError && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-2", children: "Valid JSON" })
85
87
  ] }),
86
88
  /* @__PURE__ */ jsxs("div", { children: [
87
- /* @__PURE__ */ jsx("h3", { className: "mb-2", children: "Configuration" }),
89
+ /* @__PURE__ */ jsx("h4", { className: "mb-2", children: "Configuration" }),
88
90
  /* @__PURE__ */ jsxs("div", { className: "rounded-lg border p-4 space-y-3", children: [
89
91
  /* @__PURE__ */ jsxs("div", { children: [
90
92
  /* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-muted-foreground mb-1", children: "Editable Paths" }),
@@ -122,4 +124,4 @@ function PlayJsonEditor() {
122
124
  export {
123
125
  PlayJsonEditor
124
126
  };
125
- //# sourceMappingURL=chunk-KAT24CQQ.js.map
127
+ //# sourceMappingURL=chunk-FZ3ZC7VM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pages/PlayJsonEditor.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { JsonEditor } from \"@petrarca/sonnet-ui/json-editor\";\nimport { Separator } from \"@petrarca/sonnet-ui\";\n\nconst SAMPLE_SCHEMA = JSON.stringify(\n {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n $id: \"https://example.com/schemas/patient.json\",\n title: \"Patient\",\n type: \"object\",\n metadata: {\n version: \"1.0.0\",\n description: \"Core patient demographic record\",\n tags: [\"healthcare\", \"demographics\", \"mpi\"],\n owner: \"platform-team\",\n },\n properties: {\n patient_id: {\n type: \"string\",\n format: \"uuid\",\n description: \"Unique patient identifier\",\n },\n first_name: {\n type: \"string\",\n minLength: 1,\n maxLength: 100,\n },\n last_name: {\n type: \"string\",\n minLength: 1,\n maxLength: 100,\n },\n date_of_birth: {\n type: \"string\",\n format: \"date\",\n },\n gender: {\n type: \"string\",\n enum: [\"male\", \"female\", \"other\", \"unknown\"],\n },\n },\n required: [\"patient_id\", \"first_name\", \"last_name\"],\n },\n null,\n 2,\n);\n\nconst EDITABLE_PATHS = [\"/metadata\"];\n\n/**\n * Playground page for the JsonEditor component.\n *\n * Demonstrates a JSON Schema where only the /metadata section\n * is editable. The rest of the schema (properties, required, etc.)\n * is visible but locked.\n */\nexport default function PlayJsonEditor() {\n const [value, setValue] = useState(SAMPLE_SCHEMA);\n const [lastValid, setLastValid] = useState(SAMPLE_SCHEMA);\n const [parseError, setParseError] = useState<string | null>(null);\n\n const handleChange = (newValue: string) => {\n setValue(newValue);\n try {\n JSON.parse(newValue);\n setLastValid(newValue);\n setParseError(null);\n } catch (e) {\n setParseError((e as Error).message);\n }\n };\n\n return (\n <div className=\"w-full max-w-4xl space-y-6\">\n <div>\n <h1>JSON Editor</h1>\n <p className=\"text-sm text-muted-foreground mt-1\">\n A constrained JSON editor with selectively editable regions using JSON\n Pointer (RFC 6901). Blue-tinted regions are readonly, white regions\n are editable.\n </p>\n </div>\n\n <div className=\"grid gap-6 lg:grid-cols-[1fr_320px]\">\n <div>\n <h4 className=\"mb-2\">Patient Schema</h4>\n <p className=\"text-xs text-muted-foreground mb-3\">\n Editable paths:{\" \"}\n <code className=\"text-xs bg-muted px-1 py-0.5 rounded\">\n {EDITABLE_PATHS.join(\", \")}\n </code>\n </p>\n <JsonEditor\n value={value}\n editablePaths={EDITABLE_PATHS}\n onChange={handleChange}\n height=\"500px\"\n />\n {parseError && (\n <p className=\"text-xs text-destructive mt-2\">{parseError}</p>\n )}\n {!parseError && (\n <p className=\"text-xs text-muted-foreground mt-2\">Valid JSON</p>\n )}\n </div>\n\n <div>\n <h4 className=\"mb-2\">Configuration</h4>\n <div className=\"rounded-lg border p-4 space-y-3\">\n <div>\n <p className=\"text-xs font-medium text-muted-foreground mb-1\">\n Editable Paths\n </p>\n <ul className=\"space-y-1\">\n {EDITABLE_PATHS.map((p) => (\n <li key={p}>\n <code className=\"text-xs bg-muted px-1.5 py-0.5 rounded\">\n {p}\n </code>\n </li>\n ))}\n </ul>\n </div>\n\n <Separator />\n\n <div>\n <p className=\"text-xs font-medium text-muted-foreground mb-1\">\n How it works\n </p>\n <ul className=\"text-xs text-muted-foreground space-y-1\">\n <li>Blue-tinted background = readonly (locked)</li>\n <li>White background = editable</li>\n <li>\n You can add, edit, and delete lines within the editable region\n </li>\n <li>Changes outside editable regions are silently blocked</li>\n <li>JSON syntax is validated on every keystroke</li>\n </ul>\n </div>\n\n <Separator />\n\n <div>\n <p className=\"text-xs font-medium text-muted-foreground mb-1\">\n Parsed metadata\n </p>\n <pre className=\"text-xs bg-muted rounded p-2 overflow-auto max-h-48\">\n {(() => {\n try {\n const parsed = JSON.parse(lastValid);\n return JSON.stringify(parsed.metadata, null, 2);\n } catch {\n return \"Parse error\";\n }\n })()}\n </pre>\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}