@jirawatpyk/aura-react 5.81.0 → 5.83.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/README.md CHANGED
@@ -248,6 +248,15 @@ DataTable with sort and page in the URL (4.17): `onStateChange={({ sort, page })
248
248
  - **Time zone**: `timeZone` on AuraProvider, DatePicker, DateRangePicker and Calendar decides "today" (the marker, `min`/`max="today"`, the first month shown); or pass `today` as an ISO date. `todayIn('Asia/Bangkok')` is exported from the root and `/server`.
249
249
  - **Toasts** queue past three instead of dropping: six in a row all show, in order, three at a time.
250
250
 
251
+ ## 5.83 — Chamber-OS 195–196 (Combobox announcements, Alert dismissLabel)
252
+
253
+ - **Combobox status region** (#195): one `role="status"` region is part of the field for its whole life (beside the input, so inside a Dialog too, where the portaled list sits outside the modal) and only its text changes. Closed: empty. Open: the loading text, then the empty text or — with `onSearch`, once a search has come back (`loading` back to `false` after the person typed) — the result count ("12 results", the `results` string in EN, TH, SV). The count needs a managed `loading` prop. An `onSearch` field says nothing before the person types (an empty server list doesn't say "No matches" on open). Without `onSearch`, "no matches" and "keep typing" are the same words as before, now announced reliably. A region inserted already holding text is often not announced (NVDA, VoiceOver), which is why the old line was mostly silent. The visible note is unchanged and hidden from screen readers, which hear the region. A test that finds the note by its words (`getByText('No matches')`) now matches the region too: scope it to `.aura-combo__note`, or use `getByRole('status')`.
254
+ - **Alert `dismissLabel`** (#196): the close button's accessible name, for a page with several notices or a notice about a named thing — `<Alert onDismiss={…} dismissLabel="Dismiss starter warning for Monthly Newsletter">`. Default: the `dismiss` string.
255
+
256
+ ## 5.82 — DxT Monitor 25 (Badge xs)
257
+
258
+ - **Badge `size="xs"`**: 16px high (a larger default font grows it), weight 500, 6px inset — a mark under a cell's main value that keeps a `rowHeight="density"` row at 48px (a 12px line with line-height 12px, 4px gap, the badge; a 12px text at its normal line-height is about 18px and the row grows). Thai text stays 11px at this size — the one exception to the 5.30 rule that Thai labels are at least 12px, so stacked tone marks stay off the 16px outline. Every tone and variant; no icon at this size (a dev warning says so). Also from `@jirawatpyk/aura-react/server`. `<Badge size="xs" variant="outline">Confirm</Badge>`.
259
+
251
260
  ## 5.81 — DxT Monitor 24 (the tab bar hides after a tap)
252
261
 
253
262
  - **BottomNav `hideOnScroll` and AppShell `headerHideOnScroll` after a tap**: with client-side navigation the bar stays mounted, and on Chrome / Android a tap leaves focus on the tapped tab — the bar then never hid on the next page. Focus in the bar now holds it only when it came from the keyboard: focus that enters right after a pointer press doesn't count, and focus moved with the keyboard does (Tab into or within the bar brings it back and keeps it; keys that only scroll the page, such as Space or PageDown, don't). A text field in the bar holds it however it was focused. No new prop; drop any wrapper that blurs the tab on click.
@@ -819,6 +819,7 @@ window.Aura = (() => {
819
819
  "children",
820
820
  "action",
821
821
  "onDismiss",
822
+ "dismissLabel",
822
823
  "className",
823
824
  "role",
824
825
  "icon"
@@ -923,7 +924,10 @@ window.Aura = (() => {
923
924
  );
924
925
  }
925
926
  function badgeElement(props, ref) {
926
- const rest = omit(props, ["tone", "variant", "icon", "className", "children"]);
927
+ const rest = omit(props, ["tone", "variant", "icon", "className", "children", "size"]);
928
+ const xs = props.size === "xs";
929
+ if (xs && props.icon)
930
+ devWarnOnce("badge-xs-icon", 'Badge size="xs" has no icon (16px leaves no room for one); the icon is not shown.');
927
931
  return /* @__PURE__ */ React4.createElement(
928
932
  "span",
929
933
  {
@@ -934,10 +938,11 @@ window.Aura = (() => {
934
938
  "aura-badge--" + tone(props.tone),
935
939
  props.variant === "solid" && "is-solid",
936
940
  props.variant === "outline" && "is-outline",
941
+ xs && "aura-badge--xs",
937
942
  props.className
938
943
  )
939
944
  },
940
- props.icon ? /* @__PURE__ */ React4.createElement(Icon, { name: props.icon, size: 12 }) : null,
945
+ props.icon && !xs ? /* @__PURE__ */ React4.createElement(Icon, { name: props.icon, size: 12 }) : null,
941
946
  props.children
942
947
  );
943
948
  }
@@ -4354,6 +4359,9 @@ window.Aura = (() => {
4354
4359
  [activeIdx, open]
4355
4360
  );
4356
4361
  const live = props.loading ? [] : shown;
4362
+ const listShown = open && mounted && !!posState[0];
4363
+ const searching = !!props.onSearch;
4364
+ const statusText = !listShown ? "" : props.loading ? props.loadingText || t.searching : searching && query == null ? "" : !live.length ? props.emptyText || t.noMatches : more ? t.keepTyping(options.length) : searching && props.loading === false ? t.results(live.length) : "";
4357
4365
  function openList() {
4358
4366
  if (!open && !props.disabled && !props.readOnly) {
4359
4367
  setOpen(true);
@@ -4527,7 +4535,7 @@ window.Aura = (() => {
4527
4535
  })));
4528
4536
  })
4529
4537
  ) : null,
4530
- props.loading || !live.length || more ? /* @__PURE__ */ React23.createElement("div", { className: "aura-combo__list", role: "status" }, props.loading ? /* @__PURE__ */ React23.createElement("div", { className: "aura-combo__note" }, /* @__PURE__ */ React23.createElement(Icon, { name: /* @__PURE__ */ React23.createElement(IconLoaderCircle, null), className: "aura-spin" }), props.loadingText || t.searching) : !live.length ? /* @__PURE__ */ React23.createElement("div", { className: "aura-combo__note" }, props.emptyText || t.noMatches) : /* @__PURE__ */ React23.createElement("div", { className: "aura-combo__note" }, t.keepTyping(options.length))) : null
4538
+ props.loading || !live.length || more ? /* @__PURE__ */ React23.createElement("div", { className: "aura-combo__list", "aria-hidden": "true" }, props.loading ? /* @__PURE__ */ React23.createElement("div", { className: "aura-combo__note" }, /* @__PURE__ */ React23.createElement(Icon, { name: /* @__PURE__ */ React23.createElement(IconLoaderCircle, null), className: "aura-spin" }), props.loadingText || t.searching) : !live.length ? /* @__PURE__ */ React23.createElement("div", { className: "aura-combo__note" }, props.emptyText || t.noMatches) : /* @__PURE__ */ React23.createElement("div", { className: "aura-combo__note" }, t.keepTyping(options.length))) : null
4531
4539
  ),
4532
4540
  document.body
4533
4541
  ) : null;
@@ -4653,6 +4661,7 @@ window.Aura = (() => {
4653
4661
  },
4654
4662
  /* @__PURE__ */ React23.createElement(Icon, { name: /* @__PURE__ */ React23.createElement(IconChevronDown, null) })
4655
4663
  )),
4664
+ /* @__PURE__ */ React23.createElement("div", { role: "status", className: "aura-sr-only aura-combo__status" }, statusText),
4656
4665
  list
4657
4666
  );
4658
4667
  }
@@ -4666,7 +4675,15 @@ window.Aura = (() => {
4666
4675
  return alertElement(
4667
4676
  props,
4668
4677
  ref,
4669
- props.onDismiss ? /* @__PURE__ */ React24.createElement(IconButton, { icon: /* @__PURE__ */ React24.createElement(IconX, null), label: t.dismiss, className: "aura-alert__close", onClick: props.onDismiss }) : null,
4678
+ props.onDismiss ? /* @__PURE__ */ React24.createElement(
4679
+ IconButton,
4680
+ {
4681
+ icon: /* @__PURE__ */ React24.createElement(IconX, null),
4682
+ label: props.dismissLabel || t.dismiss,
4683
+ className: "aura-alert__close",
4684
+ onClick: props.onDismiss
4685
+ }
4686
+ ) : null,
4670
4687
  autoId
4671
4688
  );
4672
4689
  });
@@ -801,6 +801,7 @@ function alertElement(props, ref, close, autoId) {
801
801
  "children",
802
802
  "action",
803
803
  "onDismiss",
804
+ "dismissLabel",
804
805
  "className",
805
806
  "role",
806
807
  "icon"
@@ -905,7 +906,10 @@ function spinnerElement(props, ref) {
905
906
  );
906
907
  }
907
908
  function badgeElement(props, ref) {
908
- const rest = omit(props, ["tone", "variant", "icon", "className", "children"]);
909
+ const rest = omit(props, ["tone", "variant", "icon", "className", "children", "size"]);
910
+ const xs = props.size === "xs";
911
+ if (xs && props.icon)
912
+ devWarnOnce("badge-xs-icon", 'Badge size="xs" has no icon (16px leaves no room for one); the icon is not shown.');
909
913
  return /* @__PURE__ */ React4.createElement(
910
914
  "span",
911
915
  {
@@ -916,10 +920,11 @@ function badgeElement(props, ref) {
916
920
  "aura-badge--" + tone(props.tone),
917
921
  props.variant === "solid" && "is-solid",
918
922
  props.variant === "outline" && "is-outline",
923
+ xs && "aura-badge--xs",
919
924
  props.className
920
925
  )
921
926
  },
922
- props.icon ? /* @__PURE__ */ React4.createElement(Icon, { name: props.icon, size: 12 }) : null,
927
+ props.icon && !xs ? /* @__PURE__ */ React4.createElement(Icon, { name: props.icon, size: 12 }) : null,
923
928
  props.children
924
929
  );
925
930
  }
@@ -4336,6 +4341,9 @@ var Combobox = React23.forwardRef(
4336
4341
  [activeIdx, open]
4337
4342
  );
4338
4343
  const live = props.loading ? [] : shown;
4344
+ const listShown = open && mounted && !!posState[0];
4345
+ const searching = !!props.onSearch;
4346
+ const statusText = !listShown ? "" : props.loading ? props.loadingText || t.searching : searching && query == null ? "" : !live.length ? props.emptyText || t.noMatches : more ? t.keepTyping(options.length) : searching && props.loading === false ? t.results(live.length) : "";
4339
4347
  function openList() {
4340
4348
  if (!open && !props.disabled && !props.readOnly) {
4341
4349
  setOpen(true);
@@ -4509,7 +4517,7 @@ var Combobox = React23.forwardRef(
4509
4517
  })));
4510
4518
  })
4511
4519
  ) : null,
4512
- props.loading || !live.length || more ? /* @__PURE__ */ React23.createElement("div", { className: "aura-combo__list", role: "status" }, props.loading ? /* @__PURE__ */ React23.createElement("div", { className: "aura-combo__note" }, /* @__PURE__ */ React23.createElement(Icon, { name: /* @__PURE__ */ React23.createElement(IconLoaderCircle, null), className: "aura-spin" }), props.loadingText || t.searching) : !live.length ? /* @__PURE__ */ React23.createElement("div", { className: "aura-combo__note" }, props.emptyText || t.noMatches) : /* @__PURE__ */ React23.createElement("div", { className: "aura-combo__note" }, t.keepTyping(options.length))) : null
4520
+ props.loading || !live.length || more ? /* @__PURE__ */ React23.createElement("div", { className: "aura-combo__list", "aria-hidden": "true" }, props.loading ? /* @__PURE__ */ React23.createElement("div", { className: "aura-combo__note" }, /* @__PURE__ */ React23.createElement(Icon, { name: /* @__PURE__ */ React23.createElement(IconLoaderCircle, null), className: "aura-spin" }), props.loadingText || t.searching) : !live.length ? /* @__PURE__ */ React23.createElement("div", { className: "aura-combo__note" }, props.emptyText || t.noMatches) : /* @__PURE__ */ React23.createElement("div", { className: "aura-combo__note" }, t.keepTyping(options.length))) : null
4513
4521
  ),
4514
4522
  document.body
4515
4523
  ) : null;
@@ -4635,6 +4643,7 @@ var Combobox = React23.forwardRef(
4635
4643
  },
4636
4644
  /* @__PURE__ */ React23.createElement(Icon, { name: /* @__PURE__ */ React23.createElement(IconChevronDown, null) })
4637
4645
  )),
4646
+ /* @__PURE__ */ React23.createElement("div", { role: "status", className: "aura-sr-only aura-combo__status" }, statusText),
4638
4647
  list
4639
4648
  );
4640
4649
  }
@@ -4648,7 +4657,15 @@ var Alert = React24.forwardRef(function Alert2(props, ref) {
4648
4657
  return alertElement(
4649
4658
  props,
4650
4659
  ref,
4651
- props.onDismiss ? /* @__PURE__ */ React24.createElement(IconButton, { icon: /* @__PURE__ */ React24.createElement(IconX, null), label: t.dismiss, className: "aura-alert__close", onClick: props.onDismiss }) : null,
4660
+ props.onDismiss ? /* @__PURE__ */ React24.createElement(
4661
+ IconButton,
4662
+ {
4663
+ icon: /* @__PURE__ */ React24.createElement(IconX, null),
4664
+ label: props.dismissLabel || t.dismiss,
4665
+ className: "aura-alert__close",
4666
+ onClick: props.onDismiss
4667
+ }
4668
+ ) : null,
4652
4669
  autoId
4653
4670
  );
4654
4671
  });
package/dist/esm/Alert.js CHANGED
@@ -12,7 +12,15 @@ const Alert = React.forwardRef(function Alert2(props, ref) {
12
12
  return alertElement(
13
13
  props,
14
14
  ref,
15
- props.onDismiss ? /* @__PURE__ */ React.createElement(IconButton, { icon: /* @__PURE__ */ React.createElement(IconX, null), label: t.dismiss, className: "aura-alert__close", onClick: props.onDismiss }) : null,
15
+ props.onDismiss ? /* @__PURE__ */ React.createElement(
16
+ IconButton,
17
+ {
18
+ icon: /* @__PURE__ */ React.createElement(IconX, null),
19
+ label: props.dismissLabel || t.dismiss,
20
+ className: "aura-alert__close",
21
+ onClick: props.onDismiss
22
+ }
23
+ ) : null,
16
24
  autoId
17
25
  );
18
26
  });
@@ -138,6 +138,9 @@ const Combobox = React.forwardRef(
138
138
  [activeIdx, open]
139
139
  );
140
140
  const live = props.loading ? [] : shown;
141
+ const listShown = open && mounted && !!posState[0];
142
+ const searching = !!props.onSearch;
143
+ const statusText = !listShown ? "" : props.loading ? props.loadingText || t.searching : searching && query == null ? "" : !live.length ? props.emptyText || t.noMatches : more ? t.keepTyping(options.length) : searching && props.loading === false ? t.results(live.length) : "";
141
144
  function openList() {
142
145
  if (!open && !props.disabled && !props.readOnly) {
143
146
  setOpen(true);
@@ -311,7 +314,7 @@ const Combobox = React.forwardRef(
311
314
  })));
312
315
  })
313
316
  ) : null,
314
- props.loading || !live.length || more ? /* @__PURE__ */ React.createElement("div", { className: "aura-combo__list", role: "status" }, props.loading ? /* @__PURE__ */ React.createElement("div", { className: "aura-combo__note" }, /* @__PURE__ */ React.createElement(Icon, { name: /* @__PURE__ */ React.createElement(IconLoaderCircle, null), className: "aura-spin" }), props.loadingText || t.searching) : !live.length ? /* @__PURE__ */ React.createElement("div", { className: "aura-combo__note" }, props.emptyText || t.noMatches) : /* @__PURE__ */ React.createElement("div", { className: "aura-combo__note" }, t.keepTyping(options.length))) : null
317
+ props.loading || !live.length || more ? /* @__PURE__ */ React.createElement("div", { className: "aura-combo__list", "aria-hidden": "true" }, props.loading ? /* @__PURE__ */ React.createElement("div", { className: "aura-combo__note" }, /* @__PURE__ */ React.createElement(Icon, { name: /* @__PURE__ */ React.createElement(IconLoaderCircle, null), className: "aura-spin" }), props.loadingText || t.searching) : !live.length ? /* @__PURE__ */ React.createElement("div", { className: "aura-combo__note" }, props.emptyText || t.noMatches) : /* @__PURE__ */ React.createElement("div", { className: "aura-combo__note" }, t.keepTyping(options.length))) : null
315
318
  ),
316
319
  document.body
317
320
  ) : null;
@@ -437,6 +440,7 @@ const Combobox = React.forwardRef(
437
440
  },
438
441
  /* @__PURE__ */ React.createElement(Icon, { name: /* @__PURE__ */ React.createElement(IconChevronDown, null) })
439
442
  )),
443
+ /* @__PURE__ */ React.createElement("div", { role: "status", className: "aura-sr-only aura-combo__status" }, statusText),
440
444
  list
441
445
  );
442
446
  }
@@ -33,6 +33,7 @@ function alertElement(props, ref, close, autoId) {
33
33
  "children",
34
34
  "action",
35
35
  "onDismiss",
36
+ "dismissLabel",
36
37
  "className",
37
38
  "role",
38
39
  "icon"
@@ -137,7 +138,10 @@ function spinnerElement(props, ref) {
137
138
  );
138
139
  }
139
140
  function badgeElement(props, ref) {
140
- const rest = omit(props, ["tone", "variant", "icon", "className", "children"]);
141
+ const rest = omit(props, ["tone", "variant", "icon", "className", "children", "size"]);
142
+ const xs = props.size === "xs";
143
+ if (xs && props.icon)
144
+ devWarnOnce("badge-xs-icon", 'Badge size="xs" has no icon (16px leaves no room for one); the icon is not shown.');
141
145
  return /* @__PURE__ */ React.createElement(
142
146
  "span",
143
147
  {
@@ -148,10 +152,11 @@ function badgeElement(props, ref) {
148
152
  "aura-badge--" + badgeTone(props.tone),
149
153
  props.variant === "solid" && "is-solid",
150
154
  props.variant === "outline" && "is-outline",
155
+ xs && "aura-badge--xs",
151
156
  props.className
152
157
  )
153
158
  },
154
- props.icon ? /* @__PURE__ */ React.createElement(Icon, { name: props.icon, size: 12 }) : null,
159
+ props.icon && !xs ? /* @__PURE__ */ React.createElement(Icon, { name: props.icon, size: 12 }) : null,
155
160
  props.children
156
161
  );
157
162
  }
package/dist/index.d.cts CHANGED
@@ -773,6 +773,10 @@ export interface AlertProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>,
773
773
  action?: React$1.ReactNode | undefined;
774
774
  /** Adds a close button. */
775
775
  onDismiss?: (() => void) | undefined;
776
+ /** 5.83 (Chamber-OS 196): the close button's accessible name — say what is dismissed when a page has several
777
+ * notices or the notice is about a named thing ("Dismiss starter warning for Monthly Newsletter"). Default: the
778
+ * `dismiss` string ("Dismiss"). */
779
+ dismissLabel?: string | undefined;
776
780
  className?: string | undefined;
777
781
  }
778
782
  /** A button (or, with `href`, a link through AuraProvider's `linkComponent`) on a toast (5.6: `href`, `dismiss`). */
@@ -1076,6 +1080,8 @@ export interface ComboboxProps extends FieldProps {
1076
1080
  clearable?: boolean | undefined;
1077
1081
  /** Server-side search: called with the typed text; the component stops filtering and shows `options` as given. */
1078
1082
  onSearch?: ((query: string) => void) | undefined;
1083
+ /** A search is running: the list shows `loadingText`. 5.83: with `onSearch`, the result count is announced when
1084
+ * `loading` goes back to `false` after a search — pass `false`, not leave it out, once results arrive. */
1079
1085
  loading?: boolean | undefined;
1080
1086
  loadingText?: string | undefined;
1081
1087
  emptyText?: string | undefined;
@@ -1719,6 +1725,9 @@ export interface BadgeProps extends React$1.HTMLAttributes<HTMLSpanElement> {
1719
1725
  /** soft (default) · solid · outline */
1720
1726
  variant?: "soft" | "solid" | "outline" | undefined;
1721
1727
  icon?: IconInput | undefined;
1728
+ /** 5.82 (DxT Monitor 25): `xs` — 16px high, weight 500, 6px inset: a mark under a value inside a `rowHeight="density"`
1729
+ * row. No icon at this size (a dev warning says so). Default `sm` (20px). */
1730
+ size?: "xs" | "sm" | undefined;
1722
1731
  }
1723
1732
  export interface TagProps extends Omit<React$1.HTMLAttributes<HTMLElement>, "onClick"> {
1724
1733
  children: React$1.ReactNode;
package/dist/index.d.ts CHANGED
@@ -773,6 +773,10 @@ export interface AlertProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>,
773
773
  action?: React$1.ReactNode | undefined;
774
774
  /** Adds a close button. */
775
775
  onDismiss?: (() => void) | undefined;
776
+ /** 5.83 (Chamber-OS 196): the close button's accessible name — say what is dismissed when a page has several
777
+ * notices or the notice is about a named thing ("Dismiss starter warning for Monthly Newsletter"). Default: the
778
+ * `dismiss` string ("Dismiss"). */
779
+ dismissLabel?: string | undefined;
776
780
  className?: string | undefined;
777
781
  }
778
782
  /** A button (or, with `href`, a link through AuraProvider's `linkComponent`) on a toast (5.6: `href`, `dismiss`). */
@@ -1076,6 +1080,8 @@ export interface ComboboxProps extends FieldProps {
1076
1080
  clearable?: boolean | undefined;
1077
1081
  /** Server-side search: called with the typed text; the component stops filtering and shows `options` as given. */
1078
1082
  onSearch?: ((query: string) => void) | undefined;
1083
+ /** A search is running: the list shows `loadingText`. 5.83: with `onSearch`, the result count is announced when
1084
+ * `loading` goes back to `false` after a search — pass `false`, not leave it out, once results arrive. */
1079
1085
  loading?: boolean | undefined;
1080
1086
  loadingText?: string | undefined;
1081
1087
  emptyText?: string | undefined;
@@ -1719,6 +1725,9 @@ export interface BadgeProps extends React$1.HTMLAttributes<HTMLSpanElement> {
1719
1725
  /** soft (default) · solid · outline */
1720
1726
  variant?: "soft" | "solid" | "outline" | undefined;
1721
1727
  icon?: IconInput | undefined;
1728
+ /** 5.82 (DxT Monitor 25): `xs` — 16px high, weight 500, 6px inset: a mark under a value inside a `rowHeight="density"`
1729
+ * row. No icon at this size (a dev warning says so). Default `sm` (20px). */
1730
+ size?: "xs" | "sm" | undefined;
1722
1731
  }
1723
1732
  export interface TagProps extends Omit<React$1.HTMLAttributes<HTMLElement>, "onClick"> {
1724
1733
  children: React$1.ReactNode;
@@ -1204,6 +1204,7 @@ function alertElement(props, ref, close, autoId) {
1204
1204
  "children",
1205
1205
  "action",
1206
1206
  "onDismiss",
1207
+ "dismissLabel",
1207
1208
  "className",
1208
1209
  "role",
1209
1210
  "icon"
@@ -1308,7 +1309,10 @@ function spinnerElement(props, ref) {
1308
1309
  );
1309
1310
  }
1310
1311
  function badgeElement(props, ref) {
1311
- const rest = omit(props, ["tone", "variant", "icon", "className", "children"]);
1312
+ const rest = omit(props, ["tone", "variant", "icon", "className", "children", "size"]);
1313
+ const xs = props.size === "xs";
1314
+ if (xs && props.icon)
1315
+ devWarnOnce("badge-xs-icon", 'Badge size="xs" has no icon (16px leaves no room for one); the icon is not shown.');
1312
1316
  return /* @__PURE__ */ React3.createElement(
1313
1317
  "span",
1314
1318
  {
@@ -1319,10 +1323,11 @@ function badgeElement(props, ref) {
1319
1323
  "aura-badge--" + tone(props.tone),
1320
1324
  props.variant === "solid" && "is-solid",
1321
1325
  props.variant === "outline" && "is-outline",
1326
+ xs && "aura-badge--xs",
1322
1327
  props.className
1323
1328
  )
1324
1329
  },
1325
- props.icon ? /* @__PURE__ */ React3.createElement(Icon, { name: props.icon, size: 12 }) : null,
1330
+ props.icon && !xs ? /* @__PURE__ */ React3.createElement(Icon, { name: props.icon, size: 12 }) : null,
1326
1331
  props.children
1327
1332
  );
1328
1333
  }
@@ -92,6 +92,10 @@ export interface AlertProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>,
92
92
  action?: React$1.ReactNode | undefined;
93
93
  /** Adds a close button. */
94
94
  onDismiss?: (() => void) | undefined;
95
+ /** 5.83 (Chamber-OS 196): the close button's accessible name — say what is dismissed when a page has several
96
+ * notices or the notice is about a named thing ("Dismiss starter warning for Monthly Newsletter"). Default: the
97
+ * `dismiss` string ("Dismiss"). */
98
+ dismissLabel?: string | undefined;
95
99
  className?: string | undefined;
96
100
  }
97
101
  /** Other attributes (`id`, `data-*`, `aria-*`) go on the card's root (5.8). */
@@ -222,6 +226,9 @@ export interface BadgeProps extends React$1.HTMLAttributes<HTMLSpanElement> {
222
226
  /** soft (default) · solid · outline */
223
227
  variant?: "soft" | "solid" | "outline" | undefined;
224
228
  icon?: IconInput | undefined;
229
+ /** 5.82 (DxT Monitor 25): `xs` — 16px high, weight 500, 6px inset: a mark under a value inside a `rowHeight="density"`
230
+ * row. No icon at this size (a dev warning says so). Default `sm` (20px). */
231
+ size?: "xs" | "sm" | undefined;
225
232
  }
226
233
  export interface EmptyStateProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, "title" | "children"> {
227
234
  title: React$1.ReactNode;
@@ -532,7 +539,7 @@ export declare function linkClass(opts?: {
532
539
  touchHeight?: boolean | "always" | undefined;
533
540
  className?: string | undefined;
534
541
  }): string;
535
- declare function ServerAlert(props: Omit<AlertProps, "onDismiss">): React$1.ReactElement;
542
+ declare function ServerAlert(props: Omit<AlertProps, "onDismiss" | "dismissLabel">): React$1.ReactElement;
536
543
  declare function ServerCard(props: CardProps): React$1.ReactElement;
537
544
  declare function ServerStatusPill(props: StatusPillProps): React$1.ReactElement;
538
545
  declare function ServerSpinner(props: SpinnerProps): React$1.ReactElement;
@@ -92,6 +92,10 @@ export interface AlertProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>,
92
92
  action?: React$1.ReactNode | undefined;
93
93
  /** Adds a close button. */
94
94
  onDismiss?: (() => void) | undefined;
95
+ /** 5.83 (Chamber-OS 196): the close button's accessible name — say what is dismissed when a page has several
96
+ * notices or the notice is about a named thing ("Dismiss starter warning for Monthly Newsletter"). Default: the
97
+ * `dismiss` string ("Dismiss"). */
98
+ dismissLabel?: string | undefined;
95
99
  className?: string | undefined;
96
100
  }
97
101
  /** Other attributes (`id`, `data-*`, `aria-*`) go on the card's root (5.8). */
@@ -222,6 +226,9 @@ export interface BadgeProps extends React$1.HTMLAttributes<HTMLSpanElement> {
222
226
  /** soft (default) · solid · outline */
223
227
  variant?: "soft" | "solid" | "outline" | undefined;
224
228
  icon?: IconInput | undefined;
229
+ /** 5.82 (DxT Monitor 25): `xs` — 16px high, weight 500, 6px inset: a mark under a value inside a `rowHeight="density"`
230
+ * row. No icon at this size (a dev warning says so). Default `sm` (20px). */
231
+ size?: "xs" | "sm" | undefined;
225
232
  }
226
233
  export interface EmptyStateProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, "title" | "children"> {
227
234
  title: React$1.ReactNode;
@@ -532,7 +539,7 @@ export declare function linkClass(opts?: {
532
539
  touchHeight?: boolean | "always" | undefined;
533
540
  className?: string | undefined;
534
541
  }): string;
535
- declare function ServerAlert(props: Omit<AlertProps, "onDismiss">): React$1.ReactElement;
542
+ declare function ServerAlert(props: Omit<AlertProps, "onDismiss" | "dismissLabel">): React$1.ReactElement;
536
543
  declare function ServerCard(props: CardProps): React$1.ReactElement;
537
544
  declare function ServerStatusPill(props: StatusPillProps): React$1.ReactElement;
538
545
  declare function ServerSpinner(props: SpinnerProps): React$1.ReactElement;
@@ -1137,6 +1137,7 @@ function alertElement(props, ref, close, autoId) {
1137
1137
  "children",
1138
1138
  "action",
1139
1139
  "onDismiss",
1140
+ "dismissLabel",
1140
1141
  "className",
1141
1142
  "role",
1142
1143
  "icon"
@@ -1241,7 +1242,10 @@ function spinnerElement(props, ref) {
1241
1242
  );
1242
1243
  }
1243
1244
  function badgeElement(props, ref) {
1244
- const rest = omit(props, ["tone", "variant", "icon", "className", "children"]);
1245
+ const rest = omit(props, ["tone", "variant", "icon", "className", "children", "size"]);
1246
+ const xs = props.size === "xs";
1247
+ if (xs && props.icon)
1248
+ devWarnOnce("badge-xs-icon", 'Badge size="xs" has no icon (16px leaves no room for one); the icon is not shown.');
1245
1249
  return /* @__PURE__ */ React3.createElement(
1246
1250
  "span",
1247
1251
  {
@@ -1252,10 +1256,11 @@ function badgeElement(props, ref) {
1252
1256
  "aura-badge--" + tone(props.tone),
1253
1257
  props.variant === "solid" && "is-solid",
1254
1258
  props.variant === "outline" && "is-outline",
1259
+ xs && "aura-badge--xs",
1255
1260
  props.className
1256
1261
  )
1257
1262
  },
1258
- props.icon ? /* @__PURE__ */ React3.createElement(Icon, { name: props.icon, size: 12 }) : null,
1263
+ props.icon && !xs ? /* @__PURE__ */ React3.createElement(Icon, { name: props.icon, size: 12 }) : null,
1259
1264
  props.children
1260
1265
  );
1261
1266
  }
package/dist/styles.css CHANGED
@@ -1671,6 +1671,12 @@ a.aura-upload__name:focus-visible { outline: var(--aura-focus-ring-width) solid
1671
1671
  .aura-badge--neutral.is-outline { border-color: var(--aura-border-control); }
1672
1672
  .aura-badge.is-solid { background: var(--aura-button-primary-bg); color: var(--aura-button-primary-fg); }
1673
1673
  .aura-badge--danger.is-solid { background: var(--aura-status-blocked-solid-bg); color: var(--aura-status-blocked-solid-fg); }
1674
+ /* 5.82 (DxT Monitor 25): xs — a mark under a cell's value in a density row (48px: a 12px line, 4px, this). 16px at the
1675
+ * default font (min-, so a larger default font grows it), weight 500, 6px inset. Same tones and variants. */
1676
+ .aura-badge--xs { min-height: 16px; padding: 0 6px; font-weight: 500; }
1677
+ /* Thai keeps 11px at xs — the one exception to the 5.30 Thai 12px floor: at 12px with line-height 1 the stacked tone
1678
+ * marks (ซ้ำ) touch the outline; 11px keeps them off the border. */
1679
+ .aura-badge.aura-badge--xs:lang(th) { font-size: max(11px, .6875rem); }
1674
1680
 
1675
1681
  /* ---------- Tag ---------- */
1676
1682
  .aura-tag {
@@ -1673,6 +1673,12 @@ a.aura-upload__name:focus-visible { outline: var(--aura-focus-ring-width) solid
1673
1673
  .aura-badge--neutral.is-outline { border-color: var(--aura-border-control); }
1674
1674
  .aura-badge.is-solid { background: var(--aura-button-primary-bg); color: var(--aura-button-primary-fg); }
1675
1675
  .aura-badge--danger.is-solid { background: var(--aura-status-blocked-solid-bg); color: var(--aura-status-blocked-solid-fg); }
1676
+ /* 5.82 (DxT Monitor 25): xs — a mark under a cell's value in a density row (48px: a 12px line, 4px, this). 16px at the
1677
+ * default font (min-, so a larger default font grows it), weight 500, 6px inset. Same tones and variants. */
1678
+ .aura-badge--xs { min-height: 16px; padding: 0 6px; font-weight: 500; }
1679
+ /* Thai keeps 11px at xs — the one exception to the 5.30 Thai 12px floor: at 12px with line-height 1 the stacked tone
1680
+ * marks (ซ้ำ) touch the outline; 11px keeps them off the border. */
1681
+ .aura-badge.aura-badge--xs:lang(th) { font-size: max(11px, .6875rem); }
1676
1682
 
1677
1683
  /* ---------- Tag ---------- */
1678
1684
  .aura-tag {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jirawatpyk/aura-react",
3
- "version": "5.81.0",
3
+ "version": "5.83.0",
4
4
  "description": "AURA Design System — React components (Enterprise Standard, Human Creative). Thai-first: Buddhist-era dates, Thai collation.",
5
5
  "license": "MIT",
6
6
  "type": "module",