@petrarca/sonnet-playground 0.5.0 → 0.7.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/README.md +63 -101
- package/dist/PlayAuth-SOEYPOOL.js +8 -0
- package/dist/{PlayCoreComponents-AG5D4SBS.js → PlayCoreComponents-YTEAS3GL.js} +2 -2
- package/dist/{PlayFormWidgets-IWJJQ5XL.js → PlayFormWidgets-6JYFRTAL.js} +2 -2
- package/dist/PlayForms-L532W3JL.js +7 -0
- package/dist/PlayGraph-M4KQSFI7.js +7 -0
- package/dist/PlaySchemaDesigner-S4DBB53G.js +7 -0
- package/dist/PlaySchemaDesigner-S4DBB53G.js.map +1 -0
- package/dist/{chunk-PBT6HTKY.js → chunk-2XMWOZ5O.js} +130 -6
- package/dist/chunk-2XMWOZ5O.js.map +1 -0
- package/dist/{chunk-Q6NLY2BZ.js → chunk-6WI3N7JI.js} +309 -1
- package/dist/chunk-6WI3N7JI.js.map +1 -0
- package/dist/{chunk-C2P3UQMZ.js → chunk-E5X7GVLU.js} +2 -2
- package/dist/chunk-E5X7GVLU.js.map +1 -0
- package/dist/{chunk-6DZ3TSV4.js → chunk-I2FLG6ZD.js} +102 -4
- package/dist/chunk-I2FLG6ZD.js.map +1 -0
- package/dist/chunk-RYCRENYO.js +401 -0
- package/dist/chunk-RYCRENYO.js.map +1 -0
- package/dist/{chunk-DZB6WFHA.js → chunk-UB7462QG.js} +106 -1
- package/dist/chunk-UB7462QG.js.map +1 -0
- package/dist/index.d.ts +59 -17
- package/dist/index.js +251 -53
- package/dist/index.js.map +1 -1
- package/dist/pages/index.d.ts +3 -1
- package/dist/pages/index.js +9 -5
- package/package.json +7 -7
- package/dist/PlayForms-FOF3XE6G.js +0 -7
- package/dist/PlayGraph-M7UE5MZC.js +0 -7
- package/dist/PlaySchemaDesigner-B2RVRRCH.js +0 -7
- package/dist/chunk-6DZ3TSV4.js.map +0 -1
- package/dist/chunk-C2P3UQMZ.js.map +0 -1
- package/dist/chunk-DZB6WFHA.js.map +0 -1
- package/dist/chunk-PBT6HTKY.js.map +0 -1
- package/dist/chunk-Q6NLY2BZ.js.map +0 -1
- /package/dist/{PlayCoreComponents-AG5D4SBS.js.map → PlayAuth-SOEYPOOL.js.map} +0 -0
- /package/dist/{PlayFormWidgets-IWJJQ5XL.js.map → PlayCoreComponents-YTEAS3GL.js.map} +0 -0
- /package/dist/{PlayForms-FOF3XE6G.js.map → PlayFormWidgets-6JYFRTAL.js.map} +0 -0
- /package/dist/{PlayGraph-M7UE5MZC.js.map → PlayForms-L532W3JL.js.map} +0 -0
- /package/dist/{PlaySchemaDesigner-B2RVRRCH.js.map → PlayGraph-M4KQSFI7.js.map} +0 -0
package/README.md
CHANGED
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
# @petrarca/sonnet-playground
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
The living reference for the Petrarca Sonnet component library: a registry of
|
|
4
|
+
demonstration pages and a factory that turns it into a `ShellModule`. It is a
|
|
5
|
+
library, not a hosted site -- you mount it in your own application and get a
|
|
6
|
+
working component reference inside your own build
|
|
7
|
+
([ADR-0005](../../docs/adr/0005-the-playground-is-the-living-documentation.md)).
|
|
5
8
|
|
|
6
|
-
## What
|
|
9
|
+
## What it provides
|
|
7
10
|
|
|
8
|
-
**
|
|
9
|
-
|
|
11
|
+
**A registry.** `PlaygroundRegistry` and `createPlaygroundRegistry`, which
|
|
12
|
+
returns one pre-populated with the built-in entries. Register your own pages
|
|
13
|
+
beside them, grouped under a label you choose.
|
|
10
14
|
|
|
11
|
-
**
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
**A module factory.** `createPlaygroundModule` turns a registry into a
|
|
16
|
+
`ShellModule` with an overview page, generated routes and navigation, ready to
|
|
17
|
+
pass to `createModuleRegistry`.
|
|
14
18
|
|
|
15
|
-
**
|
|
16
|
-
|
|
19
|
+
**Twelve built-in pages**, each lazily loaded: Typography and Color Palette
|
|
20
|
+
under Design System; Core UI Components, Advanced Components and JSON Editor
|
|
21
|
+
under Components; Form Components, Forms Renderer and Form Widgets under Forms;
|
|
22
|
+
Schema Designer under Schemas; Data Components under Data; Graph Visualization
|
|
23
|
+
under Graph; Shell API under Shell.
|
|
17
24
|
|
|
18
|
-
|
|
25
|
+
**Page building blocks.** `PlaygroundSection` for consistent section chrome,
|
|
26
|
+
`PlaygroundOverview` for the tile grid, and the playground settings provider,
|
|
27
|
+
hook and panel.
|
|
19
28
|
|
|
20
29
|
## Install
|
|
21
30
|
|
|
@@ -23,120 +32,73 @@ used by all playground pages.
|
|
|
23
32
|
pnpm add @petrarca/sonnet-playground
|
|
24
33
|
```
|
|
25
34
|
|
|
26
|
-
|
|
27
|
-
|
|
35
|
+
That single install pulls in all six other `@petrarca/sonnet-*` packages --
|
|
36
|
+
`sonnet-core`, `sonnet-ui`, `sonnet-forms`, `sonnet-shell`, `sonnet-graph` and
|
|
37
|
+
`sonnet-schema-designer` -- as regular dependencies, because the pages import
|
|
38
|
+
from every one of them.
|
|
28
39
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// src/modules/playground/index.ts
|
|
35
|
-
import {
|
|
36
|
-
createPlaygroundRegistry,
|
|
37
|
-
createPlaygroundModule,
|
|
38
|
-
} from "@petrarca/sonnet-playground";
|
|
39
|
-
|
|
40
|
-
const registry = createPlaygroundRegistry();
|
|
41
|
-
|
|
42
|
-
// Optionally add app-specific pages:
|
|
43
|
-
registry.register({
|
|
44
|
-
id: "app.my-page",
|
|
45
|
-
title: "My Page",
|
|
46
|
-
description: "Custom demo page.",
|
|
47
|
-
icon: SomeIcon,
|
|
48
|
-
color: "teal",
|
|
49
|
-
path: "my-page",
|
|
50
|
-
component: React.lazy(() => import("./pages/MyPage")),
|
|
51
|
-
group: "App",
|
|
52
|
-
order: 0,
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
export default createPlaygroundModule(registry);
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
```ts
|
|
59
|
-
// src/modules/registry.ts
|
|
60
|
-
import { createModuleRegistry } from "@petrarca/sonnet-shell";
|
|
61
|
-
import home from "./home";
|
|
62
|
-
import playground from "./playground";
|
|
63
|
-
|
|
64
|
-
export const registry = createModuleRegistry([
|
|
65
|
-
home,
|
|
66
|
-
playground, // pinBottom: true is set automatically by createPlaygroundModule
|
|
67
|
-
]);
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
`createPlaygroundModule` returns a `ShellModule` — pass it directly to
|
|
71
|
-
`createModuleRegistry` alongside your app's own modules.
|
|
72
|
-
|
|
73
|
-
---
|
|
40
|
+
| Peer | Range | Needed for |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `react`, `react-dom` | `>=19` | Everything |
|
|
43
|
+
| `react-router-dom` | `>=7` | The generated routes and the layout outlet |
|
|
44
|
+
| `tailwindcss` | `>=3` | Every page's styling |
|
|
74
45
|
|
|
75
|
-
|
|
46
|
+
Those dependencies carry further peers of their own, and some that are only
|
|
47
|
+
optional down there are required here -- the graph page needs every renderer
|
|
48
|
+
peer, and the JSON editor page needs CodeMirror. Getting that wrong shows up as
|
|
49
|
+
one page throwing rather than as an install error. See
|
|
50
|
+
[getting started](docs/usage/getting-started.md).
|
|
76
51
|
|
|
77
|
-
|
|
78
|
-
`registry.register()` before passing the registry to `createPlaygroundModule`.
|
|
79
|
-
Pages appear in the overview tile grid grouped under your chosen `group` label.
|
|
52
|
+
## Usage
|
|
80
53
|
|
|
81
54
|
```ts
|
|
82
55
|
// src/modules/playground/index.ts
|
|
83
56
|
import { lazy } from "react";
|
|
84
|
-
import {
|
|
57
|
+
import { Boxes } from "lucide-react";
|
|
85
58
|
import {
|
|
86
|
-
createPlaygroundRegistry,
|
|
87
59
|
createPlaygroundModule,
|
|
60
|
+
createPlaygroundRegistry,
|
|
88
61
|
} from "@petrarca/sonnet-playground";
|
|
89
62
|
|
|
90
63
|
const registry = createPlaygroundRegistry();
|
|
91
64
|
|
|
92
|
-
// Register app-specific pages
|
|
93
65
|
registry.register({
|
|
94
|
-
id: "app.
|
|
95
|
-
title: "
|
|
96
|
-
description: "Interactive demo of
|
|
97
|
-
icon:
|
|
66
|
+
id: "app.widgets",
|
|
67
|
+
title: "Widgets",
|
|
68
|
+
description: "Interactive demo of the Widget components.",
|
|
69
|
+
icon: Boxes,
|
|
98
70
|
color: "teal",
|
|
99
|
-
path: "
|
|
100
|
-
component: lazy(() => import("./pages/
|
|
101
|
-
group: "App Components",
|
|
71
|
+
path: "widgets",
|
|
72
|
+
component: lazy(() => import("./pages/PlayWidgets")),
|
|
73
|
+
group: "App Components",
|
|
102
74
|
order: 0,
|
|
103
75
|
});
|
|
104
76
|
|
|
105
77
|
export default createPlaygroundModule(registry);
|
|
106
78
|
```
|
|
107
79
|
|
|
108
|
-
|
|
109
|
-
|
|
80
|
+
`createPlaygroundModule` returns a `ShellModule`, so it goes into
|
|
81
|
+
`createModuleRegistry` alongside your own modules. Its options are `icon`,
|
|
82
|
+
`label`, `basePath`, `overviewTitle`, `overviewSubtitle` and `grouped`; the
|
|
83
|
+
defaults are `FlaskConical`, `"Playground"`, `"/playground"`,
|
|
84
|
+
`"Developer Playground"`, `"Experiment with components, test features, and
|
|
85
|
+
explore capabilities."` and `true`.
|
|
110
86
|
|
|
111
|
-
|
|
112
|
-
|
|
87
|
+
Individual built-in pages are available from
|
|
88
|
+
`@petrarca/sonnet-playground/pages` when you want one on a route of your own.
|
|
113
89
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
## Pages subpath
|
|
117
|
-
|
|
118
|
-
Individual built-in pages are available at `@petrarca/sonnet-playground/pages`
|
|
119
|
-
for consumers who want to cherry-pick or re-export them:
|
|
120
|
-
|
|
121
|
-
```tsx
|
|
122
|
-
import { PlayTypography, PlayColorPalette } from "@petrarca/sonnet-playground/pages";
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
---
|
|
126
|
-
|
|
127
|
-
## createPlaygroundModule options
|
|
128
|
-
|
|
129
|
-
| Option | Type | Default |
|
|
130
|
-
|---|---|---|
|
|
131
|
-
| `icon` | `LucideIcon` | `FlaskConical` |
|
|
132
|
-
| `label` | `string` | `"Playground"` |
|
|
133
|
-
| `basePath` | `string` | `"/playground"` |
|
|
134
|
-
| `overviewTitle` | `string` | `"Developer Playground"` |
|
|
135
|
-
| `overviewSubtitle` | `string` | `""` |
|
|
136
|
-
| `grouped` | `boolean` | `true` |
|
|
90
|
+
## Documentation
|
|
137
91
|
|
|
138
|
-
|
|
92
|
+
- [Usage guides](docs/usage/index.md) -- getting started,
|
|
93
|
+
[adding pages](docs/usage/adding-pages.md) and
|
|
94
|
+
[embedding](docs/usage/embedding.md).
|
|
95
|
+
- [Design docs](docs/design/index.md) -- the registry model and the page
|
|
96
|
+
contract.
|
|
97
|
+
- [sonnet-shell: getting started](../sonnet-shell/docs/usage/getting-started.md)
|
|
98
|
+
-- the application frame this module plugs into.
|
|
99
|
+
- [Workspace documentation](../../docs/README.md) -- how the packages layer and
|
|
100
|
+
the architecture decision records.
|
|
139
101
|
|
|
140
102
|
## License
|
|
141
103
|
|
|
142
|
-
See [LICENSE.md](../../LICENSE.md).
|
|
104
|
+
Apache 2.0. See [LICENSE.md](../../LICENSE.md).
|
|
@@ -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":[]}
|
|
@@ -86,6 +86,131 @@ var AUDIT_SCHEMA = {
|
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
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
|
+
};
|
|
89
214
|
var AUDIT_EDITABLE_PATHS = [
|
|
90
215
|
"/properties/metadata/properties",
|
|
91
216
|
"/properties/actor/properties/metadata/properties",
|
|
@@ -120,11 +245,10 @@ var PROFILES = {
|
|
|
120
245
|
schema: SAMPLE_SCHEMA,
|
|
121
246
|
capabilities: { mode: "data", previews: [] }
|
|
122
247
|
},
|
|
123
|
-
|
|
124
|
-
label: "
|
|
125
|
-
description: "
|
|
126
|
-
schema:
|
|
127
|
-
readOnly: true,
|
|
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,
|
|
128
252
|
capabilities: { previews: ["form", "table", "json", "capabilities"] }
|
|
129
253
|
}
|
|
130
254
|
};
|
|
@@ -188,4 +312,4 @@ function PlaySchemaDesigner() {
|
|
|
188
312
|
export {
|
|
189
313
|
PlaySchemaDesigner
|
|
190
314
|
};
|
|
191
|
-
//# sourceMappingURL=chunk-
|
|
315
|
+
//# sourceMappingURL=chunk-2XMWOZ5O.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/logic-authoring.md in the schema-designer package,\n// 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;AAySrB,SACE,KADF;AAtSN,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;AAQA,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":[]}
|