schema-components 1.28.2 → 2.0.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 +38 -16
- package/dist/core/adapter.d.mts +213 -3
- package/dist/core/adapter.mjs +21 -2
- package/dist/core/constraintHint.d.mts +15 -0
- package/dist/core/constraintHint.mjs +24 -0
- package/dist/core/constraints.d.mts +34 -2
- package/dist/core/constraints.mjs +33 -1
- 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/idPath.d.mts +35 -5
- package/dist/core/idPath.mjs +79 -7
- package/dist/core/inferValue.d.mts +2 -0
- package/dist/core/inferValue.mjs +1 -0
- package/dist/core/limits.d.mts +1 -1
- package/dist/core/limits.mjs +6 -0
- package/dist/core/merge.d.mts +22 -1
- package/dist/core/merge.mjs +66 -3
- package/dist/core/normalise.d.mts +17 -2
- package/dist/core/normalise.mjs +1 -1
- package/dist/core/openapi30.mjs +1 -1
- package/dist/core/openapiConstants.d.mts +1 -0
- package/dist/core/ref.d.mts +1 -1
- package/dist/core/refChain.d.mts +3 -4
- package/dist/core/refChain.mjs +2 -3
- package/dist/core/renderer.d.mts +199 -2
- package/dist/core/renderer.mjs +5 -0
- package/dist/core/swagger2.d.mts +1 -1
- package/dist/core/swagger2.mjs +1 -1
- package/dist/core/typeInference.d.mts +3 -3
- 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/uri.d.mts +12 -4
- package/dist/core/uri.mjs +30 -4
- package/dist/core/version.d.mts +1 -1
- package/dist/core/walkBuilders.d.mts +63 -6
- package/dist/core/walkBuilders.mjs +33 -1
- package/dist/core/walker.d.mts +14 -1
- package/dist/core/walker.mjs +18 -0
- package/dist/{diagnostics-Cbwak-ZX.d.mts → diagnostics-BTrm3O6J.d.mts} +9 -1
- package/dist/{errors-DQSIK4n1.d.mts → errors-Dki7tji4.d.mts} +23 -13
- package/dist/html/a11y.d.mts +3 -7
- package/dist/html/a11y.mjs +1 -16
- package/dist/html/html.d.mts +11 -0
- package/dist/html/html.mjs +11 -0
- package/dist/html/renderToHtml.d.mts +45 -12
- package/dist/html/renderToHtml.mjs +20 -4
- package/dist/html/renderToHtmlStream.d.mts +63 -18
- package/dist/html/renderToHtmlStream.mjs +34 -8
- package/dist/html/renderers.d.mts +6 -31
- package/dist/html/renderers.mjs +45 -91
- package/dist/html/streamRenderers.d.mts +31 -3
- package/dist/html/streamRenderers.mjs +41 -8
- package/dist/inferValue-PPXWJpbN.d.mts +77 -0
- package/dist/{limits-DJhgx5Ay.d.mts → limits-x4OiyJxh.d.mts} +6 -0
- package/dist/{normalise-Db1xaxgx.mjs → normalise-DB-Xtjmn.mjs} +43 -2
- 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 +29 -8
- package/dist/openapi/bundle.d.mts +31 -0
- package/dist/openapi/components.d.mts +135 -20
- package/dist/openapi/components.mjs +90 -15
- package/dist/openapi/parser.d.mts +140 -13
- package/dist/openapi/parser.mjs +84 -12
- package/dist/openapi/resolve.d.mts +42 -47
- package/dist/openapi/resolve.mjs +62 -56
- package/dist/react/SchemaComponent.d.mts +90 -88
- package/dist/react/SchemaComponent.mjs +74 -2
- package/dist/react/SchemaErrorBoundary.d.mts +18 -1
- package/dist/react/SchemaErrorBoundary.mjs +13 -1
- package/dist/react/SchemaView.d.mts +39 -11
- package/dist/react/SchemaView.mjs +23 -6
- package/dist/react/a11y.d.mts +74 -7
- package/dist/react/a11y.mjs +67 -6
- package/dist/react/fieldPath.d.mts +16 -1
- package/dist/react/fieldPath.mjs +25 -1
- package/dist/react/fieldShell.d.mts +49 -0
- package/dist/react/fieldShell.mjs +37 -0
- package/dist/react/headless.d.mts +1 -1
- package/dist/react/headlessRenderers.d.mts +13 -2
- package/dist/react/headlessRenderers.mjs +134 -54
- package/dist/{ref-TdeMfaV_.d.mts → ref-DdsbekXX.d.mts} +33 -1
- package/dist/themes/mantine.d.mts +54 -12
- package/dist/themes/mantine.mjs +195 -140
- package/dist/themes/mui.d.mts +64 -11
- package/dist/themes/mui.mjs +277 -213
- package/dist/themes/radix.d.mts +67 -15
- package/dist/themes/radix.mjs +235 -170
- package/dist/themes/shadcn.d.mts +25 -1
- package/dist/themes/shadcn.mjs +112 -91
- package/dist/{types-BTB73MB8.d.mts → types-BrYbjC7_.d.mts} +30 -0
- package/dist/{version-ZzL5R6cS.d.mts → version-DL8U5RuA.d.mts} +6 -0
- package/package.json +8 -1
- package/dist/adapter-DqlAnZ_w.d.mts +0 -172
- package/dist/renderer-Ul9taFYp.d.mts +0 -169
package/dist/themes/mantine.mjs
CHANGED
|
@@ -1,161 +1,216 @@
|
|
|
1
1
|
import { isObject } from "../core/guards.mjs";
|
|
2
2
|
import { sortFieldsByOrder } from "../core/fieldOrder.mjs";
|
|
3
3
|
import { inputId, toReactNode } from "../react/headlessRenderers.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { FieldShell } from "../react/fieldShell.mjs";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
//#region src/themes/mantine.tsx
|
|
7
7
|
function getLabel(props) {
|
|
8
8
|
if (typeof props.meta.description === "string") return props.meta.description;
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
...props
|
|
18
|
-
});
|
|
19
|
-
let MantineSelect = (props) => /* @__PURE__ */ jsx("select", { ...props });
|
|
20
|
-
let MantineFieldset = (props) => /* @__PURE__ */ jsx("fieldset", { ...props });
|
|
21
|
-
let MantineText = (props) => /* @__PURE__ */ jsx("span", { ...props });
|
|
22
|
-
/**
|
|
23
|
-
* Register real Mantine components for the resolver to use.
|
|
24
|
-
* Call once at app startup before rendering.
|
|
25
|
-
*
|
|
26
|
-
* `Text` is required so read-only scalars render as a styled Mantine
|
|
27
|
-
* `<Text>` element instead of a bare `<span>`, matching the visual
|
|
28
|
-
* weight of the editable variants.
|
|
29
|
-
*/
|
|
30
|
-
function registerMantineComponents(components) {
|
|
31
|
-
MantineTextInput = components.TextInput;
|
|
32
|
-
MantineNumberInput = components.NumberInput;
|
|
33
|
-
MantineSwitch = components.Switch;
|
|
34
|
-
MantineSelect = components.Select;
|
|
35
|
-
MantineFieldset = components.Fieldset;
|
|
36
|
-
MantineText = components.Text;
|
|
37
|
-
}
|
|
38
|
-
function renderStringInput(props) {
|
|
39
|
-
const strValue = typeof props.value === "string" ? props.value : "";
|
|
40
|
-
const label = getLabel(props);
|
|
41
|
-
const id = inputId(props.path);
|
|
42
|
-
if (props.readOnly) return /* @__PURE__ */ jsx(MantineText, {
|
|
43
|
-
id,
|
|
44
|
-
children: strValue || "—"
|
|
45
|
-
});
|
|
46
|
-
return /* @__PURE__ */ jsx(MantineTextInput, {
|
|
47
|
-
id,
|
|
48
|
-
label,
|
|
49
|
-
value: props.writeOnly ? "" : strValue,
|
|
50
|
-
onChange: (e) => {
|
|
51
|
-
props.onChange(e.target.value);
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
function renderNumberInput(props) {
|
|
56
|
-
const label = getLabel(props);
|
|
57
|
-
const id = inputId(props.path);
|
|
58
|
-
if (props.readOnly) {
|
|
59
|
-
if (typeof props.value !== "number") return /* @__PURE__ */ jsx(MantineText, {
|
|
10
|
+
function makeRenderStringInput(components) {
|
|
11
|
+
const { TextInput, Text } = components;
|
|
12
|
+
return function renderStringInput(props) {
|
|
13
|
+
const strValue = typeof props.value === "string" ? props.value : "";
|
|
14
|
+
const label = getLabel(props);
|
|
15
|
+
const id = inputId(props.path);
|
|
16
|
+
if (props.readOnly) return /* @__PURE__ */ jsx(Text, {
|
|
60
17
|
id,
|
|
61
|
-
children: "—"
|
|
18
|
+
children: strValue || "—"
|
|
62
19
|
});
|
|
63
|
-
return /* @__PURE__ */ jsx(
|
|
64
|
-
|
|
65
|
-
|
|
20
|
+
return /* @__PURE__ */ jsx(FieldShell, {
|
|
21
|
+
props,
|
|
22
|
+
inputId: id,
|
|
23
|
+
hideLabel: true,
|
|
24
|
+
children: (aria) => /* @__PURE__ */ jsx(TextInput, {
|
|
25
|
+
id,
|
|
26
|
+
label,
|
|
27
|
+
value: props.writeOnly ? "" : strValue,
|
|
28
|
+
onChange: (e) => {
|
|
29
|
+
props.onChange(e.target.value);
|
|
30
|
+
},
|
|
31
|
+
...aria
|
|
32
|
+
})
|
|
66
33
|
});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function makeRenderNumberInput(components) {
|
|
37
|
+
const { NumberInput, Text } = components;
|
|
38
|
+
return function renderNumberInput(props) {
|
|
39
|
+
const label = getLabel(props);
|
|
40
|
+
const id = inputId(props.path);
|
|
41
|
+
if (props.readOnly) {
|
|
42
|
+
if (typeof props.value !== "number") return /* @__PURE__ */ jsx(Text, {
|
|
43
|
+
id,
|
|
44
|
+
children: "—"
|
|
45
|
+
});
|
|
46
|
+
return /* @__PURE__ */ jsx(Text, {
|
|
47
|
+
id,
|
|
48
|
+
children: props.value.toLocaleString()
|
|
49
|
+
});
|
|
74
50
|
}
|
|
75
|
-
|
|
51
|
+
return /* @__PURE__ */ jsx(FieldShell, {
|
|
52
|
+
props,
|
|
53
|
+
inputId: id,
|
|
54
|
+
hideLabel: true,
|
|
55
|
+
children: (aria) => /* @__PURE__ */ jsx(NumberInput, {
|
|
56
|
+
id,
|
|
57
|
+
label,
|
|
58
|
+
value: props.writeOnly ? void 0 : typeof props.value === "number" ? props.value : void 0,
|
|
59
|
+
onChange: (v) => {
|
|
60
|
+
if (typeof v === "number") props.onChange(v);
|
|
61
|
+
},
|
|
62
|
+
...aria
|
|
63
|
+
})
|
|
64
|
+
});
|
|
65
|
+
};
|
|
76
66
|
}
|
|
77
|
-
function
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
67
|
+
function makeRenderBooleanInput(components) {
|
|
68
|
+
const { Switch, Text } = components;
|
|
69
|
+
return function renderBooleanInput(props) {
|
|
70
|
+
const label = getLabel(props);
|
|
71
|
+
const id = inputId(props.path);
|
|
72
|
+
if (props.readOnly) {
|
|
73
|
+
if (typeof props.value !== "boolean") return /* @__PURE__ */ jsx(Text, {
|
|
74
|
+
id,
|
|
75
|
+
children: "—"
|
|
76
|
+
});
|
|
77
|
+
return /* @__PURE__ */ jsx(Text, {
|
|
78
|
+
id,
|
|
79
|
+
children: props.value ? "Yes" : "No"
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return /* @__PURE__ */ jsx(FieldShell, {
|
|
83
|
+
props,
|
|
84
|
+
inputId: id,
|
|
85
|
+
hideLabel: true,
|
|
86
|
+
children: (aria) => /* @__PURE__ */ jsx(Switch, {
|
|
87
|
+
id,
|
|
88
|
+
label,
|
|
89
|
+
checked: props.writeOnly ? false : props.value === true,
|
|
90
|
+
onChange: (e) => {
|
|
91
|
+
props.onChange(e.target.checked);
|
|
92
|
+
},
|
|
93
|
+
...aria
|
|
94
|
+
})
|
|
84
95
|
});
|
|
85
|
-
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function makeRenderEnumInput(components) {
|
|
99
|
+
const { Select, Text } = components;
|
|
100
|
+
return function renderEnumInput(props) {
|
|
101
|
+
const enumValue = typeof props.value === "string" ? props.value : "";
|
|
102
|
+
const label = getLabel(props);
|
|
103
|
+
const id = inputId(props.path);
|
|
104
|
+
if (props.readOnly) return /* @__PURE__ */ jsx(Text, {
|
|
86
105
|
id,
|
|
87
|
-
children:
|
|
106
|
+
children: enumValue || "—"
|
|
88
107
|
});
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
id,
|
|
110
|
-
label,
|
|
111
|
-
value: props.writeOnly ? null : enumValue || null,
|
|
112
|
-
onChange: (v) => {
|
|
113
|
-
if (typeof v === "string") props.onChange(v);
|
|
114
|
-
},
|
|
115
|
-
data: enumValues.map((v) => ({
|
|
116
|
-
value: v,
|
|
117
|
-
label: v
|
|
118
|
-
}))
|
|
119
|
-
});
|
|
108
|
+
const enumValues = props.tree.type === "enum" ? props.tree.enumValues : [];
|
|
109
|
+
return /* @__PURE__ */ jsx(FieldShell, {
|
|
110
|
+
props,
|
|
111
|
+
inputId: id,
|
|
112
|
+
hideLabel: true,
|
|
113
|
+
children: (aria) => /* @__PURE__ */ jsx(Select, {
|
|
114
|
+
id,
|
|
115
|
+
label,
|
|
116
|
+
value: props.writeOnly ? null : enumValue || null,
|
|
117
|
+
onChange: (v) => {
|
|
118
|
+
if (typeof v === "string") props.onChange(v);
|
|
119
|
+
},
|
|
120
|
+
data: enumValues.map((v) => ({
|
|
121
|
+
value: v,
|
|
122
|
+
label: v
|
|
123
|
+
})),
|
|
124
|
+
...aria
|
|
125
|
+
})
|
|
126
|
+
});
|
|
127
|
+
};
|
|
120
128
|
}
|
|
121
|
-
function
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
129
|
+
function makeRenderObjectContainer(components) {
|
|
130
|
+
const { Fieldset } = components;
|
|
131
|
+
return function renderObjectContainer(props) {
|
|
132
|
+
if (props.tree.type !== "object") return null;
|
|
133
|
+
const fields = props.tree.fields;
|
|
134
|
+
const obj = isObject(props.value) ? props.value : {};
|
|
135
|
+
return /* @__PURE__ */ jsx(Fieldset, {
|
|
136
|
+
legend: getLabel(props),
|
|
137
|
+
children: sortFieldsByOrder(fields).filter(([, field]) => field.meta.visible !== false).map(([key, field]) => {
|
|
138
|
+
const childValue = obj[key];
|
|
139
|
+
const childOnChange = (v) => {
|
|
140
|
+
const updated = {};
|
|
141
|
+
for (const [k, val] of Object.entries(obj)) updated[k] = val;
|
|
142
|
+
updated[key] = v;
|
|
143
|
+
props.onChange(updated);
|
|
144
|
+
};
|
|
145
|
+
return /* @__PURE__ */ jsx("div", {
|
|
146
|
+
style: { marginBottom: "0.5rem" },
|
|
147
|
+
children: toReactNode(props.renderChild(field, childValue, childOnChange, key))
|
|
148
|
+
}, key);
|
|
149
|
+
})
|
|
150
|
+
});
|
|
151
|
+
};
|
|
141
152
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
153
|
+
const STUB_COMPONENTS = {
|
|
154
|
+
TextInput: (props) => /* @__PURE__ */ jsx("input", { ...props }),
|
|
155
|
+
NumberInput: (props) => /* @__PURE__ */ jsx("input", {
|
|
156
|
+
type: "number",
|
|
157
|
+
...props
|
|
158
|
+
}),
|
|
159
|
+
Switch: (props) => /* @__PURE__ */ jsx("input", {
|
|
160
|
+
type: "checkbox",
|
|
161
|
+
...props
|
|
162
|
+
}),
|
|
163
|
+
Select: (props) => /* @__PURE__ */ jsx("select", { ...props }),
|
|
164
|
+
Fieldset: (props) => /* @__PURE__ */ jsx("fieldset", { ...props }),
|
|
165
|
+
Text: (props) => /* @__PURE__ */ jsx("span", { ...props })
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* Build a Mantine-flavoured {@link ComponentResolver} bound to the
|
|
169
|
+
* supplied element types. Each render function captures the supplied
|
|
170
|
+
* components in a closure so two consumers can build different
|
|
171
|
+
* resolvers from the same package without leaking element types
|
|
172
|
+
* through module-level mutable state.
|
|
173
|
+
*
|
|
174
|
+
* Returns only the keys this theme actually overrides. The runtime
|
|
175
|
+
* `mergeResolvers` call inside `<SchemaComponent>` / `<SchemaView>`
|
|
176
|
+
* fills unset keys from `headlessResolver`, so variants this adapter
|
|
177
|
+
* leaves unset (literal, union, discriminatedUnion, array, record,
|
|
178
|
+
* file, unknown, …) still render via the headless fallback.
|
|
179
|
+
*
|
|
180
|
+
* @group Themes
|
|
181
|
+
*/
|
|
182
|
+
function createMantineResolver(components) {
|
|
183
|
+
return {
|
|
184
|
+
string: makeRenderStringInput(components),
|
|
185
|
+
number: makeRenderNumberInput(components),
|
|
186
|
+
boolean: makeRenderBooleanInput(components),
|
|
187
|
+
enum: makeRenderEnumInput(components),
|
|
188
|
+
object: makeRenderObjectContainer(components)
|
|
149
189
|
};
|
|
150
|
-
if (headlessResolver.literal !== void 0) resolver.literal = headlessResolver.literal;
|
|
151
|
-
if (headlessResolver.union !== void 0) resolver.union = headlessResolver.union;
|
|
152
|
-
if (headlessResolver.discriminatedUnion !== void 0) resolver.discriminatedUnion = headlessResolver.discriminatedUnion;
|
|
153
|
-
if (headlessResolver.array !== void 0) resolver.array = headlessResolver.array;
|
|
154
|
-
if (headlessResolver.record !== void 0) resolver.record = headlessResolver.record;
|
|
155
|
-
if (headlessResolver.file !== void 0) resolver.file = headlessResolver.file;
|
|
156
|
-
if (headlessResolver.unknown !== void 0) resolver.unknown = headlessResolver.unknown;
|
|
157
|
-
return resolver;
|
|
158
190
|
}
|
|
159
|
-
|
|
191
|
+
/**
|
|
192
|
+
* Component resolver mapping schema field types to Mantine primitives —
|
|
193
|
+
* `TextInput`, `NumberInput`, `Switch`, `Select`, `Fieldset`, `Text`.
|
|
194
|
+
*
|
|
195
|
+
* Built against minimal HTML stubs so the resolver is usable without
|
|
196
|
+
* wiring up `@mantine/core` first — production usage should call
|
|
197
|
+
* {@link createMantineResolver} with real Mantine element types.
|
|
198
|
+
*
|
|
199
|
+
* @group Themes
|
|
200
|
+
* @example
|
|
201
|
+
* ```tsx
|
|
202
|
+
* import { TextInput, NumberInput, Switch, Select, Fieldset, Text } from "@mantine/core";
|
|
203
|
+
* import { createMantineResolver } from "schema-components/themes/mantine";
|
|
204
|
+
*
|
|
205
|
+
* const mantineResolver = createMantineResolver({
|
|
206
|
+
* TextInput, NumberInput, Switch, Select, Fieldset, Text,
|
|
207
|
+
* });
|
|
208
|
+
*
|
|
209
|
+
* <SchemaProvider resolver={mantineResolver}>
|
|
210
|
+
* <SchemaComponent schema={userSchema} value={user} onChange={setUser} />
|
|
211
|
+
* </SchemaProvider>
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
const mantineResolver = createMantineResolver(STUB_COMPONENTS);
|
|
160
215
|
//#endregion
|
|
161
|
-
export {
|
|
216
|
+
export { createMantineResolver, mantineResolver };
|
package/dist/themes/mui.d.mts
CHANGED
|
@@ -1,17 +1,70 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ComponentResolver } from "../core/renderer.mjs";
|
|
2
|
+
import { ElementType } from "react";
|
|
2
3
|
|
|
3
4
|
//#region src/themes/mui.d.ts
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
+
* Element types the MUI resolver renders into. Every slot is the MUI
|
|
7
|
+
* component the corresponding render function expects to find at the
|
|
8
|
+
* call site; consumers wire these in once via `createMuiResolver` so
|
|
9
|
+
* the resolver can be used in SSR and multi-tenant contexts where two
|
|
10
|
+
* callers might inject different element types.
|
|
11
|
+
*/
|
|
12
|
+
interface MuiComponents {
|
|
13
|
+
TextField: ElementType;
|
|
14
|
+
Checkbox: ElementType;
|
|
15
|
+
Typography: ElementType;
|
|
16
|
+
Box: ElementType;
|
|
17
|
+
MenuItem: ElementType;
|
|
18
|
+
FormControlLabel: ElementType;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Build a MUI-flavoured {@link ComponentResolver} bound to the supplied
|
|
22
|
+
* element types. Each render function captures the supplied components
|
|
23
|
+
* in a closure so two consumers can build different resolvers from the
|
|
24
|
+
* same package without leaking element types through module-level
|
|
25
|
+
* mutable state — making the adapter safe to use in SSR and multi-tenant
|
|
26
|
+
* environments.
|
|
27
|
+
*
|
|
28
|
+
* Returns only the keys this theme actually overrides. The runtime
|
|
29
|
+
* `mergeResolvers` call inside `<SchemaComponent>` / `<SchemaView>`
|
|
30
|
+
* fills any unset keys from `headlessResolver`, so consumers never see
|
|
31
|
+
* an unhandled field type even though this resolver leaves variants
|
|
32
|
+
* like `union`, `discriminatedUnion`, `record`, `file`, and `unknown`
|
|
33
|
+
* unset on purpose.
|
|
34
|
+
*
|
|
35
|
+
* @group Themes
|
|
36
|
+
*/
|
|
37
|
+
declare function createMuiResolver(components: MuiComponents): ComponentResolver;
|
|
38
|
+
/**
|
|
39
|
+
* Component resolver mapping schema field types to MUI (Material UI)
|
|
40
|
+
* primitives — `TextField`, `Checkbox`, `Typography`, etc.
|
|
41
|
+
*
|
|
42
|
+
* This default export is built against minimal HTML stubs so it is
|
|
43
|
+
* usable without wiring up `@mui/material` first — handy for tests,
|
|
44
|
+
* stories, and tree-shaken bundles that want the resolver shape
|
|
45
|
+
* without the runtime dependency. For production usage call
|
|
46
|
+
* {@link createMuiResolver} with the real MUI element types.
|
|
47
|
+
*
|
|
48
|
+
* @group Themes
|
|
49
|
+
* @example
|
|
50
|
+
* ```tsx
|
|
51
|
+
* import TextField from "@mui/material/TextField";
|
|
52
|
+
* import Checkbox from "@mui/material/Checkbox";
|
|
53
|
+
* import Typography from "@mui/material/Typography";
|
|
54
|
+
* import Box from "@mui/material/Box";
|
|
55
|
+
* import MenuItem from "@mui/material/MenuItem";
|
|
56
|
+
* import FormControlLabel from "@mui/material/FormControlLabel";
|
|
57
|
+
* import { createMuiResolver } from "schema-components/themes/mui";
|
|
58
|
+
*
|
|
59
|
+
* const muiResolver = createMuiResolver({
|
|
60
|
+
* TextField, Checkbox, Typography, Box, MenuItem, FormControlLabel,
|
|
61
|
+
* });
|
|
62
|
+
*
|
|
63
|
+
* <SchemaProvider resolver={muiResolver}>
|
|
64
|
+
* <SchemaComponent schema={userSchema} value={user} onChange={setUser} />
|
|
65
|
+
* </SchemaProvider>
|
|
66
|
+
* ```
|
|
6
67
|
*/
|
|
7
|
-
declare function registerMuiComponents(components: {
|
|
8
|
-
TextField: React.ElementType;
|
|
9
|
-
Checkbox: React.ElementType;
|
|
10
|
-
Typography: React.ElementType;
|
|
11
|
-
Box: React.ElementType;
|
|
12
|
-
MenuItem: React.ElementType;
|
|
13
|
-
FormControlLabel: React.ElementType;
|
|
14
|
-
}): void;
|
|
15
68
|
declare const muiResolver: ComponentResolver;
|
|
16
69
|
//#endregion
|
|
17
|
-
export {
|
|
70
|
+
export { MuiComponents, createMuiResolver, muiResolver };
|