@jirawatpyk/aura-react 5.14.0 → 5.16.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.
@@ -55,7 +55,13 @@ const FilterBar = React.forwardRef(function FilterBar2(props, ref) {
55
55
  ref,
56
56
  role: "region",
57
57
  "aria-label": props.label || t.filters,
58
- className: cx("aura-filterbar", props.searchGrow && "aura-filterbar--grow", props.className)
58
+ className: cx(
59
+ "aura-filterbar",
60
+ props.searchGrow && "aura-filterbar--grow",
61
+ props.controlsLayout === "fill" && "aura-filterbar--fill",
62
+ props.stackBelow === "lg" && "aura-filterbar--stack-lg",
63
+ props.className
64
+ )
59
65
  },
60
66
  /* @__PURE__ */ React.createElement("div", { className: "aura-filterbar__row" }, hasSearch ? /* @__PURE__ */ React.createElement("div", { className: "aura-input has-icon aura-filterbar__search" }, /* @__PURE__ */ React.createElement(Icon, { name: /* @__PURE__ */ React.createElement(IconSearch, null), className: "aura-input__icon" }), /* @__PURE__ */ React.createElement(
61
67
  "input",
@@ -3,7 +3,7 @@ import * as React from "react";
3
3
  import { cx, omit } from "./internal.js";
4
4
  import { Icon } from "./Icon.js";
5
5
  const IconButton = React.forwardRef(function IconButton2(props, ref) {
6
- const rest = omit(props, ["icon", "label", "className", "size", "tone"]);
6
+ const rest = omit(props, ["icon", "label", "className", "size", "tone", "touchHeight"]);
7
7
  return /* @__PURE__ */ React.createElement(
8
8
  "button",
9
9
  {
@@ -12,7 +12,12 @@ const IconButton = React.forwardRef(function IconButton2(props, ref) {
12
12
  type: props.type || "button",
13
13
  "aria-label": props.label,
14
14
  title: props.label,
15
- className: cx("aura-icon-btn", props.tone === "danger" && "aura-icon-btn--danger", props.className)
15
+ className: cx(
16
+ "aura-icon-btn",
17
+ props.tone === "danger" && "aura-icon-btn--danger",
18
+ props.touchHeight && "aura-icon-btn--touch",
19
+ props.className
20
+ )
16
21
  },
17
22
  /* @__PURE__ */ React.createElement(Icon, { name: props.icon, size: props.size || "sm" })
18
23
  );
@@ -1,10 +1,15 @@
1
1
  'use client';
2
2
  import * as React from "react";
3
3
  import { cx, tone, uid } from "./internal.js";
4
+ import { useStrings } from "./locale.js";
4
5
  const Progress = React.forwardRef(function Progress2(props, ref) {
6
+ const t = useStrings();
5
7
  const auto = uid(), id = props.id || auto;
6
8
  const max = props.max || 100, det = props.value != null;
7
9
  const pct = det ? Math.max(0, Math.min(100, props.value / max * 100)) : 0;
10
+ const sec = det && props.secondaryValue != null && props.secondaryValue > 0 ? props.secondaryValue : 0;
11
+ const spct = sec ? Math.max(0, Math.min(100 - pct, sec / max * 100)) : 0;
12
+ const valueText = props.valueLabel != null ? String(props.valueLabel) : sec ? t.progressReserved(props.value, sec, max) : void 0;
8
13
  const shown = props.valueLabel != null ? props.valueLabel : det ? Math.round(pct) + "%" : null;
9
14
  return /* @__PURE__ */ React.createElement(
10
15
  "div",
@@ -28,9 +33,16 @@ const Progress = React.forwardRef(function Progress2(props, ref) {
28
33
  "aria-valuemin": det ? 0 : void 0,
29
34
  "aria-valuemax": det ? max : void 0,
30
35
  "aria-valuenow": det ? props.value : void 0,
31
- "aria-valuetext": det && props.valueLabel != null ? String(props.valueLabel) : void 0
36
+ "aria-valuetext": det ? valueText : void 0
32
37
  },
33
- /* @__PURE__ */ React.createElement("span", { className: "aura-progress__bar", style: det ? { width: pct + "%" } : void 0 })
38
+ /* @__PURE__ */ React.createElement("span", { className: "aura-progress__bar", style: det ? { width: pct + "%" } : void 0 }),
39
+ sec ? /* @__PURE__ */ React.createElement(
40
+ "span",
41
+ {
42
+ className: "aura-progress__bar aura-progress__bar--reserved",
43
+ style: { left: pct + "%", width: spct + "%" }
44
+ }
45
+ ) : null
34
46
  ),
35
47
  props.hint ? /* @__PURE__ */ React.createElement("p", { className: "aura-progress__hint" }, props.hint) : null
36
48
  );
@@ -147,16 +147,19 @@ const SideNav = React.forwardRef(function SideNav2(props, ref) {
147
147
  return item(c, depth + 1);
148
148
  })));
149
149
  }
150
- const on = active === it.id;
150
+ const action = it.selectable === false;
151
+ const on = !action && active === it.id;
151
152
  const common = {
152
153
  ...tipHandlers(it.label),
153
- className: cx("aura-nav__item", on && "is-active"),
154
+ className: cx("aura-nav__item", action && "aura-nav__item--action", on && "is-active"),
154
155
  "aria-current": on ? "page" : void 0,
155
156
  style: depth ? { ["--aura-nav-depth"]: depth } : void 0,
156
157
  onClick: function(e) {
157
158
  if (!it.href) e.preventDefault();
158
159
  else if (!plainClick(e)) return;
159
- st[1](it.id);
160
+ if (!action) st[1](it.id);
161
+ if (it.onSelect) it.onSelect();
162
+ if (action && props.onAction) props.onAction(it.id);
160
163
  }
161
164
  };
162
165
  return /* @__PURE__ */ React.createElement("li", { key: it.id }, it.href ? /* @__PURE__ */ React.createElement(Link, { href: it.href, ...common }, inner(it, false, false)) : /* @__PURE__ */ React.createElement("button", { type: "button", ...common }, inner(it, false, false)));
@@ -173,6 +176,7 @@ const SideNav = React.forwardRef(function SideNav2(props, ref) {
173
176
  "aura-nav",
174
177
  collapsed && "aura-nav--collapsed",
175
178
  props.bordered === false && "aura-nav--borderless",
179
+ props.chevron === "right" && "aura-nav--chevron-right",
176
180
  props.className
177
181
  ),
178
182
  "data-collapsed": collapsed ? "" : void 0,
@@ -186,7 +190,20 @@ const SideNav = React.forwardRef(function SideNav2(props, ref) {
186
190
  })));
187
191
  })),
188
192
  props.footer ? /* @__PURE__ */ React.createElement("div", { className: "aura-nav__footer" }, props.footer) : null,
189
- props.collapsible ? /* @__PURE__ */ React.createElement("div", { className: "aura-nav__toggle" }, /* @__PURE__ */ React.createElement(
193
+ props.collapsible && props.collapseToggle === "row" ? /* @__PURE__ */ React.createElement("div", { className: "aura-nav__toggle aura-nav__toggle--row" }, /* @__PURE__ */ React.createElement(
194
+ "button",
195
+ {
196
+ type: "button",
197
+ className: "aura-nav__item aura-nav__item--action",
198
+ ...tipHandlers(collapsed ? t.expandNav : t.collapseNav),
199
+ onClick: function() {
200
+ setTip(null);
201
+ col[1](!collapsed);
202
+ }
203
+ },
204
+ /* @__PURE__ */ React.createElement(Icon, { name: collapsed ? /* @__PURE__ */ React.createElement(IconPanelLeftOpen, null) : /* @__PURE__ */ React.createElement(IconPanelLeftClose, null) }),
205
+ /* @__PURE__ */ React.createElement("span", { className: "aura-nav__label" }, collapsed ? t.expandNav : t.collapseNav)
206
+ )) : props.collapsible ? /* @__PURE__ */ React.createElement("div", { className: "aura-nav__toggle" }, /* @__PURE__ */ React.createElement(
190
207
  IconButton,
191
208
  {
192
209
  icon: collapsed ? /* @__PURE__ */ React.createElement(IconPanelLeftOpen, null) : /* @__PURE__ */ React.createElement(IconPanelLeftClose, null),
package/dist/esm/Table.js CHANGED
@@ -47,7 +47,8 @@ function headerLabels(children) {
47
47
  return out;
48
48
  }
49
49
  const Table = React.forwardRef(function Table2(props, ref) {
50
- const { caption, captionHidden, density, stackBelow, align, bordered, className, children, ...rest } = props;
50
+ const { caption, captionHidden, density, stackBelow, align, bordered, stackStyle, className, children, ...rest } = props;
51
+ const cards = !!stackBelow && stackStyle === "cards";
51
52
  const labels = stackBelow ? headerLabels(children) : null;
52
53
  if (labels && !labels.length)
53
54
  devWarnOnce(
@@ -71,7 +72,7 @@ const Table = React.forwardRef(function Table2(props, ref) {
71
72
  ro.disconnect();
72
73
  };
73
74
  }, []);
74
- return /* @__PURE__ */ React.createElement(
75
+ const table = /* @__PURE__ */ React.createElement(
75
76
  "div",
76
77
  {
77
78
  ref: wrap,
@@ -90,6 +91,7 @@ const Table = React.forwardRef(function Table2(props, ref) {
90
91
  "aura-tbl",
91
92
  stackBelow && "aura-tbl--stack-" + stackBelow,
92
93
  align === "middle" && "aura-tbl--middle",
94
+ cards && "aura-tbl--cards",
93
95
  className
94
96
  ),
95
97
  role: stackBelow ? "table" : void 0,
@@ -99,6 +101,7 @@ const Table = React.forwardRef(function Table2(props, ref) {
99
101
  labels ? /* @__PURE__ */ React.createElement(StackLabels.Provider, { value: labels }, children) : outer ? /* @__PURE__ */ React.createElement(StackLabels.Provider, { value: null }, children) : children
100
102
  )
101
103
  );
104
+ return cards ? /* @__PURE__ */ React.createElement("div", { className: "aura-tbl-cards aura-tbl-cards--" + stackBelow }, table) : table;
102
105
  });
103
106
  function section(tag, cls) {
104
107
  const C = React.forwardRef(function TableSection(props, ref) {
package/dist/esm/Tabs.js CHANGED
@@ -24,7 +24,13 @@ const Tabs = React.forwardRef(function Tabs2(props, ref) {
24
24
  const Link = useLinkComponent(props.linkComponent);
25
25
  const manual = props.activation === "manual";
26
26
  const seg = props.variant === "segmented";
27
- const listCls = cx("aura-tabs__list", seg && "aura-segmented", seg && props.fullWidth && "is-full");
27
+ const fw = props.fullWidth;
28
+ const listCls = cx(
29
+ "aura-tabs__list",
30
+ seg && "aura-segmented",
31
+ fw === true && (seg ? "is-full" : "is-fill"),
32
+ typeof fw === "string" && (seg ? "is-full-" : "is-fill-") + fw
33
+ );
28
34
  const tabCls = function(on, extra) {
29
35
  return cx("aura-tab", on && "is-active", seg && "aura-segmented__option", seg && on && "is-selected", extra);
30
36
  };
@@ -52,8 +52,11 @@ function cardElement(props, ref) {
52
52
  "interactive",
53
53
  "as",
54
54
  "className",
55
- "titleId"
55
+ "titleId",
56
+ "header",
57
+ "flushBelow"
56
58
  ]);
59
+ const head = props.header !== void 0 && props.header !== null && props.header !== false;
57
60
  return h(
58
61
  props.as || "section",
59
62
  Object.assign({}, rest, {
@@ -62,12 +65,13 @@ function cardElement(props, ref) {
62
65
  "aura-card",
63
66
  creative && "aura-card--creative",
64
67
  props.interactive && "is-interactive",
68
+ props.flushBelow && "aura-card--flush-below-" + props.flushBelow,
65
69
  props.className
66
70
  ),
67
71
  /* A titled card is labelled by its title; otherwise the caller's aria-labelledby stays (5.8). */
68
- "aria-labelledby": props.title && props.titleId ? props.titleId : props["aria-labelledby"]
72
+ "aria-labelledby": !head && props.title && props.titleId ? props.titleId : props["aria-labelledby"]
69
73
  }),
70
- props.title || props.actions ? /* @__PURE__ */ React.createElement("div", { className: "aura-card__head" }, /* @__PURE__ */ React.createElement("div", { className: "aura-card__heading" }, props.title ? h("h" + (props.headingLevel || 3), { className: "aura-card__title", id: props.titleId }, props.title) : null, props.description ? /* @__PURE__ */ React.createElement("p", { className: "aura-card__desc" }, props.description) : null), props.actions ? /* @__PURE__ */ React.createElement("div", { className: "aura-card__actions" }, props.actions) : null) : null,
74
+ head || props.title || props.actions ? /* @__PURE__ */ React.createElement("div", { className: "aura-card__head" }, /* @__PURE__ */ React.createElement("div", { className: "aura-card__heading" }, head ? props.header : null, !head && props.title ? h("h" + (props.headingLevel || 3), { className: "aura-card__title", id: props.titleId }, props.title) : null, !head && props.description ? /* @__PURE__ */ React.createElement("p", { className: "aura-card__desc" }, props.description) : null), props.actions ? /* @__PURE__ */ React.createElement("div", { className: "aura-card__actions" }, props.actions) : null) : null,
71
75
  props.children ? /* @__PURE__ */ React.createElement("div", { className: "aura-card__body" }, props.children) : null,
72
76
  props.footer ? /* @__PURE__ */ React.createElement("div", { className: "aura-card__foot" }, props.footer) : null
73
77
  );
@@ -202,6 +206,7 @@ function buttonClass(opts = {}) {
202
206
  "aura-btn--" + (opts.variant || "primary"),
203
207
  opts.size === "sm" && "aura-btn--sm",
204
208
  opts.fullWidth && "aura-btn--full",
209
+ opts.touchHeight && "aura-btn--touch",
205
210
  opts.loading && "is-loading",
206
211
  opts.className
207
212
  );
package/dist/esm/index.js CHANGED
@@ -23,7 +23,7 @@ import { FormErrorSummary } from "./FormErrorSummary.js";
23
23
  import { FilterBar } from "./FilterBar.js";
24
24
  import { Command } from "./Command.js";
25
25
  import { Tooltip } from "./Tooltip.js";
26
- import { Dialog, Drawer } from "./Dialog.js";
26
+ import { Dialog, Drawer, useDialogClose } from "./Dialog.js";
27
27
  import { DataTable } from "./DataTable.js";
28
28
  import { Card } from "./Card.js";
29
29
  import { buttonClass } from "./display.js";
@@ -148,6 +148,7 @@ export {
148
148
  useBreakpoint,
149
149
  useColorScheme,
150
150
  useDensity,
151
+ useDialogClose,
151
152
  useFormatDate,
152
153
  useResponsive
153
154
  };
@@ -122,6 +122,10 @@ const STRINGS = {
122
122
  pageN: function(p) {
123
123
  return "Page " + p;
124
124
  },
125
+ progressReserved: function(v, r, max) {
126
+ return n(v) + " of " + n(max) + " used, " + n(r) + " reserved";
127
+ },
128
+ breadcrumbMore: "Show the full path",
125
129
  accepts: function(list, max) {
126
130
  return [list, max && "up to " + max + " each"].filter(Boolean).join(", ");
127
131
  }
@@ -118,6 +118,10 @@ const sv = {
118
118
  pageN: function(p) {
119
119
  return "Sida " + p;
120
120
  },
121
+ progressReserved: function(v, r, max) {
122
+ return nsv(v) + " av " + nsv(max) + " anv\xE4nda, " + nsv(r) + " reserverade";
123
+ },
124
+ breadcrumbMore: "Visa hela s\xF6kv\xE4gen",
121
125
  accepts: function(list, max) {
122
126
  return [list, max && "h\xF6gst " + max + " per fil"].filter(Boolean).join(", ");
123
127
  }
@@ -118,6 +118,10 @@ const th = {
118
118
  pageN: function(p) {
119
119
  return "\u0E2B\u0E19\u0E49\u0E32 " + p;
120
120
  },
121
+ progressReserved: function(v, r, max) {
122
+ return "\u0E43\u0E0A\u0E49\u0E41\u0E25\u0E49\u0E27 " + n(v) + " \u0E08\u0E32\u0E01 " + n(max) + " \u0E08\u0E2D\u0E07\u0E44\u0E27\u0E49 " + n(r);
123
+ },
124
+ breadcrumbMore: "\u0E41\u0E2A\u0E14\u0E07\u0E40\u0E2A\u0E49\u0E19\u0E17\u0E32\u0E07\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14",
121
125
  accepts: function(list, max) {
122
126
  return [list, max && "\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 " + max + " \u0E15\u0E48\u0E2D\u0E44\u0E1F\u0E25\u0E4C"].filter(Boolean).join(" \xB7 ");
123
127
  }
@@ -28,6 +28,8 @@ function useModal(open, ref, opts) {
28
28
  const mounted = useMounted();
29
29
  const prev = React.useRef(null);
30
30
  const o = opts || {};
31
+ const latest = React.useRef(o);
32
+ latest.current = o;
31
33
  React.useEffect(
32
34
  function() {
33
35
  if (!open || !mounted) return;
@@ -48,7 +50,12 @@ function useModal(open, ref, opts) {
48
50
  if (target && o.autoFocus !== false) target.focus();
49
51
  return function() {
50
52
  unlock();
51
- if (prev.current && prev.current.focus) prev.current.focus();
53
+ const l = latest.current;
54
+ const ff = l.finalFocus;
55
+ const to = ff ? typeof ff === "function" ? ff() : ff.current : null;
56
+ const back = to && to.isConnected ? to : prev.current;
57
+ if (back && back.focus) back.focus();
58
+ if (l.onCloseComplete) l.onCloseComplete();
52
59
  };
53
60
  },
54
61
  [open, mounted]
package/dist/index.d.cts CHANGED
@@ -20,6 +20,9 @@ export interface ButtonProps extends React$1.ButtonHTMLAttributes<HTMLButtonElem
20
20
  fullWidth?: boolean | undefined;
21
21
  /** `sm` is 32px with tighter padding, for toolbars, table rows and card footers. Default `md` (44px). */
22
22
  size?: ButtonSize | undefined;
23
+ /** 44px tall below 640px (the viewport's), whatever `size` — a small button that phones get at full touch height
24
+ * (5.15, Chamber-OS 100). From 640px up it keeps its size. */
25
+ touchHeight?: boolean | undefined;
23
26
  }
24
27
  /** A link that looks like a Button: give `Button` an `href` and it renders an `<a>` (navigation, not actions). */
25
28
  export interface ButtonLinkProps extends Omit<React$1.AnchorHTMLAttributes<HTMLAnchorElement>, "children"> {
@@ -38,9 +41,21 @@ export interface ButtonLinkProps extends Omit<React$1.AnchorHTMLAttributes<HTMLA
38
41
  fullWidth?: boolean | undefined;
39
42
  /** `sm` is 32px with tighter padding. Default `md` (44px). */
40
43
  size?: ButtonSize | undefined;
44
+ /** 44px tall below 640px (the viewport's), whatever `size` — a small button that phones get at full touch height
45
+ * (5.15, Chamber-OS 100). From 640px up it keeps its size. */
46
+ touchHeight?: boolean | undefined;
41
47
  /** A router's link to render instead of `<a>`, e.g. `Link` from `next/link` (client-side navigation). It gets `href`, `className`, the children and the ref. */
42
48
  linkComponent?: React$1.ElementType | undefined;
43
49
  }
50
+ /** How a DataTable selection changed: the second argument of `onSelectionChange` (5.16). */
51
+ export interface DataTableSelectionChange {
52
+ /** The row whose box or Space made the change; null for select-all and `sync`. */
53
+ key: string | number | null;
54
+ shiftKey: boolean;
55
+ source: "click" | "keyboard" | "all" | "sync";
56
+ /** With `rangeSelect`, the keys a Shift range set (the row's own key included). */
57
+ range?: Array<string | number> | undefined;
58
+ }
44
59
  /** What DataTable's onStateChange reports: the sort and the 1-based page, together. */
45
60
  export interface DataTableState {
46
61
  sort: DataTableSort | null;
@@ -143,7 +158,13 @@ export interface DataTableProps<Row extends Record<string, any> = Record<string,
143
158
  selected?: Array<string | number> | undefined;
144
159
  /** Initial selection when uncontrolled. */
145
160
  defaultSelected?: Array<string | number> | undefined;
146
- onSelectionChange?: ((keys: Array<string | number>) => void) | undefined;
161
+ /** The new keys, and how they changed (5.16, Chamber-OS 98): the row's `key` (null for select-all), whether Shift
162
+ * was held, and the `source` — `click` (a checkbox), `keyboard` (Space on a row), `all` (the select-all box) or
163
+ * `sync` (keys of rows `isRowSelectable` rejects, dropped). `range` lists the keys a Shift range changed. */
164
+ onSelectionChange?: ((keys: Array<string | number>, change: DataTableSelectionChange) => void) | undefined;
165
+ /** Shift-click a row's checkbox (or Shift+Space on a row) to set every selectable row from the last one changed to
166
+ * this one, on this page and in this order, to this row's new state (5.16, Chamber-OS 98). Default false. */
167
+ rangeSelect?: boolean | undefined;
147
168
  /** Shown when rows is empty. */
148
169
  empty?: DataTableEmpty | undefined;
149
170
  /** A totals row under the body (4.19): content per column key, e.g. `{ id: 'Total', vat: '7,000.00', total: '107,000.00' }`.
@@ -279,6 +300,13 @@ export interface CheckboxProps extends Omit<React$1.InputHTMLAttributes<HTMLInpu
279
300
  disabled?: boolean | undefined;
280
301
  tabIndex?: number | undefined;
281
302
  className?: string | undefined;
303
+ /** How far a click counts around a box without visible text (5.15, Chamber-OS 99): `box` (default, 16×16),
304
+ * `target` (24×24, WCAG 2.5.8, as DataTable's selection column) or `{ x, y }` — px added on each side, so
305
+ * `{ x: 12, y: 8 }` is a 40×32 area. The box looks the same; a labelled checkbox's whole label is its target. */
306
+ hitArea?: "box" | "target" | {
307
+ x: number;
308
+ y: number;
309
+ } | undefined;
282
310
  }
283
311
  /** 32px round button holding one icon. */
284
312
  export interface IconButtonProps extends React$1.ButtonHTMLAttributes<HTMLButtonElement> {
@@ -289,6 +317,9 @@ export interface IconButtonProps extends React$1.ButtonHTMLAttributes<HTMLButton
289
317
  label: string;
290
318
  /** Icon size. Default `sm` (16). */
291
319
  size?: "sm" | "md" | undefined;
320
+ /** 44×44 below 640px (the viewport's) instead of 32×32 — a phone sheet's close button, a card's ⋯ trigger
321
+ * (5.15, Chamber-OS 100). */
322
+ touchHeight?: boolean | undefined;
292
323
  }
293
324
  export interface MenuItem {
294
325
  label?: string | undefined;
@@ -415,6 +446,12 @@ export interface FilterBarProps {
415
446
  /** The search takes all the room the controls leave in its row, instead of stopping at 360px with the count and
416
447
  * actions pushed to the end (5.12). */
417
448
  searchGrow?: boolean | undefined;
449
+ /** `fill`: the filter controls share their row in equal columns (at least 120px each, wrapping when they can't),
450
+ * and the count and actions keep to the end (5.15, Chamber-OS 92). Default `auto`: each at its own width. */
451
+ controlsLayout?: "auto" | "fill" | undefined;
452
+ /** Below this width (the viewport's) the search takes a row of its own above the controls. Default `md` (768px);
453
+ * `lg` (1024px) for bars with several filters (5.15, Chamber-OS 92). */
454
+ stackBelow?: "md" | "lg" | undefined;
418
455
  className?: string | undefined;
419
456
  }
420
457
  /** One command in the palette. */
@@ -584,9 +621,22 @@ export interface FieldPropsPublic {
584
621
  required?: boolean | undefined;
585
622
  optional?: boolean | undefined;
586
623
  }
587
- export interface DialogProps {
588
- open: boolean;
589
- onClose: () => void;
624
+ /** `id`, `data-*`, `aria-*`, `style`, `lang` and `dir` go on the `.aura-dialog` panel (5.16, Chamber-OS 101). */
625
+ export interface DialogProps extends Pick<React$1.HTMLAttributes<HTMLDivElement>, "id" | "style" | "lang" | "dir">, React$1.AriaAttributes, DataAttributes {
626
+ /** Controlled open state. Leave it out with a `trigger` and the Dialog opens and closes itself (5.16). */
627
+ open?: boolean | undefined;
628
+ onClose?: (() => void) | undefined;
629
+ /** The button that opens it (5.16, Chamber-OS 101): rendered in place, with `aria-haspopup="dialog"`,
630
+ * `aria-expanded` and a click that opens the Dialog (its own onClick runs first; `preventDefault()` keeps it shut).
631
+ * Focus returns to it on close. */
632
+ trigger?: React$1.ReactElement | undefined;
633
+ /** Called when the trigger opens it (5.16). */
634
+ onOpen?: (() => void) | undefined;
635
+ /** Where focus goes when it closes — by a button, Escape or the scrim — instead of back to what opened it: the
636
+ * row a save just created (5.16). A ref, or a function read at close; null falls back to the opener. */
637
+ finalFocus?: React$1.RefObject<HTMLElement | null> | (() => HTMLElement | null) | undefined;
638
+ /** Runs once after it has closed and its panel has left the page (5.16) — reset a selection there. */
639
+ onCloseComplete?: (() => void) | undefined;
590
640
  title: React$1.ReactNode;
591
641
  description?: React$1.ReactNode | undefined;
592
642
  children?: React$1.ReactNode | undefined;
@@ -623,6 +673,12 @@ export interface CardProps extends Omit<React$1.HTMLAttributes<HTMLElement>, "ti
623
673
  className?: string | undefined;
624
674
  /** id for the title element; the card is then labelled by it (aria-labelledby). */
625
675
  titleId?: string | undefined;
676
+ /** Free head content in place of `title` and `description` (5.15, Chamber-OS 87): skeleton bars while the card
677
+ * loads, a status pill above a title you mark up yourself. No heading is added; `actions` still sit top-right. */
678
+ header?: React$1.ReactNode | undefined;
679
+ /** Below this width (the viewport's) the card drops its border, surface and shadow — a list whose rows become
680
+ * cards of their own on a phone, so there are no cards in a card (5.15, Chamber-OS 93). Padding is kept. */
681
+ flushBelow?: "sm" | "md" | "lg" | undefined;
626
682
  }
627
683
  export interface TabItem {
628
684
  id: string;
@@ -658,8 +714,10 @@ export interface TabsProps {
658
714
  /** `underline` (default) or `segmented`: the tabs as a pill track with the selected one raised, like
659
715
  * SegmentedControl, keeping every Tabs behaviour (panels, keepMounted, activation, tabProps). (5.10, Chamber-OS 72) */
660
716
  variant?: "underline" | "segmented" | undefined;
661
- /** With `variant="segmented"`: stretch the track to the full width, tabs sharing it equally. (5.10) */
662
- fullWidth?: boolean | undefined;
717
+ /** Tabs share the full width equally: the segmented track (5.10), or underline tabs (5.15, Chamber-OS 90).
718
+ * `'below-sm' | 'below-md' | 'below-lg'` only below that width (the viewport's) — `below-lg` for phone and tablet
719
+ * layouts, tabs at their own width on a desktop. */
720
+ fullWidth?: boolean | "below-sm" | "below-md" | "below-lg" | undefined;
663
721
  /** Link tabs: what the current link is (5.14). `page` (default) for routes; `location` for links to sections of
664
722
  * this page (`#contacts`). */
665
723
  current?: "page" | "location" | undefined;
@@ -676,6 +734,11 @@ export interface NavItem {
676
734
  children?: NavItem[] | undefined;
677
735
  /** Start open. A group also opens by itself when one of its items is the current one. */
678
736
  defaultOpen?: boolean | undefined;
737
+ /** Runs when the item is chosen (5.16, Chamber-OS 95). */
738
+ onSelect?: (() => void) | undefined;
739
+ /** `false` makes an action row — Sign out, Collapse sidebar: it looks like the other rows and runs `onSelect`,
740
+ * but never becomes the current item (no `aria-current`, no `onChange`). Default true. (5.16) */
741
+ selectable?: boolean | undefined;
679
742
  }
680
743
  export interface SideNavProps {
681
744
  sections?: Array<{
@@ -701,6 +764,15 @@ export interface SideNavProps {
701
764
  onCollapsedChange?: ((collapsed: boolean) => void) | undefined;
702
765
  /** Adds a collapse / expand button at the bottom. AppShell hides it in its phone drawer. */
703
766
  collapsible?: boolean | undefined;
767
+ /** Called with the item's id when an action row (`selectable: false`) is chosen, after its `onSelect` (5.16).
768
+ * AppShell uses it to close its phone drawer. */
769
+ onAction?: ((id: string) => void) | undefined;
770
+ /** How `collapsible` shows its toggle: `icon` (default, an IconButton) or `row` — a labelled nav row
771
+ * ("Collapse sidebar") with the rows' look, its icon alone in the rail (5.16, Chamber-OS 95). */
772
+ collapseToggle?: "icon" | "row" | undefined;
773
+ /** Where a closed group's chevron points: `down` (default; up when open) or `right` (down when open; left in
774
+ * right-to-left pages) (5.16, Chamber-OS 96). */
775
+ chevron?: "down" | "right" | undefined;
704
776
  /** The 1px right edge that divides the nav from the page. Default true; `false` when your layout draws its own
705
777
  * divider. (5.1) */
706
778
  bordered?: boolean | undefined;
@@ -713,8 +785,16 @@ export interface BreadcrumbProps {
713
785
  label: string;
714
786
  href?: string | undefined;
715
787
  onClick?: (() => void) | undefined;
788
+ /** Attributes for this item's `<li>` — `data-slot`, `data-testid` (5.15, Chamber-OS 94). */
789
+ itemProps?: (React$1.LiHTMLAttributes<HTMLLIElement> & DataAttributes) | undefined;
790
+ /** Attributes for the item's link, button or text (5.15): `data-*`, `target`, `rel`… Its `onClick` runs before
791
+ * the item's own. */
792
+ linkProps?: (React$1.AnchorHTMLAttributes<HTMLAnchorElement> & Omit<React$1.ButtonHTMLAttributes<HTMLButtonElement>, keyof React$1.AnchorHTMLAttributes<HTMLAnchorElement>> & DataAttributes) | undefined;
716
793
  }>;
717
794
  label?: string | undefined;
795
+ /** Below this width (the viewport's) a trail of three or more shows the first item, "…" and the last; the "…"
796
+ * button shows the rest (5.15, Chamber-OS 94). Decided in CSS, so the server's HTML is already right. */
797
+ collapseBelow?: "sm" | "md" | undefined;
718
798
  /** Your router's link (e.g. `Link` from `next/link`) for this component; defaults to AuraProvider's `linkComponent`, then `<a>`. */
719
799
  linkComponent?: React$1.ElementType | undefined;
720
800
  className?: string | undefined;
@@ -752,7 +832,7 @@ export interface ComboboxOption {
752
832
  icon?: IconInput | undefined;
753
833
  }
754
834
  /** Combobox with `multiple`: pick any number; the picks show as removable chips in the field. */
755
- export interface ComboboxMultipleProps extends Omit<ComboboxProps, "value" | "defaultValue" | "onChange" | "clearable"> {
835
+ export interface ComboboxMultipleProps extends Omit<ComboboxProps, "value" | "defaultValue" | "onChange" | "clearable" | "allowCustomValue"> {
756
836
  multiple: true;
757
837
  /** Selected option values, in the order they were picked (controlled). */
758
838
  value?: string[] | undefined;
@@ -764,7 +844,8 @@ export interface ComboboxMultipleProps extends Omit<ComboboxProps, "value" | "de
764
844
  max?: number | undefined;
765
845
  }
766
846
  export interface ComboboxProps extends FieldProps {
767
- options: Array<ComboboxOption | string>;
847
+ /** The options. Optional with `groups` (5.16). */
848
+ options?: Array<ComboboxOption | string> | undefined;
768
849
  /** Selected option value (controlled). */
769
850
  value?: string | null | undefined;
770
851
  defaultValue?: string | null | undefined;
@@ -787,6 +868,17 @@ export interface ComboboxProps extends FieldProps {
787
868
  limit?: number | undefined;
788
869
  /** Replace the Thai-aware default filter (label, description, keywords). */
789
870
  filter?: ((option: ComboboxOption, query: string) => boolean) | undefined;
871
+ /** Options under headings, after any in `options` (5.16, Chamber-OS 105): `[{ label: 'Nordic and Thailand',
872
+ * options: [...] }]`. Each heading names its group for screen readers; filtering keeps a heading while any of its
873
+ * options match. */
874
+ groups?: Array<{
875
+ label: string;
876
+ options: Array<ComboboxOption | string>;
877
+ }> | undefined;
878
+ /** A typed value that isn't in the list is kept (5.16, Chamber-OS 105): Enter with no match highlighted, or leaving
879
+ * the field, makes the text the value (text matching an option's label picks that option). Clearing the text
880
+ * clears the value. Single value only. */
881
+ allowCustomValue?: boolean | undefined;
790
882
  className?: string | undefined;
791
883
  }
792
884
  /** Number input: thousands separators, +/− buttons, arrow keys, min/max/step, prefix/suffix (฿, %). */
@@ -935,6 +1027,10 @@ export type ButtonAttributes = React$1.ButtonHTMLAttributes<HTMLButtonElement> &
935
1027
  export interface DrawerProps extends Pick<React$1.HTMLAttributes<HTMLDivElement>, "id" | "style" | "lang" | "dir">, React$1.AriaAttributes, DataAttributes {
936
1028
  open: boolean;
937
1029
  onClose: () => void;
1030
+ /** As Dialog's (5.16): where focus goes when it closes, instead of back to what opened it. */
1031
+ finalFocus?: React$1.RefObject<HTMLElement | null> | (() => HTMLElement | null) | undefined;
1032
+ /** As Dialog's (5.16): runs once after it has closed and left the page. */
1033
+ onCloseComplete?: (() => void) | undefined;
938
1034
  /** Default `right`. */
939
1035
  side?: "right" | "left" | undefined;
940
1036
  /** sm 360 · md 480 (default) · lg 640 · nav = SideNav width. Full width below 640px. */
@@ -956,8 +1052,11 @@ export interface DrawerProps extends Pick<React$1.HTMLAttributes<HTMLDivElement>
956
1052
  /** The close button's accessible name and tooltip, saying what it closes ("Close payment drawer"). Default: the
957
1053
  * built-in "Close" in the provider's language. (5.9) */
958
1054
  closeLabel?: string | undefined;
959
- /** Attributes for the close button, e.g. `{ 'data-testid': 'pay-sheet-close' }`. (5.9) */
960
- closeProps?: ButtonAttributes | undefined;
1055
+ /** Attributes for the close button, e.g. `{ 'data-testid': 'pay-sheet-close' }` (5.9), or `touchHeight: true` for a
1056
+ * 44px close button on phones (5.15). */
1057
+ closeProps?: (ButtonAttributes & {
1058
+ touchHeight?: boolean | undefined;
1059
+ }) | undefined;
961
1060
  }
962
1061
  export type Breakpoint = "base" | "sm" | "md" | "lg" | "xl";
963
1062
  export type Responsive<T> = T | Partial<Record<Breakpoint, T>>;
@@ -1027,6 +1126,10 @@ export interface TableProps extends Omit<React$1.TableHTMLAttributes<HTMLTableEl
1027
1126
  /** `false` (5.13) drops the frame — border, radius, background — and the outer cells' side padding, so the table
1028
1127
  * lines up with the content around it, e.g. flush inside a Card under its heading. Default `true`. */
1029
1128
  bordered?: boolean | undefined;
1129
+ /** How stacked rows look (5.15, Chamber-OS 85): `list` (default) — one frame, rows divided by rules; `cards` —
1130
+ * each row its own framed card, spaced like DataTable's cards, with no frame around them. From the `stackBelow`
1131
+ * width up the table is unchanged. The table then sits in one more `div` (`.aura-tbl-cards`). */
1132
+ stackStyle?: "list" | "cards" | undefined;
1030
1133
  className?: string | undefined;
1031
1134
  children?: React$1.ReactNode | undefined;
1032
1135
  }
@@ -1213,6 +1316,9 @@ export interface ProgressProps {
1213
1316
  showValue?: boolean | undefined;
1214
1317
  /** Replaces the % text, e.g. "3 of 5 files". Also read out as aria-valuetext. */
1215
1318
  valueLabel?: React$1.ReactNode | undefined;
1319
+ /** A reserved amount drawn after `value` as a striped segment of the same tone — queued sends on a quota
1320
+ * (5.15, Chamber-OS 89). Both counts are read out ("2 of 6 used, 1 reserved") unless `valueLabel` is given. */
1321
+ secondaryValue?: number | undefined;
1216
1322
  hint?: React$1.ReactNode | undefined;
1217
1323
  tone?: Tone | undefined;
1218
1324
  size?: "sm" | "md" | undefined;
@@ -1429,6 +1535,7 @@ export declare function buttonClass(opts?: {
1429
1535
  size?: ButtonProps["size"];
1430
1536
  fullWidth?: boolean | undefined;
1431
1537
  loading?: boolean | undefined;
1538
+ touchHeight?: boolean | undefined;
1432
1539
  className?: string | undefined;
1433
1540
  }): string;
1434
1541
  export declare const Alert: React$1.ForwardRefExoticComponent<AlertProps & React$1.RefAttributes<HTMLDivElement>>;
@@ -1460,6 +1567,10 @@ export declare const FormErrorSummary: React$1.ForwardRefExoticComponent<FormErr
1460
1567
  export declare const FilterBar: React$1.ForwardRefExoticComponent<FilterBarProps & React$1.RefAttributes<HTMLDivElement>>;
1461
1568
  export declare function Command(props: CommandProps): React$1.ReactElement | null;
1462
1569
  export declare const Tooltip: React$1.ForwardRefExoticComponent<TooltipProps & React$1.RefAttributes<HTMLSpanElement>>;
1570
+ /** Inside a Dialog's body or footer: a function that closes it (5.16) — also when `dismissible={false}`, which only
1571
+ * turns off Escape, the scrim and ×. Outside a Dialog it does nothing. Use it for Cancel and Save in a Dialog that
1572
+ * has a `trigger` and no `open`. */
1573
+ export declare function useDialogClose(): () => void;
1463
1574
  export declare const Dialog: React$1.ForwardRefExoticComponent<DialogProps & React$1.RefAttributes<HTMLDivElement>>;
1464
1575
  /** Side panel over the page: record detail, filters, mobile navigation. Modal (focus trap, scroll lock, focus restore). */
1465
1576
  export declare const Drawer: React$1.ForwardRefExoticComponent<DrawerProps & React$1.RefAttributes<HTMLDivElement>>;
@@ -1612,6 +1723,10 @@ export interface AuraStrings {
1612
1723
  pagination: string;
1613
1724
  pageN: (p: number) => string;
1614
1725
  accepts: (list?: string, max?: number | string) => string;
1726
+ /** Progress with a reserved segment (5.15): "2 of 6 used, 1 reserved". */
1727
+ progressReserved: (value: number, reserved: number, max: number) => string;
1728
+ /** The collapsed middle of a Breadcrumb (5.15). */
1729
+ breadcrumbMore: string;
1615
1730
  }
1616
1731
  /** Built-in strings by locale. th and sv also ship as packs (`@jirawatpyk/aura-react/locales/th`, `/sv`, 5.9); in 6.0
1617
1732
  * only en stays built in and a Thai or Swedish app passes its pack to AuraProvider `strings`. */