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,79 @@
1
+ /**
2
+ * Per-instance id-prefix derivation, parallel to
3
+ * `react/SchemaComponent.tsx`'s {@link sanitisePrefix}.
4
+ *
5
+ * Vue 3.5 introduced `useId()` for stable per-instance ids inside
6
+ * `setup()`. The helper below normalises whatever Vue returns into a
7
+ * DOM-id-safe string (no colons, parens, or other punctuation that
8
+ * breaks CSS selectors) so the result composes with the canonical
9
+ * `sc-` prefix from `core/cssClasses.ts`.
10
+ *
11
+ * Older Vue versions (before 3.5) do not expose `useId()`; the SFCs that
12
+ * consume the helper therefore prefer it when available and fall back
13
+ * to a monotonic counter scoped to the module. Both branches produce
14
+ * deterministic, sanitised prefixes.
15
+ */
16
+
17
+ import { useId as vueUseId } from "vue";
18
+
19
+ let fallbackCounter = 0;
20
+
21
+ /**
22
+ * Sanitise a raw id value into a DOM-id-safe prefix. Mirrors the
23
+ * sanitiser used by the React adapter so prefixes derived from
24
+ * `useId()` survive every CSS selector and `aria-controls` reference.
25
+ */
26
+ export function sanitisePrefix(value: string): string {
27
+ const sanitised = value
28
+ .replace(/[^a-zA-Z0-9_]+/g, "-")
29
+ .replace(/^-+|-+$/g, "");
30
+ if (sanitised.length === 0) {
31
+ throw new Error(
32
+ `Cannot derive a DOM-safe id prefix from "${value}". Pass an explicit idPrefix prop.`
33
+ );
34
+ }
35
+ return sanitised;
36
+ }
37
+
38
+ /**
39
+ * Append a child path suffix to a parent path. When the suffix is
40
+ * omitted (e.g. transparent wrappers like union options), the parent
41
+ * path is returned unchanged so the child inherits the parent's id.
42
+ *
43
+ * Mirror of `react/SchemaComponent.tsx` `joinPath` — bracketed array
44
+ * indices like `[0]` append directly so `tags` + `[0]` becomes
45
+ * `tags[0]`, matching the canonical form used by `html/a11y.ts` and
46
+ * `core/fieldPath.ts`.
47
+ */
48
+ export function joinPath(parent: string, suffix: string | undefined): string {
49
+ if (suffix === undefined || suffix.length === 0) return parent;
50
+ if (parent.length === 0) return suffix;
51
+ if (suffix.startsWith("[")) return `${parent}${suffix}`;
52
+ return `${parent}.${suffix}`;
53
+ }
54
+
55
+ /**
56
+ * Derive the per-instance id prefix used by the Vue SFCs.
57
+ *
58
+ * Prefers Vue 3.5+ `useId()` (which guarantees per-component
59
+ * uniqueness across SSR/CSR hydration). Older Vue runtimes expose
60
+ * `useId` as a function returning `undefined` or omit it entirely
61
+ * — the helper falls back to a monotonic counter scoped to this
62
+ * module so the resulting prefix is still deterministic and
63
+ * collision-free within a single render tree.
64
+ *
65
+ * Must be called from within a `setup()` invocation: Vue's `useId`
66
+ * only resolves inside an active component instance.
67
+ */
68
+ export function deriveIdPrefix(explicit: string | undefined): string {
69
+ if (explicit !== undefined) return sanitisePrefix(explicit);
70
+ // Vue's `useId` is typed to always return a string in 3.5+. The
71
+ // runtime check guards older Vue versions where the export may
72
+ // be `undefined`.
73
+ const raw = typeof vueUseId === "function" ? vueUseId() : undefined;
74
+ if (typeof raw === "string" && raw.length > 0) {
75
+ return sanitisePrefix(raw);
76
+ }
77
+ fallbackCounter += 1;
78
+ return `sc-vue-${String(fallbackCounter)}`;
79
+ }
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Vue-flavoured wrapper around the framework-agnostic
3
+ * `dispatchRenderField` from `core/renderField.ts`.
4
+ *
5
+ * Constructs a Vue-shaped {@link DispatchConfig} (widget lookup against
6
+ * the instance → context → global chain, recursion sentinel as a Vue
7
+ * `<fieldset>` {@link VNode}, fallback as a `<span>`-wrapped value) and
8
+ * forwards the call. Used by the `<SchemaComponent>` and `<SchemaView>`
9
+ * SFCs and exported so other Vue surfaces (future API operation
10
+ * components, etc.) can dispatch into the same fallback chain.
11
+ *
12
+ * The widget-lookup contract matches the React adapter exactly:
13
+ * instance map first, then context map, then global registry. The
14
+ * dispatcher itself remains agnostic to how widget maps are scoped —
15
+ * the resolution chain is expressed here in the `lookupWidget`
16
+ * closure.
17
+ */
18
+
19
+ import { h, isVNode, type VNode } from "vue";
20
+ import { dispatchRenderField } from "../core/renderField.ts";
21
+ import type { WalkedField } from "../core/types.ts";
22
+ import { EM_DASH } from "../core/cssClasses.ts";
23
+ import { getVueRenderFunction, mergeVueResolvers } from "./resolver.ts";
24
+ import { headlessVueResolver } from "./headless.ts";
25
+ import type {
26
+ VueComponentResolver,
27
+ VueRenderProps,
28
+ VueWidgetMap,
29
+ } from "./types.ts";
30
+ import { lookupGlobalWidget } from "./widget.ts";
31
+
32
+ /**
33
+ * Build the {@link VueRenderProps} object handed to a Vue render
34
+ * function or widget. Mirrors `buildRenderProps` in `core/renderer.ts`
35
+ * but emits Vue's `VNode`-returning `renderChild` signature directly so
36
+ * the dispatcher does not need to cross-cast between React and Vue
37
+ * shapes at the resolver boundary.
38
+ */
39
+ function buildVueRenderProps(
40
+ tree: WalkedField,
41
+ value: unknown,
42
+ onChange: (next: unknown) => void,
43
+ renderChild: VueRenderProps["renderChild"],
44
+ path: string
45
+ ): VueRenderProps {
46
+ const isReadOnly = tree.editability === "presentation";
47
+ const isWriteOnly = tree.editability === "input";
48
+ const props: VueRenderProps = {
49
+ value,
50
+ onChange,
51
+ readOnly: isReadOnly,
52
+ writeOnly: isWriteOnly,
53
+ meta: tree.meta,
54
+ constraints: tree.constraints,
55
+ path,
56
+ tree,
57
+ renderChild,
58
+ };
59
+ if (tree.examples !== undefined) props.examples = tree.examples;
60
+ return props;
61
+ }
62
+
63
+ /**
64
+ * Render a single walked field through the resolved widget / resolver
65
+ * / headless pipeline.
66
+ *
67
+ * Thin Vue-flavoured wrapper around {@link dispatchRenderField}: it
68
+ * constructs a Vue-shaped {@link DispatchConfig} and returns the
69
+ * dispatcher's {@link VNode} output.
70
+ *
71
+ * @param tree - The walked field tree node to render.
72
+ * @param value - The current value at this position.
73
+ * @param onChange - Callback invoked when the field emits a change. For
74
+ * read-only renders (e.g. `<SchemaView>`) pass a noop.
75
+ * @param userResolver - User-supplied resolver, or `undefined` to use
76
+ * the headless resolver alone.
77
+ * @param renderChild - Recursive child renderer threaded through
78
+ * the {@link VueRenderProps} `renderChild` field.
79
+ * @param path - Dot-separated structural path; non-empty.
80
+ * @param instanceWidgets - Per-instance widget map (highest priority).
81
+ * @param contextWidgets - Context-scoped widget map (middle priority).
82
+ * @param depth - Recursion depth used by the depth cap in
83
+ * {@link dispatchRenderField}.
84
+ */
85
+ export function vueRenderField(
86
+ tree: WalkedField,
87
+ value: unknown,
88
+ onChange: (v: unknown) => void,
89
+ userResolver: VueComponentResolver | undefined,
90
+ renderChild: VueRenderProps["renderChild"],
91
+ path: string,
92
+ instanceWidgets?: VueWidgetMap,
93
+ contextWidgets?: VueWidgetMap,
94
+ depth = 0
95
+ ): VNode {
96
+ if (path.length === 0) {
97
+ throw new Error(
98
+ "vueRenderField requires a non-empty path. Pass the root path " +
99
+ "(derived from `idPrefix` or `useId()`) for the root field, " +
100
+ "and use renderChild's pathSuffix to derive child paths."
101
+ );
102
+ }
103
+
104
+ // Build the merged resolver once per dispatch — user overrides on
105
+ // top of the headless fallback, mirroring the historic React
106
+ // behaviour.
107
+ const resolver: VueComponentResolver =
108
+ userResolver !== undefined
109
+ ? mergeVueResolvers(userResolver, headlessVueResolver)
110
+ : headlessVueResolver;
111
+
112
+ return dispatchRenderField<VueRenderProps, VNode, VueComponentResolver>({
113
+ tree,
114
+ value,
115
+ path,
116
+ depth,
117
+ resolver,
118
+ config: {
119
+ buildProps: (fieldTree, fieldPath) =>
120
+ buildVueRenderProps(
121
+ fieldTree,
122
+ value,
123
+ onChange,
124
+ renderChild,
125
+ fieldPath
126
+ ),
127
+ lookupRenderFn: (type, mergedResolver) =>
128
+ getVueRenderFunction(type, mergedResolver),
129
+ // Widget lookup follows the canonical Vue resolution
130
+ // order: instance → context → global. Pulled out as a
131
+ // closure so the dispatcher remains agnostic to how
132
+ // widget maps are scoped.
133
+ lookupWidget: (name) =>
134
+ instanceWidgets?.get(name) ??
135
+ contextWidgets?.get(name) ??
136
+ lookupGlobalWidget(name),
137
+ recursionSentinel: (fieldTree) => {
138
+ const label =
139
+ typeof fieldTree.meta.description === "string"
140
+ ? fieldTree.meta.description
141
+ : "schema";
142
+ return h("fieldset", undefined, [
143
+ h("em", undefined, `↻ ${label} (recursive)`),
144
+ ]);
145
+ },
146
+ fallback: (_fieldTree, fieldValue) => {
147
+ if (fieldValue === undefined || fieldValue === null)
148
+ return h("span", undefined, EM_DASH);
149
+ return h(
150
+ "span",
151
+ undefined,
152
+ typeof fieldValue === "string"
153
+ ? fieldValue
154
+ : JSON.stringify(fieldValue)
155
+ );
156
+ },
157
+ coerceResult: (result, step) => {
158
+ if (step === "widget") {
159
+ if (result === undefined || result === null)
160
+ return undefined;
161
+ if (isVNode(result)) return result;
162
+ // Widget returned a value but not in a Vue-renderable
163
+ // shape — wrap it in a span so the output remains a
164
+ // valid VNode rather than falling through to the
165
+ // resolver.
166
+ if (
167
+ typeof result === "string" ||
168
+ typeof result === "number"
169
+ )
170
+ return h("span", undefined, String(result));
171
+ return h("span");
172
+ }
173
+ if (result === undefined || result === null)
174
+ return h("span", { style: { display: "none" } });
175
+ if (isVNode(result)) return result;
176
+ if (typeof result === "string" || typeof result === "number")
177
+ return h("span", undefined, String(result));
178
+ return undefined;
179
+ },
180
+ },
181
+ });
182
+ }