@oods/components-react 0.3.3 → 0.4.1

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 CHANGED
@@ -1,10 +1,10 @@
1
- import { Badge, Select, Input, Checkbox, Text } from './chunk-BPEHI36W.js';
2
- export { AuditTimeline, Badge, Banner, Button, CancellationSummary, Card, Checkbox, DatePicker, Input, PaginationBar, PriceBadge, RelativeTimestamp, SearchInput, Select, StatusBadge, StatusTimeline, Text, Textarea } from './chunk-BPEHI36W.js';
3
- export { Table } from './chunk-XAWAMZUQ.js';
4
- import './chunk-G74PKSW3.js';
5
- import * as React3 from 'react';
1
+ import { Badge, StatusIcon, Select, Input, Checkbox, Text } from './chunk-NLWXBLPA.js';
2
+ export { AuditTimeline, Badge, Banner, Button, CancellationSummary, Card, Checkbox, DatePicker, Dialog, Input, PaginationBar, PriceBadge, RelativeTimestamp, SearchInput, Select, StatusBadge, StatusTimeline, Switch, Text, Textarea } from './chunk-NLWXBLPA.js';
3
+ export { Table } from './chunk-XEX22E24.js';
4
+ import './chunk-2VEQWKGK.js';
5
+ import * as React4 from 'react';
6
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';
7
+ import { vizPreviewLayers, svgCarriesTitle, formatPriceAmount, formatPriceCode, formatReferenceLabel, ownershipPhrase, 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
8
 
9
9
  var classes = (...values) => values.filter(Boolean).join(" ");
10
10
  var GAP_VALUES = {
@@ -19,7 +19,7 @@ var maxColumns = (columns) => {
19
19
  const count = Number(columns);
20
20
  return Number.isFinite(count) && count > 0 ? count : void 0;
21
21
  };
22
- var Grid = React3.forwardRef(
22
+ var Grid = React4.forwardRef(
23
23
  ({
24
24
  columns = "auto-fit",
25
25
  minColumnWidth = "16rem",
@@ -49,7 +49,7 @@ var Grid = React3.forwardRef(
49
49
  )
50
50
  );
51
51
  Grid.displayName = "OODS.Grid";
52
- var Stack = React3.forwardRef(
52
+ var Stack = React4.forwardRef(
53
53
  ({
54
54
  direction = "column",
55
55
  gap = "md",
@@ -95,7 +95,7 @@ var partitionForOverflow = (items, visibleCount, selectedId) => {
95
95
  overflowItems: items.filter((item) => !visibleIds.has(item.id))
96
96
  };
97
97
  };
98
- var Tabs = React3.forwardRef(
98
+ var Tabs = React4.forwardRef(
99
99
  ({
100
100
  items,
101
101
  selectedId,
@@ -109,22 +109,22 @@ var Tabs = React3.forwardRef(
109
109
  "aria-label": ariaLabelAttribute,
110
110
  ...rest
111
111
  }, ref) => {
112
- const instanceId = React3.useId().replaceAll(":", "");
112
+ const instanceId = React4.useId().replaceAll(":", "");
113
113
  const controlled = selectedId !== void 0;
114
114
  const firstEnabled = items.find((item) => !item.disabled && !item.isDisabled)?.id ?? "";
115
- const [internalSelectedId, setInternalSelectedId] = React3.useState(
115
+ const [internalSelectedId, setInternalSelectedId] = React4.useState(
116
116
  defaultSelectedId ?? firstEnabled
117
117
  );
118
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(
119
+ const [focusedId, setFocusedId] = React4.useState(activeId);
120
+ const [visibleCount, setVisibleCount] = React4.useState(items.length);
121
+ const [menuOpen, setMenuOpen] = React4.useState(false);
122
+ const listRef = React4.useRef(null);
123
+ const tabRefs = React4.useRef(/* @__PURE__ */ new Map());
124
+ const itemWidths = React4.useRef(/* @__PURE__ */ new Map());
125
+ const focusRequestedByUser = React4.useRef(false);
126
+ React4.useEffect(() => setFocusedId(activeId), [activeId]);
127
+ const select = React4.useCallback(
128
128
  (id) => {
129
129
  const item = items.find((candidate) => candidate.id === id);
130
130
  if (!item || item.disabled || item.isDisabled) return;
@@ -136,7 +136,7 @@ var Tabs = React3.forwardRef(
136
136
  },
137
137
  [controlled, items, onChange, onUpdate]
138
138
  );
139
- const measure = React3.useCallback(() => {
139
+ const measure = React4.useCallback(() => {
140
140
  const list = listRef.current;
141
141
  if (!list || items.length < 2) return;
142
142
  const available = list.offsetWidth;
@@ -160,7 +160,7 @@ var Tabs = React3.forwardRef(
160
160
  }
161
161
  setVisibleCount(Math.max(1, count));
162
162
  }, [items.length]);
163
- React3.useLayoutEffect(() => {
163
+ React4.useLayoutEffect(() => {
164
164
  measure();
165
165
  const list = listRef.current;
166
166
  if (!list || typeof ResizeObserver === "undefined") return void 0;
@@ -188,7 +188,7 @@ var Tabs = React3.forwardRef(
188
188
  if (!nextId) return;
189
189
  select(nextId);
190
190
  };
191
- React3.useEffect(() => {
191
+ React4.useEffect(() => {
192
192
  if (focusRequestedByUser.current && visibleItems.some((item) => item.id === focusedId)) {
193
193
  focusRequestedByUser.current = false;
194
194
  tabRefs.current.get(focusedId)?.focus();
@@ -310,11 +310,75 @@ var Tabs = React3.forwardRef(
310
310
  }
311
311
  );
312
312
  Tabs.displayName = "OODS.Tabs";
313
+ var SegmentedControl = React4.forwardRef(
314
+ ({
315
+ id,
316
+ label,
317
+ options,
318
+ value,
319
+ defaultValue,
320
+ name,
321
+ size = "md",
322
+ disabled,
323
+ className,
324
+ style,
325
+ onChange,
326
+ onValueChange,
327
+ onUpdate,
328
+ ...rest
329
+ }, ref) => {
330
+ const handleChange = (event) => {
331
+ onChange?.(event);
332
+ if (event.defaultPrevented) return;
333
+ onValueChange?.(event.currentTarget.value);
334
+ onUpdate?.(event.currentTarget.value);
335
+ };
336
+ return /* @__PURE__ */ jsxs(
337
+ "div",
338
+ {
339
+ className: className ? `oods-field oods-segmented-control ${className}` : "oods-field oods-segmented-control",
340
+ style,
341
+ "data-oods-component": "SegmentedControl",
342
+ "data-size": size,
343
+ children: [
344
+ /* @__PURE__ */ jsx("span", { id: `${id}-label`, className: "oods-field-label", children: label }),
345
+ /* @__PURE__ */ jsx(
346
+ "div",
347
+ {
348
+ ref,
349
+ id,
350
+ role: "radiogroup",
351
+ "aria-labelledby": `${id}-label`,
352
+ className: "oods-segmented-control__track",
353
+ ...rest,
354
+ children: options.map((option) => /* @__PURE__ */ jsxs("label", { className: "oods-segmented-control__option", children: [
355
+ /* @__PURE__ */ jsx(
356
+ "input",
357
+ {
358
+ type: "radio",
359
+ className: "oods-segmented-control__input",
360
+ name: name || id,
361
+ value: option.value,
362
+ ...value === void 0 ? { defaultChecked: option.value === defaultValue } : { checked: option.value === value },
363
+ disabled: disabled || option.disabled,
364
+ onChange: handleChange
365
+ }
366
+ ),
367
+ /* @__PURE__ */ jsx("span", { className: "oods-segmented-control__label", children: option.label })
368
+ ] }, option.value))
369
+ }
370
+ )
371
+ ]
372
+ }
373
+ );
374
+ }
375
+ );
376
+ SegmentedControl.displayName = "OODS.SegmentedControl";
313
377
  var classes3 = (...values) => values.filter(Boolean).join(" ");
314
378
  var firstText = (...values) => values.find((value) => typeof value === "string" && value.trim().length > 0);
315
379
  function childContent(children) {
316
- const flatten = (value) => React3.Children.toArray(value).flatMap((node) => {
317
- if (React3.isValidElement(node) && node.type === React3.Fragment) {
380
+ const flatten = (value) => React4.Children.toArray(value).flatMap((node) => {
381
+ if (React4.isValidElement(node) && node.type === React4.Fragment) {
318
382
  return flatten(node.props.children);
319
383
  }
320
384
  return [node];
@@ -335,7 +399,7 @@ function notEcho(supporting, heading) {
335
399
  if (!supporting || !heading) return supporting;
336
400
  return supporting.trim() === heading.trim() ? void 0 : supporting;
337
401
  }
338
- var DetailHeader = React3.forwardRef(
402
+ var DetailHeader = React4.forwardRef(
339
403
  ({ title, label, text, subtitle, sublabel, description, metadata, meta, level, as, children, className, ...rest }, ref) => {
340
404
  const Heading = headingElement(as, level, 2);
341
405
  const content = childContent(children);
@@ -350,7 +414,7 @@ var DetailHeader = React3.forwardRef(
350
414
  }
351
415
  );
352
416
  DetailHeader.displayName = "OODS.DetailHeader";
353
- var CardHeader = React3.forwardRef(
417
+ var CardHeader = React4.forwardRef(
354
418
  ({ title, label, text, supporting, supportingText, subtitle, description, level, as, children, className, ...rest }, ref) => {
355
419
  const Heading = headingElement(as, level, 2);
356
420
  const content = childContent(children);
@@ -363,7 +427,7 @@ var CardHeader = React3.forwardRef(
363
427
  }
364
428
  );
365
429
  CardHeader.displayName = "OODS.CardHeader";
366
- var ColorSwatch = React3.forwardRef(
430
+ var ColorSwatch = React4.forwardRef(
367
431
  ({ color, value, state, label, children, className, style, ...rest }, ref) => {
368
432
  const resolvedColor = firstText(color, value, state);
369
433
  const content = childContent(children);
@@ -388,7 +452,7 @@ var ColorSwatch = React3.forwardRef(
388
452
  }
389
453
  );
390
454
  ColorSwatch.displayName = "OODS.ColorSwatch";
391
- var ColorizedBadge = React3.forwardRef(
455
+ var ColorizedBadge = React4.forwardRef(
392
456
  ({ label, text, state, value, status, color, hue, swatch, variant, tone, emphasis, children, className, style, ...rest }, ref) => {
393
457
  const content = childContent(children);
394
458
  const resolvedLabel = content.scalar ?? firstText(label, text, state, value) ?? "Color";
@@ -418,10 +482,12 @@ var ColorizedBadge = React3.forwardRef(
418
482
  }
419
483
  );
420
484
  ColorizedBadge.displayName = "OODS.ColorizedBadge";
421
- var VizAreaPreview = React3.forwardRef(
422
- ({ width = 640, height = 360, svg, svgNarrow, svgWide, title, description, children, className, style, ...rest }, ref) => {
485
+ var VizAreaPreview = React4.forwardRef(
486
+ ({ width = 640, height = 360, svg, svgNarrow, svgWide, svgDark, svgDarkNarrow, svgDarkWide, svgHc, svgHcNarrow, svgHcWide, title, description, children, className, style, ...rest }, ref) => {
423
487
  const content = childContent(children);
424
488
  if (svg !== void 0) {
489
+ const layers = vizPreviewLayers({ svg, svgNarrow, svgWide, svgDark, svgDarkNarrow, svgDarkWide, svgHc, svgHcNarrow, svgHcWide });
490
+ const renders = (layer) => layer.renders.map(([attribute, markup]) => /* @__PURE__ */ jsx("div", { ...{ [attribute]: "true" }, dangerouslySetInnerHTML: { __html: markup } }, attribute));
425
491
  return /* @__PURE__ */ jsxs(
426
492
  "figure",
427
493
  {
@@ -440,9 +506,7 @@ var VizAreaPreview = React3.forwardRef(
440
506
  ...rest,
441
507
  children: [
442
508
  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,
509
+ layers.map((layer) => layer.theme === void 0 ? renders(layer) : /* @__PURE__ */ jsx("div", { "data-viz-theme": layer.theme, "data-viz-narrow": layer.narrow ? "true" : void 0, "data-viz-wide": layer.wide ? "true" : void 0, children: renders(layer) }, layer.theme)),
446
510
  description ? /* @__PURE__ */ jsx("p", { "data-viz-description": "true", children: description }) : null
447
511
  ]
448
512
  }
@@ -487,7 +551,7 @@ var descriptorLabel = (descriptor) => firstText(
487
551
  typeof descriptor.field === "string" ? descriptor.field : void 0
488
552
  ) ?? "Filter";
489
553
  function createPanelSection(component, className, panelType, defaultTitle) {
490
- const Panel = React3.forwardRef(
554
+ const Panel = React4.forwardRef(
491
555
  ({ title, label, heading, name, subtitle, description, metadata, summary: summary2, text, body, emptyMessage, children, className: consumerClassName, ...rest }, ref) => {
492
556
  const content = childContent(children);
493
557
  const authored = content.authored || content.scalar !== void 0;
@@ -520,7 +584,7 @@ var ClassificationPanel = createPanelSection("ClassificationPanel", "oods-classi
520
584
  var AddressCollectionPanel = createPanelSection("AddressCollectionPanel", "oods-address-collection-panel", "address", "Addresses");
521
585
  var MembershipPanel = createPanelSection("MembershipPanel", "oods-membership-panel", "membership", "Membership");
522
586
  var PreferencePanel = createPanelSection("PreferencePanel", "oods-preference-panel", "preference", "Preferences");
523
- var FilterPanel = React3.forwardRef(
587
+ var FilterPanel = React4.forwardRef(
524
588
  ({ filters, activeFilters, mode, collapsible = true, children, className, ...rest }, ref) => {
525
589
  const content = childContent(children);
526
590
  const authored = content.authored || content.scalar !== void 0;
@@ -554,7 +618,7 @@ var FilterPanel = React3.forwardRef(
554
618
  }
555
619
  );
556
620
  FilterPanel.displayName = "OODS.FilterPanel";
557
- var PriceSummary = React3.forwardRef(
621
+ var PriceSummary = React4.forwardRef(
558
622
  ({
559
623
  title,
560
624
  label,
@@ -627,7 +691,7 @@ var normalizeTagItems = (value) => {
627
691
  }
628
692
  return items.filter((item) => item.length > 0);
629
693
  };
630
- var TagManager = React3.forwardRef(
694
+ var TagManager = React4.forwardRef(
631
695
  ({ title, label, heading, name, description, subtitle, hint, tags, value, children, className, onSubmit, ...rest }, ref) => {
632
696
  const content = childContent(children);
633
697
  const authored = content.authored || content.scalar !== void 0;
@@ -673,10 +737,12 @@ var asCount = (value) => {
673
737
  return void 0;
674
738
  };
675
739
  function createBadgeFamily(options) {
676
- const consumed = /* @__PURE__ */ new Set([...options.labelKeys, ...options.statusKeys, "variant", "tone", "emphasis"]);
677
- const Family = React3.forwardRef((allProps, ref) => {
740
+ const consumed = /* @__PURE__ */ new Set([...options.labelKeys, ...options.statusKeys, "variant", "tone", "emphasis", ...options.booleanProps ? ["hideWhenFalse"] : []]);
741
+ const Family = React4.forwardRef((allProps, ref) => {
678
742
  const { children, className, ...rest } = allProps;
679
743
  const record = rest;
744
+ const flag = options.booleanProps?.map((key) => record[key]).find((value) => typeof value === "boolean");
745
+ if (record.hideWhenFalse === true && flag === false) return null;
680
746
  const scalar = (key) => {
681
747
  const value = record[key];
682
748
  if (typeof value === "boolean" && options.booleanProps?.includes(key)) return String(value);
@@ -734,7 +800,7 @@ var PreferenceSummaryBadge = createBadgeFamily({
734
800
  labelKeys: ["label", "text", "namespace", "value"],
735
801
  statusKeys: ["status", "state", "version"]
736
802
  });
737
- var RoleBadgeList = React3.forwardRef(
803
+ var RoleBadgeList = React4.forwardRef(
738
804
  ({ roles, badges, roleLabels, value, variant, tone, label, text, children, className, ...rest }, ref) => {
739
805
  const content = childContent(children);
740
806
  const authored = content.authored || content.scalar !== void 0;
@@ -754,7 +820,7 @@ var RoleBadgeList = React3.forwardRef(
754
820
  }
755
821
  );
756
822
  RoleBadgeList.displayName = "OODS.RoleBadgeList";
757
- var TagPills = React3.forwardRef(
823
+ var TagPills = React4.forwardRef(
758
824
  ({ tags, value, maxVisible, overflowLabel, children, className, ...rest }, ref) => {
759
825
  const content = childContent(children);
760
826
  const authored = content.authored || content.scalar !== void 0;
@@ -806,7 +872,7 @@ var normalizeTimelineItems = (raw) => {
806
872
  };
807
873
  function createTimelineFamily(options) {
808
874
  const consumed = /* @__PURE__ */ new Set(["title", "label", "heading", "name", ...options.eventKeys]);
809
- const Family = React3.forwardRef((allProps, ref) => {
875
+ const Family = React4.forwardRef((allProps, ref) => {
810
876
  const { children, className, ...rest } = allProps;
811
877
  const record = rest;
812
878
  const text = (key) => {
@@ -871,7 +937,7 @@ var PreferenceTimeline = createTimelineFamily({
871
937
  timelineType: "preference",
872
938
  eventKeys: ["events", "changes", "history"]
873
939
  });
874
- var AuditEvent = React3.forwardRef(
940
+ var AuditEvent = React4.forwardRef(
875
941
  ({
876
942
  label,
877
943
  title,
@@ -957,7 +1023,7 @@ var addressRecord = (form) => {
957
1023
  };
958
1024
  return { street: read("street"), city: read("city"), region: read("region"), postalCode: read("postalCode") };
959
1025
  };
960
- var AddressEditor = React3.forwardRef(
1026
+ var AddressEditor = React4.forwardRef(
961
1027
  ({
962
1028
  title,
963
1029
  label,
@@ -1015,8 +1081,8 @@ var AddressEditor = React3.forwardRef(
1015
1081
  }
1016
1082
  );
1017
1083
  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) => {
1084
+ var PreferenceEditor = React4.forwardRef(
1085
+ ({ title, label, heading, name, description, subtitle, hint, namespaces, namespace, document: document2, json, value, children, className, onSubmit, ...rest }, ref) => {
1020
1086
  const content = childContent(children);
1021
1087
  const authored = content.authored || content.scalar !== void 0;
1022
1088
  const resolvedTitle = firstText(title, label, heading, name) ?? "Preference Editor";
@@ -1043,7 +1109,7 @@ var PreferenceEditor = React3.forwardRef(
1043
1109
  ] }),
1044
1110
  /* @__PURE__ */ jsxs("label", { "data-form-control": "textarea", children: [
1045
1111
  /* @__PURE__ */ jsx("span", { children: "Preference Document" }),
1046
- /* @__PURE__ */ jsx("textarea", { name: "preferenceDocument", defaultValue: firstScalar(document, json, value) ?? "" })
1112
+ /* @__PURE__ */ jsx("textarea", { name: "preferenceDocument", defaultValue: firstScalar(document2, json, value) ?? "" })
1047
1113
  ] })
1048
1114
  ] }) })
1049
1115
  ]
@@ -1052,7 +1118,7 @@ var PreferenceEditor = React3.forwardRef(
1052
1118
  }
1053
1119
  );
1054
1120
  PreferenceEditor.displayName = "OODS.PreferenceEditor";
1055
- var RoleAssignmentForm = React3.forwardRef(
1121
+ var RoleAssignmentForm = React4.forwardRef(
1056
1122
  ({ title, label, heading, name, description, subtitle, hint, roles, availableRoles, role, defaultRoleId, assignee, member, children, className, onSubmit, ...rest }, ref) => {
1057
1123
  const content = childContent(children);
1058
1124
  const authored = content.authored || content.scalar !== void 0;
@@ -1089,7 +1155,7 @@ var RoleAssignmentForm = React3.forwardRef(
1089
1155
  }
1090
1156
  );
1091
1157
  RoleAssignmentForm.displayName = "OODS.RoleAssignmentForm";
1092
- var StatusSelector = React3.forwardRef(
1158
+ var StatusSelector = React4.forwardRef(
1093
1159
  ({ label, title, help, options, states, value, status, children, className, onChange, onValueChange, onUpdate, ...rest }, ref) => {
1094
1160
  const content = childContent(children);
1095
1161
  const authored = content.authored || content.scalar !== void 0;
@@ -1131,7 +1197,7 @@ var StatusSelector = React3.forwardRef(
1131
1197
  }
1132
1198
  );
1133
1199
  StatusSelector.displayName = "OODS.StatusSelector";
1134
- var TagInput = React3.forwardRef(
1200
+ var TagInput = React4.forwardRef(
1135
1201
  ({ title, label, heading, name, description, subtitle, hint, tags, value, placeholder, children, className, onChange, onValueChange, onUpdate, ...rest }, ref) => {
1136
1202
  const content = childContent(children);
1137
1203
  const authored = content.authored || content.scalar !== void 0;
@@ -1178,7 +1244,7 @@ var TagInput = React3.forwardRef(
1178
1244
  }
1179
1245
  );
1180
1246
  TagInput.displayName = "OODS.TagInput";
1181
- var TemplatePicker = React3.forwardRef(
1247
+ var TemplatePicker = React4.forwardRef(
1182
1248
  ({ title, label, heading, name, description, subtitle, hint, templates, options, templateId, value, channels, channel, children, className, ...rest }, ref) => {
1183
1249
  const content = childContent(children);
1184
1250
  const authored = content.authored || content.scalar !== void 0;
@@ -1216,14 +1282,14 @@ var truncateLabel = (value, maxLength) => {
1216
1282
  const limit = typeof maxLength === "number" ? maxLength : Number(maxLength);
1217
1283
  return !Number.isFinite(limit) || limit <= 0 || value.length <= limit ? value : `${value.slice(0, Math.max(0, limit - 1)).trimEnd()}...`;
1218
1284
  };
1219
- var InlineLabel = React3.forwardRef(
1285
+ var InlineLabel = React4.forwardRef(
1220
1286
  ({ label, text, value, maxLength, children, className, ...rest }, ref) => {
1221
1287
  const content = childContent(children);
1222
1288
  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
1289
  }
1224
1290
  );
1225
1291
  InlineLabel.displayName = "OODS.InlineLabel";
1226
- var LabelCell = React3.forwardRef(
1292
+ var LabelCell = React4.forwardRef(
1227
1293
  ({ label, text, value, description, subtitle, sublabel, supporting, truncate, maxLength, children, className, ...rest }, ref) => {
1228
1294
  const content = childContent(children);
1229
1295
  const limit = truncate ? maxLength ?? 40 : maxLength;
@@ -1236,7 +1302,7 @@ var LabelCell = React3.forwardRef(
1236
1302
  }
1237
1303
  );
1238
1304
  LabelCell.displayName = "OODS.LabelCell";
1239
- var FormLabelGroup = React3.forwardRef(
1305
+ var FormLabelGroup = React4.forwardRef(
1240
1306
  ({ label, text, title, placeholder, hint, description, htmlFor, for: forId, inputId, children, className, ...rest }, ref) => {
1241
1307
  const detail = firstText(placeholder, hint, description);
1242
1308
  return /* @__PURE__ */ jsxs("label", { ref, className: classes3("oods-form-label-group", className), "data-oods-component": "FormLabelGroup", htmlFor: htmlFor ?? forId ?? inputId, ...rest, children: [
@@ -1255,7 +1321,7 @@ var ClassificationBadge = createBadgeFamily({
1255
1321
  labelKeys: ["label", "text", "category", "value"],
1256
1322
  statusKeys: ["status", "state", "mode"]
1257
1323
  });
1258
- var ClassificationEditor = React3.forwardRef(
1324
+ var ClassificationEditor = React4.forwardRef(
1259
1325
  ({ title, label, heading, name, description, subtitle, hint, category, primaryCategory, tags, modes, mode, classificationMode, children, className, onSubmit, ...rest }, ref) => {
1260
1326
  const content = childContent(children);
1261
1327
  const tagText = typeof tags === "string" ? tags : tags === void 0 ? "" : JSON.stringify(tags);
@@ -1301,7 +1367,7 @@ var OwnerBadge = createBadgeFamily({
1301
1367
  labelKeys: ["label", "text", "owner", "ownerType", "value"],
1302
1368
  statusKeys: ["status", "state"]
1303
1369
  });
1304
- var OwnershipSummary = React3.forwardRef(
1370
+ var OwnershipSummary = React4.forwardRef(
1305
1371
  ({ title, label, heading, name, ownerLabel, ownerId, owner_id, ownerType, owner_type, role, ownershipRole, summary: summary2, text, description, children, className, ...rest }, ref) => {
1306
1372
  const content = childContent(children);
1307
1373
  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);
@@ -1316,7 +1382,7 @@ var OwnershipSummary = React3.forwardRef(
1316
1382
  }
1317
1383
  );
1318
1384
  OwnershipSummary.displayName = "OODS.OwnershipSummary";
1319
- var TagSummary = React3.forwardRef(
1385
+ var TagSummary = React4.forwardRef(
1320
1386
  ({ title, label, heading, name, tagCount, count, tags, summary: summary2, text, description, children, className, ...rest }, ref) => {
1321
1387
  const content = childContent(children);
1322
1388
  const tagText = Array.isArray(tags) ? normalizeTagItems(tags).join(", ") || void 0 : firstText(tags);
@@ -1332,11 +1398,12 @@ var TagSummary = React3.forwardRef(
1332
1398
  }
1333
1399
  );
1334
1400
  TagSummary.displayName = "OODS.TagSummary";
1335
- var OwnershipMeta = React3.forwardRef(
1336
- ({ title, label, heading, name, ownerType, owner_type, role, ownershipRole, children, className, ...rest }, ref) => {
1401
+ var OwnershipMeta = React4.forwardRef(
1402
+ ({ title, label, heading, name, ownerType, owner_type, role, ownershipRole, ownerLabel, children, className, ...rest }, ref) => {
1337
1403
  const content = childContent(children);
1338
1404
  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: [
1405
+ const phrase = ownerLabel !== void 0 ? ownershipPhrase(ownerLabel, firstScalar(ownerType, owner_type), firstScalar(role, ownershipRole)) : void 0;
1406
+ 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 : phrase ? /* @__PURE__ */ jsx("span", { "data-meta-item": "true", children: phrase }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1340
1407
  /* @__PURE__ */ jsx("span", { "data-meta-title": "true", children: firstText(title, label, heading, name) ?? "Ownership" }),
1341
1408
  terms.map(([term, value]) => /* @__PURE__ */ jsxs("span", { "data-meta-item": "true", children: [
1342
1409
  /* @__PURE__ */ jsxs("strong", { children: [
@@ -1370,7 +1437,7 @@ var CancellationBadge = createBadgeFamily({
1370
1437
  booleanProps: ["cancelAtPeriodEnd", "isCancelled", "value"],
1371
1438
  booleanLabels: ["Cancellation scheduled", "No cancellation scheduled"]
1372
1439
  });
1373
- var ArchiveSummary = React3.forwardRef(
1440
+ var ArchiveSummary = React4.forwardRef(
1374
1441
  ({ title, label, heading, name, isArchived, archived, status, archivedAt, reason, archiveReason, summary: summary2, text, description, children, className, ...rest }, ref) => {
1375
1442
  const content = childContent(children);
1376
1443
  const terms = [["Archived", summaryValue(isArchived ?? archived ?? status)], ["Archived At", archivedAt ? formatDateTime(archivedAt) : void 0], ["Reason", firstText(reason, archiveReason)]].filter((entry) => entry[1] !== void 0);
@@ -1385,7 +1452,7 @@ var ArchiveSummary = React3.forwardRef(
1385
1452
  }
1386
1453
  );
1387
1454
  ArchiveSummary.displayName = "OODS.ArchiveSummary";
1388
- var PriceCardMeta = React3.forwardRef(
1455
+ var PriceCardMeta = React4.forwardRef(
1389
1456
  ({ title, label, heading, name, model, pricingModel, interval, billingInterval, children, className, ...rest }, ref) => {
1390
1457
  const content = childContent(children);
1391
1458
  const terms = [["Model", formatPriceCode(firstText(model, pricingModel))], ["Interval", formatPriceCode(firstText(interval, billingInterval))]].filter((entry) => entry[1] !== void 0);
@@ -1403,12 +1470,12 @@ var PriceCardMeta = React3.forwardRef(
1403
1470
  }
1404
1471
  );
1405
1472
  PriceCardMeta.displayName = "OODS.PriceCardMeta";
1406
- var CancellationForm = React3.forwardRef(
1473
+ var CancellationForm = React4.forwardRef(
1407
1474
  ({ title, label, heading, name, description, subtitle, hint, allowedReasons, reasonCode, reason, cancellationReason, embedded, reasonHelp, codeHelp, children, className, onSubmit, ...rest }, ref) => {
1408
1475
  const content = childContent(children);
1409
1476
  const choices = normalizeSelectOptions(allowedReasons ?? ["no_longer_needed", "budget", "duplicate"]);
1410
1477
  if (reasonCode && !choices.some((choice) => choice.value === reasonCode)) choices.unshift({ value: reasonCode, label: reasonCode });
1411
- return React3.createElement(embedded ? "fieldset" : "form", {
1478
+ return React4.createElement(embedded ? "fieldset" : "form", {
1412
1479
  ...rest,
1413
1480
  ref,
1414
1481
  className: classes3("oods-cancellation-form", className),
@@ -1440,11 +1507,11 @@ function BillingSummaryBadge({ id, amount, currency, minorUnits, interval, showI
1440
1507
  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) });
1441
1508
  }
1442
1509
  function BillingAmountInput({ id, amount, currency = "usd", minorUnits = BILLING_MINOR_UNITS, label = "Billing amount", name, disabled, className, help, onChange }) {
1443
- const generatedId = React3.useId();
1510
+ const generatedId = React4.useId();
1444
1511
  const controlId = id ?? `billing-amount-${generatedId}`;
1445
- const [text, setText] = React3.useState(() => billingAmountText(amount, minorUnits));
1446
- const [error, setError] = React3.useState(() => billingAmountMessage(amount, minorUnits));
1447
- React3.useEffect(() => {
1512
+ const [text, setText] = React4.useState(() => billingAmountText(amount, minorUnits));
1513
+ const [error, setError] = React4.useState(() => billingAmountMessage(amount, minorUnits));
1514
+ React4.useEffect(() => {
1448
1515
  setText(billingAmountText(amount, minorUnits));
1449
1516
  setError(billingAmountMessage(amount, minorUnits));
1450
1517
  }, [amount, minorUnits]);
@@ -1478,10 +1545,10 @@ function BillingAmountInput({ id, amount, currency = "usd", minorUnits = BILLING
1478
1545
  ] });
1479
1546
  }
1480
1547
  function BillingIntervalSelector({ id, interval, intervals = BILLING_INTERVALS, label = "Billing interval", name, disabled, className, help, onChange }) {
1481
- const generatedId = React3.useId();
1548
+ const generatedId = React4.useId();
1482
1549
  const controlId = id ?? `billing-interval-${generatedId}`;
1483
- const [value, setValue] = React3.useState(interval ?? "");
1484
- React3.useEffect(() => {
1550
+ const [value, setValue] = React4.useState(interval ?? "");
1551
+ React4.useEffect(() => {
1485
1552
  setValue(interval ?? "");
1486
1553
  }, [interval]);
1487
1554
  const error = billingIntervalMessage(value || void 0, intervals);
@@ -1589,8 +1656,8 @@ function AuditSummaryCard({ id, title = "Audit summary", showTransitionCount = t
1589
1656
  ] });
1590
1657
  }
1591
1658
  function SortIndicator({ id, label = "Sort", onChange, "data-oods-action": action, ...values }) {
1592
- const [state, setState] = React3.useState(() => initialSort(values));
1593
- React3.useEffect(() => setState(initialSort(values)), [values.sortField, values.sortDirection, values.sortActive, values.defaultSortField, values.defaultSortDirection]);
1659
+ const [state, setState] = React4.useState(() => initialSort(values));
1660
+ React4.useEffect(() => setState(initialSort(values)), [values.sortField, values.sortDirection, values.sortActive, values.defaultSortField, values.defaultSortDirection]);
1594
1661
  const sort = ariaSort(state);
1595
1662
  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: () => {
1596
1663
  const next = nextSort(state, values.triStateSort);
@@ -1598,14 +1665,15 @@ function SortIndicator({ id, label = "Sort", onChange, "data-oods-action": actio
1598
1665
  onChange?.(next);
1599
1666
  }, children: `${state.field}: ${sort}` }) }) }) }) });
1600
1667
  }
1601
- 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 }));
1668
+ var TimelineEntryLabel = React4.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 }));
1602
1669
  TimelineEntryLabel.displayName = "OODS.TimelineEntryLabel";
1603
1670
  function eventRecipe(id, kind, title) {
1604
1671
  return function TraitEvent({ id: elementId, title: heading = title, ...values }) {
1605
1672
  const rows = traitEventRows(kind, values);
1673
+ if (!rows.length) return null;
1606
1674
  return /* @__PURE__ */ jsxs("article", { id: elementId, className: "oods-trait-recipe", "data-oods-component": id, "aria-label": heading, children: [
1607
1675
  /* @__PURE__ */ jsx("h2", { children: heading }),
1608
- rows.length ? /* @__PURE__ */ jsx("ol", { children: rows.map((row, index) => /* @__PURE__ */ jsxs("li", { children: [
1676
+ /* @__PURE__ */ jsx("ol", { children: rows.map((row, index) => /* @__PURE__ */ jsxs("li", { children: [
1609
1677
  /* @__PURE__ */ jsx("strong", { children: row.title }),
1610
1678
  /* @__PURE__ */ jsx("p", { children: row.at ? /* @__PURE__ */ jsx("time", { dateTime: row.at, children: row.time }) : row.time }),
1611
1679
  row.actor && /* @__PURE__ */ jsxs("p", { children: [
@@ -1620,7 +1688,7 @@ function eventRecipe(id, kind, title) {
1620
1688
  "Code: ",
1621
1689
  row.code
1622
1690
  ] })
1623
- ] }, index)) }) : /* @__PURE__ */ jsx("p", { children: "No events recorded." })
1691
+ ] }, index)) })
1624
1692
  ] });
1625
1693
  };
1626
1694
  }
@@ -1641,9 +1709,9 @@ function CommunicationDetailPanel({ id, title = "Communication", channels = [],
1641
1709
  ] });
1642
1710
  }
1643
1711
  function ColorStatePicker({ id, title = "Color state", colorStates = DEFAULT_COLOR_STATES, value, disabled, onChange }) {
1644
- const generatedId = React3.useId();
1645
- const [selected, setSelected] = React3.useState(value ?? colorStates[0] ?? "");
1646
- React3.useEffect(() => setSelected(value ?? colorStates[0] ?? ""), [value, colorStates]);
1712
+ const generatedId = React4.useId();
1713
+ const [selected, setSelected] = React4.useState(value ?? colorStates[0] ?? "");
1714
+ React4.useEffect(() => setSelected(value ?? colorStates[0] ?? ""), [value, colorStates]);
1647
1715
  return /* @__PURE__ */ jsxs("fieldset", { id, className: "oods-trait-recipe", "data-oods-component": "ColorStatePicker", children: [
1648
1716
  /* @__PURE__ */ jsx("legend", { children: title }),
1649
1717
  /* @__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) => {
@@ -1665,9 +1733,9 @@ function StatusColorLegend({ id, title = "Status colors", colorStates = DEFAULT_
1665
1733
  ] });
1666
1734
  }
1667
1735
  function GeoFieldMappingForm({ id, title = "Geographic fields", embedded = false, disabled, onChange, ...values }) {
1668
- const generatedId = React3.useId();
1669
- const [value, setValue] = React3.useState(() => geoFieldMapping(values));
1670
- React3.useEffect(() => setValue(geoFieldMapping(values)), [values.latitude, values.longitude, values.identifier, values.autoDetect]);
1736
+ const generatedId = React4.useId();
1737
+ const [value, setValue] = React4.useState(() => geoFieldMapping(values));
1738
+ React4.useEffect(() => setValue(geoFieldMapping(values)), [values.latitude, values.longitude, values.identifier, values.autoDetect]);
1671
1739
  const update = (patch) => {
1672
1740
  const next = { ...value, ...patch };
1673
1741
  setValue(next);
@@ -1701,11 +1769,11 @@ function GeocodablePreview({ id, title = "Geographic data", resolution, requires
1701
1769
  }
1702
1770
  function controls(id) {
1703
1771
  const Component = ({ id: htmlId, title = VIZ_CONTROL_TITLES[id], value, channel = "x", disabled, onChange }) => {
1704
- const generatedId = React3.useId();
1705
- const [current, setCurrent] = React3.useState(value ?? {});
1706
- const [drafts, setDrafts] = React3.useState({});
1707
- const [errors, setErrors] = React3.useState({});
1708
- React3.useEffect(() => {
1772
+ const generatedId = React4.useId();
1773
+ const [current, setCurrent] = React4.useState(value ?? {});
1774
+ const [drafts, setDrafts] = React4.useState({});
1775
+ const [errors, setErrors] = React4.useState({});
1776
+ React4.useEffect(() => {
1709
1777
  setCurrent(value ?? {});
1710
1778
  setDrafts({});
1711
1779
  setErrors({});
@@ -1779,5 +1847,214 @@ var VizLinePreview = preview("VizLinePreview", "line");
1779
1847
  var VizMarkPreview = preview("VizMarkPreview", "bar");
1780
1848
  var VizPointPreview = preview("VizPointPreview", "scatter");
1781
1849
  var VizScatterPreview = preview("VizScatterPreview", "scatter");
1850
+ var classes4 = (...values) => values.filter(Boolean).join(" ");
1851
+ var Combobox = React4.forwardRef(
1852
+ ({
1853
+ id,
1854
+ label,
1855
+ options = [],
1856
+ value,
1857
+ defaultValue = "",
1858
+ placeholder,
1859
+ name,
1860
+ required,
1861
+ disabled,
1862
+ help,
1863
+ validation,
1864
+ size = "md",
1865
+ className,
1866
+ style,
1867
+ onValueChange,
1868
+ onUpdate,
1869
+ onKeyDown,
1870
+ onBlur,
1871
+ onClick,
1872
+ "aria-describedby": nativeDescription,
1873
+ ...rest
1874
+ }, ref) => {
1875
+ const [internalValue, setInternalValue] = React4.useState(defaultValue);
1876
+ const [query, setQuery] = React4.useState(null);
1877
+ const [open, setOpen] = React4.useState(false);
1878
+ const [active, setActive] = React4.useState(-1);
1879
+ const rootRef = React4.useRef(null);
1880
+ const listboxRef = React4.useRef(null);
1881
+ const chosenValue = value ?? internalValue;
1882
+ const chosen = options.find((option) => option.value === chosenValue);
1883
+ const text = query ?? chosen?.label ?? "";
1884
+ const needle = (query ?? "").trim().toLowerCase();
1885
+ const matches = options.map((option) => needle === "" || option.label.toLowerCase().includes(needle));
1886
+ const matchCount = matches.filter(Boolean).length;
1887
+ const reachable = options.flatMap((option, index) => matches[index] && !option.disabled ? [index] : []);
1888
+ const optionId = (index) => `${id}-option-${index}`;
1889
+ const validationId = validation?.id ?? `${id}-validation`;
1890
+ const describedBy = [nativeDescription, help ? `${id}-help` : void 0, validation?.message ? validationId : void 0].filter(Boolean).join(" ") || void 0;
1891
+ const tone = validation ? validation.state === "error" ? "critical" : validation.state : void 0;
1892
+ const close = () => {
1893
+ setOpen(false);
1894
+ setActive(-1);
1895
+ };
1896
+ const emit = (next) => {
1897
+ if (value === void 0) setInternalValue(next);
1898
+ onValueChange?.(next);
1899
+ onUpdate?.(next);
1900
+ };
1901
+ const pick = (index) => {
1902
+ const option = options[index];
1903
+ if (!option || option.disabled) return;
1904
+ setQuery(null);
1905
+ close();
1906
+ if (option.value !== chosenValue) emit(option.value);
1907
+ };
1908
+ React4.useEffect(() => {
1909
+ if (!open) return void 0;
1910
+ const outside = (event) => {
1911
+ if (!rootRef.current?.contains(event.target)) close();
1912
+ };
1913
+ document.addEventListener("pointerdown", outside);
1914
+ return () => document.removeEventListener("pointerdown", outside);
1915
+ }, [open]);
1916
+ React4.useEffect(() => {
1917
+ if (!open || active < 0) return;
1918
+ const element = listboxRef.current?.children[active];
1919
+ element?.scrollIntoView?.({ block: "nearest" });
1920
+ }, [open, active]);
1921
+ const handleKeyDown = (event) => {
1922
+ onKeyDown?.(event);
1923
+ if (event.defaultPrevented || disabled || event.nativeEvent.isComposing) return;
1924
+ const first = reachable[0] ?? -1;
1925
+ const last = reachable[reachable.length - 1] ?? -1;
1926
+ const at = reachable.indexOf(active);
1927
+ switch (event.key) {
1928
+ case "ArrowDown":
1929
+ event.preventDefault();
1930
+ setOpen(true);
1931
+ setActive(!open || at === -1 ? first : reachable[(at + 1) % reachable.length]);
1932
+ return;
1933
+ case "ArrowUp":
1934
+ event.preventDefault();
1935
+ setOpen(true);
1936
+ setActive(!open || at <= 0 ? last : reachable[at - 1]);
1937
+ return;
1938
+ case "Home":
1939
+ case "End":
1940
+ if (!open) return;
1941
+ event.preventDefault();
1942
+ setActive(event.key === "Home" ? first : last);
1943
+ return;
1944
+ case "Enter":
1945
+ if (!open) return;
1946
+ event.preventDefault();
1947
+ if (active >= 0) pick(active);
1948
+ return;
1949
+ case "Escape":
1950
+ if (open) {
1951
+ event.preventDefault();
1952
+ close();
1953
+ return;
1954
+ }
1955
+ if (text === "" && chosenValue === "") return;
1956
+ event.preventDefault();
1957
+ setQuery(null);
1958
+ if (chosenValue !== "") emit("");
1959
+ return;
1960
+ case "Tab":
1961
+ if (open) close();
1962
+ return;
1963
+ }
1964
+ };
1965
+ return /* @__PURE__ */ jsxs(
1966
+ "div",
1967
+ {
1968
+ ref: rootRef,
1969
+ className: classes4("oods-field", "oods-combobox", className),
1970
+ style: {
1971
+ ...tone ? {
1972
+ "--cmp-input-message-border": `var(--sys-status-${tone}-border)`,
1973
+ "--cmp-input-message-text": `var(--sys-status-${tone}-text)`
1974
+ } : {},
1975
+ ...style
1976
+ },
1977
+ "data-oods-component": "Combobox",
1978
+ "data-size": size,
1979
+ "data-validation-state": validation?.state,
1980
+ children: [
1981
+ /* @__PURE__ */ jsxs("label", { id: `${id}-label`, className: "oods-field-label", htmlFor: id, children: [
1982
+ label,
1983
+ required ? /* @__PURE__ */ jsx("span", { className: "oods-field-required", "aria-hidden": "true", children: "*" }) : null
1984
+ ] }),
1985
+ /* @__PURE__ */ jsxs("div", { className: "oods-combobox__control", children: [
1986
+ /* @__PURE__ */ jsx(
1987
+ "input",
1988
+ {
1989
+ ...rest,
1990
+ ref,
1991
+ id,
1992
+ type: "text",
1993
+ role: "combobox",
1994
+ className: "oods-field-control oods-combobox__input",
1995
+ value: text,
1996
+ placeholder,
1997
+ autoComplete: "off",
1998
+ "aria-autocomplete": "list",
1999
+ "aria-expanded": open,
2000
+ "aria-controls": `${id}-listbox`,
2001
+ "aria-activedescendant": open && active >= 0 ? optionId(active) : void 0,
2002
+ "aria-describedby": describedBy,
2003
+ "aria-invalid": validation?.state === "error" || void 0,
2004
+ required,
2005
+ disabled,
2006
+ onChange: (event) => {
2007
+ setQuery(event.currentTarget.value);
2008
+ setOpen(true);
2009
+ setActive(-1);
2010
+ },
2011
+ onKeyDown: handleKeyDown,
2012
+ onClick: (event) => {
2013
+ onClick?.(event);
2014
+ if (!event.defaultPrevented && !disabled) setOpen(true);
2015
+ },
2016
+ onBlur: (event) => {
2017
+ onBlur?.(event);
2018
+ setQuery(null);
2019
+ close();
2020
+ }
2021
+ }
2022
+ ),
2023
+ /* @__PURE__ */ jsx("span", { className: "oods-combobox__chevron", "aria-hidden": "true", children: /* @__PURE__ */ jsx(StatusIcon, { name: "chevron-down" }) }),
2024
+ /* @__PURE__ */ jsxs("div", { className: "oods-combobox__popup", hidden: !open, onMouseDown: (event) => event.preventDefault(), children: [
2025
+ /* @__PURE__ */ jsx("ul", { ref: listboxRef, id: `${id}-listbox`, className: "oods-combobox__listbox", role: "listbox", "aria-labelledby": `${id}-label`, children: options.map((option, index) => /* @__PURE__ */ jsxs(
2026
+ "li",
2027
+ {
2028
+ id: optionId(index),
2029
+ className: "oods-combobox__option",
2030
+ role: "option",
2031
+ "aria-selected": option.value === chosenValue,
2032
+ "aria-disabled": option.disabled || void 0,
2033
+ "data-value": option.value,
2034
+ "data-active": index === active ? "true" : void 0,
2035
+ hidden: !matches[index],
2036
+ onClick: () => pick(index),
2037
+ onPointerMove: () => {
2038
+ if (!option.disabled && index !== active) setActive(index);
2039
+ },
2040
+ children: [
2041
+ /* @__PURE__ */ jsx("span", { className: "oods-combobox__option-label", children: option.label }),
2042
+ /* @__PURE__ */ jsx("span", { className: "oods-combobox__check", "aria-hidden": "true", children: /* @__PURE__ */ jsx(StatusIcon, { name: "check" }) })
2043
+ ]
2044
+ },
2045
+ option.value
2046
+ )) }),
2047
+ /* @__PURE__ */ jsx("p", { className: "oods-combobox__empty", role: "status", children: open && matchCount === 0 ? "No matches" : "" })
2048
+ ] })
2049
+ ] }),
2050
+ name ? /* @__PURE__ */ jsx("input", { type: "hidden", name, value: chosenValue }) : null,
2051
+ help ? /* @__PURE__ */ jsx("p", { id: `${id}-help`, className: "oods-field-help", children: help }) : null,
2052
+ validation?.message ? /* @__PURE__ */ jsx("p", { id: validationId, className: "oods-field-error", role: validation.state === "error" ? "alert" : void 0, children: validation.message }) : null
2053
+ ]
2054
+ }
2055
+ );
2056
+ }
2057
+ );
2058
+ Combobox.displayName = "OODS.Combobox";
1782
2059
 
1783
- 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 };
2060
+ 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, Combobox, 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, SegmentedControl, 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 };