schema-components 1.15.0 → 1.16.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.
@@ -8,14 +8,61 @@
8
8
  * ```html
9
9
  * <link rel="stylesheet" href="node_modules/@scalar/schema-components/dist/styles.css">
10
10
  * ```
11
+ *
12
+ * Every colour flows through a --sc-* custom property. The defaults below
13
+ * cover light mode; the @media (prefers-color-scheme: dark) block redefines
14
+ * them for dark mode. Consumers can override either set of variables to
15
+ * brand the rendered output without forking the stylesheet.
11
16
  */
12
17
 
18
+ :root {
19
+ --sc-object-border: #e2e8f0;
20
+ --sc-legend-text: #334155;
21
+ --sc-label-text: #374151;
22
+ --sc-required-text: #dc2626;
23
+ --sc-input-text: #111827;
24
+ --sc-input-bg: #ffffff;
25
+ --sc-input-border: #d1d5db;
26
+ --sc-focus-ring: #3b82f6;
27
+ --sc-value-text: #111827;
28
+ --sc-value-empty-text: #9ca3af;
29
+ --sc-value-link-text: #2563eb;
30
+ --sc-hint-text: #6b7280;
31
+ --sc-tab-border: #d1d5db;
32
+ --sc-tab-text: #374151;
33
+ --sc-tab-active-bg: #eff6ff;
34
+ --sc-tab-active-border: #3b82f6;
35
+ --sc-tab-active-text: #1d4ed8;
36
+ }
37
+
38
+ @media (prefers-color-scheme: dark) {
39
+ :root {
40
+ --sc-object-border: #334155;
41
+ --sc-legend-text: #cbd5e1;
42
+ --sc-label-text: #cbd5e1;
43
+ --sc-required-text: #fca5a5;
44
+ --sc-input-text: #e2e8f0;
45
+ --sc-input-bg: #1e293b;
46
+ --sc-input-border: #475569;
47
+ --sc-focus-ring: #60a5fa;
48
+ --sc-value-text: #e2e8f0;
49
+ --sc-value-empty-text: #64748b;
50
+ --sc-value-link-text: #93c5fd;
51
+ --sc-hint-text: #94a3b8;
52
+ --sc-tab-border: #475569;
53
+ --sc-tab-text: #cbd5e1;
54
+ --sc-tab-active-bg: #1e3a5f;
55
+ --sc-tab-active-border: #60a5fa;
56
+ --sc-tab-active-text: #93c5fd;
57
+ }
58
+ }
59
+
13
60
  /* ---------------------------------------------------------------------- */
14
61
  /* Object containers */
15
62
  /* ---------------------------------------------------------------------- */
16
63
 
17
64
  .sc-object {
18
- border: 1px solid #e2e8f0;
65
+ border: 1px solid var(--sc-object-border);
19
66
  border-radius: 0.375rem;
20
67
  padding: 1rem;
21
68
  }
@@ -23,7 +70,7 @@
23
70
  .sc-object legend {
24
71
  font-weight: 600;
25
72
  font-size: 0.875rem;
26
- color: #334155;
73
+ color: var(--sc-legend-text);
27
74
  padding: 0 0.25rem;
28
75
  }
29
76
 
@@ -43,12 +90,12 @@
43
90
  display: block;
44
91
  font-size: 0.875rem;
45
92
  font-weight: 500;
46
- color: #374151;
93
+ color: var(--sc-label-text);
47
94
  margin-bottom: 0.25rem;
48
95
  }
49
96
 
50
97
  .sc-required {
51
- color: #dc2626;
98
+ color: var(--sc-required-text);
52
99
  font-weight: 600;
53
100
  }
54
101
 
@@ -59,17 +106,17 @@
59
106
  .sc-input {
60
107
  width: 100%;
61
108
  padding: 0.375rem 0.5rem;
62
- border: 1px solid #d1d5db;
109
+ border: 1px solid var(--sc-input-border);
63
110
  border-radius: 0.25rem;
64
111
  font-size: 0.875rem;
65
112
  line-height: 1.25rem;
66
- color: #111827;
67
- background-color: #fff;
113
+ color: var(--sc-input-text);
114
+ background-color: var(--sc-input-bg);
68
115
  box-sizing: border-box;
69
116
  }
70
117
 
71
118
  .sc-input:focus {
72
- outline: 2px solid #3b82f6;
119
+ outline: 2px solid var(--sc-focus-ring);
73
120
  outline-offset: -1px;
74
121
  border-color: transparent;
75
122
  }
@@ -91,11 +138,11 @@
91
138
 
92
139
  .sc-value {
93
140
  font-size: 0.875rem;
94
- color: #111827;
141
+ color: var(--sc-value-text);
95
142
  }
96
143
 
97
144
  .sc-value--empty {
98
- color: #9ca3af;
145
+ color: var(--sc-value-empty-text);
99
146
  }
100
147
 
101
148
  .sc-value--boolean {
@@ -103,7 +150,7 @@
103
150
  }
104
151
 
105
152
  .sc-value[href] {
106
- color: #2563eb;
153
+ color: var(--sc-value-link-text);
107
154
  text-decoration: none;
108
155
  }
109
156
 
@@ -152,7 +199,7 @@
152
199
  .sc-hint {
153
200
  display: block;
154
201
  font-size: 0.75rem;
155
- color: #6b7280;
202
+ color: var(--sc-hint-text);
156
203
  margin-top: 0.25rem;
157
204
  }
158
205
 
@@ -161,7 +208,7 @@
161
208
  /* ---------------------------------------------------------------------- */
162
209
 
163
210
  .sc-discriminated-union {
164
- border: 1px solid #e2e8f0;
211
+ border: 1px solid var(--sc-object-border);
165
212
  border-radius: 0.375rem;
166
213
  padding: 1rem;
167
214
  }
@@ -174,21 +221,21 @@
174
221
 
175
222
  .sc-tab {
176
223
  padding: 0.25rem 0.75rem;
177
- border: 1px solid #d1d5db;
224
+ border: 1px solid var(--sc-tab-border);
178
225
  border-radius: 0.25rem;
179
226
  background: transparent;
180
227
  cursor: pointer;
181
228
  font-size: 0.875rem;
182
- color: #374151;
229
+ color: var(--sc-tab-text);
183
230
  }
184
231
 
185
232
  .sc-tab:focus-visible {
186
- outline: 2px solid #3b82f6;
233
+ outline: 2px solid var(--sc-focus-ring);
187
234
  outline-offset: 2px;
188
235
  }
189
236
 
190
237
  .sc-tab--active {
191
- border-color: #3b82f6;
192
- background: #eff6ff;
193
- color: #1d4ed8;
238
+ border-color: var(--sc-tab-active-border);
239
+ background: var(--sc-tab-active-bg);
240
+ color: var(--sc-tab-active-text);
194
241
  }
@@ -134,7 +134,7 @@ function renderFieldServer(tree, value, resolver, renderChild, widgets) {
134
134
  throw new SchemaRenderError(err instanceof Error ? err.message : `Render function threw for type "${tree.type}"`, tree, tree.type, err);
135
135
  }
136
136
  }
137
- if (value === void 0 || value === null) return /* @__PURE__ */ jsx("span", { children: "\\u2014" });
137
+ if (value === void 0 || value === null) return /* @__PURE__ */ jsx("span", { children: "" });
138
138
  return /* @__PURE__ */ jsx("span", { children: typeof value === "string" ? value : JSON.stringify(value) });
139
139
  }
140
140
  //#endregion
@@ -71,7 +71,7 @@ function renderString(props) {
71
71
  if (strValue === void 0 || strValue.length === 0) return /* @__PURE__ */ jsx("span", {
72
72
  id,
73
73
  "aria-readonly": "true",
74
- children: "\\u2014"
74
+ children: ""
75
75
  });
76
76
  const format = props.constraints.format;
77
77
  if (format === "email") return /* @__PURE__ */ jsx("a", {
@@ -127,9 +127,9 @@ function renderString(props) {
127
127
  props.onChange(e.target.value);
128
128
  },
129
129
  ...ariaAttrs,
130
- children: [/* @__PURE__ */ jsx("option", {
130
+ children: [/* @__PURE__ */ jsxs("option", {
131
131
  value: "",
132
- children: "Select\\u2026"
132
+ children: ["Select", "…"]
133
133
  }), props.enumValues.map((v) => {
134
134
  const display = v === null ? "null" : typeof v === "string" ? v : String(v);
135
135
  return /* @__PURE__ */ jsx("option", {
@@ -157,7 +157,7 @@ function renderNumber(props) {
157
157
  if (typeof props.value !== "number") return /* @__PURE__ */ jsx("span", {
158
158
  id,
159
159
  "aria-readonly": "true",
160
- children: "\\u2014"
160
+ children: ""
161
161
  });
162
162
  return /* @__PURE__ */ jsx("span", {
163
163
  id,
@@ -186,7 +186,7 @@ function renderBoolean(props) {
186
186
  if (typeof props.value !== "boolean") return /* @__PURE__ */ jsx("span", {
187
187
  id,
188
188
  "aria-readonly": "true",
189
- children: "\\u2014"
189
+ children: ""
190
190
  });
191
191
  return /* @__PURE__ */ jsx("span", {
192
192
  id,
@@ -224,9 +224,9 @@ function renderEnum(props) {
224
224
  props.onChange(e.target.value);
225
225
  },
226
226
  ...ariaAttrs,
227
- children: [/* @__PURE__ */ jsx("option", {
227
+ children: [/* @__PURE__ */ jsxs("option", {
228
228
  value: "",
229
- children: "Select\\u2026"
229
+ children: ["Select", "…"]
230
230
  }), props.enumValues?.map((v) => {
231
231
  const display = v === null ? "null" : typeof v === "string" ? v : String(v);
232
232
  return /* @__PURE__ */ jsx("option", {
@@ -312,20 +312,20 @@ function renderArray(props) {
312
312
  function renderUnion(props) {
313
313
  const options = props.options;
314
314
  if (options === void 0 || options.length === 0) {
315
- if (props.value === void 0 || props.value === null) return /* @__PURE__ */ jsx("span", { children: "\\u2014" });
315
+ if (props.value === void 0 || props.value === null) return /* @__PURE__ */ jsx("span", { children: "" });
316
316
  return /* @__PURE__ */ jsx("span", { children: JSON.stringify(props.value) });
317
317
  }
318
318
  const matched = matchUnionOption(options, props.value);
319
319
  if (matched !== void 0) return toReactNode(props.renderChild(matched, props.value, props.onChange));
320
320
  const firstOption = options[0];
321
321
  if (firstOption !== void 0) return toReactNode(props.renderChild(firstOption, props.value, props.onChange));
322
- return /* @__PURE__ */ jsx("span", { children: "\\u2014" });
322
+ return /* @__PURE__ */ jsx("span", { children: "" });
323
323
  }
324
324
  function renderDiscriminatedUnion(props) {
325
325
  const options = props.options;
326
326
  const discriminator = props.discriminator;
327
327
  if (options === void 0 || options.length === 0) {
328
- if (props.value === void 0 || props.value === null) return /* @__PURE__ */ jsx("span", { children: "\\u2014" });
328
+ if (props.value === void 0 || props.value === null) return /* @__PURE__ */ jsx("span", { children: "" });
329
329
  return /* @__PURE__ */ jsx("span", { children: JSON.stringify(props.value) });
330
330
  }
331
331
  const obj = isObject(props.value) ? props.value : {};
@@ -350,7 +350,7 @@ function renderDiscriminatedUnion(props) {
350
350
  const panelId = inputId(props.path);
351
351
  if (props.readOnly) {
352
352
  if (activeOption !== void 0) return toReactNode(props.renderChild(activeOption, props.value, props.onChange));
353
- return /* @__PURE__ */ jsx("span", { children: "\\u2014" });
353
+ return /* @__PURE__ */ jsx("span", { children: "" });
354
354
  }
355
355
  return /* @__PURE__ */ jsx(DiscriminatedUnionTabs, {
356
356
  options,
@@ -478,7 +478,7 @@ function renderUnknown(props) {
478
478
  if (props.value === void 0 || props.value === null) return /* @__PURE__ */ jsx("span", {
479
479
  id,
480
480
  "aria-readonly": "true",
481
- children: "\\u2014"
481
+ children: ""
482
482
  });
483
483
  return /* @__PURE__ */ jsx("span", {
484
484
  id,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "schema-components",
3
- "version": "1.15.0",
3
+ "version": "1.16.0",
4
4
  "description": "React components that render UI from Zod schemas, JSON Schema, and OpenAPI documents",
5
5
  "type": "module",
6
6
  "main": "./dist/index.mjs",