@oods/components-vue 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,10 @@
1
- import { defineComponent, h, ref, computed, useId, watch, nextTick, onMounted, onBeforeUnmount, isVNode, Text as Text$1, Comment, Fragment } from 'vue';
2
- import { svgCarriesTitle, assertStaticSvg, formatPriceAmount, formatPriceCode, formatReferenceLabel, summaryValue, formatDateTime, dateTimeInputValue, formatReadOnlyValue, BILLING_MINOR_UNITS, billingSummary, formatBillingAmount, billingAmountText, billingAmountMessage, parseBillingAmount, BILLING_INTERVALS, billingIntervalMessage, billingCycle, auditSummary, initialSort, ariaSort, nextSort, recipeItemLabels, DEFAULT_COLOR_STATES, geoFieldMapping, currencyMinorUnits, billingPaymentSummary, billingPaymentRows, traitEventRows, vizControlFields, VIZ_CONTROL_TITLES, vizFieldValue, vizSummaryRows, editVizIntent } from '@oods/component-contracts';
1
+ import { defineComponent, h, useId, computed, ref, onMounted, watch, nextTick, onBeforeUnmount, isVNode, Text as Text$1, Comment, Fragment } from 'vue';
2
+ import { vizPreviewLayers, svgCarriesTitle, formatPriceAmount, formatPriceCode, formatReferenceLabel, summaryValue, formatDateTime, dateTimeInputValue, formatReadOnlyValue, BILLING_MINOR_UNITS, billingSummary, formatBillingAmount, billingAmountText, billingAmountMessage, parseBillingAmount, BILLING_INTERVALS, billingIntervalMessage, billingCycle, auditSummary, initialSort, ariaSort, nextSort, recipeItemLabels, DEFAULT_COLOR_STATES, geoFieldMapping, STATUS_ICON_SVG_ATTRS, STATUS_ICON_SHAPES, getStatusPresentation, resolveStatusIcon, currencyMinorUnits, billingPaymentSummary, billingPaymentRows, traitEventRows, vizControlFields, VIZ_CONTROL_TITLES, vizFieldValue, vizSummaryRows, editVizIntent } from '@oods/component-contracts';
3
+
4
+ // src/primitives.ts
5
+ function statusIcon(name) {
6
+ return h("svg", { ...STATUS_ICON_SVG_ATTRS }, STATUS_ICON_SHAPES[name].map((shape) => h(shape.tag, { ...shape.attrs })));
7
+ }
3
8
 
4
9
  // src/primitives.ts
5
10
  var toneProp = String;
@@ -89,8 +94,8 @@ var Badge = defineComponent({
89
94
  "--cmp-badge-text": `var(--sys-status-${palette}-text)`
90
95
  }
91
96
  }, [
92
- props.icon || slots.icon ? h("span", { class: "oods-badge-icon", "aria-hidden": "true" }, [slotOrValue(slots.icon, props.icon)]) : null,
93
- slotOrValue(slots.default, props.content ?? statusLabel(props.status))
97
+ props.icon || slots.icon ? h("span", { class: "oods-badge__icon", "aria-hidden": "true" }, [slotOrValue(slots.icon, props.icon)]) : null,
98
+ h("span", { class: "oods-badge__label" }, [slotOrValue(slots.default, props.content ?? statusLabel(props.status))])
94
99
  ]);
95
100
  };
96
101
  }
@@ -114,7 +119,7 @@ var Banner = defineComponent({
114
119
  return () => {
115
120
  const tone = resolveTone(props.tone, props.status, props.domain);
116
121
  const palette = tokenTone(tone);
117
- return h("section", {
122
+ return h("div", {
118
123
  class: "oods-banner",
119
124
  "data-oods-component": "Banner",
120
125
  "data-status": props.status,
@@ -129,20 +134,20 @@ var Banner = defineComponent({
129
134
  "--cmp-banner-text": `var(--sys-status-${palette}-text)`
130
135
  }
131
136
  }, [
132
- h("div", { class: "oods-banner-content" }, [
133
- props.title || props.status || slots.title ? h("strong", { class: "oods-banner-title" }, [
137
+ h("div", { class: "oods-banner__content" }, [
138
+ props.title || props.status || slots.title ? h("strong", { class: "oods-banner__title" }, [
134
139
  slotOrValue(slots.title, props.title || statusLabel(props.status))
135
140
  ]) : null,
136
- props.detail ? h("p", { class: "oods-banner-detail" }, props.detail) : null,
137
- slots.default || props.content ? h(slots.default ? "div" : "p", { class: "oods-banner-body" }, [slotOrValue(slots.default, props.content)]) : null,
138
- slots.actions ? h("div", { class: "oods-banner-actions" }, slots.actions()) : null
141
+ props.detail ? h("p", { class: "oods-banner__detail" }, props.detail) : null,
142
+ slots.default || props.content ? h(slots.default ? "div" : "p", { class: "oods-banner__body" }, [slotOrValue(slots.default, props.content)]) : null,
143
+ slots.actions ? h("div", { class: "oods-banner__actions" }, slots.actions()) : null
139
144
  ]),
140
145
  props.dismissLabel ? h("button", {
141
146
  type: "button",
142
- class: "oods-banner-dismiss",
147
+ class: "oods-banner-dismiss oods-banner__dismiss",
143
148
  "aria-label": props.dismissLabel,
144
149
  onClick: () => emit("dismiss")
145
- }, [h("span", { "aria-hidden": "true" }, "\xD7")]) : null
150
+ }, [statusIcon("x")]) : null
146
151
  ]);
147
152
  };
148
153
  }
@@ -152,7 +157,7 @@ var Button = defineComponent({
152
157
  props: {
153
158
  content: { type: [String, Number], default: "" },
154
159
  intent: { type: String, default: "neutral" },
155
- size: { type: sizeProp, default: "md" },
160
+ size: { type: String, default: "md" },
156
161
  disabled: Boolean,
157
162
  type: { type: String, default: "button" }
158
163
  },
@@ -179,6 +184,83 @@ var Button = defineComponent({
179
184
  }, [slotOrValue(slots.default, props.content)]);
180
185
  }
181
186
  });
187
+ var canShowModal = () => typeof HTMLDialogElement !== "undefined" && typeof HTMLDialogElement.prototype.showModal === "function";
188
+ var Dialog = defineComponent({
189
+ name: "OodsDialog",
190
+ props: {
191
+ id: String,
192
+ open: Boolean,
193
+ modal: { type: Boolean, default: true },
194
+ title: { type: String, default: "" },
195
+ description: String,
196
+ dismissLabel: { type: String, default: "Close" },
197
+ size: { type: String, default: "md" },
198
+ actions: { type: [String, Number, Object, Array], default: void 0 }
199
+ },
200
+ emits: {
201
+ close: () => true
202
+ },
203
+ setup(props, { emit, slots }) {
204
+ const generatedId = useId().replace(/[^\w-]/g, "");
205
+ const dialogId = computed(() => props.id || `oods-dialog-${generatedId}`);
206
+ const element = ref(null);
207
+ const mounted = ref(false);
208
+ const managed = computed(() => props.modal && mounted.value && canShowModal());
209
+ const sync = () => {
210
+ const dialog = element.value;
211
+ if (!dialog || !managed.value) return;
212
+ if (props.open && !dialog.open) dialog.showModal();
213
+ else if (!props.open && dialog.open) dialog.close();
214
+ };
215
+ onMounted(() => {
216
+ mounted.value = true;
217
+ });
218
+ watch([() => props.open, managed], sync, { flush: "post" });
219
+ const requestClose = (event) => {
220
+ event.preventDefault();
221
+ emit("close");
222
+ };
223
+ return () => {
224
+ const titleId = `${dialogId.value}-title`;
225
+ const descriptionId = `${dialogId.value}-description`;
226
+ const actions = slotOrValue(slots.actions, props.actions);
227
+ return h("dialog", {
228
+ ref: element,
229
+ id: dialogId.value,
230
+ class: "oods-dialog",
231
+ "data-oods-component": "Dialog",
232
+ "data-size": props.size,
233
+ "aria-labelledby": titleId,
234
+ "aria-describedby": props.description ? descriptionId : void 0,
235
+ open: managed.value ? void 0 : props.open,
236
+ onKeydown: (event) => {
237
+ if (event.key === "Escape" && !event.defaultPrevented) requestClose(event);
238
+ },
239
+ onCancel: requestClose,
240
+ // The browser closed it (a close request it would not let be cancelled) while open is still true. A close event
241
+ // from moving a mounted dialog into the top layer finds it open again, and is not reported.
242
+ onClose: () => {
243
+ if (props.open && !element.value?.open) emit("close");
244
+ }
245
+ }, [
246
+ h("div", { class: "oods-dialog__header" }, [
247
+ h("div", { class: "oods-dialog__heading" }, [
248
+ h("h2", { id: titleId, class: "oods-dialog__title" }, props.title),
249
+ props.description ? h("p", { id: descriptionId, class: "oods-dialog__description" }, props.description) : null
250
+ ]),
251
+ h("button", {
252
+ type: "button",
253
+ class: "oods-dialog__close",
254
+ "aria-label": props.dismissLabel,
255
+ onClick: () => emit("close")
256
+ }, [statusIcon("x")])
257
+ ]),
258
+ slots.default ? h("div", { class: "oods-dialog__body" }, slots.default()) : null,
259
+ actions !== void 0 && actions !== null && actions !== "" ? h("div", { class: "oods-dialog__footer" }, [actions]) : null
260
+ ]);
261
+ };
262
+ }
263
+ });
182
264
  var SAFE_CARD_ELEMENTS = /* @__PURE__ */ new Set(["div", "article", "section", "aside"]);
183
265
  var Card = defineComponent({
184
266
  name: "OodsCard",
@@ -431,6 +513,7 @@ var ColorizedBadge = defineComponent({
431
513
  const color = firstText(props.color, props.hue, props.swatch, props.state);
432
514
  const variant = firstText(props.variant) ?? "colorized";
433
515
  return h(Badge, {
516
+ class: "oods-colorized-badge",
434
517
  status,
435
518
  tone: props.tone,
436
519
  emphasis: props.emphasis,
@@ -457,6 +540,13 @@ var VizAreaPreview = defineComponent({
457
540
  svgNarrow: String,
458
541
  /** The same chart rendered at the wide size; the figure shows it instead of svg when its own inline size is at least 900px. */
459
542
  svgWide: String,
543
+ /** s222-m02 (F7): the dark and high-contrast renders; with any of them, svg* are the light ones (see React's types). */
544
+ svgDark: String,
545
+ svgDarkNarrow: String,
546
+ svgDarkWide: String,
547
+ svgHc: String,
548
+ svgHcNarrow: String,
549
+ svgHcWide: String,
460
550
  title: String,
461
551
  description: String,
462
552
  width: { type: Number, default: 640 },
@@ -465,6 +555,7 @@ var VizAreaPreview = defineComponent({
465
555
  setup(props, { slots }) {
466
556
  return () => {
467
557
  const content = authoredContent(slots.default?.());
558
+ const renders = (layer) => layer.renders.map(([attribute, markup]) => h("div", { [attribute]: "true", innerHTML: markup }));
468
559
  if (props.svg !== void 0) return h("figure", {
469
560
  class: "oods-viz-area-preview",
470
561
  "data-oods-component": "VizAreaPreview",
@@ -479,9 +570,11 @@ var VizAreaPreview = defineComponent({
479
570
  style: { "--oods-viz-width": `${props.width}px` }
480
571
  }, [
481
572
  ...props.title && !svgCarriesTitle(props.svg, props.title) ? [h("figcaption", props.title)] : [],
482
- h("div", { "data-viz-svg": "true", innerHTML: assertStaticSvg(props.svg) }),
483
- ...props.svgNarrow !== void 0 ? [h("div", { "data-viz-svg-narrow": "true", innerHTML: assertStaticSvg(props.svgNarrow) })] : [],
484
- ...props.svgWide !== void 0 ? [h("div", { "data-viz-svg-wide": "true", innerHTML: assertStaticSvg(props.svgWide) })] : [],
573
+ ...vizPreviewLayers(props).flatMap((layer) => layer.theme === void 0 ? renders(layer) : [h("div", {
574
+ "data-viz-theme": layer.theme,
575
+ ...layer.narrow ? { "data-viz-narrow": "true" } : {},
576
+ ...layer.wide ? { "data-viz-wide": "true" } : {}
577
+ }, renders(layer))]),
485
578
  ...props.description ? [h("p", { "data-viz-description": "true" }, props.description)] : []
486
579
  ]);
487
580
  return h("div", {
@@ -1504,7 +1597,9 @@ var Input = defineComponent({
1504
1597
  name: "OodsInput",
1505
1598
  props: {
1506
1599
  ...textFieldProps,
1507
- type: { type: String, default: "text" }
1600
+ type: { type: String, default: "text" },
1601
+ /** A class for the input element itself, as React's inputClassName; the field's own class stays on its frame. */
1602
+ inputClass: String
1508
1603
  },
1509
1604
  emits: {
1510
1605
  "update:modelValue": (_value) => true,
@@ -1522,7 +1617,7 @@ var Input = defineComponent({
1522
1617
  };
1523
1618
  return () => renderField("Input", props, slots, metadata, h("input", {
1524
1619
  id: metadata.controlId.value,
1525
- class: "oods-field-control",
1620
+ class: props.inputClass ? ["oods-field-control", props.inputClass] : "oods-field-control",
1526
1621
  type: props.type,
1527
1622
  name: props.name,
1528
1623
  value: props.type === "datetime-local" ? dateTimeInputValue(currentValue.value) : currentValue.value,
@@ -1722,28 +1817,97 @@ var Checkbox = defineComponent({
1722
1817
  };
1723
1818
  }
1724
1819
  });
1820
+ var Switch = defineComponent({
1821
+ name: "OodsSwitch",
1822
+ props: {
1823
+ id: String,
1824
+ label: String,
1825
+ modelValue: { type: Boolean, default: void 0 },
1826
+ checked: { type: Boolean, default: void 0 },
1827
+ defaultChecked: Boolean,
1828
+ required: Boolean,
1829
+ disabled: Boolean,
1830
+ help: String,
1831
+ validation: Object,
1832
+ size: { type: String, default: "md" }
1833
+ },
1834
+ emits: {
1835
+ "update:modelValue": (_value) => true,
1836
+ change: (_value) => true
1837
+ },
1838
+ setup(props, { emit, slots }) {
1839
+ const internalChecked = ref(props.defaultChecked);
1840
+ const currentChecked = computed(() => props.modelValue ?? props.checked ?? internalChecked.value);
1841
+ const metadata = useFieldMetadata("Switch", props, slots);
1842
+ const toggle = () => {
1843
+ const next = !currentChecked.value;
1844
+ if (props.modelValue === void 0 && props.checked === void 0) internalChecked.value = next;
1845
+ emit("update:modelValue", next);
1846
+ emit("change", next);
1847
+ };
1848
+ return () => {
1849
+ const label = slots.label?.() ?? props.label;
1850
+ const help = slots.help?.() ?? props.help;
1851
+ const validation = slots.validation?.() ?? props.validation?.message;
1852
+ const controlId = metadata.controlId.value;
1853
+ return h("div", {
1854
+ class: "oods-field oods-switch",
1855
+ style: validationStyle(props.validation),
1856
+ "data-oods-component": "Switch",
1857
+ "data-size": props.size,
1858
+ "data-validation-state": props.validation?.state
1859
+ }, [
1860
+ h("div", { class: "oods-switch__row" }, [
1861
+ h("button", {
1862
+ id: controlId,
1863
+ type: "button",
1864
+ role: "switch",
1865
+ class: "oods-switch__control",
1866
+ "aria-checked": currentChecked.value ? "true" : "false",
1867
+ "aria-labelledby": `${controlId}-label`,
1868
+ "aria-describedby": metadata.describedBy.value,
1869
+ "aria-required": props.required ? "true" : void 0,
1870
+ "aria-invalid": props.validation?.state === "error" ? "true" : void 0,
1871
+ disabled: props.disabled,
1872
+ onClick: toggle
1873
+ }, [h("span", { class: "oods-switch__thumb", "aria-hidden": "true" })]),
1874
+ h("label", { id: `${controlId}-label`, class: "oods-field-label oods-switch__label", for: controlId }, [
1875
+ label,
1876
+ props.required ? h("span", { class: "oods-field-required", "aria-hidden": "true" }, "*") : null
1877
+ ])
1878
+ ]),
1879
+ help ? h("p", { id: metadata.helpId.value, class: "oods-field-help" }, help) : null,
1880
+ validation ? h("p", {
1881
+ id: metadata.validationId.value,
1882
+ class: "oods-field-error",
1883
+ role: props.validation?.state === "error" ? "alert" : void 0
1884
+ }, validation) : null
1885
+ ]);
1886
+ };
1887
+ }
1888
+ });
1725
1889
  var TableCaption = defineComponent({
1726
1890
  name: "OodsTableCaption",
1727
1891
  setup(_props, { slots }) {
1728
- return () => h("caption", {}, slots.default?.());
1892
+ return () => h("caption", { class: "oods-table__caption" }, slots.default?.());
1729
1893
  }
1730
1894
  });
1731
1895
  var TableHead = defineComponent({
1732
1896
  name: "OodsTableHead",
1733
1897
  setup(_props, { slots }) {
1734
- return () => h("thead", {}, slots.default?.());
1898
+ return () => h("thead", { class: "oods-table__header" }, slots.default?.());
1735
1899
  }
1736
1900
  });
1737
1901
  var TableBody = defineComponent({
1738
1902
  name: "OodsTableBody",
1739
1903
  setup(_props, { slots }) {
1740
- return () => h("tbody", {}, slots.default?.());
1904
+ return () => h("tbody", { class: "oods-table__body" }, slots.default?.());
1741
1905
  }
1742
1906
  });
1743
1907
  var TableRow = defineComponent({
1744
1908
  name: "OodsTableRow",
1745
1909
  setup(_props, { slots }) {
1746
- return () => h("tr", {}, slots.default?.());
1910
+ return () => h("tr", { class: "oods-table__row" }, slots.default?.());
1747
1911
  }
1748
1912
  });
1749
1913
  var TableHeaderCell = defineComponent({
@@ -1752,19 +1916,22 @@ var TableHeaderCell = defineComponent({
1752
1916
  scope: { type: String, default: "col" }
1753
1917
  },
1754
1918
  setup(props, { slots }) {
1755
- return () => h("th", { scope: props.scope }, slots.default?.());
1919
+ return () => h("th", { class: "oods-table__header-cell", scope: props.scope }, slots.default?.());
1756
1920
  }
1757
1921
  });
1758
1922
  var TableCell = defineComponent({
1759
1923
  name: "OodsTableCell",
1760
1924
  setup(_props, { slots }) {
1761
- return () => h("td", {}, slots.default?.());
1925
+ return () => h("td", { class: "oods-table__cell" }, slots.default?.());
1762
1926
  }
1763
1927
  });
1764
1928
  var Table = defineComponent({
1765
1929
  name: "OodsTable",
1930
+ inheritAttrs: false,
1766
1931
  props: {
1767
1932
  caption: { type: String, default: "" },
1933
+ // s222-m02 (#2502 ruling 11): false keeps the caption as the table's accessible name but hides it visually.
1934
+ showCaption: { type: Boolean, default: true },
1768
1935
  columns: { type: Array, default: () => [] },
1769
1936
  rows: { type: Array, default: () => [] },
1770
1937
  density: { type: String, default: "default" },
@@ -1773,16 +1940,17 @@ var Table = defineComponent({
1773
1940
  emits: {
1774
1941
  rowActivate: (_rowId) => true
1775
1942
  },
1776
- setup(props, { emit, slots }) {
1943
+ setup(props, { attrs, emit, slots }) {
1777
1944
  const activate = (row) => emit("rowActivate", row.id);
1778
- return () => h("table", {
1779
- class: "oods-table",
1945
+ return () => h("div", { class: "oods-table__container", "data-density": props.density }, [h("table", {
1946
+ ...attrs,
1947
+ class: ["oods-table", attrs.class],
1780
1948
  "data-oods-component": "Table",
1781
1949
  "data-density": props.density
1782
1950
  }, [
1783
- h(TableCaption, {}, {
1951
+ slots.caption || props.caption ? h(TableCaption, { "data-visually-hidden": props.showCaption ? void 0 : "true" }, {
1784
1952
  default: () => slots.caption?.() ?? props.caption
1785
- }),
1953
+ }) : null,
1786
1954
  h(TableHead, {}, {
1787
1955
  default: () => slots.head?.() ?? h(TableRow, {}, {
1788
1956
  default: () => props.columns.map((column) => h(TableHeaderCell, { key: column.key }, {
@@ -1797,7 +1965,7 @@ var Table = defineComponent({
1797
1965
  }, {
1798
1966
  default: () => "No rows available."
1799
1967
  })
1800
- }) : props.rows.map((row, rowIndex) => slots.row?.({ row, rowIndex, activate: () => activate(row) }) ?? h(TableRow, { key: row.id }, {
1968
+ }) : props.rows.map((row, rowIndex) => slots.row?.({ row, rowIndex, activate: () => activate(row) }) ?? h(TableRow, { key: row.id, "data-selectable": props.selectable ? "true" : void 0 }, {
1801
1969
  default: () => props.columns.map((column, columnIndex) => {
1802
1970
  const content = slots.cell?.({ row, column, value: row[column.key] }) ?? String(row[column.key] ?? "");
1803
1971
  return h(TableCell, { key: column.key }, {
@@ -1810,7 +1978,7 @@ var Table = defineComponent({
1810
1978
  })
1811
1979
  })))
1812
1980
  })
1813
- ]);
1981
+ ])]);
1814
1982
  }
1815
1983
  });
1816
1984
  function itemDisabled(item) {
@@ -1998,82 +2166,6 @@ var Tabs = defineComponent({
1998
2166
  ]);
1999
2167
  }
2000
2168
  });
2001
-
2002
- // src/ported-core.ts
2003
- var STATUS_METADATA = {
2004
- subscription: {
2005
- future: {
2006
- description: "Subscription is scheduled but not yet active.",
2007
- tone: "info",
2008
- icon: "\u23F2"
2009
- },
2010
- trialing: {
2011
- description: "Subscription is in a trial period before billing begins.",
2012
- tone: "accent",
2013
- icon: "\u2605"
2014
- },
2015
- active: {
2016
- description: "Subscription is paid and service is provisioned.",
2017
- tone: "success",
2018
- icon: "\u2714\uFE0E"
2019
- },
2020
- paused: {
2021
- description: "Billing paused temporarily by finance or customer request.",
2022
- tone: "neutral",
2023
- icon: "\u23F8"
2024
- },
2025
- pending_cancellation: {
2026
- description: "Subscription will cancel at period end but remains active now.",
2027
- tone: "info",
2028
- icon: "\u2026"
2029
- },
2030
- past_due: {
2031
- description: "Renewal payment failed; smart retries ongoing and access retained during the grace window.",
2032
- tone: "critical",
2033
- icon: "\u26A0\uFE0E"
2034
- },
2035
- unpaid: {
2036
- description: "Payment retries exhausted; service access revoked.",
2037
- tone: "critical",
2038
- icon: "\u2A2F"
2039
- },
2040
- terminated: {
2041
- description: "Subscription ended; service access revoked and billing stopped.",
2042
- tone: "neutral",
2043
- icon: "\u2205"
2044
- }
2045
- },
2046
- invoice: {
2047
- draft: {
2048
- description: "Invoice is editable and not yet finalized.",
2049
- tone: "neutral",
2050
- icon: "\u270E"
2051
- },
2052
- posted: {
2053
- description: "Invoice finalized with terms before collection.",
2054
- tone: "info",
2055
- icon: "\u2026"
2056
- },
2057
- paid: {
2058
- description: "Invoice collected successfully in full.",
2059
- tone: "success",
2060
- icon: "\u2714\uFE0E"
2061
- },
2062
- past_due: {
2063
- description: "Invoice is unpaid past its due date.",
2064
- tone: "critical",
2065
- icon: "\u2A2F"
2066
- },
2067
- void: {
2068
- description: "Invoice canceled and no longer payable.",
2069
- tone: "neutral",
2070
- icon: "\u2205"
2071
- }
2072
- }
2073
- };
2074
- var STATUS_ALIASES = {
2075
- subscription: { delinquent: "unpaid" }
2076
- };
2077
2169
  function isRecord2(value) {
2078
2170
  return typeof value === "object" && value !== null && !Array.isArray(value);
2079
2171
  }
@@ -2090,18 +2182,13 @@ function statusLabel2(status) {
2090
2182
  return status.split(/[_-]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join(" ");
2091
2183
  }
2092
2184
  function getPortedStatusPresentation(domain, status) {
2093
- const normalizedDomain = domain.toLowerCase();
2094
- const normalizedStatus = status.toLowerCase();
2095
- const alias = STATUS_ALIASES[normalizedDomain]?.[normalizedStatus];
2096
- const metadata = STATUS_METADATA[normalizedDomain]?.[alias ?? normalizedStatus];
2097
- if (!metadata) {
2098
- return {
2099
- label: statusLabel2(status || "Unknown"),
2100
- description: "Status not found in registry; falling back to the requested token set.",
2101
- tone: "neutral"
2102
- };
2103
- }
2104
- return { ...metadata, label: statusLabel2(status) };
2185
+ const presentation = getStatusPresentation(domain.toLowerCase(), status);
2186
+ return {
2187
+ label: statusLabel2(status || "Unknown"),
2188
+ description: presentation.description,
2189
+ tone: presentation.tone,
2190
+ icon: resolveStatusIcon(presentation.iconName)
2191
+ };
2105
2192
  }
2106
2193
  function formatPrice(amountCents, amount, currency) {
2107
2194
  const normalizedAmount = amount;
@@ -2245,11 +2332,10 @@ var StatusBadge = defineComponent({
2245
2332
  domain: props.domain,
2246
2333
  tone,
2247
2334
  emphasis: props.variant === "solid" ? "solid" : props.emphasis,
2248
- icon: props.showIcon ? presentation.icon : void 0,
2249
2335
  title: stringValue(attrs.title) ?? presentation.description,
2250
2336
  "aria-label": ariaLabel,
2251
2337
  "data-oods-component": "StatusBadge"
2252
- }, slots);
2338
+ }, props.showIcon && presentation.icon && !slots.icon ? { ...slots, icon: () => statusIcon(presentation.icon) } : slots);
2253
2339
  };
2254
2340
  }
2255
2341
  });
@@ -2332,12 +2418,12 @@ var timelineProps = {
2332
2418
  };
2333
2419
  function renderTimelineEvent(event, index, showActorId, showReason) {
2334
2420
  return h("li", { key: `${event.timestamp ?? "event"}-${index}` }, [
2335
- h("article", { "data-timeline-event": "true" }, [
2336
- h("p", { "data-timeline-label": "true" }, event.label),
2421
+ h("article", { class: "oods-timeline__event", "data-timeline-event": "true" }, [
2422
+ h("p", { class: "oods-timeline__label", "data-timeline-label": "true" }, event.label),
2337
2423
  event.timestamp ? h("time", { "data-timeline-time": "true", datetime: event.timestamp }, formatDateTime(event.timestamp)) : null,
2338
- event.detail ? h("p", { "data-timeline-detail": "true" }, event.detail) : null,
2339
- showActorId && event.actorId ? h("p", { "data-timeline-actor": "true" }, `Actor: ${event.actorId}`) : null,
2340
- showReason && event.reason ? h("p", { "data-timeline-reason": "true" }, `Reason: ${event.reason}`) : null
2424
+ event.detail ? h("p", { class: "oods-timeline__detail", "data-timeline-detail": "true" }, event.detail) : null,
2425
+ showActorId && event.actorId ? h("p", { class: "oods-timeline__actor", "data-timeline-actor": "true" }, `Actor: ${event.actorId}`) : null,
2426
+ showReason && event.reason ? h("p", { class: "oods-timeline__reason", "data-timeline-reason": "true" }, `Reason: ${event.reason}`) : null
2341
2427
  ])
2342
2428
  ]);
2343
2429
  }
@@ -2355,16 +2441,16 @@ function timelineComponent(configuration) {
2355
2441
  const slottedEvents = slots.default?.();
2356
2442
  return h("div", {
2357
2443
  ...attrs,
2358
- class: mergedClass("oods-timeline", attrs.class),
2444
+ class: mergedClass(`oods-timeline oods-${configuration.timelineType}-timeline`, attrs.class),
2359
2445
  role: "log",
2360
2446
  "aria-label": stringValue(attrs["aria-label"]) ?? title,
2361
2447
  "data-oods-component": configuration.componentId,
2362
2448
  "data-timeline-type": configuration.timelineType
2363
2449
  }, [
2364
- h("h2", { "data-timeline-title": "true" }, title),
2365
- props.status ? h("p", { "data-timeline-current": "true" }, `Current status: ${statusLabel2(props.status)}`) : null,
2450
+ h("h2", { class: "oods-timeline__title", "data-timeline-title": "true" }, title),
2451
+ props.status ? h("p", { class: "oods-timeline__current", "data-timeline-current": "true" }, `Current status: ${statusLabel2(props.status)}`) : null,
2366
2452
  props.allowedTransitions?.length ? h("p", { "data-timeline-transitions": "true" }, `Allowed transitions: ${props.allowedTransitions.join(", ")}`) : null,
2367
- h("ol", { "data-timeline-events": "true" }, slottedEvents?.length ? slottedEvents : events.length ? events.map((event, index) => renderTimelineEvent(
2453
+ h("ol", { class: "oods-timeline__events", "data-timeline-events": "true" }, slottedEvents?.length ? slottedEvents : events.length ? events.map((event, index) => renderTimelineEvent(
2368
2454
  event,
2369
2455
  index,
2370
2456
  props.showActorId,
@@ -2520,8 +2606,7 @@ var SearchInput = defineComponent({
2520
2606
  updateValue("");
2521
2607
  emit("clear");
2522
2608
  };
2523
- const submit = (event) => {
2524
- event.preventDefault();
2609
+ const searchNow = () => {
2525
2610
  if (!props.disabled) {
2526
2611
  if (timer !== void 0) clearTimeout(timer);
2527
2612
  emitSearch(currentValue.value);
@@ -2530,14 +2615,13 @@ var SearchInput = defineComponent({
2530
2615
  return () => {
2531
2616
  const id = props.id ?? `oods-search-${generatedId.replace(/:/g, "")}`;
2532
2617
  const ariaLabel = stringValue(attrs["aria-label"]) ?? props.label ?? props.placeholder;
2533
- return h("form", {
2618
+ return h("div", {
2534
2619
  ...attrs,
2535
2620
  class: mergedClass("oods-search-input", attrs.class),
2536
2621
  role: "search",
2537
2622
  "aria-label": ariaLabel,
2538
2623
  "data-oods-component": "SearchInput",
2539
- "data-behavioral": "search",
2540
- onSubmit: submit
2624
+ "data-behavioral": "search"
2541
2625
  }, [
2542
2626
  h(Input, {
2543
2627
  id,
@@ -2546,19 +2630,25 @@ var SearchInput = defineComponent({
2546
2630
  value: currentValue.value,
2547
2631
  placeholder: props.placeholder,
2548
2632
  disabled: props.disabled,
2633
+ inputClass: "oods-search-input__control",
2549
2634
  "aria-label": props.label ? void 0 : ariaLabel,
2550
2635
  onInput: (value) => updateValue(value),
2551
2636
  onKeydown: (event) => {
2552
2637
  if (event.key === "Escape") clear();
2638
+ if (event.key === "Enter") {
2639
+ event.preventDefault();
2640
+ searchNow();
2641
+ }
2553
2642
  }
2554
2643
  }),
2555
2644
  props.clearable && currentValue.value ? h("button", {
2556
2645
  type: "button",
2646
+ class: "oods-search-input__clear",
2557
2647
  "data-search-clear": "true",
2558
2648
  "aria-label": "Clear search",
2559
2649
  disabled: props.disabled,
2560
2650
  onClick: clear
2561
- }, "\xD7") : null
2651
+ }, [statusIcon("x")]) : null
2562
2652
  ]);
2563
2653
  };
2564
2654
  }
@@ -2705,17 +2795,18 @@ var RelativeTimestamp = defineComponent({
2705
2795
  props.createdAt
2706
2796
  ) ?? "";
2707
2797
  if (props.hideWhenEmpty && (!datetime || Number.isNaN(Date.parse(datetime)))) return null;
2798
+ const absolute = formatDateTime(datetime, { timeZone: props.timezone });
2708
2799
  const content = firstDefined(
2709
2800
  props.relative,
2710
2801
  props.label,
2711
2802
  props.text,
2712
- props.now === void 0 ? formatDateTime(datetime, { timeZone: props.timezone }) : relativeTimestampLabel(datetime, props.now)
2803
+ !absolute ? "Unknown time" : props.now === void 0 ? absolute : relativeTimestampLabel(datetime, props.now)
2713
2804
  ) ?? "";
2714
2805
  return h("time", {
2715
2806
  ...attrs,
2716
2807
  class: mergedClass("oods-relative-timestamp", attrs.class),
2717
2808
  datetime: datetime || void 0,
2718
- title: stringValue(attrs.title) ?? formatDateTime(datetime, { timeZone: props.timezone }),
2809
+ title: stringValue(attrs.title) ?? absolute,
2719
2810
  "data-oods-component": "RelativeTimestamp"
2720
2811
  }, content);
2721
2812
  };
@@ -2963,7 +3054,7 @@ function summary(id) {
2963
3054
  } });
2964
3055
  }
2965
3056
  function preview(id, type) {
2966
- return defineComponent({ name: id, props: { svg: String, title: String, description: String, width: Number, height: Number }, setup(props, { slots }) {
3057
+ return defineComponent({ name: id, props: { svg: String, svgNarrow: String, svgWide: String, svgDark: String, svgDarkNarrow: String, svgDarkWide: String, svgHc: String, svgHcNarrow: String, svgHcWide: String, title: String, description: String, width: Number, height: Number }, setup(props, { slots }) {
2967
3058
  return () => h(VizAreaPreview, { ...props, title: props.title ?? `${type[0].toUpperCase()}${type.slice(1)} chart`, "data-oods-component": id, "data-viz-preview-type": type }, { default: slots.default ?? (() => h(Text, { content: "No rendered chart supplied" })) });
2968
3059
  } });
2969
3060
  }
@@ -2994,4 +3085,4 @@ var VizMarkPreview = preview("VizMarkPreview", "bar");
2994
3085
  var VizPointPreview = preview("VizPointPreview", "scatter");
2995
3086
  var VizScatterPreview = preview("VizScatterPreview", "scatter");
2996
3087
 
2997
- export { AddressCollectionPanel, AddressEditor, AddressSummaryBadge, AddressValidationTimeline, ArchiveEvent, ArchivePill, ArchiveSummary, ArchivedRowOverlay, AuditEvent, AuditSummaryCard, AuditTimeline, Badge, Banner, BillingAmountInput, BillingCardMeta, BillingIntervalSelector, BillingSummaryBadge, Button, CancellationBadge, CancellationEvent, CancellationForm, CancellationSummary, Card, CardHeader, Checkbox, ClassificationBadge, ClassificationEditor, ClassificationPanel, ColorStatePicker, ColorSwatch, ColorizedBadge, CommunicationDetailPanel, CycleProgressCard, DatePicker, DetailHeader, FilterPanel, FormLabelGroup, GeoFieldMappingForm, GeoResolutionBadge, GeocodablePreview, Grid, InlineLabel, Input, LabelCell, MembershipAuditTimeline, MembershipPanel, MessageEventTimeline, MessageStatusBadge, OwnerBadge, OwnershipMeta, OwnershipSummary, PaginationBar, PaymentEventTimeline, PaymentTimeline, PreferenceEditor, PreferencePanel, PreferenceSummaryBadge, PreferenceTimeline, PriceBadge, PriceCardMeta, PriceSummary, RelativeTimestamp, RoleAssignmentForm, RoleBadgeList, SearchInput, Select, SortIndicator, Stack, StateTransitionEvent, StatusBadge, StatusColorLegend, StatusSelector, StatusTimeline, Table, TableBody, TableCaption, TableCell, TableHead, TableHeaderCell, TableRow, Tabs, TagInput, TagManager, TagPills, TagSummary, TemplatePicker, Text, Textarea, 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 };
3088
+ export { AddressCollectionPanel, AddressEditor, AddressSummaryBadge, AddressValidationTimeline, ArchiveEvent, ArchivePill, ArchiveSummary, ArchivedRowOverlay, AuditEvent, AuditSummaryCard, AuditTimeline, Badge, Banner, BillingAmountInput, BillingCardMeta, BillingIntervalSelector, BillingSummaryBadge, Button, CancellationBadge, CancellationEvent, CancellationForm, CancellationSummary, Card, CardHeader, Checkbox, ClassificationBadge, ClassificationEditor, ClassificationPanel, ColorStatePicker, ColorSwatch, ColorizedBadge, CommunicationDetailPanel, CycleProgressCard, DatePicker, DetailHeader, Dialog, FilterPanel, FormLabelGroup, GeoFieldMappingForm, GeoResolutionBadge, GeocodablePreview, Grid, InlineLabel, Input, LabelCell, MembershipAuditTimeline, MembershipPanel, MessageEventTimeline, MessageStatusBadge, OwnerBadge, OwnershipMeta, OwnershipSummary, PaginationBar, PaymentEventTimeline, PaymentTimeline, PreferenceEditor, PreferencePanel, PreferenceSummaryBadge, PreferenceTimeline, PriceBadge, PriceCardMeta, PriceSummary, RelativeTimestamp, RoleAssignmentForm, RoleBadgeList, SearchInput, Select, SortIndicator, Stack, StateTransitionEvent, StatusBadge, StatusColorLegend, StatusSelector, StatusTimeline, Switch, Table, TableBody, TableCaption, TableCell, TableHead, TableHeaderCell, TableRow, Tabs, TagInput, TagManager, TagPills, TagSummary, TemplatePicker, Text, Textarea, 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 };