schema-components 2.0.2 → 2.1.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.
Files changed (180) hide show
  1. package/README.md +98 -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 +81 -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 +3 -3
  39. package/dist/{inferValue-Ce-PviSD.d.mts → inferValue-eAnh50EM.d.mts} +3 -3
  40. package/dist/lit/SchemaComponent.d.mts +125 -0
  41. package/dist/lit/SchemaComponent.mjs +2 -0
  42. package/dist/lit/SchemaField.d.mts +65 -0
  43. package/dist/lit/SchemaField.mjs +2 -0
  44. package/dist/lit/SchemaView.d.mts +14 -0
  45. package/dist/lit/SchemaView.mjs +2 -0
  46. package/dist/lit/constructorTypes.d.mts +2 -0
  47. package/dist/lit/constructorTypes.mjs +1 -0
  48. package/dist/lit/contexts.d.mts +78 -0
  49. package/dist/lit/contexts.mjs +238 -0
  50. package/dist/lit/defaultResolver.d.mts +33 -0
  51. package/dist/lit/defaultResolver.mjs +2 -0
  52. package/dist/lit/registry.d.mts +66 -0
  53. package/dist/lit/registry.mjs +2 -0
  54. package/dist/lit/renderers/baseElement.d.mts +131 -0
  55. package/dist/lit/renderers/baseElement.mjs +109 -0
  56. package/dist/lit/renderers/recordHelpers.d.mts +25 -0
  57. package/dist/lit/renderers/recordHelpers.mjs +55 -0
  58. package/dist/lit/renderers/scArray.d.mts +14 -0
  59. package/dist/lit/renderers/scArray.mjs +86 -0
  60. package/dist/lit/renderers/scBoolean.d.mts +15 -0
  61. package/dist/lit/renderers/scBoolean.mjs +47 -0
  62. package/dist/lit/renderers/scConditional.d.mts +23 -0
  63. package/dist/lit/renderers/scConditional.mjs +65 -0
  64. package/dist/lit/renderers/scDiscriminated.d.mts +23 -0
  65. package/dist/lit/renderers/scDiscriminated.mjs +138 -0
  66. package/dist/lit/renderers/scEnum.d.mts +16 -0
  67. package/dist/lit/renderers/scEnum.mjs +66 -0
  68. package/dist/lit/renderers/scFile.d.mts +15 -0
  69. package/dist/lit/renderers/scFile.mjs +53 -0
  70. package/dist/lit/renderers/scLiteralNullNever.d.mts +30 -0
  71. package/dist/lit/renderers/scLiteralNullNever.mjs +57 -0
  72. package/dist/lit/renderers/scNumber.d.mts +15 -0
  73. package/dist/lit/renderers/scNumber.mjs +64 -0
  74. package/dist/lit/renderers/scObject.d.mts +14 -0
  75. package/dist/lit/renderers/scObject.mjs +57 -0
  76. package/dist/lit/renderers/scRecord.d.mts +14 -0
  77. package/dist/lit/renderers/scRecord.mjs +112 -0
  78. package/dist/lit/renderers/scString.d.mts +19 -0
  79. package/dist/lit/renderers/scString.mjs +165 -0
  80. package/dist/lit/renderers/scTuple.d.mts +14 -0
  81. package/dist/lit/renderers/scTuple.mjs +58 -0
  82. package/dist/lit/renderers/scUnion.d.mts +14 -0
  83. package/dist/lit/renderers/scUnion.mjs +44 -0
  84. package/dist/lit/renderers/scUnknown.d.mts +15 -0
  85. package/dist/lit/renderers/scUnknown.mjs +45 -0
  86. package/dist/lit/ssr.d.mts +37 -0
  87. package/dist/lit/ssr.mjs +9565 -0
  88. package/dist/lit/types.d.mts +2 -0
  89. package/dist/lit/types.mjs +1 -0
  90. package/dist/lit/widget.d.mts +71 -0
  91. package/dist/lit/widget.mjs +87 -0
  92. package/dist/openapi/ApiCallbacks.d.mts +1 -1
  93. package/dist/openapi/ApiLinks.d.mts +1 -1
  94. package/dist/openapi/ApiResponseHeaders.d.mts +1 -1
  95. package/dist/openapi/ApiSecurity.d.mts +1 -1
  96. package/dist/openapi/components.d.mts +4 -4
  97. package/dist/openapi/parser.d.mts +2 -2
  98. package/dist/openapi/resolve.d.mts +1 -1
  99. package/dist/preact/SchemaComponent.d.mts +3 -0
  100. package/dist/preact/SchemaComponent.mjs +26 -0
  101. package/dist/preact/SchemaErrorBoundary.d.mts +2 -0
  102. package/dist/preact/SchemaErrorBoundary.mjs +20 -0
  103. package/dist/preact/SchemaView.d.mts +2 -0
  104. package/dist/preact/SchemaView.mjs +22 -0
  105. package/dist/preact/headless.d.mts +2 -0
  106. package/dist/preact/headless.mjs +18 -0
  107. package/dist/react/SchemaComponent.d.mts +3 -270
  108. package/dist/react/SchemaComponent.mjs +41 -32
  109. package/dist/react/SchemaView.d.mts +6 -6
  110. package/dist/react/SchemaView.mjs +32 -29
  111. package/dist/react/a11y.d.mts +2 -2
  112. package/dist/react/fieldShell.d.mts +1 -1
  113. package/dist/react/headless.d.mts +1 -1
  114. package/dist/react/headlessRenderers.d.mts +2 -2
  115. package/dist/{ref-DdsbekXX.d.mts → ref-DWrQG1Er.d.mts} +1 -1
  116. package/dist/renderer-ab9E52Bp.d.mts +245 -0
  117. package/dist/solid/SchemaComponent.d.mts +136 -0
  118. package/dist/solid/SchemaComponent.mjs +391 -0
  119. package/dist/solid/SchemaErrorBoundary.d.mts +38 -0
  120. package/dist/solid/SchemaErrorBoundary.mjs +57 -0
  121. package/dist/solid/SchemaField.d.mts +40 -0
  122. package/dist/solid/SchemaField.mjs +113 -0
  123. package/dist/solid/SchemaView.d.mts +54 -0
  124. package/dist/solid/SchemaView.mjs +168 -0
  125. package/dist/solid/a11y.d.mts +70 -0
  126. package/dist/solid/a11y.mjs +71 -0
  127. package/dist/solid/contexts.d.mts +37 -0
  128. package/dist/solid/contexts.mjs +66 -0
  129. package/dist/solid/headless.d.mts +10 -0
  130. package/dist/solid/headless.mjs +27 -0
  131. package/dist/solid/renderers.d.mts +79 -0
  132. package/dist/solid/renderers.mjs +840 -0
  133. package/dist/solid/types.d.mts +90 -0
  134. package/dist/solid/types.mjs +1 -0
  135. package/dist/solid/widget.d.mts +29 -0
  136. package/dist/solid/widget.mjs +35 -0
  137. package/dist/themes/mantine.d.mts +1 -1
  138. package/dist/themes/mui.d.mts +1 -1
  139. package/dist/themes/radix.d.mts +1 -1
  140. package/dist/themes/shadcn.d.mts +1 -1
  141. package/dist/typeInference-Y8tNEQJk.d.mts +983 -0
  142. package/dist/types-BCy7K3nk.d.mts +125 -0
  143. package/package.json +71 -1
  144. package/src/svelte/SchemaComponent.svelte +427 -0
  145. package/src/svelte/SchemaErrorBoundary.svelte +66 -0
  146. package/src/svelte/SchemaField.svelte +216 -0
  147. package/src/svelte/SchemaProvider.svelte +46 -0
  148. package/src/svelte/SchemaView.svelte +244 -0
  149. package/src/svelte/a11y.ts +112 -0
  150. package/src/svelte/contexts.ts +79 -0
  151. package/src/svelte/dispatch.ts +267 -0
  152. package/src/svelte/headless.ts +73 -0
  153. package/src/svelte/headlessFns.ts +124 -0
  154. package/src/svelte/renderers/Array.svelte +98 -0
  155. package/src/svelte/renderers/Boolean.svelte +43 -0
  156. package/src/svelte/renderers/Conditional.svelte +67 -0
  157. package/src/svelte/renderers/DiscriminatedUnion.svelte +197 -0
  158. package/src/svelte/renderers/Enum.svelte +53 -0
  159. package/src/svelte/renderers/Fallback.svelte +24 -0
  160. package/src/svelte/renderers/File.svelte +46 -0
  161. package/src/svelte/renderers/Literal.svelte +29 -0
  162. package/src/svelte/renderers/Mount.svelte +24 -0
  163. package/src/svelte/renderers/Negation.svelte +35 -0
  164. package/src/svelte/renderers/Never.svelte +24 -0
  165. package/src/svelte/renderers/Null.svelte +19 -0
  166. package/src/svelte/renderers/Number.svelte +68 -0
  167. package/src/svelte/renderers/Object.svelte +74 -0
  168. package/src/svelte/renderers/Record.svelte +134 -0
  169. package/src/svelte/renderers/RecursionSentinel.svelte +27 -0
  170. package/src/svelte/renderers/String.svelte +152 -0
  171. package/src/svelte/renderers/Tuple.svelte +84 -0
  172. package/src/svelte/renderers/Union.svelte +49 -0
  173. package/src/svelte/renderers/Unknown.svelte +42 -0
  174. package/src/svelte/svelte-modules.d.ts +25 -0
  175. package/src/svelte/types.ts +238 -0
  176. package/src/svelte/widget.ts +62 -0
  177. /package/dist/{diagnostics-BTrm3O6J.d.mts → diagnostics-mftUZI7c.d.mts} +0 -0
  178. /package/dist/{limits-x4OiyJxh.d.mts → limits-Vv9hUbI_.d.mts} +0 -0
  179. /package/dist/{types-BrYbjC7_.d.mts → types-BBQaEPfE.d.mts} +0 -0
  180. /package/dist/{version-DL8U5RuA.d.mts → version-BEBx10ND.d.mts} +0 -0
@@ -0,0 +1,64 @@
1
+ import { constraintHint } from "../../core/constraintHint.mjs";
2
+ import "../../core/cssClasses.mjs";
3
+ import { fieldDomId, hintIdFor } from "../../core/idPath.mjs";
4
+ import { BaseScElement } from "./baseElement.mjs";
5
+ import { html } from "lit";
6
+ //#region src/lit/renderers/scNumber.ts
7
+ /**
8
+ * `<sc-number>` — Custom Element renderer for `NumberField`.
9
+ *
10
+ * Mirrors React's `renderNumber`: `<input type="number">` with
11
+ * integer-vs-decimal `step` and `inputmode` selection. The host
12
+ * element narrows on `tree.type === "number"` to read `isInteger`.
13
+ *
14
+ * Parts: `input`, `value`, `hint`.
15
+ *
16
+ * @packageDocumentation
17
+ */
18
+ /**
19
+ * Lit Custom Element rendering a number-valued schema field.
20
+ *
21
+ * Tag: `<sc-number>` (registered by `registerSchemaComponents`).
22
+ */
23
+ var ScNumber = class extends BaseScElement {
24
+ render() {
25
+ const id = fieldDomId(this.path);
26
+ if (this.readOnly) {
27
+ if (typeof this.value !== "number") return html`<span part="value" id=${id}>${"—"}</span>`;
28
+ return html`<span part="value" id=${id}
29
+ >${this.value.toLocaleString()}</span
30
+ >`;
31
+ }
32
+ const numValue = typeof this.value === "number" ? this.value : "";
33
+ const isInteger = this.tree.type === "number" ? this.tree.isInteger : false;
34
+ const inputMode = isInteger ? "numeric" : "decimal";
35
+ const multipleOf = this.constraints.multipleOf;
36
+ const step = multipleOf !== void 0 ? String(multipleOf) : isInteger ? "1" : void 0;
37
+ const hint = constraintHint(this.constraints);
38
+ const describedBy = hint !== void 0 ? hintIdFor(id) : void 0;
39
+ return html`
40
+ <input
41
+ part="input"
42
+ id=${id}
43
+ type="number"
44
+ inputmode=${inputMode}
45
+ step=${step ?? ""}
46
+ .value=${String(this.writeOnly ? "" : numValue)}
47
+ min=${this.constraints.minimum ?? ""}
48
+ max=${this.constraints.maximum ?? ""}
49
+ aria-describedby=${describedBy ?? ""}
50
+ @input=${this.handleInput}
51
+ />
52
+ ${hint === void 0 ? html`` : html`<small part="hint" id=${hintIdFor(id)} class="sc-hint"
53
+ >${hint}</small
54
+ >`}
55
+ `;
56
+ }
57
+ handleInput = (e) => {
58
+ const target = e.target;
59
+ if (!(target instanceof HTMLInputElement)) return;
60
+ this.emitChange(Number(target.value));
61
+ };
62
+ };
63
+ //#endregion
64
+ export { ScNumber };
@@ -0,0 +1,14 @@
1
+ import { BaseScElement } from "./baseElement.mjs";
2
+ import { TemplateResult } from "lit";
3
+
4
+ //#region src/lit/renderers/scObject.d.ts
5
+ /**
6
+ * Lit Custom Element rendering an object schema field.
7
+ *
8
+ * Tag: `<sc-object>` (registered by `registerSchemaComponents`).
9
+ */
10
+ declare class ScObject extends BaseScElement {
11
+ render(): TemplateResult;
12
+ }
13
+ //#endregion
14
+ export { ScObject };
@@ -0,0 +1,57 @@
1
+ import { isObject } from "../../core/guards.mjs";
2
+ import { sortFieldsByOrder } from "../../core/fieldOrder.mjs";
3
+ import { fieldDomId } from "../../core/idPath.mjs";
4
+ import { BaseScElement } from "./baseElement.mjs";
5
+ import { html } from "lit";
6
+ //#region src/lit/renderers/scObject.ts
7
+ /**
8
+ * `<sc-object>` — Custom Element renderer for `ObjectField`.
9
+ *
10
+ * Mirrors React's `renderObject`: a `<fieldset>` with one `<label>`
11
+ * plus child renderer per property. Visibility / field-order respects
12
+ * the same `meta.visible === false` skip and `sortFieldsByOrder()`
13
+ * ordering as the React side.
14
+ *
15
+ * Parts: `fieldset`, `legend`, `field`, `label`.
16
+ *
17
+ * @packageDocumentation
18
+ */
19
+ /**
20
+ * Lit Custom Element rendering an object schema field.
21
+ *
22
+ * Tag: `<sc-object>` (registered by `registerSchemaComponents`).
23
+ */
24
+ var ScObject = class extends BaseScElement {
25
+ render() {
26
+ if (this.tree.type !== "object") return html``;
27
+ const obj = isObject(this.value) ? this.value : {};
28
+ const sortedEntries = sortFieldsByOrder(this.tree.fields);
29
+ return html`<fieldset part="fieldset">
30
+ ${typeof this.meta.description === "string" ? html`<legend part="legend">${this.meta.description}</legend>` : html``}
31
+ ${sortedEntries.filter(([, field]) => field.meta.visible !== false).map(([key, field]) => {
32
+ const childValue = obj[key];
33
+ const childId = fieldDomId(`${this.path}.${key}`);
34
+ const childChange = (v) => {
35
+ const updated = {};
36
+ for (const [k, val] of Object.entries(obj)) updated[k] = val;
37
+ updated[key] = v;
38
+ this.emitChange(updated);
39
+ };
40
+ return html`<div part="field">
41
+ <label part="label" for=${childId}>
42
+ ${typeof field.meta.description === "string" ? field.meta.description : key}
43
+ ${field.isOptional === false ? html`<span
44
+ aria-hidden="true"
45
+ class="sc-required"
46
+ >
47
+ *
48
+ </span>` : html``}
49
+ </label>
50
+ ${this.renderChild(field, childValue, childChange, key)}
51
+ </div>`;
52
+ })}
53
+ </fieldset>`;
54
+ }
55
+ };
56
+ //#endregion
57
+ export { ScObject };
@@ -0,0 +1,14 @@
1
+ import { BaseScElement } from "./baseElement.mjs";
2
+ import { TemplateResult } from "lit";
3
+
4
+ //#region src/lit/renderers/scRecord.d.ts
5
+ /**
6
+ * Lit Custom Element rendering a record schema field.
7
+ *
8
+ * Tag: `<sc-record>` (registered by `registerSchemaComponents`).
9
+ */
10
+ declare class ScRecord extends BaseScElement {
11
+ render(): TemplateResult;
12
+ }
13
+ //#endregion
14
+ export { ScRecord };
@@ -0,0 +1,112 @@
1
+ import { isObject } from "../../core/guards.mjs";
2
+ import "../../core/cssClasses.mjs";
3
+ import { fieldDomId } from "../../core/idPath.mjs";
4
+ import { BaseScElement } from "./baseElement.mjs";
5
+ import { defaultRecordValueLit, nextRecordKeyLit, renameRecordKeyLit } from "./recordHelpers.mjs";
6
+ import { html } from "lit";
7
+ //#region src/lit/renderers/scRecord.ts
8
+ /**
9
+ * `<sc-record>` — Custom Element renderer for `RecordField`.
10
+ *
11
+ * Mirrors React's `renderRecord`: editable key/value rows with rename
12
+ * (on input blur), per-row remove, and footer add. Read-only mode
13
+ * collapses to a labelled list with no controls.
14
+ *
15
+ * Parts: `list`, `item`, `key`, `remove`, `add`.
16
+ *
17
+ * @packageDocumentation
18
+ */
19
+ function ariaLabel(description) {
20
+ return typeof description === "string" ? description : void 0;
21
+ }
22
+ /**
23
+ * Lit Custom Element rendering a record schema field.
24
+ *
25
+ * Tag: `<sc-record>` (registered by `registerSchemaComponents`).
26
+ */
27
+ var ScRecord = class extends BaseScElement {
28
+ render() {
29
+ if (this.tree.type !== "record") return html``;
30
+ const obj = isObject(this.value) ? this.value : {};
31
+ const valueType = this.tree.valueType;
32
+ const entries = Object.entries(obj);
33
+ const label = ariaLabel(this.meta.description);
34
+ if (this.readOnly) {
35
+ if (entries.length === 0) return html`<span part="value">${"—"}</span>`;
36
+ return html`<div role="group" aria-label=${label ?? ""}>
37
+ ${entries.map(([key, value]) => {
38
+ return html`<div part="item">
39
+ <label for=${fieldDomId(`${this.path}.${key}`)}>${key}</label>
40
+ ${this.renderChild(valueType, value, () => {}, key)}
41
+ </div>`;
42
+ })}
43
+ </div>`;
44
+ }
45
+ const handleRename = (oldKey, newKey) => {
46
+ const renamed = renameRecordKeyLit(obj, oldKey, newKey);
47
+ if (renamed === obj) return;
48
+ this.emitChange(renamed);
49
+ };
50
+ const handleValueChange = (key, next) => {
51
+ const updated = {};
52
+ for (const [k, val] of Object.entries(obj)) updated[k] = val;
53
+ updated[key] = next;
54
+ this.emitChange(updated);
55
+ };
56
+ const handleRemove = (key) => {
57
+ const next = {};
58
+ for (const [k, v] of Object.entries(obj)) {
59
+ if (k === key) continue;
60
+ next[k] = v;
61
+ }
62
+ this.emitChange(next);
63
+ };
64
+ const handleAdd = () => {
65
+ const newKey = nextRecordKeyLit(Object.keys(obj));
66
+ const next = { ...obj };
67
+ next[newKey] = defaultRecordValueLit(valueType);
68
+ this.emitChange(next);
69
+ };
70
+ return html`<div part="list" role="group" aria-label=${label ?? ""}>
71
+ ${entries.map(([key, value]) => {
72
+ return html`<div part="item">
73
+ <input
74
+ part="key"
75
+ id=${`${fieldDomId(`${this.path}.${key}`)}-key`}
76
+ type="text"
77
+ aria-label="Entry key"
78
+ .defaultValue=${key}
79
+ @blur=${(e) => {
80
+ const target = e.target;
81
+ if (!(target instanceof HTMLInputElement)) return;
82
+ handleRename(key, target.value);
83
+ }}
84
+ />
85
+ ${this.renderChild(valueType, value, (nextValue) => {
86
+ handleValueChange(key, nextValue);
87
+ }, key)}
88
+ <button
89
+ part="remove"
90
+ type="button"
91
+ aria-label="Remove entry ${key}"
92
+ @click=${() => {
93
+ handleRemove(key);
94
+ }}
95
+ >
96
+ Remove
97
+ </button>
98
+ </div>`;
99
+ })}
100
+ <button
101
+ part="add"
102
+ type="button"
103
+ aria-label="Add entry"
104
+ @click=${handleAdd}
105
+ >
106
+ Add
107
+ </button>
108
+ </div>`;
109
+ }
110
+ };
111
+ //#endregion
112
+ export { ScRecord };
@@ -0,0 +1,19 @@
1
+ import { BaseScElement } from "./baseElement.mjs";
2
+ import { TemplateResult } from "lit";
3
+
4
+ //#region src/lit/renderers/scString.d.ts
5
+ /**
6
+ * Lit Custom Element rendering a string-valued schema field.
7
+ *
8
+ * Tag: `<sc-string>` (registered by `registerSchemaComponents`).
9
+ */
10
+ declare class ScString extends BaseScElement {
11
+ render(): TemplateResult;
12
+ private renderReadOnly;
13
+ private renderEditable;
14
+ private renderHintMaybe;
15
+ private handleInput;
16
+ private handleSelect;
17
+ }
18
+ //#endregion
19
+ export { ScString };
@@ -0,0 +1,165 @@
1
+ import { dateInputType } from "../../core/formats.mjs";
2
+ import { isSafeHyperlink, isSafeMailtoAddress } from "../../core/uri.mjs";
3
+ import { constraintHint } from "../../core/constraintHint.mjs";
4
+ import "../../core/cssClasses.mjs";
5
+ import { fieldDomId, hintIdFor } from "../../core/idPath.mjs";
6
+ import { displayJsonValue } from "../../core/walkBuilders.mjs";
7
+ import { BaseScElement } from "./baseElement.mjs";
8
+ import { html } from "lit";
9
+ //#region src/lit/renderers/scString.ts
10
+ /**
11
+ * `<sc-string>` — Custom Element renderer for `StringField`.
12
+ *
13
+ * Mirrors the React `renderString` headless renderer:
14
+ * `<input type="…">` in editable mode with `format`-aware type
15
+ * selection (`email`, `url`, `password`, date/time variants), or a
16
+ * `<span>` in read-only mode that linkifies safe `mailto:` / `http(s)`
17
+ * URLs and locale-formats date/time strings.
18
+ *
19
+ * Exposes the following CSS parts so consumers can theme without
20
+ * piercing the Shadow DOM:
21
+ *
22
+ * - `input` — the inner `<input>` element
23
+ * - `value` — the read-only `<span>` (or `<a>` for safe link formats)
24
+ * - `hint` — the constraint hint `<small>` element
25
+ *
26
+ * @packageDocumentation
27
+ */
28
+ function formatDateTime(value) {
29
+ if (typeof value !== "string" || value.length === 0) return void 0;
30
+ const date = new Date(value);
31
+ if (isNaN(date.getTime())) return void 0;
32
+ return date.toLocaleString();
33
+ }
34
+ function formatDate(value) {
35
+ if (typeof value !== "string" || value.length === 0) return void 0;
36
+ const date = new Date(value);
37
+ if (isNaN(date.getTime())) return void 0;
38
+ return date.toLocaleDateString();
39
+ }
40
+ function formatTime(value) {
41
+ if (typeof value !== "string" || value.length === 0) return void 0;
42
+ const date = new Date(value);
43
+ if (isNaN(date.getTime())) return void 0;
44
+ return date.toLocaleTimeString();
45
+ }
46
+ /**
47
+ * Lit Custom Element rendering a string-valued schema field.
48
+ *
49
+ * Tag: `<sc-string>` (registered by `registerSchemaComponents`).
50
+ */
51
+ var ScString = class extends BaseScElement {
52
+ render() {
53
+ const id = fieldDomId(this.path);
54
+ const strValue = typeof this.value === "string" ? this.value : "";
55
+ if (this.readOnly) return this.renderReadOnly(id, strValue);
56
+ return this.renderEditable(id, strValue);
57
+ }
58
+ renderReadOnly(id, strValue) {
59
+ if (strValue.length === 0) return html`<span part="value" id=${id}>${"—"}</span>`;
60
+ const format = this.constraints.format;
61
+ if (format === "email" && isSafeMailtoAddress(strValue)) return html`<a
62
+ part="value"
63
+ href=${`mailto:${strValue}`}
64
+ id=${id}
65
+ aria-readonly="true"
66
+ >${strValue}</a
67
+ >`;
68
+ if ((format === "uri" || format === "url") && isSafeHyperlink(strValue)) return html`<a
69
+ part="value"
70
+ href=${strValue}
71
+ id=${id}
72
+ aria-readonly="true"
73
+ >${strValue}</a
74
+ >`;
75
+ if (format === "date") return html`<span part="value" id=${id}
76
+ >${formatDate(strValue) ?? strValue}</span
77
+ >`;
78
+ if (format === "time") return html`<span part="value" id=${id}
79
+ >${formatTime(strValue) ?? strValue}</span
80
+ >`;
81
+ if (format === "date-time" || format === "datetime") return html`<span part="value" id=${id}
82
+ >${formatDateTime(strValue) ?? strValue}</span
83
+ >`;
84
+ return html`<span part="value" id=${id}>${strValue}</span>`;
85
+ }
86
+ renderEditable(id, strValue) {
87
+ const dateType = dateInputType(this.constraints.format);
88
+ const hint = constraintHint(this.constraints);
89
+ const hintTpl = this.renderHintMaybe(id, hint);
90
+ const describedBy = hint !== void 0 ? hintIdFor(id) : void 0;
91
+ if (dateType !== void 0) return html`
92
+ <input
93
+ part="input"
94
+ id=${id}
95
+ type=${dateType}
96
+ .value=${this.writeOnly ? "" : strValue}
97
+ aria-describedby=${describedBy ?? ""}
98
+ @input=${this.handleInput}
99
+ />
100
+ ${hintTpl}
101
+ `;
102
+ if (this.tree.type === "enum" && this.tree.enumValues.length > 0) {
103
+ const enumValues = this.tree.enumValues;
104
+ const selected = this.writeOnly ? "" : strValue;
105
+ return html`
106
+ <select
107
+ part="input"
108
+ id=${id}
109
+ .value=${selected}
110
+ aria-describedby=${describedBy ?? ""}
111
+ @change=${this.handleSelect}
112
+ >
113
+ <option value="">Select${"…"}</option>
114
+ ${enumValues.map((v) => {
115
+ const display = displayJsonValue(v);
116
+ return html`<option
117
+ value=${display}
118
+ ?selected=${display === selected}
119
+ >
120
+ ${display}
121
+ </option>`;
122
+ })}
123
+ </select>
124
+ ${hintTpl}
125
+ `;
126
+ }
127
+ const isCredential = this.writeOnly && this.constraints.format === "password";
128
+ const inputType = isCredential ? "password" : this.constraints.format === "email" ? "email" : this.constraints.format === "uri" ? "url" : "text";
129
+ const autoComplete = isCredential ? strValue.length > 0 ? "current-password" : "new-password" : void 0;
130
+ const placeholder = typeof this.meta.description === "string" ? this.meta.description : void 0;
131
+ return html`
132
+ <input
133
+ part="input"
134
+ id=${id}
135
+ type=${inputType}
136
+ autocomplete=${autoComplete ?? ""}
137
+ .value=${this.writeOnly ? "" : strValue}
138
+ placeholder=${placeholder ?? ""}
139
+ minlength=${this.constraints.minLength ?? ""}
140
+ maxlength=${this.constraints.maxLength ?? ""}
141
+ aria-describedby=${describedBy ?? ""}
142
+ @input=${this.handleInput}
143
+ />
144
+ ${hintTpl}
145
+ `;
146
+ }
147
+ renderHintMaybe(id, hint) {
148
+ if (hint === void 0) return html``;
149
+ return html`<small part="hint" id=${hintIdFor(id)} class="sc-hint"
150
+ >${hint}</small
151
+ >`;
152
+ }
153
+ handleInput = (e) => {
154
+ const target = e.target;
155
+ if (!(target instanceof HTMLInputElement)) return;
156
+ this.emitChange(target.value);
157
+ };
158
+ handleSelect = (e) => {
159
+ const target = e.target;
160
+ if (!(target instanceof HTMLSelectElement)) return;
161
+ this.emitChange(target.value);
162
+ };
163
+ };
164
+ //#endregion
165
+ export { ScString };
@@ -0,0 +1,14 @@
1
+ import { BaseScElement } from "./baseElement.mjs";
2
+ import { TemplateResult } from "lit";
3
+
4
+ //#region src/lit/renderers/scTuple.d.ts
5
+ /**
6
+ * Lit Custom Element rendering a tuple schema field.
7
+ *
8
+ * Tag: `<sc-tuple>` (registered by `registerSchemaComponents`).
9
+ */
10
+ declare class ScTuple extends BaseScElement {
11
+ render(): TemplateResult;
12
+ }
13
+ //#endregion
14
+ export { ScTuple };
@@ -0,0 +1,58 @@
1
+ import { BaseScElement } from "./baseElement.mjs";
2
+ import { html } from "lit";
3
+ //#region src/lit/renderers/scTuple.ts
4
+ /**
5
+ * `<sc-tuple>` — Custom Element renderer for `TupleField`.
6
+ *
7
+ * Mirrors React's `renderTuple`: positional rendering of every
8
+ * `prefixItems` entry, plus rest items when present. Each entry is
9
+ * threaded with a `[i]` path suffix so child DOM ids remain unique.
10
+ *
11
+ * Parts: `tuple`, `item`, `rest-item`.
12
+ *
13
+ * @packageDocumentation
14
+ */
15
+ function ariaLabel(description) {
16
+ return typeof description === "string" ? description : void 0;
17
+ }
18
+ /**
19
+ * Lit Custom Element rendering a tuple schema field.
20
+ *
21
+ * Tag: `<sc-tuple>` (registered by `registerSchemaComponents`).
22
+ */
23
+ var ScTuple = class extends BaseScElement {
24
+ render() {
25
+ if (this.tree.type !== "tuple") return html``;
26
+ const { prefixItems, restItems } = this.tree;
27
+ const arr = Array.isArray(this.value) ? this.value : [];
28
+ if (prefixItems.length === 0 && restItems === void 0 && arr.length === 0) return html``;
29
+ const restCount = restItems !== void 0 ? Math.max(arr.length - prefixItems.length, 0) : 0;
30
+ return html`<div part="tuple" role="group" aria-label=${ariaLabel(this.meta.description) ?? ""}>
31
+ ${prefixItems.map((element, i) => {
32
+ const itemValue = arr[i];
33
+ const childChange = (v) => {
34
+ const next = arr.slice();
35
+ next[i] = v;
36
+ this.emitChange(next);
37
+ };
38
+ return html`<div part="item">
39
+ ${this.renderChild(element, itemValue, childChange, `[${String(i)}]`)}
40
+ </div>`;
41
+ })}
42
+ ${restItems === void 0 ? html`` : Array.from({ length: restCount }, (_, j) => {
43
+ const i = prefixItems.length + j;
44
+ const itemValue = arr[i];
45
+ const childChange = (v) => {
46
+ const next = arr.slice();
47
+ next[i] = v;
48
+ this.emitChange(next);
49
+ };
50
+ return html`<div part="rest-item">
51
+ ${this.renderChild(restItems, itemValue, childChange, `[${String(i)}]`)}
52
+ </div>`;
53
+ })}
54
+ </div>`;
55
+ }
56
+ };
57
+ //#endregion
58
+ export { ScTuple };
@@ -0,0 +1,14 @@
1
+ import { BaseScElement } from "./baseElement.mjs";
2
+ import { TemplateResult } from "lit";
3
+
4
+ //#region src/lit/renderers/scUnion.d.ts
5
+ /**
6
+ * Lit Custom Element rendering a plain union schema field.
7
+ *
8
+ * Tag: `<sc-union>` (registered by `registerSchemaComponents`).
9
+ */
10
+ declare class ScUnion extends BaseScElement {
11
+ render(): TemplateResult;
12
+ }
13
+ //#endregion
14
+ export { ScUnion };
@@ -0,0 +1,44 @@
1
+ import "../../core/cssClasses.mjs";
2
+ import { matchUnionOption } from "../../core/unionMatch.mjs";
3
+ import { BaseScElement } from "./baseElement.mjs";
4
+ import { html } from "lit";
5
+ //#region src/lit/renderers/scUnion.ts
6
+ /**
7
+ * `<sc-union>` — Custom Element renderer for plain `UnionField`.
8
+ *
9
+ * Mirrors React's `renderUnion`: picks the structurally matching option
10
+ * via {@link matchUnionOption} and delegates to `renderChild`. Falls
11
+ * back to the first option when no match is found, or to the em-dash
12
+ * placeholder when the union has no options.
13
+ *
14
+ * Parts: `value`.
15
+ *
16
+ * @packageDocumentation
17
+ */
18
+ /**
19
+ * Lit Custom Element rendering a plain union schema field.
20
+ *
21
+ * Tag: `<sc-union>` (registered by `registerSchemaComponents`).
22
+ */
23
+ var ScUnion = class extends BaseScElement {
24
+ render() {
25
+ const options = this.tree.type === "union" || this.tree.type === "discriminatedUnion" ? this.tree.options : void 0;
26
+ if (options === void 0 || options.length === 0) {
27
+ if (this.value === void 0 || this.value === null) return html`<span part="value">${"—"}</span>`;
28
+ return html`<span part="value"
29
+ >${JSON.stringify(this.value)}</span
30
+ >`;
31
+ }
32
+ const matched = matchUnionOption(options, this.value);
33
+ if (matched !== void 0) return this.renderChild(matched, this.value, (next) => {
34
+ this.emitChange(next);
35
+ });
36
+ const firstOption = options[0];
37
+ if (firstOption !== void 0) return this.renderChild(firstOption, this.value, (next) => {
38
+ this.emitChange(next);
39
+ });
40
+ return html`<span part="value">${"—"}</span>`;
41
+ }
42
+ };
43
+ //#endregion
44
+ export { ScUnion };
@@ -0,0 +1,15 @@
1
+ import { BaseScElement } from "./baseElement.mjs";
2
+ import { TemplateResult } from "lit";
3
+
4
+ //#region src/lit/renderers/scUnknown.d.ts
5
+ /**
6
+ * Lit Custom Element rendering an unconstrained (`unknown`) schema field.
7
+ *
8
+ * Tag: `<sc-unknown>` (registered by `registerSchemaComponents`).
9
+ */
10
+ declare class ScUnknown extends BaseScElement {
11
+ render(): TemplateResult;
12
+ private handleInput;
13
+ }
14
+ //#endregion
15
+ export { ScUnknown };
@@ -0,0 +1,45 @@
1
+ import "../../core/cssClasses.mjs";
2
+ import { fieldDomId } from "../../core/idPath.mjs";
3
+ import { BaseScElement } from "./baseElement.mjs";
4
+ import { html } from "lit";
5
+ //#region src/lit/renderers/scUnknown.ts
6
+ /**
7
+ * `<sc-unknown>` — Custom Element renderer for `UnknownField`.
8
+ *
9
+ * Mirrors React's `renderUnknown`: a JSON-encoded fallback for
10
+ * unconstrained values — `<input type="text">` in editable mode, a
11
+ * `<span>` showing the stringified value in read-only mode.
12
+ *
13
+ * Parts: `input`, `value`.
14
+ *
15
+ * @packageDocumentation
16
+ */
17
+ /**
18
+ * Lit Custom Element rendering an unconstrained (`unknown`) schema field.
19
+ *
20
+ * Tag: `<sc-unknown>` (registered by `registerSchemaComponents`).
21
+ */
22
+ var ScUnknown = class extends BaseScElement {
23
+ render() {
24
+ const id = fieldDomId(this.path);
25
+ if (this.readOnly) {
26
+ if (this.value === void 0 || this.value === null) return html`<span part="value" id=${id}>${"—"}</span>`;
27
+ return html`<span part="value" id=${id}>${typeof this.value === "string" ? this.value : JSON.stringify(this.value)}</span>`;
28
+ }
29
+ const strValue = typeof this.value === "string" ? this.value : "";
30
+ return html`<input
31
+ part="input"
32
+ id=${id}
33
+ type="text"
34
+ .value=${this.writeOnly ? "" : strValue}
35
+ @input=${this.handleInput}
36
+ />`;
37
+ }
38
+ handleInput = (e) => {
39
+ const target = e.target;
40
+ if (!(target instanceof HTMLInputElement)) return;
41
+ this.emitChange(target.value);
42
+ };
43
+ };
44
+ //#endregion
45
+ export { ScUnknown };