@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
@@ -1,432 +0,0 @@
1
- // src/pages/PlayFormWidgets.tsx
2
- import { useCallback, useState } from "react";
3
- import { SimpleStack, Card } from "@petrarca/sonnet-ui";
4
- import {
5
- TextInputWidget,
6
- TextareaWidget,
7
- NumberWidget,
8
- CheckboxWidget,
9
- SelectWidget,
10
- QuantityWidget,
11
- DEFAULT_WIDGETS
12
- } from "@petrarca/sonnet-forms";
13
- import { jsx, jsxs } from "react/jsx-runtime";
14
- function PlayFormWidgets() {
15
- const [textValue, setTextValue] = useState("");
16
- const [textareaValue, setTextareaValue] = useState("");
17
- const [numberValue, setNumberValue] = useState(void 0);
18
- const [checkboxValue, setCheckboxValue] = useState(false);
19
- const [selectValue, setSelectValue] = useState("");
20
- const [multiSelectValue, setMultiSelectValue] = useState([]);
21
- const [multiSelectColorValue, setMultiSelectColorValue] = useState(
22
- []
23
- );
24
- const [tempValue, setTempValue] = useState({
25
- value: 37,
26
- unit: "degC"
27
- });
28
- const [weightValue, setWeightValue] = useState({
29
- value: void 0,
30
- unit: "kg"
31
- });
32
- const [bpValue, setBpValue] = useState({
33
- value: 72,
34
- unit: "bpm"
35
- });
36
- const [priceValue, setPriceValue] = useState({
37
- value: 49.99,
38
- unit: "EUR"
39
- });
40
- const onTextChange = useCallback(
41
- (v) => setTextValue(typeof v === "string" ? v : ""),
42
- []
43
- );
44
- const onTextareaChange = useCallback(
45
- (v) => setTextareaValue(typeof v === "string" ? v : ""),
46
- []
47
- );
48
- const onNumberChange = useCallback(
49
- (v) => setNumberValue(typeof v === "number" ? v : void 0),
50
- []
51
- );
52
- const onCheckboxChange = useCallback(
53
- (v) => setCheckboxValue(typeof v === "boolean" ? v : false),
54
- []
55
- );
56
- const onSelectChange = useCallback(
57
- (v) => setSelectValue(typeof v === "string" ? v : ""),
58
- []
59
- );
60
- const onMultiSelectChange = useCallback(
61
- (v) => setMultiSelectValue(Array.isArray(v) ? v : []),
62
- []
63
- );
64
- const onMultiSelectColorChange = useCallback(
65
- (v) => setMultiSelectColorValue(Array.isArray(v) ? v : []),
66
- []
67
- );
68
- const onTempChange = useCallback((v) => {
69
- if (v != null && typeof v === "object" && !Array.isArray(v)) {
70
- setTempValue(v);
71
- }
72
- }, []);
73
- const onWeightChange = useCallback((v) => {
74
- if (v != null && typeof v === "object" && !Array.isArray(v)) {
75
- setWeightValue(v);
76
- }
77
- }, []);
78
- const onBpChange = useCallback((v) => {
79
- if (v != null && typeof v === "object" && !Array.isArray(v)) {
80
- setBpValue(v);
81
- }
82
- }, []);
83
- const onPriceChange = useCallback((v) => {
84
- if (v != null && typeof v === "object" && !Array.isArray(v)) {
85
- setPriceValue(v);
86
- }
87
- }, []);
88
- const dummySchema = {
89
- title: "Form Widgets Demo",
90
- type: "object",
91
- properties: {},
92
- "x-entity": {
93
- type: "entity",
94
- label: "Demo",
95
- relations: []
96
- }
97
- };
98
- return /* @__PURE__ */ jsxs(
99
- "div",
100
- {
101
- style: {
102
- width: "100%",
103
- height: "100vh",
104
- display: "flex",
105
- flexDirection: "column",
106
- overflow: "hidden"
107
- },
108
- children: [
109
- /* @__PURE__ */ jsxs("div", { style: { padding: "1rem 1rem 0 1rem" }, children: [
110
- /* @__PURE__ */ jsx("h1", { children: "Basic Form Widgets Playground" }),
111
- /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-3", children: "Interactive demonstration of all basic form widgets" })
112
- ] }),
113
- /* @__PURE__ */ jsx("div", { style: { flex: 1, overflow: "auto", padding: "0 1rem 1rem 1rem" }, children: /* @__PURE__ */ jsxs(SimpleStack, { gap: "md", style: { maxWidth: "900px" }, children: [
114
- /* @__PURE__ */ jsx(Card, { className: "border shadow-sm p-4", children: /* @__PURE__ */ jsxs(SimpleStack, { gap: "sm", children: [
115
- /* @__PURE__ */ jsx("p", { className: "text-lg font-semibold", children: "TextInputWidget" }),
116
- /* @__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.)" }),
117
- /* @__PURE__ */ jsx(
118
- TextInputWidget,
119
- {
120
- id: "text-input-demo",
121
- name: "textInput",
122
- value: textValue,
123
- onChange: onTextChange,
124
- label: "Text Input",
125
- description: "Enter some text",
126
- placeholder: "Type here...",
127
- propertySchema: { type: "string" },
128
- schema: dummySchema,
129
- registry: DEFAULT_WIDGETS
130
- }
131
- ),
132
- /* @__PURE__ */ jsx(
133
- TextInputWidget,
134
- {
135
- id: "text-input-email",
136
- name: "emailInput",
137
- value: textValue,
138
- onChange: onTextChange,
139
- label: "Email Input",
140
- description: "Input type: email",
141
- placeholder: "user@example.com",
142
- propertySchema: { type: "string", format: "email" },
143
- schema: dummySchema,
144
- registry: DEFAULT_WIDGETS,
145
- options: { inputType: "email" }
146
- }
147
- ),
148
- /* @__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) }) })
149
- ] }) }),
150
- /* @__PURE__ */ jsx(Card, { className: "border shadow-sm p-4", children: /* @__PURE__ */ jsxs(SimpleStack, { gap: "sm", children: [
151
- /* @__PURE__ */ jsx("p", { className: "text-lg font-semibold", children: "TextareaWidget" }),
152
- /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Multi-line text input with configurable rows and autosize support" }),
153
- /* @__PURE__ */ jsx(
154
- TextareaWidget,
155
- {
156
- id: "textarea-demo",
157
- name: "textarea",
158
- value: textareaValue,
159
- onChange: onTextareaChange,
160
- label: "Textarea",
161
- description: "Enter multiple lines",
162
- placeholder: "Type here...",
163
- propertySchema: { type: "string" },
164
- schema: dummySchema,
165
- registry: DEFAULT_WIDGETS,
166
- options: { rows: 4 }
167
- }
168
- ),
169
- /* @__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) }) })
170
- ] }) }),
171
- /* @__PURE__ */ jsx(Card, { className: "border shadow-sm p-4", children: /* @__PURE__ */ jsxs(SimpleStack, { gap: "sm", children: [
172
- /* @__PURE__ */ jsx("p", { className: "text-lg font-semibold", children: "NumberWidget" }),
173
- /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Number input with support for min, max, and step constraints" }),
174
- /* @__PURE__ */ jsx(
175
- NumberWidget,
176
- {
177
- id: "number-demo",
178
- name: "number",
179
- value: numberValue,
180
- onChange: onNumberChange,
181
- label: "Number Input",
182
- description: "Enter a number (0-100, step: 5)",
183
- placeholder: "0",
184
- propertySchema: { type: "number", minimum: 0, maximum: 100 },
185
- schema: dummySchema,
186
- registry: DEFAULT_WIDGETS,
187
- options: { step: 5 }
188
- }
189
- ),
190
- /* @__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) }) })
191
- ] }) }),
192
- /* @__PURE__ */ jsx(Card, { className: "border shadow-sm p-4", children: /* @__PURE__ */ jsxs(SimpleStack, { gap: "sm", children: [
193
- /* @__PURE__ */ jsx("p", { className: "text-lg font-semibold", children: "CheckboxWidget" }),
194
- /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Boolean checkbox for true/false values" }),
195
- /* @__PURE__ */ jsx(
196
- CheckboxWidget,
197
- {
198
- id: "checkbox-demo",
199
- name: "checkbox",
200
- value: checkboxValue,
201
- onChange: onCheckboxChange,
202
- label: "Enable Feature",
203
- description: "Check to enable",
204
- propertySchema: { type: "boolean" },
205
- schema: dummySchema,
206
- registry: DEFAULT_WIDGETS
207
- }
208
- ),
209
- /* @__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) }) })
210
- ] }) }),
211
- /* @__PURE__ */ jsx(Card, { className: "border shadow-sm p-4", children: /* @__PURE__ */ jsxs(SimpleStack, { gap: "sm", children: [
212
- /* @__PURE__ */ jsx("p", { className: "text-lg font-semibold", children: "SelectWidget" }),
213
- /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Dropdown select for enum values with single-select, multi-select, and custom badge colors" }),
214
- /* @__PURE__ */ jsxs("div", { children: [
215
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium mb-1", children: "Single Select" }),
216
- /* @__PURE__ */ jsx(
217
- SelectWidget,
218
- {
219
- id: "select-demo",
220
- name: "select",
221
- value: selectValue,
222
- onChange: onSelectChange,
223
- label: "Select Status",
224
- description: "Choose a status",
225
- placeholder: "Select one...",
226
- propertySchema: {
227
- type: "string",
228
- enum: ["active", "inactive", "pending", "archived"]
229
- },
230
- schema: dummySchema,
231
- registry: DEFAULT_WIDGETS,
232
- options: {
233
- enumNames: {
234
- active: "Active",
235
- inactive: "Inactive",
236
- pending: "Pending",
237
- archived: "Archived"
238
- },
239
- searchable: true,
240
- clearable: true
241
- }
242
- }
243
- ),
244
- /* @__PURE__ */ jsx("pre", { className: "text-[11px] bg-muted p-2 rounded overflow-x-auto mt-2", children: /* @__PURE__ */ jsx("code", { children: JSON.stringify({ value: selectValue }, null, 2) }) })
245
- ] }),
246
- /* @__PURE__ */ jsxs("div", { children: [
247
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium mb-1", children: "Multi Select (auto-enabled when type is 'array')" }),
248
- /* @__PURE__ */ jsx(
249
- SelectWidget,
250
- {
251
- id: "multiselect-demo",
252
- name: "multiselect",
253
- value: multiSelectValue,
254
- onChange: onMultiSelectChange,
255
- label: "Select Tags",
256
- description: "Choose multiple tags",
257
- placeholder: "Select tags...",
258
- propertySchema: {
259
- type: "array",
260
- items: { type: "string" },
261
- enum: [
262
- "frontend",
263
- "backend",
264
- "database",
265
- "devops",
266
- "testing",
267
- "security"
268
- ]
269
- },
270
- schema: dummySchema,
271
- registry: DEFAULT_WIDGETS,
272
- options: { searchable: true, clearable: true }
273
- }
274
- ),
275
- /* @__PURE__ */ jsx("pre", { className: "text-[11px] bg-muted p-2 rounded overflow-x-auto mt-2", children: /* @__PURE__ */ jsx("code", { children: JSON.stringify({ value: multiSelectValue }, null, 2) }) })
276
- ] }),
277
- /* @__PURE__ */ jsxs("div", { children: [
278
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium mb-1", children: "Multi Select with Custom Badge Color" }),
279
- /* @__PURE__ */ jsx(
280
- SelectWidget,
281
- {
282
- id: "multiselect-color-demo",
283
- name: "multiselectColor",
284
- value: multiSelectColorValue,
285
- onChange: onMultiSelectColorChange,
286
- label: "Select Categories",
287
- description: "Custom grape-colored badges",
288
- placeholder: "Select categories...",
289
- propertySchema: {
290
- type: "array",
291
- items: { type: "string" },
292
- enum: [
293
- "feature",
294
- "bugfix",
295
- "enhancement",
296
- "documentation",
297
- "refactor"
298
- ]
299
- },
300
- schema: dummySchema,
301
- registry: DEFAULT_WIDGETS,
302
- options: {
303
- searchable: true,
304
- clearable: true,
305
- badgeColor: "grape",
306
- enumNames: {
307
- feature: "Feature",
308
- bugfix: "Bug Fix",
309
- enhancement: "Enhancement",
310
- documentation: "Documentation",
311
- refactor: "Refactor"
312
- }
313
- }
314
- }
315
- ),
316
- /* @__PURE__ */ jsx("pre", { className: "text-[11px] bg-muted p-2 rounded overflow-x-auto mt-2", children: /* @__PURE__ */ jsx("code", { children: JSON.stringify({ value: multiSelectColorValue }, null, 2) }) })
317
- ] })
318
- ] }) }),
319
- /* @__PURE__ */ jsx(Card, { className: "border shadow-sm p-4", children: /* @__PURE__ */ jsxs(SimpleStack, { gap: "sm", children: [
320
- /* @__PURE__ */ jsx("p", { className: "text-lg font-semibold", children: "QuantityWidget" }),
321
- /* @__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." }),
322
- /* @__PURE__ */ jsxs("div", { children: [
323
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium mb-1", children: "Multi-unit suffix (Temperature)" }),
324
- /* @__PURE__ */ jsx(
325
- QuantityWidget,
326
- {
327
- id: "quantity-temp",
328
- name: "temperature",
329
- value: tempValue,
330
- onChange: onTempChange,
331
- label: "Temperature",
332
- description: "Body temperature with per-unit validation",
333
- placeholder: "0.0",
334
- propertySchema: { type: "object" },
335
- schema: dummySchema,
336
- registry: DEFAULT_WIDGETS,
337
- options: {
338
- precision: 1,
339
- units: [
340
- { value: "degC", label: "C", min: 35, max: 42 },
341
- { value: "degF", label: "F", min: 95, max: 108 }
342
- ]
343
- }
344
- }
345
- ),
346
- /* @__PURE__ */ jsx("pre", { className: "text-[11px] bg-muted p-2 rounded overflow-x-auto mt-2", children: /* @__PURE__ */ jsx("code", { children: JSON.stringify(tempValue, null, 2) }) })
347
- ] }),
348
- /* @__PURE__ */ jsxs("div", { children: [
349
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium mb-1", children: "Single-unit suffix (Weight) -- unit shown as static text" }),
350
- /* @__PURE__ */ jsx(
351
- QuantityWidget,
352
- {
353
- id: "quantity-weight",
354
- name: "weight",
355
- value: weightValue,
356
- onChange: onWeightChange,
357
- label: "Weight",
358
- description: "Single unit, global min/max from schema",
359
- placeholder: "0",
360
- propertySchema: { type: "object", minimum: 0, maximum: 500 },
361
- schema: dummySchema,
362
- registry: DEFAULT_WIDGETS,
363
- options: {
364
- precision: 1,
365
- units: [{ value: "kg", label: "kg" }]
366
- }
367
- }
368
- ),
369
- /* @__PURE__ */ jsx("pre", { className: "text-[11px] bg-muted p-2 rounded overflow-x-auto mt-2", children: /* @__PURE__ */ jsx("code", { children: JSON.stringify(weightValue, null, 2) }) })
370
- ] }),
371
- /* @__PURE__ */ jsxs("div", { children: [
372
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium mb-1", children: "Integer mode (Heart Rate)" }),
373
- /* @__PURE__ */ jsx(
374
- QuantityWidget,
375
- {
376
- id: "quantity-hr",
377
- name: "heartRate",
378
- value: bpValue,
379
- onChange: onBpChange,
380
- label: "Heart Rate",
381
- description: "Integer with per-unit validation (30-250 bpm)",
382
- placeholder: "0",
383
- propertySchema: { type: "object" },
384
- schema: dummySchema,
385
- registry: DEFAULT_WIDGETS,
386
- options: {
387
- precision: 0,
388
- units: [{ value: "bpm", label: "bpm", min: 30, max: 250 }]
389
- }
390
- }
391
- ),
392
- /* @__PURE__ */ jsx("pre", { className: "text-[11px] bg-muted p-2 rounded overflow-x-auto mt-2", children: /* @__PURE__ */ jsx("code", { children: JSON.stringify(bpValue, null, 2) }) })
393
- ] }),
394
- /* @__PURE__ */ jsxs("div", { children: [
395
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium mb-1", children: "Multi-unit prefix (Currency) -- unit before the value" }),
396
- /* @__PURE__ */ jsx(
397
- QuantityWidget,
398
- {
399
- id: "quantity-price",
400
- name: "price",
401
- value: priceValue,
402
- onChange: onPriceChange,
403
- label: "Price",
404
- description: "Currency symbol as prefix, multi-unit selector",
405
- placeholder: "0.00",
406
- propertySchema: { type: "object", minimum: 0 },
407
- schema: dummySchema,
408
- registry: DEFAULT_WIDGETS,
409
- options: {
410
- precision: 2,
411
- unitPosition: "prefix",
412
- units: [
413
- { value: "EUR", label: "EUR" },
414
- { value: "USD", label: "$" },
415
- { value: "GBP", label: "GBP" }
416
- ]
417
- }
418
- }
419
- ),
420
- /* @__PURE__ */ jsx("pre", { className: "text-[11px] bg-muted p-2 rounded overflow-x-auto mt-2", children: /* @__PURE__ */ jsx("code", { children: JSON.stringify(priceValue, null, 2) }) })
421
- ] })
422
- ] }) })
423
- ] }) })
424
- ]
425
- }
426
- );
427
- }
428
-
429
- export {
430
- PlayFormWidgets
431
- };
432
- //# sourceMappingURL=chunk-P7I5IDXA.js.map
@@ -1 +0,0 @@
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 { useCallback, useState } from \"react\";\nimport { SimpleStack, Card } from \"@petrarca/sonnet-ui\";\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\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 // H3: Quantity onChange adapters use the functional updater form so the\n // setter itself is stable (no state value in closure, no dep array entry).\n // QuantityWidget always passes a QuantityValue; the guard ensures type safety\n // without capturing the previous state value.\n const onTempChange = useCallback((v: unknown) => {\n if (v != null && typeof v === \"object\" && !Array.isArray(v)) {\n setTempValue(v as QuantityValue);\n }\n }, []);\n const onWeightChange = useCallback((v: unknown) => {\n if (v != null && typeof v === \"object\" && !Array.isArray(v)) {\n setWeightValue(v as QuantityValue);\n }\n }, []);\n const onBpChange = useCallback((v: unknown) => {\n if (v != null && typeof v === \"object\" && !Array.isArray(v)) {\n setBpValue(v as QuantityValue);\n }\n }, []);\n const onPriceChange = useCallback((v: unknown) => {\n if (v != null && typeof v === \"object\" && !Array.isArray(v)) {\n setPriceValue(v as QuantityValue);\n }\n }, []);\n\n // Dummy schema for widgets\n const 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\n return (\n <div\n style={{\n width: \"100%\",\n height: \"100vh\",\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n }}\n >\n <div style={{ padding: \"1rem 1rem 0 1rem\" }}>\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 style={{ flex: 1, overflow: \"auto\", padding: \"0 1rem 1rem 1rem\" }}>\n <SimpleStack gap=\"md\" style={{ maxWidth: \"900px\" }}>\n {/* TextInputWidget */}\n <Card className=\"border shadow-sm p-4\">\n <SimpleStack gap=\"sm\">\n <p className=\"text-lg font-semibold\">TextInputWidget</p>\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 <p className=\"text-lg font-semibold\">TextareaWidget</p>\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 <p className=\"text-lg font-semibold\">NumberWidget</p>\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 <p className=\"text-lg font-semibold\">CheckboxWidget</p>\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 <p className=\"text-lg font-semibold\">SelectWidget</p>\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 {/* Single Select */}\n <div>\n <p className=\"text-sm font-medium mb-1\">Single Select</p>\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 <pre className=\"text-[11px] bg-muted p-2 rounded overflow-x-auto mt-2\">\n <code>{JSON.stringify({ value: selectValue }, null, 2)}</code>\n </pre>\n </div>\n\n {/* Multi Select */}\n <div>\n <p className=\"text-sm font-medium mb-1\">\n Multi Select (auto-enabled when type is 'array')\n </p>\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 <pre className=\"text-[11px] bg-muted p-2 rounded overflow-x-auto mt-2\">\n <code>\n {JSON.stringify({ value: multiSelectValue }, null, 2)}\n </code>\n </pre>\n </div>\n\n {/* Multi Select with Badge Color */}\n <div>\n <p className=\"text-sm font-medium mb-1\">\n Multi Select with Custom Badge Color\n </p>\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 <pre className=\"text-[11px] bg-muted p-2 rounded overflow-x-auto mt-2\">\n <code>\n {JSON.stringify({ value: multiSelectColorValue }, null, 2)}\n </code>\n </pre>\n </div>\n </SimpleStack>\n </Card>\n\n {/* QuantityWidget */}\n <Card className=\"border shadow-sm p-4\">\n <SimpleStack gap=\"sm\">\n <p className=\"text-lg font-semibold\">QuantityWidget</p>\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 {/* Multi-unit suffix: Temperature */}\n <div>\n <p className=\"text-sm font-medium mb-1\">\n Multi-unit suffix (Temperature)\n </p>\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 <pre className=\"text-[11px] bg-muted p-2 rounded overflow-x-auto mt-2\">\n <code>{JSON.stringify(tempValue, null, 2)}</code>\n </pre>\n </div>\n\n {/* Single-unit suffix: Weight */}\n <div>\n <p className=\"text-sm font-medium mb-1\">\n Single-unit suffix (Weight) -- unit shown as static text\n </p>\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={{ type: \"object\", minimum: 0, maximum: 500 }}\n schema={dummySchema}\n registry={DEFAULT_WIDGETS}\n options={{\n precision: 1,\n units: [{ value: \"kg\", label: \"kg\" }],\n }}\n />\n <pre className=\"text-[11px] bg-muted p-2 rounded overflow-x-auto mt-2\">\n <code>{JSON.stringify(weightValue, null, 2)}</code>\n </pre>\n </div>\n\n {/* Single-unit suffix: Heart rate (integer) */}\n <div>\n <p className=\"text-sm font-medium mb-1\">\n Integer mode (Heart Rate)\n </p>\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: [{ value: \"bpm\", label: \"bpm\", min: 30, max: 250 }],\n }}\n />\n <pre className=\"text-[11px] bg-muted p-2 rounded overflow-x-auto mt-2\">\n <code>{JSON.stringify(bpValue, null, 2)}</code>\n </pre>\n </div>\n\n {/* Multi-unit prefix: Currency */}\n <div>\n <p className=\"text-sm font-medium mb-1\">\n Multi-unit prefix (Currency) -- unit before the value\n </p>\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 <pre className=\"text-[11px] bg-muted p-2 rounded overflow-x-auto mt-2\">\n <code>{JSON.stringify(priceValue, null, 2)}</code>\n </pre>\n </div>\n </SimpleStack>\n </Card>\n </SimpleStack>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/pages/PlayGraph.tsx"],"sourcesContent":["/**\n * Playground page for @petrarca/sonnet-graph.\n * Accessible at /playground/graph\n *\n * Demonstrates graph visualization with static mock data -- no backend required.\n * Uses the GraphStoresContext provider pattern that consumers like explorer\n * and Atlas would use to wire their own stores.\n */\n\nimport React, { useCallback, useState } from \"react\";\nimport {\n GraphVisualizer,\n ActionPanel,\n GraphRendererProvider,\n GraphStoresContext,\n createGraphDataStore,\n createGraphFilterStore,\n createGraphExplorationStore,\n createSelectionStore,\n createGraphFocusStore,\n enrichNodes,\n enrichEdges,\n buildColorPalette,\n type RawGraphNode,\n type RawGraphEdge,\n type WorkspaceStores,\n} from \"@petrarca/sonnet-graph\";\nimport {\n Button,\n Alert,\n AlertDescription,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from \"@petrarca/sonnet-ui\";\nimport { Play, RotateCcw } from \"lucide-react\";\nimport { PlaygroundSection } from \"../PlaygroundSection\";\n\n// ---------------------------------------------------------------------------\n// Mock data -- a small org hierarchy\n// ---------------------------------------------------------------------------\n\nconst MOCK_NODES: RawGraphNode[] = [\n {\n id_: 1,\n label_: \"Company\",\n properties_: { name: \"Acme Corp\", founded: 1985, industry: \"Technology\" },\n },\n {\n id_: 2,\n label_: \"Department\",\n properties_: { name: \"Engineering\", headcount: 42 },\n },\n {\n id_: 3,\n label_: \"Department\",\n properties_: { name: \"Marketing\", headcount: 18 },\n },\n {\n id_: 4,\n label_: \"Department\",\n properties_: { name: \"Sales\", headcount: 25 },\n },\n {\n id_: 5,\n label_: \"Person\",\n properties_: { name: \"Alice Chen\", role: \"CTO\" },\n },\n {\n id_: 6,\n label_: \"Person\",\n properties_: { name: \"Bob Smith\", role: \"VP Engineering\" },\n },\n {\n id_: 7,\n label_: \"Person\",\n properties_: { name: \"Carol Davis\", role: \"CMO\" },\n },\n {\n id_: 8,\n label_: \"Person\",\n properties_: { name: \"Dave Wilson\", role: \"VP Sales\" },\n },\n {\n id_: 9,\n label_: \"Person\",\n properties_: { name: \"Eve Johnson\", role: \"Senior Engineer\" },\n },\n {\n id_: 10,\n label_: \"Person\",\n properties_: { name: \"Frank Brown\", role: \"Product Manager\" },\n },\n {\n id_: 11,\n label_: \"Product\",\n properties_: { name: \"CloudSuite\", version: \"3.2\", status: \"GA\" },\n },\n {\n id_: 12,\n label_: \"Product\",\n properties_: { name: \"DataPipeline\", version: \"1.0\", status: \"Beta\" },\n },\n];\n\nconst MOCK_EDGES: RawGraphEdge[] = [\n {\n id_: 101,\n label_: \"HAS_DEPARTMENT\",\n start_id_: 1,\n end_id_: 2,\n properties_: {},\n },\n {\n id_: 102,\n label_: \"HAS_DEPARTMENT\",\n start_id_: 1,\n end_id_: 3,\n properties_: {},\n },\n {\n id_: 103,\n label_: \"HAS_DEPARTMENT\",\n start_id_: 1,\n end_id_: 4,\n properties_: {},\n },\n {\n id_: 104,\n label_: \"LEADS\",\n start_id_: 5,\n end_id_: 2,\n properties_: { since: 2019 },\n },\n {\n id_: 105,\n label_: \"WORKS_IN\",\n start_id_: 6,\n end_id_: 2,\n properties_: { since: 2020 },\n },\n {\n id_: 106,\n label_: \"LEADS\",\n start_id_: 7,\n end_id_: 3,\n properties_: { since: 2021 },\n },\n {\n id_: 107,\n label_: \"LEADS\",\n start_id_: 8,\n end_id_: 4,\n properties_: { since: 2018 },\n },\n {\n id_: 108,\n label_: \"WORKS_IN\",\n start_id_: 9,\n end_id_: 2,\n properties_: { since: 2022 },\n },\n {\n id_: 109,\n label_: \"WORKS_IN\",\n start_id_: 10,\n end_id_: 2,\n properties_: { since: 2021 },\n },\n { id_: 110, label_: \"REPORTS_TO\", start_id_: 6, end_id_: 5, properties_: {} },\n { id_: 111, label_: \"REPORTS_TO\", start_id_: 9, end_id_: 6, properties_: {} },\n {\n id_: 112,\n label_: \"REPORTS_TO\",\n start_id_: 10,\n end_id_: 6,\n properties_: {},\n },\n { id_: 113, label_: \"OWNS\", start_id_: 2, end_id_: 11, properties_: {} },\n { id_: 114, label_: \"OWNS\", start_id_: 2, end_id_: 12, properties_: {} },\n];\n\n// ---------------------------------------------------------------------------\n// Store setup\n//\n// Stores are created once at module load, not inside the component.\n// This avoids re-creation on re-render and removes the need for useMemo.\n// ---------------------------------------------------------------------------\n\nfunction createPlaygroundStores(): WorkspaceStores {\n const graphFilter = createGraphFilterStore();\n const graphData = createGraphDataStore();\n const selection = createSelectionStore();\n const graphFocus = createGraphFocusStore();\n const graphExploration = createGraphExplorationStore({\n graphData,\n selection,\n graphFocus,\n graphFilter,\n // Static data -- no server expansion available in the playground\n expandNode: async () => ({ nodes: [], edges: [] }),\n getNodes: async () => [],\n });\n return { graphFilter, graphData, graphExploration, selection };\n}\n\nconst PLAYGROUND_STORES = createPlaygroundStores();\n\n// ---------------------------------------------------------------------------\n// Data helpers\n// ---------------------------------------------------------------------------\n\ninterface GraphInput {\n nodes: RawGraphNode[];\n edges: RawGraphEdge[];\n}\n\nconst INITIAL_DATA: GraphInput = { nodes: MOCK_NODES, edges: MOCK_EDGES };\n\nfunction serializeGraphData(data: GraphInput): string {\n return JSON.stringify(data, null, 2);\n}\n\nfunction validateNode(n: unknown, i: number): string | null {\n if (!n || typeof n !== \"object\") return `nodes[${i}] must be an object`;\n const node = n as Record<string, unknown>;\n if (node.id_ === undefined) return `nodes[${i}] is missing id_`;\n if (typeof node.label_ !== \"string\") return `nodes[${i}] is missing label_`;\n return null;\n}\n\nfunction validateEdge(e: unknown, i: number): string | null {\n if (!e || typeof e !== \"object\") return `edges[${i}] must be an object`;\n const edge = e as Record<string, unknown>;\n if (edge.id_ === undefined) return `edges[${i}] is missing id_`;\n if (typeof edge.label_ !== \"string\") return `edges[${i}] is missing label_`;\n if (edge.start_id_ === undefined) return `edges[${i}] is missing start_id_`;\n if (edge.end_id_ === undefined) return `edges[${i}] is missing end_id_`;\n return null;\n}\n\n/** Validates that parsed JSON is a usable GraphInput. Returns an error string or null. */\nfunction validateGraphInput(value: unknown): string | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return \"JSON must be an object with nodes and edges arrays\";\n }\n const obj = value as Record<string, unknown>;\n if (!Array.isArray(obj.nodes)) return '\"nodes\" must be an array';\n if (!Array.isArray(obj.edges)) return '\"edges\" must be an array';\n for (const [i, n] of (obj.nodes as unknown[]).entries()) {\n const err = validateNode(n, i);\n if (err) return err;\n }\n for (const [i, e] of (obj.edges as unknown[]).entries()) {\n const err = validateEdge(e, i);\n if (err) return err;\n }\n return null;\n}\n\nfunction loadIntoStore(stores: WorkspaceStores, data: GraphInput) {\n const labelCounts: Record<string, number> = {};\n for (const n of data.nodes) {\n labelCounts[n.label_] = (labelCounts[n.label_] ?? 0) + 1;\n }\n const palette = buildColorPalette(labelCounts);\n const nodes = enrichNodes(data.nodes, palette);\n const edges = enrichEdges(data.edges, palette);\n stores.graphFilter.getState().resetFilters();\n stores.graphData.getState().setQueryData(nodes, edges, {\n nodes: nodes.length,\n edges: edges.length,\n });\n // Signal renderers to re-fit layout after data change\n stores.graphFilter.getState().notifyDataChange();\n}\n\n// Load initial data immediately -- no effect needed, no empty render cycle\nloadIntoStore(PLAYGROUND_STORES, INITIAL_DATA);\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport default function PlayGraph(): React.ReactElement {\n const [jsonText, setJsonText] = useState(() =>\n serializeGraphData(INITIAL_DATA),\n );\n const [parseError, setParseError] = useState<string | null>(null);\n\n const handleApply = useCallback(() => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(jsonText);\n } catch (e) {\n setParseError(e instanceof Error ? e.message : \"Invalid JSON\");\n return;\n }\n const validationError = validateGraphInput(parsed);\n if (validationError) {\n setParseError(validationError);\n return;\n }\n setParseError(null);\n loadIntoStore(PLAYGROUND_STORES, parsed as GraphInput);\n }, [jsonText]);\n\n const handleReset = useCallback(() => {\n setJsonText(serializeGraphData(INITIAL_DATA));\n setParseError(null);\n loadIntoStore(PLAYGROUND_STORES, INITIAL_DATA);\n }, []);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === \"Enter\") {\n e.preventDefault();\n handleApply();\n }\n },\n [handleApply],\n );\n\n return (\n <PlaygroundSection\n title=\"Graph Visualization\"\n description=\"Interactive property graph with dual renderer support. Edit the JSON data and apply to re-render.\"\n >\n <GraphStoresContext.Provider value={PLAYGROUND_STORES}>\n <Tabs defaultValue=\"graph\" className=\"space-y-3\">\n <TabsList>\n <TabsTrigger value=\"graph\">Graph</TabsTrigger>\n <TabsTrigger value=\"data\">Data</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"graph\" className=\"mt-0\">\n <GraphRendererProvider defaultRenderer=\"cytoscape\">\n <div className=\"flex border rounded-lg overflow-hidden h-[600px]\">\n <div className=\"flex-1 min-w-0\">\n <GraphVisualizer />\n </div>\n <div className=\"w-[300px] flex-shrink-0 border-l\">\n <ActionPanel />\n </div>\n </div>\n </GraphRendererProvider>\n </TabsContent>\n\n <TabsContent value=\"data\" className=\"mt-0\">\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <Button size=\"sm\" onClick={handleApply}>\n <Play className=\"h-4 w-4 mr-1\" />\n Apply\n </Button>\n <Button size=\"sm\" variant=\"outline\" onClick={handleReset}>\n <RotateCcw className=\"h-4 w-4 mr-1\" />\n Reset\n </Button>\n <span className=\"text-xs text-muted-foreground ml-2\">\n Cmd+Enter to apply\n </span>\n </div>\n {parseError && (\n <Alert variant=\"destructive\">\n <AlertDescription>{parseError}</AlertDescription>\n </Alert>\n )}\n <textarea\n value={jsonText}\n onChange={(e) => setJsonText(e.target.value)}\n onKeyDown={handleKeyDown}\n spellCheck={false}\n className=\"w-full h-[600px] font-mono text-xs p-3 border rounded-lg bg-muted/30 resize-y focus:outline-none focus:ring-2 focus:ring-ring\"\n />\n </div>\n </TabsContent>\n </Tabs>\n </GraphStoresContext.Provider>\n </PlaygroundSection>\n );\n}\n"],"mappings":";;;;;AASA,SAAgB,aAAa,gBAAgB;AAC7C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,MAAM,iBAAiB;AAuStB,SACE,KADF;AAhSV,IAAM,aAA6B;AAAA,EACjC;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,aAAa,EAAE,MAAM,aAAa,SAAS,MAAM,UAAU,aAAa;AAAA,EAC1E;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,aAAa,EAAE,MAAM,eAAe,WAAW,GAAG;AAAA,EACpD;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,aAAa,EAAE,MAAM,aAAa,WAAW,GAAG;AAAA,EAClD;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,aAAa,EAAE,MAAM,SAAS,WAAW,GAAG;AAAA,EAC9C;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,aAAa,EAAE,MAAM,cAAc,MAAM,MAAM;AAAA,EACjD;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,aAAa,EAAE,MAAM,aAAa,MAAM,iBAAiB;AAAA,EAC3D;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,aAAa,EAAE,MAAM,eAAe,MAAM,MAAM;AAAA,EAClD;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,aAAa,EAAE,MAAM,eAAe,MAAM,WAAW;AAAA,EACvD;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,aAAa,EAAE,MAAM,eAAe,MAAM,kBAAkB;AAAA,EAC9D;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,aAAa,EAAE,MAAM,eAAe,MAAM,kBAAkB;AAAA,EAC9D;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,aAAa,EAAE,MAAM,cAAc,SAAS,OAAO,QAAQ,KAAK;AAAA,EAClE;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,aAAa,EAAE,MAAM,gBAAgB,SAAS,OAAO,QAAQ,OAAO;AAAA,EACtE;AACF;AAEA,IAAM,aAA6B;AAAA,EACjC;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa,CAAC;AAAA,EAChB;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa,CAAC;AAAA,EAChB;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa,CAAC;AAAA,EAChB;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa,EAAE,OAAO,KAAK;AAAA,EAC7B;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa,EAAE,OAAO,KAAK;AAAA,EAC7B;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa,EAAE,OAAO,KAAK;AAAA,EAC7B;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa,EAAE,OAAO,KAAK;AAAA,EAC7B;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa,EAAE,OAAO,KAAK;AAAA,EAC7B;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa,EAAE,OAAO,KAAK;AAAA,EAC7B;AAAA,EACA,EAAE,KAAK,KAAK,QAAQ,cAAc,WAAW,GAAG,SAAS,GAAG,aAAa,CAAC,EAAE;AAAA,EAC5E,EAAE,KAAK,KAAK,QAAQ,cAAc,WAAW,GAAG,SAAS,GAAG,aAAa,CAAC,EAAE;AAAA,EAC5E;AAAA,IACE,KAAK;AAAA,IACL,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa,CAAC;AAAA,EAChB;AAAA,EACA,EAAE,KAAK,KAAK,QAAQ,QAAQ,WAAW,GAAG,SAAS,IAAI,aAAa,CAAC,EAAE;AAAA,EACvE,EAAE,KAAK,KAAK,QAAQ,QAAQ,WAAW,GAAG,SAAS,IAAI,aAAa,CAAC,EAAE;AACzE;AASA,SAAS,yBAA0C;AACjD,QAAM,cAAc,uBAAuB;AAC3C,QAAM,YAAY,qBAAqB;AACvC,QAAM,YAAY,qBAAqB;AACvC,QAAM,aAAa,sBAAsB;AACzC,QAAM,mBAAmB,4BAA4B;AAAA,IACnD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA,YAAY,aAAa,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,EAAE;AAAA,IAChD,UAAU,YAAY,CAAC;AAAA,EACzB,CAAC;AACD,SAAO,EAAE,aAAa,WAAW,kBAAkB,UAAU;AAC/D;AAEA,IAAM,oBAAoB,uBAAuB;AAWjD,IAAM,eAA2B,EAAE,OAAO,YAAY,OAAO,WAAW;AAExE,SAAS,mBAAmB,MAA0B;AACpD,SAAO,KAAK,UAAU,MAAM,MAAM,CAAC;AACrC;AAEA,SAAS,aAAa,GAAY,GAA0B;AAC1D,MAAI,CAAC,KAAK,OAAO,MAAM,SAAU,QAAO,SAAS,CAAC;AAClD,QAAM,OAAO;AACb,MAAI,KAAK,QAAQ,OAAW,QAAO,SAAS,CAAC;AAC7C,MAAI,OAAO,KAAK,WAAW,SAAU,QAAO,SAAS,CAAC;AACtD,SAAO;AACT;AAEA,SAAS,aAAa,GAAY,GAA0B;AAC1D,MAAI,CAAC,KAAK,OAAO,MAAM,SAAU,QAAO,SAAS,CAAC;AAClD,QAAM,OAAO;AACb,MAAI,KAAK,QAAQ,OAAW,QAAO,SAAS,CAAC;AAC7C,MAAI,OAAO,KAAK,WAAW,SAAU,QAAO,SAAS,CAAC;AACtD,MAAI,KAAK,cAAc,OAAW,QAAO,SAAS,CAAC;AACnD,MAAI,KAAK,YAAY,OAAW,QAAO,SAAS,CAAC;AACjD,SAAO;AACT;AAGA,SAAS,mBAAmB,OAA+B;AACzD,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AAC/D,WAAO;AAAA,EACT;AACA,QAAM,MAAM;AACZ,MAAI,CAAC,MAAM,QAAQ,IAAI,KAAK,EAAG,QAAO;AACtC,MAAI,CAAC,MAAM,QAAQ,IAAI,KAAK,EAAG,QAAO;AACtC,aAAW,CAAC,GAAG,CAAC,KAAM,IAAI,MAAoB,QAAQ,GAAG;AACvD,UAAM,MAAM,aAAa,GAAG,CAAC;AAC7B,QAAI,IAAK,QAAO;AAAA,EAClB;AACA,aAAW,CAAC,GAAG,CAAC,KAAM,IAAI,MAAoB,QAAQ,GAAG;AACvD,UAAM,MAAM,aAAa,GAAG,CAAC;AAC7B,QAAI,IAAK,QAAO;AAAA,EAClB;AACA,SAAO;AACT;AAEA,SAAS,cAAc,QAAyB,MAAkB;AAChE,QAAM,cAAsC,CAAC;AAC7C,aAAW,KAAK,KAAK,OAAO;AAC1B,gBAAY,EAAE,MAAM,KAAK,YAAY,EAAE,MAAM,KAAK,KAAK;AAAA,EACzD;AACA,QAAM,UAAU,kBAAkB,WAAW;AAC7C,QAAM,QAAQ,YAAY,KAAK,OAAO,OAAO;AAC7C,QAAM,QAAQ,YAAY,KAAK,OAAO,OAAO;AAC7C,SAAO,YAAY,SAAS,EAAE,aAAa;AAC3C,SAAO,UAAU,SAAS,EAAE,aAAa,OAAO,OAAO;AAAA,IACrD,OAAO,MAAM;AAAA,IACb,OAAO,MAAM;AAAA,EACf,CAAC;AAED,SAAO,YAAY,SAAS,EAAE,iBAAiB;AACjD;AAGA,cAAc,mBAAmB,YAAY;AAM9B,SAAR,YAAiD;AACtD,QAAM,CAAC,UAAU,WAAW,IAAI;AAAA,IAAS,MACvC,mBAAmB,YAAY;AAAA,EACjC;AACA,QAAM,CAAC,YAAY,aAAa,IAAI,SAAwB,IAAI;AAEhE,QAAM,cAAc,YAAY,MAAM;AACpC,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,QAAQ;AAAA,IAC9B,SAAS,GAAG;AACV,oBAAc,aAAa,QAAQ,EAAE,UAAU,cAAc;AAC7D;AAAA,IACF;AACA,UAAM,kBAAkB,mBAAmB,MAAM;AACjD,QAAI,iBAAiB;AACnB,oBAAc,eAAe;AAC7B;AAAA,IACF;AACA,kBAAc,IAAI;AAClB,kBAAc,mBAAmB,MAAoB;AAAA,EACvD,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,cAAc,YAAY,MAAM;AACpC,gBAAY,mBAAmB,YAAY,CAAC;AAC5C,kBAAc,IAAI;AAClB,kBAAc,mBAAmB,YAAY;AAAA,EAC/C,GAAG,CAAC,CAAC;AAEL,QAAM,gBAAgB;AAAA,IACpB,CAAC,MAA2B;AAC1B,WAAK,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,SAAS;AACjD,UAAE,eAAe;AACjB,oBAAY;AAAA,MACd;AAAA,IACF;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,aAAY;AAAA,MAEZ,8BAAC,mBAAmB,UAAnB,EAA4B,OAAO,mBAClC,+BAAC,QAAK,cAAa,SAAQ,WAAU,aACnC;AAAA,6BAAC,YACC;AAAA,8BAAC,eAAY,OAAM,SAAQ,mBAAK;AAAA,UAChC,oBAAC,eAAY,OAAM,QAAO,kBAAI;AAAA,WAChC;AAAA,QAEA,oBAAC,eAAY,OAAM,SAAQ,WAAU,QACnC,8BAAC,yBAAsB,iBAAgB,aACrC,+BAAC,SAAI,WAAU,oDACb;AAAA,8BAAC,SAAI,WAAU,kBACb,8BAAC,mBAAgB,GACnB;AAAA,UACA,oBAAC,SAAI,WAAU,oCACb,8BAAC,eAAY,GACf;AAAA,WACF,GACF,GACF;AAAA,QAEA,oBAAC,eAAY,OAAM,QAAO,WAAU,QAClC,+BAAC,SAAI,WAAU,aACb;AAAA,+BAAC,SAAI,WAAU,2BACb;AAAA,iCAAC,UAAO,MAAK,MAAK,SAAS,aACzB;AAAA,kCAAC,QAAK,WAAU,gBAAe;AAAA,cAAE;AAAA,eAEnC;AAAA,YACA,qBAAC,UAAO,MAAK,MAAK,SAAQ,WAAU,SAAS,aAC3C;AAAA,kCAAC,aAAU,WAAU,gBAAe;AAAA,cAAE;AAAA,eAExC;AAAA,YACA,oBAAC,UAAK,WAAU,sCAAqC,gCAErD;AAAA,aACF;AAAA,UACC,cACC,oBAAC,SAAM,SAAQ,eACb,8BAAC,oBAAkB,sBAAW,GAChC;AAAA,UAEF;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,cACP,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK;AAAA,cAC3C,WAAW;AAAA,cACX,YAAY;AAAA,cACZ,WAAU;AAAA;AAAA,UACZ;AAAA,WACF,GACF;AAAA,SACF,GACF;AAAA;AAAA,EACF;AAEJ;","names":[]}