schema-components 1.28.2 → 1.29.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/{adapter-DqlAnZ_w.d.mts → adapter-DcWi4XXn.d.mts} +60 -9
- package/dist/core/adapter.d.mts +2 -2
- package/dist/core/adapter.mjs +20 -1
- package/dist/core/constraints.d.mts +34 -2
- package/dist/core/constraints.mjs +32 -0
- package/dist/core/cssClasses.d.mts +1 -0
- package/dist/core/diagnostics.d.mts +1 -1
- package/dist/core/errors.d.mts +1 -1
- package/dist/core/errors.mjs +22 -12
- package/dist/core/fieldOrder.d.mts +1 -1
- package/dist/core/formats.d.mts +7 -1
- package/dist/core/formats.mjs +6 -0
- package/dist/core/limits.d.mts +1 -1
- package/dist/core/limits.mjs +1 -0
- package/dist/core/merge.d.mts +11 -1
- package/dist/core/normalise.d.mts +17 -2
- package/dist/core/openapiConstants.d.mts +1 -0
- package/dist/core/ref.d.mts +1 -1
- package/dist/core/renderer.d.mts +1 -1
- package/dist/core/renderer.mjs +5 -0
- package/dist/core/swagger2.d.mts +1 -1
- package/dist/core/typeInference.d.mts +2 -2
- package/dist/core/types.d.mts +1 -1
- package/dist/core/types.mjs +17 -0
- package/dist/core/unionMatch.d.mts +1 -1
- package/dist/core/version.d.mts +1 -1
- package/dist/core/walkBuilders.d.mts +48 -3
- package/dist/core/walkBuilders.mjs +30 -0
- package/dist/core/walker.d.mts +14 -1
- package/dist/core/walker.mjs +13 -0
- package/dist/{diagnostics-Cbwak-ZX.d.mts → diagnostics-ByEzkjrA.d.mts} +8 -0
- package/dist/{errors-DQSIK4n1.d.mts → errors-D8JndRwI.d.mts} +23 -13
- package/dist/html/a11y.d.mts +2 -2
- package/dist/html/html.d.mts +11 -0
- package/dist/html/html.mjs +11 -0
- package/dist/html/renderToHtml.d.mts +25 -5
- package/dist/html/renderToHtml.mjs +18 -3
- package/dist/html/renderToHtmlStream.d.mts +41 -9
- package/dist/html/renderToHtmlStream.mjs +32 -7
- package/dist/html/renderers.d.mts +7 -1
- package/dist/html/renderers.mjs +6 -0
- package/dist/html/streamRenderers.d.mts +31 -3
- package/dist/html/streamRenderers.mjs +28 -0
- package/dist/{limits-DJhgx5Ay.d.mts → limits-DswmqWuy.d.mts} +1 -0
- package/dist/openapi/ApiCallbacks.d.mts +13 -1
- package/dist/openapi/ApiCallbacks.mjs +7 -0
- package/dist/openapi/ApiLinks.d.mts +13 -1
- package/dist/openapi/ApiLinks.mjs +7 -0
- package/dist/openapi/ApiResponseHeaders.d.mts +13 -1
- package/dist/openapi/ApiResponseHeaders.mjs +7 -0
- package/dist/openapi/ApiSecurity.d.mts +14 -1
- package/dist/openapi/ApiSecurity.mjs +8 -0
- package/dist/openapi/components.d.mts +96 -12
- package/dist/openapi/components.mjs +71 -2
- package/dist/openapi/parser.d.mts +129 -2
- package/dist/openapi/parser.mjs +72 -0
- package/dist/openapi/resolve.d.mts +7 -1
- package/dist/react/SchemaComponent.d.mts +84 -6
- package/dist/react/SchemaComponent.mjs +62 -1
- package/dist/react/SchemaErrorBoundary.d.mts +18 -1
- package/dist/react/SchemaErrorBoundary.mjs +13 -1
- package/dist/react/SchemaView.d.mts +32 -8
- package/dist/react/SchemaView.mjs +20 -5
- package/dist/react/a11y.d.mts +1 -1
- package/dist/react/fieldPath.d.mts +1 -1
- package/dist/react/headless.d.mts +1 -1
- package/dist/react/headlessRenderers.d.mts +13 -2
- package/dist/react/headlessRenderers.mjs +12 -1
- package/dist/{ref-TdeMfaV_.d.mts → ref-CPh8rKQ3.d.mts} +1 -1
- package/dist/{renderer-Ul9taFYp.d.mts → renderer-OaOz-n6-.d.mts} +17 -1
- package/dist/themes/mantine.d.mts +29 -3
- package/dist/themes/mantine.mjs +28 -2
- package/dist/themes/mui.d.mts +29 -2
- package/dist/themes/mui.mjs +29 -2
- package/dist/themes/radix.d.mts +40 -3
- package/dist/themes/radix.mjs +39 -2
- package/dist/themes/shadcn.d.mts +22 -1
- package/dist/themes/shadcn.mjs +21 -0
- package/dist/{types-BTB73MB8.d.mts → types-C2Ay1FEh.d.mts} +23 -0
- package/dist/{version-ZzL5R6cS.d.mts → version-DL8U5RuA.d.mts} +6 -0
- package/package.json +5 -1
|
@@ -23,10 +23,22 @@ import { Component } from "react";
|
|
|
23
23
|
* - Errors in server-side rendering
|
|
24
24
|
*/
|
|
25
25
|
/**
|
|
26
|
-
* React error boundary that catches
|
|
26
|
+
* React error boundary that catches rendering errors from
|
|
27
|
+
* `SchemaComponent`, theme adapters, and any descendant.
|
|
27
28
|
*
|
|
28
29
|
* Provides a `reset` callback that clears the error state, allowing
|
|
29
30
|
* the children to re-render (e.g. after fixing a bad schema prop).
|
|
31
|
+
* Does not catch errors thrown from event handlers, async work, or
|
|
32
|
+
* server-side rendering — those paths must be handled by the host
|
|
33
|
+
* application.
|
|
34
|
+
*
|
|
35
|
+
* @group Components
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* <SchemaErrorBoundary fallback={(error) => <p>{error.message}</p>}>
|
|
39
|
+
* <SchemaComponent schema={userSchema} value={user} onChange={setUser} />
|
|
40
|
+
* </SchemaErrorBoundary>
|
|
41
|
+
* ```
|
|
30
42
|
*/
|
|
31
43
|
var SchemaErrorBoundary = class extends Component {
|
|
32
44
|
state = { error: void 0 };
|
|
@@ -1,12 +1,21 @@
|
|
|
1
|
-
import { w as SchemaMeta } from "../types-
|
|
2
|
-
import { t as Diagnostic } from "../diagnostics-
|
|
3
|
-
import { i as SchemaIoSide } from "../adapter-
|
|
4
|
-
import { r as ComponentResolver } from "../renderer-
|
|
1
|
+
import { w as SchemaMeta } from "../types-C2Ay1FEh.mjs";
|
|
2
|
+
import { t as Diagnostic } from "../diagnostics-ByEzkjrA.mjs";
|
|
3
|
+
import { i as SchemaIoSide } from "../adapter-DcWi4XXn.mjs";
|
|
4
|
+
import { r as ComponentResolver } from "../renderer-OaOz-n6-.mjs";
|
|
5
5
|
import { RejectUnrepresentableZod } from "../core/typeInference.mjs";
|
|
6
6
|
import { InferredValue, WidgetMap } from "./SchemaComponent.mjs";
|
|
7
7
|
import { ReactNode } from "react";
|
|
8
8
|
|
|
9
9
|
//#region src/react/SchemaView.d.ts
|
|
10
|
+
/**
|
|
11
|
+
* Props accepted by {@link SchemaView}.
|
|
12
|
+
*
|
|
13
|
+
* Mirrors `SchemaComponentProps` for the read-only / RSC path — no
|
|
14
|
+
* `onChange`, no `validate`, and the theme is supplied via the
|
|
15
|
+
* `resolver` prop because Server Components cannot read React context.
|
|
16
|
+
*
|
|
17
|
+
* @group Components
|
|
18
|
+
*/
|
|
10
19
|
interface SchemaViewProps<T = unknown, Ref extends string | undefined = undefined, Mode extends SchemaIoSide = "output"> {
|
|
11
20
|
/**
|
|
12
21
|
* Zod schema, JSON Schema object, or OpenAPI document.
|
|
@@ -61,11 +70,26 @@ interface SchemaViewProps<T = unknown, Ref extends string | undefined = undefine
|
|
|
61
70
|
idPrefix?: string;
|
|
62
71
|
}
|
|
63
72
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
73
|
+
* Read-only schema renderer that is safe to use inside a React Server
|
|
74
|
+
* Component.
|
|
75
|
+
*
|
|
76
|
+
* Uses no context, state, or effects — the only hook called is
|
|
77
|
+
* `useId()`, which is RSC-safe. Always renders read-only; pair with
|
|
78
|
+
* `SchemaComponent` (which requires `"use client"`) when an editable
|
|
79
|
+
* form is required. Because Server Components cannot read React
|
|
80
|
+
* context, the theme adapter is passed via the `resolver` prop rather
|
|
81
|
+
* than `SchemaProvider`.
|
|
82
|
+
*
|
|
83
|
+
* @group Components
|
|
84
|
+
* @example
|
|
85
|
+
* ```tsx
|
|
86
|
+
* import { SchemaView } from "schema-components/react/SchemaView";
|
|
66
87
|
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
88
|
+
* export default async function Page() {
|
|
89
|
+
* const user = await getUser();
|
|
90
|
+
* return <SchemaView schema={userSchema} value={user} />;
|
|
91
|
+
* }
|
|
92
|
+
* ```
|
|
69
93
|
*/
|
|
70
94
|
declare function SchemaView<T = unknown, Ref extends string | undefined = undefined, Mode extends SchemaIoSide = "output">({
|
|
71
95
|
schema: schemaInput,
|
|
@@ -5,8 +5,8 @@ import { buildRenderProps, getRenderFunction, mergeResolvers } from "../core/ren
|
|
|
5
5
|
import { walk } from "../core/walker.mjs";
|
|
6
6
|
import { headlessResolver } from "./headless.mjs";
|
|
7
7
|
import { joinPath, sanitisePrefix } from "./SchemaComponent.mjs";
|
|
8
|
-
import { createElement, isValidElement, useId } from "react";
|
|
9
8
|
import { jsx } from "react/jsx-runtime";
|
|
9
|
+
import { createElement, isValidElement, useId } from "react";
|
|
10
10
|
//#region src/react/SchemaView.tsx
|
|
11
11
|
/**
|
|
12
12
|
* React Server Component for read-only schema rendering.
|
|
@@ -36,11 +36,26 @@ import { jsx } from "react/jsx-runtime";
|
|
|
36
36
|
* is passed explicitly.
|
|
37
37
|
*/
|
|
38
38
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
39
|
+
* Read-only schema renderer that is safe to use inside a React Server
|
|
40
|
+
* Component.
|
|
41
|
+
*
|
|
42
|
+
* Uses no context, state, or effects — the only hook called is
|
|
43
|
+
* `useId()`, which is RSC-safe. Always renders read-only; pair with
|
|
44
|
+
* `SchemaComponent` (which requires `"use client"`) when an editable
|
|
45
|
+
* form is required. Because Server Components cannot read React
|
|
46
|
+
* context, the theme adapter is passed via the `resolver` prop rather
|
|
47
|
+
* than `SchemaProvider`.
|
|
48
|
+
*
|
|
49
|
+
* @group Components
|
|
50
|
+
* @example
|
|
51
|
+
* ```tsx
|
|
52
|
+
* import { SchemaView } from "schema-components/react/SchemaView";
|
|
41
53
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
54
|
+
* export default async function Page() {
|
|
55
|
+
* const user = await getUser();
|
|
56
|
+
* return <SchemaView schema={userSchema} value={user} />;
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
44
59
|
*/
|
|
45
60
|
function SchemaView({ schema: schemaInput, ref: refInput, io, value, fields, meta: componentMeta, description, resolver, widgets, onDiagnostic, strict, idPrefix }) {
|
|
46
61
|
const generatedId = useId();
|
package/dist/react/a11y.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { j as WalkedField } from "../types-
|
|
2
|
-
import { l as RenderProps } from "../renderer-
|
|
1
|
+
import { j as WalkedField } from "../types-C2Ay1FEh.mjs";
|
|
2
|
+
import { l as RenderProps } from "../renderer-OaOz-n6-.mjs";
|
|
3
3
|
import { ReactNode } from "react";
|
|
4
4
|
|
|
5
5
|
//#region src/react/headlessRenderers.d.ts
|
|
@@ -20,10 +20,15 @@ declare function toReactNode(value: unknown): ReactNode;
|
|
|
20
20
|
* Throws on an empty path; see `fieldDomId` for the rationale.
|
|
21
21
|
*/
|
|
22
22
|
declare function inputId(path: string): string;
|
|
23
|
+
/** Headless renderer for `StringField` — plain `<input>` / `<span>`. */
|
|
23
24
|
declare function renderString(props: RenderProps): ReactNode;
|
|
25
|
+
/** Headless renderer for `NumberField` — plain `<input type="number">`. */
|
|
24
26
|
declare function renderNumber(props: RenderProps): ReactNode;
|
|
27
|
+
/** Headless renderer for `BooleanField` — plain `<input type="checkbox">`. */
|
|
25
28
|
declare function renderBoolean(props: RenderProps): ReactNode;
|
|
29
|
+
/** Headless renderer for `EnumField` — plain `<select>` listing each option. */
|
|
26
30
|
declare function renderEnum(props: RenderProps): ReactNode;
|
|
31
|
+
/** Headless renderer for `ObjectField` — `<fieldset>` per object with one child per property. */
|
|
27
32
|
declare function renderObject(props: RenderProps): ReactNode;
|
|
28
33
|
/**
|
|
29
34
|
* Compute the default value for a freshly added record entry based on the
|
|
@@ -42,9 +47,13 @@ declare function nextRecordKey(existing: readonly string[], base?: string): stri
|
|
|
42
47
|
* or when newKey collides with an existing key.
|
|
43
48
|
*/
|
|
44
49
|
declare function renameRecordKey(obj: Record<string, unknown>, oldKey: string, newKey: string): Record<string, unknown>;
|
|
50
|
+
/** Headless renderer for `RecordField` — editable key/value rows with add/remove controls. */
|
|
45
51
|
declare function renderRecord(props: RenderProps): ReactNode;
|
|
52
|
+
/** Headless renderer for `ArrayField` — ordered list with add/remove controls. */
|
|
46
53
|
declare function renderArray(props: RenderProps): ReactNode;
|
|
54
|
+
/** Headless renderer for plain `UnionField` — picks the matching option and renders it. */
|
|
47
55
|
declare function renderUnion(props: RenderProps): ReactNode;
|
|
56
|
+
/** Headless renderer for `DiscriminatedUnionField` — tabbed UI driven by the discriminator. */
|
|
48
57
|
declare function renderDiscriminatedUnion(props: RenderProps): ReactNode;
|
|
49
58
|
/**
|
|
50
59
|
* Pure helper: convert a tab index into the new value the discriminated
|
|
@@ -54,6 +63,7 @@ declare function renderDiscriminatedUnion(props: RenderProps): ReactNode;
|
|
|
54
63
|
* without rendering the tabs component (which relies on React hooks).
|
|
55
64
|
*/
|
|
56
65
|
declare function discriminatedUnionValueForTab(optionLabels: readonly string[], discKey: string, newIndex: number): Record<string, string> | undefined;
|
|
66
|
+
/** Headless renderer for `FileField` — plain `<input type="file">`. */
|
|
57
67
|
declare function renderFile(props: RenderProps): ReactNode;
|
|
58
68
|
/**
|
|
59
69
|
* Render a literal field — `z.literal("a")` or `{ const: 5 }`.
|
|
@@ -106,6 +116,7 @@ declare function renderConditional(props: RenderProps): ReactNode;
|
|
|
106
116
|
* beneath an explanatory preamble.
|
|
107
117
|
*/
|
|
108
118
|
declare function renderNegation(props: RenderProps): ReactNode;
|
|
119
|
+
/** Headless renderer for `UnknownField` — JSON-encoded fallback for unconstrained values. */
|
|
109
120
|
declare function renderUnknown(props: RenderProps): ReactNode;
|
|
110
121
|
//#endregion
|
|
111
122
|
export { defaultRecordValue, discriminatedUnionValueForTab, inputId, nextRecordKey, renameRecordKey, renderArray, renderBoolean, renderConditional, renderDiscriminatedUnion, renderEnum, renderFile, renderLiteral, renderNegation, renderNever, renderNull, renderNumber, renderObject, renderRecord, renderString, renderTuple, renderUnion, renderUnknown, toReactNode };
|
|
@@ -7,8 +7,8 @@ import { fieldDomId, panelIdFor, tabIdFor } from "../core/idPath.mjs";
|
|
|
7
7
|
import { matchUnionOption, resolveDiscriminatedActive } from "../core/unionMatch.mjs";
|
|
8
8
|
import { displayJsonValue } from "../core/walkBuilders.mjs";
|
|
9
9
|
import { buildAriaAttrs } from "./a11y.mjs";
|
|
10
|
-
import { isValidElement, useCallback, useEffect, useRef } from "react";
|
|
11
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { isValidElement, useCallback, useEffect, useRef } from "react";
|
|
12
12
|
//#region src/react/headlessRenderers.tsx
|
|
13
13
|
/**
|
|
14
14
|
* Headless renderer functions — one per schema type.
|
|
@@ -61,6 +61,7 @@ function formatTime(value) {
|
|
|
61
61
|
function inputId(path) {
|
|
62
62
|
return fieldDomId(path);
|
|
63
63
|
}
|
|
64
|
+
/** Headless renderer for `StringField` — plain `<input>` / `<span>`. */
|
|
64
65
|
function renderString(props) {
|
|
65
66
|
const id = inputId(props.path);
|
|
66
67
|
if (props.readOnly) {
|
|
@@ -150,6 +151,7 @@ function renderString(props) {
|
|
|
150
151
|
...ariaAttrs
|
|
151
152
|
});
|
|
152
153
|
}
|
|
154
|
+
/** Headless renderer for `NumberField` — plain `<input type="number">`. */
|
|
153
155
|
function renderNumber(props) {
|
|
154
156
|
const id = inputId(props.path);
|
|
155
157
|
if (props.readOnly) {
|
|
@@ -178,6 +180,7 @@ function renderNumber(props) {
|
|
|
178
180
|
...ariaAttrs
|
|
179
181
|
});
|
|
180
182
|
}
|
|
183
|
+
/** Headless renderer for `BooleanField` — plain `<input type="checkbox">`. */
|
|
181
184
|
function renderBoolean(props) {
|
|
182
185
|
const id = inputId(props.path);
|
|
183
186
|
if (props.readOnly) {
|
|
@@ -203,6 +206,7 @@ function renderBoolean(props) {
|
|
|
203
206
|
...ariaAttrs
|
|
204
207
|
});
|
|
205
208
|
}
|
|
209
|
+
/** Headless renderer for `EnumField` — plain `<select>` listing each option. */
|
|
206
210
|
function renderEnum(props) {
|
|
207
211
|
const id = inputId(props.path);
|
|
208
212
|
const enumValue = typeof props.value === "string" ? props.value : "";
|
|
@@ -232,6 +236,7 @@ function renderEnum(props) {
|
|
|
232
236
|
})]
|
|
233
237
|
});
|
|
234
238
|
}
|
|
239
|
+
/** Headless renderer for `ObjectField` — `<fieldset>` per object with one child per property. */
|
|
235
240
|
function renderObject(props) {
|
|
236
241
|
if (props.tree.type !== "object") return null;
|
|
237
242
|
const obj = isObject(props.value) ? props.value : {};
|
|
@@ -297,6 +302,7 @@ function renameRecordKey(obj, oldKey, newKey) {
|
|
|
297
302
|
for (const [k, v] of Object.entries(obj)) renamed[k === oldKey ? newKey : k] = v;
|
|
298
303
|
return renamed;
|
|
299
304
|
}
|
|
305
|
+
/** Headless renderer for `RecordField` — editable key/value rows with add/remove controls. */
|
|
300
306
|
function renderRecord(props) {
|
|
301
307
|
if (props.tree.type !== "record") return null;
|
|
302
308
|
const obj = isObject(props.value) ? props.value : {};
|
|
@@ -377,6 +383,7 @@ function renderRecord(props) {
|
|
|
377
383
|
})]
|
|
378
384
|
});
|
|
379
385
|
}
|
|
386
|
+
/** Headless renderer for `ArrayField` — ordered list with add/remove controls. */
|
|
380
387
|
function renderArray(props) {
|
|
381
388
|
if (props.tree.type !== "array") return null;
|
|
382
389
|
const arr = Array.isArray(props.value) ? props.value : [];
|
|
@@ -396,6 +403,7 @@ function renderArray(props) {
|
|
|
396
403
|
})
|
|
397
404
|
});
|
|
398
405
|
}
|
|
406
|
+
/** Headless renderer for plain `UnionField` — picks the matching option and renders it. */
|
|
399
407
|
function renderUnion(props) {
|
|
400
408
|
const options = props.tree.type === "union" || props.tree.type === "discriminatedUnion" ? props.tree.options : void 0;
|
|
401
409
|
if (options === void 0 || options.length === 0) {
|
|
@@ -408,6 +416,7 @@ function renderUnion(props) {
|
|
|
408
416
|
if (firstOption !== void 0) return toReactNode(props.renderChild(firstOption, props.value, props.onChange));
|
|
409
417
|
return /* @__PURE__ */ jsx("span", { children: "—" });
|
|
410
418
|
}
|
|
419
|
+
/** Headless renderer for `DiscriminatedUnionField` — tabbed UI driven by the discriminator. */
|
|
411
420
|
function renderDiscriminatedUnion(props) {
|
|
412
421
|
if (props.tree.type !== "discriminatedUnion") {
|
|
413
422
|
if (props.value === void 0 || props.value === null) return /* @__PURE__ */ jsx("span", { children: "—" });
|
|
@@ -533,6 +542,7 @@ function DiscriminatedUnionTabs({ options, optionLabels, activeIndex, path, disc
|
|
|
533
542
|
children: activeOption !== void 0 && toReactNode(props.renderChild(activeOption, props.value, props.onChange))
|
|
534
543
|
})] });
|
|
535
544
|
}
|
|
545
|
+
/** Headless renderer for `FileField` — plain `<input type="file">`. */
|
|
536
546
|
function renderFile(props) {
|
|
537
547
|
const id = inputId(props.path);
|
|
538
548
|
const accept = props.constraints.mimeTypes?.join(",");
|
|
@@ -701,6 +711,7 @@ function renderNegation(props) {
|
|
|
701
711
|
]
|
|
702
712
|
});
|
|
703
713
|
}
|
|
714
|
+
/** Headless renderer for `UnknownField` — JSON-encoded fallback for unconstrained values. */
|
|
704
715
|
function renderUnknown(props) {
|
|
705
716
|
const id = inputId(props.path);
|
|
706
717
|
if (props.readOnly) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as StringConstraints, f as FileConstraints, j as WalkedField, t as ArrayConstraints, w as SchemaMeta, x as ObjectConstraints, y as NumberConstraints } from "./types-
|
|
1
|
+
import { E as StringConstraints, f as FileConstraints, j as WalkedField, t as ArrayConstraints, w as SchemaMeta, x as ObjectConstraints, y as NumberConstraints } from "./types-C2Ay1FEh.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/core/renderer.d.ts
|
|
4
4
|
/**
|
|
@@ -93,7 +93,18 @@ interface HtmlRenderProps extends BaseFieldProps {
|
|
|
93
93
|
* from `tree.editability`.
|
|
94
94
|
*/
|
|
95
95
|
declare function buildRenderProps(tree: WalkedField, value: unknown, onChange: ((next: unknown) => void) | undefined, renderChild: RenderProps["renderChild"], path: string): RenderProps;
|
|
96
|
+
/**
|
|
97
|
+
* Signature for a React render function attached to a
|
|
98
|
+
* {@link ComponentResolver}. Receives the per-field {@link RenderProps}
|
|
99
|
+
* built by the walker and returns any ReactNode-compatible value.
|
|
100
|
+
*/
|
|
96
101
|
type RenderFunction = (props: RenderProps) => unknown;
|
|
102
|
+
/**
|
|
103
|
+
* Theme adapter — maps every schema field type to its React renderer.
|
|
104
|
+
* Unset keys fall back to the headless resolver. Pass to
|
|
105
|
+
* `SchemaProvider` (or `SchemaView.resolver`) to drive every
|
|
106
|
+
* schema-driven render with a specific theme.
|
|
107
|
+
*/
|
|
97
108
|
interface ComponentResolver {
|
|
98
109
|
string?: RenderFunction;
|
|
99
110
|
number?: RenderFunction;
|
|
@@ -140,6 +151,11 @@ interface HtmlResolver {
|
|
|
140
151
|
never?: HtmlRenderFunction;
|
|
141
152
|
unknown?: HtmlRenderFunction;
|
|
142
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Canonical list of resolver keys, one per {@link WalkedField} variant.
|
|
156
|
+
* Iterated by the resolver merge helpers so adding a new key here is the
|
|
157
|
+
* single point of change when a new field variant is introduced.
|
|
158
|
+
*/
|
|
143
159
|
declare const RESOLVER_KEYS: readonly ["string", "number", "boolean", "null", "enum", "object", "array", "tuple", "record", "union", "discriminatedUnion", "conditional", "negation", "literal", "file", "never", "unknown"];
|
|
144
160
|
type ResolverKey = (typeof RESOLVER_KEYS)[number];
|
|
145
161
|
/**
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import { r as ComponentResolver } from "../renderer-
|
|
1
|
+
import { r as ComponentResolver } from "../renderer-OaOz-n6-.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/themes/mantine.d.ts
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Inject real Mantine element types into the resolver. Call once at
|
|
6
|
+
* application startup before rendering any schema-driven component so
|
|
7
|
+
* that {@link mantineResolver}'s renderers delegate to the supplied
|
|
8
|
+
* Mantine primitives.
|
|
7
9
|
*
|
|
8
10
|
* `Text` is required so read-only scalars render as a styled Mantine
|
|
9
11
|
* `<Text>` element instead of a bare `<span>`, matching the visual
|
|
10
12
|
* weight of the editable variants.
|
|
13
|
+
*
|
|
14
|
+
* @group Themes
|
|
11
15
|
*/
|
|
12
16
|
declare function registerMantineComponents(components: {
|
|
13
17
|
TextInput: React.ElementType;
|
|
@@ -17,6 +21,28 @@ declare function registerMantineComponents(components: {
|
|
|
17
21
|
Fieldset: React.ElementType;
|
|
18
22
|
Text: React.ElementType;
|
|
19
23
|
}): void;
|
|
24
|
+
/**
|
|
25
|
+
* Component resolver mapping schema field types to Mantine primitives —
|
|
26
|
+
* `TextInput`, `NumberInput`, `Switch`, `Select`, `Fieldset`, `Text`.
|
|
27
|
+
*
|
|
28
|
+
* Pass to `SchemaProvider` to render schema-driven UI through Mantine.
|
|
29
|
+
* Requires `@mantine/core` installed in the consuming project and a
|
|
30
|
+
* one-time call to {@link registerMantineComponents} to inject the
|
|
31
|
+
* actual Mantine element types.
|
|
32
|
+
*
|
|
33
|
+
* @group Themes
|
|
34
|
+
* @example
|
|
35
|
+
* ```tsx
|
|
36
|
+
* import { TextInput, NumberInput, Switch, Select, Fieldset, Text } from "@mantine/core";
|
|
37
|
+
* import { mantineResolver, registerMantineComponents } from "schema-components/themes/mantine";
|
|
38
|
+
*
|
|
39
|
+
* registerMantineComponents({ TextInput, NumberInput, Switch, Select, Fieldset, Text });
|
|
40
|
+
*
|
|
41
|
+
* <SchemaProvider resolver={mantineResolver}>
|
|
42
|
+
* <SchemaComponent schema={userSchema} value={user} onChange={setUser} />
|
|
43
|
+
* </SchemaProvider>
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
20
46
|
declare const mantineResolver: ComponentResolver;
|
|
21
47
|
//#endregion
|
|
22
48
|
export { mantineResolver, registerMantineComponents };
|
package/dist/themes/mantine.mjs
CHANGED
|
@@ -20,12 +20,16 @@ let MantineSelect = (props) => /* @__PURE__ */ jsx("select", { ...props });
|
|
|
20
20
|
let MantineFieldset = (props) => /* @__PURE__ */ jsx("fieldset", { ...props });
|
|
21
21
|
let MantineText = (props) => /* @__PURE__ */ jsx("span", { ...props });
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* Inject real Mantine element types into the resolver. Call once at
|
|
24
|
+
* application startup before rendering any schema-driven component so
|
|
25
|
+
* that {@link mantineResolver}'s renderers delegate to the supplied
|
|
26
|
+
* Mantine primitives.
|
|
25
27
|
*
|
|
26
28
|
* `Text` is required so read-only scalars render as a styled Mantine
|
|
27
29
|
* `<Text>` element instead of a bare `<span>`, matching the visual
|
|
28
30
|
* weight of the editable variants.
|
|
31
|
+
*
|
|
32
|
+
* @group Themes
|
|
29
33
|
*/
|
|
30
34
|
function registerMantineComponents(components) {
|
|
31
35
|
MantineTextInput = components.TextInput;
|
|
@@ -156,6 +160,28 @@ function buildResolver() {
|
|
|
156
160
|
if (headlessResolver.unknown !== void 0) resolver.unknown = headlessResolver.unknown;
|
|
157
161
|
return resolver;
|
|
158
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Component resolver mapping schema field types to Mantine primitives —
|
|
165
|
+
* `TextInput`, `NumberInput`, `Switch`, `Select`, `Fieldset`, `Text`.
|
|
166
|
+
*
|
|
167
|
+
* Pass to `SchemaProvider` to render schema-driven UI through Mantine.
|
|
168
|
+
* Requires `@mantine/core` installed in the consuming project and a
|
|
169
|
+
* one-time call to {@link registerMantineComponents} to inject the
|
|
170
|
+
* actual Mantine element types.
|
|
171
|
+
*
|
|
172
|
+
* @group Themes
|
|
173
|
+
* @example
|
|
174
|
+
* ```tsx
|
|
175
|
+
* import { TextInput, NumberInput, Switch, Select, Fieldset, Text } from "@mantine/core";
|
|
176
|
+
* import { mantineResolver, registerMantineComponents } from "schema-components/themes/mantine";
|
|
177
|
+
*
|
|
178
|
+
* registerMantineComponents({ TextInput, NumberInput, Switch, Select, Fieldset, Text });
|
|
179
|
+
*
|
|
180
|
+
* <SchemaProvider resolver={mantineResolver}>
|
|
181
|
+
* <SchemaComponent schema={userSchema} value={user} onChange={setUser} />
|
|
182
|
+
* </SchemaProvider>
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
159
185
|
const mantineResolver = buildResolver();
|
|
160
186
|
//#endregion
|
|
161
187
|
export { mantineResolver, registerMantineComponents };
|
package/dist/themes/mui.d.mts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import { r as ComponentResolver } from "../renderer-
|
|
1
|
+
import { r as ComponentResolver } from "../renderer-OaOz-n6-.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/themes/mui.d.ts
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Inject real MUI element types into the resolver. Call once at
|
|
6
|
+
* application startup before rendering any schema-driven component so
|
|
7
|
+
* that {@link muiResolver}'s renderers delegate to the supplied MUI
|
|
8
|
+
* primitives.
|
|
9
|
+
*
|
|
10
|
+
* @group Themes
|
|
6
11
|
*/
|
|
7
12
|
declare function registerMuiComponents(components: {
|
|
8
13
|
TextField: React.ElementType;
|
|
@@ -12,6 +17,28 @@ declare function registerMuiComponents(components: {
|
|
|
12
17
|
MenuItem: React.ElementType;
|
|
13
18
|
FormControlLabel: React.ElementType;
|
|
14
19
|
}): void;
|
|
20
|
+
/**
|
|
21
|
+
* Component resolver mapping schema field types to MUI (Material UI)
|
|
22
|
+
* primitives — `TextField`, `Checkbox`, `Typography`, etc.
|
|
23
|
+
*
|
|
24
|
+
* Pass to `SchemaProvider` to render schema-driven UI through MUI.
|
|
25
|
+
* Requires `@mui/material` installed in the consuming project and a
|
|
26
|
+
* one-time call to {@link registerMuiComponents} to inject the actual
|
|
27
|
+
* MUI element types.
|
|
28
|
+
*
|
|
29
|
+
* @group Themes
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* import { TextField, Checkbox, Typography, Box, MenuItem, FormControlLabel } from "@mui/material";
|
|
33
|
+
* import { muiResolver, registerMuiComponents } from "schema-components/themes/mui";
|
|
34
|
+
*
|
|
35
|
+
* registerMuiComponents({ TextField, Checkbox, Typography, Box, MenuItem, FormControlLabel });
|
|
36
|
+
*
|
|
37
|
+
* <SchemaProvider resolver={muiResolver}>
|
|
38
|
+
* <SchemaComponent schema={userSchema} value={user} onChange={setUser} />
|
|
39
|
+
* </SchemaProvider>
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
15
42
|
declare const muiResolver: ComponentResolver;
|
|
16
43
|
//#endregion
|
|
17
44
|
export { muiResolver, registerMuiComponents };
|
package/dist/themes/mui.mjs
CHANGED
|
@@ -2,8 +2,8 @@ import { isObject } from "../core/guards.mjs";
|
|
|
2
2
|
import { sortFieldsByOrder } from "../core/fieldOrder.mjs";
|
|
3
3
|
import { inputId, toReactNode } from "../react/headlessRenderers.mjs";
|
|
4
4
|
import { headlessResolver } from "../react/headless.mjs";
|
|
5
|
-
import { isValidElement } from "react";
|
|
6
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { isValidElement } from "react";
|
|
7
7
|
//#region src/themes/mui.tsx
|
|
8
8
|
function ariaRequired(tree) {
|
|
9
9
|
return { required: tree.isOptional === false };
|
|
@@ -212,7 +212,12 @@ let MuiFormControlLabel = (props) => {
|
|
|
212
212
|
});
|
|
213
213
|
};
|
|
214
214
|
/**
|
|
215
|
-
*
|
|
215
|
+
* Inject real MUI element types into the resolver. Call once at
|
|
216
|
+
* application startup before rendering any schema-driven component so
|
|
217
|
+
* that {@link muiResolver}'s renderers delegate to the supplied MUI
|
|
218
|
+
* primitives.
|
|
219
|
+
*
|
|
220
|
+
* @group Themes
|
|
216
221
|
*/
|
|
217
222
|
function registerMuiComponents(components) {
|
|
218
223
|
MuiTextField = components.TextField;
|
|
@@ -239,6 +244,28 @@ function buildResolver() {
|
|
|
239
244
|
if (headlessResolver.unknown !== void 0) resolver.unknown = headlessResolver.unknown;
|
|
240
245
|
return resolver;
|
|
241
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* Component resolver mapping schema field types to MUI (Material UI)
|
|
249
|
+
* primitives — `TextField`, `Checkbox`, `Typography`, etc.
|
|
250
|
+
*
|
|
251
|
+
* Pass to `SchemaProvider` to render schema-driven UI through MUI.
|
|
252
|
+
* Requires `@mui/material` installed in the consuming project and a
|
|
253
|
+
* one-time call to {@link registerMuiComponents} to inject the actual
|
|
254
|
+
* MUI element types.
|
|
255
|
+
*
|
|
256
|
+
* @group Themes
|
|
257
|
+
* @example
|
|
258
|
+
* ```tsx
|
|
259
|
+
* import { TextField, Checkbox, Typography, Box, MenuItem, FormControlLabel } from "@mui/material";
|
|
260
|
+
* import { muiResolver, registerMuiComponents } from "schema-components/themes/mui";
|
|
261
|
+
*
|
|
262
|
+
* registerMuiComponents({ TextField, Checkbox, Typography, Box, MenuItem, FormControlLabel });
|
|
263
|
+
*
|
|
264
|
+
* <SchemaProvider resolver={muiResolver}>
|
|
265
|
+
* <SchemaComponent schema={userSchema} value={user} onChange={setUser} />
|
|
266
|
+
* </SchemaProvider>
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
242
269
|
const muiResolver = buildResolver();
|
|
243
270
|
//#endregion
|
|
244
271
|
export { muiResolver, registerMuiComponents };
|
package/dist/themes/radix.d.mts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { r as ComponentResolver } from "../renderer-
|
|
1
|
+
import { r as ComponentResolver } from "../renderer-OaOz-n6-.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/themes/radix.d.ts
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* Inject real Radix Themes element types into the resolver. Call once
|
|
6
|
+
* at application startup before rendering any schema-driven component
|
|
7
|
+
* so that {@link radixResolver}'s renderers delegate to the supplied
|
|
8
|
+
* Radix primitives.
|
|
9
|
+
*
|
|
10
|
+
* @group Themes
|
|
7
11
|
*/
|
|
8
12
|
declare function registerRadixComponents(components: {
|
|
9
13
|
Box: React.ElementType;
|
|
@@ -16,6 +20,39 @@ declare function registerRadixComponents(components: {
|
|
|
16
20
|
Text: React.ElementType;
|
|
17
21
|
TextField: React.ElementType;
|
|
18
22
|
}): void;
|
|
23
|
+
/**
|
|
24
|
+
* Component resolver mapping schema field types to Radix Themes
|
|
25
|
+
* primitives — `Box`, `Checkbox`, `Flex`, `Select.*`, `Text`,
|
|
26
|
+
* `TextField`.
|
|
27
|
+
*
|
|
28
|
+
* Pass to `SchemaProvider` to render schema-driven UI through Radix
|
|
29
|
+
* Themes. Requires `@radix-ui/themes` installed in the consuming
|
|
30
|
+
* project and a one-time call to {@link registerRadixComponents} to
|
|
31
|
+
* inject the actual Radix element types.
|
|
32
|
+
*
|
|
33
|
+
* @group Themes
|
|
34
|
+
* @example
|
|
35
|
+
* ```tsx
|
|
36
|
+
* import * as Radix from "@radix-ui/themes";
|
|
37
|
+
* import { radixResolver, registerRadixComponents } from "schema-components/themes/radix";
|
|
38
|
+
*
|
|
39
|
+
* registerRadixComponents({
|
|
40
|
+
* Box: Radix.Box,
|
|
41
|
+
* Checkbox: Radix.Checkbox,
|
|
42
|
+
* Flex: Radix.Flex,
|
|
43
|
+
* SelectRoot: Radix.Select.Root,
|
|
44
|
+
* SelectTrigger: Radix.Select.Trigger,
|
|
45
|
+
* SelectContent: Radix.Select.Content,
|
|
46
|
+
* SelectItem: Radix.Select.Item,
|
|
47
|
+
* Text: Radix.Text,
|
|
48
|
+
* TextField: Radix.TextField.Root,
|
|
49
|
+
* });
|
|
50
|
+
*
|
|
51
|
+
* <SchemaProvider resolver={radixResolver}>
|
|
52
|
+
* <SchemaComponent schema={userSchema} value={user} onChange={setUser} />
|
|
53
|
+
* </SchemaProvider>
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
19
56
|
declare const radixResolver: ComponentResolver;
|
|
20
57
|
//#endregion
|
|
21
58
|
export { radixResolver, registerRadixComponents };
|
package/dist/themes/radix.mjs
CHANGED
|
@@ -25,8 +25,12 @@ let RadixSelectItem = (props) => /* @__PURE__ */ jsx("option", { ...props });
|
|
|
25
25
|
let RadixText = (props) => /* @__PURE__ */ jsx("span", { ...props });
|
|
26
26
|
let RadixTextField = (props) => /* @__PURE__ */ jsx("input", { ...stripChildren(props) });
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
28
|
+
* Inject real Radix Themes element types into the resolver. Call once
|
|
29
|
+
* at application startup before rendering any schema-driven component
|
|
30
|
+
* so that {@link radixResolver}'s renderers delegate to the supplied
|
|
31
|
+
* Radix primitives.
|
|
32
|
+
*
|
|
33
|
+
* @group Themes
|
|
30
34
|
*/
|
|
31
35
|
function registerRadixComponents(components) {
|
|
32
36
|
RadixBox = components.Box;
|
|
@@ -191,6 +195,39 @@ function buildResolver() {
|
|
|
191
195
|
if (headlessResolver.unknown !== void 0) resolver.unknown = headlessResolver.unknown;
|
|
192
196
|
return resolver;
|
|
193
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* Component resolver mapping schema field types to Radix Themes
|
|
200
|
+
* primitives — `Box`, `Checkbox`, `Flex`, `Select.*`, `Text`,
|
|
201
|
+
* `TextField`.
|
|
202
|
+
*
|
|
203
|
+
* Pass to `SchemaProvider` to render schema-driven UI through Radix
|
|
204
|
+
* Themes. Requires `@radix-ui/themes` installed in the consuming
|
|
205
|
+
* project and a one-time call to {@link registerRadixComponents} to
|
|
206
|
+
* inject the actual Radix element types.
|
|
207
|
+
*
|
|
208
|
+
* @group Themes
|
|
209
|
+
* @example
|
|
210
|
+
* ```tsx
|
|
211
|
+
* import * as Radix from "@radix-ui/themes";
|
|
212
|
+
* import { radixResolver, registerRadixComponents } from "schema-components/themes/radix";
|
|
213
|
+
*
|
|
214
|
+
* registerRadixComponents({
|
|
215
|
+
* Box: Radix.Box,
|
|
216
|
+
* Checkbox: Radix.Checkbox,
|
|
217
|
+
* Flex: Radix.Flex,
|
|
218
|
+
* SelectRoot: Radix.Select.Root,
|
|
219
|
+
* SelectTrigger: Radix.Select.Trigger,
|
|
220
|
+
* SelectContent: Radix.Select.Content,
|
|
221
|
+
* SelectItem: Radix.Select.Item,
|
|
222
|
+
* Text: Radix.Text,
|
|
223
|
+
* TextField: Radix.TextField.Root,
|
|
224
|
+
* });
|
|
225
|
+
*
|
|
226
|
+
* <SchemaProvider resolver={radixResolver}>
|
|
227
|
+
* <SchemaComponent schema={userSchema} value={user} onChange={setUser} />
|
|
228
|
+
* </SchemaProvider>
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
194
231
|
const radixResolver = buildResolver();
|
|
195
232
|
//#endregion
|
|
196
233
|
export { radixResolver, registerRadixComponents };
|