schema-components 2.0.2 → 2.1.1
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 +133 -1
- package/dist/SchemaComponent-B__6-5-E.d.mts +277 -0
- package/dist/SchemaComponent-BxzzsHsK.mjs +668 -0
- package/dist/adapter-ktQaheWB.d.mts +213 -0
- package/dist/constructorTypes-BdCiMS6e.d.mts +30 -0
- package/dist/core/adapter.d.mts +3 -213
- package/dist/core/constraintHint.d.mts +1 -1
- package/dist/core/constraints.d.mts +2 -2
- package/dist/core/contexts.d.mts +71 -0
- package/dist/core/contexts.mjs +1 -0
- package/dist/core/diagnostics.d.mts +1 -1
- package/dist/core/errors.d.mts +1 -1
- package/dist/core/fieldOrder.d.mts +1 -1
- package/dist/{react → core}/fieldPath.d.mts +2 -2
- package/dist/{react → core}/fieldPath.mjs +3 -3
- package/dist/core/formats.d.mts +1 -1
- package/dist/core/inferValue.d.mts +1 -1
- package/dist/core/limits.d.mts +1 -1
- package/dist/core/merge.d.mts +1 -1
- package/dist/core/normalise.d.mts +2 -2
- package/dist/core/ref.d.mts +1 -1
- package/dist/core/renderField.d.mts +147 -0
- package/dist/core/renderField.mjs +115 -0
- package/dist/core/renderer.d.mts +2 -199
- package/dist/core/swagger2.d.mts +1 -1
- package/dist/core/typeInference.d.mts +1 -982
- package/dist/core/types.d.mts +1 -1
- package/dist/core/unionMatch.d.mts +1 -1
- package/dist/core/version.d.mts +1 -1
- package/dist/core/walkBuilders.d.mts +3 -3
- package/dist/core/walker.d.mts +1 -1
- package/dist/{errors-Dki7tji4.d.mts → errors-DbaI04x2.d.mts} +1 -1
- package/dist/html/a11y.d.mts +2 -2
- package/dist/html/renderToHtml.d.mts +5 -5
- package/dist/html/renderToHtml.mjs +33 -18
- package/dist/html/renderToHtmlStream.d.mts +5 -5
- package/dist/html/renderers.d.mts +1 -1
- package/dist/html/streamRenderers.d.mts +15 -6
- package/dist/html/streamRenderers.mjs +56 -10
- package/dist/{inferValue-Ce-PviSD.d.mts → inferValue-eAnh50EM.d.mts} +3 -3
- package/dist/lit/SchemaComponent.d.mts +125 -0
- package/dist/lit/SchemaComponent.mjs +2 -0
- package/dist/lit/SchemaField.d.mts +65 -0
- package/dist/lit/SchemaField.mjs +2 -0
- package/dist/lit/SchemaView.d.mts +14 -0
- package/dist/lit/SchemaView.mjs +2 -0
- package/dist/lit/constructorTypes.d.mts +2 -0
- package/dist/lit/constructorTypes.mjs +1 -0
- package/dist/lit/contexts.d.mts +78 -0
- package/dist/lit/contexts.mjs +238 -0
- package/dist/lit/defaultResolver.d.mts +33 -0
- package/dist/lit/defaultResolver.mjs +2 -0
- package/dist/lit/registry.d.mts +66 -0
- package/dist/lit/registry.mjs +2 -0
- package/dist/lit/renderers/baseElement.d.mts +131 -0
- package/dist/lit/renderers/baseElement.mjs +109 -0
- package/dist/lit/renderers/recordHelpers.d.mts +25 -0
- package/dist/lit/renderers/recordHelpers.mjs +55 -0
- package/dist/lit/renderers/scArray.d.mts +14 -0
- package/dist/lit/renderers/scArray.mjs +86 -0
- package/dist/lit/renderers/scBoolean.d.mts +15 -0
- package/dist/lit/renderers/scBoolean.mjs +47 -0
- package/dist/lit/renderers/scConditional.d.mts +23 -0
- package/dist/lit/renderers/scConditional.mjs +65 -0
- package/dist/lit/renderers/scDiscriminated.d.mts +23 -0
- package/dist/lit/renderers/scDiscriminated.mjs +138 -0
- package/dist/lit/renderers/scEnum.d.mts +16 -0
- package/dist/lit/renderers/scEnum.mjs +66 -0
- package/dist/lit/renderers/scFile.d.mts +15 -0
- package/dist/lit/renderers/scFile.mjs +53 -0
- package/dist/lit/renderers/scLiteralNullNever.d.mts +30 -0
- package/dist/lit/renderers/scLiteralNullNever.mjs +57 -0
- package/dist/lit/renderers/scNumber.d.mts +15 -0
- package/dist/lit/renderers/scNumber.mjs +64 -0
- package/dist/lit/renderers/scObject.d.mts +14 -0
- package/dist/lit/renderers/scObject.mjs +57 -0
- package/dist/lit/renderers/scRecord.d.mts +14 -0
- package/dist/lit/renderers/scRecord.mjs +112 -0
- package/dist/lit/renderers/scString.d.mts +19 -0
- package/dist/lit/renderers/scString.mjs +165 -0
- package/dist/lit/renderers/scTuple.d.mts +14 -0
- package/dist/lit/renderers/scTuple.mjs +58 -0
- package/dist/lit/renderers/scUnion.d.mts +14 -0
- package/dist/lit/renderers/scUnion.mjs +44 -0
- package/dist/lit/renderers/scUnknown.d.mts +15 -0
- package/dist/lit/renderers/scUnknown.mjs +45 -0
- package/dist/lit/ssr.d.mts +37 -0
- package/dist/lit/ssr.mjs +9565 -0
- package/dist/lit/types.d.mts +2 -0
- package/dist/lit/types.mjs +1 -0
- package/dist/lit/widget.d.mts +71 -0
- package/dist/lit/widget.mjs +87 -0
- package/dist/openapi/ApiCallbacks.d.mts +1 -1
- package/dist/openapi/ApiLinks.d.mts +1 -1
- package/dist/openapi/ApiResponseHeaders.d.mts +1 -1
- package/dist/openapi/ApiSecurity.d.mts +1 -1
- package/dist/openapi/components.d.mts +4 -4
- package/dist/openapi/parser.d.mts +2 -2
- package/dist/openapi/resolve.d.mts +1 -1
- package/dist/preact/SchemaComponent.d.mts +3 -0
- package/dist/preact/SchemaComponent.mjs +26 -0
- package/dist/preact/SchemaErrorBoundary.d.mts +2 -0
- package/dist/preact/SchemaErrorBoundary.mjs +20 -0
- package/dist/preact/SchemaView.d.mts +2 -0
- package/dist/preact/SchemaView.mjs +22 -0
- package/dist/preact/headless.d.mts +2 -0
- package/dist/preact/headless.mjs +18 -0
- package/dist/react/SchemaComponent.d.mts +3 -270
- package/dist/react/SchemaComponent.mjs +41 -32
- package/dist/react/SchemaView.d.mts +6 -6
- package/dist/react/SchemaView.mjs +32 -29
- package/dist/react/a11y.d.mts +2 -2
- package/dist/react/fieldShell.d.mts +1 -1
- package/dist/react/headless.d.mts +1 -1
- package/dist/react/headlessRenderers.d.mts +2 -2
- package/dist/{ref-DdsbekXX.d.mts → ref-DWrQG1Er.d.mts} +1 -1
- package/dist/renderer-ab9E52Bp.d.mts +245 -0
- package/dist/solid/SchemaComponent.d.mts +136 -0
- package/dist/solid/SchemaComponent.mjs +391 -0
- package/dist/solid/SchemaErrorBoundary.d.mts +38 -0
- package/dist/solid/SchemaErrorBoundary.mjs +57 -0
- package/dist/solid/SchemaField.d.mts +40 -0
- package/dist/solid/SchemaField.mjs +113 -0
- package/dist/solid/SchemaView.d.mts +54 -0
- package/dist/solid/SchemaView.mjs +168 -0
- package/dist/solid/a11y.d.mts +70 -0
- package/dist/solid/a11y.mjs +71 -0
- package/dist/solid/contexts.d.mts +37 -0
- package/dist/solid/contexts.mjs +66 -0
- package/dist/solid/headless.d.mts +10 -0
- package/dist/solid/headless.mjs +27 -0
- package/dist/solid/renderers.d.mts +79 -0
- package/dist/solid/renderers.mjs +840 -0
- package/dist/solid/types.d.mts +90 -0
- package/dist/solid/types.mjs +1 -0
- package/dist/solid/widget.d.mts +29 -0
- package/dist/solid/widget.mjs +35 -0
- package/dist/themes/mantine.d.mts +1 -1
- package/dist/themes/mui.d.mts +1 -1
- package/dist/themes/radix.d.mts +1 -1
- package/dist/themes/shadcn.d.mts +1 -1
- package/dist/typeInference-Y8tNEQJk.d.mts +983 -0
- package/dist/types-BCy7K3nk.d.mts +125 -0
- package/package.json +73 -1
- package/src/svelte/SchemaComponent.svelte +427 -0
- package/src/svelte/SchemaErrorBoundary.svelte +66 -0
- package/src/svelte/SchemaField.svelte +216 -0
- package/src/svelte/SchemaProvider.svelte +46 -0
- package/src/svelte/SchemaView.svelte +244 -0
- package/src/svelte/a11y.ts +112 -0
- package/src/svelte/contexts.ts +79 -0
- package/src/svelte/dispatch.ts +267 -0
- package/src/svelte/headless.ts +73 -0
- package/src/svelte/headlessFns.ts +124 -0
- package/src/svelte/renderers/Array.svelte +98 -0
- package/src/svelte/renderers/Boolean.svelte +43 -0
- package/src/svelte/renderers/Conditional.svelte +67 -0
- package/src/svelte/renderers/DiscriminatedUnion.svelte +197 -0
- package/src/svelte/renderers/Enum.svelte +53 -0
- package/src/svelte/renderers/Fallback.svelte +24 -0
- package/src/svelte/renderers/File.svelte +46 -0
- package/src/svelte/renderers/Literal.svelte +29 -0
- package/src/svelte/renderers/Mount.svelte +24 -0
- package/src/svelte/renderers/Negation.svelte +35 -0
- package/src/svelte/renderers/Never.svelte +24 -0
- package/src/svelte/renderers/Null.svelte +19 -0
- package/src/svelte/renderers/Number.svelte +68 -0
- package/src/svelte/renderers/Object.svelte +74 -0
- package/src/svelte/renderers/Record.svelte +134 -0
- package/src/svelte/renderers/RecursionSentinel.svelte +27 -0
- package/src/svelte/renderers/String.svelte +152 -0
- package/src/svelte/renderers/Tuple.svelte +84 -0
- package/src/svelte/renderers/Union.svelte +49 -0
- package/src/svelte/renderers/Unknown.svelte +42 -0
- package/src/svelte/svelte-modules.d.ts +25 -0
- package/src/svelte/types.ts +238 -0
- package/src/svelte/widget.ts +62 -0
- package/src/vue/SchemaComponent.vue +274 -0
- package/src/vue/SchemaErrorBoundary.vue +60 -0
- package/src/vue/SchemaField.vue +178 -0
- package/src/vue/SchemaProvider.vue +39 -0
- package/src/vue/SchemaView.vue +198 -0
- package/src/vue/VNodeHost.ts +32 -0
- package/src/vue/contexts.ts +116 -0
- package/src/vue/eventTargets.ts +35 -0
- package/src/vue/headless.ts +61 -0
- package/src/vue/idPrefix.ts +79 -0
- package/src/vue/renderField.ts +182 -0
- package/src/vue/renderers.ts +1297 -0
- package/src/vue/resolver.ts +45 -0
- package/src/vue/types.ts +140 -0
- package/src/vue/vue-shim.d.ts +25 -0
- package/src/vue/widget.ts +51 -0
- /package/dist/{diagnostics-BTrm3O6J.d.mts → diagnostics-mftUZI7c.d.mts} +0 -0
- /package/dist/{limits-x4OiyJxh.d.mts → limits-Vv9hUbI_.d.mts} +0 -0
- /package/dist/{types-BrYbjC7_.d.mts → types-BBQaEPfE.d.mts} +0 -0
- /package/dist/{version-DL8U5RuA.d.mts → version-BEBx10ND.d.mts} +0 -0
|
@@ -0,0 +1,668 @@
|
|
|
1
|
+
import { isObject, toRecordOrUndefined } from "./core/guards.mjs";
|
|
2
|
+
import "./core/limits.mjs";
|
|
3
|
+
import { SchemaFieldError, SchemaNormalisationError, SchemaRenderError } from "./core/errors.mjs";
|
|
4
|
+
import { normaliseSchema } from "./core/adapter.mjs";
|
|
5
|
+
import { SC_CLASSES } from "./core/cssClasses.mjs";
|
|
6
|
+
import { buildRenderProps } from "./core/renderer.mjs";
|
|
7
|
+
import { walk } from "./core/walker.mjs";
|
|
8
|
+
import { ScString } from "./lit/renderers/scString.mjs";
|
|
9
|
+
import { ScNumber } from "./lit/renderers/scNumber.mjs";
|
|
10
|
+
import { ScBoolean } from "./lit/renderers/scBoolean.mjs";
|
|
11
|
+
import { ScEnum } from "./lit/renderers/scEnum.mjs";
|
|
12
|
+
import { ScObject } from "./lit/renderers/scObject.mjs";
|
|
13
|
+
import { ScArray } from "./lit/renderers/scArray.mjs";
|
|
14
|
+
import { ScTuple } from "./lit/renderers/scTuple.mjs";
|
|
15
|
+
import { ScRecord } from "./lit/renderers/scRecord.mjs";
|
|
16
|
+
import { ScUnion } from "./lit/renderers/scUnion.mjs";
|
|
17
|
+
import { ScDiscriminated } from "./lit/renderers/scDiscriminated.mjs";
|
|
18
|
+
import { ScFile } from "./lit/renderers/scFile.mjs";
|
|
19
|
+
import { ScUnknown } from "./lit/renderers/scUnknown.mjs";
|
|
20
|
+
import { ScLiteral, ScNever, ScNull } from "./lit/renderers/scLiteralNullNever.mjs";
|
|
21
|
+
import { ScConditional, ScNegation } from "./lit/renderers/scConditional.mjs";
|
|
22
|
+
import { resolveLitWidget } from "./lit/widget.mjs";
|
|
23
|
+
import { LitElement, html } from "lit";
|
|
24
|
+
//#region src/lit/SchemaView.ts
|
|
25
|
+
/**
|
|
26
|
+
* `<schema-view>` — read-only Lit Custom Element variant of
|
|
27
|
+
* `<schema-component>`.
|
|
28
|
+
*
|
|
29
|
+
* Parallel to React's `<SchemaView>`: renders the supplied schema +
|
|
30
|
+
* value in read-only mode, never emits a `change` event, and ignores
|
|
31
|
+
* any user input on a nested control. Subclasses
|
|
32
|
+
* `<schema-component>` so the implementation work is just forcing
|
|
33
|
+
* `readOnly = true` and refusing to propagate child change events.
|
|
34
|
+
*
|
|
35
|
+
* **SSR caveat.** This element ALSO runs under `@lit-labs/ssr` for
|
|
36
|
+
* the equivalent of React's server-rendered `<SchemaView>`. The
|
|
37
|
+
* server path uses Declarative Shadow DOM via the `renderToString`
|
|
38
|
+
* helper in `lit/ssr.ts`. See that module's docstring for the
|
|
39
|
+
* documented limitations: `@lit-labs/ssr` is labs status,
|
|
40
|
+
* `@lit/context` does not server-render, and light-DOM-only
|
|
41
|
+
* components are not supported.
|
|
42
|
+
*
|
|
43
|
+
* @packageDocumentation
|
|
44
|
+
*/
|
|
45
|
+
/**
|
|
46
|
+
* Lit Custom Element rendering a schema in read-only mode.
|
|
47
|
+
*
|
|
48
|
+
* Tag: `<schema-view>` (registered by `registerSchemaComponents`).
|
|
49
|
+
*/
|
|
50
|
+
var SchemaView = class extends SchemaComponent {
|
|
51
|
+
constructor() {
|
|
52
|
+
super();
|
|
53
|
+
this.readOnly = true;
|
|
54
|
+
}
|
|
55
|
+
connectedCallback() {
|
|
56
|
+
super.connectedCallback();
|
|
57
|
+
this.readOnly = true;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/lit/SchemaField.ts
|
|
62
|
+
/**
|
|
63
|
+
* `<schema-field>` — Lit Custom Element rendering a single field from
|
|
64
|
+
* a schema by dot-separated `path`.
|
|
65
|
+
*
|
|
66
|
+
* Parallel to React's `<SchemaField>`. The element walks the supplied
|
|
67
|
+
* schema, resolves the field at `path`, and renders just that branch.
|
|
68
|
+
* Useful for forms where the layout is hand-built and each field
|
|
69
|
+
* needs its own renderer slot.
|
|
70
|
+
*
|
|
71
|
+
* Implementation note: `<schema-field>` extends `<schema-component>`
|
|
72
|
+
* so the normalisation / dispatch logic is inherited. The override
|
|
73
|
+
* here intercepts the post-walk tree and substitutes the path-
|
|
74
|
+
* targeted branch.
|
|
75
|
+
*
|
|
76
|
+
* @packageDocumentation
|
|
77
|
+
*/
|
|
78
|
+
/**
|
|
79
|
+
* Lit Custom Element rendering a single sub-field of a schema.
|
|
80
|
+
*
|
|
81
|
+
* Tag: `<schema-field>` (registered by `registerSchemaComponents`).
|
|
82
|
+
*/
|
|
83
|
+
var SchemaField = class extends SchemaComponent {
|
|
84
|
+
static properties = {
|
|
85
|
+
...SchemaComponent.properties,
|
|
86
|
+
path: { attribute: false }
|
|
87
|
+
};
|
|
88
|
+
constructor() {
|
|
89
|
+
super();
|
|
90
|
+
this.path = "";
|
|
91
|
+
}
|
|
92
|
+
render() {
|
|
93
|
+
if (this.schema === void 0 || this.path.length === 0) return html``;
|
|
94
|
+
let jsonSchema;
|
|
95
|
+
let rootMeta;
|
|
96
|
+
let rootDocument;
|
|
97
|
+
try {
|
|
98
|
+
const normalised = normaliseSchema(this.schema, this.ref);
|
|
99
|
+
jsonSchema = normalised.jsonSchema;
|
|
100
|
+
rootMeta = normalised.rootMeta;
|
|
101
|
+
rootDocument = normalised.rootDocument;
|
|
102
|
+
} catch (err) {
|
|
103
|
+
if (err instanceof SchemaNormalisationError) throw err;
|
|
104
|
+
throw new SchemaNormalisationError(err instanceof Error ? err.message : "Failed to normalise schema", this.schema, "unknown");
|
|
105
|
+
}
|
|
106
|
+
const walkOptions = {
|
|
107
|
+
componentMeta: this.meta,
|
|
108
|
+
rootMeta,
|
|
109
|
+
fieldOverrides: toRecordOrUndefined(this.fields),
|
|
110
|
+
rootDocument
|
|
111
|
+
};
|
|
112
|
+
const root = walk(jsonSchema, walkOptions);
|
|
113
|
+
const located = locateField(root, this.path);
|
|
114
|
+
if (located === void 0) throw new SchemaFieldError(`No field at path ${this.path}`, root, this.path);
|
|
115
|
+
const { tree, value } = located;
|
|
116
|
+
const valueToRender = value ?? tree.defaultValue;
|
|
117
|
+
const userResolver = this.resolver ?? createDefaultLitResolver();
|
|
118
|
+
const renderChild = this.makeRenderChild(0, this.path, userResolver);
|
|
119
|
+
return this.renderField(tree, valueToRender, (next) => {
|
|
120
|
+
this.dispatchEvent(new CustomEvent("change", { detail: {
|
|
121
|
+
value: next,
|
|
122
|
+
path: this.path
|
|
123
|
+
} }));
|
|
124
|
+
}, userResolver, renderChild, this.path);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Resolve a dot-separated path through a walked field tree, also
|
|
129
|
+
* tracking the value at the same position. Mirrors
|
|
130
|
+
* `react/fieldPath.ts::resolvePath` + `resolveValue` rolled into one.
|
|
131
|
+
*
|
|
132
|
+
* @internal
|
|
133
|
+
*/
|
|
134
|
+
function locateField(root, path) {
|
|
135
|
+
const segments = splitPath(path);
|
|
136
|
+
let currentTree = root;
|
|
137
|
+
let currentValue = void 0;
|
|
138
|
+
for (const segment of segments) {
|
|
139
|
+
const numericIndex = parseIndex(segment);
|
|
140
|
+
if (numericIndex !== void 0) {
|
|
141
|
+
if (currentTree.type === "array" && currentTree.element) {
|
|
142
|
+
currentTree = currentTree.element;
|
|
143
|
+
currentValue = Array.isArray(currentValue) ? currentValue[numericIndex] : void 0;
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (currentTree.type === "tuple") {
|
|
147
|
+
const next = currentTree.prefixItems[numericIndex];
|
|
148
|
+
if (next === void 0) return void 0;
|
|
149
|
+
currentTree = next;
|
|
150
|
+
currentValue = Array.isArray(currentValue) ? currentValue[numericIndex] : void 0;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (currentTree.type === "object") {
|
|
156
|
+
const next = currentTree.fields[segment];
|
|
157
|
+
if (next === void 0) return void 0;
|
|
158
|
+
currentTree = next;
|
|
159
|
+
currentValue = isObject(currentValue) ? currentValue[segment] : void 0;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (currentTree.type === "record") {
|
|
163
|
+
currentTree = currentTree.valueType;
|
|
164
|
+
currentValue = isObject(currentValue) ? currentValue[segment] : void 0;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
tree: currentTree,
|
|
171
|
+
value: currentValue
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Split a dot-separated path with bracketed indices into its
|
|
176
|
+
* structural segments. `"a.b[0].c"` → `["a", "b", "[0]", "c"]`.
|
|
177
|
+
*/
|
|
178
|
+
function splitPath(path) {
|
|
179
|
+
const out = [];
|
|
180
|
+
let current = "";
|
|
181
|
+
for (const ch of path) {
|
|
182
|
+
if (ch === ".") {
|
|
183
|
+
if (current.length > 0) {
|
|
184
|
+
out.push(current);
|
|
185
|
+
current = "";
|
|
186
|
+
}
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (ch === "[") {
|
|
190
|
+
if (current.length > 0) out.push(current);
|
|
191
|
+
current = "[";
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (ch === "]") {
|
|
195
|
+
current += "]";
|
|
196
|
+
out.push(current);
|
|
197
|
+
current = "";
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
current += ch;
|
|
201
|
+
}
|
|
202
|
+
if (current.length > 0) out.push(current);
|
|
203
|
+
return out;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Parse a `[i]` bracketed-index segment to a number. Returns
|
|
207
|
+
* `undefined` for non-numeric or non-bracketed input.
|
|
208
|
+
*/
|
|
209
|
+
function parseIndex(segment) {
|
|
210
|
+
if (!segment.startsWith("[") || !segment.endsWith("]")) return void 0;
|
|
211
|
+
const inner = segment.slice(1, -1);
|
|
212
|
+
if (inner.length === 0) return void 0;
|
|
213
|
+
const n = Number(inner);
|
|
214
|
+
if (!Number.isInteger(n) || n < 0) return void 0;
|
|
215
|
+
return n;
|
|
216
|
+
}
|
|
217
|
+
//#endregion
|
|
218
|
+
//#region src/lit/registry.ts
|
|
219
|
+
/**
|
|
220
|
+
* Mapping from the canonical built-in tag (without prefix) to the
|
|
221
|
+
* `BaseScElement` subclass that backs it. Exported so consumers can
|
|
222
|
+
* introspect what {@link registerSchemaComponents} will register —
|
|
223
|
+
* useful for diagnostics and for building documentation surfaces.
|
|
224
|
+
*
|
|
225
|
+
* The top-level orchestrator elements (`schema-component`,
|
|
226
|
+
* `schema-view`, `schema-field`) are listed alongside the per-type
|
|
227
|
+
* `<sc-*>` elements; the structural type relaxes to `HTMLElement` so
|
|
228
|
+
* every constructor is assignable.
|
|
229
|
+
*/
|
|
230
|
+
const BUILT_IN_ELEMENTS = Object.freeze({
|
|
231
|
+
"schema-component": SchemaComponent,
|
|
232
|
+
"schema-view": SchemaView,
|
|
233
|
+
"schema-field": SchemaField,
|
|
234
|
+
"sc-string": ScString,
|
|
235
|
+
"sc-number": ScNumber,
|
|
236
|
+
"sc-boolean": ScBoolean,
|
|
237
|
+
"sc-enum": ScEnum,
|
|
238
|
+
"sc-object": ScObject,
|
|
239
|
+
"sc-array": ScArray,
|
|
240
|
+
"sc-tuple": ScTuple,
|
|
241
|
+
"sc-record": ScRecord,
|
|
242
|
+
"sc-union": ScUnion,
|
|
243
|
+
"sc-discriminated": ScDiscriminated,
|
|
244
|
+
"sc-conditional": ScConditional,
|
|
245
|
+
"sc-negation": ScNegation,
|
|
246
|
+
"sc-literal": ScLiteral,
|
|
247
|
+
"sc-null": ScNull,
|
|
248
|
+
"sc-never": ScNever,
|
|
249
|
+
"sc-file": ScFile,
|
|
250
|
+
"sc-unknown": ScUnknown
|
|
251
|
+
});
|
|
252
|
+
/**
|
|
253
|
+
* Register every built-in `<sc-*>` Custom Element on the global
|
|
254
|
+
* `customElements` registry, optionally namespaced under `prefix`.
|
|
255
|
+
*
|
|
256
|
+
* Re-registering the same tag is a no-op — `customElements.get(tag)`
|
|
257
|
+
* is checked first so calling this function twice (or alongside
|
|
258
|
+
* another library that registered the same tag) does not throw.
|
|
259
|
+
*
|
|
260
|
+
* @param prefix - Optional prefix prepended to every built-in tag.
|
|
261
|
+
* E.g. `registerSchemaComponents("myapp-")` registers
|
|
262
|
+
* `<myapp-sc-string>`, `<myapp-sc-number>`, …, avoiding collisions
|
|
263
|
+
* with another library that may have shipped its own `<sc-*>`
|
|
264
|
+
* elements. Pass an empty string (the default) to use the
|
|
265
|
+
* canonical names.
|
|
266
|
+
* @returns A {@link RegistrationResult} carrying the canonical-tag →
|
|
267
|
+
* registered-tag map and the list of elements skipped because the
|
|
268
|
+
* tag was already registered. The map is used by the default
|
|
269
|
+
* resolver to look up the right tag when the consumer chose a
|
|
270
|
+
* custom prefix.
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* ```ts
|
|
274
|
+
* // Default registration — tags are <sc-string>, <sc-number>, ...
|
|
275
|
+
* import { registerSchemaComponents } from "schema-components/lit/registry";
|
|
276
|
+
* const tags = registerSchemaComponents();
|
|
277
|
+
*
|
|
278
|
+
* // Namespaced registration — tags are <myapp-sc-string>, ...
|
|
279
|
+
* const namespaced = registerSchemaComponents("myapp-");
|
|
280
|
+
* ```
|
|
281
|
+
*/
|
|
282
|
+
function registerSchemaComponents(prefix = "") {
|
|
283
|
+
const registered = {};
|
|
284
|
+
const skipped = [];
|
|
285
|
+
for (const [canonical, ctor] of Object.entries(BUILT_IN_ELEMENTS)) {
|
|
286
|
+
const tag = `${prefix}${canonical}`;
|
|
287
|
+
if (customElements.get(tag) !== void 0) {
|
|
288
|
+
registered[canonical] = tag;
|
|
289
|
+
skipped.push(tag);
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
customElements.define(tag, ctor);
|
|
293
|
+
registered[canonical] = tag;
|
|
294
|
+
}
|
|
295
|
+
return {
|
|
296
|
+
tags: registered,
|
|
297
|
+
skipped
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
//#endregion
|
|
301
|
+
//#region src/lit/defaultResolver.ts
|
|
302
|
+
/**
|
|
303
|
+
* Default Lit {@link LitComponentResolver} that dispatches every
|
|
304
|
+
* built-in schema type to the matching `<sc-*>` Custom Element.
|
|
305
|
+
*
|
|
306
|
+
* Where the React adapter's headless resolver composes per-type
|
|
307
|
+
* functions that return React elements, the Lit equivalent emits a
|
|
308
|
+
* `<sc-string>` / `<sc-number>` / … Custom Element with the per-field
|
|
309
|
+
* props attached. The element itself is responsible for rendering —
|
|
310
|
+
* the resolver is just a tag-name lookup with property assignment.
|
|
311
|
+
*
|
|
312
|
+
* When the consumer registered the elements with a non-empty prefix
|
|
313
|
+
* (`registerSchemaComponents("myapp-")`), the resolver looks up the
|
|
314
|
+
* prefixed tag from the {@link RegistrationResult.tags} map so the
|
|
315
|
+
* right element is instantiated. A consumer that never called
|
|
316
|
+
* `registerSchemaComponents` falls back to the canonical `sc-*`
|
|
317
|
+
* names — letting tests render the elements directly with
|
|
318
|
+
* `customElements.define` while keeping the production path
|
|
319
|
+
* consumer-controlled.
|
|
320
|
+
*
|
|
321
|
+
* Implementation note: because Lit's `html` tagged template does not
|
|
322
|
+
* support dynamically-named element tags, the resolver builds each
|
|
323
|
+
* Custom Element via `document.createElement` and interpolates the
|
|
324
|
+
* resulting `Node` into the template. This trades one shared cache
|
|
325
|
+
* entry for any tag prefix — Lit's template caching is keyed on the
|
|
326
|
+
* literal, so all 17 dispatches share the same cache slot — for the
|
|
327
|
+
* loss of strictly-typed attribute templating. Per-field props are
|
|
328
|
+
* still assigned through statically-typed property accessors below.
|
|
329
|
+
*
|
|
330
|
+
* @packageDocumentation
|
|
331
|
+
*/
|
|
332
|
+
/**
|
|
333
|
+
* Map of every `WalkedField.type` to its matching canonical `<sc-*>`
|
|
334
|
+
* tag. Exhaustive over the discriminated union — adding a new variant
|
|
335
|
+
* to the walker forces a deliberate update here.
|
|
336
|
+
*
|
|
337
|
+
* Exported so theme adapters can introspect the mapping when building
|
|
338
|
+
* their own resolvers (e.g. a shadcn-flavoured Web Components theme
|
|
339
|
+
* that wraps `<sc-string>` in a `<sl-input>`-style shell).
|
|
340
|
+
*/
|
|
341
|
+
const TYPE_TO_CANONICAL_TAG = Object.freeze({
|
|
342
|
+
string: "sc-string",
|
|
343
|
+
number: "sc-number",
|
|
344
|
+
boolean: "sc-boolean",
|
|
345
|
+
null: "sc-null",
|
|
346
|
+
enum: "sc-enum",
|
|
347
|
+
object: "sc-object",
|
|
348
|
+
array: "sc-array",
|
|
349
|
+
tuple: "sc-tuple",
|
|
350
|
+
record: "sc-record",
|
|
351
|
+
union: "sc-union",
|
|
352
|
+
discriminatedUnion: "sc-discriminated",
|
|
353
|
+
conditional: "sc-conditional",
|
|
354
|
+
negation: "sc-negation",
|
|
355
|
+
literal: "sc-literal",
|
|
356
|
+
file: "sc-file",
|
|
357
|
+
never: "sc-never",
|
|
358
|
+
unknown: "sc-unknown"
|
|
359
|
+
});
|
|
360
|
+
/**
|
|
361
|
+
* Build the default Lit resolver for the supplied
|
|
362
|
+
* {@link RegistrationResult}.
|
|
363
|
+
*
|
|
364
|
+
* Each render function emits a Lit `html` template whose body is a
|
|
365
|
+
* dynamically-created `<sc-*>` element with every field prop assigned.
|
|
366
|
+
* The change callback is forwarded directly so user input on a leaf
|
|
367
|
+
* renderer reaches the orchestrator without going through a Custom
|
|
368
|
+
* Event boundary on the fast path.
|
|
369
|
+
*
|
|
370
|
+
* When no `registration` is supplied, the resolver emits the
|
|
371
|
+
* canonical `sc-*` tags. Useful in tests where `customElements.define`
|
|
372
|
+
* may have been called separately and the consumer doesn't need a
|
|
373
|
+
* prefixed registration object.
|
|
374
|
+
*/
|
|
375
|
+
function createDefaultLitResolver(registration) {
|
|
376
|
+
const tags = registration?.tags ?? Object.fromEntries(Object.keys(BUILT_IN_ELEMENTS).map((tag) => [tag, tag]));
|
|
377
|
+
function tagFor(type) {
|
|
378
|
+
const canonical = TYPE_TO_CANONICAL_TAG[type];
|
|
379
|
+
return tags[canonical] ?? canonical;
|
|
380
|
+
}
|
|
381
|
+
function elementRenderer(type) {
|
|
382
|
+
return (props) => renderTagged(tagFor(type), props);
|
|
383
|
+
}
|
|
384
|
+
return {
|
|
385
|
+
string: elementRenderer("string"),
|
|
386
|
+
number: elementRenderer("number"),
|
|
387
|
+
boolean: elementRenderer("boolean"),
|
|
388
|
+
null: elementRenderer("null"),
|
|
389
|
+
enum: elementRenderer("enum"),
|
|
390
|
+
object: elementRenderer("object"),
|
|
391
|
+
array: elementRenderer("array"),
|
|
392
|
+
tuple: elementRenderer("tuple"),
|
|
393
|
+
record: elementRenderer("record"),
|
|
394
|
+
union: elementRenderer("union"),
|
|
395
|
+
discriminatedUnion: elementRenderer("discriminatedUnion"),
|
|
396
|
+
conditional: elementRenderer("conditional"),
|
|
397
|
+
negation: elementRenderer("negation"),
|
|
398
|
+
literal: elementRenderer("literal"),
|
|
399
|
+
file: elementRenderer("file"),
|
|
400
|
+
never: elementRenderer("never"),
|
|
401
|
+
unknown: elementRenderer("unknown")
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Build a Lit template fragment that renders a single Custom Element
|
|
406
|
+
* by tag name with every per-field prop attached.
|
|
407
|
+
*
|
|
408
|
+
* Pure DOM-side path. The `lit-labs/ssr` path (`renderToString` in
|
|
409
|
+
* `lit/ssr.ts`) takes a separate code path that emits Declarative
|
|
410
|
+
* Shadow DOM markup; this helper is for the browser render only.
|
|
411
|
+
*/
|
|
412
|
+
function renderTagged(tag, props) {
|
|
413
|
+
if (typeof document === "undefined") return html``;
|
|
414
|
+
const el = document.createElement(tag);
|
|
415
|
+
applyProperties(el, props);
|
|
416
|
+
return html`${el}`;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Assign every prop from {@link LitRenderProps} onto the created
|
|
420
|
+
* element. Element constructors created with `document.createElement`
|
|
421
|
+
* are typed as `HTMLElement`; we narrow through the `BaseScElement`
|
|
422
|
+
* field shape (every built-in implements it) so the assignment is
|
|
423
|
+
* statically typed without an `as` cast.
|
|
424
|
+
*
|
|
425
|
+
* If the element turns out NOT to be a `BaseScElement` (a tag prefix
|
|
426
|
+
* collision with a consumer-registered third-party element, or a
|
|
427
|
+
* misconfigured override), the assignment still succeeds because the
|
|
428
|
+
* built-in field shape is structurally identical to a plain object —
|
|
429
|
+
* the consumer is responsible for matching the field surface.
|
|
430
|
+
*/
|
|
431
|
+
function applyProperties(el, props) {
|
|
432
|
+
Reflect.set(el, "tree", props.tree);
|
|
433
|
+
Reflect.set(el, "value", props.value);
|
|
434
|
+
Reflect.set(el, "readOnly", props.readOnly);
|
|
435
|
+
Reflect.set(el, "writeOnly", props.writeOnly);
|
|
436
|
+
Reflect.set(el, "path", props.path);
|
|
437
|
+
Reflect.set(el, "meta", props.meta);
|
|
438
|
+
Reflect.set(el, "constraints", props.constraints);
|
|
439
|
+
if (props.examples !== void 0) Reflect.set(el, "examples", props.examples);
|
|
440
|
+
Reflect.set(el, "change", props.change);
|
|
441
|
+
Reflect.set(el, "renderChild", props.renderChild);
|
|
442
|
+
}
|
|
443
|
+
//#endregion
|
|
444
|
+
//#region src/lit/SchemaComponent.ts
|
|
445
|
+
/**
|
|
446
|
+
* `<schema-component>` — top-level Lit Custom Element for editable
|
|
447
|
+
* schema-driven UI.
|
|
448
|
+
*
|
|
449
|
+
* Parity with the React `<SchemaComponent>` for the rendering path:
|
|
450
|
+
*
|
|
451
|
+
* - Accepts a Zod schema, JSON Schema, or OpenAPI document via the
|
|
452
|
+
* `schema` property (NOT attribute — see "Property-only schema/
|
|
453
|
+
* value/resolver" in `lit/README.md`).
|
|
454
|
+
* - Walks the schema via `normaliseSchema` → `walk` from
|
|
455
|
+
* `core/walker.ts` and dispatches every node through a Lit
|
|
456
|
+
* resolver — by default, the {@link createDefaultLitResolver}
|
|
457
|
+
* resolver that renders the built-in `<sc-*>` Custom Elements.
|
|
458
|
+
* - Emits a public `change` Custom Event on every user edit, with
|
|
459
|
+
* the updated root value in `event.detail.value`. Cross-framework
|
|
460
|
+
* wrappers translate this into the host framework's event /
|
|
461
|
+
* binding primitive (React's `onChange`, Vue `@change`, Svelte
|
|
462
|
+
* `on:change`).
|
|
463
|
+
*
|
|
464
|
+
* The element is registered by {@link registerSchemaComponents}; tag
|
|
465
|
+
* name defaults to `<schema-component>`. Pass a non-empty prefix
|
|
466
|
+
* (`registerSchemaComponents("myapp-")`) to namespace the top-level
|
|
467
|
+
* tag alongside every `<sc-*>` child.
|
|
468
|
+
*
|
|
469
|
+
* @packageDocumentation
|
|
470
|
+
*/
|
|
471
|
+
/**
|
|
472
|
+
* Lit Custom Element for editable schema-driven UI.
|
|
473
|
+
*
|
|
474
|
+
* Tag: `<schema-component>` (default) or `<{prefix}schema-component>`
|
|
475
|
+
* (when `registerSchemaComponents(prefix)` is called).
|
|
476
|
+
*
|
|
477
|
+
* **Required:** call {@link registerSchemaComponents} once at module
|
|
478
|
+
* setup before instantiating this element in HTML markup, otherwise
|
|
479
|
+
* none of the per-type `<sc-*>` children will upgrade and the tree
|
|
480
|
+
* will render as unknown elements.
|
|
481
|
+
*/
|
|
482
|
+
var SchemaComponent = class extends LitElement {
|
|
483
|
+
/**
|
|
484
|
+
* Element property declarations.
|
|
485
|
+
*
|
|
486
|
+
* All four "data" properties (`schema`, `value`, `resolver`,
|
|
487
|
+
* `widgets`) carry `attribute: false`: Custom Element attributes
|
|
488
|
+
* are strings, and these payloads (an arbitrary Zod schema, an
|
|
489
|
+
* arbitrary JS value, a resolver function map, a widget tag map)
|
|
490
|
+
* cannot round-trip through attribute serialisation. Set them via
|
|
491
|
+
* direct property assignment.
|
|
492
|
+
*
|
|
493
|
+
* `readOnly` is a boolean attribute (and reflects to DOM) so the
|
|
494
|
+
* common "render read-only view" case is reachable from plain
|
|
495
|
+
* HTML markup (`<schema-component readonly></schema-component>`).
|
|
496
|
+
* The capitalisation is `readOnly` on the property and `readonly`
|
|
497
|
+
* on the attribute — matching the HTML `readonly` attribute on
|
|
498
|
+
* `<input>` / `<textarea>`.
|
|
499
|
+
*/
|
|
500
|
+
static properties = {
|
|
501
|
+
schema: { attribute: false },
|
|
502
|
+
value: { attribute: false },
|
|
503
|
+
resolver: { attribute: false },
|
|
504
|
+
widgets: { attribute: false },
|
|
505
|
+
fields: { attribute: false },
|
|
506
|
+
meta: { attribute: false },
|
|
507
|
+
ref: { attribute: false },
|
|
508
|
+
io: { attribute: false },
|
|
509
|
+
idPrefix: { attribute: false },
|
|
510
|
+
onDiagnostic: { attribute: false },
|
|
511
|
+
readOnly: {
|
|
512
|
+
type: Boolean,
|
|
513
|
+
reflect: true,
|
|
514
|
+
attribute: "readonly"
|
|
515
|
+
},
|
|
516
|
+
strict: { type: Boolean }
|
|
517
|
+
};
|
|
518
|
+
constructor() {
|
|
519
|
+
super();
|
|
520
|
+
this.schema = void 0;
|
|
521
|
+
this.value = void 0;
|
|
522
|
+
this.readOnly = false;
|
|
523
|
+
this.strict = false;
|
|
524
|
+
}
|
|
525
|
+
render() {
|
|
526
|
+
if (this.schema === void 0) return html``;
|
|
527
|
+
let jsonSchema;
|
|
528
|
+
let rootMeta;
|
|
529
|
+
let rootDocument;
|
|
530
|
+
try {
|
|
531
|
+
const diagnosticsOptions = this.onDiagnostic !== void 0 || this.strict ? this.buildDiagnostics() : void 0;
|
|
532
|
+
const normaliseOptions = diagnosticsOptions !== void 0 || this.io !== void 0 ? {
|
|
533
|
+
...diagnosticsOptions !== void 0 ? { diagnostics: diagnosticsOptions } : {},
|
|
534
|
+
...this.io !== void 0 ? { io: this.io } : {}
|
|
535
|
+
} : void 0;
|
|
536
|
+
const normalised = normaliseSchema(this.schema, this.ref, normaliseOptions);
|
|
537
|
+
jsonSchema = normalised.jsonSchema;
|
|
538
|
+
rootMeta = normalised.rootMeta;
|
|
539
|
+
rootDocument = normalised.rootDocument;
|
|
540
|
+
} catch (err) {
|
|
541
|
+
if (err instanceof SchemaNormalisationError) throw err;
|
|
542
|
+
throw new SchemaNormalisationError(err instanceof Error ? err.message : "Failed to normalise schema", this.schema, "unknown");
|
|
543
|
+
}
|
|
544
|
+
const mergedMeta = { ...this.meta };
|
|
545
|
+
if (this.readOnly) mergedMeta.readOnly = true;
|
|
546
|
+
const walkOptions = {
|
|
547
|
+
componentMeta: mergedMeta,
|
|
548
|
+
rootMeta,
|
|
549
|
+
fieldOverrides: toRecordOrUndefined(this.fields),
|
|
550
|
+
rootDocument,
|
|
551
|
+
...this.onDiagnostic !== void 0 || this.strict ? { diagnostics: this.buildDiagnostics() } : {}
|
|
552
|
+
};
|
|
553
|
+
const tree = walk(jsonSchema, walkOptions);
|
|
554
|
+
const userResolver = this.resolver ?? createDefaultLitResolver();
|
|
555
|
+
const rootPath = this.idPrefix ?? "root";
|
|
556
|
+
const rootChange = (next) => {
|
|
557
|
+
this.value = next;
|
|
558
|
+
this.dispatchEvent(new CustomEvent("change", {
|
|
559
|
+
detail: { value: next },
|
|
560
|
+
bubbles: false,
|
|
561
|
+
composed: false
|
|
562
|
+
}));
|
|
563
|
+
this.requestUpdate();
|
|
564
|
+
};
|
|
565
|
+
const renderChild = this.makeRenderChild(0, rootPath, userResolver);
|
|
566
|
+
return this.renderField(tree, this.value ?? tree.defaultValue, rootChange, userResolver, renderChild, rootPath);
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Build the recursive `renderChild` closure threaded through every
|
|
570
|
+
* container renderer.
|
|
571
|
+
*/
|
|
572
|
+
makeRenderChild(currentDepth, parentPath, userResolver) {
|
|
573
|
+
const joinPath = (parent, suffix) => {
|
|
574
|
+
if (suffix === void 0) return parent;
|
|
575
|
+
return suffix.startsWith("[") ? `${parent}${suffix}` : `${parent}.${suffix}`;
|
|
576
|
+
};
|
|
577
|
+
return (childTree, childValue, childChange, pathSuffix) => {
|
|
578
|
+
const childPath = joinPath(parentPath, pathSuffix);
|
|
579
|
+
if (currentDepth >= 10) {
|
|
580
|
+
const label = typeof childTree.meta.description === "string" ? childTree.meta.description : "schema";
|
|
581
|
+
return html`<fieldset class=${SC_CLASSES.recursive}>
|
|
582
|
+
<em>${`↻ ${label} (recursive)`}</em>
|
|
583
|
+
</fieldset>`;
|
|
584
|
+
}
|
|
585
|
+
const grandChild = this.makeRenderChild(currentDepth + 1, childPath, userResolver);
|
|
586
|
+
return this.renderField(childTree, childValue, childChange, userResolver, grandChild, childPath);
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Dispatch a single walked field through the resolver, widget
|
|
591
|
+
* registry, and recursion limit. Parallel to
|
|
592
|
+
* `renderField` in `react/SchemaComponent.tsx`.
|
|
593
|
+
*/
|
|
594
|
+
renderField(tree, value, change, userResolver, renderChild, path) {
|
|
595
|
+
const componentHint = tree.meta.component;
|
|
596
|
+
if (typeof componentHint === "string") {
|
|
597
|
+
const widget = resolveLitWidget(componentHint, this.widgets);
|
|
598
|
+
if (widget !== void 0) {
|
|
599
|
+
if (typeof document === "undefined") return html``;
|
|
600
|
+
const el = document.createElement(widget);
|
|
601
|
+
this.applyWidgetProperties(el, tree, value, change, path);
|
|
602
|
+
return html`${el}`;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
const renderFn = userResolver[litResolverKey(tree.type)];
|
|
606
|
+
if (renderFn !== void 0) {
|
|
607
|
+
const adaptedRenderChild = (childTree, childValue, childOnChange, pathSuffix) => renderChild(childTree, childValue, childOnChange, pathSuffix);
|
|
608
|
+
const coreProps = buildRenderProps(tree, value, change, adaptedRenderChild, path);
|
|
609
|
+
const litProps = {
|
|
610
|
+
value: coreProps.value,
|
|
611
|
+
readOnly: coreProps.readOnly,
|
|
612
|
+
writeOnly: coreProps.writeOnly,
|
|
613
|
+
meta: coreProps.meta,
|
|
614
|
+
constraints: coreProps.constraints,
|
|
615
|
+
path: coreProps.path,
|
|
616
|
+
tree: coreProps.tree,
|
|
617
|
+
change,
|
|
618
|
+
renderChild,
|
|
619
|
+
...coreProps.examples !== void 0 ? { examples: coreProps.examples } : {}
|
|
620
|
+
};
|
|
621
|
+
try {
|
|
622
|
+
return renderFn(litProps);
|
|
623
|
+
} catch (err) {
|
|
624
|
+
throw new SchemaRenderError(err instanceof Error ? err.message : `Render function threw for type "${tree.type}"`, tree, tree.type, err);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
if (value === void 0 || value === null) return html`<span>—</span>`;
|
|
628
|
+
return html`<span>${typeof value === "string" ? value : JSON.stringify(value)}</span>`;
|
|
629
|
+
}
|
|
630
|
+
applyWidgetProperties(el, tree, value, change, path) {
|
|
631
|
+
Reflect.set(el, "tree", tree);
|
|
632
|
+
Reflect.set(el, "value", value);
|
|
633
|
+
Reflect.set(el, "readOnly", this.readOnly);
|
|
634
|
+
Reflect.set(el, "path", path);
|
|
635
|
+
Reflect.set(el, "meta", tree.meta);
|
|
636
|
+
Reflect.set(el, "constraints", tree.constraints);
|
|
637
|
+
Reflect.set(el, "change", change);
|
|
638
|
+
}
|
|
639
|
+
buildDiagnostics() {
|
|
640
|
+
const opts = {};
|
|
641
|
+
if (this.onDiagnostic !== void 0) opts.diagnostics = this.onDiagnostic;
|
|
642
|
+
if (this.strict) opts.strict = true;
|
|
643
|
+
return opts;
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
function litResolverKey(type) {
|
|
647
|
+
switch (type) {
|
|
648
|
+
case "string":
|
|
649
|
+
case "number":
|
|
650
|
+
case "boolean":
|
|
651
|
+
case "null":
|
|
652
|
+
case "enum":
|
|
653
|
+
case "object":
|
|
654
|
+
case "array":
|
|
655
|
+
case "tuple":
|
|
656
|
+
case "record":
|
|
657
|
+
case "union":
|
|
658
|
+
case "discriminatedUnion":
|
|
659
|
+
case "conditional":
|
|
660
|
+
case "negation":
|
|
661
|
+
case "literal":
|
|
662
|
+
case "file":
|
|
663
|
+
case "never":
|
|
664
|
+
case "unknown": return type;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
//#endregion
|
|
668
|
+
export { registerSchemaComponents as a, BUILT_IN_ELEMENTS as i, TYPE_TO_CANONICAL_TAG as n, SchemaField as o, createDefaultLitResolver as r, SchemaView as s, SchemaComponent as t };
|