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.
Files changed (197) hide show
  1. package/README.md +133 -1
  2. package/dist/SchemaComponent-B__6-5-E.d.mts +277 -0
  3. package/dist/SchemaComponent-BxzzsHsK.mjs +668 -0
  4. package/dist/adapter-ktQaheWB.d.mts +213 -0
  5. package/dist/constructorTypes-BdCiMS6e.d.mts +30 -0
  6. package/dist/core/adapter.d.mts +3 -213
  7. package/dist/core/constraintHint.d.mts +1 -1
  8. package/dist/core/constraints.d.mts +2 -2
  9. package/dist/core/contexts.d.mts +71 -0
  10. package/dist/core/contexts.mjs +1 -0
  11. package/dist/core/diagnostics.d.mts +1 -1
  12. package/dist/core/errors.d.mts +1 -1
  13. package/dist/core/fieldOrder.d.mts +1 -1
  14. package/dist/{react → core}/fieldPath.d.mts +2 -2
  15. package/dist/{react → core}/fieldPath.mjs +3 -3
  16. package/dist/core/formats.d.mts +1 -1
  17. package/dist/core/inferValue.d.mts +1 -1
  18. package/dist/core/limits.d.mts +1 -1
  19. package/dist/core/merge.d.mts +1 -1
  20. package/dist/core/normalise.d.mts +2 -2
  21. package/dist/core/ref.d.mts +1 -1
  22. package/dist/core/renderField.d.mts +147 -0
  23. package/dist/core/renderField.mjs +115 -0
  24. package/dist/core/renderer.d.mts +2 -199
  25. package/dist/core/swagger2.d.mts +1 -1
  26. package/dist/core/typeInference.d.mts +1 -982
  27. package/dist/core/types.d.mts +1 -1
  28. package/dist/core/unionMatch.d.mts +1 -1
  29. package/dist/core/version.d.mts +1 -1
  30. package/dist/core/walkBuilders.d.mts +3 -3
  31. package/dist/core/walker.d.mts +1 -1
  32. package/dist/{errors-Dki7tji4.d.mts → errors-DbaI04x2.d.mts} +1 -1
  33. package/dist/html/a11y.d.mts +2 -2
  34. package/dist/html/renderToHtml.d.mts +5 -5
  35. package/dist/html/renderToHtml.mjs +33 -18
  36. package/dist/html/renderToHtmlStream.d.mts +5 -5
  37. package/dist/html/renderers.d.mts +1 -1
  38. package/dist/html/streamRenderers.d.mts +15 -6
  39. package/dist/html/streamRenderers.mjs +56 -10
  40. package/dist/{inferValue-Ce-PviSD.d.mts → inferValue-eAnh50EM.d.mts} +3 -3
  41. package/dist/lit/SchemaComponent.d.mts +125 -0
  42. package/dist/lit/SchemaComponent.mjs +2 -0
  43. package/dist/lit/SchemaField.d.mts +65 -0
  44. package/dist/lit/SchemaField.mjs +2 -0
  45. package/dist/lit/SchemaView.d.mts +14 -0
  46. package/dist/lit/SchemaView.mjs +2 -0
  47. package/dist/lit/constructorTypes.d.mts +2 -0
  48. package/dist/lit/constructorTypes.mjs +1 -0
  49. package/dist/lit/contexts.d.mts +78 -0
  50. package/dist/lit/contexts.mjs +238 -0
  51. package/dist/lit/defaultResolver.d.mts +33 -0
  52. package/dist/lit/defaultResolver.mjs +2 -0
  53. package/dist/lit/registry.d.mts +66 -0
  54. package/dist/lit/registry.mjs +2 -0
  55. package/dist/lit/renderers/baseElement.d.mts +131 -0
  56. package/dist/lit/renderers/baseElement.mjs +109 -0
  57. package/dist/lit/renderers/recordHelpers.d.mts +25 -0
  58. package/dist/lit/renderers/recordHelpers.mjs +55 -0
  59. package/dist/lit/renderers/scArray.d.mts +14 -0
  60. package/dist/lit/renderers/scArray.mjs +86 -0
  61. package/dist/lit/renderers/scBoolean.d.mts +15 -0
  62. package/dist/lit/renderers/scBoolean.mjs +47 -0
  63. package/dist/lit/renderers/scConditional.d.mts +23 -0
  64. package/dist/lit/renderers/scConditional.mjs +65 -0
  65. package/dist/lit/renderers/scDiscriminated.d.mts +23 -0
  66. package/dist/lit/renderers/scDiscriminated.mjs +138 -0
  67. package/dist/lit/renderers/scEnum.d.mts +16 -0
  68. package/dist/lit/renderers/scEnum.mjs +66 -0
  69. package/dist/lit/renderers/scFile.d.mts +15 -0
  70. package/dist/lit/renderers/scFile.mjs +53 -0
  71. package/dist/lit/renderers/scLiteralNullNever.d.mts +30 -0
  72. package/dist/lit/renderers/scLiteralNullNever.mjs +57 -0
  73. package/dist/lit/renderers/scNumber.d.mts +15 -0
  74. package/dist/lit/renderers/scNumber.mjs +64 -0
  75. package/dist/lit/renderers/scObject.d.mts +14 -0
  76. package/dist/lit/renderers/scObject.mjs +57 -0
  77. package/dist/lit/renderers/scRecord.d.mts +14 -0
  78. package/dist/lit/renderers/scRecord.mjs +112 -0
  79. package/dist/lit/renderers/scString.d.mts +19 -0
  80. package/dist/lit/renderers/scString.mjs +165 -0
  81. package/dist/lit/renderers/scTuple.d.mts +14 -0
  82. package/dist/lit/renderers/scTuple.mjs +58 -0
  83. package/dist/lit/renderers/scUnion.d.mts +14 -0
  84. package/dist/lit/renderers/scUnion.mjs +44 -0
  85. package/dist/lit/renderers/scUnknown.d.mts +15 -0
  86. package/dist/lit/renderers/scUnknown.mjs +45 -0
  87. package/dist/lit/ssr.d.mts +37 -0
  88. package/dist/lit/ssr.mjs +9565 -0
  89. package/dist/lit/types.d.mts +2 -0
  90. package/dist/lit/types.mjs +1 -0
  91. package/dist/lit/widget.d.mts +71 -0
  92. package/dist/lit/widget.mjs +87 -0
  93. package/dist/openapi/ApiCallbacks.d.mts +1 -1
  94. package/dist/openapi/ApiLinks.d.mts +1 -1
  95. package/dist/openapi/ApiResponseHeaders.d.mts +1 -1
  96. package/dist/openapi/ApiSecurity.d.mts +1 -1
  97. package/dist/openapi/components.d.mts +4 -4
  98. package/dist/openapi/parser.d.mts +2 -2
  99. package/dist/openapi/resolve.d.mts +1 -1
  100. package/dist/preact/SchemaComponent.d.mts +3 -0
  101. package/dist/preact/SchemaComponent.mjs +26 -0
  102. package/dist/preact/SchemaErrorBoundary.d.mts +2 -0
  103. package/dist/preact/SchemaErrorBoundary.mjs +20 -0
  104. package/dist/preact/SchemaView.d.mts +2 -0
  105. package/dist/preact/SchemaView.mjs +22 -0
  106. package/dist/preact/headless.d.mts +2 -0
  107. package/dist/preact/headless.mjs +18 -0
  108. package/dist/react/SchemaComponent.d.mts +3 -270
  109. package/dist/react/SchemaComponent.mjs +41 -32
  110. package/dist/react/SchemaView.d.mts +6 -6
  111. package/dist/react/SchemaView.mjs +32 -29
  112. package/dist/react/a11y.d.mts +2 -2
  113. package/dist/react/fieldShell.d.mts +1 -1
  114. package/dist/react/headless.d.mts +1 -1
  115. package/dist/react/headlessRenderers.d.mts +2 -2
  116. package/dist/{ref-DdsbekXX.d.mts → ref-DWrQG1Er.d.mts} +1 -1
  117. package/dist/renderer-ab9E52Bp.d.mts +245 -0
  118. package/dist/solid/SchemaComponent.d.mts +136 -0
  119. package/dist/solid/SchemaComponent.mjs +391 -0
  120. package/dist/solid/SchemaErrorBoundary.d.mts +38 -0
  121. package/dist/solid/SchemaErrorBoundary.mjs +57 -0
  122. package/dist/solid/SchemaField.d.mts +40 -0
  123. package/dist/solid/SchemaField.mjs +113 -0
  124. package/dist/solid/SchemaView.d.mts +54 -0
  125. package/dist/solid/SchemaView.mjs +168 -0
  126. package/dist/solid/a11y.d.mts +70 -0
  127. package/dist/solid/a11y.mjs +71 -0
  128. package/dist/solid/contexts.d.mts +37 -0
  129. package/dist/solid/contexts.mjs +66 -0
  130. package/dist/solid/headless.d.mts +10 -0
  131. package/dist/solid/headless.mjs +27 -0
  132. package/dist/solid/renderers.d.mts +79 -0
  133. package/dist/solid/renderers.mjs +840 -0
  134. package/dist/solid/types.d.mts +90 -0
  135. package/dist/solid/types.mjs +1 -0
  136. package/dist/solid/widget.d.mts +29 -0
  137. package/dist/solid/widget.mjs +35 -0
  138. package/dist/themes/mantine.d.mts +1 -1
  139. package/dist/themes/mui.d.mts +1 -1
  140. package/dist/themes/radix.d.mts +1 -1
  141. package/dist/themes/shadcn.d.mts +1 -1
  142. package/dist/typeInference-Y8tNEQJk.d.mts +983 -0
  143. package/dist/types-BCy7K3nk.d.mts +125 -0
  144. package/package.json +73 -1
  145. package/src/svelte/SchemaComponent.svelte +427 -0
  146. package/src/svelte/SchemaErrorBoundary.svelte +66 -0
  147. package/src/svelte/SchemaField.svelte +216 -0
  148. package/src/svelte/SchemaProvider.svelte +46 -0
  149. package/src/svelte/SchemaView.svelte +244 -0
  150. package/src/svelte/a11y.ts +112 -0
  151. package/src/svelte/contexts.ts +79 -0
  152. package/src/svelte/dispatch.ts +267 -0
  153. package/src/svelte/headless.ts +73 -0
  154. package/src/svelte/headlessFns.ts +124 -0
  155. package/src/svelte/renderers/Array.svelte +98 -0
  156. package/src/svelte/renderers/Boolean.svelte +43 -0
  157. package/src/svelte/renderers/Conditional.svelte +67 -0
  158. package/src/svelte/renderers/DiscriminatedUnion.svelte +197 -0
  159. package/src/svelte/renderers/Enum.svelte +53 -0
  160. package/src/svelte/renderers/Fallback.svelte +24 -0
  161. package/src/svelte/renderers/File.svelte +46 -0
  162. package/src/svelte/renderers/Literal.svelte +29 -0
  163. package/src/svelte/renderers/Mount.svelte +24 -0
  164. package/src/svelte/renderers/Negation.svelte +35 -0
  165. package/src/svelte/renderers/Never.svelte +24 -0
  166. package/src/svelte/renderers/Null.svelte +19 -0
  167. package/src/svelte/renderers/Number.svelte +68 -0
  168. package/src/svelte/renderers/Object.svelte +74 -0
  169. package/src/svelte/renderers/Record.svelte +134 -0
  170. package/src/svelte/renderers/RecursionSentinel.svelte +27 -0
  171. package/src/svelte/renderers/String.svelte +152 -0
  172. package/src/svelte/renderers/Tuple.svelte +84 -0
  173. package/src/svelte/renderers/Union.svelte +49 -0
  174. package/src/svelte/renderers/Unknown.svelte +42 -0
  175. package/src/svelte/svelte-modules.d.ts +25 -0
  176. package/src/svelte/types.ts +238 -0
  177. package/src/svelte/widget.ts +62 -0
  178. package/src/vue/SchemaComponent.vue +274 -0
  179. package/src/vue/SchemaErrorBoundary.vue +60 -0
  180. package/src/vue/SchemaField.vue +178 -0
  181. package/src/vue/SchemaProvider.vue +39 -0
  182. package/src/vue/SchemaView.vue +198 -0
  183. package/src/vue/VNodeHost.ts +32 -0
  184. package/src/vue/contexts.ts +116 -0
  185. package/src/vue/eventTargets.ts +35 -0
  186. package/src/vue/headless.ts +61 -0
  187. package/src/vue/idPrefix.ts +79 -0
  188. package/src/vue/renderField.ts +182 -0
  189. package/src/vue/renderers.ts +1297 -0
  190. package/src/vue/resolver.ts +45 -0
  191. package/src/vue/types.ts +140 -0
  192. package/src/vue/vue-shim.d.ts +25 -0
  193. package/src/vue/widget.ts +51 -0
  194. /package/dist/{diagnostics-BTrm3O6J.d.mts → diagnostics-mftUZI7c.d.mts} +0 -0
  195. /package/dist/{limits-x4OiyJxh.d.mts → limits-Vv9hUbI_.d.mts} +0 -0
  196. /package/dist/{types-BrYbjC7_.d.mts → types-BBQaEPfE.d.mts} +0 -0
  197. /package/dist/{version-DL8U5RuA.d.mts → version-BEBx10ND.d.mts} +0 -0
@@ -0,0 +1,54 @@
1
+ import { w as SchemaMeta } from "../types-BBQaEPfE.mjs";
2
+ import { t as Diagnostic } from "../diagnostics-mftUZI7c.mjs";
3
+ import { r as SchemaIoSide } from "../adapter-ktQaheWB.mjs";
4
+ import { f as RejectUnrepresentableZod } from "../typeInference-Y8tNEQJk.mjs";
5
+ import { a as InferredValue, t as InferFields } from "../inferValue-eAnh50EM.mjs";
6
+ import { SolidComponentResolver, SolidWidgetMap } from "./types.mjs";
7
+ import { JSX } from "solid-js";
8
+
9
+ //#region src/solid/SchemaView.d.ts
10
+ /**
11
+ * Props accepted by {@link SchemaView}.
12
+ *
13
+ * Mirrors `<SchemaComponent>` for the read-only path — no `onChange`,
14
+ * no `validate`, and the theme is supplied via the `resolver` prop
15
+ * rather than `SchemaProvider` so it can be rendered without a
16
+ * Solid context binding.
17
+ *
18
+ * @group Components
19
+ */
20
+ interface SchemaViewProps<T = unknown, Ref extends string | undefined = undefined, Mode extends SchemaIoSide = "output"> {
21
+ schema: RejectUnrepresentableZod<T>;
22
+ ref?: Ref;
23
+ io?: Mode;
24
+ value?: InferredValue<T, Ref, undefined, Mode>;
25
+ fields?: InferFields<T, Ref>;
26
+ meta?: SchemaMeta;
27
+ description?: string;
28
+ /** Theme resolver. Falls back to the headless resolver if omitted. */
29
+ resolver?: SolidComponentResolver;
30
+ widgets?: SolidWidgetMap;
31
+ onDiagnostic?: (diagnostic: Diagnostic) => void;
32
+ strict?: boolean;
33
+ idPrefix?: string;
34
+ }
35
+ /**
36
+ * Read-only Solid renderer that is safe to use outside a Solid context
37
+ * subtree — the theme adapter is passed via the `resolver` prop.
38
+ *
39
+ * Always renders read-only; pair with `SchemaComponent` for editable
40
+ * forms. Mirrors the contract of the React `<SchemaView>`.
41
+ *
42
+ * @group Components
43
+ * @example
44
+ * ```tsx
45
+ * import { SchemaView } from "schema-components/solid/SchemaView";
46
+ *
47
+ * export default function UserCard(props: { user: User }) {
48
+ * return <SchemaView schema={userSchema} value={props.user} />;
49
+ * }
50
+ * ```
51
+ */
52
+ declare function SchemaView<T = unknown, Ref extends string | undefined = undefined, Mode extends SchemaIoSide = "output">(props: SchemaViewProps<T, Ref, Mode>): JSX.Element;
53
+ //#endregion
54
+ export { SchemaView, SchemaViewProps };
@@ -0,0 +1,168 @@
1
+ import { toRecordOrUndefined } from "../core/guards.mjs";
2
+ import "../core/limits.mjs";
3
+ import { SchemaNormalisationError, SchemaRenderError } from "../core/errors.mjs";
4
+ import { normaliseSchema } from "../core/adapter.mjs";
5
+ import { walk } from "../core/walker.mjs";
6
+ import { headlessSolidResolver } from "./headless.mjs";
7
+ import { joinPath, sanitisePrefix } from "./SchemaComponent.mjs";
8
+ import { createUniqueId } from "solid-js";
9
+ import { jsx, jsxs } from "solid-js/jsx-runtime";
10
+ //#region src/solid/SchemaView.tsx
11
+ /** @jsxImportSource solid-js */
12
+ /**
13
+ * Solid read-only schema renderer.
14
+ *
15
+ * Mirror of `react/SchemaView.tsx` for Solid. Renders a schema in
16
+ * read-only mode without any context — the theme adapter is passed
17
+ * explicitly via the `resolver` prop, matching the React Server
18
+ * Component contract.
19
+ *
20
+ * The compute primitive used is `createUniqueId()` plus a single
21
+ * recursive render dispatcher. There is no per-render hook state; the
22
+ * tree is walked once per render and dispatched to the resolver.
23
+ *
24
+ * SSR note: Solid Start ships a server-component equivalent
25
+ * (server-only directives, etc.) but the API is still moving.
26
+ * `<SchemaView>` is documented as the read-only entry point and works
27
+ * as a normal Solid component inside an SSR-rendered tree; consumers
28
+ * using Solid Start can place it anywhere, including in a server-
29
+ * rendered route. A dedicated Solid Start server-only surface can be
30
+ * added as a thin wrapper once the upstream API stabilises.
31
+ */
32
+ /**
33
+ * Read-only Solid renderer that is safe to use outside a Solid context
34
+ * subtree — the theme adapter is passed via the `resolver` prop.
35
+ *
36
+ * Always renders read-only; pair with `SchemaComponent` for editable
37
+ * forms. Mirrors the contract of the React `<SchemaView>`.
38
+ *
39
+ * @group Components
40
+ * @example
41
+ * ```tsx
42
+ * import { SchemaView } from "schema-components/solid/SchemaView";
43
+ *
44
+ * export default function UserCard(props: { user: User }) {
45
+ * return <SchemaView schema={userSchema} value={props.user} />;
46
+ * }
47
+ * ```
48
+ */
49
+ function SchemaView(props) {
50
+ const generatedId = createUniqueId();
51
+ const rootPath = props.idPrefix ?? sanitisePrefix(generatedId);
52
+ const mergedMeta = {
53
+ ...props.meta,
54
+ readOnly: true
55
+ };
56
+ if (props.description !== void 0) mergedMeta.description = props.description;
57
+ const diagnostics = props.onDiagnostic !== void 0 || props.strict === true ? {
58
+ ...props.onDiagnostic !== void 0 ? { diagnostics: props.onDiagnostic } : {},
59
+ ...props.strict !== void 0 ? { strict: props.strict } : {}
60
+ } : void 0;
61
+ let jsonSchema;
62
+ let rootMeta;
63
+ let rootDocument;
64
+ try {
65
+ const normaliseOptions = diagnostics !== void 0 || props.io !== void 0 ? {
66
+ ...diagnostics !== void 0 ? { diagnostics } : {},
67
+ ...props.io !== void 0 ? { io: props.io } : {}
68
+ } : void 0;
69
+ const normalised = normaliseSchema(props.schema, props.ref, normaliseOptions);
70
+ jsonSchema = normalised.jsonSchema;
71
+ rootMeta = normalised.rootMeta;
72
+ rootDocument = normalised.rootDocument;
73
+ } catch (err) {
74
+ if (err instanceof SchemaNormalisationError) throw err;
75
+ throw new SchemaNormalisationError(err instanceof Error ? err.message : "Failed to normalise schema", props.schema, "unknown");
76
+ }
77
+ const fieldsRecord = toRecordOrUndefined(props.fields);
78
+ const walkOptions = {
79
+ componentMeta: mergedMeta,
80
+ rootMeta,
81
+ fieldOverrides: fieldsRecord,
82
+ rootDocument,
83
+ ...diagnostics !== void 0 ? { diagnostics } : {}
84
+ };
85
+ const tree = walk(jsonSchema, walkOptions);
86
+ const resolver = props.resolver !== void 0 ? mergeSolidResolvers(props.resolver, headlessSolidResolver) : headlessSolidResolver;
87
+ const makeRenderChild = (currentDepth, parentPath) => (childTree, childValue, _childOnChange, pathSuffix) => {
88
+ const childPath = joinPath(parentPath, pathSuffix);
89
+ if (currentDepth >= 10) return /* @__PURE__ */ jsx("fieldset", { children: /* @__PURE__ */ jsxs("em", { children: [
90
+ "↻ ",
91
+ typeof childTree.meta.description === "string" ? childTree.meta.description : "schema",
92
+ " (recursive)"
93
+ ] }) });
94
+ return renderFieldServer(childTree, childValue, resolver, makeRenderChild(currentDepth + 1, childPath), childPath, props.widgets);
95
+ };
96
+ const renderChild = makeRenderChild(0, rootPath);
97
+ return renderFieldServer(tree, props.value ?? tree.defaultValue, resolver, renderChild, rootPath, props.widgets);
98
+ }
99
+ function renderFieldServer(tree, value, resolver, renderChild, path, widgets) {
100
+ if (path.length === 0) throw new Error("renderFieldServer requires a non-empty path. Pass the root path at the top and join children via joinPath().");
101
+ const componentHint = tree.meta.component;
102
+ if (typeof componentHint === "string") {
103
+ const widget = widgets?.get(componentHint);
104
+ if (widget !== void 0) {
105
+ const result = widget({
106
+ value,
107
+ readOnly: true,
108
+ writeOnly: false,
109
+ meta: tree.meta,
110
+ constraints: tree.constraints,
111
+ path,
112
+ tree,
113
+ onChange: () => {},
114
+ renderChild,
115
+ ...tree.examples !== void 0 ? { examples: tree.examples } : {}
116
+ });
117
+ if (result !== null && result !== void 0) return result;
118
+ }
119
+ }
120
+ const renderFn = resolver[tree.type];
121
+ if (renderFn !== void 0) try {
122
+ const result = renderFn({
123
+ value,
124
+ readOnly: true,
125
+ writeOnly: false,
126
+ meta: tree.meta,
127
+ constraints: tree.constraints,
128
+ path,
129
+ tree,
130
+ onChange: () => {},
131
+ renderChild,
132
+ ...tree.examples !== void 0 ? { examples: tree.examples } : {}
133
+ });
134
+ if (result !== null && result !== void 0) return result;
135
+ } catch (err) {
136
+ throw new SchemaRenderError(err instanceof Error ? err.message : `Render function threw for type "${tree.type}"`, tree, tree.type, err);
137
+ }
138
+ if (value === void 0 || value === null) return /* @__PURE__ */ jsx("span", { children: "—" });
139
+ return /* @__PURE__ */ jsx("span", { children: typeof value === "string" ? value : JSON.stringify(value) });
140
+ }
141
+ function mergeSolidResolvers(user, fallback) {
142
+ const merged = {};
143
+ for (const key of [
144
+ "string",
145
+ "number",
146
+ "boolean",
147
+ "null",
148
+ "enum",
149
+ "object",
150
+ "array",
151
+ "tuple",
152
+ "record",
153
+ "union",
154
+ "discriminatedUnion",
155
+ "conditional",
156
+ "negation",
157
+ "literal",
158
+ "file",
159
+ "never",
160
+ "unknown"
161
+ ]) {
162
+ const fn = user[key] ?? fallback[key];
163
+ if (fn !== void 0) merged[key] = fn;
164
+ }
165
+ return merged;
166
+ }
167
+ //#endregion
168
+ export { SchemaView };
@@ -0,0 +1,70 @@
1
+ import { j as WalkedField } from "../types-BBQaEPfE.mjs";
2
+ import { t as AllConstraints } from "../renderer-ab9E52Bp.mjs";
3
+
4
+ //#region src/solid/a11y.d.ts
5
+ /**
6
+ * Build the ARIA attribute bundle for a renderer.
7
+ *
8
+ * - `aria-required="true"` whenever the field is non-optional.
9
+ * - `aria-describedby=<hint-id>` whenever a constraint hint applies.
10
+ * - `aria-label=<description>` when a non-empty description is supplied.
11
+ *
12
+ * Pass `inputId` + `constraints` only when the renderer emits a
13
+ * constraint-hint sibling; the helper then auto-derives the
14
+ * `aria-describedby` value from `hintIdFor(inputId)`. Omitting either
15
+ * argument skips the attribute.
16
+ */
17
+ declare function buildAriaAttrs(tree: WalkedField, description?: unknown, inputId?: string, constraints?: AllConstraints): Record<string, string>;
18
+ /**
19
+ * Description for a constraint hint emitted alongside an input.
20
+ *
21
+ * Returned by {@link constraintHint} when the field carries one or
22
+ * more constraint keywords the user should be told about (min/max,
23
+ * pattern, item count, …). Theme adapters render this as a `<small>`
24
+ * element wired to the input via `aria-describedby`.
25
+ */
26
+ interface Hint {
27
+ /** DOM id matching {@link hintIdFor}(inputId) on the host input. */
28
+ readonly id: string;
29
+ /** Human-readable hint text. */
30
+ readonly text: string;
31
+ }
32
+ /**
33
+ * Derive the constraint-hint descriptor for a field at `inputId`.
34
+ * Returns `undefined` when the field has no constraint worth
35
+ * announcing — callers skip rendering the `<small>` element entirely
36
+ * rather than emitting an empty node.
37
+ */
38
+ declare function constraintHint(inputId: string, constraints: AllConstraints): Hint | undefined;
39
+ /**
40
+ * True when the supplied field is non-optional and therefore deserves
41
+ * a visual required indicator alongside its label.
42
+ */
43
+ declare function isFieldRequired(tree: WalkedField): boolean;
44
+ /**
45
+ * Narrow `meta.description` (typed `unknown`) to a string value safe to
46
+ * pass into JSX `aria-label`. Returns `undefined` for non-string or
47
+ * empty-string descriptions so Solid drops the attribute rather than
48
+ * stringifying e.g. `{}` to `"[object Object]"`.
49
+ */
50
+ declare function ariaLabel(description: unknown): string | undefined;
51
+ /**
52
+ * Structured constraint-hint data for the Solid renderers. Identical
53
+ * shape to `react/a11y.ts` `HintInfo` — the input takes the
54
+ * `ariaDescribedBy` id, the renderer emits a sibling `<small id={...}>`
55
+ * whose text is `hint`. Returns `undefined` when the field has no
56
+ * advertise-able constraints.
57
+ */
58
+ interface HintInfo {
59
+ readonly id: string;
60
+ readonly hint: string;
61
+ readonly ariaDescribedBy: string;
62
+ }
63
+ /**
64
+ * Build {@link HintInfo} for a field at `inputId` given its declared
65
+ * constraints. Returns `undefined` when no constraint message would be
66
+ * produced.
67
+ */
68
+ declare function buildHintInfo(inputId: string, constraints: AllConstraints): HintInfo | undefined;
69
+ //#endregion
70
+ export { Hint, HintInfo, ariaLabel, buildAriaAttrs, buildHintInfo, constraintHint, isFieldRequired };
@@ -0,0 +1,71 @@
1
+ import { constraintHint as constraintHint$1 } from "../core/constraintHint.mjs";
2
+ import { hintIdFor } from "../core/idPath.mjs";
3
+ //#region src/solid/a11y.ts
4
+ /**
5
+ * Build the ARIA attribute bundle for a renderer.
6
+ *
7
+ * - `aria-required="true"` whenever the field is non-optional.
8
+ * - `aria-describedby=<hint-id>` whenever a constraint hint applies.
9
+ * - `aria-label=<description>` when a non-empty description is supplied.
10
+ *
11
+ * Pass `inputId` + `constraints` only when the renderer emits a
12
+ * constraint-hint sibling; the helper then auto-derives the
13
+ * `aria-describedby` value from `hintIdFor(inputId)`. Omitting either
14
+ * argument skips the attribute.
15
+ */
16
+ function buildAriaAttrs(tree, description, inputId, constraints) {
17
+ const attrs = {};
18
+ if (tree.isOptional === false) attrs["aria-required"] = "true";
19
+ if (inputId !== void 0 && constraints !== void 0 && constraintHint$1(constraints) !== void 0) attrs["aria-describedby"] = hintIdFor(inputId);
20
+ if (typeof description === "string" && description.length > 0) attrs["aria-label"] = description;
21
+ return attrs;
22
+ }
23
+ /**
24
+ * Derive the constraint-hint descriptor for a field at `inputId`.
25
+ * Returns `undefined` when the field has no constraint worth
26
+ * announcing — callers skip rendering the `<small>` element entirely
27
+ * rather than emitting an empty node.
28
+ */
29
+ function constraintHint(inputId, constraints) {
30
+ const text = constraintHint$1(constraints);
31
+ if (text === void 0) return void 0;
32
+ return {
33
+ id: hintIdFor(inputId),
34
+ text
35
+ };
36
+ }
37
+ /**
38
+ * True when the supplied field is non-optional and therefore deserves
39
+ * a visual required indicator alongside its label.
40
+ */
41
+ function isFieldRequired(tree) {
42
+ return tree.isOptional === false;
43
+ }
44
+ /**
45
+ * Narrow `meta.description` (typed `unknown`) to a string value safe to
46
+ * pass into JSX `aria-label`. Returns `undefined` for non-string or
47
+ * empty-string descriptions so Solid drops the attribute rather than
48
+ * stringifying e.g. `{}` to `"[object Object]"`.
49
+ */
50
+ function ariaLabel(description) {
51
+ if (typeof description !== "string") return void 0;
52
+ if (description.length === 0) return void 0;
53
+ return description;
54
+ }
55
+ /**
56
+ * Build {@link HintInfo} for a field at `inputId` given its declared
57
+ * constraints. Returns `undefined` when no constraint message would be
58
+ * produced.
59
+ */
60
+ function buildHintInfo(inputId, constraints) {
61
+ const hint = constraintHint$1(constraints);
62
+ if (hint === void 0) return void 0;
63
+ const id = hintIdFor(inputId);
64
+ return {
65
+ id,
66
+ hint,
67
+ ariaDescribedBy: id
68
+ };
69
+ }
70
+ //#endregion
71
+ export { ariaLabel, buildAriaAttrs, buildHintInfo, constraintHint, isFieldRequired };
@@ -0,0 +1,37 @@
1
+ import { ContextPort } from "../core/contexts.mjs";
2
+ import { SolidComponentResolver, SolidWidgetMap } from "./types.mjs";
3
+ import { Context } from "solid-js";
4
+
5
+ //#region src/solid/contexts.d.ts
6
+ /**
7
+ * Solid context carrying the theme resolver propagated by
8
+ * {@link SchemaProvider}. Default value `undefined` — the renderer falls
9
+ * back to the headless resolver when no provider sits above a
10
+ * `<SchemaComponent>`.
11
+ */
12
+ declare const UserResolverContext: Context<SolidComponentResolver | undefined>;
13
+ /**
14
+ * Solid context carrying the widget map provided by
15
+ * {@link SchemaProvider}. Default value `undefined` — the renderer
16
+ * dispatches to instance widgets / globals when no provider supplies a
17
+ * context-level map.
18
+ */
19
+ declare const WidgetsContext: Context<SolidWidgetMap | undefined>;
20
+ /**
21
+ * Solid binding of {@link ContextPort} for the user resolver context.
22
+ *
23
+ * Exposed primarily so the {@link ContextPort} contract has a concrete
24
+ * Solid implementation alongside the React, Vue and Svelte bindings —
25
+ * generic consumers (cross-framework testing, port-driven adapters)
26
+ * can read the resolver without depending on Solid's native context
27
+ * shape. The Solid {@link SchemaProvider} component performs the actual
28
+ * `<Context.Provider>` wrapping in its template.
29
+ */
30
+ declare const userResolverPort: ContextPort<SolidComponentResolver | undefined>;
31
+ /**
32
+ * Solid binding of {@link ContextPort} for the widgets context. Parallel
33
+ * to {@link userResolverPort}.
34
+ */
35
+ declare const widgetsPort: ContextPort<SolidWidgetMap | undefined>;
36
+ //#endregion
37
+ export { UserResolverContext, WidgetsContext, userResolverPort, widgetsPort };
@@ -0,0 +1,66 @@
1
+ import { createContext, useContext } from "solid-js";
2
+ //#region src/solid/contexts.ts
3
+ /**
4
+ * Solid bindings for the framework-agnostic {@link ContextPort} contract.
5
+ *
6
+ * Wraps Solid's native `createContext`/`useContext` primitives into the
7
+ * shape every framework adapter exposes. Two ports are pre-bound for the
8
+ * schema-components subtree — the theme resolver and the widget map —
9
+ * mirroring the React adapter's `UserResolverContext` and
10
+ * `WidgetsContext`.
11
+ *
12
+ * Unlike React's wrapping `<Provider>` JSX, Solid's `<Context.Provider>`
13
+ * is itself a JSX component and must be invoked from inside a JSX tree.
14
+ * The {@link ContextPort.provide} adapter therefore cannot construct the
15
+ * Solid `<Provider>` element directly — it returns `children` unchanged,
16
+ * relying on the Solid `<SchemaProvider>` template to wrap descendants
17
+ * with the underlying `Context.Provider`. The ports exist so the generic
18
+ * {@link ContextPort} contract has a concrete Solid implementation that
19
+ * cross-framework consumers can introspect.
20
+ */
21
+ /**
22
+ * Solid context carrying the theme resolver propagated by
23
+ * {@link SchemaProvider}. Default value `undefined` — the renderer falls
24
+ * back to the headless resolver when no provider sits above a
25
+ * `<SchemaComponent>`.
26
+ */
27
+ const UserResolverContext = createContext(void 0);
28
+ /**
29
+ * Solid context carrying the widget map provided by
30
+ * {@link SchemaProvider}. Default value `undefined` — the renderer
31
+ * dispatches to instance widgets / globals when no provider supplies a
32
+ * context-level map.
33
+ */
34
+ const WidgetsContext = createContext(void 0);
35
+ /**
36
+ * Solid binding of {@link ContextPort} for the user resolver context.
37
+ *
38
+ * Exposed primarily so the {@link ContextPort} contract has a concrete
39
+ * Solid implementation alongside the React, Vue and Svelte bindings —
40
+ * generic consumers (cross-framework testing, port-driven adapters)
41
+ * can read the resolver without depending on Solid's native context
42
+ * shape. The Solid {@link SchemaProvider} component performs the actual
43
+ * `<Context.Provider>` wrapping in its template.
44
+ */
45
+ const userResolverPort = {
46
+ provide(_value, children) {
47
+ return children;
48
+ },
49
+ consume() {
50
+ return useContext(UserResolverContext);
51
+ }
52
+ };
53
+ /**
54
+ * Solid binding of {@link ContextPort} for the widgets context. Parallel
55
+ * to {@link userResolverPort}.
56
+ */
57
+ const widgetsPort = {
58
+ provide(_value, children) {
59
+ return children;
60
+ },
61
+ consume() {
62
+ return useContext(WidgetsContext);
63
+ }
64
+ };
65
+ //#endregion
66
+ export { UserResolverContext, WidgetsContext, userResolverPort, widgetsPort };
@@ -0,0 +1,10 @@
1
+ import { SolidComponentResolver } from "./types.mjs";
2
+
3
+ //#region src/solid/headless.d.ts
4
+ /**
5
+ * The Solid headless resolver. Every variant of `WalkedField` is wired
6
+ * here; theme adapters override individual keys to customise the look.
7
+ */
8
+ declare const headlessSolidResolver: SolidComponentResolver;
9
+ //#endregion
10
+ export { headlessSolidResolver };
@@ -0,0 +1,27 @@
1
+ import { renderArray, renderBoolean, renderConditional, renderDiscriminatedUnion, renderEnum, renderFile, renderLiteral, renderNegation, renderNever, renderNull, renderNumber, renderObject, renderRecord, renderString, renderTuple, renderUnion, renderUnknown } from "./renderers.mjs";
2
+ //#region src/solid/headless.ts
3
+ /**
4
+ * The Solid headless resolver. Every variant of `WalkedField` is wired
5
+ * here; theme adapters override individual keys to customise the look.
6
+ */
7
+ const headlessSolidResolver = {
8
+ string: renderString,
9
+ number: renderNumber,
10
+ boolean: renderBoolean,
11
+ null: renderNull,
12
+ enum: renderEnum,
13
+ object: renderObject,
14
+ record: renderRecord,
15
+ array: renderArray,
16
+ tuple: renderTuple,
17
+ union: renderUnion,
18
+ discriminatedUnion: renderDiscriminatedUnion,
19
+ conditional: renderConditional,
20
+ negation: renderNegation,
21
+ literal: renderLiteral,
22
+ file: renderFile,
23
+ never: renderNever,
24
+ unknown: renderUnknown
25
+ };
26
+ //#endregion
27
+ export { headlessSolidResolver };
@@ -0,0 +1,79 @@
1
+ import { j as WalkedField } from "../types-BBQaEPfE.mjs";
2
+ import { SolidRenderProps } from "./types.mjs";
3
+ import { JSX } from "solid-js";
4
+
5
+ //#region src/solid/renderers.d.ts
6
+ /**
7
+ * Build a stable, unique input ID from the path. Re-exported alias for
8
+ * {@link fieldDomId} so the Solid adapter has the same import shape as
9
+ * the React adapter's `inputId`.
10
+ */
11
+ declare function inputId(path: string): string;
12
+ /** Headless renderer for `StringField` — plain `<input>` / `<span>`. */
13
+ declare function renderString(props: SolidRenderProps): JSX.Element;
14
+ /** Headless renderer for `NumberField` — plain `<input type="number">`. */
15
+ declare function renderNumber(props: SolidRenderProps): JSX.Element;
16
+ /** Headless renderer for `BooleanField` — plain `<input type="checkbox">`. */
17
+ declare function renderBoolean(props: SolidRenderProps): JSX.Element;
18
+ /** Headless renderer for `EnumField` — plain `<select>` listing each option. */
19
+ declare function renderEnum(props: SolidRenderProps): JSX.Element;
20
+ /**
21
+ * Compute the default value for a freshly added record entry based on
22
+ * the record's value-type schema. Mirrors the React headless
23
+ * implementation byte-for-byte so both adapters seed new entries the
24
+ * same way.
25
+ */
26
+ declare function defaultRecordValue(valueType: WalkedField): unknown;
27
+ /**
28
+ * Generate a unique, currently-unused key for a new record entry.
29
+ * Picks the first of `key`, `key-1`, `key-2`, … not in `existing`.
30
+ */
31
+ declare function nextRecordKey(existing: readonly string[], base?: string): string;
32
+ /**
33
+ * Rename a key in an object while preserving insertion order. Returns
34
+ * the original object reference when the rename is a no-op
35
+ * (oldKey === newKey) or when newKey collides with an existing key.
36
+ */
37
+ declare function renameRecordKey(obj: Record<string, unknown>, oldKey: string, newKey: string): Record<string, unknown>;
38
+ /** Headless renderer for `ObjectField` — `<fieldset>` per object. */
39
+ declare function renderObject(props: SolidRenderProps): JSX.Element;
40
+ /** Headless renderer for `RecordField` — editable key/value rows. */
41
+ declare function renderRecord(props: SolidRenderProps): JSX.Element;
42
+ /** Headless renderer for `ArrayField` — ordered list with add/remove controls. */
43
+ declare function renderArray(props: SolidRenderProps): JSX.Element;
44
+ /** Headless renderer for plain `UnionField` — picks the matching option. */
45
+ declare function renderUnion(props: SolidRenderProps): JSX.Element;
46
+ /**
47
+ * Pure helper: convert a tab index into the new value the discriminated
48
+ * union should emit. Returns `undefined` when the index is out of bounds.
49
+ *
50
+ * Extracted so the contract is unit-testable without rendering the tabs
51
+ * component. Mirrors the React adapter's `discriminatedUnionValueForTab`.
52
+ */
53
+ declare function discriminatedUnionValueForTab(optionLabels: readonly string[], discKey: string, newIndex: number): Record<string, string> | undefined;
54
+ /** Headless renderer for `DiscriminatedUnionField` — tabbed UI. */
55
+ declare function renderDiscriminatedUnion(props: SolidRenderProps): JSX.Element;
56
+ /** Headless renderer for `FileField` — plain `<input type="file">`. */
57
+ declare function renderFile(props: SolidRenderProps): JSX.Element;
58
+ /**
59
+ * Render a literal field — `z.literal("a")` or `{ const: 5 }`.
60
+ *
61
+ * Literals are non-editable by nature; both read-only and editable modes
62
+ * display the literal value(s). Multiple literals (`z.literal(["a","b"])`)
63
+ * render comma-separated.
64
+ */
65
+ declare function renderLiteral(props: SolidRenderProps): JSX.Element;
66
+ /** Render a null field — `z.null()` or `{ type: "null" }`. */
67
+ declare function renderNull(props: SolidRenderProps): JSX.Element;
68
+ /** Render a never field — `z.never()` or `{ not: {} }` / `false` schema. */
69
+ declare function renderNever(props: SolidRenderProps): JSX.Element;
70
+ /** Render a tuple field — positional rendering of each prefix item. */
71
+ declare function renderTuple(props: SolidRenderProps): JSX.Element;
72
+ /** Render a conditional field — JSON Schema `if`/`then`/`else`. */
73
+ declare function renderConditional(props: SolidRenderProps): JSX.Element;
74
+ /** Render a negation field — JSON Schema `{ not: { ... } }`. */
75
+ declare function renderNegation(props: SolidRenderProps): JSX.Element;
76
+ /** Headless renderer for `UnknownField` — JSON-encoded fallback. */
77
+ declare function renderUnknown(props: SolidRenderProps): JSX.Element;
78
+ //#endregion
79
+ export { defaultRecordValue, discriminatedUnionValueForTab, inputId, nextRecordKey, renameRecordKey, renderArray, renderBoolean, renderConditional, renderDiscriminatedUnion, renderEnum, renderFile, renderLiteral, renderNegation, renderNever, renderNull, renderNumber, renderObject, renderRecord, renderString, renderTuple, renderUnion, renderUnknown };