@petrarca/sonnet-playground 0.4.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{PlayCoreComponents-GXFMB24T.js → PlayCoreComponents-YTEAS3GL.js} +2 -2
- package/dist/{PlayFormWidgets-IWJJQ5XL.js → PlayFormWidgets-6JYFRTAL.js} +2 -2
- package/dist/PlayForms-2G7PROCH.js +7 -0
- package/dist/PlayGraph-M7UE5MZC.js +7 -0
- package/dist/PlaySchemaDesigner-ZM4F7KBU.js +7 -0
- package/dist/PlaySchemaDesigner-ZM4F7KBU.js.map +1 -0
- package/dist/chunk-6VQJFBTM.js +315 -0
- package/dist/chunk-6VQJFBTM.js.map +1 -0
- package/dist/{chunk-YOOWJORD.js → chunk-6WI3N7JI.js} +361 -2
- package/dist/chunk-6WI3N7JI.js.map +1 -0
- package/dist/chunk-C2P3UQMZ.js +1058 -0
- package/dist/chunk-C2P3UQMZ.js.map +1 -0
- package/dist/{chunk-DZB6WFHA.js → chunk-UB7462QG.js} +106 -1
- package/dist/chunk-UB7462QG.js.map +1 -0
- package/dist/{chunk-6DZ3TSV4.js → chunk-ZSUCFEB6.js} +101 -4
- package/dist/chunk-ZSUCFEB6.js.map +1 -0
- package/dist/index.d.ts +41 -9
- package/dist/index.js +216 -51
- package/dist/index.js.map +1 -1
- package/dist/pages/index.d.ts +10 -2
- package/dist/pages/index.js +8 -4
- package/package.json +7 -6
- package/dist/PlayForms-FOF3XE6G.js +0 -7
- package/dist/PlayGraph-ADRTDRA7.js +0 -7
- package/dist/chunk-4ORSUS65.js +0 -359
- package/dist/chunk-4ORSUS65.js.map +0 -1
- package/dist/chunk-6DZ3TSV4.js.map +0 -1
- package/dist/chunk-DZB6WFHA.js.map +0 -1
- package/dist/chunk-YOOWJORD.js.map +0 -1
- /package/dist/{PlayCoreComponents-GXFMB24T.js.map → PlayCoreComponents-YTEAS3GL.js.map} +0 -0
- /package/dist/{PlayFormWidgets-IWJJQ5XL.js.map → PlayFormWidgets-6JYFRTAL.js.map} +0 -0
- /package/dist/{PlayForms-FOF3XE6G.js.map → PlayForms-2G7PROCH.js.map} +0 -0
- /package/dist/{PlayGraph-ADRTDRA7.js.map → PlayGraph-M7UE5MZC.js.map} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PlayCoreComponents
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6WI3N7JI.js";
|
|
4
4
|
import "./chunk-C2EZ2ECG.js";
|
|
5
5
|
export {
|
|
6
6
|
PlayCoreComponents as default
|
|
7
7
|
};
|
|
8
|
-
//# sourceMappingURL=PlayCoreComponents-
|
|
8
|
+
//# sourceMappingURL=PlayCoreComponents-YTEAS3GL.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PlayFormWidgets
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-UB7462QG.js";
|
|
4
4
|
import "./chunk-C2EZ2ECG.js";
|
|
5
5
|
export {
|
|
6
6
|
PlayFormWidgets as default
|
|
7
7
|
};
|
|
8
|
-
//# sourceMappingURL=PlayFormWidgets-
|
|
8
|
+
//# sourceMappingURL=PlayFormWidgets-6JYFRTAL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
// src/pages/PlaySchemaDesigner.tsx
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import {
|
|
4
|
+
SchemaDesigner
|
|
5
|
+
} from "@petrarca/sonnet-schema-designer";
|
|
6
|
+
import { FormSelect } from "@petrarca/sonnet-forms";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
var SAMPLE_SCHEMA = {
|
|
9
|
+
title: "Patient",
|
|
10
|
+
type: "object",
|
|
11
|
+
properties: {
|
|
12
|
+
first_name: { type: "string", title: "First name", minLength: 1 },
|
|
13
|
+
last_name: { type: "string", title: "Last name", minLength: 1 },
|
|
14
|
+
date_of_birth: { type: "string", format: "date", title: "Date of birth" },
|
|
15
|
+
gender: {
|
|
16
|
+
type: "string",
|
|
17
|
+
title: "Gender",
|
|
18
|
+
enum: ["male", "female", "other", "unknown"]
|
|
19
|
+
},
|
|
20
|
+
active: { type: "boolean", title: "Active" },
|
|
21
|
+
contact: {
|
|
22
|
+
type: "object",
|
|
23
|
+
title: "Contact",
|
|
24
|
+
properties: {
|
|
25
|
+
email: { type: "string", format: "email", title: "Email" },
|
|
26
|
+
phone: { type: "string", title: "Phone" }
|
|
27
|
+
},
|
|
28
|
+
required: ["email"]
|
|
29
|
+
},
|
|
30
|
+
addresses: {
|
|
31
|
+
type: "array",
|
|
32
|
+
title: "Addresses",
|
|
33
|
+
minItems: 1,
|
|
34
|
+
maxItems: 3,
|
|
35
|
+
items: {
|
|
36
|
+
type: "object",
|
|
37
|
+
properties: {
|
|
38
|
+
street: { type: "string", title: "Street" },
|
|
39
|
+
city: { type: "string", title: "City" },
|
|
40
|
+
zip: { type: "string", title: "ZIP" },
|
|
41
|
+
country: { type: "string", title: "Country" }
|
|
42
|
+
},
|
|
43
|
+
required: ["street", "city"]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
required: ["first_name", "last_name"]
|
|
48
|
+
};
|
|
49
|
+
var AUDIT_SCHEMA = {
|
|
50
|
+
title: "AuditEvent",
|
|
51
|
+
type: "object",
|
|
52
|
+
properties: {
|
|
53
|
+
actor: {
|
|
54
|
+
type: "object",
|
|
55
|
+
title: "Actor",
|
|
56
|
+
properties: {
|
|
57
|
+
type: { type: "string", title: "Type" },
|
|
58
|
+
id: { type: "string", title: "ID" },
|
|
59
|
+
metadata: {
|
|
60
|
+
type: "object",
|
|
61
|
+
title: "Actor metadata",
|
|
62
|
+
properties: { role: { type: "string", title: "Role" } }
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
targets: {
|
|
67
|
+
type: "array",
|
|
68
|
+
title: "Targets",
|
|
69
|
+
items: {
|
|
70
|
+
type: "object",
|
|
71
|
+
properties: {
|
|
72
|
+
type: { type: "string", title: "Type" },
|
|
73
|
+
id: { type: "string", title: "ID" },
|
|
74
|
+
metadata: {
|
|
75
|
+
type: "object",
|
|
76
|
+
title: "Target metadata",
|
|
77
|
+
properties: { ward: { type: "string", title: "Ward" } }
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
metadata: {
|
|
83
|
+
type: "object",
|
|
84
|
+
title: "Metadata",
|
|
85
|
+
properties: { reason: { type: "string", title: "Reason" } }
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
var LOGIC_SCHEMA = {
|
|
90
|
+
title: "Checkout",
|
|
91
|
+
type: "object",
|
|
92
|
+
// A reusable definition referenced by $ref (shows read-only expansion).
|
|
93
|
+
$defs: {
|
|
94
|
+
Address: {
|
|
95
|
+
type: "object",
|
|
96
|
+
properties: {
|
|
97
|
+
street: { type: "string", title: "Street" },
|
|
98
|
+
city: { type: "string", title: "City" },
|
|
99
|
+
zip: { type: "string", title: "ZIP" }
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"x-ui-order": [
|
|
104
|
+
"schema_version",
|
|
105
|
+
"amount",
|
|
106
|
+
"requires_approval",
|
|
107
|
+
"currency",
|
|
108
|
+
"expedited",
|
|
109
|
+
"delivery_window",
|
|
110
|
+
"gift_wrap",
|
|
111
|
+
"gift_message",
|
|
112
|
+
"shipping_address",
|
|
113
|
+
"note",
|
|
114
|
+
"payment"
|
|
115
|
+
],
|
|
116
|
+
properties: {
|
|
117
|
+
// A $ref to the shared Address definition (read-only in the tree).
|
|
118
|
+
shipping_address: { $ref: "#/$defs/Address", title: "Shipping address" },
|
|
119
|
+
// A fixed value carried by every document (const authoring).
|
|
120
|
+
schema_version: {
|
|
121
|
+
type: "string",
|
|
122
|
+
title: "Schema version",
|
|
123
|
+
const: "checkout/v1"
|
|
124
|
+
},
|
|
125
|
+
amount: { type: "number", title: "Amount", minimum: 0 },
|
|
126
|
+
currency: {
|
|
127
|
+
type: "string",
|
|
128
|
+
title: "Currency",
|
|
129
|
+
enum: ["EUR", "USD", "GBP"]
|
|
130
|
+
},
|
|
131
|
+
expedited: { type: "boolean", title: "Expedited" },
|
|
132
|
+
gift_wrap: { type: "boolean", title: "Gift wrap" },
|
|
133
|
+
// Declarative visibility rule (x-ui-rule): declared at its own position,
|
|
134
|
+
// shown only when gift_wrap is checked. Contrast with the if/then/else
|
|
135
|
+
// fields above, which are structurally added by their conditionals.
|
|
136
|
+
gift_message: {
|
|
137
|
+
type: "string",
|
|
138
|
+
title: "Gift message",
|
|
139
|
+
"x-ui-rule": {
|
|
140
|
+
effect: "show",
|
|
141
|
+
condition: { scope: "/gift_wrap", schema: { const: true } }
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
// Nullable optional (anyOf [T, null]) -- the renderer unwraps to T.
|
|
145
|
+
note: {
|
|
146
|
+
title: "Note (optional)",
|
|
147
|
+
anyOf: [{ type: "string" }, { type: "null" }]
|
|
148
|
+
},
|
|
149
|
+
// A discriminated union (oneOf): the payment method.
|
|
150
|
+
payment: {
|
|
151
|
+
type: "object",
|
|
152
|
+
title: "Payment method",
|
|
153
|
+
discriminator: { propertyName: "kind" },
|
|
154
|
+
oneOf: [
|
|
155
|
+
{
|
|
156
|
+
title: "Card",
|
|
157
|
+
properties: {
|
|
158
|
+
kind: { const: "card" },
|
|
159
|
+
card_number: { type: "string", title: "Card number" },
|
|
160
|
+
cvc: { type: "string", title: "CVC" }
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
title: "Bank transfer",
|
|
165
|
+
properties: {
|
|
166
|
+
kind: { const: "bank" },
|
|
167
|
+
iban: { type: "string", title: "IBAN" }
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
title: "Cash",
|
|
172
|
+
properties: { kind: { const: "cash" } }
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
required: ["amount", "currency"],
|
|
178
|
+
// Conditionals (if/then/else) authored as allOf members.
|
|
179
|
+
allOf: [
|
|
180
|
+
{
|
|
181
|
+
// Large amounts require an approval reference.
|
|
182
|
+
if: {
|
|
183
|
+
properties: { amount: { exclusiveMinimum: 1e3 } },
|
|
184
|
+
required: ["amount"]
|
|
185
|
+
},
|
|
186
|
+
then: {
|
|
187
|
+
properties: {
|
|
188
|
+
requires_approval: {
|
|
189
|
+
type: "string",
|
|
190
|
+
title: "Approval reference"
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
required: ["requires_approval"]
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
// Expedited orders ask for a delivery window; otherwise none.
|
|
198
|
+
if: {
|
|
199
|
+
properties: { expedited: { const: true } },
|
|
200
|
+
required: ["expedited"]
|
|
201
|
+
},
|
|
202
|
+
then: {
|
|
203
|
+
properties: {
|
|
204
|
+
delivery_window: {
|
|
205
|
+
type: "string",
|
|
206
|
+
title: "Delivery window",
|
|
207
|
+
enum: ["morning", "afternoon", "evening"]
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
]
|
|
213
|
+
};
|
|
214
|
+
var AUDIT_EDITABLE_PATHS = [
|
|
215
|
+
"/properties/metadata/properties",
|
|
216
|
+
"/properties/actor/properties/metadata/properties",
|
|
217
|
+
"/properties/targets/items/properties/metadata/properties"
|
|
218
|
+
];
|
|
219
|
+
var PROFILES = {
|
|
220
|
+
full: {
|
|
221
|
+
label: "Full (schema + uiSchema)",
|
|
222
|
+
description: "Default: author the schema and its form presentation hints.",
|
|
223
|
+
schema: SAMPLE_SCHEMA,
|
|
224
|
+
capabilities: { previews: ["form", "table", "json", "capabilities"] }
|
|
225
|
+
},
|
|
226
|
+
data: {
|
|
227
|
+
label: "Data schema only",
|
|
228
|
+
description: "Pure JSON Schema (audit, terminology): no UI/Combined tabs, JSON preview only.",
|
|
229
|
+
schema: SAMPLE_SCHEMA,
|
|
230
|
+
capabilities: { mode: "data", previews: ["json", "capabilities"] }
|
|
231
|
+
},
|
|
232
|
+
scoped: {
|
|
233
|
+
label: "Scoped (audit event)",
|
|
234
|
+
description: "Fixed envelope; only the three metadata containers are editable.",
|
|
235
|
+
schema: AUDIT_SCHEMA,
|
|
236
|
+
capabilities: {
|
|
237
|
+
mode: "data",
|
|
238
|
+
editablePaths: AUDIT_EDITABLE_PATHS,
|
|
239
|
+
previews: ["json", "capabilities"]
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
structure: {
|
|
243
|
+
label: "Structure only (no preview)",
|
|
244
|
+
description: "Tree + inspector only; the center preview pane is hidden.",
|
|
245
|
+
schema: SAMPLE_SCHEMA,
|
|
246
|
+
capabilities: { mode: "data", previews: [] }
|
|
247
|
+
},
|
|
248
|
+
logic: {
|
|
249
|
+
label: "Logic (variants + conditionals)",
|
|
250
|
+
description: "Shows every logic construct: a oneOf variant, if/then/else conditionals, a const field, and a nullable optional.",
|
|
251
|
+
schema: LOGIC_SCHEMA,
|
|
252
|
+
capabilities: { previews: ["form", "table", "json", "capabilities"] }
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
function PlaySchemaDesigner() {
|
|
256
|
+
const [profileKey, setProfileKey] = useState("full");
|
|
257
|
+
const profile = PROFILES[profileKey];
|
|
258
|
+
const [schema, setSchema] = useState(profile.schema);
|
|
259
|
+
const [uiSchema, setUiSchema] = useState({});
|
|
260
|
+
const selectProfile = (key) => {
|
|
261
|
+
setProfileKey(key);
|
|
262
|
+
setSchema(PROFILES[key].schema);
|
|
263
|
+
setUiSchema({});
|
|
264
|
+
};
|
|
265
|
+
return /* @__PURE__ */ jsxs("div", { className: "w-full flex flex-col gap-3 h-[calc(100vh-8rem)]", children: [
|
|
266
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
267
|
+
/* @__PURE__ */ jsx("h1", { children: "Schema Designer" }),
|
|
268
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-3", children: "Visually author a JSON Schema and its UI presentation hints. Edits flow through onChange as a valid schema + uiSchema." })
|
|
269
|
+
] }),
|
|
270
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
271
|
+
/* @__PURE__ */ jsx(
|
|
272
|
+
"label",
|
|
273
|
+
{
|
|
274
|
+
htmlFor: "capability-profile",
|
|
275
|
+
className: "shrink-0 text-sm font-medium",
|
|
276
|
+
children: "Capability profile"
|
|
277
|
+
}
|
|
278
|
+
),
|
|
279
|
+
/* @__PURE__ */ jsx("div", { className: "w-72", children: /* @__PURE__ */ jsx(
|
|
280
|
+
FormSelect,
|
|
281
|
+
{
|
|
282
|
+
id: "capability-profile",
|
|
283
|
+
name: "profile",
|
|
284
|
+
value: profileKey,
|
|
285
|
+
options: Object.keys(PROFILES).map((k) => ({
|
|
286
|
+
value: k,
|
|
287
|
+
label: PROFILES[k].label
|
|
288
|
+
})),
|
|
289
|
+
onChange: (v) => selectProfile(v ?? "full"),
|
|
290
|
+
clearable: false
|
|
291
|
+
}
|
|
292
|
+
) }),
|
|
293
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: profile.description })
|
|
294
|
+
] }),
|
|
295
|
+
/* @__PURE__ */ jsx("div", { style: { flex: 1, minHeight: 0 }, children: /* @__PURE__ */ jsx(
|
|
296
|
+
SchemaDesigner,
|
|
297
|
+
{
|
|
298
|
+
schema,
|
|
299
|
+
uiSchema,
|
|
300
|
+
capabilities: profile.capabilities,
|
|
301
|
+
readOnly: profile.readOnly,
|
|
302
|
+
onChange: (nextSchema, nextUiSchema) => {
|
|
303
|
+
setSchema(nextSchema);
|
|
304
|
+
setUiSchema(nextUiSchema);
|
|
305
|
+
}
|
|
306
|
+
},
|
|
307
|
+
profileKey
|
|
308
|
+
) })
|
|
309
|
+
] });
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export {
|
|
313
|
+
PlaySchemaDesigner
|
|
314
|
+
};
|
|
315
|
+
//# sourceMappingURL=chunk-6VQJFBTM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pages/PlaySchemaDesigner.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport {\n SchemaDesigner,\n type SchemaDesignerCapabilities,\n} from \"@petrarca/sonnet-schema-designer\";\nimport { FormSelect } from \"@petrarca/sonnet-forms\";\nimport type { JsonSchema, UISchema } from \"@petrarca/sonnet-core/schema\";\n\nconst SAMPLE_SCHEMA: JsonSchema = {\n title: \"Patient\",\n type: \"object\",\n properties: {\n first_name: { type: \"string\", title: \"First name\", minLength: 1 },\n last_name: { type: \"string\", title: \"Last name\", minLength: 1 },\n date_of_birth: { type: \"string\", format: \"date\", title: \"Date of birth\" },\n gender: {\n type: \"string\",\n title: \"Gender\",\n enum: [\"male\", \"female\", \"other\", \"unknown\"],\n },\n active: { type: \"boolean\", title: \"Active\" },\n contact: {\n type: \"object\",\n title: \"Contact\",\n properties: {\n email: { type: \"string\", format: \"email\", title: \"Email\" },\n phone: { type: \"string\", title: \"Phone\" },\n },\n required: [\"email\"],\n },\n addresses: {\n type: \"array\",\n title: \"Addresses\",\n minItems: 1,\n maxItems: 3,\n items: {\n type: \"object\",\n properties: {\n street: { type: \"string\", title: \"Street\" },\n city: { type: \"string\", title: \"City\" },\n zip: { type: \"string\", title: \"ZIP\" },\n country: { type: \"string\", title: \"Country\" },\n },\n required: [\"street\", \"city\"],\n },\n },\n },\n required: [\"first_name\", \"last_name\"],\n};\n\n// An audit-event-like schema: a fixed envelope (actor, targets) with three\n// extensible metadata containers. Used to demo scoped editing.\nconst AUDIT_SCHEMA: JsonSchema = {\n title: \"AuditEvent\",\n type: \"object\",\n properties: {\n actor: {\n type: \"object\",\n title: \"Actor\",\n properties: {\n type: { type: \"string\", title: \"Type\" },\n id: { type: \"string\", title: \"ID\" },\n metadata: {\n type: \"object\",\n title: \"Actor metadata\",\n properties: { role: { type: \"string\", title: \"Role\" } },\n },\n },\n },\n targets: {\n type: \"array\",\n title: \"Targets\",\n items: {\n type: \"object\",\n properties: {\n type: { type: \"string\", title: \"Type\" },\n id: { type: \"string\", title: \"ID\" },\n metadata: {\n type: \"object\",\n title: \"Target metadata\",\n properties: { ward: { type: \"string\", title: \"Ward\" } },\n },\n },\n },\n },\n metadata: {\n type: \"object\",\n title: \"Metadata\",\n properties: { reason: { type: \"string\", title: \"Reason\" } },\n },\n },\n};\n\n// A schema exercising every logic construct the designer can author: a oneOf\n// discriminated variant (payment method), if/then/else conditionals (authored\n// as allOf members), a const-tagged field, and a nullable anyOf optional field.\n// x-ui-order places each conditional field right after the property it depends\n// on (see docs/design/schema-designer-logic-authoring.md, ordering note).\nconst LOGIC_SCHEMA: JsonSchema = {\n title: \"Checkout\",\n type: \"object\",\n // A reusable definition referenced by $ref (shows read-only expansion).\n $defs: {\n Address: {\n type: \"object\",\n properties: {\n street: { type: \"string\", title: \"Street\" },\n city: { type: \"string\", title: \"City\" },\n zip: { type: \"string\", title: \"ZIP\" },\n },\n },\n },\n \"x-ui-order\": [\n \"schema_version\",\n \"amount\",\n \"requires_approval\",\n \"currency\",\n \"expedited\",\n \"delivery_window\",\n \"gift_wrap\",\n \"gift_message\",\n \"shipping_address\",\n \"note\",\n \"payment\",\n ],\n properties: {\n // A $ref to the shared Address definition (read-only in the tree).\n shipping_address: { $ref: \"#/$defs/Address\", title: \"Shipping address\" },\n // A fixed value carried by every document (const authoring).\n schema_version: {\n type: \"string\",\n title: \"Schema version\",\n const: \"checkout/v1\",\n },\n amount: { type: \"number\", title: \"Amount\", minimum: 0 },\n currency: {\n type: \"string\",\n title: \"Currency\",\n enum: [\"EUR\", \"USD\", \"GBP\"],\n },\n expedited: { type: \"boolean\", title: \"Expedited\" },\n gift_wrap: { type: \"boolean\", title: \"Gift wrap\" },\n // Declarative visibility rule (x-ui-rule): declared at its own position,\n // shown only when gift_wrap is checked. Contrast with the if/then/else\n // fields above, which are structurally added by their conditionals.\n gift_message: {\n type: \"string\",\n title: \"Gift message\",\n \"x-ui-rule\": {\n effect: \"show\",\n condition: { scope: \"/gift_wrap\", schema: { const: true } },\n },\n },\n // Nullable optional (anyOf [T, null]) -- the renderer unwraps to T.\n note: {\n title: \"Note (optional)\",\n anyOf: [{ type: \"string\" }, { type: \"null\" }],\n },\n // A discriminated union (oneOf): the payment method.\n payment: {\n type: \"object\",\n title: \"Payment method\",\n discriminator: { propertyName: \"kind\" },\n oneOf: [\n {\n title: \"Card\",\n properties: {\n kind: { const: \"card\" },\n card_number: { type: \"string\", title: \"Card number\" },\n cvc: { type: \"string\", title: \"CVC\" },\n },\n },\n {\n title: \"Bank transfer\",\n properties: {\n kind: { const: \"bank\" },\n iban: { type: \"string\", title: \"IBAN\" },\n },\n },\n {\n title: \"Cash\",\n properties: { kind: { const: \"cash\" } },\n },\n ],\n },\n },\n required: [\"amount\", \"currency\"],\n // Conditionals (if/then/else) authored as allOf members.\n allOf: [\n {\n // Large amounts require an approval reference.\n if: {\n properties: { amount: { exclusiveMinimum: 1000 } },\n required: [\"amount\"],\n },\n then: {\n properties: {\n requires_approval: {\n type: \"string\",\n title: \"Approval reference\",\n },\n },\n required: [\"requires_approval\"],\n },\n },\n {\n // Expedited orders ask for a delivery window; otherwise none.\n if: {\n properties: { expedited: { const: true } },\n required: [\"expedited\"],\n },\n then: {\n properties: {\n delivery_window: {\n type: \"string\",\n title: \"Delivery window\",\n enum: [\"morning\", \"afternoon\", \"evening\"],\n },\n },\n },\n },\n ],\n};\n\nconst AUDIT_EDITABLE_PATHS = [\n \"/properties/metadata/properties\",\n \"/properties/actor/properties/metadata/properties\",\n \"/properties/targets/items/properties/metadata/properties\",\n];\n\ntype ProfileKey = \"full\" | \"data\" | \"scoped\" | \"structure\" | \"logic\";\n\ninterface Profile {\n label: string;\n description: string;\n schema: JsonSchema;\n capabilities?: SchemaDesignerCapabilities;\n readOnly?: boolean;\n}\n\nconst PROFILES: Record<ProfileKey, Profile> = {\n full: {\n label: \"Full (schema + uiSchema)\",\n description: \"Default: author the schema and its form presentation hints.\",\n schema: SAMPLE_SCHEMA,\n capabilities: { previews: [\"form\", \"table\", \"json\", \"capabilities\"] },\n },\n data: {\n label: \"Data schema only\",\n description:\n \"Pure JSON Schema (audit, terminology): no UI/Combined tabs, JSON preview only.\",\n schema: SAMPLE_SCHEMA,\n capabilities: { mode: \"data\", previews: [\"json\", \"capabilities\"] },\n },\n scoped: {\n label: \"Scoped (audit event)\",\n description:\n \"Fixed envelope; only the three metadata containers are editable.\",\n schema: AUDIT_SCHEMA,\n capabilities: {\n mode: \"data\",\n editablePaths: AUDIT_EDITABLE_PATHS,\n previews: [\"json\", \"capabilities\"],\n },\n },\n structure: {\n label: \"Structure only (no preview)\",\n description: \"Tree + inspector only; the center preview pane is hidden.\",\n schema: SAMPLE_SCHEMA,\n capabilities: { mode: \"data\", previews: [] },\n },\n logic: {\n label: \"Logic (variants + conditionals)\",\n description:\n \"Shows every logic construct: a oneOf variant, if/then/else conditionals, a const field, and a nullable optional.\",\n schema: LOGIC_SCHEMA,\n capabilities: { previews: [\"form\", \"table\", \"json\", \"capabilities\"] },\n },\n};\n\n/**\n * PlaySchemaDesigner -- exercises SchemaDesigner: visually author a JsonSchema\n * (and its uiSchema presentation hints), with a live preview. The profile\n * switcher presets the capability profile (data/full triage, scoped editing,\n * read-only); the in-designer Capabilities tab tweaks it live.\n */\nexport default function PlaySchemaDesigner() {\n const [profileKey, setProfileKey] = useState<ProfileKey>(\"full\");\n const profile = PROFILES[profileKey];\n\n const [schema, setSchema] = useState<JsonSchema>(profile.schema);\n const [uiSchema, setUiSchema] = useState<Record<string, UISchema>>({});\n\n const selectProfile = (key: ProfileKey) => {\n setProfileKey(key);\n setSchema(PROFILES[key].schema);\n setUiSchema({});\n };\n\n return (\n <div className=\"w-full flex flex-col gap-3 h-[calc(100vh-8rem)]\">\n <div>\n <h1>Schema Designer</h1>\n <p className=\"text-sm text-muted-foreground mb-3\">\n Visually author a JSON Schema and its UI presentation hints. Edits\n flow through onChange as a valid schema + uiSchema.\n </p>\n </div>\n\n <div className=\"flex items-center gap-3\">\n <label\n htmlFor=\"capability-profile\"\n className=\"shrink-0 text-sm font-medium\"\n >\n Capability profile\n </label>\n <div className=\"w-72\">\n <FormSelect\n id=\"capability-profile\"\n name=\"profile\"\n value={profileKey}\n options={(Object.keys(PROFILES) as ProfileKey[]).map((k) => ({\n value: k,\n label: PROFILES[k].label,\n }))}\n onChange={(v) => selectProfile((v as ProfileKey) ?? \"full\")}\n clearable={false}\n />\n </div>\n <p className=\"text-sm text-muted-foreground\">{profile.description}</p>\n </div>\n\n <div style={{ flex: 1, minHeight: 0 }}>\n <SchemaDesigner\n key={profileKey}\n schema={schema}\n uiSchema={uiSchema}\n capabilities={profile.capabilities}\n readOnly={profile.readOnly}\n onChange={(nextSchema, nextUiSchema) => {\n setSchema(nextSchema);\n setUiSchema(nextUiSchema);\n }}\n />\n </div>\n </div>\n );\n}\n"],"mappings":";AAAA,SAAS,gBAAgB;AACzB;AAAA,EACE;AAAA,OAEK;AACP,SAAS,kBAAkB;AAwSrB,SACE,KADF;AArSN,IAAM,gBAA4B;AAAA,EAChC,OAAO;AAAA,EACP,MAAM;AAAA,EACN,YAAY;AAAA,IACV,YAAY,EAAE,MAAM,UAAU,OAAO,cAAc,WAAW,EAAE;AAAA,IAChE,WAAW,EAAE,MAAM,UAAU,OAAO,aAAa,WAAW,EAAE;AAAA,IAC9D,eAAe,EAAE,MAAM,UAAU,QAAQ,QAAQ,OAAO,gBAAgB;AAAA,IACxE,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,OAAO;AAAA,MACP,MAAM,CAAC,QAAQ,UAAU,SAAS,SAAS;AAAA,IAC7C;AAAA,IACA,QAAQ,EAAE,MAAM,WAAW,OAAO,SAAS;AAAA,IAC3C,SAAS;AAAA,MACP,MAAM;AAAA,MACN,OAAO;AAAA,MACP,YAAY;AAAA,QACV,OAAO,EAAE,MAAM,UAAU,QAAQ,SAAS,OAAO,QAAQ;AAAA,QACzD,OAAO,EAAE,MAAM,UAAU,OAAO,QAAQ;AAAA,MAC1C;AAAA,MACA,UAAU,CAAC,OAAO;AAAA,IACpB;AAAA,IACA,WAAW;AAAA,MACT,MAAM;AAAA,MACN,OAAO;AAAA,MACP,UAAU;AAAA,MACV,UAAU;AAAA,MACV,OAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY;AAAA,UACV,QAAQ,EAAE,MAAM,UAAU,OAAO,SAAS;AAAA,UAC1C,MAAM,EAAE,MAAM,UAAU,OAAO,OAAO;AAAA,UACtC,KAAK,EAAE,MAAM,UAAU,OAAO,MAAM;AAAA,UACpC,SAAS,EAAE,MAAM,UAAU,OAAO,UAAU;AAAA,QAC9C;AAAA,QACA,UAAU,CAAC,UAAU,MAAM;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AAAA,EACA,UAAU,CAAC,cAAc,WAAW;AACtC;AAIA,IAAM,eAA2B;AAAA,EAC/B,OAAO;AAAA,EACP,MAAM;AAAA,EACN,YAAY;AAAA,IACV,OAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,MACP,YAAY;AAAA,QACV,MAAM,EAAE,MAAM,UAAU,OAAO,OAAO;AAAA,QACtC,IAAI,EAAE,MAAM,UAAU,OAAO,KAAK;AAAA,QAClC,UAAU;AAAA,UACR,MAAM;AAAA,UACN,OAAO;AAAA,UACP,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,OAAO,OAAO,EAAE;AAAA,QACxD;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY;AAAA,UACV,MAAM,EAAE,MAAM,UAAU,OAAO,OAAO;AAAA,UACtC,IAAI,EAAE,MAAM,UAAU,OAAO,KAAK;AAAA,UAClC,UAAU;AAAA,YACR,MAAM;AAAA,YACN,OAAO;AAAA,YACP,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,OAAO,OAAO,EAAE;AAAA,UACxD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,OAAO;AAAA,MACP,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,OAAO,SAAS,EAAE;AAAA,IAC5D;AAAA,EACF;AACF;AAOA,IAAM,eAA2B;AAAA,EAC/B,OAAO;AAAA,EACP,MAAM;AAAA;AAAA,EAEN,OAAO;AAAA,IACL,SAAS;AAAA,MACP,MAAM;AAAA,MACN,YAAY;AAAA,QACV,QAAQ,EAAE,MAAM,UAAU,OAAO,SAAS;AAAA,QAC1C,MAAM,EAAE,MAAM,UAAU,OAAO,OAAO;AAAA,QACtC,KAAK,EAAE,MAAM,UAAU,OAAO,MAAM;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AAAA,EACA,cAAc;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,YAAY;AAAA;AAAA,IAEV,kBAAkB,EAAE,MAAM,mBAAmB,OAAO,mBAAmB;AAAA;AAAA,IAEvE,gBAAgB;AAAA,MACd,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,IACA,QAAQ,EAAE,MAAM,UAAU,OAAO,UAAU,SAAS,EAAE;AAAA,IACtD,UAAU;AAAA,MACR,MAAM;AAAA,MACN,OAAO;AAAA,MACP,MAAM,CAAC,OAAO,OAAO,KAAK;AAAA,IAC5B;AAAA,IACA,WAAW,EAAE,MAAM,WAAW,OAAO,YAAY;AAAA,IACjD,WAAW,EAAE,MAAM,WAAW,OAAO,YAAY;AAAA;AAAA;AAAA;AAAA,IAIjD,cAAc;AAAA,MACZ,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,QACX,QAAQ;AAAA,QACR,WAAW,EAAE,OAAO,cAAc,QAAQ,EAAE,OAAO,KAAK,EAAE;AAAA,MAC5D;AAAA,IACF;AAAA;AAAA,IAEA,MAAM;AAAA,MACJ,OAAO;AAAA,MACP,OAAO,CAAC,EAAE,MAAM,SAAS,GAAG,EAAE,MAAM,OAAO,CAAC;AAAA,IAC9C;AAAA;AAAA,IAEA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,OAAO;AAAA,MACP,eAAe,EAAE,cAAc,OAAO;AAAA,MACtC,OAAO;AAAA,QACL;AAAA,UACE,OAAO;AAAA,UACP,YAAY;AAAA,YACV,MAAM,EAAE,OAAO,OAAO;AAAA,YACtB,aAAa,EAAE,MAAM,UAAU,OAAO,cAAc;AAAA,YACpD,KAAK,EAAE,MAAM,UAAU,OAAO,MAAM;AAAA,UACtC;AAAA,QACF;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,YAAY;AAAA,YACV,MAAM,EAAE,OAAO,OAAO;AAAA,YACtB,MAAM,EAAE,MAAM,UAAU,OAAO,OAAO;AAAA,UACxC;AAAA,QACF;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,YAAY,EAAE,MAAM,EAAE,OAAO,OAAO,EAAE;AAAA,QACxC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,UAAU,CAAC,UAAU,UAAU;AAAA;AAAA,EAE/B,OAAO;AAAA,IACL;AAAA;AAAA,MAEE,IAAI;AAAA,QACF,YAAY,EAAE,QAAQ,EAAE,kBAAkB,IAAK,EAAE;AAAA,QACjD,UAAU,CAAC,QAAQ;AAAA,MACrB;AAAA,MACA,MAAM;AAAA,QACJ,YAAY;AAAA,UACV,mBAAmB;AAAA,YACjB,MAAM;AAAA,YACN,OAAO;AAAA,UACT;AAAA,QACF;AAAA,QACA,UAAU,CAAC,mBAAmB;AAAA,MAChC;AAAA,IACF;AAAA,IACA;AAAA;AAAA,MAEE,IAAI;AAAA,QACF,YAAY,EAAE,WAAW,EAAE,OAAO,KAAK,EAAE;AAAA,QACzC,UAAU,CAAC,WAAW;AAAA,MACxB;AAAA,MACA,MAAM;AAAA,QACJ,YAAY;AAAA,UACV,iBAAiB;AAAA,YACf,MAAM;AAAA,YACN,OAAO;AAAA,YACP,MAAM,CAAC,WAAW,aAAa,SAAS;AAAA,UAC1C;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,uBAAuB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACF;AAYA,IAAM,WAAwC;AAAA,EAC5C,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,cAAc,EAAE,UAAU,CAAC,QAAQ,SAAS,QAAQ,cAAc,EAAE;AAAA,EACtE;AAAA,EACA,MAAM;AAAA,IACJ,OAAO;AAAA,IACP,aACE;AAAA,IACF,QAAQ;AAAA,IACR,cAAc,EAAE,MAAM,QAAQ,UAAU,CAAC,QAAQ,cAAc,EAAE;AAAA,EACnE;AAAA,EACA,QAAQ;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,QAAQ;AAAA,IACR,cAAc;AAAA,MACZ,MAAM;AAAA,MACN,eAAe;AAAA,MACf,UAAU,CAAC,QAAQ,cAAc;AAAA,IACnC;AAAA,EACF;AAAA,EACA,WAAW;AAAA,IACT,OAAO;AAAA,IACP,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,cAAc,EAAE,MAAM,QAAQ,UAAU,CAAC,EAAE;AAAA,EAC7C;AAAA,EACA,OAAO;AAAA,IACL,OAAO;AAAA,IACP,aACE;AAAA,IACF,QAAQ;AAAA,IACR,cAAc,EAAE,UAAU,CAAC,QAAQ,SAAS,QAAQ,cAAc,EAAE;AAAA,EACtE;AACF;AAQe,SAAR,qBAAsC;AAC3C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAqB,MAAM;AAC/D,QAAM,UAAU,SAAS,UAAU;AAEnC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAqB,QAAQ,MAAM;AAC/D,QAAM,CAAC,UAAU,WAAW,IAAI,SAAmC,CAAC,CAAC;AAErE,QAAM,gBAAgB,CAAC,QAAoB;AACzC,kBAAc,GAAG;AACjB,cAAU,SAAS,GAAG,EAAE,MAAM;AAC9B,gBAAY,CAAC,CAAC;AAAA,EAChB;AAEA,SACE,qBAAC,SAAI,WAAU,mDACb;AAAA,yBAAC,SACC;AAAA,0BAAC,QAAG,6BAAe;AAAA,MACnB,oBAAC,OAAE,WAAU,sCAAqC,oIAGlD;AAAA,OACF;AAAA,IAEA,qBAAC,SAAI,WAAU,2BACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,SAAQ;AAAA,UACR,WAAU;AAAA,UACX;AAAA;AAAA,MAED;AAAA,MACA,oBAAC,SAAI,WAAU,QACb;AAAA,QAAC;AAAA;AAAA,UACC,IAAG;AAAA,UACH,MAAK;AAAA,UACL,OAAO;AAAA,UACP,SAAU,OAAO,KAAK,QAAQ,EAAmB,IAAI,CAAC,OAAO;AAAA,YAC3D,OAAO;AAAA,YACP,OAAO,SAAS,CAAC,EAAE;AAAA,UACrB,EAAE;AAAA,UACF,UAAU,CAAC,MAAM,cAAe,KAAoB,MAAM;AAAA,UAC1D,WAAW;AAAA;AAAA,MACb,GACF;AAAA,MACA,oBAAC,OAAE,WAAU,iCAAiC,kBAAQ,aAAY;AAAA,OACpE;AAAA,IAEA,oBAAC,SAAI,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,GAClC;AAAA,MAAC;AAAA;AAAA,QAEC;AAAA,QACA;AAAA,QACA,cAAc,QAAQ;AAAA,QACtB,UAAU,QAAQ;AAAA,QAClB,UAAU,CAAC,YAAY,iBAAiB;AACtC,oBAAU,UAAU;AACpB,sBAAY,YAAY;AAAA,QAC1B;AAAA;AAAA,MARK;AAAA,IASP,GACF;AAAA,KACF;AAEJ;","names":[]}
|