@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.js ADDED
@@ -0,0 +1,1781 @@
1
+ import { Badge, Select, Input, Checkbox, Text } from './chunk-A4T7OOIY.js';
2
+ export { AuditTimeline, Badge, Banner, Button, CancellationSummary, Card, Checkbox, DatePicker, Input, PaginationBar, PriceBadge, RelativeTimestamp, SearchInput, Select, StatusBadge, StatusTimeline, Text, Textarea } from './chunk-A4T7OOIY.js';
3
+ export { Table } from './chunk-YCI5AEWL.js';
4
+ import './chunk-G74PKSW3.js';
5
+ import * as React3 from 'react';
6
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
+ import { svgCarriesTitle, assertStaticSvg, formatPriceAmount, formatPriceCode, formatReferenceLabel, summaryValue, formatDateTime, formatReadOnlyValue, billingSummary, formatBillingAmount, billingAmountText, BILLING_MINOR_UNITS, billingAmountMessage, parseBillingAmount, billingIntervalMessage, BILLING_INTERVALS, billingCycle, auditSummary, initialSort, ariaSort, nextSort, traitEventRows, recipeItemLabels, DEFAULT_COLOR_STATES, geoFieldMapping, vizSummaryRows, vizControlFields, VIZ_CONTROL_TITLES, vizFieldValue, billingPaymentSummary, billingPaymentRows, editVizIntent } from '@oods/component-contracts';
8
+
9
+ var classes = (...values) => values.filter(Boolean).join(" ");
10
+ var GAP_VALUES = {
11
+ xs: "var(--cmp-spacing-inline-xs, 0.5rem)",
12
+ sm: "var(--cmp-spacing-inline-sm, 0.75rem)",
13
+ md: "var(--cmp-spacing-stack-default, 1rem)",
14
+ lg: "var(--cmp-spacing-stack-lg, 1.5rem)",
15
+ xl: "var(--cmp-spacing-stack-xl, 2rem)"
16
+ };
17
+ var resolveGap = (gap) => gap ? GAP_VALUES[gap] ?? gap : void 0;
18
+ var maxColumns = (columns) => {
19
+ const count = Number(columns);
20
+ return Number.isFinite(count) && count > 0 ? count : void 0;
21
+ };
22
+ var Grid = React3.forwardRef(
23
+ ({
24
+ columns = "auto-fit",
25
+ minColumnWidth = "16rem",
26
+ gap = "md",
27
+ align = "stretch",
28
+ justify = "normal",
29
+ className,
30
+ style,
31
+ ...rest
32
+ }, ref) => /* @__PURE__ */ jsx(
33
+ "div",
34
+ {
35
+ ref,
36
+ className: classes("oods-grid", className),
37
+ "data-oods-component": "Grid",
38
+ "data-max-columns": maxColumns(columns),
39
+ style: {
40
+ "--oods-grid-columns": columns,
41
+ "--oods-grid-min-column": minColumnWidth,
42
+ "--oods-layout-gap": resolveGap(gap),
43
+ "--oods-layout-align": align,
44
+ "--oods-layout-justify": justify,
45
+ ...style
46
+ },
47
+ ...rest
48
+ }
49
+ )
50
+ );
51
+ Grid.displayName = "OODS.Grid";
52
+ var Stack = React3.forwardRef(
53
+ ({
54
+ direction = "column",
55
+ gap = "md",
56
+ align = "stretch",
57
+ justify = "flex-start",
58
+ wrap = false,
59
+ className,
60
+ style,
61
+ ...rest
62
+ }, ref) => /* @__PURE__ */ jsx(
63
+ "div",
64
+ {
65
+ ref,
66
+ className: classes("oods-stack", className),
67
+ "data-oods-component": "Stack",
68
+ "data-direction": direction,
69
+ "data-wrap": wrap ? "true" : "false",
70
+ style: {
71
+ "--oods-stack-direction": direction,
72
+ "--oods-stack-wrap": wrap ? "wrap" : "nowrap",
73
+ "--oods-layout-gap": resolveGap(gap),
74
+ "--oods-layout-align": align,
75
+ "--oods-layout-justify": justify,
76
+ ...style
77
+ },
78
+ ...rest
79
+ }
80
+ )
81
+ );
82
+ Stack.displayName = "OODS.Stack";
83
+ var classes2 = (...values) => values.filter(Boolean).join(" ");
84
+ var enabledTabIndexes = (items) => items.flatMap((item, index) => item.disabled || item.isDisabled ? [] : [index]);
85
+ var partitionForOverflow = (items, visibleCount, selectedId) => {
86
+ if (visibleCount >= items.length) return { visibleItems: items, overflowItems: [] };
87
+ const visibleItems = [...items.slice(0, Math.max(1, visibleCount))];
88
+ const selected = items.find((item) => item.id === selectedId);
89
+ if (selected && !visibleItems.some((item) => item.id === selectedId)) {
90
+ visibleItems[visibleItems.length - 1] = selected;
91
+ }
92
+ const visibleIds = new Set(visibleItems.map((item) => item.id));
93
+ return {
94
+ visibleItems,
95
+ overflowItems: items.filter((item) => !visibleIds.has(item.id))
96
+ };
97
+ };
98
+ var Tabs = React3.forwardRef(
99
+ ({
100
+ items,
101
+ selectedId,
102
+ defaultSelectedId,
103
+ size = "md",
104
+ overflowLabel = "More",
105
+ ariaLabel,
106
+ onChange,
107
+ onUpdate,
108
+ className,
109
+ "aria-label": ariaLabelAttribute,
110
+ ...rest
111
+ }, ref) => {
112
+ const instanceId = React3.useId().replaceAll(":", "");
113
+ const controlled = selectedId !== void 0;
114
+ const firstEnabled = items.find((item) => !item.disabled && !item.isDisabled)?.id ?? "";
115
+ const [internalSelectedId, setInternalSelectedId] = React3.useState(
116
+ defaultSelectedId ?? firstEnabled
117
+ );
118
+ const activeId = controlled ? selectedId : internalSelectedId;
119
+ const [focusedId, setFocusedId] = React3.useState(activeId);
120
+ const [visibleCount, setVisibleCount] = React3.useState(items.length);
121
+ const [menuOpen, setMenuOpen] = React3.useState(false);
122
+ const listRef = React3.useRef(null);
123
+ const tabRefs = React3.useRef(/* @__PURE__ */ new Map());
124
+ const itemWidths = React3.useRef(/* @__PURE__ */ new Map());
125
+ const focusRequestedByUser = React3.useRef(false);
126
+ React3.useEffect(() => setFocusedId(activeId), [activeId]);
127
+ const select = React3.useCallback(
128
+ (id) => {
129
+ const item = items.find((candidate) => candidate.id === id);
130
+ if (!item || item.disabled || item.isDisabled) return;
131
+ if (!controlled) setInternalSelectedId(id);
132
+ focusRequestedByUser.current = true;
133
+ setFocusedId(id);
134
+ onChange?.(id);
135
+ onUpdate?.(id);
136
+ },
137
+ [controlled, items, onChange, onUpdate]
138
+ );
139
+ const measure = React3.useCallback(() => {
140
+ const list = listRef.current;
141
+ if (!list || items.length < 2) return;
142
+ const available = list.offsetWidth;
143
+ for (const tab of Array.from(list.querySelectorAll('[role="tab"]'))) {
144
+ const itemId = tab.dataset.tabId;
145
+ if (itemId && tab.offsetWidth > 0) itemWidths.current.set(itemId, tab.offsetWidth);
146
+ }
147
+ const widths = items.map((item) => itemWidths.current.get(item.id) ?? 0);
148
+ const total = widths.reduce((sum, width) => sum + width, 0);
149
+ if (!available || !total || total <= available) {
150
+ setVisibleCount(items.length);
151
+ return;
152
+ }
153
+ const overflowReserve = 80;
154
+ let used = 0;
155
+ let count = 0;
156
+ for (const width of widths) {
157
+ if (used + width > available - overflowReserve) break;
158
+ used += width;
159
+ count += 1;
160
+ }
161
+ setVisibleCount(Math.max(1, count));
162
+ }, [items.length]);
163
+ React3.useLayoutEffect(() => {
164
+ measure();
165
+ const list = listRef.current;
166
+ if (!list || typeof ResizeObserver === "undefined") return void 0;
167
+ const observer = new ResizeObserver(measure);
168
+ observer.observe(list);
169
+ return () => observer.disconnect();
170
+ }, [measure]);
171
+ const { visibleItems, overflowItems } = partitionForOverflow(
172
+ items,
173
+ visibleCount,
174
+ activeId
175
+ );
176
+ const move = (currentId, key) => {
177
+ const enabled = enabledTabIndexes(items);
178
+ if (enabled.length === 0) return;
179
+ const currentIndex = items.findIndex((item) => item.id === currentId);
180
+ const position = enabled.indexOf(currentIndex);
181
+ let nextIndex;
182
+ if (key === "Home") nextIndex = enabled[0];
183
+ if (key === "End") nextIndex = enabled[enabled.length - 1];
184
+ if (key === "ArrowRight") nextIndex = enabled[(Math.max(0, position) + 1) % enabled.length];
185
+ if (key === "ArrowLeft") nextIndex = enabled[(position - 1 + enabled.length) % enabled.length];
186
+ if (nextIndex === void 0) return;
187
+ const nextId = items[nextIndex]?.id;
188
+ if (!nextId) return;
189
+ select(nextId);
190
+ };
191
+ React3.useEffect(() => {
192
+ if (focusRequestedByUser.current && visibleItems.some((item) => item.id === focusedId)) {
193
+ focusRequestedByUser.current = false;
194
+ tabRefs.current.get(focusedId)?.focus();
195
+ }
196
+ }, [focusedId, visibleItems]);
197
+ const renderTab = (item) => {
198
+ const disabled = Boolean(item.disabled || item.isDisabled);
199
+ const selected = item.id === activeId;
200
+ return /* @__PURE__ */ jsx(
201
+ "button",
202
+ {
203
+ ref: (node) => {
204
+ if (node) tabRefs.current.set(item.id, node);
205
+ else tabRefs.current.delete(item.id);
206
+ },
207
+ id: `${instanceId}-tab-${item.id}`,
208
+ type: "button",
209
+ role: "tab",
210
+ className: classes2(
211
+ "oods-tab",
212
+ "tabs__tab",
213
+ selected && "tabs__tab--selected",
214
+ disabled && "tabs__tab--disabled"
215
+ ),
216
+ "data-size": size,
217
+ "data-tab-id": item.id,
218
+ "aria-selected": selected,
219
+ "aria-controls": `${instanceId}-panel-${item.id}`,
220
+ tabIndex: item.id === focusedId ? 0 : -1,
221
+ disabled,
222
+ title: typeof item.label === "string" ? item.label : void 0,
223
+ onFocus: () => setFocusedId(item.id),
224
+ onClick: () => select(item.id),
225
+ onKeyDown: (event) => {
226
+ if (["ArrowRight", "ArrowLeft", "Home", "End"].includes(event.key)) {
227
+ event.preventDefault();
228
+ move(item.id, event.key);
229
+ }
230
+ },
231
+ children: /* @__PURE__ */ jsx("span", { className: "tabs__tab-label", children: item.label })
232
+ },
233
+ item.id
234
+ );
235
+ };
236
+ return /* @__PURE__ */ jsxs(
237
+ "div",
238
+ {
239
+ ref,
240
+ className: classes2("oods-tabs", "tabs", className),
241
+ "data-oods-component": "Tabs",
242
+ "data-size": size,
243
+ ...rest,
244
+ children: [
245
+ /* @__PURE__ */ jsxs(
246
+ "div",
247
+ {
248
+ ref: listRef,
249
+ className: "oods-tab-list tabs__list",
250
+ role: "tablist",
251
+ "aria-label": ariaLabel ?? ariaLabelAttribute,
252
+ children: [
253
+ visibleItems.map(renderTab),
254
+ overflowItems.length ? /* @__PURE__ */ jsxs("div", { className: "oods-tabs__overflow", children: [
255
+ /* @__PURE__ */ jsx(
256
+ "button",
257
+ {
258
+ type: "button",
259
+ className: "tabs__overflow-trigger",
260
+ "aria-label": `${overflowLabel} tabs`,
261
+ "aria-haspopup": "menu",
262
+ "aria-expanded": menuOpen,
263
+ "data-tabs-overflow-trigger": "true",
264
+ onClick: () => setMenuOpen((open) => !open),
265
+ children: overflowLabel
266
+ }
267
+ ),
268
+ menuOpen ? /* @__PURE__ */ jsx("div", { className: "tabs__overflow-menu", role: "menu", children: overflowItems.map((item) => /* @__PURE__ */ jsx(
269
+ "button",
270
+ {
271
+ type: "button",
272
+ role: "menuitem",
273
+ disabled: item.disabled || item.isDisabled,
274
+ "aria-current": item.id === activeId ? "true" : void 0,
275
+ className: classes2(
276
+ "tabs__overflow-item",
277
+ item.id === activeId && "tabs__overflow-item--selected"
278
+ ),
279
+ onClick: () => {
280
+ select(item.id);
281
+ setMenuOpen(false);
282
+ },
283
+ children: item.label
284
+ },
285
+ item.id
286
+ )) }) : null
287
+ ] }) : null
288
+ ]
289
+ }
290
+ ),
291
+ items.map((item) => {
292
+ const selected = item.id === activeId;
293
+ return /* @__PURE__ */ jsx(
294
+ "div",
295
+ {
296
+ id: `${instanceId}-panel-${item.id}`,
297
+ role: "tabpanel",
298
+ className: "oods-tab-panel tabs__panel",
299
+ "aria-labelledby": `${instanceId}-tab-${item.id}`,
300
+ hidden: !selected,
301
+ tabIndex: 0,
302
+ children: selected ? item.panel : null
303
+ },
304
+ item.id
305
+ );
306
+ })
307
+ ]
308
+ }
309
+ );
310
+ }
311
+ );
312
+ Tabs.displayName = "OODS.Tabs";
313
+ var classes3 = (...values) => values.filter(Boolean).join(" ");
314
+ var firstText = (...values) => values.find((value) => typeof value === "string" && value.trim().length > 0);
315
+ function childContent(children) {
316
+ const flatten = (value) => React3.Children.toArray(value).flatMap((node) => {
317
+ if (React3.isValidElement(node) && node.type === React3.Fragment) {
318
+ return flatten(node.props.children);
319
+ }
320
+ return [node];
321
+ });
322
+ const nodes = flatten(children);
323
+ if (nodes.every((node) => typeof node === "string" || typeof node === "number")) {
324
+ const scalar = nodes.join("");
325
+ return { scalar: scalar.trim().length > 0 ? scalar : void 0, authored: false };
326
+ }
327
+ return { authored: nodes.length > 0 };
328
+ }
329
+ function headingElement(as, level, fallback) {
330
+ if (as && /^h[1-6]$/.test(as)) return as;
331
+ const bounded = Number.isFinite(level) ? Math.max(1, Math.min(6, Math.trunc(level))) : fallback;
332
+ return `h${bounded}`;
333
+ }
334
+ function notEcho(supporting, heading) {
335
+ if (!supporting || !heading) return supporting;
336
+ return supporting.trim() === heading.trim() ? void 0 : supporting;
337
+ }
338
+ var DetailHeader = React3.forwardRef(
339
+ ({ title, label, text, subtitle, sublabel, description, metadata, meta, level, as, children, className, ...rest }, ref) => {
340
+ const Heading = headingElement(as, level, 2);
341
+ const content = childContent(children);
342
+ const heading = content.scalar ?? firstText(title, label, text) ?? "Details";
343
+ const supporting = notEcho(firstText(subtitle, sublabel, description), heading);
344
+ const metadataText = firstText(metadata, meta);
345
+ return /* @__PURE__ */ jsx("header", { ref, className: classes3("oods-detail-header", className), "data-oods-component": "DetailHeader", ...rest, children: content.authored ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
346
+ /* @__PURE__ */ jsx(Heading, { children: heading }),
347
+ supporting ? /* @__PURE__ */ jsx("span", { "data-oods-subtitle": "true", children: supporting }) : null,
348
+ metadataText ? /* @__PURE__ */ jsx("span", { "data-oods-metadata": "true", children: metadataText }) : null
349
+ ] }) });
350
+ }
351
+ );
352
+ DetailHeader.displayName = "OODS.DetailHeader";
353
+ var CardHeader = React3.forwardRef(
354
+ ({ title, label, text, supporting, supportingText, subtitle, description, level, as, children, className, ...rest }, ref) => {
355
+ const Heading = headingElement(as, level, 2);
356
+ const content = childContent(children);
357
+ const heading = content.scalar ?? firstText(title, label, text) ?? "Card";
358
+ const supportingLabel = notEcho(firstText(supporting, supportingText, subtitle, description), heading);
359
+ return /* @__PURE__ */ jsx("header", { ref, className: classes3("oods-card-header", className), "data-oods-component": "CardHeader", ...rest, children: content.authored ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
360
+ /* @__PURE__ */ jsx(Heading, { children: heading }),
361
+ supportingLabel ? /* @__PURE__ */ jsx("span", { "data-oods-supporting": "true", children: supportingLabel }) : null
362
+ ] }) });
363
+ }
364
+ );
365
+ CardHeader.displayName = "OODS.CardHeader";
366
+ var ColorSwatch = React3.forwardRef(
367
+ ({ color, value, state, label, children, className, style, ...rest }, ref) => {
368
+ const resolvedColor = firstText(color, value, state);
369
+ const content = childContent(children);
370
+ const resolvedLabel = content.scalar ?? firstText(label) ?? resolvedColor ?? "default";
371
+ return /* @__PURE__ */ jsxs(
372
+ "span",
373
+ {
374
+ ref,
375
+ className: classes3("oods-color-swatch", className),
376
+ "data-oods-component": "ColorSwatch",
377
+ "data-summary-type": "color-swatch",
378
+ "data-swatch-color": resolvedColor ?? "default",
379
+ style: { "--oods-swatch-color": resolvedColor === "default" ? void 0 : resolvedColor, ...style },
380
+ ...rest,
381
+ children: [
382
+ /* @__PURE__ */ jsx("span", { "data-oods-swatch-chip": "true", "aria-hidden": "true" }),
383
+ /* @__PURE__ */ jsx("span", { "data-oods-swatch-label": "true", children: resolvedLabel }),
384
+ content.authored ? children : null
385
+ ]
386
+ }
387
+ );
388
+ }
389
+ );
390
+ ColorSwatch.displayName = "OODS.ColorSwatch";
391
+ var ColorizedBadge = React3.forwardRef(
392
+ ({ label, text, state, value, status, color, hue, swatch, variant, tone, emphasis, children, className, style, ...rest }, ref) => {
393
+ const content = childContent(children);
394
+ const resolvedLabel = content.scalar ?? firstText(label, text, state, value) ?? "Color";
395
+ const resolvedColor = firstText(color, hue, swatch, state);
396
+ const resolvedStatus = firstText(status, state, value);
397
+ return /* @__PURE__ */ jsxs(
398
+ Badge,
399
+ {
400
+ ref,
401
+ status: resolvedStatus,
402
+ tone,
403
+ emphasis,
404
+ className: classes3("oods-colorized-badge", className),
405
+ "data-oods-component": "ColorizedBadge",
406
+ "data-badge-status": resolvedStatus,
407
+ "data-badge-color": resolvedColor,
408
+ "data-badge-variant": firstText(variant) ?? "colorized",
409
+ icon: /* @__PURE__ */ jsx("span", { "data-oods-badge-marker": "true", "aria-hidden": "true" }),
410
+ style: { "--oods-badge-color": resolvedColor, ...style },
411
+ ...rest,
412
+ children: [
413
+ /* @__PURE__ */ jsx("span", { "data-oods-badge-label": "true", children: resolvedLabel }),
414
+ content.authored ? children : null
415
+ ]
416
+ }
417
+ );
418
+ }
419
+ );
420
+ ColorizedBadge.displayName = "OODS.ColorizedBadge";
421
+ var VizAreaPreview = React3.forwardRef(
422
+ ({ width = 640, height = 360, svg, svgNarrow, svgWide, title, description, children, className, style, ...rest }, ref) => {
423
+ const content = childContent(children);
424
+ if (svg !== void 0) {
425
+ return /* @__PURE__ */ jsxs(
426
+ "figure",
427
+ {
428
+ ref,
429
+ className: classes3("oods-viz-area-preview", className),
430
+ "data-oods-component": "VizAreaPreview",
431
+ "data-viz-preview-type": "area",
432
+ "data-viz-rendered": "true",
433
+ "data-viz-width": width,
434
+ "data-viz-height": height,
435
+ "data-viz-narrow": svgNarrow !== void 0 ? "true" : void 0,
436
+ "data-viz-wide": svgWide !== void 0 ? "true" : void 0,
437
+ role: "img",
438
+ "aria-label": title ?? description ?? "Payment amounts",
439
+ style: { "--oods-viz-width": `${width}px`, ...style },
440
+ ...rest,
441
+ children: [
442
+ title && !svgCarriesTitle(svg, title) ? /* @__PURE__ */ jsx("figcaption", { children: title }) : null,
443
+ /* @__PURE__ */ jsx("div", { "data-viz-svg": "true", dangerouslySetInnerHTML: { __html: assertStaticSvg(svg) } }),
444
+ svgNarrow !== void 0 ? /* @__PURE__ */ jsx("div", { "data-viz-svg-narrow": "true", dangerouslySetInnerHTML: { __html: assertStaticSvg(svgNarrow) } }) : null,
445
+ svgWide !== void 0 ? /* @__PURE__ */ jsx("div", { "data-viz-svg-wide": "true", dangerouslySetInnerHTML: { __html: assertStaticSvg(svgWide) } }) : null,
446
+ description ? /* @__PURE__ */ jsx("p", { "data-viz-description": "true", children: description }) : null
447
+ ]
448
+ }
449
+ );
450
+ }
451
+ return /* @__PURE__ */ jsx(
452
+ "div",
453
+ {
454
+ ref,
455
+ className: classes3("oods-viz-area-preview", className),
456
+ "data-oods-component": "VizAreaPreview",
457
+ "data-viz-preview-type": "area",
458
+ "data-viz-width": width,
459
+ "data-viz-height": height,
460
+ style: { "--oods-viz-width": `${width}px`, "--oods-viz-height": `${height}px`, ...style },
461
+ ...rest,
462
+ children: content.authored || content.scalar !== void 0 ? children : /* @__PURE__ */ jsxs("div", { "data-viz-preview-placeholder": "true", children: [
463
+ "Area preview (",
464
+ width,
465
+ " x ",
466
+ height,
467
+ ")"
468
+ ] })
469
+ }
470
+ );
471
+ }
472
+ );
473
+ VizAreaPreview.displayName = "OODS.VizAreaPreview";
474
+ var firstScalar = (...values) => {
475
+ for (const value of values) {
476
+ if (typeof value === "string") {
477
+ if (value.trim().length > 0) return value;
478
+ continue;
479
+ }
480
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
481
+ }
482
+ return void 0;
483
+ };
484
+ var isRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
485
+ var descriptorLabel = (descriptor) => firstText(
486
+ typeof descriptor.label === "string" ? descriptor.label : void 0,
487
+ typeof descriptor.field === "string" ? descriptor.field : void 0
488
+ ) ?? "Filter";
489
+ function createPanelSection(component, className, panelType, defaultTitle) {
490
+ const Panel = React3.forwardRef(
491
+ ({ title, label, heading, name, subtitle, description, metadata, summary: summary2, text, body, emptyMessage, children, className: consumerClassName, ...rest }, ref) => {
492
+ const content = childContent(children);
493
+ const authored = content.authored || content.scalar !== void 0;
494
+ const resolvedTitle = firstText(title, label, heading, name) ?? defaultTitle;
495
+ const resolvedSubtitle = firstText(subtitle, description, metadata);
496
+ const fallback = firstText(summary2, text, body, emptyMessage);
497
+ return /* @__PURE__ */ jsxs(
498
+ "section",
499
+ {
500
+ ref,
501
+ className: classes3(className, consumerClassName),
502
+ "data-oods-component": component,
503
+ "data-panel-type": panelType,
504
+ ...rest,
505
+ children: [
506
+ /* @__PURE__ */ jsxs("header", { "data-panel-header": "true", children: [
507
+ /* @__PURE__ */ jsx("h2", { children: resolvedTitle }),
508
+ resolvedSubtitle ? /* @__PURE__ */ jsx("span", { "data-panel-subtitle": "true", children: resolvedSubtitle }) : null
509
+ ] }),
510
+ /* @__PURE__ */ jsx("div", { "data-panel-content": "true", children: authored ? children : fallback ? /* @__PURE__ */ jsx("span", { "data-panel-summary": "true", children: fallback }) : null })
511
+ ]
512
+ }
513
+ );
514
+ }
515
+ );
516
+ Panel.displayName = `OODS.${component}`;
517
+ return Panel;
518
+ }
519
+ var ClassificationPanel = createPanelSection("ClassificationPanel", "oods-classification-panel", "classification", "Classification");
520
+ var AddressCollectionPanel = createPanelSection("AddressCollectionPanel", "oods-address-collection-panel", "address", "Addresses");
521
+ var MembershipPanel = createPanelSection("MembershipPanel", "oods-membership-panel", "membership", "Membership");
522
+ var PreferencePanel = createPanelSection("PreferencePanel", "oods-preference-panel", "preference", "Preferences");
523
+ var FilterPanel = React3.forwardRef(
524
+ ({ filters, activeFilters, mode, collapsible = true, children, className, ...rest }, ref) => {
525
+ const content = childContent(children);
526
+ const authored = content.authored || content.scalar !== void 0;
527
+ const resolvedMode = firstText(mode) ?? "immediate";
528
+ const descriptors = (Array.isArray(filters) ? filters : []).filter(isRecord);
529
+ const activeCount = Array.isArray(activeFilters) ? activeFilters.length : 0;
530
+ return /* @__PURE__ */ jsx(
531
+ "aside",
532
+ {
533
+ ref,
534
+ className: classes3("oods-filter-panel", className),
535
+ "data-oods-component": "FilterPanel",
536
+ "data-behavioral": "filter",
537
+ "data-filter-mode": resolvedMode,
538
+ role: "region",
539
+ "aria-label": "Filters",
540
+ ...rest,
541
+ children: authored ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
542
+ activeCount > 0 ? /* @__PURE__ */ jsxs("div", { "data-active-filters": "true", "aria-live": "polite", children: [
543
+ /* @__PURE__ */ jsxs("span", { "data-filter-count": "true", children: [
544
+ activeCount,
545
+ " active"
546
+ ] }),
547
+ /* @__PURE__ */ jsx("button", { type: "button", "data-filter-clear-all": "true", children: "Clear all" })
548
+ ] }) : null,
549
+ descriptors.map((descriptor, index) => /* @__PURE__ */ jsx("fieldset", { "data-filter-section": "true", "data-collapsible": collapsible ? "true" : void 0, children: /* @__PURE__ */ jsx("legend", { children: descriptorLabel(descriptor) }) }, index)),
550
+ resolvedMode === "batch" ? /* @__PURE__ */ jsx("button", { type: "button", "data-filter-apply": "true", children: "Apply" }) : null
551
+ ] })
552
+ }
553
+ );
554
+ }
555
+ );
556
+ FilterPanel.displayName = "OODS.FilterPanel";
557
+ var PriceSummary = React3.forwardRef(
558
+ ({
559
+ title,
560
+ label,
561
+ heading,
562
+ name,
563
+ amount,
564
+ amountCents,
565
+ unitAmountCents,
566
+ minorUnits,
567
+ currency,
568
+ currencyCode,
569
+ model,
570
+ pricingModel,
571
+ interval,
572
+ billingInterval,
573
+ summary: summary2,
574
+ text,
575
+ description,
576
+ children,
577
+ className,
578
+ ...rest
579
+ }, ref) => {
580
+ const content = childContent(children);
581
+ const authored = content.authored || content.scalar !== void 0;
582
+ const resolvedTitle = firstText(title, label, heading, name) ?? "Price Summary";
583
+ const entries = [
584
+ ["Amount", [amount, amountCents, unitAmountCents, currency, currencyCode, model, pricingModel, interval, billingInterval].some((value) => value !== void 0) ? formatPriceAmount(amount ?? amountCents ?? unitAmountCents, firstText(currency, currencyCode), minorUnits) : void 0],
585
+ ["Currency", firstScalar(currency, currencyCode)],
586
+ ["Model", formatPriceCode(model ?? pricingModel)],
587
+ ["Interval", formatPriceCode(interval ?? billingInterval)]
588
+ ];
589
+ const terms = entries.filter((entry) => entry[1] !== void 0);
590
+ const fallback = firstText(summary2, text, description);
591
+ return /* @__PURE__ */ jsxs(
592
+ "section",
593
+ {
594
+ ref,
595
+ className: classes3("oods-price-summary", className),
596
+ "data-oods-component": "PriceSummary",
597
+ "data-summary-type": "price",
598
+ ...rest,
599
+ children: [
600
+ /* @__PURE__ */ jsx("h2", { "data-summary-title": "true", children: resolvedTitle }),
601
+ authored ? children : terms.length > 0 ? /* @__PURE__ */ jsx("dl", { children: terms.map(([term, value]) => /* @__PURE__ */ jsxs("div", { "data-summary-item": "true", children: [
602
+ /* @__PURE__ */ jsx("dt", { children: term }),
603
+ /* @__PURE__ */ jsx("dd", { children: value })
604
+ ] }, term)) }) : fallback ? /* @__PURE__ */ jsx("p", { "data-summary-fallback": "true", children: fallback }) : /* @__PURE__ */ jsx("dl", {})
605
+ ]
606
+ }
607
+ );
608
+ }
609
+ );
610
+ PriceSummary.displayName = "OODS.PriceSummary";
611
+ var normalizeTagItems = (value) => {
612
+ if (!Array.isArray(value)) return [];
613
+ const items = [];
614
+ for (const entry of value) {
615
+ if (entry === void 0 || entry === null) continue;
616
+ if (isRecord(entry)) {
617
+ const text = firstScalar(
618
+ ...["label", "name", "role", "value", "id"].map((key) => {
619
+ const candidate = entry[key];
620
+ return typeof candidate === "string" || typeof candidate === "number" || typeof candidate === "boolean" ? candidate : void 0;
621
+ })
622
+ );
623
+ if (text) items.push(text);
624
+ continue;
625
+ }
626
+ items.push(typeof entry === "object" ? JSON.stringify(entry) : String(entry));
627
+ }
628
+ return items.filter((item) => item.length > 0);
629
+ };
630
+ var TagManager = React3.forwardRef(
631
+ ({ title, label, heading, name, description, subtitle, hint, tags, value, children, className, onSubmit, ...rest }, ref) => {
632
+ const content = childContent(children);
633
+ const authored = content.authored || content.scalar !== void 0;
634
+ const resolvedTitle = firstText(title, label, heading, name) ?? "Tag Manager";
635
+ const resolvedSubtitle = firstText(description, subtitle, hint);
636
+ const items = normalizeTagItems(tags ?? value);
637
+ return /* @__PURE__ */ jsxs(
638
+ "form",
639
+ {
640
+ ref,
641
+ className: classes3("oods-tag-manager", className),
642
+ "data-oods-component": "TagManager",
643
+ "data-form-type": "tag-manager",
644
+ onSubmit: (event) => {
645
+ event.preventDefault();
646
+ onSubmit?.(event);
647
+ },
648
+ ...rest,
649
+ children: [
650
+ /* @__PURE__ */ jsxs("header", { "data-form-header": "true", children: [
651
+ /* @__PURE__ */ jsx("h2", { children: resolvedTitle }),
652
+ resolvedSubtitle ? /* @__PURE__ */ jsx("span", { "data-form-subtitle": "true", children: resolvedSubtitle }) : null
653
+ ] }),
654
+ /* @__PURE__ */ jsx("div", { "data-form-content": "true", children: authored ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
655
+ /* @__PURE__ */ jsx("div", { "data-tag-list": "true", children: items.map((tag, index) => /* @__PURE__ */ jsx("span", { "data-tag-item": "true", children: tag }, index)) }),
656
+ /* @__PURE__ */ jsxs("label", { "data-form-control": "input", children: [
657
+ /* @__PURE__ */ jsx("span", { children: "Add Tag" }),
658
+ /* @__PURE__ */ jsx("input", { type: "text", name: "newTag", placeholder: "Type a tag" })
659
+ ] })
660
+ ] }) })
661
+ ]
662
+ }
663
+ );
664
+ }
665
+ );
666
+ TagManager.displayName = "OODS.TagManager";
667
+ var asCount = (value) => {
668
+ if (typeof value === "number" && Number.isFinite(value)) return value;
669
+ if (typeof value === "string" && value.trim().length > 0) {
670
+ const parsed = Number.parseInt(value, 10);
671
+ if (Number.isFinite(parsed)) return parsed;
672
+ }
673
+ return void 0;
674
+ };
675
+ function createBadgeFamily(options) {
676
+ const consumed = /* @__PURE__ */ new Set([...options.labelKeys, ...options.statusKeys, "variant", "tone", "emphasis"]);
677
+ const Family = React3.forwardRef((allProps, ref) => {
678
+ const { children, className, ...rest } = allProps;
679
+ const record = rest;
680
+ const scalar = (key) => {
681
+ const value = record[key];
682
+ if (typeof value === "boolean" && options.booleanProps?.includes(key)) return String(value);
683
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
684
+ };
685
+ const content = childContent(children);
686
+ 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;
687
+ const status = firstText(...options.statusKeys.map(scalar));
688
+ const variant = scalar("variant") ?? options.defaultVariant;
689
+ const tone = record.tone;
690
+ const emphasis = record.emphasis;
691
+ const domRest = {};
692
+ for (const [key, value] of Object.entries(record)) if (!consumed.has(key)) domRest[key] = value;
693
+ return /* @__PURE__ */ jsx(
694
+ Badge,
695
+ {
696
+ ref,
697
+ status,
698
+ showIcon: false,
699
+ tone,
700
+ emphasis,
701
+ className: classes3(options.className, className),
702
+ "data-oods-component": options.component,
703
+ "data-badge-status": status,
704
+ "data-badge-variant": variant,
705
+ ...domRest,
706
+ children: content.authored ? children : /* @__PURE__ */ jsx("span", { "data-oods-badge-label": "true", children: label })
707
+ }
708
+ );
709
+ });
710
+ Family.displayName = `OODS.${options.component}`;
711
+ return Family;
712
+ }
713
+ var AddressSummaryBadge = createBadgeFamily({
714
+ component: "AddressSummaryBadge",
715
+ className: "oods-address-summary-badge",
716
+ defaultLabel: "Address",
717
+ defaultVariant: "address",
718
+ labelKeys: ["label", "text", "role", "value"],
719
+ statusKeys: ["status", "state", "role"]
720
+ });
721
+ var MessageStatusBadge = createBadgeFamily({
722
+ component: "MessageStatusBadge",
723
+ className: "oods-message-status-badge",
724
+ defaultLabel: "Message",
725
+ defaultVariant: "message",
726
+ labelKeys: ["label", "text", "status", "delivery", "value"],
727
+ statusKeys: ["status", "state", "delivery", "value"]
728
+ });
729
+ var PreferenceSummaryBadge = createBadgeFamily({
730
+ component: "PreferenceSummaryBadge",
731
+ className: "oods-preference-summary-badge",
732
+ defaultLabel: "Preferences",
733
+ defaultVariant: "preference",
734
+ labelKeys: ["label", "text", "namespace", "value"],
735
+ statusKeys: ["status", "state", "version"]
736
+ });
737
+ var RoleBadgeList = React3.forwardRef(
738
+ ({ roles, badges, roleLabels, value, variant, tone, label, text, children, className, ...rest }, ref) => {
739
+ const content = childContent(children);
740
+ const authored = content.authored || content.scalar !== void 0;
741
+ const items = normalizeTagItems(roles ?? badges ?? roleLabels ?? value);
742
+ const resolvedVariant = firstText(variant, tone) ?? "roles";
743
+ return /* @__PURE__ */ jsx(
744
+ "span",
745
+ {
746
+ ref,
747
+ className: classes3("oods-role-badge-list", className),
748
+ "data-oods-component": "RoleBadgeList",
749
+ "data-badge-variant": resolvedVariant,
750
+ ...rest,
751
+ children: authored ? children : items.length > 0 ? items.map((role, index) => /* @__PURE__ */ jsx("span", { "data-role-badge": "true", children: role }, index)) : firstText(label, text) ?? "Roles"
752
+ }
753
+ );
754
+ }
755
+ );
756
+ RoleBadgeList.displayName = "OODS.RoleBadgeList";
757
+ var TagPills = React3.forwardRef(
758
+ ({ tags, value, maxVisible, overflowLabel, children, className, ...rest }, ref) => {
759
+ const content = childContent(children);
760
+ const authored = content.authored || content.scalar !== void 0;
761
+ const items = normalizeTagItems(tags ?? value);
762
+ const limit = asCount(maxVisible) ?? items.length;
763
+ const visible = items.slice(0, Math.max(0, limit));
764
+ const overflow = items.length - visible.length;
765
+ const template = firstText(overflowLabel);
766
+ const overflowText = overflow > 0 ? template ? template.replace("{{ tag_count }}", String(items.length)) : `+${overflow}` : "";
767
+ return /* @__PURE__ */ jsx(
768
+ "div",
769
+ {
770
+ ref,
771
+ className: classes3("oods-tag-pills", className),
772
+ "data-oods-component": "TagPills",
773
+ "data-summary-type": "tag-pills",
774
+ ...rest,
775
+ children: authored ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
776
+ visible.map((tag, index) => /* @__PURE__ */ jsx("span", { "data-tag-pill": "true", children: tag }, index)),
777
+ overflowText ? /* @__PURE__ */ jsx("span", { "data-tag-overflow": "true", children: overflowText }) : null
778
+ ] })
779
+ }
780
+ );
781
+ }
782
+ );
783
+ TagPills.displayName = "OODS.TagPills";
784
+ var normalizeTimelineItems = (raw) => {
785
+ if (!Array.isArray(raw)) return [];
786
+ const items = [];
787
+ const read = (record, keys) => firstScalar(
788
+ ...keys.map((key) => {
789
+ const value = record[key];
790
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean" ? value : void 0;
791
+ })
792
+ );
793
+ for (const entry of raw) {
794
+ if (entry === void 0 || entry === null) continue;
795
+ if (isRecord(entry)) {
796
+ items.push({
797
+ label: read(entry, ["label", "title", "event", "status", "state", "text", "name"]) ?? "Event",
798
+ timestamp: read(entry, ["timestamp", "datetime", "time", "at", "createdAt", "updatedAt"]),
799
+ detail: read(entry, ["detail", "description", "reason", "message", "from", "to"])
800
+ });
801
+ continue;
802
+ }
803
+ items.push({ label: typeof entry === "object" ? JSON.stringify(entry) : String(entry) });
804
+ }
805
+ return items;
806
+ };
807
+ function createTimelineFamily(options) {
808
+ const consumed = /* @__PURE__ */ new Set(["title", "label", "heading", "name", ...options.eventKeys]);
809
+ const Family = React3.forwardRef((allProps, ref) => {
810
+ const { children, className, ...rest } = allProps;
811
+ const record = rest;
812
+ const text = (key) => {
813
+ const value = record[key];
814
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
815
+ };
816
+ const content = childContent(children);
817
+ const authored = content.authored || content.scalar !== void 0;
818
+ const title = firstText(text("title"), text("label"), text("heading"), text("name")) ?? options.defaultTitle;
819
+ const events = normalizeTimelineItems(options.eventKeys.map((key) => record[key]).find((value) => Array.isArray(value)));
820
+ const domRest = {};
821
+ for (const [key, value] of Object.entries(record)) if (!consumed.has(key)) domRest[key] = value;
822
+ return /* @__PURE__ */ jsxs(
823
+ "div",
824
+ {
825
+ ref,
826
+ className: classes3(options.className, className),
827
+ "data-oods-component": options.component,
828
+ "data-timeline-type": options.timelineType,
829
+ role: "log",
830
+ "aria-label": title,
831
+ ...domRest,
832
+ children: [
833
+ /* @__PURE__ */ jsx("h2", { "data-timeline-title": "true", children: title }),
834
+ /* @__PURE__ */ jsx("ol", { "data-timeline-events": "true", children: authored ? children : events.length > 0 ? events.map((item, index) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("article", { "data-timeline-event": "true", children: [
835
+ /* @__PURE__ */ jsx("p", { "data-timeline-label": "true", children: item.label }),
836
+ item.timestamp ? /* @__PURE__ */ jsx("time", { "data-timeline-time": "true", dateTime: item.timestamp, children: item.timestamp }) : null,
837
+ item.detail ? /* @__PURE__ */ jsx("p", { "data-timeline-detail": "true", children: item.detail }) : null
838
+ ] }) }, index)) : /* @__PURE__ */ jsx("li", { "data-timeline-empty": "true", children: "No events" }) })
839
+ ]
840
+ }
841
+ );
842
+ });
843
+ Family.displayName = `OODS.${options.component}`;
844
+ return Family;
845
+ }
846
+ var AddressValidationTimeline = createTimelineFamily({
847
+ component: "AddressValidationTimeline",
848
+ className: "oods-address-validation-timeline",
849
+ defaultTitle: "Address Validation Timeline",
850
+ timelineType: "address-validation",
851
+ eventKeys: ["events", "validations", "history"]
852
+ });
853
+ var MembershipAuditTimeline = createTimelineFamily({
854
+ component: "MembershipAuditTimeline",
855
+ className: "oods-membership-audit-timeline",
856
+ defaultTitle: "Membership Timeline",
857
+ timelineType: "membership",
858
+ eventKeys: ["events", "memberships", "history"]
859
+ });
860
+ var MessageEventTimeline = createTimelineFamily({
861
+ component: "MessageEventTimeline",
862
+ className: "oods-message-event-timeline",
863
+ defaultTitle: "Message Timeline",
864
+ timelineType: "message",
865
+ eventKeys: ["events", "messages", "statuses"]
866
+ });
867
+ var PreferenceTimeline = createTimelineFamily({
868
+ component: "PreferenceTimeline",
869
+ className: "oods-preference-timeline",
870
+ defaultTitle: "Preference Timeline",
871
+ timelineType: "preference",
872
+ eventKeys: ["events", "changes", "history"]
873
+ });
874
+ var AuditEvent = React3.forwardRef(
875
+ ({
876
+ label,
877
+ title,
878
+ event,
879
+ status,
880
+ state,
881
+ reason,
882
+ text,
883
+ timestamp,
884
+ datetime,
885
+ time,
886
+ at,
887
+ createdAt,
888
+ updatedAt,
889
+ detail,
890
+ description,
891
+ message,
892
+ from,
893
+ to,
894
+ code,
895
+ children,
896
+ className,
897
+ ...rest
898
+ }, ref) => {
899
+ const content = childContent(children);
900
+ const authored = content.authored || content.scalar !== void 0;
901
+ const resolvedLabel = firstText(label, title, event, status, state, reason, text) ?? "Audit Event";
902
+ const resolvedTimestamp = firstText(timestamp, datetime, time, at, createdAt, updatedAt);
903
+ const resolvedDetail = firstText(detail, description, reason, message, from, to, code);
904
+ return /* @__PURE__ */ jsx(
905
+ "article",
906
+ {
907
+ ref,
908
+ className: classes3("oods-audit-event", className),
909
+ "data-oods-component": "AuditEvent",
910
+ "data-event-type": "audit",
911
+ ...rest,
912
+ children: authored ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
913
+ resolvedTimestamp ? /* @__PURE__ */ jsx("time", { "data-event-time": "true", dateTime: resolvedTimestamp, children: resolvedTimestamp }) : null,
914
+ /* @__PURE__ */ jsx("p", { "data-event-label": "true", children: resolvedLabel }),
915
+ resolvedDetail ? /* @__PURE__ */ jsx("p", { "data-event-detail": "true", children: resolvedDetail }) : null
916
+ ] })
917
+ }
918
+ );
919
+ }
920
+ );
921
+ AuditEvent.displayName = "OODS.AuditEvent";
922
+ var normalizeSelectOptions = (raw) => {
923
+ if (!Array.isArray(raw)) return [];
924
+ const choices = [];
925
+ for (const entry of raw) {
926
+ if (isRecord(entry)) {
927
+ const text = (key) => typeof entry[key] === "string" && entry[key].length > 0 ? entry[key] : void 0;
928
+ const value2 = text("value") ?? text("id") ?? text("label") ?? "";
929
+ const label = text("label") ?? text("name") ?? formatReadOnlyValue(value2, "string", true);
930
+ if (!value2 && !label) continue;
931
+ choices.push({ value: value2, label });
932
+ continue;
933
+ }
934
+ if (entry === void 0 || entry === null) continue;
935
+ const value = typeof entry === "object" ? JSON.stringify(entry) : String(entry);
936
+ if (!value) continue;
937
+ choices.push({ value, label: formatReadOnlyValue(value, "string", true) });
938
+ }
939
+ return choices;
940
+ };
941
+ var selectOptionsMarkup = (choices) => choices.length > 0 ? choices.map((choice, index) => /* @__PURE__ */ jsx("option", { value: choice.value, children: choice.label }, index)) : /* @__PURE__ */ jsx("option", { value: "", children: "Select..." });
942
+ var preventSubmit = (event) => {
943
+ event.preventDefault();
944
+ };
945
+ var formHeader = (title, subtitle) => /* @__PURE__ */ jsxs("header", { "data-form-header": "true", children: [
946
+ /* @__PURE__ */ jsx("h2", { children: title }),
947
+ subtitle ? /* @__PURE__ */ jsx("span", { "data-form-subtitle": "true", children: subtitle }) : null
948
+ ] });
949
+ var fieldsetHeader = (title, subtitle) => /* @__PURE__ */ jsxs(Fragment, { children: [
950
+ /* @__PURE__ */ jsx("legend", { children: title }),
951
+ subtitle ? /* @__PURE__ */ jsx("span", { "data-form-subtitle": "true", children: subtitle }) : null
952
+ ] });
953
+ var addressRecord = (form) => {
954
+ const read = (name) => {
955
+ const control = form?.elements.namedItem(name);
956
+ return control instanceof HTMLInputElement ? control.value : "";
957
+ };
958
+ return { street: read("street"), city: read("city"), region: read("region"), postalCode: read("postalCode") };
959
+ };
960
+ var AddressEditor = React3.forwardRef(
961
+ ({
962
+ title,
963
+ label,
964
+ heading,
965
+ name,
966
+ description,
967
+ subtitle,
968
+ hint,
969
+ street,
970
+ line1,
971
+ addressLine1,
972
+ city,
973
+ region,
974
+ state,
975
+ postalCode,
976
+ zip,
977
+ children,
978
+ className,
979
+ onChange,
980
+ onSubmit,
981
+ ...rest
982
+ }, ref) => {
983
+ const content = childContent(children);
984
+ const authored = content.authored || content.scalar !== void 0;
985
+ const resolvedTitle = firstText(title, label, heading, name) ?? "Address Editor";
986
+ const resolvedSubtitle = firstText(description, subtitle, hint);
987
+ const publish = (event) => onChange?.(addressRecord(event.currentTarget.form));
988
+ const control = (fieldLabel, fieldName, initial) => /* @__PURE__ */ jsxs("label", { "data-form-control": "input", children: [
989
+ /* @__PURE__ */ jsx("span", { children: fieldLabel }),
990
+ /* @__PURE__ */ jsx("input", { type: "text", name: fieldName, defaultValue: initial, onChange: publish })
991
+ ] });
992
+ return /* @__PURE__ */ jsxs(
993
+ "form",
994
+ {
995
+ ref,
996
+ className: classes3("oods-address-editor", className),
997
+ "data-oods-component": "AddressEditor",
998
+ "data-form-type": "address-editor",
999
+ onSubmit: (event) => {
1000
+ preventSubmit(event);
1001
+ onSubmit?.(event);
1002
+ },
1003
+ ...rest,
1004
+ children: [
1005
+ formHeader(resolvedTitle, resolvedSubtitle),
1006
+ /* @__PURE__ */ jsx("div", { "data-form-content": "true", children: authored ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
1007
+ control("Street", "street", firstText(street, line1, addressLine1)),
1008
+ control("City", "city", firstText(city)),
1009
+ control("Region", "region", firstText(region, state)),
1010
+ control("Postal Code", "postalCode", firstText(postalCode, zip))
1011
+ ] }) })
1012
+ ]
1013
+ }
1014
+ );
1015
+ }
1016
+ );
1017
+ AddressEditor.displayName = "OODS.AddressEditor";
1018
+ var PreferenceEditor = React3.forwardRef(
1019
+ ({ title, label, heading, name, description, subtitle, hint, namespaces, namespace, document, json, value, children, className, onSubmit, ...rest }, ref) => {
1020
+ const content = childContent(children);
1021
+ const authored = content.authored || content.scalar !== void 0;
1022
+ const resolvedTitle = firstText(title, label, heading, name) ?? "Preference Editor";
1023
+ const resolvedSubtitle = firstText(description, subtitle, hint);
1024
+ const choices = normalizeSelectOptions(Array.isArray(namespaces) ? namespaces : ["default"]);
1025
+ return /* @__PURE__ */ jsxs(
1026
+ "form",
1027
+ {
1028
+ ref,
1029
+ className: classes3("oods-preference-editor", className),
1030
+ "data-oods-component": "PreferenceEditor",
1031
+ "data-form-type": "preference-editor",
1032
+ onSubmit: (event) => {
1033
+ preventSubmit(event);
1034
+ onSubmit?.(event);
1035
+ },
1036
+ ...rest,
1037
+ children: [
1038
+ formHeader(resolvedTitle, resolvedSubtitle),
1039
+ /* @__PURE__ */ jsx("div", { "data-form-content": "true", children: authored ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
1040
+ /* @__PURE__ */ jsxs("label", { "data-form-control": "select", children: [
1041
+ /* @__PURE__ */ jsx("span", { children: "Namespace" }),
1042
+ /* @__PURE__ */ jsx("select", { name: "namespace", defaultValue: firstText(namespace), children: selectOptionsMarkup(choices) })
1043
+ ] }),
1044
+ /* @__PURE__ */ jsxs("label", { "data-form-control": "textarea", children: [
1045
+ /* @__PURE__ */ jsx("span", { children: "Preference Document" }),
1046
+ /* @__PURE__ */ jsx("textarea", { name: "preferenceDocument", defaultValue: firstScalar(document, json, value) ?? "" })
1047
+ ] })
1048
+ ] }) })
1049
+ ]
1050
+ }
1051
+ );
1052
+ }
1053
+ );
1054
+ PreferenceEditor.displayName = "OODS.PreferenceEditor";
1055
+ var RoleAssignmentForm = React3.forwardRef(
1056
+ ({ title, label, heading, name, description, subtitle, hint, roles, availableRoles, role, defaultRoleId, assignee, member, children, className, onSubmit, ...rest }, ref) => {
1057
+ const content = childContent(children);
1058
+ const authored = content.authored || content.scalar !== void 0;
1059
+ const resolvedTitle = firstText(title, label, heading, name) ?? "Role Assignment";
1060
+ const resolvedSubtitle = firstText(description, subtitle, hint);
1061
+ const choices = normalizeSelectOptions(roles ?? availableRoles ?? []);
1062
+ return /* @__PURE__ */ jsxs(
1063
+ "form",
1064
+ {
1065
+ ref,
1066
+ className: classes3("oods-role-assignment-form", className),
1067
+ "data-oods-component": "RoleAssignmentForm",
1068
+ "data-form-type": "role-assignment",
1069
+ onSubmit: (event) => {
1070
+ preventSubmit(event);
1071
+ onSubmit?.(event);
1072
+ },
1073
+ ...rest,
1074
+ children: [
1075
+ formHeader(resolvedTitle, resolvedSubtitle),
1076
+ /* @__PURE__ */ jsx("div", { "data-form-content": "true", children: authored ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
1077
+ /* @__PURE__ */ jsxs("label", { "data-form-control": "select", children: [
1078
+ /* @__PURE__ */ jsx("span", { children: "Role" }),
1079
+ /* @__PURE__ */ jsx("select", { name: "role", defaultValue: firstText(role, defaultRoleId), children: selectOptionsMarkup(choices) })
1080
+ ] }),
1081
+ /* @__PURE__ */ jsxs("label", { "data-form-control": "input", children: [
1082
+ /* @__PURE__ */ jsx("span", { children: "Assignee" }),
1083
+ /* @__PURE__ */ jsx("input", { type: "text", name: "assignee", defaultValue: firstText(assignee, member) })
1084
+ ] })
1085
+ ] }) })
1086
+ ]
1087
+ }
1088
+ );
1089
+ }
1090
+ );
1091
+ RoleAssignmentForm.displayName = "OODS.RoleAssignmentForm";
1092
+ var StatusSelector = React3.forwardRef(
1093
+ ({ label, title, help, options, states, value, status, children, className, onChange, onValueChange, onUpdate, ...rest }, ref) => {
1094
+ const content = childContent(children);
1095
+ const authored = content.authored || content.scalar !== void 0;
1096
+ const resolvedLabel = firstText(label, title) ?? "Status";
1097
+ const choices = normalizeSelectOptions(options ?? states ?? ["draft", "active", "inactive"]);
1098
+ const handleChange = (event) => {
1099
+ onChange?.(event);
1100
+ if (!event.defaultPrevented) {
1101
+ onValueChange?.(event.currentTarget.value);
1102
+ onUpdate?.(event.currentTarget.value);
1103
+ }
1104
+ };
1105
+ const controlled = value !== void 0;
1106
+ return /* @__PURE__ */ jsxs(
1107
+ "div",
1108
+ {
1109
+ ref,
1110
+ className: classes3("oods-status-selector", className),
1111
+ "data-oods-component": "StatusSelector",
1112
+ "data-summary-type": "status-selector",
1113
+ ...rest,
1114
+ children: [
1115
+ authored ? children : /* @__PURE__ */ jsxs("label", { "data-form-control": "select", children: [
1116
+ /* @__PURE__ */ jsx("span", { children: resolvedLabel }),
1117
+ /* @__PURE__ */ jsx(
1118
+ "select",
1119
+ {
1120
+ name: "status",
1121
+ ...controlled ? { value } : { defaultValue: firstText(status) },
1122
+ onChange: handleChange,
1123
+ children: selectOptionsMarkup(choices)
1124
+ }
1125
+ )
1126
+ ] }),
1127
+ help && /* @__PURE__ */ jsx("p", { className: "oods-field-help", children: help })
1128
+ ]
1129
+ }
1130
+ );
1131
+ }
1132
+ );
1133
+ StatusSelector.displayName = "OODS.StatusSelector";
1134
+ var TagInput = React3.forwardRef(
1135
+ ({ title, label, heading, name, description, subtitle, hint, tags, value, placeholder, children, className, onChange, onValueChange, onUpdate, ...rest }, ref) => {
1136
+ const content = childContent(children);
1137
+ const authored = content.authored || content.scalar !== void 0;
1138
+ const resolvedTitle = firstText(title, label, heading, name) ?? "Tag Input";
1139
+ const resolvedSubtitle = firstText(description, subtitle, hint);
1140
+ const items = normalizeTagItems(tags);
1141
+ const handleChange = (event) => {
1142
+ onChange?.(event);
1143
+ if (!event.defaultPrevented) {
1144
+ onValueChange?.(event.currentTarget.value);
1145
+ onUpdate?.(event.currentTarget.value);
1146
+ }
1147
+ };
1148
+ const controlled = value !== void 0;
1149
+ return /* @__PURE__ */ jsxs(
1150
+ "fieldset",
1151
+ {
1152
+ ref,
1153
+ className: classes3("oods-tag-input", className),
1154
+ "data-oods-component": "TagInput",
1155
+ "data-form-type": "tag-input",
1156
+ ...rest,
1157
+ children: [
1158
+ fieldsetHeader(resolvedTitle, resolvedSubtitle),
1159
+ /* @__PURE__ */ jsx("div", { "data-form-content": "true", children: authored ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
1160
+ /* @__PURE__ */ jsxs("label", { "data-form-control": "input", children: [
1161
+ /* @__PURE__ */ jsx("span", { children: "Tag" }),
1162
+ /* @__PURE__ */ jsx(
1163
+ "input",
1164
+ {
1165
+ type: "text",
1166
+ name: "tag",
1167
+ placeholder: firstText(placeholder),
1168
+ ...controlled ? { value } : {},
1169
+ onChange: handleChange
1170
+ }
1171
+ )
1172
+ ] }),
1173
+ items.length > 0 ? /* @__PURE__ */ jsx("div", { "data-tag-list": "true", children: items.map((tag, index) => /* @__PURE__ */ jsx("span", { "data-tag-item": "true", children: tag }, index)) }) : null
1174
+ ] }) })
1175
+ ]
1176
+ }
1177
+ );
1178
+ }
1179
+ );
1180
+ TagInput.displayName = "OODS.TagInput";
1181
+ var TemplatePicker = React3.forwardRef(
1182
+ ({ title, label, heading, name, description, subtitle, hint, templates, options, templateId, value, channels, channel, children, className, ...rest }, ref) => {
1183
+ const content = childContent(children);
1184
+ const authored = content.authored || content.scalar !== void 0;
1185
+ const resolvedTitle = firstText(title, label, heading, name) ?? "Template Picker";
1186
+ const resolvedSubtitle = firstText(description, subtitle, hint);
1187
+ const templateChoices = normalizeSelectOptions(templates ?? options ?? []);
1188
+ const channelChoices = normalizeSelectOptions(channels ?? ["email", "sms", "in_app"]);
1189
+ return /* @__PURE__ */ jsxs(
1190
+ "fieldset",
1191
+ {
1192
+ ref,
1193
+ className: classes3("oods-template-picker", className),
1194
+ "data-oods-component": "TemplatePicker",
1195
+ "data-form-type": "template-picker",
1196
+ ...rest,
1197
+ children: [
1198
+ fieldsetHeader(resolvedTitle, resolvedSubtitle),
1199
+ /* @__PURE__ */ jsx("div", { "data-form-content": "true", children: authored ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
1200
+ /* @__PURE__ */ jsxs("label", { "data-form-control": "select", children: [
1201
+ /* @__PURE__ */ jsx("span", { children: "Template" }),
1202
+ /* @__PURE__ */ jsx("select", { name: "template", defaultValue: firstText(templateId, value), children: selectOptionsMarkup(templateChoices) })
1203
+ ] }),
1204
+ /* @__PURE__ */ jsxs("label", { "data-form-control": "select", children: [
1205
+ /* @__PURE__ */ jsx("span", { children: "Channel" }),
1206
+ /* @__PURE__ */ jsx("select", { name: "channel", defaultValue: firstText(channel), children: selectOptionsMarkup(channelChoices) })
1207
+ ] })
1208
+ ] }) })
1209
+ ]
1210
+ }
1211
+ );
1212
+ }
1213
+ );
1214
+ TemplatePicker.displayName = "OODS.TemplatePicker";
1215
+ var truncateLabel = (value, maxLength) => {
1216
+ const limit = typeof maxLength === "number" ? maxLength : Number(maxLength);
1217
+ return !Number.isFinite(limit) || limit <= 0 || value.length <= limit ? value : `${value.slice(0, Math.max(0, limit - 1)).trimEnd()}...`;
1218
+ };
1219
+ var InlineLabel = React3.forwardRef(
1220
+ ({ label, text, value, maxLength, children, className, ...rest }, ref) => {
1221
+ const content = childContent(children);
1222
+ return /* @__PURE__ */ jsx("span", { ref, className: classes3("oods-inline-label", className), "data-oods-component": "InlineLabel", ...rest, children: content.authored || content.scalar !== void 0 ? children : truncateLabel(firstText(label, text, value) ?? "", maxLength) });
1223
+ }
1224
+ );
1225
+ InlineLabel.displayName = "OODS.InlineLabel";
1226
+ var LabelCell = React3.forwardRef(
1227
+ ({ label, text, value, description, subtitle, sublabel, supporting, truncate, maxLength, children, className, ...rest }, ref) => {
1228
+ const content = childContent(children);
1229
+ const limit = truncate ? maxLength ?? 40 : maxLength;
1230
+ const primary = truncateLabel(firstText(label, text, value) ?? "", limit);
1231
+ const detail = notEcho(firstText(description, subtitle, sublabel, supporting), firstText(label, text, value));
1232
+ return /* @__PURE__ */ jsx("span", { ref, className: classes3("oods-label-cell", className), "data-oods-component": "LabelCell", ...rest, children: content.authored || content.scalar !== void 0 ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
1233
+ /* @__PURE__ */ jsx("span", { "data-oods-label-cell-primary": "true", children: primary }),
1234
+ detail ? /* @__PURE__ */ jsx("span", { "data-oods-label-cell-description": "true", children: truncateLabel(detail, limit) }) : null
1235
+ ] }) });
1236
+ }
1237
+ );
1238
+ LabelCell.displayName = "OODS.LabelCell";
1239
+ var FormLabelGroup = React3.forwardRef(
1240
+ ({ label, text, title, placeholder, hint, description, htmlFor, for: forId, inputId, children, className, ...rest }, ref) => {
1241
+ const detail = firstText(placeholder, hint, description);
1242
+ return /* @__PURE__ */ jsxs("label", { ref, className: classes3("oods-form-label-group", className), "data-oods-component": "FormLabelGroup", htmlFor: htmlFor ?? forId ?? inputId, ...rest, children: [
1243
+ /* @__PURE__ */ jsx("span", { "data-oods-form-label": "true", children: firstText(label, text, title) ?? "Label" }),
1244
+ children,
1245
+ detail ? /* @__PURE__ */ jsx("span", { "data-oods-form-hint": "true", children: detail }) : null
1246
+ ] });
1247
+ }
1248
+ );
1249
+ FormLabelGroup.displayName = "OODS.FormLabelGroup";
1250
+ var ClassificationBadge = createBadgeFamily({
1251
+ component: "ClassificationBadge",
1252
+ className: "oods-classification-badge",
1253
+ defaultLabel: "Classification",
1254
+ defaultVariant: "classification",
1255
+ labelKeys: ["label", "text", "category", "value"],
1256
+ statusKeys: ["status", "state", "mode"]
1257
+ });
1258
+ var ClassificationEditor = React3.forwardRef(
1259
+ ({ title, label, heading, name, description, subtitle, hint, category, primaryCategory, tags, modes, mode, classificationMode, children, className, onSubmit, ...rest }, ref) => {
1260
+ const content = childContent(children);
1261
+ const tagText = typeof tags === "string" ? tags : tags === void 0 ? "" : JSON.stringify(tags);
1262
+ return /* @__PURE__ */ jsxs(
1263
+ "form",
1264
+ {
1265
+ ref,
1266
+ className: classes3("oods-classification-editor", className),
1267
+ "data-oods-component": "ClassificationEditor",
1268
+ "data-form-type": "classification-editor",
1269
+ onSubmit: (event) => {
1270
+ preventSubmit(event);
1271
+ onSubmit?.(event);
1272
+ },
1273
+ ...rest,
1274
+ children: [
1275
+ formHeader(firstText(title, label, heading, name) ?? "Classification Editor", firstText(description, subtitle, hint)),
1276
+ /* @__PURE__ */ jsx("div", { "data-form-content": "true", children: content.authored || content.scalar !== void 0 ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
1277
+ /* @__PURE__ */ jsxs("label", { "data-form-control": "input", children: [
1278
+ /* @__PURE__ */ jsx("span", { children: "Category" }),
1279
+ /* @__PURE__ */ jsx("input", { type: "text", name: "category", defaultValue: firstText(category, primaryCategory) ?? "" })
1280
+ ] }),
1281
+ /* @__PURE__ */ jsxs("label", { "data-form-control": "input", children: [
1282
+ /* @__PURE__ */ jsx("span", { children: "Tags" }),
1283
+ /* @__PURE__ */ jsx("input", { type: "text", name: "tags", placeholder: "tag-1, tag-2", defaultValue: tagText })
1284
+ ] }),
1285
+ /* @__PURE__ */ jsxs("label", { "data-form-control": "select", children: [
1286
+ /* @__PURE__ */ jsx("span", { children: "Mode" }),
1287
+ /* @__PURE__ */ jsx("select", { name: "mode", defaultValue: firstText(mode, classificationMode), children: selectOptionsMarkup(normalizeSelectOptions(Array.isArray(modes) ? modes : ["strict", "flexible"])) })
1288
+ ] })
1289
+ ] }) })
1290
+ ]
1291
+ }
1292
+ );
1293
+ }
1294
+ );
1295
+ ClassificationEditor.displayName = "OODS.ClassificationEditor";
1296
+ var OwnerBadge = createBadgeFamily({
1297
+ component: "OwnerBadge",
1298
+ className: "oods-owner-badge",
1299
+ defaultLabel: "Owner",
1300
+ defaultVariant: "owner",
1301
+ labelKeys: ["label", "text", "owner", "ownerType", "value"],
1302
+ statusKeys: ["status", "state"]
1303
+ });
1304
+ var OwnershipSummary = React3.forwardRef(
1305
+ ({ title, label, heading, name, ownerLabel, ownerId, owner_id, ownerType, owner_type, role, ownershipRole, summary: summary2, text, description, children, className, ...rest }, ref) => {
1306
+ const content = childContent(children);
1307
+ const terms = [["Owner", ownerId === void 0 && owner_id === void 0 && ownerLabel === void 0 ? void 0 : formatReferenceLabel(ownerId ?? owner_id, ownerLabel, "Owner")], ["Owner Type", firstScalar(ownerType, owner_type)], ["Role", firstScalar(role, ownershipRole)]].filter((entry) => entry[1] !== void 0);
1308
+ const fallback = firstText(summary2, text, description);
1309
+ return /* @__PURE__ */ jsxs("section", { ref, className: classes3("oods-ownership-summary", className), "data-oods-component": "OwnershipSummary", "data-summary-type": "ownership", ...rest, children: [
1310
+ /* @__PURE__ */ jsx("h2", { "data-summary-title": "true", children: firstText(title, label, heading, name) ?? "Ownership Summary" }),
1311
+ content.authored || content.scalar !== void 0 ? children : terms.length ? /* @__PURE__ */ jsx("dl", { children: terms.map(([term, value]) => /* @__PURE__ */ jsxs("div", { "data-summary-item": "true", children: [
1312
+ /* @__PURE__ */ jsx("dt", { children: term }),
1313
+ /* @__PURE__ */ jsx("dd", { children: value })
1314
+ ] }, term)) }) : fallback ? /* @__PURE__ */ jsx("p", { "data-summary-fallback": "true", children: fallback }) : /* @__PURE__ */ jsx("dl", {})
1315
+ ] });
1316
+ }
1317
+ );
1318
+ OwnershipSummary.displayName = "OODS.OwnershipSummary";
1319
+ var TagSummary = React3.forwardRef(
1320
+ ({ title, label, heading, name, tagCount, count, tags, summary: summary2, text, description, children, className, ...rest }, ref) => {
1321
+ const content = childContent(children);
1322
+ const tagText = Array.isArray(tags) ? normalizeTagItems(tags).join(", ") || void 0 : firstText(tags);
1323
+ const terms = [["Tag Count", firstScalar(tagCount, count)], ["Tags", tagText]].filter((entry) => entry[1] !== void 0);
1324
+ const fallback = firstText(summary2, text, description);
1325
+ return /* @__PURE__ */ jsxs("section", { ref, className: classes3("oods-tags-summary", className), "data-oods-component": "TagSummary", "data-summary-type": "tags", ...rest, children: [
1326
+ /* @__PURE__ */ jsx("h2", { "data-summary-title": "true", children: firstText(title, label, heading, name) ?? "Tag Summary" }),
1327
+ content.authored || content.scalar !== void 0 ? children : terms.length ? /* @__PURE__ */ jsx("dl", { children: terms.map(([term, value]) => /* @__PURE__ */ jsxs("div", { "data-summary-item": "true", children: [
1328
+ /* @__PURE__ */ jsx("dt", { children: term }),
1329
+ /* @__PURE__ */ jsx("dd", { children: value })
1330
+ ] }, term)) }) : fallback ? /* @__PURE__ */ jsx("p", { "data-summary-fallback": "true", children: fallback }) : /* @__PURE__ */ jsx("dl", {})
1331
+ ] });
1332
+ }
1333
+ );
1334
+ TagSummary.displayName = "OODS.TagSummary";
1335
+ var OwnershipMeta = React3.forwardRef(
1336
+ ({ title, label, heading, name, ownerType, owner_type, role, ownershipRole, children, className, ...rest }, ref) => {
1337
+ const content = childContent(children);
1338
+ const terms = [["Owner Type", firstScalar(ownerType, owner_type)], ["Role", firstScalar(role, ownershipRole)]].filter((entry) => entry[1] !== void 0);
1339
+ return /* @__PURE__ */ jsx("div", { ref, className: classes3("oods-ownership-meta", className), "data-oods-component": "OwnershipMeta", "data-meta-type": "ownership", ...rest, children: content.authored || content.scalar !== void 0 ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
1340
+ /* @__PURE__ */ jsx("span", { "data-meta-title": "true", children: firstText(title, label, heading, name) ?? "Ownership" }),
1341
+ terms.map(([term, value]) => /* @__PURE__ */ jsxs("span", { "data-meta-item": "true", children: [
1342
+ /* @__PURE__ */ jsxs("strong", { children: [
1343
+ term,
1344
+ ":"
1345
+ ] }),
1346
+ " ",
1347
+ value
1348
+ ] }, term))
1349
+ ] }) });
1350
+ }
1351
+ );
1352
+ OwnershipMeta.displayName = "OODS.OwnershipMeta";
1353
+ var ArchivePill = createBadgeFamily({
1354
+ component: "ArchivePill",
1355
+ className: "oods-archive-pill",
1356
+ defaultLabel: "Archive",
1357
+ defaultVariant: "archive",
1358
+ labelKeys: ["label", "text", "status", "state", "isArchived", "value"],
1359
+ statusKeys: ["status", "state", "isArchived", "value"],
1360
+ booleanProps: ["isArchived", "value"]
1361
+ });
1362
+ var CancellationBadge = createBadgeFamily({
1363
+ component: "CancellationBadge",
1364
+ className: "oods-cancellation-badge",
1365
+ defaultLabel: "Cancellation",
1366
+ defaultVariant: "cancellation",
1367
+ labelKeys: ["label", "text", "status", "state", "cancelAtPeriodEnd", "value"],
1368
+ statusKeys: ["status", "state", "cancelAtPeriodEnd", "isCancelled", "value"],
1369
+ booleanProps: ["cancelAtPeriodEnd", "isCancelled", "value"]
1370
+ });
1371
+ var ArchiveSummary = React3.forwardRef(
1372
+ ({ title, label, heading, name, isArchived, archived, status, archivedAt, reason, archiveReason, summary: summary2, text, description, children, className, ...rest }, ref) => {
1373
+ const content = childContent(children);
1374
+ const terms = [["Archived", summaryValue(isArchived ?? archived ?? status)], ["Archived At", archivedAt ? formatDateTime(archivedAt) : void 0], ["Reason", firstText(reason, archiveReason)]].filter((entry) => entry[1] !== void 0);
1375
+ const fallback = firstText(summary2, text, description);
1376
+ return /* @__PURE__ */ jsxs("section", { ref, className: classes3("oods-archive-summary", className), "data-oods-component": "ArchiveSummary", "data-summary-type": "archive", ...rest, children: [
1377
+ /* @__PURE__ */ jsx("h2", { "data-summary-title": "true", children: firstText(title, label, heading, name) ?? "Archive Summary" }),
1378
+ content.authored || content.scalar !== void 0 ? children : terms.length ? /* @__PURE__ */ jsx("dl", { children: terms.map(([term, value]) => /* @__PURE__ */ jsxs("div", { "data-summary-item": "true", children: [
1379
+ /* @__PURE__ */ jsx("dt", { children: term }),
1380
+ /* @__PURE__ */ jsx("dd", { children: value })
1381
+ ] }, term)) }) : fallback ? /* @__PURE__ */ jsx("p", { "data-summary-fallback": "true", children: fallback }) : /* @__PURE__ */ jsx("dl", {})
1382
+ ] });
1383
+ }
1384
+ );
1385
+ ArchiveSummary.displayName = "OODS.ArchiveSummary";
1386
+ var PriceCardMeta = React3.forwardRef(
1387
+ ({ title, label, heading, name, model, pricingModel, interval, billingInterval, children, className, ...rest }, ref) => {
1388
+ const content = childContent(children);
1389
+ const terms = [["Model", firstText(model, pricingModel)], ["Interval", firstText(interval, billingInterval)]].filter((entry) => entry[1] !== void 0);
1390
+ return /* @__PURE__ */ jsx("div", { ref, className: classes3("oods-price-card-meta", className), "data-oods-component": "PriceCardMeta", "data-meta-type": "price", ...rest, children: content.authored || content.scalar !== void 0 ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
1391
+ /* @__PURE__ */ jsx("span", { "data-meta-title": "true", children: firstText(title, label, heading, name) ?? "Price" }),
1392
+ terms.map(([term, value]) => /* @__PURE__ */ jsxs("span", { "data-meta-item": "true", children: [
1393
+ /* @__PURE__ */ jsxs("strong", { children: [
1394
+ term,
1395
+ ":"
1396
+ ] }),
1397
+ " ",
1398
+ value
1399
+ ] }, term))
1400
+ ] }) });
1401
+ }
1402
+ );
1403
+ PriceCardMeta.displayName = "OODS.PriceCardMeta";
1404
+ var CancellationForm = React3.forwardRef(
1405
+ ({ title, label, heading, name, description, subtitle, hint, allowedReasons, reasonCode, reason, cancellationReason, embedded, reasonHelp, codeHelp, children, className, onSubmit, ...rest }, ref) => {
1406
+ const content = childContent(children);
1407
+ const choices = normalizeSelectOptions(allowedReasons ?? ["no_longer_needed", "budget", "duplicate"]);
1408
+ if (reasonCode && !choices.some((choice) => choice.value === reasonCode)) choices.unshift({ value: reasonCode, label: reasonCode });
1409
+ return React3.createElement(embedded ? "fieldset" : "form", {
1410
+ ...rest,
1411
+ ref,
1412
+ className: classes3("oods-cancellation-form", className),
1413
+ "data-oods-component": "CancellationForm",
1414
+ "data-form-type": "cancellation",
1415
+ ...!embedded ? { onSubmit: (event) => {
1416
+ preventSubmit(event);
1417
+ onSubmit?.(event);
1418
+ } } : {}
1419
+ }, /* @__PURE__ */ jsxs(Fragment, { children: [
1420
+ formHeader(firstText(title, label, heading, name) ?? "Cancellation Form", firstText(description, subtitle, hint)),
1421
+ /* @__PURE__ */ jsx("div", { "data-form-content": "true", children: content.authored || content.scalar !== void 0 ? children : /* @__PURE__ */ jsxs(Fragment, { children: [
1422
+ /* @__PURE__ */ jsxs("label", { "data-form-control": "select", children: [
1423
+ /* @__PURE__ */ jsx("span", { children: "Reason Code" }),
1424
+ allowedReasons?.length === 0 ? /* @__PURE__ */ jsx("input", { name: "reasonCode", defaultValue: reasonCode ?? "" }) : /* @__PURE__ */ jsx("select", { name: "reasonCode", defaultValue: reasonCode, children: selectOptionsMarkup(choices) })
1425
+ ] }),
1426
+ codeHelp && /* @__PURE__ */ jsx("p", { className: "oods-field-help", children: codeHelp }),
1427
+ /* @__PURE__ */ jsxs("label", { "data-form-control": "textarea", children: [
1428
+ /* @__PURE__ */ jsx("span", { children: "Reason" }),
1429
+ /* @__PURE__ */ jsx("textarea", { name: "reason", defaultValue: firstText(reason, cancellationReason) ?? "" })
1430
+ ] }),
1431
+ reasonHelp && /* @__PURE__ */ jsx("p", { className: "oods-field-help", children: reasonHelp })
1432
+ ] }) })
1433
+ ] }));
1434
+ }
1435
+ );
1436
+ CancellationForm.displayName = "OODS.CancellationForm";
1437
+ function BillingSummaryBadge({ id, amount, currency, minorUnits, interval, showInterval = true, className }) {
1438
+ return /* @__PURE__ */ jsx("span", { id, className: `oods-billing-summary ${className ?? ""}`.trim(), "data-oods-component": "BillingSummaryBadge", children: showInterval ? billingSummary(amount, currency, minorUnits, interval) : formatBillingAmount(amount, currency, minorUnits) });
1439
+ }
1440
+ function BillingAmountInput({ id, amount, currency = "usd", minorUnits = BILLING_MINOR_UNITS, label = "Billing amount", name, disabled, className, help, onChange }) {
1441
+ const generatedId = React3.useId();
1442
+ const controlId = id ?? `billing-amount-${generatedId}`;
1443
+ const [text, setText] = React3.useState(() => billingAmountText(amount, minorUnits));
1444
+ const [error, setError] = React3.useState(() => billingAmountMessage(amount, minorUnits));
1445
+ React3.useEffect(() => {
1446
+ setText(billingAmountText(amount, minorUnits));
1447
+ setError(billingAmountMessage(amount, minorUnits));
1448
+ }, [amount, minorUnits]);
1449
+ return /* @__PURE__ */ jsxs("div", { className: `oods-billing-field ${className ?? ""}`.trim(), "data-oods-component": "BillingAmountInput", "data-state": error ? "invalid" : "editing", children: [
1450
+ /* @__PURE__ */ jsx("label", { htmlFor: controlId, children: label }),
1451
+ /* @__PURE__ */ jsx("span", { id: `${controlId}-currency`, children: currency.toUpperCase() }),
1452
+ /* @__PURE__ */ jsx(
1453
+ "input",
1454
+ {
1455
+ id: controlId,
1456
+ name,
1457
+ type: "text",
1458
+ inputMode: "decimal",
1459
+ value: text,
1460
+ disabled,
1461
+ "data-billing-minor-units": minorUnits,
1462
+ "aria-invalid": error ? true : void 0,
1463
+ "aria-describedby": [`${controlId}-currency`, error && `${controlId}-error`].filter(Boolean).join(" "),
1464
+ onChange: (event) => {
1465
+ const next = event.currentTarget.value;
1466
+ const result = parseBillingAmount(next, minorUnits);
1467
+ event.currentTarget.setCustomValidity(result.valid ? "" : result.message);
1468
+ setText(next);
1469
+ setError(result.valid ? void 0 : result.message);
1470
+ if (result.valid) onChange?.(result.value);
1471
+ }
1472
+ }
1473
+ ),
1474
+ help && /* @__PURE__ */ jsx("p", { className: "oods-field-help", children: help }),
1475
+ error && /* @__PURE__ */ jsx("p", { id: `${controlId}-error`, role: "alert", children: error })
1476
+ ] });
1477
+ }
1478
+ function BillingIntervalSelector({ id, interval, intervals = BILLING_INTERVALS, label = "Billing interval", name, disabled, className, help, onChange }) {
1479
+ const generatedId = React3.useId();
1480
+ const controlId = id ?? `billing-interval-${generatedId}`;
1481
+ const [value, setValue] = React3.useState(interval ?? "");
1482
+ React3.useEffect(() => {
1483
+ setValue(interval ?? "");
1484
+ }, [interval]);
1485
+ const error = billingIntervalMessage(value || void 0, intervals);
1486
+ return /* @__PURE__ */ jsxs("div", { className: `oods-billing-field ${className ?? ""}`.trim(), "data-oods-component": "BillingIntervalSelector", "data-state": error ? "invalid" : "editing", children: [
1487
+ /* @__PURE__ */ jsx("label", { htmlFor: controlId, children: label }),
1488
+ /* @__PURE__ */ jsxs(
1489
+ "select",
1490
+ {
1491
+ id: controlId,
1492
+ name,
1493
+ value,
1494
+ disabled,
1495
+ "aria-invalid": error ? true : void 0,
1496
+ "aria-describedby": error ? `${controlId}-error` : void 0,
1497
+ onChange: (event) => {
1498
+ const next = event.currentTarget.value;
1499
+ if (intervals.includes(next)) {
1500
+ setValue(next);
1501
+ onChange?.(next);
1502
+ }
1503
+ },
1504
+ children: [
1505
+ !intervals.includes(value) && /* @__PURE__ */ jsx("option", { value, disabled: true, children: value || "Choose interval" }),
1506
+ intervals.map((option) => /* @__PURE__ */ jsx("option", { value: option, children: formatReadOnlyValue(option, "string", true) }, option))
1507
+ ]
1508
+ }
1509
+ ),
1510
+ help && /* @__PURE__ */ jsx("p", { className: "oods-field-help", children: help }),
1511
+ error && /* @__PURE__ */ jsx("p", { id: `${controlId}-error`, role: "alert", children: error })
1512
+ ] });
1513
+ }
1514
+ function CycleProgressCard({ id, title = "Billing cycle", ...values }) {
1515
+ const cycle = billingCycle(values);
1516
+ return /* @__PURE__ */ jsxs("section", { id, className: "oods-billing-cycle", "data-oods-component": "CycleProgressCard", "aria-label": title, children: [
1517
+ /* @__PURE__ */ jsx("h2", { children: title }),
1518
+ /* @__PURE__ */ jsx("p", { children: cycle.announcement }),
1519
+ cycle.percent !== void 0 && /* @__PURE__ */ jsx("progress", { max: 100, value: cycle.percent, "aria-label": cycle.announcement }),
1520
+ values.interval && /* @__PURE__ */ jsx("p", { className: "oods-billing-muted", children: values.interval })
1521
+ ] });
1522
+ }
1523
+ function BillingTimeline({ id, title, component, includeMethod, ...values }) {
1524
+ const heading = title ?? (includeMethod ? "Payments" : "Payment events");
1525
+ return /* @__PURE__ */ jsxs("section", { id, className: "oods-payment-timeline", "data-oods-component": component, role: "log", "aria-label": heading, children: [
1526
+ /* @__PURE__ */ jsx("h2", { children: heading }),
1527
+ /* @__PURE__ */ jsx("p", { children: billingPaymentSummary(values) }),
1528
+ includeMethod && /* @__PURE__ */ jsx("p", { className: "oods-billing-muted", children: `Payment method: ${values.paymentMethod ?? "Not provided"}` }),
1529
+ /* @__PURE__ */ jsx("ol", { children: billingPaymentRows(values).map((row) => /* @__PURE__ */ jsxs("li", { "data-payment-kind": row.kind, children: [
1530
+ /* @__PURE__ */ jsx("strong", { children: row.label }),
1531
+ row.at ? /* @__PURE__ */ jsx("time", { dateTime: row.at, children: row.text }) : /* @__PURE__ */ jsx("span", { children: row.text })
1532
+ ] }, row.kind)) })
1533
+ ] });
1534
+ }
1535
+ function PaymentTimeline(props) {
1536
+ return /* @__PURE__ */ jsx(BillingTimeline, { ...props, component: "PaymentTimeline", includeMethod: true });
1537
+ }
1538
+ function PaymentEventTimeline(props) {
1539
+ if (props.event) return /* @__PURE__ */ jsxs("section", { id: props.id, "data-oods-component": "PaymentEventTimeline", "aria-label": props.event.title ?? "Payment event", children: [
1540
+ /* @__PURE__ */ jsx("strong", { children: props.event.title }),
1541
+ /* @__PURE__ */ jsx("time", { dateTime: props.event.at, children: formatDateTime(props.event.at) }),
1542
+ /* @__PURE__ */ jsx("p", { children: props.event.description })
1543
+ ] });
1544
+ return /* @__PURE__ */ jsx(BillingTimeline, { ...props, component: "PaymentEventTimeline", includeMethod: false });
1545
+ }
1546
+ function BillingCardMeta({ id, amount, currency, minorUnits, interval }) {
1547
+ return /* @__PURE__ */ jsx("span", { id, className: "oods-billing-card-meta", "data-oods-component": "BillingCardMeta", children: billingSummary(amount, currency, minorUnits, interval) });
1548
+ }
1549
+ function ArchivedRowOverlay({ id, isArchived = false, showBadge = true, separateTab = true, tabLabel = "Archived", label, children }) {
1550
+ return /* @__PURE__ */ jsxs(
1551
+ "span",
1552
+ {
1553
+ id,
1554
+ className: "oods-archived-row",
1555
+ "data-oods-component": "ArchivedRowOverlay",
1556
+ "data-archived": isArchived ? "true" : void 0,
1557
+ "data-archive-tab": separateTab ? tabLabel : void 0,
1558
+ role: isArchived ? "group" : void 0,
1559
+ "aria-hidden": isArchived ? false : void 0,
1560
+ "aria-label": isArchived ? `${tabLabel}${label ? `: ${label}` : ""}` : void 0,
1561
+ children: [
1562
+ children,
1563
+ isArchived && showBadge && /* @__PURE__ */ jsx("span", { className: "oods-archive-badge", children: tabLabel })
1564
+ ]
1565
+ }
1566
+ );
1567
+ }
1568
+ function AuditSummaryCard({ id, title = "Audit summary", showTransitionCount = true, showLastTransitionTime = true, showLastActor = true, ...values }) {
1569
+ const summary2 = auditSummary(values);
1570
+ return /* @__PURE__ */ jsxs("section", { id, className: "oods-audit-summary", "data-oods-component": "AuditSummaryCard", "aria-label": title, children: [
1571
+ /* @__PURE__ */ jsx("h2", { children: title }),
1572
+ /* @__PURE__ */ jsxs("dl", { children: [
1573
+ showTransitionCount && /* @__PURE__ */ jsxs(Fragment, { children: [
1574
+ /* @__PURE__ */ jsx("dt", { children: "Transitions" }),
1575
+ /* @__PURE__ */ jsx("dd", { children: summary2.count })
1576
+ ] }),
1577
+ showLastActor && /* @__PURE__ */ jsxs(Fragment, { children: [
1578
+ /* @__PURE__ */ jsx("dt", { children: "Last actor" }),
1579
+ /* @__PURE__ */ jsx("dd", { children: summary2.actor })
1580
+ ] }),
1581
+ showLastTransitionTime && /* @__PURE__ */ jsxs(Fragment, { children: [
1582
+ /* @__PURE__ */ jsx("dt", { children: "Last transition" }),
1583
+ /* @__PURE__ */ jsx("dd", { children: summary2.at ? /* @__PURE__ */ jsx("time", { dateTime: summary2.at, children: summary2.timestamp }) : summary2.timestamp })
1584
+ ] })
1585
+ ] }),
1586
+ summary2.recent.length > 0 && /* @__PURE__ */ jsx("ol", { "aria-label": "Recent transitions", children: summary2.recent.map((entry, index) => /* @__PURE__ */ jsx("li", { children: String(entry.to_state ?? "Transition") }, index)) })
1587
+ ] });
1588
+ }
1589
+ function SortIndicator({ id, label = "Sort", onChange, "data-oods-action": action, ...values }) {
1590
+ const [state, setState] = React3.useState(() => initialSort(values));
1591
+ React3.useEffect(() => setState(initialSort(values)), [values.sortField, values.sortDirection, values.sortActive, values.defaultSortField, values.defaultSortDirection]);
1592
+ const sort = ariaSort(state);
1593
+ return /* @__PURE__ */ jsx("table", { id, className: "oods-sort-indicator", "data-oods-component": "SortIndicator", "aria-label": label, children: /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("th", { scope: "col", "aria-sort": sort, children: /* @__PURE__ */ jsx("button", { type: "button", "data-oods-action": action, "aria-label": `${label} ${state.field}`, onClick: () => {
1594
+ const next = nextSort(state, values.triStateSort);
1595
+ setState(next);
1596
+ onChange?.(next);
1597
+ }, children: `${state.field}: ${sort}` }) }) }) }) });
1598
+ }
1599
+ var TimelineEntryLabel = React3.forwardRef(({ compact = true, maxLength, ...props }, ref) => /* @__PURE__ */ jsx(InlineLabel, { ...props, ref, maxLength: maxLength ?? (compact ? 40 : void 0), "data-oods-component": "TimelineEntryLabel", "data-timeline-label": "true", "data-compact": compact }));
1600
+ TimelineEntryLabel.displayName = "OODS.TimelineEntryLabel";
1601
+ function eventRecipe(id, kind, title) {
1602
+ return function TraitEvent({ id: elementId, title: heading = title, ...values }) {
1603
+ const rows = traitEventRows(kind, values);
1604
+ return /* @__PURE__ */ jsxs("article", { id: elementId, className: "oods-trait-recipe", "data-oods-component": id, "aria-label": heading, children: [
1605
+ /* @__PURE__ */ jsx("h2", { children: heading }),
1606
+ rows.length ? /* @__PURE__ */ jsx("ol", { children: rows.map((row, index) => /* @__PURE__ */ jsxs("li", { children: [
1607
+ /* @__PURE__ */ jsx("strong", { children: row.title }),
1608
+ /* @__PURE__ */ jsx("p", { children: row.at ? /* @__PURE__ */ jsx("time", { dateTime: row.at, children: row.time }) : row.time }),
1609
+ row.actor && /* @__PURE__ */ jsxs("p", { children: [
1610
+ "Actor: ",
1611
+ row.actor
1612
+ ] }),
1613
+ row.reason && /* @__PURE__ */ jsxs("p", { children: [
1614
+ "Reason: ",
1615
+ row.reason
1616
+ ] }),
1617
+ row.code && /* @__PURE__ */ jsxs("p", { children: [
1618
+ "Code: ",
1619
+ row.code
1620
+ ] })
1621
+ ] }, index)) }) : /* @__PURE__ */ jsx("p", { children: "No events recorded." })
1622
+ ] });
1623
+ };
1624
+ }
1625
+ var ArchiveEvent = eventRecipe("ArchiveEvent", "archive", "Archive events");
1626
+ var CancellationEvent = eventRecipe("CancellationEvent", "cancellation", "Cancellation event");
1627
+ var StateTransitionEvent = eventRecipe("StateTransitionEvent", "transition", "State transitions");
1628
+ function CommunicationDetailPanel({ id, title = "Communication", channels = [], templates = [], policies = [], conversations = [] }) {
1629
+ return /* @__PURE__ */ jsxs("section", { id, className: "oods-trait-recipe", "data-oods-component": "CommunicationDetailPanel", "aria-label": title, children: [
1630
+ /* @__PURE__ */ jsx("h2", { children: title }),
1631
+ /* @__PURE__ */ jsxs("div", { role: "status", "aria-live": "polite", children: [
1632
+ conversations.length,
1633
+ " conversations"
1634
+ ] }),
1635
+ /* @__PURE__ */ jsx("dl", { children: [["Channels", channels], ["Templates", templates], ["Delivery policies", policies], ["Conversations", conversations]].map(([label, rows]) => /* @__PURE__ */ jsxs("div", { children: [
1636
+ /* @__PURE__ */ jsx("dt", { children: label }),
1637
+ /* @__PURE__ */ jsx("dd", { children: rows.length ? /* @__PURE__ */ jsx("ul", { children: recipeItemLabels(rows).map((text, index) => /* @__PURE__ */ jsx("li", { children: text }, index)) }) : "None recorded" })
1638
+ ] }, label)) })
1639
+ ] });
1640
+ }
1641
+ function ColorStatePicker({ id, title = "Color state", colorStates = DEFAULT_COLOR_STATES, value, disabled, onChange }) {
1642
+ const generatedId = React3.useId();
1643
+ const [selected, setSelected] = React3.useState(value ?? colorStates[0] ?? "");
1644
+ React3.useEffect(() => setSelected(value ?? colorStates[0] ?? ""), [value, colorStates]);
1645
+ return /* @__PURE__ */ jsxs("fieldset", { id, className: "oods-trait-recipe", "data-oods-component": "ColorStatePicker", children: [
1646
+ /* @__PURE__ */ jsx("legend", { children: title }),
1647
+ /* @__PURE__ */ 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: formatReadOnlyValue(value2, "string", true) }))], onValueChange: (next) => {
1648
+ setSelected(next);
1649
+ onChange?.(next);
1650
+ } })
1651
+ ] });
1652
+ }
1653
+ function StatusColorLegend({ id, title = "Status colors", colorStates = DEFAULT_COLOR_STATES, value, showTokenReferences = false }) {
1654
+ return /* @__PURE__ */ jsxs("section", { id, className: "oods-trait-recipe", "data-oods-component": "StatusColorLegend", "aria-label": title, children: [
1655
+ /* @__PURE__ */ jsx("h2", { children: title }),
1656
+ /* @__PURE__ */ jsx("dl", { children: colorStates.map((state) => /* @__PURE__ */ jsxs("div", { children: [
1657
+ /* @__PURE__ */ jsxs("dt", { children: [
1658
+ /* @__PURE__ */ jsx(ColorSwatch, { label: state, color: `var(--sys-status-${state}-surface)` }),
1659
+ state === value && " (current)"
1660
+ ] }),
1661
+ /* @__PURE__ */ jsx("dd", { children: showTokenReferences ? `--sys-status-${state}-surface` : state })
1662
+ ] }, state)) })
1663
+ ] });
1664
+ }
1665
+ function GeoFieldMappingForm({ id, title = "Geographic fields", embedded = false, disabled, onChange, ...values }) {
1666
+ const generatedId = React3.useId();
1667
+ const [value, setValue] = React3.useState(() => geoFieldMapping(values));
1668
+ React3.useEffect(() => setValue(geoFieldMapping(values)), [values.latitude, values.longitude, values.identifier, values.autoDetect]);
1669
+ const update = (patch) => {
1670
+ const next = { ...value, ...patch };
1671
+ setValue(next);
1672
+ onChange?.(next);
1673
+ };
1674
+ const Tag = embedded ? "fieldset" : "form";
1675
+ return /* @__PURE__ */ jsxs(Tag, { id, className: "oods-trait-recipe", "data-oods-component": "GeoFieldMappingForm", "aria-label": title, onSubmit: (event) => event.preventDefault(), children: [
1676
+ embedded ? /* @__PURE__ */ jsx("legend", { children: title }) : /* @__PURE__ */ jsx("h2", { children: title }),
1677
+ ["latitude", "longitude", "identifier"].map((field) => /* @__PURE__ */ 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)),
1678
+ /* @__PURE__ */ jsx(Checkbox, { id: `${id ?? generatedId}-auto`, name: "geo_auto_detect_enabled", label: "Auto detect fields", checked: value.autoDetect, disabled, onCheckedChange: (autoDetect) => update({ autoDetect }) })
1679
+ ] });
1680
+ }
1681
+ function GeoResolutionBadge({ id, resolution }) {
1682
+ return /* @__PURE__ */ jsxs("span", { id, className: "oods-geo-resolution", "data-oods-component": "GeoResolutionBadge", children: [
1683
+ "Resolution: ",
1684
+ resolution || "Not determined"
1685
+ ] });
1686
+ }
1687
+ function GeocodablePreview({ id, title = "Geographic data", resolution, requiresLookup, detectedFields = [] }) {
1688
+ return /* @__PURE__ */ jsxs("section", { id, className: "oods-trait-recipe", "data-oods-component": "GeocodablePreview", "aria-label": title, children: [
1689
+ /* @__PURE__ */ jsx("h2", { children: title }),
1690
+ /* @__PURE__ */ jsxs("dl", { children: [
1691
+ /* @__PURE__ */ jsx("dt", { children: "Resolution" }),
1692
+ /* @__PURE__ */ jsx("dd", { children: resolution || "Not determined" }),
1693
+ /* @__PURE__ */ jsx("dt", { children: "Requires lookup" }),
1694
+ /* @__PURE__ */ jsx("dd", { children: requiresLookup === void 0 ? "Not determined" : requiresLookup ? "Yes" : "No" }),
1695
+ /* @__PURE__ */ jsx("dt", { children: "Detected fields" }),
1696
+ /* @__PURE__ */ jsx("dd", { children: recipeItemLabels(detectedFields).join(", ") || "None detected" })
1697
+ ] })
1698
+ ] });
1699
+ }
1700
+ function controls(id) {
1701
+ const Component = ({ id: htmlId, title = VIZ_CONTROL_TITLES[id], value, channel = "x", disabled, onChange }) => {
1702
+ const generatedId = React3.useId();
1703
+ const [current, setCurrent] = React3.useState(value ?? {});
1704
+ const [drafts, setDrafts] = React3.useState({});
1705
+ const [errors, setErrors] = React3.useState({});
1706
+ React3.useEffect(() => {
1707
+ setCurrent(value ?? {});
1708
+ setDrafts({});
1709
+ setErrors({});
1710
+ }, [value]);
1711
+ const update = (field, text) => {
1712
+ const result = editVizIntent(current, field, text);
1713
+ setDrafts((previous) => ({ ...previous, [field.key]: text }));
1714
+ setErrors((previous) => ({ ...previous, [field.key]: result.error }));
1715
+ if (result.value) {
1716
+ setCurrent(result.value);
1717
+ onChange?.(result.value);
1718
+ }
1719
+ };
1720
+ return /* @__PURE__ */ jsxs("fieldset", { id: htmlId, className: "oods-viz-controls oods-trait-recipe", "data-oods-component": id, disabled, children: [
1721
+ /* @__PURE__ */ jsx("legend", { children: title }),
1722
+ vizControlFields(id, channel).map((field) => {
1723
+ const fieldId = `${htmlId ?? generatedId}-${field.key.replace(".", "-")}`;
1724
+ const text = drafts[field.key] ?? vizFieldValue(current, field.key);
1725
+ const validation = errors[field.key] ? { state: "error", message: errors[field.key] } : void 0;
1726
+ return field.type === "select" ? /* @__PURE__ */ 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__ */ 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);
1727
+ }),
1728
+ (id === "VizColorControls" || id === "VizColorLegendConfig") && /* @__PURE__ */ jsx("div", { className: "oods-viz-swatches", children: current.encodings?.color?.range?.map((color, index) => /* @__PURE__ */ jsx(ColorSwatch, { color, label: `Category color ${index + 1}: ${color}` }, index)) }),
1729
+ id === "VizShapeLegend" && /* @__PURE__ */ jsx(Text, { content: `Shape field: ${current.encodings?.shape?.field || "Not bound"}` })
1730
+ ] });
1731
+ };
1732
+ Component.displayName = `OODS.${id}`;
1733
+ return Component;
1734
+ }
1735
+ function summary(id) {
1736
+ return function VizSummary({ id: htmlId, title, value = {}, channel = "x" }) {
1737
+ const rows = vizSummaryRows(id, value, channel);
1738
+ if (id === "VizEncodingBadge" || id === "VizRoleBadge") return /* @__PURE__ */ jsx("span", { id: htmlId, "data-oods-component": id, children: /* @__PURE__ */ jsx(Badge, { content: rows.map(([label, text]) => `${label}: ${text}`).join(" \xB7 ") }) });
1739
+ const heading = title ?? id.replace(/^Viz/, "").replace(/Summary$/, "") + " summary";
1740
+ return /* @__PURE__ */ jsxs("section", { id: htmlId, className: "oods-trait-recipe", "data-oods-component": id, "aria-label": heading, children: [
1741
+ /* @__PURE__ */ jsx("h2", { children: heading }),
1742
+ /* @__PURE__ */ jsx("dl", { children: rows.map(([label, text]) => /* @__PURE__ */ jsxs("div", { children: [
1743
+ /* @__PURE__ */ jsx("dt", { children: label }),
1744
+ /* @__PURE__ */ jsx("dd", { children: /* @__PURE__ */ jsx(Text, { content: text }) })
1745
+ ] }, label)) })
1746
+ ] });
1747
+ };
1748
+ }
1749
+ function preview(id, type) {
1750
+ return function VizPreview({ title = `${type[0].toUpperCase()}${type.slice(1)} chart`, children, ...props }) {
1751
+ return /* @__PURE__ */ jsx(VizAreaPreview, { ...props, title, "data-oods-component": id, "data-viz-preview-type": type, children: children ?? /* @__PURE__ */ jsx(Text, { content: "No rendered chart supplied" }) });
1752
+ };
1753
+ }
1754
+ var VizAreaControls = controls("VizAreaControls");
1755
+ var VizAxisControls = controls("VizAxisControls");
1756
+ var VizColorControls = controls("VizColorControls");
1757
+ var VizHeatmapControls = controls("VizHeatmapControls");
1758
+ var VizLineControls = controls("VizLineControls");
1759
+ var VizMarkControls = controls("VizMarkControls");
1760
+ var VizOpacityControls = controls("VizOpacityControls");
1761
+ var VizPointControls = controls("VizPointControls");
1762
+ var VizScaleControls = controls("VizScaleControls");
1763
+ var VizScatterControls = controls("VizScatterControls");
1764
+ var VizShapeControls = controls("VizShapeControls");
1765
+ var VizSizeControls = controls("VizSizeControls");
1766
+ var VizColorLegendConfig = controls("VizColorLegendConfig");
1767
+ var VizShapeLegend = controls("VizShapeLegend");
1768
+ var VizAxisSummary = summary("VizAxisSummary");
1769
+ var VizOpacitySummary = summary("VizOpacitySummary");
1770
+ var VizScaleSummary = summary("VizScaleSummary");
1771
+ var VizSizeSummary = summary("VizSizeSummary");
1772
+ var VizEncodingBadge = summary("VizEncodingBadge");
1773
+ var VizRoleBadge = summary("VizRoleBadge");
1774
+ var VizHeatmapPreview = preview("VizHeatmapPreview", "heatmap");
1775
+ var VizGraphPreview = preview("VizGraphPreview", "force_graph");
1776
+ var VizLinePreview = preview("VizLinePreview", "line");
1777
+ var VizMarkPreview = preview("VizMarkPreview", "bar");
1778
+ var VizPointPreview = preview("VizPointPreview", "scatter");
1779
+ var VizScatterPreview = preview("VizScatterPreview", "scatter");
1780
+
1781
+ export { AddressCollectionPanel, AddressEditor, AddressSummaryBadge, AddressValidationTimeline, ArchiveEvent, ArchivePill, ArchiveSummary, ArchivedRowOverlay, AuditEvent, AuditSummaryCard, BillingAmountInput, BillingCardMeta, BillingIntervalSelector, BillingSummaryBadge, CancellationBadge, CancellationEvent, CancellationForm, CardHeader, ClassificationBadge, ClassificationEditor, ClassificationPanel, ColorStatePicker, ColorSwatch, ColorizedBadge, CommunicationDetailPanel, CycleProgressCard, DetailHeader, FilterPanel, FormLabelGroup, GeoFieldMappingForm, GeoResolutionBadge, GeocodablePreview, Grid, InlineLabel, LabelCell, MembershipAuditTimeline, MembershipPanel, MessageEventTimeline, MessageStatusBadge, OwnerBadge, OwnershipMeta, OwnershipSummary, PaymentEventTimeline, PaymentTimeline, PreferenceEditor, PreferencePanel, PreferenceSummaryBadge, PreferenceTimeline, PriceCardMeta, PriceSummary, RoleAssignmentForm, RoleBadgeList, SortIndicator, Stack, StateTransitionEvent, StatusColorLegend, StatusSelector, Tabs, TagInput, TagManager, TagPills, TagSummary, TemplatePicker, TimelineEntryLabel, VizAreaControls, VizAreaPreview, VizAxisControls, VizAxisSummary, VizColorControls, VizColorLegendConfig, VizEncodingBadge, VizGraphPreview, VizHeatmapControls, VizHeatmapPreview, VizLineControls, VizLinePreview, VizMarkControls, VizMarkPreview, VizOpacityControls, VizOpacitySummary, VizPointControls, VizPointPreview, VizRoleBadge, VizScaleControls, VizScaleSummary, VizScatterControls, VizScatterPreview, VizShapeControls, VizShapeLegend, VizSizeControls, VizSizeSummary };