@oods/components-react 0.3.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 ADDED
@@ -0,0 +1,3605 @@
1
+ 'use strict';
2
+
3
+ var React7 = require('react');
4
+ var reactSlot = require('@radix-ui/react-slot');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var componentContracts = require('@oods/component-contracts');
7
+
8
+ function _interopNamespace(e) {
9
+ if (e && e.__esModule) return e;
10
+ var n = Object.create(null);
11
+ if (e) {
12
+ Object.keys(e).forEach(function (k) {
13
+ if (k !== 'default') {
14
+ var d = Object.getOwnPropertyDescriptor(e, k);
15
+ Object.defineProperty(n, k, d.get ? d : {
16
+ enumerable: true,
17
+ get: function () { return e[k]; }
18
+ });
19
+ }
20
+ });
21
+ }
22
+ n.default = e;
23
+ return Object.freeze(n);
24
+ }
25
+
26
+ var React7__namespace = /*#__PURE__*/_interopNamespace(React7);
27
+
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"
252
+ };
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;
359
+ }
360
+ var classes = (...values) => values.filter(Boolean).join(" ");
361
+ var Badge = React7__namespace.forwardRef(
362
+ ({
363
+ content,
364
+ status,
365
+ domain = "subscription",
366
+ tone: toneOverride,
367
+ emphasis = "subtle",
368
+ icon,
369
+ iconPosition = "start",
370
+ showIcon,
371
+ children,
372
+ className,
373
+ style,
374
+ title,
375
+ "aria-label": ariaLabel,
376
+ ...rest
377
+ }, ref) => {
378
+ const presentation = status ? getStatusPresentation(domain, status) : void 0;
379
+ 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);
381
+ const resolvedContent = children ?? content ?? presentation?.label ?? status;
382
+ const resolvedIcon = icon ?? resolveStatusGlyph(presentation?.iconName);
383
+ 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;
385
+ return /* @__PURE__ */ jsxRuntime.jsxs(
386
+ "span",
387
+ {
388
+ ref,
389
+ className: classes("oods-badge", "statusable-badge", className),
390
+ "data-oods-component": "Badge",
391
+ "data-status": status,
392
+ "data-domain": domain,
393
+ "data-tone": tone,
394
+ "data-emphasis": emphasis,
395
+ title: title ?? presentation?.description,
396
+ "aria-label": ariaLabel,
397
+ style: {
398
+ "--cmp-badge-background": tokenSet.background,
399
+ "--cmp-badge-border": tokenSet.border,
400
+ "--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
+ ...style
406
+ },
407
+ ...rest,
408
+ children: [
409
+ iconPosition === "start" ? iconNode : null,
410
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oods-badge__label statusable-badge__label", children: resolvedContent }),
411
+ iconPosition === "end" ? iconNode : null
412
+ ]
413
+ }
414
+ );
415
+ }
416
+ );
417
+ Badge.displayName = "OODS.Badge";
418
+ var Banner = React7__namespace.forwardRef(
419
+ ({
420
+ title,
421
+ detail,
422
+ description,
423
+ content,
424
+ status,
425
+ domain = "subscription",
426
+ tone: toneOverride,
427
+ emphasis = "subtle",
428
+ icon,
429
+ actions,
430
+ onDismiss,
431
+ dismissLabel = "Dismiss notification",
432
+ showIcon,
433
+ children,
434
+ className,
435
+ style,
436
+ ...rest
437
+ }, ref) => {
438
+ const presentation = status ? getStatusPresentation(domain, status) : void 0;
439
+ const tone = toneOverride ?? presentation?.tone ?? "neutral";
440
+ const tokenSet = emphasis === "solid" ? presentation?.banner.solid ?? getToneTokenSet(tone) : presentation?.banner.subtle ?? getBannerToneTokenSet(tone);
441
+ const heading = title ?? presentation?.label ?? status;
442
+ const body = detail ?? description ?? children ?? content ?? presentation?.description;
443
+ const role = tone === "critical" || tone === "danger" ? "alert" : "status";
444
+ const resolvedIcon = icon ?? resolveStatusGlyph(presentation?.iconName);
445
+ const resolvedShowIcon = showIcon ?? resolvedIcon !== void 0;
446
+ return /* @__PURE__ */ jsxRuntime.jsxs(
447
+ "div",
448
+ {
449
+ ref,
450
+ role,
451
+ "aria-live": role === "alert" ? "assertive" : "polite",
452
+ className: classes("oods-banner", "statusable-banner", className),
453
+ "data-oods-component": "Banner",
454
+ "data-status": status,
455
+ "data-domain": domain,
456
+ "data-tone": tone,
457
+ "data-emphasis": emphasis,
458
+ style: {
459
+ "--cmp-banner-background": tokenSet.background,
460
+ "--cmp-banner-border": tokenSet.border,
461
+ "--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
+ ...style
467
+ },
468
+ ...rest,
469
+ 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
475
+ ] }),
476
+ onDismiss ? /* @__PURE__ */ jsxRuntime.jsx(
477
+ "button",
478
+ {
479
+ type: "button",
480
+ className: "oods-banner-dismiss oods-banner__dismiss statusable-banner__dismiss",
481
+ "aria-label": dismissLabel,
482
+ onClick: () => onDismiss(),
483
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\xD7" })
484
+ }
485
+ ) : null
486
+ ]
487
+ }
488
+ );
489
+ }
490
+ );
491
+ Banner.displayName = "OODS.Banner";
492
+ var Button = React7__namespace.forwardRef(
493
+ ({
494
+ asChild = false,
495
+ content,
496
+ children,
497
+ className,
498
+ intent = "neutral",
499
+ size = "md",
500
+ style,
501
+ type,
502
+ onClick,
503
+ onActivate,
504
+ ...rest
505
+ }, ref) => {
506
+ const Component = asChild ? reactSlot.Slot : "button";
507
+ const handleClick = (event) => {
508
+ onClick?.(event);
509
+ if (!event.defaultPrevented) onActivate?.(event);
510
+ };
511
+ const nativeProps = asChild ? {} : { type: type ?? "button" };
512
+ return /* @__PURE__ */ jsxRuntime.jsx(
513
+ Component,
514
+ {
515
+ ref,
516
+ className: classes("oods-button", className),
517
+ "data-oods-component": "Button",
518
+ "data-intent": intent,
519
+ "data-size": size,
520
+ style: {
521
+ "--cmp-button-background": "var(--sys-surface-interactive-primary-default)",
522
+ "--cmp-button-background-hover": "var(--sys-surface-interactive-primary-hover)",
523
+ "--cmp-button-background-disabled": "var(--sys-surface-disabled)",
524
+ "--cmp-button-border": "var(--sys-border-subtle)",
525
+ "--cmp-button-text": "var(--sys-text-on-interactive)",
526
+ "--cmp-button-text-disabled": "var(--sys-text-disabled)",
527
+ ...style
528
+ },
529
+ onClick: handleClick,
530
+ ...nativeProps,
531
+ ...rest,
532
+ children: children ?? content
533
+ }
534
+ );
535
+ }
536
+ );
537
+ Button.displayName = "OODS.Button";
538
+ var Card = React7__namespace.forwardRef(
539
+ ({ as = "div", elevated = false, className, ...rest }, ref) => {
540
+ const Element = as;
541
+ return /* @__PURE__ */ jsxRuntime.jsx(
542
+ Element,
543
+ {
544
+ ref,
545
+ className: classes("oods-card", className),
546
+ "data-oods-component": "Card",
547
+ "data-elevated": elevated ? "true" : "false",
548
+ ...rest
549
+ }
550
+ );
551
+ }
552
+ );
553
+ Card.displayName = "OODS.Card";
554
+ var Text = React7__namespace.forwardRef(
555
+ ({
556
+ as = "span",
557
+ content,
558
+ children,
559
+ label,
560
+ size = "md",
561
+ weight = "regular",
562
+ className,
563
+ "aria-description": ariaDescription,
564
+ ...rest
565
+ }, ref) => {
566
+ const Element = as;
567
+ return /* @__PURE__ */ jsxRuntime.jsx(
568
+ Element,
569
+ {
570
+ ref,
571
+ className: classes("oods-text", className),
572
+ "data-oods-component": "Text",
573
+ "data-size": size,
574
+ "data-weight": weight,
575
+ "aria-description": ariaDescription ?? label,
576
+ ...rest,
577
+ children: children ?? content
578
+ }
579
+ );
580
+ }
581
+ );
582
+ Text.displayName = "OODS.Text";
583
+ var classes2 = (...values) => values.filter(Boolean).join(" ");
584
+ var describedByIds = (id, help, validation, nativeDescription) => [
585
+ nativeDescription,
586
+ help ? `${id}-description` : void 0,
587
+ validation?.message ? validation.id ?? `${id}-validation` : void 0
588
+ ].filter(Boolean).join(" ") || void 0;
589
+ var RequiredIndicator = ({
590
+ required,
591
+ children
592
+ }) => required && children !== null ? children ?? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oods-field-required form-field__required-indicator", "aria-hidden": "true", children: "*" }) : null;
593
+ var FieldFrame = ({
594
+ id,
595
+ label,
596
+ help,
597
+ description,
598
+ validation,
599
+ density = "comfortable",
600
+ required,
601
+ requiredIndicator,
602
+ checkboxControl,
603
+ className,
604
+ style,
605
+ children
606
+ }) => {
607
+ const resolvedHelp = help ?? description;
608
+ const validationTone = validation?.state === "error" ? "critical" : validation?.state === "warning" ? "warning" : validation?.state;
609
+ const validationTokens = validationTone ? getToneTokenSet(validationTone) : void 0;
610
+ const validationStyle = validationTokens ? {
611
+ "--cmp-input-message-border": validationTokens.border,
612
+ "--cmp-input-message-text": validationTokens.foreground,
613
+ "--form-field-border": validationTokens.border,
614
+ "--form-field-border-active": validationTokens.border,
615
+ "--form-field-background-active": validationTokens.background,
616
+ "--form-field-validation-color": validationTokens.foreground,
617
+ "--form-field-focus-inner": validationTokens.border,
618
+ "--form-field-focus-outer": validationTokens.background,
619
+ "--form-field-accent": validationTokens.foreground
620
+ } : {};
621
+ return /* @__PURE__ */ jsxRuntime.jsxs(
622
+ "div",
623
+ {
624
+ className: classes2(
625
+ "oods-field",
626
+ "form-field",
627
+ checkboxControl !== void 0 && "oods-checkbox",
628
+ className
629
+ ),
630
+ style: { ...validationStyle, ...style },
631
+ "data-density": density,
632
+ "data-validation-state": validation?.state,
633
+ children: [
634
+ /* @__PURE__ */ jsxRuntime.jsxs(
635
+ "label",
636
+ {
637
+ className: "form-field__label",
638
+ htmlFor: id,
639
+ children: [
640
+ checkboxControl,
641
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oods-field-label", children: label }),
642
+ /* @__PURE__ */ jsxRuntime.jsx(RequiredIndicator, { required, children: requiredIndicator })
643
+ ]
644
+ }
645
+ ),
646
+ checkboxControl === void 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "form-field__control", children }) : null,
647
+ resolvedHelp ? /* @__PURE__ */ jsxRuntime.jsx("p", { id: `${id}-description`, className: "oods-field-help form-field__description", children: resolvedHelp }) : null,
648
+ validation?.message ? /* @__PURE__ */ jsxRuntime.jsx(
649
+ "p",
650
+ {
651
+ id: validation.id ?? `${id}-validation`,
652
+ className: "oods-field-error form-field__validation",
653
+ role: validation.state === "error" ? "alert" : "status",
654
+ "aria-live": validation.state === "error" ? "assertive" : "polite",
655
+ "data-state": validation.state,
656
+ children: validation.message
657
+ }
658
+ ) : null
659
+ ]
660
+ }
661
+ );
662
+ };
663
+ var InputPrimitive = React7__namespace.forwardRef(
664
+ ({
665
+ id,
666
+ label,
667
+ help,
668
+ description,
669
+ validation,
670
+ density,
671
+ requiredIndicator,
672
+ className,
673
+ style,
674
+ inputClassName,
675
+ inputStyle,
676
+ onChange,
677
+ onInput,
678
+ onValueChange,
679
+ onUpdate,
680
+ required,
681
+ "aria-describedby": nativeDescription,
682
+ type = "text",
683
+ ...rest
684
+ }, ref) => {
685
+ if (type === "datetime-local") {
686
+ if (rest.value !== void 0) rest.value = componentContracts.dateTimeInputValue(rest.value);
687
+ if (rest.defaultValue !== void 0) rest.defaultValue = componentContracts.dateTimeInputValue(rest.defaultValue);
688
+ }
689
+ const resolvedHelp = help ?? description;
690
+ const handleChange = (event) => {
691
+ onChange?.(event);
692
+ if (!event.defaultPrevented) {
693
+ onValueChange?.(event.currentTarget.value);
694
+ onUpdate?.(event.currentTarget.value);
695
+ }
696
+ };
697
+ return /* @__PURE__ */ jsxRuntime.jsx(
698
+ FieldFrame,
699
+ {
700
+ id,
701
+ label,
702
+ help: resolvedHelp,
703
+ validation,
704
+ density,
705
+ required,
706
+ requiredIndicator,
707
+ className,
708
+ style,
709
+ children: /* @__PURE__ */ jsxRuntime.jsx(
710
+ "input",
711
+ {
712
+ ref,
713
+ id,
714
+ type,
715
+ className: classes2("oods-field-control", "form-field__input", inputClassName),
716
+ style: inputStyle,
717
+ "data-oods-component": "Input",
718
+ "data-validation-state": validation?.state,
719
+ "aria-describedby": describedByIds(id, resolvedHelp, validation, nativeDescription),
720
+ "aria-invalid": validation?.state === "error" || void 0,
721
+ required,
722
+ onInput,
723
+ onChange: handleChange,
724
+ ...rest
725
+ }
726
+ )
727
+ }
728
+ );
729
+ }
730
+ );
731
+ InputPrimitive.displayName = "OODS.Input";
732
+ var Input = InputPrimitive;
733
+ var DatePicker = React7__namespace.forwardRef(
734
+ ({ pickerClassName, pickerStyle, inputClassName, inputStyle, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
735
+ Input,
736
+ {
737
+ ref,
738
+ type: "date",
739
+ "data-oods-component": "DatePicker",
740
+ inputClassName: classes2("form-field__date-picker", inputClassName, pickerClassName),
741
+ inputStyle: { ...inputStyle, ...pickerStyle },
742
+ ...rest
743
+ }
744
+ )
745
+ );
746
+ DatePicker.displayName = "OODS.DatePicker";
747
+ var Checkbox = React7__namespace.forwardRef(
748
+ ({
749
+ id,
750
+ label,
751
+ help,
752
+ description,
753
+ validation,
754
+ density,
755
+ requiredIndicator,
756
+ className,
757
+ style,
758
+ checkboxClassName,
759
+ checkboxStyle,
760
+ onChange,
761
+ onCheckedChange,
762
+ onUpdate,
763
+ required,
764
+ "aria-describedby": nativeDescription,
765
+ ...rest
766
+ }, ref) => {
767
+ const resolvedHelp = help ?? description;
768
+ const handleChange = (event) => {
769
+ onChange?.(event);
770
+ if (!event.defaultPrevented) {
771
+ onCheckedChange?.(event.currentTarget.checked);
772
+ onUpdate?.(event.currentTarget.checked);
773
+ }
774
+ };
775
+ const control = /* @__PURE__ */ jsxRuntime.jsx(
776
+ "input",
777
+ {
778
+ ref,
779
+ id,
780
+ type: "checkbox",
781
+ className: classes2("form-field__checkbox", checkboxClassName),
782
+ style: checkboxStyle,
783
+ "data-oods-component": "Checkbox",
784
+ "data-validation-state": validation?.state,
785
+ "aria-describedby": describedByIds(id, resolvedHelp, validation, nativeDescription),
786
+ "aria-invalid": validation?.state === "error" || void 0,
787
+ required,
788
+ onChange: handleChange,
789
+ ...rest
790
+ }
791
+ );
792
+ return /* @__PURE__ */ jsxRuntime.jsx(
793
+ FieldFrame,
794
+ {
795
+ id,
796
+ label,
797
+ help: resolvedHelp,
798
+ validation,
799
+ density,
800
+ required,
801
+ requiredIndicator,
802
+ checkboxControl: control,
803
+ className,
804
+ style
805
+ }
806
+ );
807
+ }
808
+ );
809
+ Checkbox.displayName = "OODS.Checkbox";
810
+ var Select = React7__namespace.forwardRef(
811
+ ({
812
+ id,
813
+ label,
814
+ help,
815
+ description,
816
+ validation,
817
+ density,
818
+ requiredIndicator,
819
+ className,
820
+ style,
821
+ options,
822
+ placeholder,
823
+ selectClassName,
824
+ selectStyle,
825
+ onChange,
826
+ onValueChange,
827
+ onUpdate,
828
+ children,
829
+ required,
830
+ "aria-describedby": nativeDescription,
831
+ ...rest
832
+ }, ref) => {
833
+ const resolvedHelp = help ?? description;
834
+ const handleChange = (event) => {
835
+ onChange?.(event);
836
+ if (!event.defaultPrevented) {
837
+ onValueChange?.(event.currentTarget.value);
838
+ onUpdate?.(event.currentTarget.value);
839
+ }
840
+ };
841
+ return /* @__PURE__ */ jsxRuntime.jsx(
842
+ FieldFrame,
843
+ {
844
+ id,
845
+ label,
846
+ help: resolvedHelp,
847
+ validation,
848
+ density,
849
+ required,
850
+ requiredIndicator,
851
+ className,
852
+ style,
853
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
854
+ "select",
855
+ {
856
+ ref,
857
+ id,
858
+ className: classes2("oods-field-control", "form-field__select", selectClassName),
859
+ style: selectStyle,
860
+ "data-oods-component": "Select",
861
+ "data-validation-state": validation?.state,
862
+ "aria-describedby": describedByIds(id, resolvedHelp, validation, nativeDescription),
863
+ "aria-invalid": validation?.state === "error" || void 0,
864
+ required,
865
+ onChange: handleChange,
866
+ ...rest,
867
+ children: [
868
+ placeholder ? /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: placeholder }) : null,
869
+ children ?? options?.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option.value, disabled: option.disabled, children: option.label }, option.value))
870
+ ]
871
+ }
872
+ )
873
+ }
874
+ );
875
+ }
876
+ );
877
+ Select.displayName = "OODS.Select";
878
+ var Textarea = React7__namespace.forwardRef(
879
+ ({
880
+ id,
881
+ label,
882
+ help,
883
+ description,
884
+ validation,
885
+ density,
886
+ requiredIndicator,
887
+ className,
888
+ style,
889
+ textareaClassName,
890
+ textareaStyle,
891
+ onChange,
892
+ onInput,
893
+ onValueChange,
894
+ onUpdate,
895
+ rows = 4,
896
+ required,
897
+ "aria-describedby": nativeDescription,
898
+ ...rest
899
+ }, ref) => {
900
+ const resolvedHelp = help ?? description;
901
+ const handleChange = (event) => {
902
+ onChange?.(event);
903
+ if (!event.defaultPrevented) {
904
+ onValueChange?.(event.currentTarget.value);
905
+ onUpdate?.(event.currentTarget.value);
906
+ }
907
+ };
908
+ return /* @__PURE__ */ jsxRuntime.jsx(
909
+ FieldFrame,
910
+ {
911
+ id,
912
+ label,
913
+ help: resolvedHelp,
914
+ validation,
915
+ density,
916
+ required,
917
+ requiredIndicator,
918
+ className,
919
+ style,
920
+ children: /* @__PURE__ */ jsxRuntime.jsx(
921
+ "textarea",
922
+ {
923
+ ref,
924
+ id,
925
+ className: classes2(
926
+ "oods-field-control",
927
+ "form-field__input",
928
+ "form-field__textarea",
929
+ textareaClassName
930
+ ),
931
+ style: textareaStyle,
932
+ "data-oods-component": "Textarea",
933
+ "data-validation-state": validation?.state,
934
+ "aria-describedby": describedByIds(id, resolvedHelp, validation, nativeDescription),
935
+ "aria-invalid": validation?.state === "error" || void 0,
936
+ rows,
937
+ required,
938
+ onInput,
939
+ onChange: handleChange,
940
+ ...rest
941
+ }
942
+ )
943
+ }
944
+ );
945
+ }
946
+ );
947
+ Textarea.displayName = "OODS.Textarea";
948
+ var classes3 = (...values) => values.filter(Boolean).join(" ");
949
+ var GAP_VALUES = {
950
+ xs: "var(--cmp-spacing-inline-xs, 0.5rem)",
951
+ sm: "var(--cmp-spacing-inline-sm, 0.75rem)",
952
+ md: "var(--cmp-spacing-stack-default, 1rem)",
953
+ lg: "var(--cmp-spacing-stack-lg, 1.5rem)",
954
+ xl: "var(--cmp-spacing-stack-xl, 2rem)"
955
+ };
956
+ var resolveGap = (gap) => gap ? GAP_VALUES[gap] ?? gap : void 0;
957
+ var maxColumns = (columns) => {
958
+ const count = Number(columns);
959
+ return Number.isFinite(count) && count > 0 ? count : void 0;
960
+ };
961
+ var Grid = React7__namespace.forwardRef(
962
+ ({
963
+ columns = "auto-fit",
964
+ minColumnWidth = "16rem",
965
+ gap = "md",
966
+ align = "stretch",
967
+ justify = "normal",
968
+ className,
969
+ style,
970
+ ...rest
971
+ }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
972
+ "div",
973
+ {
974
+ ref,
975
+ className: classes3("oods-grid", className),
976
+ "data-oods-component": "Grid",
977
+ "data-max-columns": maxColumns(columns),
978
+ style: {
979
+ "--oods-grid-columns": columns,
980
+ "--oods-grid-min-column": minColumnWidth,
981
+ "--oods-layout-gap": resolveGap(gap),
982
+ "--oods-layout-align": align,
983
+ "--oods-layout-justify": justify,
984
+ ...style
985
+ },
986
+ ...rest
987
+ }
988
+ )
989
+ );
990
+ Grid.displayName = "OODS.Grid";
991
+ var Stack = React7__namespace.forwardRef(
992
+ ({
993
+ direction = "column",
994
+ gap = "md",
995
+ align = "stretch",
996
+ justify = "flex-start",
997
+ wrap = false,
998
+ className,
999
+ style,
1000
+ ...rest
1001
+ }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
1002
+ "div",
1003
+ {
1004
+ ref,
1005
+ className: classes3("oods-stack", className),
1006
+ "data-oods-component": "Stack",
1007
+ "data-direction": direction,
1008
+ "data-wrap": wrap ? "true" : "false",
1009
+ style: {
1010
+ "--oods-stack-direction": direction,
1011
+ "--oods-stack-wrap": wrap ? "wrap" : "nowrap",
1012
+ "--oods-layout-gap": resolveGap(gap),
1013
+ "--oods-layout-align": align,
1014
+ "--oods-layout-justify": justify,
1015
+ ...style
1016
+ },
1017
+ ...rest
1018
+ }
1019
+ )
1020
+ );
1021
+ Stack.displayName = "OODS.Stack";
1022
+ var classes4 = (...values) => values.filter(Boolean).join(" ");
1023
+ var TableHead = React7__namespace.forwardRef(
1024
+ ({ className, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx("thead", { ref, className: classes4("oods-table__header", className), ...rest })
1025
+ );
1026
+ TableHead.displayName = "OODS.Table.Head";
1027
+ var TableBody = React7__namespace.forwardRef(
1028
+ ({ className, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx("tbody", { ref, className: classes4("oods-table__body", className), ...rest })
1029
+ );
1030
+ TableBody.displayName = "OODS.Table.Body";
1031
+ var TableCaption = React7__namespace.forwardRef(
1032
+ ({ className, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx("caption", { ref, className: classes4("oods-table__caption", className), ...rest })
1033
+ );
1034
+ TableCaption.displayName = "OODS.Table.Caption";
1035
+ var TableRow = React7__namespace.forwardRef(
1036
+ ({
1037
+ selectable = false,
1038
+ selected = false,
1039
+ onActivate,
1040
+ className,
1041
+ tabIndex,
1042
+ onClick,
1043
+ onKeyDown,
1044
+ ...rest
1045
+ }, ref) => {
1046
+ const handleClick = (event) => {
1047
+ onClick?.(event);
1048
+ if (!event.defaultPrevented) onActivate?.(event);
1049
+ };
1050
+ const handleKeyDown = (event) => {
1051
+ onKeyDown?.(event);
1052
+ if (!event.defaultPrevented && selectable && (event.key === "Enter" || event.key === " ")) {
1053
+ event.preventDefault();
1054
+ onActivate?.(event);
1055
+ }
1056
+ };
1057
+ return /* @__PURE__ */ jsxRuntime.jsx(
1058
+ "tr",
1059
+ {
1060
+ ref,
1061
+ className: classes4("oods-table__row", className),
1062
+ "data-selectable": selectable ? "true" : void 0,
1063
+ "data-selected": selected ? "true" : void 0,
1064
+ "aria-selected": selectable ? selected : void 0,
1065
+ tabIndex: selectable ? tabIndex ?? 0 : tabIndex,
1066
+ onClick: handleClick,
1067
+ onKeyDown: handleKeyDown,
1068
+ ...rest
1069
+ }
1070
+ );
1071
+ }
1072
+ );
1073
+ TableRow.displayName = "OODS.Table.Row";
1074
+ var TableHeaderCell = React7__namespace.forwardRef(
1075
+ ({ numeric = false, className, scope = "col", ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
1076
+ "th",
1077
+ {
1078
+ ref,
1079
+ className: classes4(
1080
+ "oods-table__header-cell",
1081
+ numeric && "oods-table__header-cell--numeric",
1082
+ className
1083
+ ),
1084
+ "data-numeric": numeric ? "true" : void 0,
1085
+ scope,
1086
+ ...rest
1087
+ }
1088
+ )
1089
+ );
1090
+ TableHeaderCell.displayName = "OODS.Table.HeaderCell";
1091
+ var TableCell = React7__namespace.forwardRef(
1092
+ ({
1093
+ numeric = false,
1094
+ status,
1095
+ statusDomain = "subscription",
1096
+ tone: toneOverride,
1097
+ statusEmphasis = "surface",
1098
+ className,
1099
+ children,
1100
+ style,
1101
+ title,
1102
+ ...rest
1103
+ }, ref) => {
1104
+ const presentation = status ? getStatusPresentation(statusDomain, status) : void 0;
1105
+ const tone = toneOverride ?? presentation?.tone;
1106
+ const tokens = tone ? getToneTokenSet(tone) : void 0;
1107
+ const statusStyle = tokens ? statusEmphasis === "text" ? { "--table-cell-status-foreground": tokens.foreground } : {
1108
+ "--table-cell-status-background": tokens.background,
1109
+ "--table-cell-status-border": tokens.border,
1110
+ "--table-cell-status-foreground": tokens.foreground
1111
+ } : {};
1112
+ return /* @__PURE__ */ jsxRuntime.jsx(
1113
+ "td",
1114
+ {
1115
+ ref,
1116
+ className: classes4(
1117
+ "oods-table__cell",
1118
+ numeric && "oods-table__cell--numeric",
1119
+ status && "oods-table__cell--status",
1120
+ className
1121
+ ),
1122
+ "data-numeric": numeric ? "true" : void 0,
1123
+ "data-status": status,
1124
+ "data-status-domain": status ? statusDomain : void 0,
1125
+ "data-status-tone": status ? tone : void 0,
1126
+ "data-status-emphasis": status ? statusEmphasis : void 0,
1127
+ "data-has-status": status ? "true" : void 0,
1128
+ title: title ?? presentation?.description,
1129
+ style: { ...statusStyle, ...style },
1130
+ ...rest,
1131
+ children: children ?? presentation?.label ?? status
1132
+ }
1133
+ );
1134
+ }
1135
+ );
1136
+ TableCell.displayName = "OODS.Table.Cell";
1137
+ var TableRoot = React7__namespace.forwardRef(
1138
+ ({
1139
+ caption,
1140
+ columns,
1141
+ rows,
1142
+ density = "comfortable",
1143
+ selectable = false,
1144
+ onRowActivate,
1145
+ children,
1146
+ containerClassName,
1147
+ containerStyle,
1148
+ className,
1149
+ ...rest
1150
+ }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
1151
+ "div",
1152
+ {
1153
+ className: classes4("oods-table__container", containerClassName),
1154
+ style: containerStyle,
1155
+ "data-density": density,
1156
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1157
+ "table",
1158
+ {
1159
+ ref,
1160
+ className: classes4("oods-table", className),
1161
+ "data-oods-component": "Table",
1162
+ "data-density": density,
1163
+ ...rest,
1164
+ 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)) }) }),
1167
+ /* @__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
+ "tr",
1169
+ {
1170
+ className: "oods-table__row",
1171
+ "data-selectable": selectable ? "true" : void 0,
1172
+ children: columns?.map((column, columnIndex) => {
1173
+ const value = row[column.key];
1174
+ const rendered = column.render ? column.render(value, row) : String(value ?? "");
1175
+ return /* @__PURE__ */ jsxRuntime.jsx(TableCell, { numeric: column.numeric, children: selectable && columnIndex === 0 ? /* @__PURE__ */ jsxRuntime.jsx(
1176
+ "button",
1177
+ {
1178
+ type: "button",
1179
+ className: "oods-table-row-action",
1180
+ onClick: (event) => onRowActivate?.(row.id, row, event),
1181
+ children: rendered
1182
+ }
1183
+ ) : rendered }, column.key);
1184
+ })
1185
+ },
1186
+ row.id
1187
+ )) })
1188
+ ] })
1189
+ }
1190
+ )
1191
+ }
1192
+ )
1193
+ );
1194
+ TableRoot.displayName = "OODS.Table";
1195
+ var Table = Object.assign(TableRoot, {
1196
+ Head: TableHead,
1197
+ Body: TableBody,
1198
+ Caption: TableCaption,
1199
+ Row: TableRow,
1200
+ HeaderCell: TableHeaderCell,
1201
+ Cell: TableCell
1202
+ });
1203
+ var classes5 = (...values) => values.filter(Boolean).join(" ");
1204
+ var enabledTabIndexes = (items) => items.flatMap((item, index) => item.disabled || item.isDisabled ? [] : [index]);
1205
+ var partitionForOverflow = (items, visibleCount, selectedId) => {
1206
+ if (visibleCount >= items.length) return { visibleItems: items, overflowItems: [] };
1207
+ const visibleItems = [...items.slice(0, Math.max(1, visibleCount))];
1208
+ const selected = items.find((item) => item.id === selectedId);
1209
+ if (selected && !visibleItems.some((item) => item.id === selectedId)) {
1210
+ visibleItems[visibleItems.length - 1] = selected;
1211
+ }
1212
+ const visibleIds = new Set(visibleItems.map((item) => item.id));
1213
+ return {
1214
+ visibleItems,
1215
+ overflowItems: items.filter((item) => !visibleIds.has(item.id))
1216
+ };
1217
+ };
1218
+ var Tabs = React7__namespace.forwardRef(
1219
+ ({
1220
+ items,
1221
+ selectedId,
1222
+ defaultSelectedId,
1223
+ size = "md",
1224
+ overflowLabel = "More",
1225
+ ariaLabel,
1226
+ onChange,
1227
+ onUpdate,
1228
+ className,
1229
+ "aria-label": ariaLabelAttribute,
1230
+ ...rest
1231
+ }, ref) => {
1232
+ const instanceId = React7__namespace.useId().replaceAll(":", "");
1233
+ const controlled = selectedId !== void 0;
1234
+ const firstEnabled = items.find((item) => !item.disabled && !item.isDisabled)?.id ?? "";
1235
+ const [internalSelectedId, setInternalSelectedId] = React7__namespace.useState(
1236
+ defaultSelectedId ?? firstEnabled
1237
+ );
1238
+ 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(
1248
+ (id) => {
1249
+ const item = items.find((candidate) => candidate.id === id);
1250
+ if (!item || item.disabled || item.isDisabled) return;
1251
+ if (!controlled) setInternalSelectedId(id);
1252
+ focusRequestedByUser.current = true;
1253
+ setFocusedId(id);
1254
+ onChange?.(id);
1255
+ onUpdate?.(id);
1256
+ },
1257
+ [controlled, items, onChange, onUpdate]
1258
+ );
1259
+ const measure = React7__namespace.useCallback(() => {
1260
+ const list = listRef.current;
1261
+ if (!list || items.length < 2) return;
1262
+ const available = list.offsetWidth;
1263
+ for (const tab of Array.from(list.querySelectorAll('[role="tab"]'))) {
1264
+ const itemId = tab.dataset.tabId;
1265
+ if (itemId && tab.offsetWidth > 0) itemWidths.current.set(itemId, tab.offsetWidth);
1266
+ }
1267
+ const widths = items.map((item) => itemWidths.current.get(item.id) ?? 0);
1268
+ const total = widths.reduce((sum, width) => sum + width, 0);
1269
+ if (!available || !total || total <= available) {
1270
+ setVisibleCount(items.length);
1271
+ return;
1272
+ }
1273
+ const overflowReserve = 80;
1274
+ let used = 0;
1275
+ let count = 0;
1276
+ for (const width of widths) {
1277
+ if (used + width > available - overflowReserve) break;
1278
+ used += width;
1279
+ count += 1;
1280
+ }
1281
+ setVisibleCount(Math.max(1, count));
1282
+ }, [items.length]);
1283
+ React7__namespace.useLayoutEffect(() => {
1284
+ measure();
1285
+ const list = listRef.current;
1286
+ if (!list || typeof ResizeObserver === "undefined") return void 0;
1287
+ const observer = new ResizeObserver(measure);
1288
+ observer.observe(list);
1289
+ return () => observer.disconnect();
1290
+ }, [measure]);
1291
+ const { visibleItems, overflowItems } = partitionForOverflow(
1292
+ items,
1293
+ visibleCount,
1294
+ activeId
1295
+ );
1296
+ const move = (currentId, key) => {
1297
+ const enabled = enabledTabIndexes(items);
1298
+ if (enabled.length === 0) return;
1299
+ const currentIndex = items.findIndex((item) => item.id === currentId);
1300
+ const position = enabled.indexOf(currentIndex);
1301
+ let nextIndex;
1302
+ if (key === "Home") nextIndex = enabled[0];
1303
+ if (key === "End") nextIndex = enabled[enabled.length - 1];
1304
+ if (key === "ArrowRight") nextIndex = enabled[(Math.max(0, position) + 1) % enabled.length];
1305
+ if (key === "ArrowLeft") nextIndex = enabled[(position - 1 + enabled.length) % enabled.length];
1306
+ if (nextIndex === void 0) return;
1307
+ const nextId = items[nextIndex]?.id;
1308
+ if (!nextId) return;
1309
+ select(nextId);
1310
+ };
1311
+ React7__namespace.useEffect(() => {
1312
+ if (focusRequestedByUser.current && visibleItems.some((item) => item.id === focusedId)) {
1313
+ focusRequestedByUser.current = false;
1314
+ tabRefs.current.get(focusedId)?.focus();
1315
+ }
1316
+ }, [focusedId, visibleItems]);
1317
+ const renderTab = (item) => {
1318
+ const disabled = Boolean(item.disabled || item.isDisabled);
1319
+ const selected = item.id === activeId;
1320
+ return /* @__PURE__ */ jsxRuntime.jsx(
1321
+ "button",
1322
+ {
1323
+ ref: (node) => {
1324
+ if (node) tabRefs.current.set(item.id, node);
1325
+ else tabRefs.current.delete(item.id);
1326
+ },
1327
+ id: `${instanceId}-tab-${item.id}`,
1328
+ type: "button",
1329
+ role: "tab",
1330
+ className: classes5(
1331
+ "oods-tab",
1332
+ "tabs__tab",
1333
+ selected && "tabs__tab--selected",
1334
+ disabled && "tabs__tab--disabled"
1335
+ ),
1336
+ "data-size": size,
1337
+ "data-tab-id": item.id,
1338
+ "aria-selected": selected,
1339
+ "aria-controls": `${instanceId}-panel-${item.id}`,
1340
+ tabIndex: item.id === focusedId ? 0 : -1,
1341
+ disabled,
1342
+ title: typeof item.label === "string" ? item.label : void 0,
1343
+ onFocus: () => setFocusedId(item.id),
1344
+ onClick: () => select(item.id),
1345
+ onKeyDown: (event) => {
1346
+ if (["ArrowRight", "ArrowLeft", "Home", "End"].includes(event.key)) {
1347
+ event.preventDefault();
1348
+ move(item.id, event.key);
1349
+ }
1350
+ },
1351
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tabs__tab-label", children: item.label })
1352
+ },
1353
+ item.id
1354
+ );
1355
+ };
1356
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1357
+ "div",
1358
+ {
1359
+ ref,
1360
+ className: classes5("oods-tabs", "tabs", className),
1361
+ "data-oods-component": "Tabs",
1362
+ "data-size": size,
1363
+ ...rest,
1364
+ children: [
1365
+ /* @__PURE__ */ jsxRuntime.jsxs(
1366
+ "div",
1367
+ {
1368
+ ref: listRef,
1369
+ className: "oods-tab-list tabs__list",
1370
+ role: "tablist",
1371
+ "aria-label": ariaLabel ?? ariaLabelAttribute,
1372
+ children: [
1373
+ visibleItems.map(renderTab),
1374
+ overflowItems.length ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "oods-tabs__overflow", children: [
1375
+ /* @__PURE__ */ jsxRuntime.jsx(
1376
+ "button",
1377
+ {
1378
+ type: "button",
1379
+ className: "tabs__overflow-trigger",
1380
+ "aria-label": `${overflowLabel} tabs`,
1381
+ "aria-haspopup": "menu",
1382
+ "aria-expanded": menuOpen,
1383
+ "data-tabs-overflow-trigger": "true",
1384
+ onClick: () => setMenuOpen((open) => !open),
1385
+ children: overflowLabel
1386
+ }
1387
+ ),
1388
+ menuOpen ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tabs__overflow-menu", role: "menu", children: overflowItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
1389
+ "button",
1390
+ {
1391
+ type: "button",
1392
+ role: "menuitem",
1393
+ disabled: item.disabled || item.isDisabled,
1394
+ "aria-current": item.id === activeId ? "true" : void 0,
1395
+ className: classes5(
1396
+ "tabs__overflow-item",
1397
+ item.id === activeId && "tabs__overflow-item--selected"
1398
+ ),
1399
+ onClick: () => {
1400
+ select(item.id);
1401
+ setMenuOpen(false);
1402
+ },
1403
+ children: item.label
1404
+ },
1405
+ item.id
1406
+ )) }) : null
1407
+ ] }) : null
1408
+ ]
1409
+ }
1410
+ ),
1411
+ items.map((item) => {
1412
+ const selected = item.id === activeId;
1413
+ return /* @__PURE__ */ jsxRuntime.jsx(
1414
+ "div",
1415
+ {
1416
+ id: `${instanceId}-panel-${item.id}`,
1417
+ role: "tabpanel",
1418
+ className: "oods-tab-panel tabs__panel",
1419
+ "aria-labelledby": `${instanceId}-tab-${item.id}`,
1420
+ hidden: !selected,
1421
+ tabIndex: 0,
1422
+ children: selected ? item.panel : null
1423
+ },
1424
+ item.id
1425
+ );
1426
+ })
1427
+ ]
1428
+ }
1429
+ );
1430
+ }
1431
+ );
1432
+ Tabs.displayName = "OODS.Tabs";
1433
+ var classes6 = (...values) => values.filter(Boolean).join(" ");
1434
+ var humanize = (value) => value.split(/[_-]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join(" ");
1435
+ var StatusBadge = React7__namespace.forwardRef(
1436
+ ({
1437
+ status,
1438
+ value,
1439
+ label,
1440
+ children,
1441
+ content,
1442
+ domain = "subscription",
1443
+ tone,
1444
+ emphasis = "subtle",
1445
+ showIcon = true,
1446
+ field,
1447
+ statusField,
1448
+ domainField,
1449
+ readOnly,
1450
+ compact,
1451
+ variant,
1452
+ title,
1453
+ "aria-label": ariaLabel,
1454
+ ...rest
1455
+ }, ref) => {
1456
+ const resolvedStatus = status ?? value ?? "unknown";
1457
+ const presentation = getStatusPresentation(domain, resolvedStatus);
1458
+ return /* @__PURE__ */ jsxRuntime.jsx(
1459
+ Badge,
1460
+ {
1461
+ ref,
1462
+ status: resolvedStatus,
1463
+ domain,
1464
+ tone: tone === "lifecycle" ? void 0 : tone,
1465
+ emphasis: variant === "solid" ? "solid" : emphasis,
1466
+ showIcon,
1467
+ content: children ?? content,
1468
+ title: title ?? presentation.description,
1469
+ "aria-label": ariaLabel ?? label ?? `Status: ${presentation.label}`,
1470
+ "data-oods-component": "StatusBadge",
1471
+ ...rest
1472
+ }
1473
+ );
1474
+ }
1475
+ );
1476
+ StatusBadge.displayName = "OODS.StatusBadge";
1477
+ function formatPrice(amount, currency, fallback2) {
1478
+ if (amount === void 0 || !Number.isFinite(amount)) return fallback2;
1479
+ if (!currency) return new Intl.NumberFormat(void 0, { maximumFractionDigits: 2 }).format(amount);
1480
+ try {
1481
+ return new Intl.NumberFormat(void 0, {
1482
+ style: "currency",
1483
+ currency: currency.toUpperCase()
1484
+ }).format(amount);
1485
+ } catch {
1486
+ return `${currency.toUpperCase()} ${amount.toFixed(2)}`;
1487
+ }
1488
+ }
1489
+ var PriceBadge = React7__namespace.forwardRef(
1490
+ ({
1491
+ amountCents,
1492
+ unitAmountCents,
1493
+ minorUnits,
1494
+ amount,
1495
+ unitAmount,
1496
+ currency,
1497
+ currencyCode,
1498
+ label,
1499
+ value,
1500
+ children,
1501
+ emphasis = "subtle",
1502
+ field,
1503
+ amountField,
1504
+ currencyField,
1505
+ intervalField,
1506
+ minorUnitsParameter,
1507
+ className,
1508
+ ...rest
1509
+ }, ref) => {
1510
+ const cents = amountCents ?? unitAmountCents;
1511
+ const resolvedCurrency = currency ?? currencyCode;
1512
+ const resolvedAmount = cents === void 0 ? amount ?? unitAmount : cents / componentContracts.currencyMinorUnits(resolvedCurrency, minorUnits);
1513
+ const content = label ?? children ?? formatPrice(resolvedAmount, resolvedCurrency, value ?? "Price");
1514
+ return /* @__PURE__ */ jsxRuntime.jsx(
1515
+ Badge,
1516
+ {
1517
+ ref,
1518
+ content,
1519
+ emphasis,
1520
+ className: classes6("oods-price-badge", className),
1521
+ "data-oods-component": "PriceBadge",
1522
+ "data-badge-variant": "price",
1523
+ "data-price": "true",
1524
+ "data-currency": resolvedCurrency?.toUpperCase(),
1525
+ ...rest
1526
+ }
1527
+ );
1528
+ }
1529
+ );
1530
+ PriceBadge.displayName = "OODS.PriceBadge";
1531
+ function isRecord(value) {
1532
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1533
+ }
1534
+ function eventText(record, keys) {
1535
+ for (const key of keys) {
1536
+ const value = record[key];
1537
+ if (typeof value === "string") return value;
1538
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
1539
+ }
1540
+ return void 0;
1541
+ }
1542
+ function normalizeTimelineEvents(values) {
1543
+ return values.flatMap((value, index) => {
1544
+ if (!isRecord(value)) {
1545
+ return value === void 0 || value === null ? [] : [{ label: String(value) }];
1546
+ }
1547
+ const from = eventText(value, ["from"]);
1548
+ const to = eventText(value, ["to"]);
1549
+ return [{
1550
+ id: eventText(value, ["id"]) ?? `event-${index}`,
1551
+ label: eventText(value, ["label", "title"]) ?? (eventText(value, ["event", "status", "state"]) ? humanize(eventText(value, ["event", "status", "state"])) : void 0) ?? eventText(value, ["text", "name"]) ?? (to ? from ? `${humanize(from)} \u2192 ${humanize(to)}` : humanize(to) : void 0) ?? "Event",
1552
+ from,
1553
+ to,
1554
+ status: eventText(value, ["status"]),
1555
+ state: eventText(value, ["state"]),
1556
+ timestamp: eventText(value, ["timestamp", "datetime", "time", "at", "createdAt", "updatedAt"]),
1557
+ actor: eventText(value, ["actorId", "actor_id", "actor"]),
1558
+ actorId: eventText(value, ["actorId", "actor_id"]),
1559
+ reason: eventText(value, ["reason"]),
1560
+ detail: eventText(value, ["detail", "description", "message"]) ?? (to ? from ? `${humanize(from)} \u2192 ${humanize(to)}` : humanize(to) : void 0)
1561
+ }];
1562
+ });
1563
+ }
1564
+ var TimelinePrimitive = React7__namespace.forwardRef(
1565
+ ({
1566
+ componentId,
1567
+ defaultTitle,
1568
+ kind,
1569
+ source,
1570
+ title = defaultTitle,
1571
+ events,
1572
+ history,
1573
+ entries,
1574
+ stateHistory,
1575
+ status,
1576
+ allowedTransitions,
1577
+ showActorId = true,
1578
+ showReason = true,
1579
+ maxVisible,
1580
+ children,
1581
+ field,
1582
+ historyField,
1583
+ statesParameter,
1584
+ auditLogField,
1585
+ createdField,
1586
+ updatedField,
1587
+ eventField,
1588
+ eventTimestampField,
1589
+ eventOptionsParameter,
1590
+ showFromState,
1591
+ className,
1592
+ ...rest
1593
+ }, ref) => {
1594
+ const allEvents = normalizeTimelineEvents(source ?? events ?? history ?? entries ?? stateHistory ?? []);
1595
+ const visibleEvents = Number.isFinite(maxVisible) ? allEvents.slice(0, Math.max(0, Math.floor(maxVisible ?? 0))) : allEvents;
1596
+ const transitionCount = allowedTransitions?.length ?? 0;
1597
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1598
+ "div",
1599
+ {
1600
+ ref,
1601
+ role: "log",
1602
+ "aria-label": typeof title === "string" ? title : defaultTitle,
1603
+ className: classes6("oods-timeline", `oods-${kind}-timeline`, className),
1604
+ "data-oods-component": componentId,
1605
+ "data-timeline-type": kind,
1606
+ ...rest,
1607
+ children: [
1608
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "oods-timeline__title", children: title }),
1609
+ kind === "status" && status ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "oods-timeline__current", "data-timeline-current": "true", children: [
1610
+ "Current status: ",
1611
+ humanize(status)
1612
+ ] }) : null,
1613
+ transitionCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
1614
+ "Allowed transitions: ",
1615
+ allowedTransitions?.join(", ")
1616
+ ] }) : 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) => {
1618
+ const timestamp = event.timestamp ?? event.datetime;
1619
+ const actor = event.actor ?? event.actorId ?? event.actor_id;
1620
+ 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
+ const detail = event.detail ?? event.description;
1622
+ 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: [
1627
+ "Actor: ",
1628
+ actor
1629
+ ] }) : null,
1630
+ showReason && event.reason ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "oods-timeline__reason", children: [
1631
+ "Reason: ",
1632
+ event.reason
1633
+ ] }) : null
1634
+ ] }) }, event.id ?? `${timestamp ?? "event"}-${index}`);
1635
+ }) })
1636
+ ]
1637
+ }
1638
+ );
1639
+ }
1640
+ );
1641
+ TimelinePrimitive.displayName = "OODS.TimelinePrimitive";
1642
+ var StatusTimeline = React7__namespace.forwardRef(
1643
+ (props, ref) => /* @__PURE__ */ jsxRuntime.jsx(
1644
+ TimelinePrimitive,
1645
+ {
1646
+ ref,
1647
+ componentId: "StatusTimeline",
1648
+ defaultTitle: "Status Timeline",
1649
+ kind: "status",
1650
+ ...props
1651
+ }
1652
+ )
1653
+ );
1654
+ StatusTimeline.displayName = "OODS.StatusTimeline";
1655
+ var AuditTimeline = React7__namespace.forwardRef(
1656
+ ({ auditLog, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
1657
+ TimelinePrimitive,
1658
+ {
1659
+ ref,
1660
+ componentId: "AuditTimeline",
1661
+ defaultTitle: "Audit Timeline",
1662
+ kind: "audit",
1663
+ source: auditLog,
1664
+ ...props
1665
+ }
1666
+ )
1667
+ );
1668
+ AuditTimeline.displayName = "OODS.AuditTimeline";
1669
+ var CancellationSummary = React7__namespace.forwardRef(
1670
+ ({
1671
+ label,
1672
+ title = label ?? "Cancellation Summary",
1673
+ cancelAtPeriodEnd,
1674
+ requestedAt,
1675
+ reason,
1676
+ code,
1677
+ children,
1678
+ field,
1679
+ cancelAtPeriodEndField,
1680
+ requestedAtField,
1681
+ reasonField,
1682
+ codeField,
1683
+ className,
1684
+ ...rest
1685
+ }, ref) => {
1686
+ const childValue = typeof children === "boolean" ? children ? "Yes" : "No" : children;
1687
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1688
+ "section",
1689
+ {
1690
+ ref,
1691
+ className: classes6("oods-cancellation-summary", className),
1692
+ "data-oods-component": "CancellationSummary",
1693
+ "data-summary-type": "cancellation",
1694
+ "data-cancellation-state": cancelAtPeriodEnd === void 0 ? void 0 : String(cancelAtPeriodEnd),
1695
+ ...rest,
1696
+ children: [
1697
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: title }),
1698
+ /* @__PURE__ */ jsxRuntime.jsxs("dl", { children: [
1699
+ cancelAtPeriodEnd !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-summary-item": "true", children: [
1700
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Cancel at period end" }),
1701
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: cancelAtPeriodEnd ? "Yes" : "No" })
1702
+ ] }) : null,
1703
+ requestedAt ? /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-summary-item": "true", children: [
1704
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Requested at" }),
1705
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: componentContracts.formatDateTime(requestedAt) })
1706
+ ] }) : null,
1707
+ reason ? /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-summary-item": "true", children: [
1708
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Reason" }),
1709
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: reason })
1710
+ ] }) : null,
1711
+ code ? /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-summary-item": "true", children: [
1712
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Code" }),
1713
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: componentContracts.formatReadOnlyValue(code, "string", true) })
1714
+ ] }) : null,
1715
+ childValue !== void 0 && childValue !== null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-summary-item": "true", children: [
1716
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: label ?? "Cancellation" }),
1717
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: childValue })
1718
+ ] }) : null
1719
+ ] })
1720
+ ]
1721
+ }
1722
+ );
1723
+ }
1724
+ );
1725
+ CancellationSummary.displayName = "OODS.CancellationSummary";
1726
+ var SearchInput = React7__namespace.forwardRef(
1727
+ ({
1728
+ id,
1729
+ label = "Search",
1730
+ value,
1731
+ defaultValue = "",
1732
+ placeholder = "Search\u2026",
1733
+ clearable = true,
1734
+ debounceMs,
1735
+ debounce,
1736
+ minQueryLength = 0,
1737
+ field,
1738
+ placeholderParameter,
1739
+ debounceParameter,
1740
+ minQueryLengthParameter,
1741
+ clearableParameter,
1742
+ disabled,
1743
+ className,
1744
+ onChange,
1745
+ onValueChange,
1746
+ onUpdate,
1747
+ onSearch,
1748
+ onClear,
1749
+ onKeyDown,
1750
+ ...rest
1751
+ }, ref) => {
1752
+ const generatedId = React7__namespace.useId();
1753
+ const resolvedId = id ?? `oods-search-${generatedId.replace(/:/g, "")}`;
1754
+ const [uncontrolledValue, setUncontrolledValue] = React7__namespace.useState(defaultValue);
1755
+ const currentValue = value ?? uncontrolledValue;
1756
+ const timerRef = React7__namespace.useRef(void 0);
1757
+ const delay = Math.max(0, debounceMs ?? debounce ?? 0);
1758
+ React7__namespace.useEffect(() => () => {
1759
+ if (timerRef.current !== void 0) clearTimeout(timerRef.current);
1760
+ }, []);
1761
+ const publish = (nextValue) => {
1762
+ if (timerRef.current !== void 0) clearTimeout(timerRef.current);
1763
+ const emit = () => {
1764
+ if (nextValue.length >= minQueryLength || nextValue.length === 0) {
1765
+ onValueChange?.(nextValue);
1766
+ onUpdate?.(nextValue);
1767
+ onSearch?.(nextValue);
1768
+ }
1769
+ };
1770
+ if (delay === 0) emit();
1771
+ else timerRef.current = setTimeout(emit, delay);
1772
+ };
1773
+ const updateValue = (nextValue) => {
1774
+ if (value === void 0) setUncontrolledValue(nextValue);
1775
+ publish(nextValue);
1776
+ };
1777
+ const handleChange = (event) => {
1778
+ onChange?.(event);
1779
+ if (!event.defaultPrevented) updateValue(event.currentTarget.value);
1780
+ };
1781
+ const clear = () => {
1782
+ onClear?.();
1783
+ updateValue("");
1784
+ };
1785
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1786
+ "div",
1787
+ {
1788
+ role: "search",
1789
+ "aria-label": label,
1790
+ className: classes6("oods-search-input", className),
1791
+ "data-oods-component": "SearchInput",
1792
+ "data-behavioral": "search",
1793
+ children: [
1794
+ /* @__PURE__ */ jsxRuntime.jsx(
1795
+ Input,
1796
+ {
1797
+ ...rest,
1798
+ ref,
1799
+ id: resolvedId,
1800
+ type: "search",
1801
+ label,
1802
+ placeholder,
1803
+ value: currentValue,
1804
+ disabled,
1805
+ inputClassName: "oods-search-input__control",
1806
+ onChange: handleChange,
1807
+ onKeyDown: (event) => {
1808
+ onKeyDown?.(event);
1809
+ if (!event.defaultPrevented && event.key === "Escape" && currentValue) clear();
1810
+ }
1811
+ }
1812
+ ),
1813
+ clearable && currentValue ? /* @__PURE__ */ jsxRuntime.jsx(
1814
+ "button",
1815
+ {
1816
+ type: "button",
1817
+ className: "oods-search-input__clear",
1818
+ "aria-label": "Clear search",
1819
+ disabled,
1820
+ onClick: clear,
1821
+ children: "\xD7"
1822
+ }
1823
+ ) : null
1824
+ ]
1825
+ }
1826
+ );
1827
+ }
1828
+ );
1829
+ SearchInput.displayName = "OODS.SearchInput";
1830
+ function visiblePages(page, totalPages) {
1831
+ if (totalPages <= 7) return Array.from({ length: totalPages }, (_, index) => index + 1);
1832
+ const candidates = /* @__PURE__ */ new Set([1, totalPages, page - 1, page, page + 1]);
1833
+ const pages = [...candidates].filter((candidate) => candidate >= 1 && candidate <= totalPages).sort((a, b) => a - b);
1834
+ const result = [];
1835
+ for (const candidate of pages) {
1836
+ const previous = result[result.length - 1];
1837
+ if (typeof previous === "number" && candidate - previous > 1) result.push("ellipsis");
1838
+ result.push(candidate);
1839
+ }
1840
+ return result;
1841
+ }
1842
+ var PaginationBar = React7__namespace.forwardRef(
1843
+ ({
1844
+ page = 1,
1845
+ pageSize = 25,
1846
+ totalItems = 0,
1847
+ totalPages: suppliedTotalPages,
1848
+ pageSizeOptions = [10, 25, 50, 100],
1849
+ showPageSizeSelector = false,
1850
+ showGotoPage = false,
1851
+ showItemRange = true,
1852
+ pageField,
1853
+ pageSizeField,
1854
+ totalItemsField,
1855
+ totalPagesField,
1856
+ pageSizeOptionsParameter,
1857
+ showPageSizeSelectorParameter,
1858
+ showGotoPageParameter,
1859
+ showItemRangeParameter,
1860
+ onPageChange,
1861
+ onPageSizeChange,
1862
+ onChange,
1863
+ onUpdate,
1864
+ className,
1865
+ "aria-label": ariaLabel = "Pagination",
1866
+ ...rest
1867
+ }, ref) => {
1868
+ const safePageSize = Number.isFinite(pageSize) && pageSize > 0 ? Math.floor(pageSize) : 25;
1869
+ const derivedTotalPages = safePageSize > 0 ? Math.ceil(Math.max(0, totalItems) / safePageSize) : 0;
1870
+ const totalPages = Math.max(0, Math.floor(suppliedTotalPages ?? derivedTotalPages));
1871
+ const currentPage = totalPages > 0 ? Math.max(1, Math.min(Math.floor(page), totalPages)) : 1;
1872
+ const goToPage = (nextPage) => {
1873
+ if (totalPages === 0) return;
1874
+ const target = Math.max(1, Math.min(Math.floor(nextPage), totalPages));
1875
+ if (target === currentPage) return;
1876
+ onPageChange?.(target);
1877
+ onChange?.(target);
1878
+ onUpdate?.(target);
1879
+ };
1880
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1881
+ "nav",
1882
+ {
1883
+ ref,
1884
+ "aria-label": ariaLabel,
1885
+ className: classes6("oods-pagination-bar", className),
1886
+ "data-oods-component": "PaginationBar",
1887
+ "data-behavioral": "pagination",
1888
+ ...rest,
1889
+ children: [
1890
+ showItemRange ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1891
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-pagination-count": "true", children: `${totalItems} ${totalItems === 1 ? "record" : "records"}` }),
1892
+ totalItems > 0 && totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-pagination-range": "true", children: `Showing ${(currentPage - 1) * safePageSize + 1}\u2013${Math.min(currentPage * safePageSize, totalItems)} of ${totalItems}` })
1893
+ ] }) : null,
1894
+ totalPages > 1 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1895
+ /* @__PURE__ */ jsxRuntime.jsx(
1896
+ "button",
1897
+ {
1898
+ type: "button",
1899
+ "aria-label": "Previous page",
1900
+ "data-pagination-prev": "true",
1901
+ disabled: totalPages === 0 || currentPage <= 1,
1902
+ onClick: () => goToPage(currentPage - 1),
1903
+ children: "\u2039"
1904
+ }
1905
+ ),
1906
+ /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "oods-pagination-bar__pages", children: visiblePages(currentPage, totalPages).map((item, index) => item === "ellipsis" ? /* @__PURE__ */ jsxRuntime.jsx("li", { "aria-hidden": "true", children: "\u2026" }, `ellipsis-${index}`) : /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
1907
+ "button",
1908
+ {
1909
+ type: "button",
1910
+ "aria-label": `Page ${item}`,
1911
+ "aria-current": item === currentPage ? "page" : void 0,
1912
+ "data-pagination-page": item,
1913
+ onClick: () => goToPage(item),
1914
+ children: item
1915
+ }
1916
+ ) }, item)) }),
1917
+ /* @__PURE__ */ jsxRuntime.jsx(
1918
+ "button",
1919
+ {
1920
+ type: "button",
1921
+ "aria-label": "Next page",
1922
+ "data-pagination-next": "true",
1923
+ disabled: totalPages === 0 || currentPage >= totalPages,
1924
+ onClick: () => goToPage(currentPage + 1),
1925
+ children: "\u203A"
1926
+ }
1927
+ ),
1928
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-pagination-current": "true", children: `Page ${currentPage} of ${Math.max(1, totalPages)}` })
1929
+ ] }) : null,
1930
+ showPageSizeSelector ? /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1931
+ "Items per page",
1932
+ /* @__PURE__ */ jsxRuntime.jsx(
1933
+ "select",
1934
+ {
1935
+ "aria-label": "Items per page",
1936
+ value: safePageSize,
1937
+ onChange: (event) => onPageSizeChange?.(Number(event.currentTarget.value)),
1938
+ children: pageSizeOptions.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option, children: option }, option))
1939
+ }
1940
+ )
1941
+ ] }) : null,
1942
+ showGotoPage ? /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1943
+ "Go to page",
1944
+ /* @__PURE__ */ jsxRuntime.jsx(
1945
+ "input",
1946
+ {
1947
+ type: "number",
1948
+ min: 1,
1949
+ max: Math.max(1, totalPages),
1950
+ defaultValue: currentPage,
1951
+ onKeyDown: (event) => {
1952
+ if (event.key === "Enter") goToPage(Number(event.currentTarget.value));
1953
+ }
1954
+ }
1955
+ )
1956
+ ] }) : null
1957
+ ]
1958
+ }
1959
+ );
1960
+ }
1961
+ );
1962
+ PaginationBar.displayName = "OODS.PaginationBar";
1963
+ function asDate(value) {
1964
+ if (value === void 0) return void 0;
1965
+ const date = value instanceof Date ? value : new Date(value);
1966
+ return Number.isNaN(date.getTime()) ? void 0 : date;
1967
+ }
1968
+ function relativeLabel(date, now) {
1969
+ const seconds = Math.round((date.getTime() - now.getTime()) / 1e3);
1970
+ const units = [
1971
+ ["year", 31536e3],
1972
+ ["month", 2592e3],
1973
+ ["day", 86400],
1974
+ ["hour", 3600],
1975
+ ["minute", 60]
1976
+ ];
1977
+ const [unit, divisor] = units.find(([, candidate]) => Math.abs(seconds) >= candidate) ?? ["second", 1];
1978
+ return new Intl.RelativeTimeFormat(void 0, { numeric: "auto" }).format(
1979
+ Math.round(seconds / divisor),
1980
+ unit
1981
+ );
1982
+ }
1983
+ var RelativeTimestamp = React7__namespace.forwardRef(
1984
+ ({
1985
+ datetime,
1986
+ timestamp,
1987
+ value,
1988
+ updatedAt,
1989
+ createdAt,
1990
+ relative,
1991
+ label,
1992
+ text,
1993
+ timezone = "UTC",
1994
+ hideWhenEmpty,
1995
+ now,
1996
+ children,
1997
+ field,
1998
+ fallbackField,
1999
+ timezoneParameter,
2000
+ title,
2001
+ className,
2002
+ ...rest
2003
+ }, ref) => {
2004
+ const childRaw = typeof children === "string" || typeof children === "number" ? children : void 0;
2005
+ const raw = datetime ?? timestamp ?? value ?? updatedAt ?? createdAt ?? childRaw;
2006
+ const date = asDate(raw);
2007
+ if (hideWhenEmpty && !date) return null;
2008
+ const nowDate = asDate(now) ?? /* @__PURE__ */ new Date();
2009
+ const iso = date?.toISOString() ?? (raw === void 0 ? void 0 : String(raw));
2010
+ const absolute = componentContracts.formatDateTime(date, { timeZone: timezone });
2011
+ const content = relative ?? label ?? text ?? (now !== void 0 && date ? relativeLabel(date, nowDate) : absolute || children || "Unknown time");
2012
+ return /* @__PURE__ */ jsxRuntime.jsx(
2013
+ "time",
2014
+ {
2015
+ ref,
2016
+ dateTime: iso,
2017
+ title: title ?? absolute,
2018
+ className: classes6("oods-relative-timestamp", className),
2019
+ "data-oods-component": "RelativeTimestamp",
2020
+ suppressHydrationWarning: true,
2021
+ ...rest,
2022
+ children: content
2023
+ }
2024
+ );
2025
+ }
2026
+ );
2027
+ RelativeTimestamp.displayName = "OODS.RelativeTimestamp";
2028
+ var classes7 = (...values) => values.filter(Boolean).join(" ");
2029
+ var firstText = (...values) => values.find((value) => typeof value === "string" && value.trim().length > 0);
2030
+ 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) {
2033
+ return flatten(node.props.children);
2034
+ }
2035
+ return [node];
2036
+ });
2037
+ const nodes = flatten(children);
2038
+ if (nodes.every((node) => typeof node === "string" || typeof node === "number")) {
2039
+ const scalar = nodes.join("");
2040
+ return { scalar: scalar.trim().length > 0 ? scalar : void 0, authored: false };
2041
+ }
2042
+ return { authored: nodes.length > 0 };
2043
+ }
2044
+ function headingElement(as, level, fallback2) {
2045
+ 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;
2047
+ return `h${bounded}`;
2048
+ }
2049
+ function notEcho(supporting, heading) {
2050
+ if (!supporting || !heading) return supporting;
2051
+ return supporting.trim() === heading.trim() ? void 0 : supporting;
2052
+ }
2053
+ var DetailHeader = React7__namespace.forwardRef(
2054
+ ({ title, label, text, subtitle, sublabel, description, metadata, meta, level, as, children, className, ...rest }, ref) => {
2055
+ const Heading = headingElement(as, level, 2);
2056
+ const content = childContent(children);
2057
+ const heading = content.scalar ?? firstText(title, label, text) ?? "Details";
2058
+ const supporting = notEcho(firstText(subtitle, sublabel, description), heading);
2059
+ const metadataText = firstText(metadata, meta);
2060
+ return /* @__PURE__ */ jsxRuntime.jsx("header", { ref, className: classes7("oods-detail-header", className), "data-oods-component": "DetailHeader", ...rest, children: content.authored ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2061
+ /* @__PURE__ */ jsxRuntime.jsx(Heading, { children: heading }),
2062
+ supporting ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-oods-subtitle": "true", children: supporting }) : null,
2063
+ metadataText ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-oods-metadata": "true", children: metadataText }) : null
2064
+ ] }) });
2065
+ }
2066
+ );
2067
+ DetailHeader.displayName = "OODS.DetailHeader";
2068
+ var CardHeader = React7__namespace.forwardRef(
2069
+ ({ title, label, text, supporting, supportingText, subtitle, description, level, as, children, className, ...rest }, ref) => {
2070
+ const Heading = headingElement(as, level, 2);
2071
+ const content = childContent(children);
2072
+ const heading = content.scalar ?? firstText(title, label, text) ?? "Card";
2073
+ const supportingLabel = notEcho(firstText(supporting, supportingText, subtitle, description), heading);
2074
+ return /* @__PURE__ */ jsxRuntime.jsx("header", { ref, className: classes7("oods-card-header", className), "data-oods-component": "CardHeader", ...rest, children: content.authored ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2075
+ /* @__PURE__ */ jsxRuntime.jsx(Heading, { children: heading }),
2076
+ supportingLabel ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-oods-supporting": "true", children: supportingLabel }) : null
2077
+ ] }) });
2078
+ }
2079
+ );
2080
+ CardHeader.displayName = "OODS.CardHeader";
2081
+ var ColorSwatch = React7__namespace.forwardRef(
2082
+ ({ color, value, state, label, children, className, style, ...rest }, ref) => {
2083
+ const resolvedColor = firstText(color, value, state);
2084
+ const content = childContent(children);
2085
+ const resolvedLabel = content.scalar ?? firstText(label) ?? resolvedColor ?? "default";
2086
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2087
+ "span",
2088
+ {
2089
+ ref,
2090
+ className: classes7("oods-color-swatch", className),
2091
+ "data-oods-component": "ColorSwatch",
2092
+ "data-summary-type": "color-swatch",
2093
+ "data-swatch-color": resolvedColor ?? "default",
2094
+ style: { "--oods-swatch-color": resolvedColor === "default" ? void 0 : resolvedColor, ...style },
2095
+ ...rest,
2096
+ children: [
2097
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-oods-swatch-chip": "true", "aria-hidden": "true" }),
2098
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-oods-swatch-label": "true", children: resolvedLabel }),
2099
+ content.authored ? children : null
2100
+ ]
2101
+ }
2102
+ );
2103
+ }
2104
+ );
2105
+ ColorSwatch.displayName = "OODS.ColorSwatch";
2106
+ var ColorizedBadge = React7__namespace.forwardRef(
2107
+ ({ label, text, state, value, status, color, hue, swatch, variant, tone, emphasis, children, className, style, ...rest }, ref) => {
2108
+ const content = childContent(children);
2109
+ const resolvedLabel = content.scalar ?? firstText(label, text, state, value) ?? "Color";
2110
+ const resolvedColor = firstText(color, hue, swatch, state);
2111
+ const resolvedStatus = firstText(status, state, value);
2112
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2113
+ Badge,
2114
+ {
2115
+ ref,
2116
+ status: resolvedStatus,
2117
+ tone,
2118
+ emphasis,
2119
+ className: classes7("oods-colorized-badge", className),
2120
+ "data-oods-component": "ColorizedBadge",
2121
+ "data-badge-status": resolvedStatus,
2122
+ "data-badge-color": resolvedColor,
2123
+ "data-badge-variant": firstText(variant) ?? "colorized",
2124
+ icon: /* @__PURE__ */ jsxRuntime.jsx("span", { "data-oods-badge-marker": "true", "aria-hidden": "true" }),
2125
+ style: { "--oods-badge-color": resolvedColor, ...style },
2126
+ ...rest,
2127
+ children: [
2128
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-oods-badge-label": "true", children: resolvedLabel }),
2129
+ content.authored ? children : null
2130
+ ]
2131
+ }
2132
+ );
2133
+ }
2134
+ );
2135
+ 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) => {
2138
+ const content = childContent(children);
2139
+ if (svg !== void 0) {
2140
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2141
+ "figure",
2142
+ {
2143
+ ref,
2144
+ className: classes7("oods-viz-area-preview", className),
2145
+ "data-oods-component": "VizAreaPreview",
2146
+ "data-viz-preview-type": "area",
2147
+ "data-viz-rendered": "true",
2148
+ "data-viz-width": width,
2149
+ "data-viz-height": height,
2150
+ "data-viz-narrow": svgNarrow !== void 0 ? "true" : void 0,
2151
+ "data-viz-wide": svgWide !== void 0 ? "true" : void 0,
2152
+ role: "img",
2153
+ "aria-label": title ?? description ?? "Payment amounts",
2154
+ style: { "--oods-viz-width": `${width}px`, ...style },
2155
+ ...rest,
2156
+ children: [
2157
+ 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,
2161
+ description ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-viz-description": "true", children: description }) : null
2162
+ ]
2163
+ }
2164
+ );
2165
+ }
2166
+ return /* @__PURE__ */ jsxRuntime.jsx(
2167
+ "div",
2168
+ {
2169
+ ref,
2170
+ className: classes7("oods-viz-area-preview", className),
2171
+ "data-oods-component": "VizAreaPreview",
2172
+ "data-viz-preview-type": "area",
2173
+ "data-viz-width": width,
2174
+ "data-viz-height": height,
2175
+ style: { "--oods-viz-width": `${width}px`, "--oods-viz-height": `${height}px`, ...style },
2176
+ ...rest,
2177
+ children: content.authored || content.scalar !== void 0 ? children : /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-viz-preview-placeholder": "true", children: [
2178
+ "Area preview (",
2179
+ width,
2180
+ " x ",
2181
+ height,
2182
+ ")"
2183
+ ] })
2184
+ }
2185
+ );
2186
+ }
2187
+ );
2188
+ VizAreaPreview.displayName = "OODS.VizAreaPreview";
2189
+ var firstScalar = (...values) => {
2190
+ for (const value of values) {
2191
+ if (typeof value === "string") {
2192
+ if (value.trim().length > 0) return value;
2193
+ continue;
2194
+ }
2195
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
2196
+ }
2197
+ return void 0;
2198
+ };
2199
+ var isRecord2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
2200
+ var descriptorLabel = (descriptor) => firstText(
2201
+ typeof descriptor.label === "string" ? descriptor.label : void 0,
2202
+ typeof descriptor.field === "string" ? descriptor.field : void 0
2203
+ ) ?? "Filter";
2204
+ function createPanelSection(component, className, panelType, defaultTitle) {
2205
+ const Panel = React7__namespace.forwardRef(
2206
+ ({ title, label, heading, name, subtitle, description, metadata, summary: summary2, text, body, emptyMessage, children, className: consumerClassName, ...rest }, ref) => {
2207
+ const content = childContent(children);
2208
+ const authored = content.authored || content.scalar !== void 0;
2209
+ const resolvedTitle = firstText(title, label, heading, name) ?? defaultTitle;
2210
+ const resolvedSubtitle = firstText(subtitle, description, metadata);
2211
+ const fallback2 = firstText(summary2, text, body, emptyMessage);
2212
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2213
+ "section",
2214
+ {
2215
+ ref,
2216
+ className: classes7(className, consumerClassName),
2217
+ "data-oods-component": component,
2218
+ "data-panel-type": panelType,
2219
+ ...rest,
2220
+ children: [
2221
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { "data-panel-header": "true", children: [
2222
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: resolvedTitle }),
2223
+ resolvedSubtitle ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-panel-subtitle": "true", children: resolvedSubtitle }) : null
2224
+ ] }),
2225
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-panel-content": "true", children: authored ? children : fallback2 ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-panel-summary": "true", children: fallback2 }) : null })
2226
+ ]
2227
+ }
2228
+ );
2229
+ }
2230
+ );
2231
+ Panel.displayName = `OODS.${component}`;
2232
+ return Panel;
2233
+ }
2234
+ var ClassificationPanel = createPanelSection("ClassificationPanel", "oods-classification-panel", "classification", "Classification");
2235
+ var AddressCollectionPanel = createPanelSection("AddressCollectionPanel", "oods-address-collection-panel", "address", "Addresses");
2236
+ var MembershipPanel = createPanelSection("MembershipPanel", "oods-membership-panel", "membership", "Membership");
2237
+ var PreferencePanel = createPanelSection("PreferencePanel", "oods-preference-panel", "preference", "Preferences");
2238
+ var FilterPanel = React7__namespace.forwardRef(
2239
+ ({ filters, activeFilters, mode, collapsible = true, children, className, ...rest }, ref) => {
2240
+ const content = childContent(children);
2241
+ const authored = content.authored || content.scalar !== void 0;
2242
+ const resolvedMode = firstText(mode) ?? "immediate";
2243
+ const descriptors = (Array.isArray(filters) ? filters : []).filter(isRecord2);
2244
+ const activeCount = Array.isArray(activeFilters) ? activeFilters.length : 0;
2245
+ return /* @__PURE__ */ jsxRuntime.jsx(
2246
+ "aside",
2247
+ {
2248
+ ref,
2249
+ className: classes7("oods-filter-panel", className),
2250
+ "data-oods-component": "FilterPanel",
2251
+ "data-behavioral": "filter",
2252
+ "data-filter-mode": resolvedMode,
2253
+ role: "region",
2254
+ "aria-label": "Filters",
2255
+ ...rest,
2256
+ children: authored ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2257
+ activeCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-active-filters": "true", "aria-live": "polite", children: [
2258
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-filter-count": "true", children: [
2259
+ activeCount,
2260
+ " active"
2261
+ ] }),
2262
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", "data-filter-clear-all": "true", children: "Clear all" })
2263
+ ] }) : null,
2264
+ descriptors.map((descriptor, index) => /* @__PURE__ */ jsxRuntime.jsx("fieldset", { "data-filter-section": "true", "data-collapsible": collapsible ? "true" : void 0, children: /* @__PURE__ */ jsxRuntime.jsx("legend", { children: descriptorLabel(descriptor) }) }, index)),
2265
+ resolvedMode === "batch" ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", "data-filter-apply": "true", children: "Apply" }) : null
2266
+ ] })
2267
+ }
2268
+ );
2269
+ }
2270
+ );
2271
+ FilterPanel.displayName = "OODS.FilterPanel";
2272
+ var PriceSummary = React7__namespace.forwardRef(
2273
+ ({
2274
+ title,
2275
+ label,
2276
+ heading,
2277
+ name,
2278
+ amount,
2279
+ amountCents,
2280
+ unitAmountCents,
2281
+ minorUnits,
2282
+ currency,
2283
+ currencyCode,
2284
+ model,
2285
+ pricingModel,
2286
+ interval,
2287
+ billingInterval,
2288
+ summary: summary2,
2289
+ text,
2290
+ description,
2291
+ children,
2292
+ className,
2293
+ ...rest
2294
+ }, ref) => {
2295
+ const content = childContent(children);
2296
+ const authored = content.authored || content.scalar !== void 0;
2297
+ const resolvedTitle = firstText(title, label, heading, name) ?? "Price Summary";
2298
+ const entries = [
2299
+ ["Amount", [amount, amountCents, unitAmountCents, currency, currencyCode, model, pricingModel, interval, billingInterval].some((value) => value !== void 0) ? componentContracts.formatPriceAmount(amount ?? amountCents ?? unitAmountCents, firstText(currency, currencyCode), minorUnits) : void 0],
2300
+ ["Currency", firstScalar(currency, currencyCode)],
2301
+ ["Model", componentContracts.formatPriceCode(model ?? pricingModel)],
2302
+ ["Interval", componentContracts.formatPriceCode(interval ?? billingInterval)]
2303
+ ];
2304
+ const terms = entries.filter((entry) => entry[1] !== void 0);
2305
+ const fallback2 = firstText(summary2, text, description);
2306
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2307
+ "section",
2308
+ {
2309
+ ref,
2310
+ className: classes7("oods-price-summary", className),
2311
+ "data-oods-component": "PriceSummary",
2312
+ "data-summary-type": "price",
2313
+ ...rest,
2314
+ children: [
2315
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-summary-title": "true", children: resolvedTitle }),
2316
+ authored ? children : terms.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("dl", { children: terms.map(([term, value]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-summary-item": "true", children: [
2317
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: term }),
2318
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: value })
2319
+ ] }, term)) }) : fallback2 ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-summary-fallback": "true", children: fallback2 }) : /* @__PURE__ */ jsxRuntime.jsx("dl", {})
2320
+ ]
2321
+ }
2322
+ );
2323
+ }
2324
+ );
2325
+ PriceSummary.displayName = "OODS.PriceSummary";
2326
+ var normalizeTagItems = (value) => {
2327
+ if (!Array.isArray(value)) return [];
2328
+ const items = [];
2329
+ for (const entry of value) {
2330
+ if (entry === void 0 || entry === null) continue;
2331
+ if (isRecord2(entry)) {
2332
+ const text = firstScalar(
2333
+ ...["label", "name", "role", "value", "id"].map((key) => {
2334
+ const candidate = entry[key];
2335
+ return typeof candidate === "string" || typeof candidate === "number" || typeof candidate === "boolean" ? candidate : void 0;
2336
+ })
2337
+ );
2338
+ if (text) items.push(text);
2339
+ continue;
2340
+ }
2341
+ items.push(typeof entry === "object" ? JSON.stringify(entry) : String(entry));
2342
+ }
2343
+ return items.filter((item) => item.length > 0);
2344
+ };
2345
+ var TagManager = React7__namespace.forwardRef(
2346
+ ({ title, label, heading, name, description, subtitle, hint, tags, value, children, className, onSubmit, ...rest }, ref) => {
2347
+ const content = childContent(children);
2348
+ const authored = content.authored || content.scalar !== void 0;
2349
+ const resolvedTitle = firstText(title, label, heading, name) ?? "Tag Manager";
2350
+ const resolvedSubtitle = firstText(description, subtitle, hint);
2351
+ const items = normalizeTagItems(tags ?? value);
2352
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2353
+ "form",
2354
+ {
2355
+ ref,
2356
+ className: classes7("oods-tag-manager", className),
2357
+ "data-oods-component": "TagManager",
2358
+ "data-form-type": "tag-manager",
2359
+ onSubmit: (event) => {
2360
+ event.preventDefault();
2361
+ onSubmit?.(event);
2362
+ },
2363
+ ...rest,
2364
+ children: [
2365
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { "data-form-header": "true", children: [
2366
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: resolvedTitle }),
2367
+ resolvedSubtitle ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-form-subtitle": "true", children: resolvedSubtitle }) : null
2368
+ ] }),
2369
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-form-content": "true", children: authored ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2370
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-tag-list": "true", children: items.map((tag, index) => /* @__PURE__ */ jsxRuntime.jsx("span", { "data-tag-item": "true", children: tag }, index)) }),
2371
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-form-control": "input", children: [
2372
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Add Tag" }),
2373
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "text", name: "newTag", placeholder: "Type a tag" })
2374
+ ] })
2375
+ ] }) })
2376
+ ]
2377
+ }
2378
+ );
2379
+ }
2380
+ );
2381
+ TagManager.displayName = "OODS.TagManager";
2382
+ var asCount = (value) => {
2383
+ if (typeof value === "number" && Number.isFinite(value)) return value;
2384
+ if (typeof value === "string" && value.trim().length > 0) {
2385
+ const parsed = Number.parseInt(value, 10);
2386
+ if (Number.isFinite(parsed)) return parsed;
2387
+ }
2388
+ return void 0;
2389
+ };
2390
+ function createBadgeFamily(options) {
2391
+ const consumed = /* @__PURE__ */ new Set([...options.labelKeys, ...options.statusKeys, "variant", "tone", "emphasis"]);
2392
+ const Family = React7__namespace.forwardRef((allProps, ref) => {
2393
+ const { children, className, ...rest } = allProps;
2394
+ const record = rest;
2395
+ const scalar = (key) => {
2396
+ const value = record[key];
2397
+ if (typeof value === "boolean" && options.booleanProps?.includes(key)) return String(value);
2398
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
2399
+ };
2400
+ const content = childContent(children);
2401
+ const label = content.scalar ?? firstText(...options.labelKeys.map((key) => options.component === "CancellationBadge" && typeof record[key] === "boolean" && options.booleanProps?.includes(key) ? record[key] ? "Cancellation scheduled" : "No cancellation scheduled" : scalar(key))) ?? options.defaultLabel;
2402
+ const status = firstText(...options.statusKeys.map(scalar));
2403
+ const variant = scalar("variant") ?? options.defaultVariant;
2404
+ const tone = record.tone;
2405
+ const emphasis = record.emphasis;
2406
+ const domRest = {};
2407
+ for (const [key, value] of Object.entries(record)) if (!consumed.has(key)) domRest[key] = value;
2408
+ return /* @__PURE__ */ jsxRuntime.jsx(
2409
+ Badge,
2410
+ {
2411
+ ref,
2412
+ status,
2413
+ showIcon: false,
2414
+ tone,
2415
+ emphasis,
2416
+ className: classes7(options.className, className),
2417
+ "data-oods-component": options.component,
2418
+ "data-badge-status": status,
2419
+ "data-badge-variant": variant,
2420
+ ...domRest,
2421
+ children: content.authored ? children : /* @__PURE__ */ jsxRuntime.jsx("span", { "data-oods-badge-label": "true", children: label })
2422
+ }
2423
+ );
2424
+ });
2425
+ Family.displayName = `OODS.${options.component}`;
2426
+ return Family;
2427
+ }
2428
+ var AddressSummaryBadge = createBadgeFamily({
2429
+ component: "AddressSummaryBadge",
2430
+ className: "oods-address-summary-badge",
2431
+ defaultLabel: "Address",
2432
+ defaultVariant: "address",
2433
+ labelKeys: ["label", "text", "role", "value"],
2434
+ statusKeys: ["status", "state", "role"]
2435
+ });
2436
+ var MessageStatusBadge = createBadgeFamily({
2437
+ component: "MessageStatusBadge",
2438
+ className: "oods-message-status-badge",
2439
+ defaultLabel: "Message",
2440
+ defaultVariant: "message",
2441
+ labelKeys: ["label", "text", "status", "delivery", "value"],
2442
+ statusKeys: ["status", "state", "delivery", "value"]
2443
+ });
2444
+ var PreferenceSummaryBadge = createBadgeFamily({
2445
+ component: "PreferenceSummaryBadge",
2446
+ className: "oods-preference-summary-badge",
2447
+ defaultLabel: "Preferences",
2448
+ defaultVariant: "preference",
2449
+ labelKeys: ["label", "text", "namespace", "value"],
2450
+ statusKeys: ["status", "state", "version"]
2451
+ });
2452
+ var RoleBadgeList = React7__namespace.forwardRef(
2453
+ ({ roles, badges, roleLabels, value, variant, tone, label, text, children, className, ...rest }, ref) => {
2454
+ const content = childContent(children);
2455
+ const authored = content.authored || content.scalar !== void 0;
2456
+ const items = normalizeTagItems(roles ?? badges ?? roleLabels ?? value);
2457
+ const resolvedVariant = firstText(variant, tone) ?? "roles";
2458
+ return /* @__PURE__ */ jsxRuntime.jsx(
2459
+ "span",
2460
+ {
2461
+ ref,
2462
+ className: classes7("oods-role-badge-list", className),
2463
+ "data-oods-component": "RoleBadgeList",
2464
+ "data-badge-variant": resolvedVariant,
2465
+ ...rest,
2466
+ children: authored ? children : items.length > 0 ? items.map((role, index) => /* @__PURE__ */ jsxRuntime.jsx("span", { "data-role-badge": "true", children: role }, index)) : firstText(label, text) ?? "Roles"
2467
+ }
2468
+ );
2469
+ }
2470
+ );
2471
+ RoleBadgeList.displayName = "OODS.RoleBadgeList";
2472
+ var TagPills = React7__namespace.forwardRef(
2473
+ ({ tags, value, maxVisible, overflowLabel, children, className, ...rest }, ref) => {
2474
+ const content = childContent(children);
2475
+ const authored = content.authored || content.scalar !== void 0;
2476
+ const items = normalizeTagItems(tags ?? value);
2477
+ const limit = asCount(maxVisible) ?? items.length;
2478
+ const visible = items.slice(0, Math.max(0, limit));
2479
+ const overflow = items.length - visible.length;
2480
+ const template = firstText(overflowLabel);
2481
+ const overflowText = overflow > 0 ? template ? template.replace("{{ tag_count }}", String(items.length)) : `+${overflow}` : "";
2482
+ return /* @__PURE__ */ jsxRuntime.jsx(
2483
+ "div",
2484
+ {
2485
+ ref,
2486
+ className: classes7("oods-tag-pills", className),
2487
+ "data-oods-component": "TagPills",
2488
+ "data-summary-type": "tag-pills",
2489
+ ...rest,
2490
+ children: authored ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2491
+ visible.map((tag, index) => /* @__PURE__ */ jsxRuntime.jsx("span", { "data-tag-pill": "true", children: tag }, index)),
2492
+ overflowText ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-tag-overflow": "true", children: overflowText }) : null
2493
+ ] })
2494
+ }
2495
+ );
2496
+ }
2497
+ );
2498
+ TagPills.displayName = "OODS.TagPills";
2499
+ var normalizeTimelineItems = (raw) => {
2500
+ if (!Array.isArray(raw)) return [];
2501
+ const items = [];
2502
+ const read = (record, keys) => firstScalar(
2503
+ ...keys.map((key) => {
2504
+ const value = record[key];
2505
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? value : void 0;
2506
+ })
2507
+ );
2508
+ for (const entry of raw) {
2509
+ if (entry === void 0 || entry === null) continue;
2510
+ if (isRecord2(entry)) {
2511
+ items.push({
2512
+ label: read(entry, ["label", "title", "event", "status", "state", "text", "name"]) ?? "Event",
2513
+ timestamp: read(entry, ["timestamp", "datetime", "time", "at", "createdAt", "updatedAt"]),
2514
+ detail: read(entry, ["detail", "description", "reason", "message", "from", "to"])
2515
+ });
2516
+ continue;
2517
+ }
2518
+ items.push({ label: typeof entry === "object" ? JSON.stringify(entry) : String(entry) });
2519
+ }
2520
+ return items;
2521
+ };
2522
+ function createTimelineFamily(options) {
2523
+ const consumed = /* @__PURE__ */ new Set(["title", "label", "heading", "name", ...options.eventKeys]);
2524
+ const Family = React7__namespace.forwardRef((allProps, ref) => {
2525
+ const { children, className, ...rest } = allProps;
2526
+ const record = rest;
2527
+ const text = (key) => {
2528
+ const value = record[key];
2529
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
2530
+ };
2531
+ const content = childContent(children);
2532
+ const authored = content.authored || content.scalar !== void 0;
2533
+ const title = firstText(text("title"), text("label"), text("heading"), text("name")) ?? options.defaultTitle;
2534
+ const events = normalizeTimelineItems(options.eventKeys.map((key) => record[key]).find((value) => Array.isArray(value)));
2535
+ const domRest = {};
2536
+ for (const [key, value] of Object.entries(record)) if (!consumed.has(key)) domRest[key] = value;
2537
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2538
+ "div",
2539
+ {
2540
+ ref,
2541
+ className: classes7(options.className, className),
2542
+ "data-oods-component": options.component,
2543
+ "data-timeline-type": options.timelineType,
2544
+ role: "log",
2545
+ "aria-label": title,
2546
+ ...domRest,
2547
+ children: [
2548
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-timeline-title": "true", children: title }),
2549
+ /* @__PURE__ */ jsxRuntime.jsx("ol", { "data-timeline-events": "true", children: authored ? children : events.length > 0 ? events.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs("article", { "data-timeline-event": "true", children: [
2550
+ /* @__PURE__ */ jsxRuntime.jsx("p", { "data-timeline-label": "true", children: item.label }),
2551
+ item.timestamp ? /* @__PURE__ */ jsxRuntime.jsx("time", { "data-timeline-time": "true", dateTime: item.timestamp, children: item.timestamp }) : null,
2552
+ item.detail ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-timeline-detail": "true", children: item.detail }) : null
2553
+ ] }) }, index)) : /* @__PURE__ */ jsxRuntime.jsx("li", { "data-timeline-empty": "true", children: "No events" }) })
2554
+ ]
2555
+ }
2556
+ );
2557
+ });
2558
+ Family.displayName = `OODS.${options.component}`;
2559
+ return Family;
2560
+ }
2561
+ var AddressValidationTimeline = createTimelineFamily({
2562
+ component: "AddressValidationTimeline",
2563
+ className: "oods-address-validation-timeline",
2564
+ defaultTitle: "Address Validation Timeline",
2565
+ timelineType: "address-validation",
2566
+ eventKeys: ["events", "validations", "history"]
2567
+ });
2568
+ var MembershipAuditTimeline = createTimelineFamily({
2569
+ component: "MembershipAuditTimeline",
2570
+ className: "oods-membership-audit-timeline",
2571
+ defaultTitle: "Membership Timeline",
2572
+ timelineType: "membership",
2573
+ eventKeys: ["events", "memberships", "history"]
2574
+ });
2575
+ var MessageEventTimeline = createTimelineFamily({
2576
+ component: "MessageEventTimeline",
2577
+ className: "oods-message-event-timeline",
2578
+ defaultTitle: "Message Timeline",
2579
+ timelineType: "message",
2580
+ eventKeys: ["events", "messages", "statuses"]
2581
+ });
2582
+ var PreferenceTimeline = createTimelineFamily({
2583
+ component: "PreferenceTimeline",
2584
+ className: "oods-preference-timeline",
2585
+ defaultTitle: "Preference Timeline",
2586
+ timelineType: "preference",
2587
+ eventKeys: ["events", "changes", "history"]
2588
+ });
2589
+ var AuditEvent = React7__namespace.forwardRef(
2590
+ ({
2591
+ label,
2592
+ title,
2593
+ event,
2594
+ status,
2595
+ state,
2596
+ reason,
2597
+ text,
2598
+ timestamp,
2599
+ datetime,
2600
+ time,
2601
+ at,
2602
+ createdAt,
2603
+ updatedAt,
2604
+ detail,
2605
+ description,
2606
+ message,
2607
+ from,
2608
+ to,
2609
+ code,
2610
+ children,
2611
+ className,
2612
+ ...rest
2613
+ }, ref) => {
2614
+ const content = childContent(children);
2615
+ const authored = content.authored || content.scalar !== void 0;
2616
+ const resolvedLabel = firstText(label, title, event, status, state, reason, text) ?? "Audit Event";
2617
+ const resolvedTimestamp = firstText(timestamp, datetime, time, at, createdAt, updatedAt);
2618
+ const resolvedDetail = firstText(detail, description, reason, message, from, to, code);
2619
+ return /* @__PURE__ */ jsxRuntime.jsx(
2620
+ "article",
2621
+ {
2622
+ ref,
2623
+ className: classes7("oods-audit-event", className),
2624
+ "data-oods-component": "AuditEvent",
2625
+ "data-event-type": "audit",
2626
+ ...rest,
2627
+ children: authored ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2628
+ resolvedTimestamp ? /* @__PURE__ */ jsxRuntime.jsx("time", { "data-event-time": "true", dateTime: resolvedTimestamp, children: resolvedTimestamp }) : null,
2629
+ /* @__PURE__ */ jsxRuntime.jsx("p", { "data-event-label": "true", children: resolvedLabel }),
2630
+ resolvedDetail ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-event-detail": "true", children: resolvedDetail }) : null
2631
+ ] })
2632
+ }
2633
+ );
2634
+ }
2635
+ );
2636
+ AuditEvent.displayName = "OODS.AuditEvent";
2637
+ var normalizeSelectOptions = (raw) => {
2638
+ if (!Array.isArray(raw)) return [];
2639
+ const choices = [];
2640
+ for (const entry of raw) {
2641
+ if (isRecord2(entry)) {
2642
+ const text = (key) => typeof entry[key] === "string" && entry[key].length > 0 ? entry[key] : void 0;
2643
+ const value2 = text("value") ?? text("id") ?? text("label") ?? "";
2644
+ const label = text("label") ?? text("name") ?? componentContracts.formatReadOnlyValue(value2, "string", true);
2645
+ if (!value2 && !label) continue;
2646
+ choices.push({ value: value2, label });
2647
+ continue;
2648
+ }
2649
+ if (entry === void 0 || entry === null) continue;
2650
+ const value = typeof entry === "object" ? JSON.stringify(entry) : String(entry);
2651
+ if (!value) continue;
2652
+ choices.push({ value, label: componentContracts.formatReadOnlyValue(value, "string", true) });
2653
+ }
2654
+ return choices;
2655
+ };
2656
+ var selectOptionsMarkup = (choices) => choices.length > 0 ? choices.map((choice, index) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: choice.value, children: choice.label }, index)) : /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select..." });
2657
+ var preventSubmit = (event) => {
2658
+ event.preventDefault();
2659
+ };
2660
+ var formHeader = (title, subtitle) => /* @__PURE__ */ jsxRuntime.jsxs("header", { "data-form-header": "true", children: [
2661
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: title }),
2662
+ subtitle ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-form-subtitle": "true", children: subtitle }) : null
2663
+ ] });
2664
+ var fieldsetHeader = (title, subtitle) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2665
+ /* @__PURE__ */ jsxRuntime.jsx("legend", { children: title }),
2666
+ subtitle ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-form-subtitle": "true", children: subtitle }) : null
2667
+ ] });
2668
+ var addressRecord = (form) => {
2669
+ const read = (name) => {
2670
+ const control = form?.elements.namedItem(name);
2671
+ return control instanceof HTMLInputElement ? control.value : "";
2672
+ };
2673
+ return { street: read("street"), city: read("city"), region: read("region"), postalCode: read("postalCode") };
2674
+ };
2675
+ var AddressEditor = React7__namespace.forwardRef(
2676
+ ({
2677
+ title,
2678
+ label,
2679
+ heading,
2680
+ name,
2681
+ description,
2682
+ subtitle,
2683
+ hint,
2684
+ street,
2685
+ line1,
2686
+ addressLine1,
2687
+ city,
2688
+ region,
2689
+ state,
2690
+ postalCode,
2691
+ zip,
2692
+ children,
2693
+ className,
2694
+ onChange,
2695
+ onSubmit,
2696
+ ...rest
2697
+ }, ref) => {
2698
+ const content = childContent(children);
2699
+ const authored = content.authored || content.scalar !== void 0;
2700
+ const resolvedTitle = firstText(title, label, heading, name) ?? "Address Editor";
2701
+ const resolvedSubtitle = firstText(description, subtitle, hint);
2702
+ const publish = (event) => onChange?.(addressRecord(event.currentTarget.form));
2703
+ const control = (fieldLabel, fieldName, initial) => /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-form-control": "input", children: [
2704
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: fieldLabel }),
2705
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "text", name: fieldName, defaultValue: initial, onChange: publish })
2706
+ ] });
2707
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2708
+ "form",
2709
+ {
2710
+ ref,
2711
+ className: classes7("oods-address-editor", className),
2712
+ "data-oods-component": "AddressEditor",
2713
+ "data-form-type": "address-editor",
2714
+ onSubmit: (event) => {
2715
+ preventSubmit(event);
2716
+ onSubmit?.(event);
2717
+ },
2718
+ ...rest,
2719
+ children: [
2720
+ formHeader(resolvedTitle, resolvedSubtitle),
2721
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-form-content": "true", children: authored ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2722
+ control("Street", "street", firstText(street, line1, addressLine1)),
2723
+ control("City", "city", firstText(city)),
2724
+ control("Region", "region", firstText(region, state)),
2725
+ control("Postal Code", "postalCode", firstText(postalCode, zip))
2726
+ ] }) })
2727
+ ]
2728
+ }
2729
+ );
2730
+ }
2731
+ );
2732
+ AddressEditor.displayName = "OODS.AddressEditor";
2733
+ var PreferenceEditor = React7__namespace.forwardRef(
2734
+ ({ title, label, heading, name, description, subtitle, hint, namespaces, namespace, document, json, value, children, className, onSubmit, ...rest }, ref) => {
2735
+ const content = childContent(children);
2736
+ const authored = content.authored || content.scalar !== void 0;
2737
+ const resolvedTitle = firstText(title, label, heading, name) ?? "Preference Editor";
2738
+ const resolvedSubtitle = firstText(description, subtitle, hint);
2739
+ const choices = normalizeSelectOptions(Array.isArray(namespaces) ? namespaces : ["default"]);
2740
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2741
+ "form",
2742
+ {
2743
+ ref,
2744
+ className: classes7("oods-preference-editor", className),
2745
+ "data-oods-component": "PreferenceEditor",
2746
+ "data-form-type": "preference-editor",
2747
+ onSubmit: (event) => {
2748
+ preventSubmit(event);
2749
+ onSubmit?.(event);
2750
+ },
2751
+ ...rest,
2752
+ children: [
2753
+ formHeader(resolvedTitle, resolvedSubtitle),
2754
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-form-content": "true", children: authored ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2755
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-form-control": "select", children: [
2756
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Namespace" }),
2757
+ /* @__PURE__ */ jsxRuntime.jsx("select", { name: "namespace", defaultValue: firstText(namespace), children: selectOptionsMarkup(choices) })
2758
+ ] }),
2759
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-form-control": "textarea", children: [
2760
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Preference Document" }),
2761
+ /* @__PURE__ */ jsxRuntime.jsx("textarea", { name: "preferenceDocument", defaultValue: firstScalar(document, json, value) ?? "" })
2762
+ ] })
2763
+ ] }) })
2764
+ ]
2765
+ }
2766
+ );
2767
+ }
2768
+ );
2769
+ PreferenceEditor.displayName = "OODS.PreferenceEditor";
2770
+ var RoleAssignmentForm = React7__namespace.forwardRef(
2771
+ ({ title, label, heading, name, description, subtitle, hint, roles, availableRoles, role, defaultRoleId, assignee, member, children, className, onSubmit, ...rest }, ref) => {
2772
+ const content = childContent(children);
2773
+ const authored = content.authored || content.scalar !== void 0;
2774
+ const resolvedTitle = firstText(title, label, heading, name) ?? "Role Assignment";
2775
+ const resolvedSubtitle = firstText(description, subtitle, hint);
2776
+ const choices = normalizeSelectOptions(roles ?? availableRoles ?? []);
2777
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2778
+ "form",
2779
+ {
2780
+ ref,
2781
+ className: classes7("oods-role-assignment-form", className),
2782
+ "data-oods-component": "RoleAssignmentForm",
2783
+ "data-form-type": "role-assignment",
2784
+ onSubmit: (event) => {
2785
+ preventSubmit(event);
2786
+ onSubmit?.(event);
2787
+ },
2788
+ ...rest,
2789
+ children: [
2790
+ formHeader(resolvedTitle, resolvedSubtitle),
2791
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-form-content": "true", children: authored ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2792
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-form-control": "select", children: [
2793
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Role" }),
2794
+ /* @__PURE__ */ jsxRuntime.jsx("select", { name: "role", defaultValue: firstText(role, defaultRoleId), children: selectOptionsMarkup(choices) })
2795
+ ] }),
2796
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-form-control": "input", children: [
2797
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Assignee" }),
2798
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "text", name: "assignee", defaultValue: firstText(assignee, member) })
2799
+ ] })
2800
+ ] }) })
2801
+ ]
2802
+ }
2803
+ );
2804
+ }
2805
+ );
2806
+ RoleAssignmentForm.displayName = "OODS.RoleAssignmentForm";
2807
+ var StatusSelector = React7__namespace.forwardRef(
2808
+ ({ label, title, help, options, states, value, status, children, className, onChange, onValueChange, onUpdate, ...rest }, ref) => {
2809
+ const content = childContent(children);
2810
+ const authored = content.authored || content.scalar !== void 0;
2811
+ const resolvedLabel = firstText(label, title) ?? "Status";
2812
+ const choices = normalizeSelectOptions(options ?? states ?? ["draft", "active", "inactive"]);
2813
+ const handleChange = (event) => {
2814
+ onChange?.(event);
2815
+ if (!event.defaultPrevented) {
2816
+ onValueChange?.(event.currentTarget.value);
2817
+ onUpdate?.(event.currentTarget.value);
2818
+ }
2819
+ };
2820
+ const controlled = value !== void 0;
2821
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2822
+ "div",
2823
+ {
2824
+ ref,
2825
+ className: classes7("oods-status-selector", className),
2826
+ "data-oods-component": "StatusSelector",
2827
+ "data-summary-type": "status-selector",
2828
+ ...rest,
2829
+ children: [
2830
+ authored ? children : /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-form-control": "select", children: [
2831
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: resolvedLabel }),
2832
+ /* @__PURE__ */ jsxRuntime.jsx(
2833
+ "select",
2834
+ {
2835
+ name: "status",
2836
+ ...controlled ? { value } : { defaultValue: firstText(status) },
2837
+ onChange: handleChange,
2838
+ children: selectOptionsMarkup(choices)
2839
+ }
2840
+ )
2841
+ ] }),
2842
+ help && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oods-field-help", children: help })
2843
+ ]
2844
+ }
2845
+ );
2846
+ }
2847
+ );
2848
+ StatusSelector.displayName = "OODS.StatusSelector";
2849
+ var TagInput = React7__namespace.forwardRef(
2850
+ ({ title, label, heading, name, description, subtitle, hint, tags, value, placeholder, children, className, onChange, onValueChange, onUpdate, ...rest }, ref) => {
2851
+ const content = childContent(children);
2852
+ const authored = content.authored || content.scalar !== void 0;
2853
+ const resolvedTitle = firstText(title, label, heading, name) ?? "Tag Input";
2854
+ const resolvedSubtitle = firstText(description, subtitle, hint);
2855
+ const items = normalizeTagItems(tags);
2856
+ const handleChange = (event) => {
2857
+ onChange?.(event);
2858
+ if (!event.defaultPrevented) {
2859
+ onValueChange?.(event.currentTarget.value);
2860
+ onUpdate?.(event.currentTarget.value);
2861
+ }
2862
+ };
2863
+ const controlled = value !== void 0;
2864
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2865
+ "fieldset",
2866
+ {
2867
+ ref,
2868
+ className: classes7("oods-tag-input", className),
2869
+ "data-oods-component": "TagInput",
2870
+ "data-form-type": "tag-input",
2871
+ ...rest,
2872
+ children: [
2873
+ fieldsetHeader(resolvedTitle, resolvedSubtitle),
2874
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-form-content": "true", children: authored ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2875
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-form-control": "input", children: [
2876
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Tag" }),
2877
+ /* @__PURE__ */ jsxRuntime.jsx(
2878
+ "input",
2879
+ {
2880
+ type: "text",
2881
+ name: "tag",
2882
+ placeholder: firstText(placeholder),
2883
+ ...controlled ? { value } : {},
2884
+ onChange: handleChange
2885
+ }
2886
+ )
2887
+ ] }),
2888
+ items.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-tag-list": "true", children: items.map((tag, index) => /* @__PURE__ */ jsxRuntime.jsx("span", { "data-tag-item": "true", children: tag }, index)) }) : null
2889
+ ] }) })
2890
+ ]
2891
+ }
2892
+ );
2893
+ }
2894
+ );
2895
+ TagInput.displayName = "OODS.TagInput";
2896
+ var TemplatePicker = React7__namespace.forwardRef(
2897
+ ({ title, label, heading, name, description, subtitle, hint, templates, options, templateId, value, channels, channel, children, className, ...rest }, ref) => {
2898
+ const content = childContent(children);
2899
+ const authored = content.authored || content.scalar !== void 0;
2900
+ const resolvedTitle = firstText(title, label, heading, name) ?? "Template Picker";
2901
+ const resolvedSubtitle = firstText(description, subtitle, hint);
2902
+ const templateChoices = normalizeSelectOptions(templates ?? options ?? []);
2903
+ const channelChoices = normalizeSelectOptions(channels ?? ["email", "sms", "in_app"]);
2904
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2905
+ "fieldset",
2906
+ {
2907
+ ref,
2908
+ className: classes7("oods-template-picker", className),
2909
+ "data-oods-component": "TemplatePicker",
2910
+ "data-form-type": "template-picker",
2911
+ ...rest,
2912
+ children: [
2913
+ fieldsetHeader(resolvedTitle, resolvedSubtitle),
2914
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-form-content": "true", children: authored ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2915
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-form-control": "select", children: [
2916
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Template" }),
2917
+ /* @__PURE__ */ jsxRuntime.jsx("select", { name: "template", defaultValue: firstText(templateId, value), children: selectOptionsMarkup(templateChoices) })
2918
+ ] }),
2919
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-form-control": "select", children: [
2920
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Channel" }),
2921
+ /* @__PURE__ */ jsxRuntime.jsx("select", { name: "channel", defaultValue: firstText(channel), children: selectOptionsMarkup(channelChoices) })
2922
+ ] })
2923
+ ] }) })
2924
+ ]
2925
+ }
2926
+ );
2927
+ }
2928
+ );
2929
+ TemplatePicker.displayName = "OODS.TemplatePicker";
2930
+ var truncateLabel = (value, maxLength) => {
2931
+ const limit = typeof maxLength === "number" ? maxLength : Number(maxLength);
2932
+ return !Number.isFinite(limit) || limit <= 0 || value.length <= limit ? value : `${value.slice(0, Math.max(0, limit - 1)).trimEnd()}...`;
2933
+ };
2934
+ var InlineLabel = React7__namespace.forwardRef(
2935
+ ({ label, text, value, maxLength, children, className, ...rest }, ref) => {
2936
+ const content = childContent(children);
2937
+ 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
+ }
2939
+ );
2940
+ InlineLabel.displayName = "OODS.InlineLabel";
2941
+ var LabelCell = React7__namespace.forwardRef(
2942
+ ({ label, text, value, description, subtitle, sublabel, supporting, truncate, maxLength, children, className, ...rest }, ref) => {
2943
+ const content = childContent(children);
2944
+ const limit = truncate ? maxLength ?? 40 : maxLength;
2945
+ const primary = truncateLabel(firstText(label, text, value) ?? "", limit);
2946
+ const detail = notEcho(firstText(description, subtitle, sublabel, supporting), firstText(label, text, value));
2947
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { ref, className: classes7("oods-label-cell", className), "data-oods-component": "LabelCell", ...rest, children: content.authored || content.scalar !== void 0 ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2948
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-oods-label-cell-primary": "true", children: primary }),
2949
+ detail ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-oods-label-cell-description": "true", children: truncateLabel(detail, limit) }) : null
2950
+ ] }) });
2951
+ }
2952
+ );
2953
+ LabelCell.displayName = "OODS.LabelCell";
2954
+ var FormLabelGroup = React7__namespace.forwardRef(
2955
+ ({ label, text, title, placeholder, hint, description, htmlFor, for: forId, inputId, children, className, ...rest }, ref) => {
2956
+ const detail = firstText(placeholder, hint, description);
2957
+ return /* @__PURE__ */ jsxRuntime.jsxs("label", { ref, className: classes7("oods-form-label-group", className), "data-oods-component": "FormLabelGroup", htmlFor: htmlFor ?? forId ?? inputId, ...rest, children: [
2958
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-oods-form-label": "true", children: firstText(label, text, title) ?? "Label" }),
2959
+ children,
2960
+ detail ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-oods-form-hint": "true", children: detail }) : null
2961
+ ] });
2962
+ }
2963
+ );
2964
+ FormLabelGroup.displayName = "OODS.FormLabelGroup";
2965
+ var ClassificationBadge = createBadgeFamily({
2966
+ component: "ClassificationBadge",
2967
+ className: "oods-classification-badge",
2968
+ defaultLabel: "Classification",
2969
+ defaultVariant: "classification",
2970
+ labelKeys: ["label", "text", "category", "value"],
2971
+ statusKeys: ["status", "state", "mode"]
2972
+ });
2973
+ var ClassificationEditor = React7__namespace.forwardRef(
2974
+ ({ title, label, heading, name, description, subtitle, hint, category, primaryCategory, tags, modes, mode, classificationMode, children, className, onSubmit, ...rest }, ref) => {
2975
+ const content = childContent(children);
2976
+ const tagText = typeof tags === "string" ? tags : tags === void 0 ? "" : JSON.stringify(tags);
2977
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2978
+ "form",
2979
+ {
2980
+ ref,
2981
+ className: classes7("oods-classification-editor", className),
2982
+ "data-oods-component": "ClassificationEditor",
2983
+ "data-form-type": "classification-editor",
2984
+ onSubmit: (event) => {
2985
+ preventSubmit(event);
2986
+ onSubmit?.(event);
2987
+ },
2988
+ ...rest,
2989
+ children: [
2990
+ formHeader(firstText(title, label, heading, name) ?? "Classification Editor", firstText(description, subtitle, hint)),
2991
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-form-content": "true", children: content.authored || content.scalar !== void 0 ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2992
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-form-control": "input", children: [
2993
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Category" }),
2994
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "text", name: "category", defaultValue: firstText(category, primaryCategory) ?? "" })
2995
+ ] }),
2996
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-form-control": "input", children: [
2997
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Tags" }),
2998
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type: "text", name: "tags", placeholder: "tag-1, tag-2", defaultValue: tagText })
2999
+ ] }),
3000
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-form-control": "select", children: [
3001
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Mode" }),
3002
+ /* @__PURE__ */ jsxRuntime.jsx("select", { name: "mode", defaultValue: firstText(mode, classificationMode), children: selectOptionsMarkup(normalizeSelectOptions(Array.isArray(modes) ? modes : ["strict", "flexible"])) })
3003
+ ] })
3004
+ ] }) })
3005
+ ]
3006
+ }
3007
+ );
3008
+ }
3009
+ );
3010
+ ClassificationEditor.displayName = "OODS.ClassificationEditor";
3011
+ var OwnerBadge = createBadgeFamily({
3012
+ component: "OwnerBadge",
3013
+ className: "oods-owner-badge",
3014
+ defaultLabel: "Owner",
3015
+ defaultVariant: "owner",
3016
+ labelKeys: ["label", "text", "owner", "ownerType", "value"],
3017
+ statusKeys: ["status", "state"]
3018
+ });
3019
+ var OwnershipSummary = React7__namespace.forwardRef(
3020
+ ({ title, label, heading, name, ownerLabel, ownerId, owner_id, ownerType, owner_type, role, ownershipRole, summary: summary2, text, description, children, className, ...rest }, ref) => {
3021
+ const content = childContent(children);
3022
+ 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);
3024
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { ref, className: classes7("oods-ownership-summary", className), "data-oods-component": "OwnershipSummary", "data-summary-type": "ownership", ...rest, children: [
3025
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-summary-title": "true", children: firstText(title, label, heading, name) ?? "Ownership Summary" }),
3026
+ 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
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: term }),
3028
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: value })
3029
+ ] }, term)) }) : fallback2 ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-summary-fallback": "true", children: fallback2 }) : /* @__PURE__ */ jsxRuntime.jsx("dl", {})
3030
+ ] });
3031
+ }
3032
+ );
3033
+ OwnershipSummary.displayName = "OODS.OwnershipSummary";
3034
+ var TagSummary = React7__namespace.forwardRef(
3035
+ ({ title, label, heading, name, tagCount, count, tags, summary: summary2, text, description, children, className, ...rest }, ref) => {
3036
+ const content = childContent(children);
3037
+ const tagText = Array.isArray(tags) ? normalizeTagItems(tags).join(", ") || void 0 : firstText(tags);
3038
+ const terms = [["Tag Count", firstScalar(tagCount, count)], ["Tags", tagText]].filter((entry) => entry[1] !== void 0);
3039
+ const fallback2 = firstText(summary2, text, description);
3040
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { ref, className: classes7("oods-tags-summary", className), "data-oods-component": "TagSummary", "data-summary-type": "tags", ...rest, children: [
3041
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-summary-title": "true", children: firstText(title, label, heading, name) ?? "Tag Summary" }),
3042
+ 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
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: term }),
3044
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: value })
3045
+ ] }, term)) }) : fallback2 ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-summary-fallback": "true", children: fallback2 }) : /* @__PURE__ */ jsxRuntime.jsx("dl", {})
3046
+ ] });
3047
+ }
3048
+ );
3049
+ TagSummary.displayName = "OODS.TagSummary";
3050
+ var OwnershipMeta = React7__namespace.forwardRef(
3051
+ ({ title, label, heading, name, ownerType, owner_type, role, ownershipRole, children, className, ...rest }, ref) => {
3052
+ const content = childContent(children);
3053
+ const terms = [["Owner Type", firstScalar(ownerType, owner_type)], ["Role", firstScalar(role, ownershipRole)]].filter((entry) => entry[1] !== void 0);
3054
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: classes7("oods-ownership-meta", className), "data-oods-component": "OwnershipMeta", "data-meta-type": "ownership", ...rest, children: content.authored || content.scalar !== void 0 ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3055
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-meta-title": "true", children: firstText(title, label, heading, name) ?? "Ownership" }),
3056
+ terms.map(([term, value]) => /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-meta-item": "true", children: [
3057
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { children: [
3058
+ term,
3059
+ ":"
3060
+ ] }),
3061
+ " ",
3062
+ value
3063
+ ] }, term))
3064
+ ] }) });
3065
+ }
3066
+ );
3067
+ OwnershipMeta.displayName = "OODS.OwnershipMeta";
3068
+ var ArchivePill = createBadgeFamily({
3069
+ component: "ArchivePill",
3070
+ className: "oods-archive-pill",
3071
+ defaultLabel: "Archive",
3072
+ defaultVariant: "archive",
3073
+ labelKeys: ["label", "text", "status", "state", "isArchived", "value"],
3074
+ statusKeys: ["status", "state", "isArchived", "value"],
3075
+ booleanProps: ["isArchived", "value"]
3076
+ });
3077
+ var CancellationBadge = createBadgeFamily({
3078
+ component: "CancellationBadge",
3079
+ className: "oods-cancellation-badge",
3080
+ defaultLabel: "Cancellation",
3081
+ defaultVariant: "cancellation",
3082
+ labelKeys: ["label", "text", "status", "state", "cancelAtPeriodEnd", "value"],
3083
+ statusKeys: ["status", "state", "cancelAtPeriodEnd", "isCancelled", "value"],
3084
+ booleanProps: ["cancelAtPeriodEnd", "isCancelled", "value"]
3085
+ });
3086
+ var ArchiveSummary = React7__namespace.forwardRef(
3087
+ ({ title, label, heading, name, isArchived, archived, status, archivedAt, reason, archiveReason, summary: summary2, text, description, children, className, ...rest }, ref) => {
3088
+ const content = childContent(children);
3089
+ 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);
3090
+ const fallback2 = firstText(summary2, text, description);
3091
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { ref, className: classes7("oods-archive-summary", className), "data-oods-component": "ArchiveSummary", "data-summary-type": "archive", ...rest, children: [
3092
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { "data-summary-title": "true", children: firstText(title, label, heading, name) ?? "Archive Summary" }),
3093
+ 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: [
3094
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: term }),
3095
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: value })
3096
+ ] }, term)) }) : fallback2 ? /* @__PURE__ */ jsxRuntime.jsx("p", { "data-summary-fallback": "true", children: fallback2 }) : /* @__PURE__ */ jsxRuntime.jsx("dl", {})
3097
+ ] });
3098
+ }
3099
+ );
3100
+ ArchiveSummary.displayName = "OODS.ArchiveSummary";
3101
+ var PriceCardMeta = React7__namespace.forwardRef(
3102
+ ({ title, label, heading, name, model, pricingModel, interval, billingInterval, children, className, ...rest }, ref) => {
3103
+ const content = childContent(children);
3104
+ const terms = [["Model", firstText(model, pricingModel)], ["Interval", firstText(interval, billingInterval)]].filter((entry) => entry[1] !== void 0);
3105
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: classes7("oods-price-card-meta", className), "data-oods-component": "PriceCardMeta", "data-meta-type": "price", ...rest, children: content.authored || content.scalar !== void 0 ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3106
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-meta-title": "true", children: firstText(title, label, heading, name) ?? "Price" }),
3107
+ terms.map(([term, value]) => /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-meta-item": "true", children: [
3108
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { children: [
3109
+ term,
3110
+ ":"
3111
+ ] }),
3112
+ " ",
3113
+ value
3114
+ ] }, term))
3115
+ ] }) });
3116
+ }
3117
+ );
3118
+ PriceCardMeta.displayName = "OODS.PriceCardMeta";
3119
+ var CancellationForm = React7__namespace.forwardRef(
3120
+ ({ title, label, heading, name, description, subtitle, hint, allowedReasons, reasonCode, reason, cancellationReason, embedded, reasonHelp, codeHelp, children, className, onSubmit, ...rest }, ref) => {
3121
+ const content = childContent(children);
3122
+ const choices = normalizeSelectOptions(allowedReasons ?? ["no_longer_needed", "budget", "duplicate"]);
3123
+ if (reasonCode && !choices.some((choice) => choice.value === reasonCode)) choices.unshift({ value: reasonCode, label: reasonCode });
3124
+ return React7__namespace.createElement(embedded ? "fieldset" : "form", {
3125
+ ...rest,
3126
+ ref,
3127
+ className: classes7("oods-cancellation-form", className),
3128
+ "data-oods-component": "CancellationForm",
3129
+ "data-form-type": "cancellation",
3130
+ ...!embedded ? { onSubmit: (event) => {
3131
+ preventSubmit(event);
3132
+ onSubmit?.(event);
3133
+ } } : {}
3134
+ }, /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3135
+ formHeader(firstText(title, label, heading, name) ?? "Cancellation Form", firstText(description, subtitle, hint)),
3136
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-form-content": "true", children: content.authored || content.scalar !== void 0 ? children : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3137
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-form-control": "select", children: [
3138
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Reason Code" }),
3139
+ allowedReasons?.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("input", { name: "reasonCode", defaultValue: reasonCode ?? "" }) : /* @__PURE__ */ jsxRuntime.jsx("select", { name: "reasonCode", defaultValue: reasonCode, children: selectOptionsMarkup(choices) })
3140
+ ] }),
3141
+ codeHelp && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oods-field-help", children: codeHelp }),
3142
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { "data-form-control": "textarea", children: [
3143
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Reason" }),
3144
+ /* @__PURE__ */ jsxRuntime.jsx("textarea", { name: "reason", defaultValue: firstText(reason, cancellationReason) ?? "" })
3145
+ ] }),
3146
+ reasonHelp && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oods-field-help", children: reasonHelp })
3147
+ ] }) })
3148
+ ] }));
3149
+ }
3150
+ );
3151
+ CancellationForm.displayName = "OODS.CancellationForm";
3152
+ function BillingSummaryBadge({ id, amount, currency, minorUnits, interval, showInterval = true, className }) {
3153
+ 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) });
3154
+ }
3155
+ function BillingAmountInput({ id, amount, currency = "usd", minorUnits = componentContracts.BILLING_MINOR_UNITS, label = "Billing amount", name, disabled, className, help, onChange }) {
3156
+ const generatedId = React7__namespace.useId();
3157
+ const controlId = id ?? `billing-amount-${generatedId}`;
3158
+ const [text, setText] = React7__namespace.useState(() => componentContracts.billingAmountText(amount, minorUnits));
3159
+ const [error, setError] = React7__namespace.useState(() => componentContracts.billingAmountMessage(amount, minorUnits));
3160
+ React7__namespace.useEffect(() => {
3161
+ setText(componentContracts.billingAmountText(amount, minorUnits));
3162
+ setError(componentContracts.billingAmountMessage(amount, minorUnits));
3163
+ }, [amount, minorUnits]);
3164
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `oods-billing-field ${className ?? ""}`.trim(), "data-oods-component": "BillingAmountInput", "data-state": error ? "invalid" : "editing", children: [
3165
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: controlId, children: label }),
3166
+ /* @__PURE__ */ jsxRuntime.jsx("span", { id: `${controlId}-currency`, children: currency.toUpperCase() }),
3167
+ /* @__PURE__ */ jsxRuntime.jsx(
3168
+ "input",
3169
+ {
3170
+ id: controlId,
3171
+ name,
3172
+ type: "text",
3173
+ inputMode: "decimal",
3174
+ value: text,
3175
+ disabled,
3176
+ "data-billing-minor-units": minorUnits,
3177
+ "aria-invalid": error ? true : void 0,
3178
+ "aria-describedby": [`${controlId}-currency`, error && `${controlId}-error`].filter(Boolean).join(" "),
3179
+ onChange: (event) => {
3180
+ const next = event.currentTarget.value;
3181
+ const result = componentContracts.parseBillingAmount(next, minorUnits);
3182
+ event.currentTarget.setCustomValidity(result.valid ? "" : result.message);
3183
+ setText(next);
3184
+ setError(result.valid ? void 0 : result.message);
3185
+ if (result.valid) onChange?.(result.value);
3186
+ }
3187
+ }
3188
+ ),
3189
+ help && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oods-field-help", children: help }),
3190
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: `${controlId}-error`, role: "alert", children: error })
3191
+ ] });
3192
+ }
3193
+ function BillingIntervalSelector({ id, interval, intervals = componentContracts.BILLING_INTERVALS, label = "Billing interval", name, disabled, className, help, onChange }) {
3194
+ const generatedId = React7__namespace.useId();
3195
+ const controlId = id ?? `billing-interval-${generatedId}`;
3196
+ const [value, setValue] = React7__namespace.useState(interval ?? "");
3197
+ React7__namespace.useEffect(() => {
3198
+ setValue(interval ?? "");
3199
+ }, [interval]);
3200
+ const error = componentContracts.billingIntervalMessage(value || void 0, intervals);
3201
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `oods-billing-field ${className ?? ""}`.trim(), "data-oods-component": "BillingIntervalSelector", "data-state": error ? "invalid" : "editing", children: [
3202
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: controlId, children: label }),
3203
+ /* @__PURE__ */ jsxRuntime.jsxs(
3204
+ "select",
3205
+ {
3206
+ id: controlId,
3207
+ name,
3208
+ value,
3209
+ disabled,
3210
+ "aria-invalid": error ? true : void 0,
3211
+ "aria-describedby": error ? `${controlId}-error` : void 0,
3212
+ onChange: (event) => {
3213
+ const next = event.currentTarget.value;
3214
+ if (intervals.includes(next)) {
3215
+ setValue(next);
3216
+ onChange?.(next);
3217
+ }
3218
+ },
3219
+ children: [
3220
+ !intervals.includes(value) && /* @__PURE__ */ jsxRuntime.jsx("option", { value, disabled: true, children: value || "Choose interval" }),
3221
+ intervals.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option, children: componentContracts.formatReadOnlyValue(option, "string", true) }, option))
3222
+ ]
3223
+ }
3224
+ ),
3225
+ help && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oods-field-help", children: help }),
3226
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: `${controlId}-error`, role: "alert", children: error })
3227
+ ] });
3228
+ }
3229
+ function CycleProgressCard({ id, title = "Billing cycle", ...values }) {
3230
+ const cycle = componentContracts.billingCycle(values);
3231
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { id, className: "oods-billing-cycle", "data-oods-component": "CycleProgressCard", "aria-label": title, children: [
3232
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: title }),
3233
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: cycle.announcement }),
3234
+ cycle.percent !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("progress", { max: 100, value: cycle.percent, "aria-label": cycle.announcement }),
3235
+ values.interval && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oods-billing-muted", children: values.interval })
3236
+ ] });
3237
+ }
3238
+ function BillingTimeline({ id, title, component, includeMethod, ...values }) {
3239
+ const heading = title ?? (includeMethod ? "Payments" : "Payment events");
3240
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { id, className: "oods-payment-timeline", "data-oods-component": component, role: "log", "aria-label": heading, children: [
3241
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: heading }),
3242
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: componentContracts.billingPaymentSummary(values) }),
3243
+ includeMethod && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oods-billing-muted", children: `Payment method: ${values.paymentMethod ?? "Not provided"}` }),
3244
+ /* @__PURE__ */ jsxRuntime.jsx("ol", { children: componentContracts.billingPaymentRows(values).map((row) => /* @__PURE__ */ jsxRuntime.jsxs("li", { "data-payment-kind": row.kind, children: [
3245
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: row.label }),
3246
+ row.at ? /* @__PURE__ */ jsxRuntime.jsx("time", { dateTime: row.at, children: row.text }) : /* @__PURE__ */ jsxRuntime.jsx("span", { children: row.text })
3247
+ ] }, row.kind)) })
3248
+ ] });
3249
+ }
3250
+ function PaymentTimeline(props) {
3251
+ return /* @__PURE__ */ jsxRuntime.jsx(BillingTimeline, { ...props, component: "PaymentTimeline", includeMethod: true });
3252
+ }
3253
+ function PaymentEventTimeline(props) {
3254
+ if (props.event) return /* @__PURE__ */ jsxRuntime.jsxs("section", { id: props.id, "data-oods-component": "PaymentEventTimeline", "aria-label": props.event.title ?? "Payment event", children: [
3255
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: props.event.title }),
3256
+ /* @__PURE__ */ jsxRuntime.jsx("time", { dateTime: props.event.at, children: componentContracts.formatDateTime(props.event.at) }),
3257
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: props.event.description })
3258
+ ] });
3259
+ return /* @__PURE__ */ jsxRuntime.jsx(BillingTimeline, { ...props, component: "PaymentEventTimeline", includeMethod: false });
3260
+ }
3261
+ function BillingCardMeta({ id, amount, currency, minorUnits, interval }) {
3262
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { id, className: "oods-billing-card-meta", "data-oods-component": "BillingCardMeta", children: componentContracts.billingSummary(amount, currency, minorUnits, interval) });
3263
+ }
3264
+ function ArchivedRowOverlay({ id, isArchived = false, showBadge = true, separateTab = true, tabLabel = "Archived", label, children }) {
3265
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3266
+ "span",
3267
+ {
3268
+ id,
3269
+ className: "oods-archived-row",
3270
+ "data-oods-component": "ArchivedRowOverlay",
3271
+ "data-archived": isArchived ? "true" : void 0,
3272
+ "data-archive-tab": separateTab ? tabLabel : void 0,
3273
+ role: isArchived ? "group" : void 0,
3274
+ "aria-hidden": isArchived ? false : void 0,
3275
+ "aria-label": isArchived ? `${tabLabel}${label ? `: ${label}` : ""}` : void 0,
3276
+ children: [
3277
+ children,
3278
+ isArchived && showBadge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "oods-archive-badge", children: tabLabel })
3279
+ ]
3280
+ }
3281
+ );
3282
+ }
3283
+ function AuditSummaryCard({ id, title = "Audit summary", showTransitionCount = true, showLastTransitionTime = true, showLastActor = true, ...values }) {
3284
+ const summary2 = componentContracts.auditSummary(values);
3285
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { id, className: "oods-audit-summary", "data-oods-component": "AuditSummaryCard", "aria-label": title, children: [
3286
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: title }),
3287
+ /* @__PURE__ */ jsxRuntime.jsxs("dl", { children: [
3288
+ showTransitionCount && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3289
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Transitions" }),
3290
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: summary2.count })
3291
+ ] }),
3292
+ showLastActor && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3293
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Last actor" }),
3294
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: summary2.actor })
3295
+ ] }),
3296
+ showLastTransitionTime && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3297
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Last transition" }),
3298
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: summary2.at ? /* @__PURE__ */ jsxRuntime.jsx("time", { dateTime: summary2.at, children: summary2.timestamp }) : summary2.timestamp })
3299
+ ] })
3300
+ ] }),
3301
+ summary2.recent.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ol", { "aria-label": "Recent transitions", children: summary2.recent.map((entry, index) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: String(entry.to_state ?? "Transition") }, index)) })
3302
+ ] });
3303
+ }
3304
+ function SortIndicator({ id, label = "Sort", onChange, "data-oods-action": action, ...values }) {
3305
+ const [state, setState] = React7__namespace.useState(() => componentContracts.initialSort(values));
3306
+ React7__namespace.useEffect(() => setState(componentContracts.initialSort(values)), [values.sortField, values.sortDirection, values.sortActive, values.defaultSortField, values.defaultSortDirection]);
3307
+ const sort = componentContracts.ariaSort(state);
3308
+ 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: () => {
3309
+ const next = componentContracts.nextSort(state, values.triStateSort);
3310
+ setState(next);
3311
+ onChange?.(next);
3312
+ }, children: `${state.field}: ${sort}` }) }) }) }) });
3313
+ }
3314
+ 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 }));
3315
+ TimelineEntryLabel.displayName = "OODS.TimelineEntryLabel";
3316
+ function eventRecipe(id, kind, title) {
3317
+ return function TraitEvent({ id: elementId, title: heading = title, ...values }) {
3318
+ const rows = componentContracts.traitEventRows(kind, values);
3319
+ return /* @__PURE__ */ jsxRuntime.jsxs("article", { id: elementId, className: "oods-trait-recipe", "data-oods-component": id, "aria-label": heading, children: [
3320
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: heading }),
3321
+ rows.length ? /* @__PURE__ */ jsxRuntime.jsx("ol", { children: rows.map((row, index) => /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
3322
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: row.title }),
3323
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: row.at ? /* @__PURE__ */ jsxRuntime.jsx("time", { dateTime: row.at, children: row.time }) : row.time }),
3324
+ row.actor && /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
3325
+ "Actor: ",
3326
+ row.actor
3327
+ ] }),
3328
+ row.reason && /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
3329
+ "Reason: ",
3330
+ row.reason
3331
+ ] }),
3332
+ row.code && /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
3333
+ "Code: ",
3334
+ row.code
3335
+ ] })
3336
+ ] }, index)) }) : /* @__PURE__ */ jsxRuntime.jsx("p", { children: "No events recorded." })
3337
+ ] });
3338
+ };
3339
+ }
3340
+ var ArchiveEvent = eventRecipe("ArchiveEvent", "archive", "Archive events");
3341
+ var CancellationEvent = eventRecipe("CancellationEvent", "cancellation", "Cancellation event");
3342
+ var StateTransitionEvent = eventRecipe("StateTransitionEvent", "transition", "State transitions");
3343
+ function CommunicationDetailPanel({ id, title = "Communication", channels = [], templates = [], policies = [], conversations = [] }) {
3344
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { id, className: "oods-trait-recipe", "data-oods-component": "CommunicationDetailPanel", "aria-label": title, children: [
3345
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: title }),
3346
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "status", "aria-live": "polite", children: [
3347
+ conversations.length,
3348
+ " conversations"
3349
+ ] }),
3350
+ /* @__PURE__ */ jsxRuntime.jsx("dl", { children: [["Channels", channels], ["Templates", templates], ["Delivery policies", policies], ["Conversations", conversations]].map(([label, rows]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3351
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: label }),
3352
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: rows.length ? /* @__PURE__ */ jsxRuntime.jsx("ul", { children: componentContracts.recipeItemLabels(rows).map((text, index) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: text }, index)) }) : "None recorded" })
3353
+ ] }, label)) })
3354
+ ] });
3355
+ }
3356
+ function ColorStatePicker({ id, title = "Color state", colorStates = componentContracts.DEFAULT_COLOR_STATES, value, disabled, onChange }) {
3357
+ const generatedId = React7__namespace.useId();
3358
+ const [selected, setSelected] = React7__namespace.useState(value ?? colorStates[0] ?? "");
3359
+ React7__namespace.useEffect(() => setSelected(value ?? colorStates[0] ?? ""), [value, colorStates]);
3360
+ return /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { id, className: "oods-trait-recipe", "data-oods-component": "ColorStatePicker", children: [
3361
+ /* @__PURE__ */ jsxRuntime.jsx("legend", { children: title }),
3362
+ /* @__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) => {
3363
+ setSelected(next);
3364
+ onChange?.(next);
3365
+ } })
3366
+ ] });
3367
+ }
3368
+ function StatusColorLegend({ id, title = "Status colors", colorStates = componentContracts.DEFAULT_COLOR_STATES, value, showTokenReferences = false }) {
3369
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { id, className: "oods-trait-recipe", "data-oods-component": "StatusColorLegend", "aria-label": title, children: [
3370
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: title }),
3371
+ /* @__PURE__ */ jsxRuntime.jsx("dl", { children: colorStates.map((state) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3372
+ /* @__PURE__ */ jsxRuntime.jsxs("dt", { children: [
3373
+ /* @__PURE__ */ jsxRuntime.jsx(ColorSwatch, { label: state, color: `var(--sys-status-${state}-surface)` }),
3374
+ state === value && " (current)"
3375
+ ] }),
3376
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: showTokenReferences ? `--sys-status-${state}-surface` : state })
3377
+ ] }, state)) })
3378
+ ] });
3379
+ }
3380
+ function GeoFieldMappingForm({ id, title = "Geographic fields", embedded = false, disabled, onChange, ...values }) {
3381
+ const generatedId = React7__namespace.useId();
3382
+ const [value, setValue] = React7__namespace.useState(() => componentContracts.geoFieldMapping(values));
3383
+ React7__namespace.useEffect(() => setValue(componentContracts.geoFieldMapping(values)), [values.latitude, values.longitude, values.identifier, values.autoDetect]);
3384
+ const update = (patch) => {
3385
+ const next = { ...value, ...patch };
3386
+ setValue(next);
3387
+ onChange?.(next);
3388
+ };
3389
+ const Tag = embedded ? "fieldset" : "form";
3390
+ return /* @__PURE__ */ jsxRuntime.jsxs(Tag, { id, className: "oods-trait-recipe", "data-oods-component": "GeoFieldMappingForm", "aria-label": title, onSubmit: (event) => event.preventDefault(), children: [
3391
+ embedded ? /* @__PURE__ */ jsxRuntime.jsx("legend", { children: title }) : /* @__PURE__ */ jsxRuntime.jsx("h2", { children: title }),
3392
+ ["latitude", "longitude", "identifier"].map((field) => /* @__PURE__ */ jsxRuntime.jsx(Input, { id: `${id ?? generatedId}-${field}`, name: `geo_${field}_field`, label: `${field[0].toUpperCase()}${field.slice(1)} field`, value: value[field], disabled, onValueChange: (next) => update({ [field]: next }) }, field)),
3393
+ /* @__PURE__ */ jsxRuntime.jsx(Checkbox, { id: `${id ?? generatedId}-auto`, name: "geo_auto_detect_enabled", label: "Auto detect fields", checked: value.autoDetect, disabled, onCheckedChange: (autoDetect) => update({ autoDetect }) })
3394
+ ] });
3395
+ }
3396
+ function GeoResolutionBadge({ id, resolution }) {
3397
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { id, className: "oods-geo-resolution", "data-oods-component": "GeoResolutionBadge", children: [
3398
+ "Resolution: ",
3399
+ resolution || "Not determined"
3400
+ ] });
3401
+ }
3402
+ function GeocodablePreview({ id, title = "Geographic data", resolution, requiresLookup, detectedFields = [] }) {
3403
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { id, className: "oods-trait-recipe", "data-oods-component": "GeocodablePreview", "aria-label": title, children: [
3404
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: title }),
3405
+ /* @__PURE__ */ jsxRuntime.jsxs("dl", { children: [
3406
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Resolution" }),
3407
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: resolution || "Not determined" }),
3408
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Requires lookup" }),
3409
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: requiresLookup === void 0 ? "Not determined" : requiresLookup ? "Yes" : "No" }),
3410
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Detected fields" }),
3411
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: componentContracts.recipeItemLabels(detectedFields).join(", ") || "None detected" })
3412
+ ] })
3413
+ ] });
3414
+ }
3415
+ function controls(id) {
3416
+ const Component = ({ id: htmlId, title = componentContracts.VIZ_CONTROL_TITLES[id], value, channel = "x", disabled, onChange }) => {
3417
+ const generatedId = React7__namespace.useId();
3418
+ const [current, setCurrent] = React7__namespace.useState(value ?? {});
3419
+ const [drafts, setDrafts] = React7__namespace.useState({});
3420
+ const [errors, setErrors] = React7__namespace.useState({});
3421
+ React7__namespace.useEffect(() => {
3422
+ setCurrent(value ?? {});
3423
+ setDrafts({});
3424
+ setErrors({});
3425
+ }, [value]);
3426
+ const update = (field, text) => {
3427
+ const result = componentContracts.editVizIntent(current, field, text);
3428
+ setDrafts((previous) => ({ ...previous, [field.key]: text }));
3429
+ setErrors((previous) => ({ ...previous, [field.key]: result.error }));
3430
+ if (result.value) {
3431
+ setCurrent(result.value);
3432
+ onChange?.(result.value);
3433
+ }
3434
+ };
3435
+ return /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { id: htmlId, className: "oods-viz-controls oods-trait-recipe", "data-oods-component": id, disabled, children: [
3436
+ /* @__PURE__ */ jsxRuntime.jsx("legend", { children: title }),
3437
+ componentContracts.vizControlFields(id, channel).map((field) => {
3438
+ const fieldId = `${htmlId ?? generatedId}-${field.key.replace(".", "-")}`;
3439
+ const text = drafts[field.key] ?? componentContracts.vizFieldValue(current, field.key);
3440
+ const validation = errors[field.key] ? { state: "error", message: errors[field.key] } : void 0;
3441
+ return field.type === "select" ? /* @__PURE__ */ jsxRuntime.jsx(Select, { id: fieldId, name: field.key, label: field.label, value: text, options: [...!field.options?.includes(text) ? [{ value: text, label: text || "Choose option", disabled: true }] : [], ...field.options.map((value2) => ({ value: value2, label: value2 }))], validation, onValueChange: (value2) => update(field, value2) }, field.key) : /* @__PURE__ */ jsxRuntime.jsx(Input, { id: fieldId, name: field.key, label: field.label, value: text, type: field.type === "number" ? "number" : "text", min: field.min, max: field.max, step: field.step, validation, onValueChange: (value2) => update(field, value2) }, field.key);
3442
+ }),
3443
+ (id === "VizColorControls" || id === "VizColorLegendConfig") && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oods-viz-swatches", children: current.encodings?.color?.range?.map((color, index) => /* @__PURE__ */ jsxRuntime.jsx(ColorSwatch, { color, label: `Category color ${index + 1}: ${color}` }, index)) }),
3444
+ id === "VizShapeLegend" && /* @__PURE__ */ jsxRuntime.jsx(Text, { content: `Shape field: ${current.encodings?.shape?.field || "Not bound"}` })
3445
+ ] });
3446
+ };
3447
+ Component.displayName = `OODS.${id}`;
3448
+ return Component;
3449
+ }
3450
+ function summary(id) {
3451
+ return function VizSummary({ id: htmlId, title, value = {}, channel = "x" }) {
3452
+ const rows = componentContracts.vizSummaryRows(id, value, channel);
3453
+ if (id === "VizEncodingBadge" || id === "VizRoleBadge") return /* @__PURE__ */ jsxRuntime.jsx("span", { id: htmlId, "data-oods-component": id, children: /* @__PURE__ */ jsxRuntime.jsx(Badge, { content: rows.map(([label, text]) => `${label}: ${text}`).join(" \xB7 ") }) });
3454
+ const heading = title ?? id.replace(/^Viz/, "").replace(/Summary$/, "") + " summary";
3455
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { id: htmlId, className: "oods-trait-recipe", "data-oods-component": id, "aria-label": heading, children: [
3456
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: heading }),
3457
+ /* @__PURE__ */ jsxRuntime.jsx("dl", { children: rows.map(([label, text]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3458
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: label }),
3459
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: /* @__PURE__ */ jsxRuntime.jsx(Text, { content: text }) })
3460
+ ] }, label)) })
3461
+ ] });
3462
+ };
3463
+ }
3464
+ function preview(id, type) {
3465
+ return function VizPreview({ title = `${type[0].toUpperCase()}${type.slice(1)} chart`, children, ...props }) {
3466
+ return /* @__PURE__ */ jsxRuntime.jsx(VizAreaPreview, { ...props, title, "data-oods-component": id, "data-viz-preview-type": type, children: children ?? /* @__PURE__ */ jsxRuntime.jsx(Text, { content: "No rendered chart supplied" }) });
3467
+ };
3468
+ }
3469
+ var VizAreaControls = controls("VizAreaControls");
3470
+ var VizAxisControls = controls("VizAxisControls");
3471
+ var VizColorControls = controls("VizColorControls");
3472
+ var VizHeatmapControls = controls("VizHeatmapControls");
3473
+ var VizLineControls = controls("VizLineControls");
3474
+ var VizMarkControls = controls("VizMarkControls");
3475
+ var VizOpacityControls = controls("VizOpacityControls");
3476
+ var VizPointControls = controls("VizPointControls");
3477
+ var VizScaleControls = controls("VizScaleControls");
3478
+ var VizScatterControls = controls("VizScatterControls");
3479
+ var VizShapeControls = controls("VizShapeControls");
3480
+ var VizSizeControls = controls("VizSizeControls");
3481
+ var VizColorLegendConfig = controls("VizColorLegendConfig");
3482
+ var VizShapeLegend = controls("VizShapeLegend");
3483
+ var VizAxisSummary = summary("VizAxisSummary");
3484
+ var VizOpacitySummary = summary("VizOpacitySummary");
3485
+ var VizScaleSummary = summary("VizScaleSummary");
3486
+ var VizSizeSummary = summary("VizSizeSummary");
3487
+ var VizEncodingBadge = summary("VizEncodingBadge");
3488
+ var VizRoleBadge = summary("VizRoleBadge");
3489
+ var VizHeatmapPreview = preview("VizHeatmapPreview", "heatmap");
3490
+ var VizGraphPreview = preview("VizGraphPreview", "force_graph");
3491
+ var VizLinePreview = preview("VizLinePreview", "line");
3492
+ var VizMarkPreview = preview("VizMarkPreview", "bar");
3493
+ var VizPointPreview = preview("VizPointPreview", "scatter");
3494
+ var VizScatterPreview = preview("VizScatterPreview", "scatter");
3495
+
3496
+ exports.AddressCollectionPanel = AddressCollectionPanel;
3497
+ exports.AddressEditor = AddressEditor;
3498
+ exports.AddressSummaryBadge = AddressSummaryBadge;
3499
+ exports.AddressValidationTimeline = AddressValidationTimeline;
3500
+ exports.ArchiveEvent = ArchiveEvent;
3501
+ exports.ArchivePill = ArchivePill;
3502
+ exports.ArchiveSummary = ArchiveSummary;
3503
+ exports.ArchivedRowOverlay = ArchivedRowOverlay;
3504
+ exports.AuditEvent = AuditEvent;
3505
+ exports.AuditSummaryCard = AuditSummaryCard;
3506
+ exports.AuditTimeline = AuditTimeline;
3507
+ exports.Badge = Badge;
3508
+ exports.Banner = Banner;
3509
+ exports.BillingAmountInput = BillingAmountInput;
3510
+ exports.BillingCardMeta = BillingCardMeta;
3511
+ exports.BillingIntervalSelector = BillingIntervalSelector;
3512
+ exports.BillingSummaryBadge = BillingSummaryBadge;
3513
+ exports.Button = Button;
3514
+ exports.CancellationBadge = CancellationBadge;
3515
+ exports.CancellationEvent = CancellationEvent;
3516
+ exports.CancellationForm = CancellationForm;
3517
+ exports.CancellationSummary = CancellationSummary;
3518
+ exports.Card = Card;
3519
+ exports.CardHeader = CardHeader;
3520
+ exports.Checkbox = Checkbox;
3521
+ exports.ClassificationBadge = ClassificationBadge;
3522
+ exports.ClassificationEditor = ClassificationEditor;
3523
+ exports.ClassificationPanel = ClassificationPanel;
3524
+ exports.ColorStatePicker = ColorStatePicker;
3525
+ exports.ColorSwatch = ColorSwatch;
3526
+ exports.ColorizedBadge = ColorizedBadge;
3527
+ exports.CommunicationDetailPanel = CommunicationDetailPanel;
3528
+ exports.CycleProgressCard = CycleProgressCard;
3529
+ exports.DatePicker = DatePicker;
3530
+ exports.DetailHeader = DetailHeader;
3531
+ exports.FilterPanel = FilterPanel;
3532
+ exports.FormLabelGroup = FormLabelGroup;
3533
+ exports.GeoFieldMappingForm = GeoFieldMappingForm;
3534
+ exports.GeoResolutionBadge = GeoResolutionBadge;
3535
+ exports.GeocodablePreview = GeocodablePreview;
3536
+ exports.Grid = Grid;
3537
+ exports.InlineLabel = InlineLabel;
3538
+ exports.Input = Input;
3539
+ exports.LabelCell = LabelCell;
3540
+ exports.MembershipAuditTimeline = MembershipAuditTimeline;
3541
+ exports.MembershipPanel = MembershipPanel;
3542
+ exports.MessageEventTimeline = MessageEventTimeline;
3543
+ exports.MessageStatusBadge = MessageStatusBadge;
3544
+ exports.OwnerBadge = OwnerBadge;
3545
+ exports.OwnershipMeta = OwnershipMeta;
3546
+ exports.OwnershipSummary = OwnershipSummary;
3547
+ exports.PaginationBar = PaginationBar;
3548
+ exports.PaymentEventTimeline = PaymentEventTimeline;
3549
+ exports.PaymentTimeline = PaymentTimeline;
3550
+ exports.PreferenceEditor = PreferenceEditor;
3551
+ exports.PreferencePanel = PreferencePanel;
3552
+ exports.PreferenceSummaryBadge = PreferenceSummaryBadge;
3553
+ exports.PreferenceTimeline = PreferenceTimeline;
3554
+ exports.PriceBadge = PriceBadge;
3555
+ exports.PriceCardMeta = PriceCardMeta;
3556
+ exports.PriceSummary = PriceSummary;
3557
+ exports.RelativeTimestamp = RelativeTimestamp;
3558
+ exports.RoleAssignmentForm = RoleAssignmentForm;
3559
+ exports.RoleBadgeList = RoleBadgeList;
3560
+ exports.SearchInput = SearchInput;
3561
+ exports.Select = Select;
3562
+ exports.SortIndicator = SortIndicator;
3563
+ exports.Stack = Stack;
3564
+ exports.StateTransitionEvent = StateTransitionEvent;
3565
+ exports.StatusBadge = StatusBadge;
3566
+ exports.StatusColorLegend = StatusColorLegend;
3567
+ exports.StatusSelector = StatusSelector;
3568
+ exports.StatusTimeline = StatusTimeline;
3569
+ exports.Table = Table;
3570
+ exports.Tabs = Tabs;
3571
+ exports.TagInput = TagInput;
3572
+ exports.TagManager = TagManager;
3573
+ exports.TagPills = TagPills;
3574
+ exports.TagSummary = TagSummary;
3575
+ exports.TemplatePicker = TemplatePicker;
3576
+ exports.Text = Text;
3577
+ exports.Textarea = Textarea;
3578
+ exports.TimelineEntryLabel = TimelineEntryLabel;
3579
+ exports.VizAreaControls = VizAreaControls;
3580
+ exports.VizAreaPreview = VizAreaPreview;
3581
+ exports.VizAxisControls = VizAxisControls;
3582
+ exports.VizAxisSummary = VizAxisSummary;
3583
+ exports.VizColorControls = VizColorControls;
3584
+ exports.VizColorLegendConfig = VizColorLegendConfig;
3585
+ exports.VizEncodingBadge = VizEncodingBadge;
3586
+ exports.VizGraphPreview = VizGraphPreview;
3587
+ exports.VizHeatmapControls = VizHeatmapControls;
3588
+ exports.VizHeatmapPreview = VizHeatmapPreview;
3589
+ exports.VizLineControls = VizLineControls;
3590
+ exports.VizLinePreview = VizLinePreview;
3591
+ exports.VizMarkControls = VizMarkControls;
3592
+ exports.VizMarkPreview = VizMarkPreview;
3593
+ exports.VizOpacityControls = VizOpacityControls;
3594
+ exports.VizOpacitySummary = VizOpacitySummary;
3595
+ exports.VizPointControls = VizPointControls;
3596
+ exports.VizPointPreview = VizPointPreview;
3597
+ exports.VizRoleBadge = VizRoleBadge;
3598
+ exports.VizScaleControls = VizScaleControls;
3599
+ exports.VizScaleSummary = VizScaleSummary;
3600
+ exports.VizScatterControls = VizScatterControls;
3601
+ exports.VizScatterPreview = VizScatterPreview;
3602
+ exports.VizShapeControls = VizShapeControls;
3603
+ exports.VizShapeLegend = VizShapeLegend;
3604
+ exports.VizSizeControls = VizSizeControls;
3605
+ exports.VizSizeSummary = VizSizeSummary;