@oods/components-react 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var React7 = require('react');
3
+ var React8 = require('react');
4
4
  var reactSlot = require('@radix-ui/react-slot');
5
- var jsxRuntime = require('react/jsx-runtime');
6
5
  var componentContracts = require('@oods/component-contracts');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
7
 
8
8
  function _interopNamespace(e) {
9
9
  if (e && e.__esModule) return e;
@@ -23,342 +23,25 @@ function _interopNamespace(e) {
23
23
  return Object.freeze(n);
24
24
  }
25
25
 
26
- var React7__namespace = /*#__PURE__*/_interopNamespace(React7);
26
+ var React8__namespace = /*#__PURE__*/_interopNamespace(React8);
27
27
 
28
28
  // src/presentational.tsx
29
-
30
- // src/status-map.json
31
- var status_map_default = {
32
- domains: {
33
- subscription: {
34
- future: {
35
- description: "Subscription is scheduled but not yet active.",
36
- chip: {
37
- foreground: "color.text.info",
38
- background: "color.background.info.subtle",
39
- border: "color.border.info",
40
- icon: "icon.status.scheduled"
41
- },
42
- banner: {
43
- foreground: "color.text.info",
44
- background: "color.background.surface.default",
45
- border: "color.border.info",
46
- icon: "icon.status.scheduled"
47
- }
48
- },
49
- trialing: {
50
- description: "Subscription is in a trial period before billing begins.",
51
- chip: {
52
- foreground: "color.text.accent",
53
- background: "color.background.accent.subtle",
54
- border: "color.border.accent",
55
- icon: "icon.status.trial"
56
- },
57
- banner: {
58
- foreground: "color.text.accent",
59
- background: "color.background.surface.default",
60
- border: "color.border.accent",
61
- icon: "icon.status.trial"
62
- }
63
- },
64
- active: {
65
- description: "Subscription is paid and service is provisioned.",
66
- chip: {
67
- foreground: "color.text.positive",
68
- background: "color.background.positive.subtle",
69
- border: "color.border.positive",
70
- icon: "icon.status.success"
71
- },
72
- banner: {
73
- foreground: "color.text.positive",
74
- background: "color.background.surface.default",
75
- border: "color.border.positive",
76
- icon: "icon.status.success"
77
- }
78
- },
79
- paused: {
80
- description: "Billing paused temporarily by finance or customer request.",
81
- chip: {
82
- foreground: "color.text.neutral",
83
- background: "color.background.neutral.subtle",
84
- border: "color.border.neutral",
85
- icon: "icon.status.paused"
86
- },
87
- banner: {
88
- foreground: "color.text.neutral",
89
- background: "color.background.surface.muted",
90
- border: "color.border.neutral",
91
- icon: "icon.status.paused"
92
- }
93
- },
94
- pending_cancellation: {
95
- description: "Subscription will cancel at period end but remains active now.",
96
- chip: {
97
- foreground: "color.text.info",
98
- background: "color.background.info.subtle",
99
- border: "color.border.info",
100
- icon: "icon.status.pending"
101
- },
102
- banner: {
103
- foreground: "color.text.info",
104
- background: "color.background.surface.default",
105
- border: "color.border.info",
106
- icon: "icon.status.pending"
107
- }
108
- },
109
- past_due: {
110
- description: "Renewal payment failed; smart retries ongoing and access retained during the grace window.",
111
- chip: {
112
- foreground: "color.text.danger",
113
- background: "color.background.danger.subtle",
114
- border: "color.border.danger",
115
- icon: "icon.status.warning"
116
- },
117
- banner: {
118
- foreground: "color.text.onbold",
119
- background: "color.background.danger.bold",
120
- border: "color.border.danger",
121
- icon: "icon.status.warning"
122
- }
123
- },
124
- unpaid: {
125
- description: "Payment retries exhausted; service access revoked.",
126
- chip: {
127
- foreground: "color.text.danger",
128
- background: "color.background.danger.subtle",
129
- border: "color.border.danger",
130
- icon: "icon.status.error"
131
- },
132
- banner: {
133
- foreground: "color.text.onbold",
134
- background: "color.background.danger.bold",
135
- border: "color.border.danger",
136
- icon: "icon.status.error"
137
- }
138
- },
139
- terminated: {
140
- description: "Subscription ended; service access revoked and billing stopped.",
141
- chip: {
142
- foreground: "color.text.disabled",
143
- background: "color.background.disabled",
144
- border: "color.border.disabled",
145
- icon: "icon.status.canceled"
146
- },
147
- banner: {
148
- foreground: "color.text.neutral",
149
- background: "color.background.neutral.subtle",
150
- border: "color.border.neutral",
151
- icon: "icon.status.canceled"
152
- }
153
- }
154
- },
155
- invoice: {
156
- draft: {
157
- description: "Invoice is editable and not yet finalized.",
158
- chip: {
159
- foreground: "color.text.neutral",
160
- background: "color.background.neutral.subtle",
161
- border: "color.border.neutral",
162
- icon: "icon.status.draft"
163
- },
164
- banner: {
165
- foreground: "color.text.neutral",
166
- background: "color.background.surface.muted",
167
- border: "color.border.neutral",
168
- icon: "icon.status.draft"
169
- }
170
- },
171
- posted: {
172
- description: "Invoice finalized with terms before collection.",
173
- chip: {
174
- foreground: "color.text.info",
175
- background: "color.background.info.subtle",
176
- border: "color.border.info",
177
- icon: "icon.status.pending"
178
- },
179
- banner: {
180
- foreground: "color.text.info",
181
- background: "color.background.surface.default",
182
- border: "color.border.info",
183
- icon: "icon.status.pending"
184
- }
185
- },
186
- paid: {
187
- description: "Invoice collected successfully in full.",
188
- chip: {
189
- foreground: "color.text.positive",
190
- background: "color.background.positive.subtle",
191
- border: "color.border.positive",
192
- icon: "icon.status.success"
193
- },
194
- banner: {
195
- foreground: "color.text.positive",
196
- background: "color.background.surface.default",
197
- border: "color.border.positive",
198
- icon: "icon.status.success"
199
- }
200
- },
201
- past_due: {
202
- description: "Invoice is unpaid past its due date.",
203
- chip: {
204
- foreground: "color.text.danger",
205
- background: "color.background.danger.subtle",
206
- border: "color.border.danger",
207
- icon: "icon.status.error"
208
- },
209
- banner: {
210
- foreground: "color.text.onbold",
211
- background: "color.background.danger.bold",
212
- border: "color.border.danger",
213
- icon: "icon.status.error"
214
- }
215
- },
216
- void: {
217
- description: "Invoice canceled and no longer payable.",
218
- chip: {
219
- foreground: "color.text.disabled",
220
- background: "color.background.disabled",
221
- border: "color.border.disabled",
222
- icon: "icon.status.void"
223
- },
224
- banner: {
225
- foreground: "color.text.neutral",
226
- background: "color.background.neutral.subtle",
227
- border: "color.border.neutral",
228
- icon: "icon.status.void"
229
- }
230
- }
231
- }
232
- }
233
- };
234
-
235
- // src/status.ts
236
- var TONE_ALIASES = {
237
- info: "info",
238
- informational: "info",
239
- accent: "accent",
240
- highlight: "accent",
241
- positive: "success",
242
- success: "success",
243
- ok: "success",
244
- warning: "warning",
245
- caution: "warning",
246
- danger: "critical",
247
- critical: "critical",
248
- error: "critical",
249
- negative: "critical",
250
- neutral: "neutral",
251
- pending: "info"
29
+ var REACT_NAMES = {
30
+ viewBox: "viewBox",
31
+ fill: "fill",
32
+ stroke: "stroke",
33
+ "stroke-width": "strokeWidth",
34
+ "stroke-linecap": "strokeLinecap",
35
+ "stroke-linejoin": "strokeLinejoin",
36
+ "aria-hidden": "aria-hidden",
37
+ focusable: "focusable"
252
38
  };
253
- var toLabel = (status) => status.split(/[_-]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join(" ");
254
- var inferTone = (entry) => {
255
- if (!entry) return "neutral";
256
- for (const reference of [entry.foreground, entry.background, entry.border]) {
257
- const segments = reference.replace(/^\{|\}$/g, "").split(/[\s./_-]+/).reverse();
258
- for (const segment of segments) {
259
- const tone = TONE_ALIASES[segment.toLowerCase()];
260
- if (tone) return tone;
261
- }
262
- }
263
- return "neutral";
264
- };
265
- var componentTokenSet = (tone) => {
266
- const normalized = tone === "positive" ? "success" : tone === "danger" ? "critical" : tone;
267
- return {
268
- background: `var(--sys-status-${normalized}-surface)`,
269
- border: `var(--sys-status-${normalized}-border)`,
270
- foreground: `var(--sys-status-${normalized}-text)`
271
- };
272
- };
273
- var rawTokenSet = (entry) => {
274
- const tone = inferTone(entry);
275
- return componentTokenSet(tone);
276
- };
277
- var bannerFallback = (tone) => tone === "neutral" ? {
278
- background: "var(--cmp-banner-background)",
279
- border: "var(--cmp-banner-border)",
280
- foreground: "var(--cmp-banner-text)"
281
- } : componentTokenSet(tone);
282
- var fallback = (domain, status, tone = "neutral") => ({
283
- domain,
284
- status,
285
- label: toLabel(status || "Unknown"),
286
- description: "Status not found in registry; falling back to the requested token set.",
287
- tone,
288
- badge: { subtle: componentTokenSet(tone), solid: componentTokenSet(tone) },
289
- banner: { subtle: bannerFallback(tone), solid: componentTokenSet(tone) }
290
- });
291
- var registry = /* @__PURE__ */ new Map();
292
- for (const [domain, entries] of Object.entries(status_map_default.domains)) {
293
- const domainEntries = /* @__PURE__ */ new Map();
294
- for (const [status, entry] of Object.entries(entries)) {
295
- const tone = inferTone(entry.chip);
296
- domainEntries.set(status.toLowerCase(), {
297
- domain,
298
- status,
299
- label: toLabel(status),
300
- description: entry.description,
301
- tone,
302
- iconName: entry.chip.icon ?? entry.banner?.icon,
303
- badge: { subtle: rawTokenSet(entry.chip), solid: componentTokenSet(tone) },
304
- banner: {
305
- subtle: entry.banner ? rawTokenSet(entry.banner) : bannerFallback(tone),
306
- solid: componentTokenSet(tone)
307
- }
308
- });
309
- }
310
- registry.set(domain, domainEntries);
311
- }
312
- var LEGACY_STATUS_ALIASES = {
313
- subscription: { delinquent: "unpaid" }
314
- };
315
- Object.freeze([...registry.keys()]);
316
- function getStatusPresentation(domain, status) {
317
- const entries = registry.get(domain);
318
- if (!entries) return fallback(domain, status);
319
- const normalized = status.toLowerCase();
320
- const direct = entries.get(normalized);
321
- if (direct) return direct;
322
- const alias = LEGACY_STATUS_ALIASES[domain]?.[normalized];
323
- const aliased = alias ? entries.get(alias) : void 0;
324
- return aliased ? { ...aliased, status, label: toLabel(status) } : fallback(domain, status);
325
- }
326
- function getToneTokenSet(tone) {
327
- return componentTokenSet(tone);
328
- }
329
- function getBannerToneTokenSet(tone) {
330
- return bannerFallback(tone);
331
- }
332
- var ICON_GLYPHS = {
333
- success: "\u2714\uFE0E",
334
- warning: "\u26A0\uFE0E",
335
- critical: "\u2A2F",
336
- danger: "\u2A2F",
337
- error: "\u2A2F",
338
- negative: "\u2A2F",
339
- pending: "\u2026",
340
- processing: "\u27F3",
341
- paused: "\u23F8",
342
- canceled: "\u2205",
343
- cancelled: "\u2205",
344
- draft: "\u270E",
345
- void: "\u2205",
346
- paid: "\u2714\uFE0E",
347
- info: "\u2139\uFE0E",
348
- trial: "\u2605",
349
- future: "\u23F2",
350
- scheduled: "\u23F2",
351
- refunded: "\u21BA",
352
- locked: "\u{1F512}",
353
- unlocked: "\u{1F513}",
354
- default: "\u2022"
355
- };
356
- function resolveStatusGlyph(iconName) {
357
- const segment = iconName?.split(".").pop()?.toLowerCase();
358
- return segment ? ICON_GLYPHS[segment] ?? ICON_GLYPHS.default : void 0;
39
+ var svgProps = Object.fromEntries(Object.entries(componentContracts.STATUS_ICON_SVG_ATTRS).map(([name, value]) => [REACT_NAMES[name] ?? name, value]));
40
+ function StatusIcon({ name }) {
41
+ return /* @__PURE__ */ jsxRuntime.jsx("svg", { ...svgProps, children: componentContracts.STATUS_ICON_SHAPES[name].map((shape, index) => React8__namespace.createElement(shape.tag, { key: index, ...shape.attrs })) });
359
42
  }
360
43
  var classes = (...values) => values.filter(Boolean).join(" ");
361
- var Badge = React7__namespace.forwardRef(
44
+ var Badge = React8__namespace.forwardRef(
362
45
  ({
363
46
  content,
364
47
  status,
@@ -375,18 +58,19 @@ var Badge = React7__namespace.forwardRef(
375
58
  "aria-label": ariaLabel,
376
59
  ...rest
377
60
  }, ref) => {
378
- const presentation = status ? getStatusPresentation(domain, status) : void 0;
61
+ const presentation = status ? componentContracts.getStatusPresentation(domain, status) : void 0;
379
62
  const tone = toneOverride ?? presentation?.tone ?? "neutral";
380
- const tokenSet = toneOverride !== void 0 ? getToneTokenSet(tone) : emphasis === "solid" ? presentation?.badge.solid ?? getToneTokenSet(tone) : presentation?.badge.subtle ?? getToneTokenSet(tone);
63
+ const tokenSet = toneOverride !== void 0 ? componentContracts.getToneTokenSet(tone) : emphasis === "solid" ? presentation?.badge.solid ?? componentContracts.getToneTokenSet(tone) : presentation?.badge.subtle ?? componentContracts.getToneTokenSet(tone);
381
64
  const resolvedContent = children ?? content ?? presentation?.label ?? status;
382
- const resolvedIcon = icon ?? resolveStatusGlyph(presentation?.iconName);
65
+ const statusIcon = componentContracts.resolveStatusIcon(presentation?.iconName);
66
+ const resolvedIcon = icon ?? (statusIcon ? /* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { name: statusIcon }) : void 0);
383
67
  const resolvedShowIcon = showIcon ?? resolvedIcon !== void 0;
384
- const iconNode = resolvedShowIcon && resolvedIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oods-badge__icon statusable-badge__icon", "aria-hidden": "true", children: resolvedIcon }) : null;
68
+ const iconNode = resolvedShowIcon && resolvedIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oods-badge__icon", "aria-hidden": "true", children: resolvedIcon }) : null;
385
69
  return /* @__PURE__ */ jsxRuntime.jsxs(
386
70
  "span",
387
71
  {
388
72
  ref,
389
- className: classes("oods-badge", "statusable-badge", className),
73
+ className: classes("oods-badge", className),
390
74
  "data-oods-component": "Badge",
391
75
  "data-status": status,
392
76
  "data-domain": domain,
@@ -398,16 +82,12 @@ var Badge = React7__namespace.forwardRef(
398
82
  "--cmp-badge-background": tokenSet.background,
399
83
  "--cmp-badge-border": tokenSet.border,
400
84
  "--cmp-badge-text": tokenSet.foreground,
401
- "--statusable-badge-background": tokenSet.background,
402
- "--statusable-badge-border": tokenSet.border,
403
- "--statusable-badge-foreground": tokenSet.foreground,
404
- "--statusable-badge-icon-color": tokenSet.foreground,
405
85
  ...style
406
86
  },
407
87
  ...rest,
408
88
  children: [
409
89
  iconPosition === "start" ? iconNode : null,
410
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oods-badge__label statusable-badge__label", children: resolvedContent }),
90
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oods-badge__label", children: resolvedContent }),
411
91
  iconPosition === "end" ? iconNode : null
412
92
  ]
413
93
  }
@@ -415,7 +95,7 @@ var Badge = React7__namespace.forwardRef(
415
95
  }
416
96
  );
417
97
  Badge.displayName = "OODS.Badge";
418
- var Banner = React7__namespace.forwardRef(
98
+ var Banner = React8__namespace.forwardRef(
419
99
  ({
420
100
  title,
421
101
  detail,
@@ -435,13 +115,14 @@ var Banner = React7__namespace.forwardRef(
435
115
  style,
436
116
  ...rest
437
117
  }, ref) => {
438
- const presentation = status ? getStatusPresentation(domain, status) : void 0;
118
+ const presentation = status ? componentContracts.getStatusPresentation(domain, status) : void 0;
439
119
  const tone = toneOverride ?? presentation?.tone ?? "neutral";
440
- const tokenSet = emphasis === "solid" ? presentation?.banner.solid ?? getToneTokenSet(tone) : presentation?.banner.subtle ?? getBannerToneTokenSet(tone);
120
+ const tokenSet = emphasis === "solid" ? presentation?.banner.solid ?? componentContracts.getToneTokenSet(tone) : presentation?.banner.subtle ?? componentContracts.getBannerToneTokenSet(tone);
441
121
  const heading = title ?? presentation?.label ?? status;
442
122
  const body = detail ?? description ?? children ?? content ?? presentation?.description;
443
123
  const role = tone === "critical" || tone === "danger" ? "alert" : "status";
444
- const resolvedIcon = icon ?? resolveStatusGlyph(presentation?.iconName);
124
+ const statusIcon = componentContracts.resolveStatusIcon(presentation?.iconName);
125
+ const resolvedIcon = icon ?? (statusIcon ? /* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { name: statusIcon }) : void 0);
445
126
  const resolvedShowIcon = showIcon ?? resolvedIcon !== void 0;
446
127
  return /* @__PURE__ */ jsxRuntime.jsxs(
447
128
  "div",
@@ -449,7 +130,7 @@ var Banner = React7__namespace.forwardRef(
449
130
  ref,
450
131
  role,
451
132
  "aria-live": role === "alert" ? "assertive" : "polite",
452
- className: classes("oods-banner", "statusable-banner", className),
133
+ className: classes("oods-banner", className),
453
134
  "data-oods-component": "Banner",
454
135
  "data-status": status,
455
136
  "data-domain": domain,
@@ -459,28 +140,24 @@ var Banner = React7__namespace.forwardRef(
459
140
  "--cmp-banner-background": tokenSet.background,
460
141
  "--cmp-banner-border": tokenSet.border,
461
142
  "--cmp-banner-text": tokenSet.foreground,
462
- "--statusable-banner-background": tokenSet.background,
463
- "--statusable-banner-border": tokenSet.border,
464
- "--statusable-banner-foreground": tokenSet.foreground,
465
- "--statusable-banner-icon-color": tokenSet.foreground,
466
143
  ...style
467
144
  },
468
145
  ...rest,
469
146
  children: [
470
- resolvedShowIcon && resolvedIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oods-banner__icon statusable-banner__icon", "aria-hidden": "true", children: resolvedIcon }) : null,
471
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oods-banner__content statusable-banner__content", children: [
472
- heading ? /* @__PURE__ */ jsxRuntime.jsx("strong", { className: "oods-banner__title statusable-banner__title", children: heading }) : null,
473
- body ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oods-banner__detail statusable-banner__description", children: body }) : null,
474
- actions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oods-banner__actions statusable-banner__actions", children: actions }) : null
147
+ resolvedShowIcon && resolvedIcon ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oods-banner__icon", "aria-hidden": "true", children: resolvedIcon }) : null,
148
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oods-banner__content", children: [
149
+ heading ? /* @__PURE__ */ jsxRuntime.jsx("strong", { className: "oods-banner__title", children: heading }) : null,
150
+ body ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oods-banner__detail", children: body }) : null,
151
+ actions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oods-banner__actions", children: actions }) : null
475
152
  ] }),
476
153
  onDismiss ? /* @__PURE__ */ jsxRuntime.jsx(
477
154
  "button",
478
155
  {
479
156
  type: "button",
480
- className: "oods-banner-dismiss oods-banner__dismiss statusable-banner__dismiss",
157
+ className: "oods-banner-dismiss oods-banner__dismiss",
481
158
  "aria-label": dismissLabel,
482
159
  onClick: () => onDismiss(),
483
- children: /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\xD7" })
160
+ children: /* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { name: "x" })
484
161
  }
485
162
  ) : null
486
163
  ]
@@ -489,7 +166,7 @@ var Banner = React7__namespace.forwardRef(
489
166
  }
490
167
  );
491
168
  Banner.displayName = "OODS.Banner";
492
- var Button = React7__namespace.forwardRef(
169
+ var Button = React8__namespace.forwardRef(
493
170
  ({
494
171
  asChild = false,
495
172
  content,
@@ -535,7 +212,85 @@ var Button = React7__namespace.forwardRef(
535
212
  }
536
213
  );
537
214
  Button.displayName = "OODS.Button";
538
- var Card = React7__namespace.forwardRef(
215
+ var noSubscription = () => () => void 0;
216
+ var useIsomorphicLayoutEffect = typeof window === "undefined" ? React8__namespace.useEffect : React8__namespace.useLayoutEffect;
217
+ var canShowModal = () => typeof HTMLDialogElement !== "undefined" && typeof HTMLDialogElement.prototype.showModal === "function";
218
+ var hasContent = (node) => node !== void 0 && node !== null && node !== false && node !== "";
219
+ var Dialog = React8__namespace.forwardRef(
220
+ ({
221
+ id,
222
+ open = false,
223
+ modal = true,
224
+ title,
225
+ description,
226
+ dismissLabel = "Close",
227
+ size = "md",
228
+ actions,
229
+ children,
230
+ className,
231
+ onClose,
232
+ onKeyDown,
233
+ ...rest
234
+ }, ref) => {
235
+ const generatedId = React8__namespace.useId().replace(/[^\w-]/g, "");
236
+ const dialogId = id ?? `oods-dialog-${generatedId}`;
237
+ const element = React8__namespace.useRef(null);
238
+ const openRef = React8__namespace.useRef(open);
239
+ const serverMarkup = React8__namespace.useSyncExternalStore(noSubscription, () => false, () => true);
240
+ const managed = modal && !serverMarkup && canShowModal();
241
+ const setRef = React8__namespace.useCallback((node) => {
242
+ element.current = node;
243
+ if (typeof ref === "function") ref(node);
244
+ else if (ref) ref.current = node;
245
+ }, [ref]);
246
+ useIsomorphicLayoutEffect(() => {
247
+ openRef.current = open;
248
+ const dialog = element.current;
249
+ if (!dialog || !managed) return;
250
+ if (open && !dialog.open) dialog.showModal();
251
+ else if (!open && dialog.open) dialog.close();
252
+ }, [open, managed]);
253
+ const requestClose = (event) => {
254
+ event.preventDefault();
255
+ onClose?.();
256
+ };
257
+ return /* @__PURE__ */ jsxRuntime.jsxs(
258
+ "dialog",
259
+ {
260
+ ref: setRef,
261
+ id: dialogId,
262
+ className: classes("oods-dialog", className),
263
+ "data-oods-component": "Dialog",
264
+ "data-size": size,
265
+ "aria-labelledby": `${dialogId}-title`,
266
+ "aria-describedby": hasContent(description) ? `${dialogId}-description` : void 0,
267
+ open: managed ? void 0 : open,
268
+ onKeyDown: (event) => {
269
+ onKeyDown?.(event);
270
+ if (event.key === "Escape" && !event.defaultPrevented) requestClose(event);
271
+ },
272
+ onCancel: requestClose,
273
+ onClose: () => {
274
+ if (openRef.current && !element.current?.open) onClose?.();
275
+ },
276
+ ...rest,
277
+ children: [
278
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oods-dialog__header", children: [
279
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oods-dialog__heading", children: [
280
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { id: `${dialogId}-title`, className: "oods-dialog__title", children: title }),
281
+ hasContent(description) ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: `${dialogId}-description`, className: "oods-dialog__description", children: description }) : null
282
+ ] }),
283
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "oods-dialog__close", "aria-label": dismissLabel, onClick: () => onClose?.(), children: /* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { name: "x" }) })
284
+ ] }),
285
+ hasContent(children) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oods-dialog__body", children }) : null,
286
+ hasContent(actions) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oods-dialog__footer", children: actions }) : null
287
+ ]
288
+ }
289
+ );
290
+ }
291
+ );
292
+ Dialog.displayName = "OODS.Dialog";
293
+ var Card = React8__namespace.forwardRef(
539
294
  ({ as = "div", elevated = false, className, ...rest }, ref) => {
540
295
  const Element = as;
541
296
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -551,7 +306,7 @@ var Card = React7__namespace.forwardRef(
551
306
  }
552
307
  );
553
308
  Card.displayName = "OODS.Card";
554
- var Text = React7__namespace.forwardRef(
309
+ var Text = React8__namespace.forwardRef(
555
310
  ({
556
311
  as = "span",
557
312
  content,
@@ -606,7 +361,7 @@ var FieldFrame = ({
606
361
  }) => {
607
362
  const resolvedHelp = help ?? description;
608
363
  const validationTone = validation?.state === "error" ? "critical" : validation?.state === "warning" ? "warning" : validation?.state;
609
- const validationTokens = validationTone ? getToneTokenSet(validationTone) : void 0;
364
+ const validationTokens = validationTone ? componentContracts.getToneTokenSet(validationTone) : void 0;
610
365
  const validationStyle = validationTokens ? {
611
366
  "--cmp-input-message-border": validationTokens.border,
612
367
  "--cmp-input-message-text": validationTokens.foreground,
@@ -660,7 +415,7 @@ var FieldFrame = ({
660
415
  }
661
416
  );
662
417
  };
663
- var InputPrimitive = React7__namespace.forwardRef(
418
+ var InputPrimitive = React8__namespace.forwardRef(
664
419
  ({
665
420
  id,
666
421
  label,
@@ -730,21 +485,20 @@ var InputPrimitive = React7__namespace.forwardRef(
730
485
  );
731
486
  InputPrimitive.displayName = "OODS.Input";
732
487
  var Input = InputPrimitive;
733
- var DatePicker = React7__namespace.forwardRef(
734
- ({ pickerClassName, pickerStyle, inputClassName, inputStyle, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
488
+ var DatePicker = React8__namespace.forwardRef(
489
+ ({ pickerClassName, pickerStyle, inputClassName, inputStyle, className, style, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: classes2("oods-date-picker", className), style, "data-oods-component": "DatePicker", children: /* @__PURE__ */ jsxRuntime.jsx(
735
490
  Input,
736
491
  {
737
492
  ref,
738
493
  type: "date",
739
- "data-oods-component": "DatePicker",
740
494
  inputClassName: classes2("form-field__date-picker", inputClassName, pickerClassName),
741
495
  inputStyle: { ...inputStyle, ...pickerStyle },
742
496
  ...rest
743
497
  }
744
- )
498
+ ) })
745
499
  );
746
500
  DatePicker.displayName = "OODS.DatePicker";
747
- var Checkbox = React7__namespace.forwardRef(
501
+ var Checkbox = React8__namespace.forwardRef(
748
502
  ({
749
503
  id,
750
504
  label,
@@ -807,7 +561,85 @@ var Checkbox = React7__namespace.forwardRef(
807
561
  }
808
562
  );
809
563
  Checkbox.displayName = "OODS.Checkbox";
810
- var Select = React7__namespace.forwardRef(
564
+ var Switch = React8__namespace.forwardRef(
565
+ ({
566
+ id,
567
+ label,
568
+ checked,
569
+ defaultChecked = false,
570
+ required,
571
+ help,
572
+ validation,
573
+ size = "md",
574
+ className,
575
+ style,
576
+ onClick,
577
+ onCheckedChange,
578
+ onUpdate,
579
+ "aria-describedby": nativeDescription,
580
+ ...rest
581
+ }, ref) => {
582
+ const [internalChecked, setInternalChecked] = React8__namespace.useState(defaultChecked);
583
+ const on = checked ?? internalChecked;
584
+ const validationId = validation?.id ?? `${id}-validation`;
585
+ const describedBy = [nativeDescription, help ? `${id}-help` : void 0, validation?.message ? validationId : void 0].filter(Boolean).join(" ") || void 0;
586
+ const tone = validation ? validation.state === "error" ? "critical" : validation.state : void 0;
587
+ const handleClick = (event) => {
588
+ onClick?.(event);
589
+ if (event.defaultPrevented) return;
590
+ const next = !on;
591
+ if (checked === void 0) setInternalChecked(next);
592
+ onCheckedChange?.(next);
593
+ onUpdate?.(next);
594
+ };
595
+ return /* @__PURE__ */ jsxRuntime.jsxs(
596
+ "div",
597
+ {
598
+ className: classes2("oods-field", "oods-switch", className),
599
+ style: {
600
+ ...tone ? {
601
+ "--cmp-input-message-border": `var(--sys-status-${tone}-border)`,
602
+ "--cmp-input-message-text": `var(--sys-status-${tone}-text)`
603
+ } : {},
604
+ ...style
605
+ },
606
+ "data-oods-component": "Switch",
607
+ "data-size": size,
608
+ "data-validation-state": validation?.state,
609
+ children: [
610
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oods-switch__row", children: [
611
+ /* @__PURE__ */ jsxRuntime.jsx(
612
+ "button",
613
+ {
614
+ ref,
615
+ id,
616
+ type: "button",
617
+ role: "switch",
618
+ className: "oods-switch__control",
619
+ "aria-checked": on,
620
+ "aria-labelledby": `${id}-label`,
621
+ "aria-describedby": describedBy,
622
+ "aria-required": required || void 0,
623
+ "aria-invalid": validation?.state === "error" || void 0,
624
+ onClick: handleClick,
625
+ ...rest,
626
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oods-switch__thumb", "aria-hidden": "true" })
627
+ }
628
+ ),
629
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { id: `${id}-label`, className: "oods-field-label oods-switch__label", htmlFor: id, children: [
630
+ label,
631
+ required ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oods-field-required", "aria-hidden": "true", children: "*" }) : null
632
+ ] })
633
+ ] }),
634
+ help ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: `${id}-help`, className: "oods-field-help", children: help }) : null,
635
+ validation?.message ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: validationId, className: "oods-field-error", role: validation.state === "error" ? "alert" : void 0, children: validation.message }) : null
636
+ ]
637
+ }
638
+ );
639
+ }
640
+ );
641
+ Switch.displayName = "OODS.Switch";
642
+ var Select = React8__namespace.forwardRef(
811
643
  ({
812
644
  id,
813
645
  label,
@@ -875,7 +707,7 @@ var Select = React7__namespace.forwardRef(
875
707
  }
876
708
  );
877
709
  Select.displayName = "OODS.Select";
878
- var Textarea = React7__namespace.forwardRef(
710
+ var Textarea = React8__namespace.forwardRef(
879
711
  ({
880
712
  id,
881
713
  label,
@@ -958,7 +790,7 @@ var maxColumns = (columns) => {
958
790
  const count = Number(columns);
959
791
  return Number.isFinite(count) && count > 0 ? count : void 0;
960
792
  };
961
- var Grid = React7__namespace.forwardRef(
793
+ var Grid = React8__namespace.forwardRef(
962
794
  ({
963
795
  columns = "auto-fit",
964
796
  minColumnWidth = "16rem",
@@ -988,7 +820,7 @@ var Grid = React7__namespace.forwardRef(
988
820
  )
989
821
  );
990
822
  Grid.displayName = "OODS.Grid";
991
- var Stack = React7__namespace.forwardRef(
823
+ var Stack = React8__namespace.forwardRef(
992
824
  ({
993
825
  direction = "column",
994
826
  gap = "md",
@@ -1020,19 +852,19 @@ var Stack = React7__namespace.forwardRef(
1020
852
  );
1021
853
  Stack.displayName = "OODS.Stack";
1022
854
  var classes4 = (...values) => values.filter(Boolean).join(" ");
1023
- var TableHead = React7__namespace.forwardRef(
855
+ var TableHead = React8__namespace.forwardRef(
1024
856
  ({ className, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx("thead", { ref, className: classes4("oods-table__header", className), ...rest })
1025
857
  );
1026
858
  TableHead.displayName = "OODS.Table.Head";
1027
- var TableBody = React7__namespace.forwardRef(
859
+ var TableBody = React8__namespace.forwardRef(
1028
860
  ({ className, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx("tbody", { ref, className: classes4("oods-table__body", className), ...rest })
1029
861
  );
1030
862
  TableBody.displayName = "OODS.Table.Body";
1031
- var TableCaption = React7__namespace.forwardRef(
863
+ var TableCaption = React8__namespace.forwardRef(
1032
864
  ({ className, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx("caption", { ref, className: classes4("oods-table__caption", className), ...rest })
1033
865
  );
1034
866
  TableCaption.displayName = "OODS.Table.Caption";
1035
- var TableRow = React7__namespace.forwardRef(
867
+ var TableRow = React8__namespace.forwardRef(
1036
868
  ({
1037
869
  selectable = false,
1038
870
  selected = false,
@@ -1071,7 +903,7 @@ var TableRow = React7__namespace.forwardRef(
1071
903
  }
1072
904
  );
1073
905
  TableRow.displayName = "OODS.Table.Row";
1074
- var TableHeaderCell = React7__namespace.forwardRef(
906
+ var TableHeaderCell = React8__namespace.forwardRef(
1075
907
  ({ numeric = false, className, scope = "col", ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
1076
908
  "th",
1077
909
  {
@@ -1088,7 +920,7 @@ var TableHeaderCell = React7__namespace.forwardRef(
1088
920
  )
1089
921
  );
1090
922
  TableHeaderCell.displayName = "OODS.Table.HeaderCell";
1091
- var TableCell = React7__namespace.forwardRef(
923
+ var TableCell = React8__namespace.forwardRef(
1092
924
  ({
1093
925
  numeric = false,
1094
926
  status,
@@ -1101,9 +933,9 @@ var TableCell = React7__namespace.forwardRef(
1101
933
  title,
1102
934
  ...rest
1103
935
  }, ref) => {
1104
- const presentation = status ? getStatusPresentation(statusDomain, status) : void 0;
936
+ const presentation = status ? componentContracts.getStatusPresentation(statusDomain, status) : void 0;
1105
937
  const tone = toneOverride ?? presentation?.tone;
1106
- const tokens = tone ? getToneTokenSet(tone) : void 0;
938
+ const tokens = tone ? componentContracts.getToneTokenSet(tone) : void 0;
1107
939
  const statusStyle = tokens ? statusEmphasis === "text" ? { "--table-cell-status-foreground": tokens.foreground } : {
1108
940
  "--table-cell-status-background": tokens.background,
1109
941
  "--table-cell-status-border": tokens.border,
@@ -1134,9 +966,10 @@ var TableCell = React7__namespace.forwardRef(
1134
966
  }
1135
967
  );
1136
968
  TableCell.displayName = "OODS.Table.Cell";
1137
- var TableRoot = React7__namespace.forwardRef(
969
+ var TableRoot = React8__namespace.forwardRef(
1138
970
  ({
1139
971
  caption,
972
+ showCaption = true,
1140
973
  columns,
1141
974
  rows,
1142
975
  density = "comfortable",
@@ -1162,8 +995,8 @@ var TableRoot = React7__namespace.forwardRef(
1162
995
  "data-density": density,
1163
996
  ...rest,
1164
997
  children: children ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1165
- caption ? /* @__PURE__ */ jsxRuntime.jsx(TableCaption, { children: caption }) : null,
1166
- /* @__PURE__ */ jsxRuntime.jsx(TableHead, { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: columns?.map((column) => /* @__PURE__ */ jsxRuntime.jsx(TableHeaderCell, { numeric: column.numeric, children: column.label }, column.key)) }) }),
998
+ caption ? /* @__PURE__ */ jsxRuntime.jsx(TableCaption, { "data-visually-hidden": showCaption ? void 0 : "true", children: caption }) : null,
999
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "oods-table__row", children: columns?.map((column) => /* @__PURE__ */ jsxRuntime.jsx(TableHeaderCell, { numeric: column.numeric, children: column.label }, column.key)) }) }),
1167
1000
  /* @__PURE__ */ jsxRuntime.jsx(TableBody, { children: (rows?.length ?? 0) === 0 ? /* @__PURE__ */ jsxRuntime.jsx("tr", { className: "oods-table__row", children: /* @__PURE__ */ jsxRuntime.jsx(TableCell, { colSpan: Math.max(columns?.length ?? 0, 1), children: "No rows available." }) }) : rows?.map((row) => /* @__PURE__ */ jsxRuntime.jsx(
1168
1001
  "tr",
1169
1002
  {
@@ -1215,7 +1048,7 @@ var partitionForOverflow = (items, visibleCount, selectedId) => {
1215
1048
  overflowItems: items.filter((item) => !visibleIds.has(item.id))
1216
1049
  };
1217
1050
  };
1218
- var Tabs = React7__namespace.forwardRef(
1051
+ var Tabs = React8__namespace.forwardRef(
1219
1052
  ({
1220
1053
  items,
1221
1054
  selectedId,
@@ -1229,22 +1062,22 @@ var Tabs = React7__namespace.forwardRef(
1229
1062
  "aria-label": ariaLabelAttribute,
1230
1063
  ...rest
1231
1064
  }, ref) => {
1232
- const instanceId = React7__namespace.useId().replaceAll(":", "");
1065
+ const instanceId = React8__namespace.useId().replaceAll(":", "");
1233
1066
  const controlled = selectedId !== void 0;
1234
1067
  const firstEnabled = items.find((item) => !item.disabled && !item.isDisabled)?.id ?? "";
1235
- const [internalSelectedId, setInternalSelectedId] = React7__namespace.useState(
1068
+ const [internalSelectedId, setInternalSelectedId] = React8__namespace.useState(
1236
1069
  defaultSelectedId ?? firstEnabled
1237
1070
  );
1238
1071
  const activeId = controlled ? selectedId : internalSelectedId;
1239
- const [focusedId, setFocusedId] = React7__namespace.useState(activeId);
1240
- const [visibleCount, setVisibleCount] = React7__namespace.useState(items.length);
1241
- const [menuOpen, setMenuOpen] = React7__namespace.useState(false);
1242
- const listRef = React7__namespace.useRef(null);
1243
- const tabRefs = React7__namespace.useRef(/* @__PURE__ */ new Map());
1244
- const itemWidths = React7__namespace.useRef(/* @__PURE__ */ new Map());
1245
- const focusRequestedByUser = React7__namespace.useRef(false);
1246
- React7__namespace.useEffect(() => setFocusedId(activeId), [activeId]);
1247
- const select = React7__namespace.useCallback(
1072
+ const [focusedId, setFocusedId] = React8__namespace.useState(activeId);
1073
+ const [visibleCount, setVisibleCount] = React8__namespace.useState(items.length);
1074
+ const [menuOpen, setMenuOpen] = React8__namespace.useState(false);
1075
+ const listRef = React8__namespace.useRef(null);
1076
+ const tabRefs = React8__namespace.useRef(/* @__PURE__ */ new Map());
1077
+ const itemWidths = React8__namespace.useRef(/* @__PURE__ */ new Map());
1078
+ const focusRequestedByUser = React8__namespace.useRef(false);
1079
+ React8__namespace.useEffect(() => setFocusedId(activeId), [activeId]);
1080
+ const select = React8__namespace.useCallback(
1248
1081
  (id) => {
1249
1082
  const item = items.find((candidate) => candidate.id === id);
1250
1083
  if (!item || item.disabled || item.isDisabled) return;
@@ -1256,7 +1089,7 @@ var Tabs = React7__namespace.forwardRef(
1256
1089
  },
1257
1090
  [controlled, items, onChange, onUpdate]
1258
1091
  );
1259
- const measure = React7__namespace.useCallback(() => {
1092
+ const measure = React8__namespace.useCallback(() => {
1260
1093
  const list = listRef.current;
1261
1094
  if (!list || items.length < 2) return;
1262
1095
  const available = list.offsetWidth;
@@ -1280,7 +1113,7 @@ var Tabs = React7__namespace.forwardRef(
1280
1113
  }
1281
1114
  setVisibleCount(Math.max(1, count));
1282
1115
  }, [items.length]);
1283
- React7__namespace.useLayoutEffect(() => {
1116
+ React8__namespace.useLayoutEffect(() => {
1284
1117
  measure();
1285
1118
  const list = listRef.current;
1286
1119
  if (!list || typeof ResizeObserver === "undefined") return void 0;
@@ -1308,7 +1141,7 @@ var Tabs = React7__namespace.forwardRef(
1308
1141
  if (!nextId) return;
1309
1142
  select(nextId);
1310
1143
  };
1311
- React7__namespace.useEffect(() => {
1144
+ React8__namespace.useEffect(() => {
1312
1145
  if (focusRequestedByUser.current && visibleItems.some((item) => item.id === focusedId)) {
1313
1146
  focusRequestedByUser.current = false;
1314
1147
  tabRefs.current.get(focusedId)?.focus();
@@ -1432,7 +1265,7 @@ var Tabs = React7__namespace.forwardRef(
1432
1265
  Tabs.displayName = "OODS.Tabs";
1433
1266
  var classes6 = (...values) => values.filter(Boolean).join(" ");
1434
1267
  var humanize = (value) => value.split(/[_-]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join(" ");
1435
- var StatusBadge = React7__namespace.forwardRef(
1268
+ var StatusBadge = React8__namespace.forwardRef(
1436
1269
  ({
1437
1270
  status,
1438
1271
  value,
@@ -1450,11 +1283,12 @@ var StatusBadge = React7__namespace.forwardRef(
1450
1283
  compact,
1451
1284
  variant,
1452
1285
  title,
1286
+ className,
1453
1287
  "aria-label": ariaLabel,
1454
1288
  ...rest
1455
1289
  }, ref) => {
1456
1290
  const resolvedStatus = status ?? value ?? "unknown";
1457
- const presentation = getStatusPresentation(domain, resolvedStatus);
1291
+ const presentation = componentContracts.getStatusPresentation(domain, resolvedStatus);
1458
1292
  return /* @__PURE__ */ jsxRuntime.jsx(
1459
1293
  Badge,
1460
1294
  {
@@ -1467,6 +1301,7 @@ var StatusBadge = React7__namespace.forwardRef(
1467
1301
  content: children ?? content,
1468
1302
  title: title ?? presentation.description,
1469
1303
  "aria-label": ariaLabel ?? label ?? `Status: ${presentation.label}`,
1304
+ className: classes6("oods-status-badge", className),
1470
1305
  "data-oods-component": "StatusBadge",
1471
1306
  ...rest
1472
1307
  }
@@ -1474,8 +1309,8 @@ var StatusBadge = React7__namespace.forwardRef(
1474
1309
  }
1475
1310
  );
1476
1311
  StatusBadge.displayName = "OODS.StatusBadge";
1477
- function formatPrice(amount, currency, fallback2) {
1478
- if (amount === void 0 || !Number.isFinite(amount)) return fallback2;
1312
+ function formatPrice(amount, currency, fallback) {
1313
+ if (amount === void 0 || !Number.isFinite(amount)) return fallback;
1479
1314
  if (!currency) return new Intl.NumberFormat(void 0, { maximumFractionDigits: 2 }).format(amount);
1480
1315
  try {
1481
1316
  return new Intl.NumberFormat(void 0, {
@@ -1486,7 +1321,7 @@ function formatPrice(amount, currency, fallback2) {
1486
1321
  return `${currency.toUpperCase()} ${amount.toFixed(2)}`;
1487
1322
  }
1488
1323
  }
1489
- var PriceBadge = React7__namespace.forwardRef(
1324
+ var PriceBadge = React8__namespace.forwardRef(
1490
1325
  ({
1491
1326
  amountCents,
1492
1327
  unitAmountCents,
@@ -1561,7 +1396,7 @@ function normalizeTimelineEvents(values) {
1561
1396
  }];
1562
1397
  });
1563
1398
  }
1564
- var TimelinePrimitive = React7__namespace.forwardRef(
1399
+ var TimelinePrimitive = React8__namespace.forwardRef(
1565
1400
  ({
1566
1401
  componentId,
1567
1402
  defaultTitle,
@@ -1605,29 +1440,29 @@ var TimelinePrimitive = React7__namespace.forwardRef(
1605
1440
  "data-timeline-type": kind,
1606
1441
  ...rest,
1607
1442
  children: [
1608
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "oods-timeline__title", children: title }),
1443
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "oods-timeline__title", "data-timeline-title": "true", children: title }),
1609
1444
  kind === "status" && status ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "oods-timeline__current", "data-timeline-current": "true", children: [
1610
1445
  "Current status: ",
1611
1446
  humanize(status)
1612
1447
  ] }) : null,
1613
- transitionCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
1448
+ transitionCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("p", { "data-timeline-transitions": "true", children: [
1614
1449
  "Allowed transitions: ",
1615
1450
  allowedTransitions?.join(", ")
1616
1451
  ] }) : null,
1617
- children ?? /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "oods-timeline__events", children: visibleEvents.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("li", { "data-timeline-empty": "true", children: "No events" }) : visibleEvents.map((event, index) => {
1452
+ children ?? /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "oods-timeline__events", "data-timeline-events": "true", children: visibleEvents.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("li", { "data-timeline-empty": "true", children: "No events" }) : visibleEvents.map((event, index) => {
1618
1453
  const timestamp = event.timestamp ?? event.datetime;
1619
1454
  const actor = event.actor ?? event.actorId ?? event.actor_id;
1620
1455
  const eventLabel = event.label ?? event.title ?? (event.from && event.to ? `${humanize(event.from)} \u2192 ${humanize(event.to)}` : void 0) ?? (event.status ? humanize(event.status) : void 0) ?? (event.state ? humanize(event.state) : void 0) ?? "Event";
1621
1456
  const detail = event.detail ?? event.description;
1622
1457
  return /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs("article", { className: "oods-timeline__event", "data-timeline-event": "true", children: [
1623
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oods-timeline__label", children: eventLabel }),
1624
- timestamp ? /* @__PURE__ */ jsxRuntime.jsx("time", { dateTime: timestamp, children: componentContracts.formatDateTime(timestamp) }) : null,
1625
- detail ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oods-timeline__detail", children: detail }) : null,
1626
- showActorId && actor ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "oods-timeline__actor", children: [
1458
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oods-timeline__label", "data-timeline-label": "true", children: eventLabel }),
1459
+ timestamp ? /* @__PURE__ */ jsxRuntime.jsx("time", { "data-timeline-time": "true", dateTime: timestamp, children: componentContracts.formatDateTime(timestamp) }) : null,
1460
+ detail ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oods-timeline__detail", "data-timeline-detail": "true", children: detail }) : null,
1461
+ showActorId && actor ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "oods-timeline__actor", "data-timeline-actor": "true", children: [
1627
1462
  "Actor: ",
1628
1463
  actor
1629
1464
  ] }) : null,
1630
- showReason && event.reason ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "oods-timeline__reason", children: [
1465
+ showReason && event.reason ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "oods-timeline__reason", "data-timeline-reason": "true", children: [
1631
1466
  "Reason: ",
1632
1467
  event.reason
1633
1468
  ] }) : null
@@ -1639,7 +1474,7 @@ var TimelinePrimitive = React7__namespace.forwardRef(
1639
1474
  }
1640
1475
  );
1641
1476
  TimelinePrimitive.displayName = "OODS.TimelinePrimitive";
1642
- var StatusTimeline = React7__namespace.forwardRef(
1477
+ var StatusTimeline = React8__namespace.forwardRef(
1643
1478
  (props, ref) => /* @__PURE__ */ jsxRuntime.jsx(
1644
1479
  TimelinePrimitive,
1645
1480
  {
@@ -1652,7 +1487,7 @@ var StatusTimeline = React7__namespace.forwardRef(
1652
1487
  )
1653
1488
  );
1654
1489
  StatusTimeline.displayName = "OODS.StatusTimeline";
1655
- var AuditTimeline = React7__namespace.forwardRef(
1490
+ var AuditTimeline = React8__namespace.forwardRef(
1656
1491
  ({ auditLog, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
1657
1492
  TimelinePrimitive,
1658
1493
  {
@@ -1666,7 +1501,7 @@ var AuditTimeline = React7__namespace.forwardRef(
1666
1501
  )
1667
1502
  );
1668
1503
  AuditTimeline.displayName = "OODS.AuditTimeline";
1669
- var CancellationSummary = React7__namespace.forwardRef(
1504
+ var CancellationSummary = React8__namespace.forwardRef(
1670
1505
  ({
1671
1506
  label,
1672
1507
  title = label ?? "Cancellation Summary",
@@ -1723,7 +1558,7 @@ var CancellationSummary = React7__namespace.forwardRef(
1723
1558
  }
1724
1559
  );
1725
1560
  CancellationSummary.displayName = "OODS.CancellationSummary";
1726
- var SearchInput = React7__namespace.forwardRef(
1561
+ var SearchInput = React8__namespace.forwardRef(
1727
1562
  ({
1728
1563
  id,
1729
1564
  label = "Search",
@@ -1749,13 +1584,13 @@ var SearchInput = React7__namespace.forwardRef(
1749
1584
  onKeyDown,
1750
1585
  ...rest
1751
1586
  }, ref) => {
1752
- const generatedId = React7__namespace.useId();
1587
+ const generatedId = React8__namespace.useId();
1753
1588
  const resolvedId = id ?? `oods-search-${generatedId.replace(/:/g, "")}`;
1754
- const [uncontrolledValue, setUncontrolledValue] = React7__namespace.useState(defaultValue);
1589
+ const [uncontrolledValue, setUncontrolledValue] = React8__namespace.useState(defaultValue);
1755
1590
  const currentValue = value ?? uncontrolledValue;
1756
- const timerRef = React7__namespace.useRef(void 0);
1591
+ const timerRef = React8__namespace.useRef(void 0);
1757
1592
  const delay = Math.max(0, debounceMs ?? debounce ?? 0);
1758
- React7__namespace.useEffect(() => () => {
1593
+ React8__namespace.useEffect(() => () => {
1759
1594
  if (timerRef.current !== void 0) clearTimeout(timerRef.current);
1760
1595
  }, []);
1761
1596
  const publish = (nextValue) => {
@@ -1818,7 +1653,7 @@ var SearchInput = React7__namespace.forwardRef(
1818
1653
  "aria-label": "Clear search",
1819
1654
  disabled,
1820
1655
  onClick: clear,
1821
- children: "\xD7"
1656
+ children: /* @__PURE__ */ jsxRuntime.jsx(StatusIcon, { name: "x" })
1822
1657
  }
1823
1658
  ) : null
1824
1659
  ]
@@ -1839,7 +1674,7 @@ function visiblePages(page, totalPages) {
1839
1674
  }
1840
1675
  return result;
1841
1676
  }
1842
- var PaginationBar = React7__namespace.forwardRef(
1677
+ var PaginationBar = React8__namespace.forwardRef(
1843
1678
  ({
1844
1679
  page = 1,
1845
1680
  pageSize = 25,
@@ -1980,7 +1815,7 @@ function relativeLabel(date, now) {
1980
1815
  unit
1981
1816
  );
1982
1817
  }
1983
- var RelativeTimestamp = React7__namespace.forwardRef(
1818
+ var RelativeTimestamp = React8__namespace.forwardRef(
1984
1819
  ({
1985
1820
  datetime,
1986
1821
  timestamp,
@@ -2006,7 +1841,7 @@ var RelativeTimestamp = React7__namespace.forwardRef(
2006
1841
  const date = asDate(raw);
2007
1842
  if (hideWhenEmpty && !date) return null;
2008
1843
  const nowDate = asDate(now) ?? /* @__PURE__ */ new Date();
2009
- const iso = date?.toISOString() ?? (raw === void 0 ? void 0 : String(raw));
1844
+ const iso = date?.toISOString() ?? (raw === void 0 || raw === "" ? void 0 : String(raw));
2010
1845
  const absolute = componentContracts.formatDateTime(date, { timeZone: timezone });
2011
1846
  const content = relative ?? label ?? text ?? (now !== void 0 && date ? relativeLabel(date, nowDate) : absolute || children || "Unknown time");
2012
1847
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -2028,8 +1863,8 @@ RelativeTimestamp.displayName = "OODS.RelativeTimestamp";
2028
1863
  var classes7 = (...values) => values.filter(Boolean).join(" ");
2029
1864
  var firstText = (...values) => values.find((value) => typeof value === "string" && value.trim().length > 0);
2030
1865
  function childContent(children) {
2031
- const flatten = (value) => React7__namespace.Children.toArray(value).flatMap((node) => {
2032
- if (React7__namespace.isValidElement(node) && node.type === React7__namespace.Fragment) {
1866
+ const flatten = (value) => React8__namespace.Children.toArray(value).flatMap((node) => {
1867
+ if (React8__namespace.isValidElement(node) && node.type === React8__namespace.Fragment) {
2033
1868
  return flatten(node.props.children);
2034
1869
  }
2035
1870
  return [node];
@@ -2041,16 +1876,16 @@ function childContent(children) {
2041
1876
  }
2042
1877
  return { authored: nodes.length > 0 };
2043
1878
  }
2044
- function headingElement(as, level, fallback2) {
1879
+ function headingElement(as, level, fallback) {
2045
1880
  if (as && /^h[1-6]$/.test(as)) return as;
2046
- const bounded = Number.isFinite(level) ? Math.max(1, Math.min(6, Math.trunc(level))) : fallback2;
1881
+ const bounded = Number.isFinite(level) ? Math.max(1, Math.min(6, Math.trunc(level))) : fallback;
2047
1882
  return `h${bounded}`;
2048
1883
  }
2049
1884
  function notEcho(supporting, heading) {
2050
1885
  if (!supporting || !heading) return supporting;
2051
1886
  return supporting.trim() === heading.trim() ? void 0 : supporting;
2052
1887
  }
2053
- var DetailHeader = React7__namespace.forwardRef(
1888
+ var DetailHeader = React8__namespace.forwardRef(
2054
1889
  ({ title, label, text, subtitle, sublabel, description, metadata, meta, level, as, children, className, ...rest }, ref) => {
2055
1890
  const Heading = headingElement(as, level, 2);
2056
1891
  const content = childContent(children);
@@ -2065,7 +1900,7 @@ var DetailHeader = React7__namespace.forwardRef(
2065
1900
  }
2066
1901
  );
2067
1902
  DetailHeader.displayName = "OODS.DetailHeader";
2068
- var CardHeader = React7__namespace.forwardRef(
1903
+ var CardHeader = React8__namespace.forwardRef(
2069
1904
  ({ title, label, text, supporting, supportingText, subtitle, description, level, as, children, className, ...rest }, ref) => {
2070
1905
  const Heading = headingElement(as, level, 2);
2071
1906
  const content = childContent(children);
@@ -2078,7 +1913,7 @@ var CardHeader = React7__namespace.forwardRef(
2078
1913
  }
2079
1914
  );
2080
1915
  CardHeader.displayName = "OODS.CardHeader";
2081
- var ColorSwatch = React7__namespace.forwardRef(
1916
+ var ColorSwatch = React8__namespace.forwardRef(
2082
1917
  ({ color, value, state, label, children, className, style, ...rest }, ref) => {
2083
1918
  const resolvedColor = firstText(color, value, state);
2084
1919
  const content = childContent(children);
@@ -2103,7 +1938,7 @@ var ColorSwatch = React7__namespace.forwardRef(
2103
1938
  }
2104
1939
  );
2105
1940
  ColorSwatch.displayName = "OODS.ColorSwatch";
2106
- var ColorizedBadge = React7__namespace.forwardRef(
1941
+ var ColorizedBadge = React8__namespace.forwardRef(
2107
1942
  ({ label, text, state, value, status, color, hue, swatch, variant, tone, emphasis, children, className, style, ...rest }, ref) => {
2108
1943
  const content = childContent(children);
2109
1944
  const resolvedLabel = content.scalar ?? firstText(label, text, state, value) ?? "Color";
@@ -2133,10 +1968,12 @@ var ColorizedBadge = React7__namespace.forwardRef(
2133
1968
  }
2134
1969
  );
2135
1970
  ColorizedBadge.displayName = "OODS.ColorizedBadge";
2136
- var VizAreaPreview = React7__namespace.forwardRef(
2137
- ({ width = 640, height = 360, svg, svgNarrow, svgWide, title, description, children, className, style, ...rest }, ref) => {
1971
+ var VizAreaPreview = React8__namespace.forwardRef(
1972
+ ({ width = 640, height = 360, svg, svgNarrow, svgWide, svgDark, svgDarkNarrow, svgDarkWide, svgHc, svgHcNarrow, svgHcWide, title, description, children, className, style, ...rest }, ref) => {
2138
1973
  const content = childContent(children);
2139
1974
  if (svg !== void 0) {
1975
+ const layers = componentContracts.vizPreviewLayers({ svg, svgNarrow, svgWide, svgDark, svgDarkNarrow, svgDarkWide, svgHc, svgHcNarrow, svgHcWide });
1976
+ const renders = (layer) => layer.renders.map(([attribute, markup]) => /* @__PURE__ */ jsxRuntime.jsx("div", { ...{ [attribute]: "true" }, dangerouslySetInnerHTML: { __html: markup } }, attribute));
2140
1977
  return /* @__PURE__ */ jsxRuntime.jsxs(
2141
1978
  "figure",
2142
1979
  {
@@ -2155,9 +1992,7 @@ var VizAreaPreview = React7__namespace.forwardRef(
2155
1992
  ...rest,
2156
1993
  children: [
2157
1994
  title && !componentContracts.svgCarriesTitle(svg, title) ? /* @__PURE__ */ jsxRuntime.jsx("figcaption", { children: title }) : null,
2158
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-viz-svg": "true", dangerouslySetInnerHTML: { __html: componentContracts.assertStaticSvg(svg) } }),
2159
- svgNarrow !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-viz-svg-narrow": "true", dangerouslySetInnerHTML: { __html: componentContracts.assertStaticSvg(svgNarrow) } }) : null,
2160
- svgWide !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-viz-svg-wide": "true", dangerouslySetInnerHTML: { __html: componentContracts.assertStaticSvg(svgWide) } }) : null,
1995
+ layers.map((layer) => layer.theme === void 0 ? renders(layer) : /* @__PURE__ */ jsxRuntime.jsx("div", { "data-viz-theme": layer.theme, "data-viz-narrow": layer.narrow ? "true" : void 0, "data-viz-wide": layer.wide ? "true" : void 0, children: renders(layer) }, layer.theme)),
2161
1996
  description ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-viz-description": "true", children: description }) : null
2162
1997
  ]
2163
1998
  }
@@ -2202,13 +2037,13 @@ var descriptorLabel = (descriptor) => firstText(
2202
2037
  typeof descriptor.field === "string" ? descriptor.field : void 0
2203
2038
  ) ?? "Filter";
2204
2039
  function createPanelSection(component, className, panelType, defaultTitle) {
2205
- const Panel = React7__namespace.forwardRef(
2040
+ const Panel = React8__namespace.forwardRef(
2206
2041
  ({ title, label, heading, name, subtitle, description, metadata, summary: summary2, text, body, emptyMessage, children, className: consumerClassName, ...rest }, ref) => {
2207
2042
  const content = childContent(children);
2208
2043
  const authored = content.authored || content.scalar !== void 0;
2209
2044
  const resolvedTitle = firstText(title, label, heading, name) ?? defaultTitle;
2210
2045
  const resolvedSubtitle = firstText(subtitle, description, metadata);
2211
- const fallback2 = firstText(summary2, text, body, emptyMessage);
2046
+ const fallback = firstText(summary2, text, body, emptyMessage);
2212
2047
  return /* @__PURE__ */ jsxRuntime.jsxs(
2213
2048
  "section",
2214
2049
  {
@@ -2222,7 +2057,7 @@ function createPanelSection(component, className, panelType, defaultTitle) {
2222
2057
  /* @__PURE__ */ jsxRuntime.jsx("h2", { children: resolvedTitle }),
2223
2058
  resolvedSubtitle ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-panel-subtitle": "true", children: resolvedSubtitle }) : null
2224
2059
  ] }),
2225
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-panel-content": "true", children: authored ? children : fallback2 ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-panel-summary": "true", children: fallback2 }) : null })
2060
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-panel-content": "true", children: authored ? children : fallback ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-panel-summary": "true", children: fallback }) : null })
2226
2061
  ]
2227
2062
  }
2228
2063
  );
@@ -2235,7 +2070,7 @@ var ClassificationPanel = createPanelSection("ClassificationPanel", "oods-classi
2235
2070
  var AddressCollectionPanel = createPanelSection("AddressCollectionPanel", "oods-address-collection-panel", "address", "Addresses");
2236
2071
  var MembershipPanel = createPanelSection("MembershipPanel", "oods-membership-panel", "membership", "Membership");
2237
2072
  var PreferencePanel = createPanelSection("PreferencePanel", "oods-preference-panel", "preference", "Preferences");
2238
- var FilterPanel = React7__namespace.forwardRef(
2073
+ var FilterPanel = React8__namespace.forwardRef(
2239
2074
  ({ filters, activeFilters, mode, collapsible = true, children, className, ...rest }, ref) => {
2240
2075
  const content = childContent(children);
2241
2076
  const authored = content.authored || content.scalar !== void 0;
@@ -2269,7 +2104,7 @@ var FilterPanel = React7__namespace.forwardRef(
2269
2104
  }
2270
2105
  );
2271
2106
  FilterPanel.displayName = "OODS.FilterPanel";
2272
- var PriceSummary = React7__namespace.forwardRef(
2107
+ var PriceSummary = React8__namespace.forwardRef(
2273
2108
  ({
2274
2109
  title,
2275
2110
  label,
@@ -2302,7 +2137,7 @@ var PriceSummary = React7__namespace.forwardRef(
2302
2137
  ["Interval", componentContracts.formatPriceCode(interval ?? billingInterval)]
2303
2138
  ];
2304
2139
  const terms = entries.filter((entry) => entry[1] !== void 0);
2305
- const fallback2 = firstText(summary2, text, description);
2140
+ const fallback = firstText(summary2, text, description);
2306
2141
  return /* @__PURE__ */ jsxRuntime.jsxs(
2307
2142
  "section",
2308
2143
  {
@@ -2316,7 +2151,7 @@ var PriceSummary = React7__namespace.forwardRef(
2316
2151
  authored ? children : terms.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("dl", { children: terms.map(([term, value]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-summary-item": "true", children: [
2317
2152
  /* @__PURE__ */ jsxRuntime.jsx("dt", { children: term }),
2318
2153
  /* @__PURE__ */ jsxRuntime.jsx("dd", { children: value })
2319
- ] }, term)) }) : fallback2 ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-summary-fallback": "true", children: fallback2 }) : /* @__PURE__ */ jsxRuntime.jsx("dl", {})
2154
+ ] }, term)) }) : fallback ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-summary-fallback": "true", children: fallback }) : /* @__PURE__ */ jsxRuntime.jsx("dl", {})
2320
2155
  ]
2321
2156
  }
2322
2157
  );
@@ -2342,7 +2177,7 @@ var normalizeTagItems = (value) => {
2342
2177
  }
2343
2178
  return items.filter((item) => item.length > 0);
2344
2179
  };
2345
- var TagManager = React7__namespace.forwardRef(
2180
+ var TagManager = React8__namespace.forwardRef(
2346
2181
  ({ title, label, heading, name, description, subtitle, hint, tags, value, children, className, onSubmit, ...rest }, ref) => {
2347
2182
  const content = childContent(children);
2348
2183
  const authored = content.authored || content.scalar !== void 0;
@@ -2389,7 +2224,7 @@ var asCount = (value) => {
2389
2224
  };
2390
2225
  function createBadgeFamily(options) {
2391
2226
  const consumed = /* @__PURE__ */ new Set([...options.labelKeys, ...options.statusKeys, "variant", "tone", "emphasis"]);
2392
- const Family = React7__namespace.forwardRef((allProps, ref) => {
2227
+ const Family = React8__namespace.forwardRef((allProps, ref) => {
2393
2228
  const { children, className, ...rest } = allProps;
2394
2229
  const record = rest;
2395
2230
  const scalar = (key) => {
@@ -2449,7 +2284,7 @@ var PreferenceSummaryBadge = createBadgeFamily({
2449
2284
  labelKeys: ["label", "text", "namespace", "value"],
2450
2285
  statusKeys: ["status", "state", "version"]
2451
2286
  });
2452
- var RoleBadgeList = React7__namespace.forwardRef(
2287
+ var RoleBadgeList = React8__namespace.forwardRef(
2453
2288
  ({ roles, badges, roleLabels, value, variant, tone, label, text, children, className, ...rest }, ref) => {
2454
2289
  const content = childContent(children);
2455
2290
  const authored = content.authored || content.scalar !== void 0;
@@ -2469,7 +2304,7 @@ var RoleBadgeList = React7__namespace.forwardRef(
2469
2304
  }
2470
2305
  );
2471
2306
  RoleBadgeList.displayName = "OODS.RoleBadgeList";
2472
- var TagPills = React7__namespace.forwardRef(
2307
+ var TagPills = React8__namespace.forwardRef(
2473
2308
  ({ tags, value, maxVisible, overflowLabel, children, className, ...rest }, ref) => {
2474
2309
  const content = childContent(children);
2475
2310
  const authored = content.authored || content.scalar !== void 0;
@@ -2521,7 +2356,7 @@ var normalizeTimelineItems = (raw) => {
2521
2356
  };
2522
2357
  function createTimelineFamily(options) {
2523
2358
  const consumed = /* @__PURE__ */ new Set(["title", "label", "heading", "name", ...options.eventKeys]);
2524
- const Family = React7__namespace.forwardRef((allProps, ref) => {
2359
+ const Family = React8__namespace.forwardRef((allProps, ref) => {
2525
2360
  const { children, className, ...rest } = allProps;
2526
2361
  const record = rest;
2527
2362
  const text = (key) => {
@@ -2586,7 +2421,7 @@ var PreferenceTimeline = createTimelineFamily({
2586
2421
  timelineType: "preference",
2587
2422
  eventKeys: ["events", "changes", "history"]
2588
2423
  });
2589
- var AuditEvent = React7__namespace.forwardRef(
2424
+ var AuditEvent = React8__namespace.forwardRef(
2590
2425
  ({
2591
2426
  label,
2592
2427
  title,
@@ -2672,7 +2507,7 @@ var addressRecord = (form) => {
2672
2507
  };
2673
2508
  return { street: read("street"), city: read("city"), region: read("region"), postalCode: read("postalCode") };
2674
2509
  };
2675
- var AddressEditor = React7__namespace.forwardRef(
2510
+ var AddressEditor = React8__namespace.forwardRef(
2676
2511
  ({
2677
2512
  title,
2678
2513
  label,
@@ -2730,7 +2565,7 @@ var AddressEditor = React7__namespace.forwardRef(
2730
2565
  }
2731
2566
  );
2732
2567
  AddressEditor.displayName = "OODS.AddressEditor";
2733
- var PreferenceEditor = React7__namespace.forwardRef(
2568
+ var PreferenceEditor = React8__namespace.forwardRef(
2734
2569
  ({ title, label, heading, name, description, subtitle, hint, namespaces, namespace, document, json, value, children, className, onSubmit, ...rest }, ref) => {
2735
2570
  const content = childContent(children);
2736
2571
  const authored = content.authored || content.scalar !== void 0;
@@ -2767,7 +2602,7 @@ var PreferenceEditor = React7__namespace.forwardRef(
2767
2602
  }
2768
2603
  );
2769
2604
  PreferenceEditor.displayName = "OODS.PreferenceEditor";
2770
- var RoleAssignmentForm = React7__namespace.forwardRef(
2605
+ var RoleAssignmentForm = React8__namespace.forwardRef(
2771
2606
  ({ title, label, heading, name, description, subtitle, hint, roles, availableRoles, role, defaultRoleId, assignee, member, children, className, onSubmit, ...rest }, ref) => {
2772
2607
  const content = childContent(children);
2773
2608
  const authored = content.authored || content.scalar !== void 0;
@@ -2804,7 +2639,7 @@ var RoleAssignmentForm = React7__namespace.forwardRef(
2804
2639
  }
2805
2640
  );
2806
2641
  RoleAssignmentForm.displayName = "OODS.RoleAssignmentForm";
2807
- var StatusSelector = React7__namespace.forwardRef(
2642
+ var StatusSelector = React8__namespace.forwardRef(
2808
2643
  ({ label, title, help, options, states, value, status, children, className, onChange, onValueChange, onUpdate, ...rest }, ref) => {
2809
2644
  const content = childContent(children);
2810
2645
  const authored = content.authored || content.scalar !== void 0;
@@ -2846,7 +2681,7 @@ var StatusSelector = React7__namespace.forwardRef(
2846
2681
  }
2847
2682
  );
2848
2683
  StatusSelector.displayName = "OODS.StatusSelector";
2849
- var TagInput = React7__namespace.forwardRef(
2684
+ var TagInput = React8__namespace.forwardRef(
2850
2685
  ({ title, label, heading, name, description, subtitle, hint, tags, value, placeholder, children, className, onChange, onValueChange, onUpdate, ...rest }, ref) => {
2851
2686
  const content = childContent(children);
2852
2687
  const authored = content.authored || content.scalar !== void 0;
@@ -2893,7 +2728,7 @@ var TagInput = React7__namespace.forwardRef(
2893
2728
  }
2894
2729
  );
2895
2730
  TagInput.displayName = "OODS.TagInput";
2896
- var TemplatePicker = React7__namespace.forwardRef(
2731
+ var TemplatePicker = React8__namespace.forwardRef(
2897
2732
  ({ title, label, heading, name, description, subtitle, hint, templates, options, templateId, value, channels, channel, children, className, ...rest }, ref) => {
2898
2733
  const content = childContent(children);
2899
2734
  const authored = content.authored || content.scalar !== void 0;
@@ -2931,14 +2766,14 @@ var truncateLabel = (value, maxLength) => {
2931
2766
  const limit = typeof maxLength === "number" ? maxLength : Number(maxLength);
2932
2767
  return !Number.isFinite(limit) || limit <= 0 || value.length <= limit ? value : `${value.slice(0, Math.max(0, limit - 1)).trimEnd()}...`;
2933
2768
  };
2934
- var InlineLabel = React7__namespace.forwardRef(
2769
+ var InlineLabel = React8__namespace.forwardRef(
2935
2770
  ({ label, text, value, maxLength, children, className, ...rest }, ref) => {
2936
2771
  const content = childContent(children);
2937
2772
  return /* @__PURE__ */ jsxRuntime.jsx("span", { ref, className: classes7("oods-inline-label", className), "data-oods-component": "InlineLabel", ...rest, children: content.authored || content.scalar !== void 0 ? children : truncateLabel(firstText(label, text, value) ?? "", maxLength) });
2938
2773
  }
2939
2774
  );
2940
2775
  InlineLabel.displayName = "OODS.InlineLabel";
2941
- var LabelCell = React7__namespace.forwardRef(
2776
+ var LabelCell = React8__namespace.forwardRef(
2942
2777
  ({ label, text, value, description, subtitle, sublabel, supporting, truncate, maxLength, children, className, ...rest }, ref) => {
2943
2778
  const content = childContent(children);
2944
2779
  const limit = truncate ? maxLength ?? 40 : maxLength;
@@ -2951,7 +2786,7 @@ var LabelCell = React7__namespace.forwardRef(
2951
2786
  }
2952
2787
  );
2953
2788
  LabelCell.displayName = "OODS.LabelCell";
2954
- var FormLabelGroup = React7__namespace.forwardRef(
2789
+ var FormLabelGroup = React8__namespace.forwardRef(
2955
2790
  ({ label, text, title, placeholder, hint, description, htmlFor, for: forId, inputId, children, className, ...rest }, ref) => {
2956
2791
  const detail = firstText(placeholder, hint, description);
2957
2792
  return /* @__PURE__ */ jsxRuntime.jsxs("label", { ref, className: classes7("oods-form-label-group", className), "data-oods-component": "FormLabelGroup", htmlFor: htmlFor ?? forId ?? inputId, ...rest, children: [
@@ -2970,7 +2805,7 @@ var ClassificationBadge = createBadgeFamily({
2970
2805
  labelKeys: ["label", "text", "category", "value"],
2971
2806
  statusKeys: ["status", "state", "mode"]
2972
2807
  });
2973
- var ClassificationEditor = React7__namespace.forwardRef(
2808
+ var ClassificationEditor = React8__namespace.forwardRef(
2974
2809
  ({ title, label, heading, name, description, subtitle, hint, category, primaryCategory, tags, modes, mode, classificationMode, children, className, onSubmit, ...rest }, ref) => {
2975
2810
  const content = childContent(children);
2976
2811
  const tagText = typeof tags === "string" ? tags : tags === void 0 ? "" : JSON.stringify(tags);
@@ -3016,38 +2851,38 @@ var OwnerBadge = createBadgeFamily({
3016
2851
  labelKeys: ["label", "text", "owner", "ownerType", "value"],
3017
2852
  statusKeys: ["status", "state"]
3018
2853
  });
3019
- var OwnershipSummary = React7__namespace.forwardRef(
2854
+ var OwnershipSummary = React8__namespace.forwardRef(
3020
2855
  ({ title, label, heading, name, ownerLabel, ownerId, owner_id, ownerType, owner_type, role, ownershipRole, summary: summary2, text, description, children, className, ...rest }, ref) => {
3021
2856
  const content = childContent(children);
3022
2857
  const terms = [["Owner", ownerId === void 0 && owner_id === void 0 && ownerLabel === void 0 ? void 0 : componentContracts.formatReferenceLabel(ownerId ?? owner_id, ownerLabel, "Owner")], ["Owner Type", firstScalar(ownerType, owner_type)], ["Role", firstScalar(role, ownershipRole)]].filter((entry) => entry[1] !== void 0);
3023
- const fallback2 = firstText(summary2, text, description);
2858
+ const fallback = firstText(summary2, text, description);
3024
2859
  return /* @__PURE__ */ jsxRuntime.jsxs("section", { ref, className: classes7("oods-ownership-summary", className), "data-oods-component": "OwnershipSummary", "data-summary-type": "ownership", ...rest, children: [
3025
2860
  /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-summary-title": "true", children: firstText(title, label, heading, name) ?? "Ownership Summary" }),
3026
2861
  content.authored || content.scalar !== void 0 ? children : terms.length ? /* @__PURE__ */ jsxRuntime.jsx("dl", { children: terms.map(([term, value]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-summary-item": "true", children: [
3027
2862
  /* @__PURE__ */ jsxRuntime.jsx("dt", { children: term }),
3028
2863
  /* @__PURE__ */ jsxRuntime.jsx("dd", { children: value })
3029
- ] }, term)) }) : fallback2 ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-summary-fallback": "true", children: fallback2 }) : /* @__PURE__ */ jsxRuntime.jsx("dl", {})
2864
+ ] }, term)) }) : fallback ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-summary-fallback": "true", children: fallback }) : /* @__PURE__ */ jsxRuntime.jsx("dl", {})
3030
2865
  ] });
3031
2866
  }
3032
2867
  );
3033
2868
  OwnershipSummary.displayName = "OODS.OwnershipSummary";
3034
- var TagSummary = React7__namespace.forwardRef(
2869
+ var TagSummary = React8__namespace.forwardRef(
3035
2870
  ({ title, label, heading, name, tagCount, count, tags, summary: summary2, text, description, children, className, ...rest }, ref) => {
3036
2871
  const content = childContent(children);
3037
2872
  const tagText = Array.isArray(tags) ? normalizeTagItems(tags).join(", ") || void 0 : firstText(tags);
3038
2873
  const terms = [["Tag Count", firstScalar(tagCount, count)], ["Tags", tagText]].filter((entry) => entry[1] !== void 0);
3039
- const fallback2 = firstText(summary2, text, description);
2874
+ const fallback = firstText(summary2, text, description);
3040
2875
  return /* @__PURE__ */ jsxRuntime.jsxs("section", { ref, className: classes7("oods-tags-summary", className), "data-oods-component": "TagSummary", "data-summary-type": "tags", ...rest, children: [
3041
2876
  /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-summary-title": "true", children: firstText(title, label, heading, name) ?? "Tag Summary" }),
3042
2877
  content.authored || content.scalar !== void 0 ? children : terms.length ? /* @__PURE__ */ jsxRuntime.jsx("dl", { children: terms.map(([term, value]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-summary-item": "true", children: [
3043
2878
  /* @__PURE__ */ jsxRuntime.jsx("dt", { children: term }),
3044
2879
  /* @__PURE__ */ jsxRuntime.jsx("dd", { children: value })
3045
- ] }, term)) }) : fallback2 ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-summary-fallback": "true", children: fallback2 }) : /* @__PURE__ */ jsxRuntime.jsx("dl", {})
2880
+ ] }, term)) }) : fallback ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-summary-fallback": "true", children: fallback }) : /* @__PURE__ */ jsxRuntime.jsx("dl", {})
3046
2881
  ] });
3047
2882
  }
3048
2883
  );
3049
2884
  TagSummary.displayName = "OODS.TagSummary";
3050
- var OwnershipMeta = React7__namespace.forwardRef(
2885
+ var OwnershipMeta = React8__namespace.forwardRef(
3051
2886
  ({ title, label, heading, name, ownerType, owner_type, role, ownershipRole, children, className, ...rest }, ref) => {
3052
2887
  const content = childContent(children);
3053
2888
  const terms = [["Owner Type", firstScalar(ownerType, owner_type)], ["Role", firstScalar(role, ownershipRole)]].filter((entry) => entry[1] !== void 0);
@@ -3085,22 +2920,22 @@ var CancellationBadge = createBadgeFamily({
3085
2920
  booleanProps: ["cancelAtPeriodEnd", "isCancelled", "value"],
3086
2921
  booleanLabels: ["Cancellation scheduled", "No cancellation scheduled"]
3087
2922
  });
3088
- var ArchiveSummary = React7__namespace.forwardRef(
2923
+ var ArchiveSummary = React8__namespace.forwardRef(
3089
2924
  ({ title, label, heading, name, isArchived, archived, status, archivedAt, reason, archiveReason, summary: summary2, text, description, children, className, ...rest }, ref) => {
3090
2925
  const content = childContent(children);
3091
2926
  const terms = [["Archived", componentContracts.summaryValue(isArchived ?? archived ?? status)], ["Archived At", archivedAt ? componentContracts.formatDateTime(archivedAt) : void 0], ["Reason", firstText(reason, archiveReason)]].filter((entry) => entry[1] !== void 0);
3092
- const fallback2 = firstText(summary2, text, description);
2927
+ const fallback = firstText(summary2, text, description);
3093
2928
  return /* @__PURE__ */ jsxRuntime.jsxs("section", { ref, className: classes7("oods-archive-summary", className), "data-oods-component": "ArchiveSummary", "data-summary-type": "archive", ...rest, children: [
3094
2929
  /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-summary-title": "true", children: firstText(title, label, heading, name) ?? "Archive Summary" }),
3095
2930
  content.authored || content.scalar !== void 0 ? children : terms.length ? /* @__PURE__ */ jsxRuntime.jsx("dl", { children: terms.map(([term, value]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-summary-item": "true", children: [
3096
2931
  /* @__PURE__ */ jsxRuntime.jsx("dt", { children: term }),
3097
2932
  /* @__PURE__ */ jsxRuntime.jsx("dd", { children: value })
3098
- ] }, term)) }) : fallback2 ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-summary-fallback": "true", children: fallback2 }) : /* @__PURE__ */ jsxRuntime.jsx("dl", {})
2933
+ ] }, term)) }) : fallback ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-summary-fallback": "true", children: fallback }) : /* @__PURE__ */ jsxRuntime.jsx("dl", {})
3099
2934
  ] });
3100
2935
  }
3101
2936
  );
3102
2937
  ArchiveSummary.displayName = "OODS.ArchiveSummary";
3103
- var PriceCardMeta = React7__namespace.forwardRef(
2938
+ var PriceCardMeta = React8__namespace.forwardRef(
3104
2939
  ({ title, label, heading, name, model, pricingModel, interval, billingInterval, children, className, ...rest }, ref) => {
3105
2940
  const content = childContent(children);
3106
2941
  const terms = [["Model", componentContracts.formatPriceCode(firstText(model, pricingModel))], ["Interval", componentContracts.formatPriceCode(firstText(interval, billingInterval))]].filter((entry) => entry[1] !== void 0);
@@ -3118,12 +2953,12 @@ var PriceCardMeta = React7__namespace.forwardRef(
3118
2953
  }
3119
2954
  );
3120
2955
  PriceCardMeta.displayName = "OODS.PriceCardMeta";
3121
- var CancellationForm = React7__namespace.forwardRef(
2956
+ var CancellationForm = React8__namespace.forwardRef(
3122
2957
  ({ title, label, heading, name, description, subtitle, hint, allowedReasons, reasonCode, reason, cancellationReason, embedded, reasonHelp, codeHelp, children, className, onSubmit, ...rest }, ref) => {
3123
2958
  const content = childContent(children);
3124
2959
  const choices = normalizeSelectOptions(allowedReasons ?? ["no_longer_needed", "budget", "duplicate"]);
3125
2960
  if (reasonCode && !choices.some((choice) => choice.value === reasonCode)) choices.unshift({ value: reasonCode, label: reasonCode });
3126
- return React7__namespace.createElement(embedded ? "fieldset" : "form", {
2961
+ return React8__namespace.createElement(embedded ? "fieldset" : "form", {
3127
2962
  ...rest,
3128
2963
  ref,
3129
2964
  className: classes7("oods-cancellation-form", className),
@@ -3155,11 +2990,11 @@ function BillingSummaryBadge({ id, amount, currency, minorUnits, interval, showI
3155
2990
  return /* @__PURE__ */ jsxRuntime.jsx("span", { id, className: `oods-billing-summary ${className ?? ""}`.trim(), "data-oods-component": "BillingSummaryBadge", children: showInterval ? componentContracts.billingSummary(amount, currency, minorUnits, interval) : componentContracts.formatBillingAmount(amount, currency, minorUnits) });
3156
2991
  }
3157
2992
  function BillingAmountInput({ id, amount, currency = "usd", minorUnits = componentContracts.BILLING_MINOR_UNITS, label = "Billing amount", name, disabled, className, help, onChange }) {
3158
- const generatedId = React7__namespace.useId();
2993
+ const generatedId = React8__namespace.useId();
3159
2994
  const controlId = id ?? `billing-amount-${generatedId}`;
3160
- const [text, setText] = React7__namespace.useState(() => componentContracts.billingAmountText(amount, minorUnits));
3161
- const [error, setError] = React7__namespace.useState(() => componentContracts.billingAmountMessage(amount, minorUnits));
3162
- React7__namespace.useEffect(() => {
2995
+ const [text, setText] = React8__namespace.useState(() => componentContracts.billingAmountText(amount, minorUnits));
2996
+ const [error, setError] = React8__namespace.useState(() => componentContracts.billingAmountMessage(amount, minorUnits));
2997
+ React8__namespace.useEffect(() => {
3163
2998
  setText(componentContracts.billingAmountText(amount, minorUnits));
3164
2999
  setError(componentContracts.billingAmountMessage(amount, minorUnits));
3165
3000
  }, [amount, minorUnits]);
@@ -3193,10 +3028,10 @@ function BillingAmountInput({ id, amount, currency = "usd", minorUnits = compone
3193
3028
  ] });
3194
3029
  }
3195
3030
  function BillingIntervalSelector({ id, interval, intervals = componentContracts.BILLING_INTERVALS, label = "Billing interval", name, disabled, className, help, onChange }) {
3196
- const generatedId = React7__namespace.useId();
3031
+ const generatedId = React8__namespace.useId();
3197
3032
  const controlId = id ?? `billing-interval-${generatedId}`;
3198
- const [value, setValue] = React7__namespace.useState(interval ?? "");
3199
- React7__namespace.useEffect(() => {
3033
+ const [value, setValue] = React8__namespace.useState(interval ?? "");
3034
+ React8__namespace.useEffect(() => {
3200
3035
  setValue(interval ?? "");
3201
3036
  }, [interval]);
3202
3037
  const error = componentContracts.billingIntervalMessage(value || void 0, intervals);
@@ -3304,8 +3139,8 @@ function AuditSummaryCard({ id, title = "Audit summary", showTransitionCount = t
3304
3139
  ] });
3305
3140
  }
3306
3141
  function SortIndicator({ id, label = "Sort", onChange, "data-oods-action": action, ...values }) {
3307
- const [state, setState] = React7__namespace.useState(() => componentContracts.initialSort(values));
3308
- React7__namespace.useEffect(() => setState(componentContracts.initialSort(values)), [values.sortField, values.sortDirection, values.sortActive, values.defaultSortField, values.defaultSortDirection]);
3142
+ const [state, setState] = React8__namespace.useState(() => componentContracts.initialSort(values));
3143
+ React8__namespace.useEffect(() => setState(componentContracts.initialSort(values)), [values.sortField, values.sortDirection, values.sortActive, values.defaultSortField, values.defaultSortDirection]);
3309
3144
  const sort = componentContracts.ariaSort(state);
3310
3145
  return /* @__PURE__ */ jsxRuntime.jsx("table", { id, className: "oods-sort-indicator", "data-oods-component": "SortIndicator", "aria-label": label, children: /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", "aria-sort": sort, children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", "data-oods-action": action, "aria-label": `${label} ${state.field}`, onClick: () => {
3311
3146
  const next = componentContracts.nextSort(state, values.triStateSort);
@@ -3313,7 +3148,7 @@ function SortIndicator({ id, label = "Sort", onChange, "data-oods-action": actio
3313
3148
  onChange?.(next);
3314
3149
  }, children: `${state.field}: ${sort}` }) }) }) }) });
3315
3150
  }
3316
- var TimelineEntryLabel = React7__namespace.forwardRef(({ compact = true, maxLength, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(InlineLabel, { ...props, ref, maxLength: maxLength ?? (compact ? 40 : void 0), "data-oods-component": "TimelineEntryLabel", "data-timeline-label": "true", "data-compact": compact }));
3151
+ var TimelineEntryLabel = React8__namespace.forwardRef(({ compact = true, maxLength, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(InlineLabel, { ...props, ref, maxLength: maxLength ?? (compact ? 40 : void 0), "data-oods-component": "TimelineEntryLabel", "data-timeline-label": "true", "data-compact": compact }));
3317
3152
  TimelineEntryLabel.displayName = "OODS.TimelineEntryLabel";
3318
3153
  function eventRecipe(id, kind, title) {
3319
3154
  return function TraitEvent({ id: elementId, title: heading = title, ...values }) {
@@ -3356,9 +3191,9 @@ function CommunicationDetailPanel({ id, title = "Communication", channels = [],
3356
3191
  ] });
3357
3192
  }
3358
3193
  function ColorStatePicker({ id, title = "Color state", colorStates = componentContracts.DEFAULT_COLOR_STATES, value, disabled, onChange }) {
3359
- const generatedId = React7__namespace.useId();
3360
- const [selected, setSelected] = React7__namespace.useState(value ?? colorStates[0] ?? "");
3361
- React7__namespace.useEffect(() => setSelected(value ?? colorStates[0] ?? ""), [value, colorStates]);
3194
+ const generatedId = React8__namespace.useId();
3195
+ const [selected, setSelected] = React8__namespace.useState(value ?? colorStates[0] ?? "");
3196
+ React8__namespace.useEffect(() => setSelected(value ?? colorStates[0] ?? ""), [value, colorStates]);
3362
3197
  return /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { id, className: "oods-trait-recipe", "data-oods-component": "ColorStatePicker", children: [
3363
3198
  /* @__PURE__ */ jsxRuntime.jsx("legend", { children: title }),
3364
3199
  /* @__PURE__ */ jsxRuntime.jsx(Select, { id: `${id ?? generatedId}-state`, label: "Color state", name: "color_state", value: selected, disabled, options: [...!colorStates.includes(selected) ? [{ value: selected, label: selected || "Choose state", disabled: true }] : [], ...colorStates.map((value2) => ({ value: value2, label: componentContracts.formatReadOnlyValue(value2, "string", true) }))], onValueChange: (next) => {
@@ -3380,9 +3215,9 @@ function StatusColorLegend({ id, title = "Status colors", colorStates = componen
3380
3215
  ] });
3381
3216
  }
3382
3217
  function GeoFieldMappingForm({ id, title = "Geographic fields", embedded = false, disabled, onChange, ...values }) {
3383
- const generatedId = React7__namespace.useId();
3384
- const [value, setValue] = React7__namespace.useState(() => componentContracts.geoFieldMapping(values));
3385
- React7__namespace.useEffect(() => setValue(componentContracts.geoFieldMapping(values)), [values.latitude, values.longitude, values.identifier, values.autoDetect]);
3218
+ const generatedId = React8__namespace.useId();
3219
+ const [value, setValue] = React8__namespace.useState(() => componentContracts.geoFieldMapping(values));
3220
+ React8__namespace.useEffect(() => setValue(componentContracts.geoFieldMapping(values)), [values.latitude, values.longitude, values.identifier, values.autoDetect]);
3386
3221
  const update = (patch) => {
3387
3222
  const next = { ...value, ...patch };
3388
3223
  setValue(next);
@@ -3416,11 +3251,11 @@ function GeocodablePreview({ id, title = "Geographic data", resolution, requires
3416
3251
  }
3417
3252
  function controls(id) {
3418
3253
  const Component = ({ id: htmlId, title = componentContracts.VIZ_CONTROL_TITLES[id], value, channel = "x", disabled, onChange }) => {
3419
- const generatedId = React7__namespace.useId();
3420
- const [current, setCurrent] = React7__namespace.useState(value ?? {});
3421
- const [drafts, setDrafts] = React7__namespace.useState({});
3422
- const [errors, setErrors] = React7__namespace.useState({});
3423
- React7__namespace.useEffect(() => {
3254
+ const generatedId = React8__namespace.useId();
3255
+ const [current, setCurrent] = React8__namespace.useState(value ?? {});
3256
+ const [drafts, setDrafts] = React8__namespace.useState({});
3257
+ const [errors, setErrors] = React8__namespace.useState({});
3258
+ React8__namespace.useEffect(() => {
3424
3259
  setCurrent(value ?? {});
3425
3260
  setDrafts({});
3426
3261
  setErrors({});
@@ -3530,6 +3365,7 @@ exports.CommunicationDetailPanel = CommunicationDetailPanel;
3530
3365
  exports.CycleProgressCard = CycleProgressCard;
3531
3366
  exports.DatePicker = DatePicker;
3532
3367
  exports.DetailHeader = DetailHeader;
3368
+ exports.Dialog = Dialog;
3533
3369
  exports.FilterPanel = FilterPanel;
3534
3370
  exports.FormLabelGroup = FormLabelGroup;
3535
3371
  exports.GeoFieldMappingForm = GeoFieldMappingForm;
@@ -3568,6 +3404,7 @@ exports.StatusBadge = StatusBadge;
3568
3404
  exports.StatusColorLegend = StatusColorLegend;
3569
3405
  exports.StatusSelector = StatusSelector;
3570
3406
  exports.StatusTimeline = StatusTimeline;
3407
+ exports.Switch = Switch;
3571
3408
  exports.Table = Table;
3572
3409
  exports.Tabs = Tabs;
3573
3410
  exports.TagInput = TagInput;