@jirawatpyk/aura-react 5.22.0 → 5.23.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
@@ -186,6 +186,12 @@ DataTable with sort and page in the URL (4.17): `onStateChange={({ sort, page })
186
186
  - **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`.
187
187
  - **Toasts** queue past three instead of dropping: six in a row all show, in order, three at a time.
188
188
 
189
+ ## 5.23 — Chamber-OS addenda 23–25
190
+
191
+ - **DataTable `card: 'wide'`** (item 120): in a stacked card the column is a field on a line of its own at the card's full inner width, after the half-width fields (and before a `footer`), its label above and its text wrapping — a reason with its evidence line. The grid is unchanged (an ordinary column at its `width`).
192
+ - **Underline Tabs show their whole 2px indicator** (item 121): the list scrolls sideways, and a scroll container clips at its padding box, so the indicator pulled 1px over the list's border showed only 1px. The track is now an inset shadow inside the list and the indicator paints over its bottom row; the tabs' size is unchanged. In forced colours the track is a border again, with the indicator just above it (the list is 1px taller there).
193
+ - **ActionBar `touchHeight`** (item 122): the bar's own Clear button takes Button's `touchHeight` — 44px below 640px — to match action buttons that use it.
194
+
189
195
  ## 5.22 — Chamber-OS addendum 22
190
196
 
191
197
  - **DataTable `card: 'footer'`** (item 118): in a stacked card the column becomes the card's last row, full width, after every other cell — row actions such as "Send reminder" and a menu. A Button placed directly in the cell grows to fill the row; an IconButton or menu keeps its size. The grid is unchanged (an ordinary column at its `width`).
@@ -5298,12 +5298,13 @@ window.Aura = (() => {
5298
5298
  const part = cardPart(c, i), lv = hideLevel(c);
5299
5299
  return {
5300
5300
  "data-card": part,
5301
- "data-label": part === "field" ? c.label || void 0 : void 0,
5301
+ "data-label": part === "field" || part === "wide" ? c.label || void 0 : void 0,
5302
5302
  "data-hide": lv ? String(lv) : void 0
5303
5303
  };
5304
5304
  }
5305
5305
  const hasFields = vis.some(function(c, i) {
5306
- return cardPart(c, i) === "field";
5306
+ const p = cardPart(c, i);
5307
+ return p === "field" || p === "wide";
5307
5308
  });
5308
5309
  const hasFlex = vis.some(function(c) {
5309
5310
  return widthOf(c) == null;
@@ -7198,7 +7199,7 @@ window.Aura = (() => {
7198
7199
  props.className
7199
7200
  )
7200
7201
  },
7201
- /* @__PURE__ */ React42.createElement("div", { className: cx("aura-actionbar__inner", hasStart && "has-start") }, /* @__PURE__ */ React42.createElement("div", { className: "aura-actionbar__status", role: "status" }, count, count && props.status ? " \xB7 " : null, props.status), !idle && hasStart ? /* @__PURE__ */ React42.createElement("div", { className: "aura-actionbar__start" }, props.start) : null, !idle ? /* @__PURE__ */ React42.createElement("div", { className: "aura-actionbar__actions" }, count && props.onClearSelection ? /* @__PURE__ */ React42.createElement(Button, { variant: "ghost", size: "sm", onClick: clear }, t.clear()) : null, props.children) : null)
7202
+ /* @__PURE__ */ React42.createElement("div", { className: cx("aura-actionbar__inner", hasStart && "has-start") }, /* @__PURE__ */ React42.createElement("div", { className: "aura-actionbar__status", role: "status" }, count, count && props.status ? " \xB7 " : null, props.status), !idle && hasStart ? /* @__PURE__ */ React42.createElement("div", { className: "aura-actionbar__start" }, props.start) : null, !idle ? /* @__PURE__ */ React42.createElement("div", { className: "aura-actionbar__actions" }, count && props.onClearSelection ? /* @__PURE__ */ React42.createElement(Button, { variant: "ghost", size: "sm", touchHeight: props.touchHeight, onClick: clear }, t.clear()) : null, props.children) : null)
7202
7203
  );
7203
7204
  });
7204
7205
 
@@ -5280,12 +5280,13 @@ var DataTableImpl = React31.forwardRef(function DataTable(props, ref) {
5280
5280
  const part = cardPart(c, i), lv = hideLevel(c);
5281
5281
  return {
5282
5282
  "data-card": part,
5283
- "data-label": part === "field" ? c.label || void 0 : void 0,
5283
+ "data-label": part === "field" || part === "wide" ? c.label || void 0 : void 0,
5284
5284
  "data-hide": lv ? String(lv) : void 0
5285
5285
  };
5286
5286
  }
5287
5287
  const hasFields = vis.some(function(c, i) {
5288
- return cardPart(c, i) === "field";
5288
+ const p = cardPart(c, i);
5289
+ return p === "field" || p === "wide";
5289
5290
  });
5290
5291
  const hasFlex = vis.some(function(c) {
5291
5292
  return widthOf(c) == null;
@@ -7180,7 +7181,7 @@ var ActionBar = React42.forwardRef(function ActionBar2(props, ref) {
7180
7181
  props.className
7181
7182
  )
7182
7183
  },
7183
- /* @__PURE__ */ React42.createElement("div", { className: cx("aura-actionbar__inner", hasStart && "has-start") }, /* @__PURE__ */ React42.createElement("div", { className: "aura-actionbar__status", role: "status" }, count, count && props.status ? " \xB7 " : null, props.status), !idle && hasStart ? /* @__PURE__ */ React42.createElement("div", { className: "aura-actionbar__start" }, props.start) : null, !idle ? /* @__PURE__ */ React42.createElement("div", { className: "aura-actionbar__actions" }, count && props.onClearSelection ? /* @__PURE__ */ React42.createElement(Button, { variant: "ghost", size: "sm", onClick: clear }, t.clear()) : null, props.children) : null)
7184
+ /* @__PURE__ */ React42.createElement("div", { className: cx("aura-actionbar__inner", hasStart && "has-start") }, /* @__PURE__ */ React42.createElement("div", { className: "aura-actionbar__status", role: "status" }, count, count && props.status ? " \xB7 " : null, props.status), !idle && hasStart ? /* @__PURE__ */ React42.createElement("div", { className: "aura-actionbar__start" }, props.start) : null, !idle ? /* @__PURE__ */ React42.createElement("div", { className: "aura-actionbar__actions" }, count && props.onClearSelection ? /* @__PURE__ */ React42.createElement(Button, { variant: "ghost", size: "sm", touchHeight: props.touchHeight, onClick: clear }, t.clear()) : null, props.children) : null)
7184
7185
  );
7185
7186
  });
7186
7187
 
@@ -42,7 +42,7 @@ const ActionBar = React.forwardRef(function ActionBar2(props, ref) {
42
42
  props.className
43
43
  )
44
44
  },
45
- /* @__PURE__ */ React.createElement("div", { className: cx("aura-actionbar__inner", hasStart && "has-start") }, /* @__PURE__ */ React.createElement("div", { className: "aura-actionbar__status", role: "status" }, count, count && props.status ? " \xB7 " : null, props.status), !idle && hasStart ? /* @__PURE__ */ React.createElement("div", { className: "aura-actionbar__start" }, props.start) : null, !idle ? /* @__PURE__ */ React.createElement("div", { className: "aura-actionbar__actions" }, count && props.onClearSelection ? /* @__PURE__ */ React.createElement(Button, { variant: "ghost", size: "sm", onClick: clear }, t.clear()) : null, props.children) : null)
45
+ /* @__PURE__ */ React.createElement("div", { className: cx("aura-actionbar__inner", hasStart && "has-start") }, /* @__PURE__ */ React.createElement("div", { className: "aura-actionbar__status", role: "status" }, count, count && props.status ? " \xB7 " : null, props.status), !idle && hasStart ? /* @__PURE__ */ React.createElement("div", { className: "aura-actionbar__start" }, props.start) : null, !idle ? /* @__PURE__ */ React.createElement("div", { className: "aura-actionbar__actions" }, count && props.onClearSelection ? /* @__PURE__ */ React.createElement(Button, { variant: "ghost", size: "sm", touchHeight: props.touchHeight, onClick: clear }, t.clear()) : null, props.children) : null)
46
46
  );
47
47
  });
48
48
  export {
@@ -299,12 +299,13 @@ const DataTableImpl = React.forwardRef(function DataTable(props, ref) {
299
299
  const part = cardPart(c, i), lv = hideLevel(c);
300
300
  return {
301
301
  "data-card": part,
302
- "data-label": part === "field" ? c.label || void 0 : void 0,
302
+ "data-label": part === "field" || part === "wide" ? c.label || void 0 : void 0,
303
303
  "data-hide": lv ? String(lv) : void 0
304
304
  };
305
305
  }
306
306
  const hasFields = vis.some(function(c, i) {
307
- return cardPart(c, i) === "field";
307
+ const p = cardPart(c, i);
308
+ return p === "field" || p === "wide";
308
309
  });
309
310
  const hasFlex = vis.some(function(c) {
310
311
  return widthOf(c) == null;
package/dist/index.d.cts CHANGED
@@ -108,8 +108,10 @@ export interface DataTableColumn<Row extends Record<string, any> = Record<string
108
108
  * make it the card's title or the pill beside it (instead of the first column / first pill column), `'field'` a
109
109
  * label/value field. `'footer'` (5.22, Chamber-OS 118) makes it the card's last row, full width — row actions
110
110
  * such as "Send reminder" and a menu: a Button placed directly in the cell grows to fill the row, an IconButton or
111
- * menu keeps its size. Default: today's rule. The grid is unchanged by any of them. */
112
- card?: "hide" | "field" | "title" | "pill" | "footer" | undefined;
111
+ * menu keeps its size. `'wide'` (5.23, Chamber-OS 120) is a field on a line of its own at the card's full width,
112
+ * after the half-width fields (in column order; `cardOrder` doesn't move it), its label above and its text wrapping —
113
+ * a reason with its evidence. Default: today's rule. The grid is unchanged by any of them. */
114
+ card?: "hide" | "field" | "title" | "pill" | "footer" | "wide" | undefined;
113
115
  /** The order of fields in a stacked card (5.13), lowest first; the grid's column order is unchanged. Fields
114
116
  * without one sort by their column index (0-based). Screen readers and arrow keys follow the grid's order. */
115
117
  cardOrder?: number | undefined;
@@ -1201,6 +1203,9 @@ export interface ActionBarProps {
1201
1203
  selected?: number | undefined;
1202
1204
  /** Adds a "Clear" button next to the count. */
1203
1205
  onClearSelection?: (() => void) | undefined;
1206
+ /** 5.23 (Chamber-OS 122): the bar's own Clear button takes Button's `touchHeight` — 44px below 640px — to match
1207
+ * action buttons that use it. */
1208
+ touchHeight?: boolean | undefined;
1204
1209
  /** Name of the region. Default "Actions". */
1205
1210
  label?: string | undefined;
1206
1211
  className?: string | undefined;
package/dist/index.d.ts CHANGED
@@ -108,8 +108,10 @@ export interface DataTableColumn<Row extends Record<string, any> = Record<string
108
108
  * make it the card's title or the pill beside it (instead of the first column / first pill column), `'field'` a
109
109
  * label/value field. `'footer'` (5.22, Chamber-OS 118) makes it the card's last row, full width — row actions
110
110
  * such as "Send reminder" and a menu: a Button placed directly in the cell grows to fill the row, an IconButton or
111
- * menu keeps its size. Default: today's rule. The grid is unchanged by any of them. */
112
- card?: "hide" | "field" | "title" | "pill" | "footer" | undefined;
111
+ * menu keeps its size. `'wide'` (5.23, Chamber-OS 120) is a field on a line of its own at the card's full width,
112
+ * after the half-width fields (in column order; `cardOrder` doesn't move it), its label above and its text wrapping —
113
+ * a reason with its evidence. Default: today's rule. The grid is unchanged by any of them. */
114
+ card?: "hide" | "field" | "title" | "pill" | "footer" | "wide" | undefined;
113
115
  /** The order of fields in a stacked card (5.13), lowest first; the grid's column order is unchanged. Fields
114
116
  * without one sort by their column index (0-based). Screen readers and arrow keys follow the grid's order. */
115
117
  cardOrder?: number | undefined;
@@ -1201,6 +1203,9 @@ export interface ActionBarProps {
1201
1203
  selected?: number | undefined;
1202
1204
  /** Adds a "Clear" button next to the count. */
1203
1205
  onClearSelection?: (() => void) | undefined;
1206
+ /** 5.23 (Chamber-OS 122): the bar's own Clear button takes Button's `touchHeight` — 44px below 640px — to match
1207
+ * action buttons that use it. */
1208
+ touchHeight?: boolean | undefined;
1204
1209
  /** Name of the region. Default "Actions". */
1205
1210
  label?: string | undefined;
1206
1211
  className?: string | undefined;
package/dist/styles.css CHANGED
@@ -669,10 +669,13 @@ a.aura-icon-btn { text-decoration: none; }
669
669
 
670
670
  /* ---------- Tabs ---------- */
671
671
  .aura-tabs { font-family: var(--font-sans); }
672
- .aura-tabs__list { display: flex; gap: var(--aura-space-6); border-bottom: 1px solid var(--aura-border-default); overflow-x: auto; scrollbar-width: none; }
672
+ /* 5.23 (Chamber-OS 121): the 1px track is an inset shadow inside the list's padding box, and the active tab's 2px
673
+ * indicator paints over its bottom row. The list scrolls sideways (overflow-x), and a scroll container clips at its
674
+ * padding box: an indicator pulled 1px over a border (as up to 5.22) showed only half its height. Same box height. */
675
+ .aura-tabs__list { display: flex; gap: var(--aura-space-6); box-shadow: inset 0 -1px 0 var(--aura-border-default); overflow-x: auto; scrollbar-width: none; }
673
676
  .aura-tab {
674
677
  position: relative; display: inline-flex; align-items: center; gap: var(--aura-space-2); flex: none;
675
- height: var(--aura-input-height); padding: 0; margin-bottom: -1px;
678
+ height: var(--aura-input-height); padding: 0;
676
679
  border: 0; border-bottom: 2px solid transparent; background: transparent;
677
680
  color: var(--aura-fg-secondary); font: inherit; font-size: 13px; font-weight: 500; cursor: pointer;
678
681
  transition: color var(--aura-duration-fast) var(--aura-ease), border-color var(--aura-duration-fast) var(--aura-ease);
@@ -1335,9 +1338,8 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1335
1338
  * ring is drawn inside the pill, so neither the scrolling list (many tabs on a phone) nor the next pill can cover it;
1336
1339
  * full-width tabs share the track but never shrink below their label (the track scrolls instead). The phone rule's
1337
1340
  * wider tab gap doesn't apply. */
1338
- .aura-tabs--segmented .aura-tabs__list.aura-segmented { gap: 2px; }
1341
+ .aura-tabs--segmented .aura-tabs__list.aura-segmented { gap: 2px; box-shadow: none; }
1339
1342
  .aura-tabs--segmented .aura-tabs__list.aura-segmented.is-full .aura-tab { min-width: max-content; }
1340
- .aura-tabs--segmented .aura-tab.aura-segmented__option { margin-bottom: 0; }
1341
1343
  /* 5.15 (Chamber-OS 90): underline tabs sharing the width, always or below a breakpoint; the segmented track below one. */
1342
1344
  .aura-tabs__list.is-fill { gap: 0; }
1343
1345
  .aura-tabs__list.is-fill > .aura-tab { flex: 1 1 0; min-width: max-content; justify-content: center; padding: 0 var(--aura-space-3); }
@@ -1861,6 +1863,8 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1861
1863
  .aura-table__row > .aura-table__sel { align-self: flex-start; margin-top: 2px; }
1862
1864
  /* Actions top-right sit on that first line too (a 32px button centred on 20px, the same 24px footprint as before). */
1863
1865
  .aura-table__td[data-card='actions'] { align-self: flex-start; margin-top: calc(-1 * var(--aura-space-1) - 2px); margin-bottom: -2px; }
1866
+ /* 5.23 (Chamber-OS 120): card: 'wide' — a field on its own full-width line after the half-width ones, wrapping. */
1867
+ .aura-table__td[data-card='wide'] { order: 90; flex: 0 0 100%; white-space: normal; overflow: visible; overflow-wrap: anywhere; }
1864
1868
  /* 5.22 (Chamber-OS 118): card: 'footer' — the card's last row, full width; a Button in it grows, an IconButton or a
1865
1869
  * menu keeps its size. */
1866
1870
  .aura-table__td[data-card='footer'] {
@@ -1901,6 +1905,8 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1901
1905
  .aura-segmented__option.is-selected { outline: 2px solid Highlight; outline-offset: -2px; }
1902
1906
  .aura-tab { border-bottom-color: Canvas; }
1903
1907
  .aura-tab.is-active { border-bottom-color: Highlight; }
1908
+ /* Shadows are dropped in forced colours: the track is a real border again, the indicator just above it. */
1909
+ .aura-tabs__list:not(.aura-segmented) { border-bottom: 1px solid CanvasText; }
1904
1910
  /* 5.10: segmented tabs mark the selection with a border and focus with a dashed ring inside it, so a focused tab
1905
1911
  * and the selected one never look alike (manual activation moves focus without selecting). */
1906
1912
  .aura-tabs--segmented .aura-tab.aura-segmented__option.is-selected { outline: none; border: 2px solid Highlight; }
@@ -671,10 +671,13 @@ a.aura-icon-btn { text-decoration: none; }
671
671
 
672
672
  /* ---------- Tabs ---------- */
673
673
  .aura-tabs { font-family: var(--font-sans); }
674
- .aura-tabs__list { display: flex; gap: var(--aura-space-6); border-bottom: 1px solid var(--aura-border-default); overflow-x: auto; scrollbar-width: none; }
674
+ /* 5.23 (Chamber-OS 121): the 1px track is an inset shadow inside the list's padding box, and the active tab's 2px
675
+ * indicator paints over its bottom row. The list scrolls sideways (overflow-x), and a scroll container clips at its
676
+ * padding box: an indicator pulled 1px over a border (as up to 5.22) showed only half its height. Same box height. */
677
+ .aura-tabs__list { display: flex; gap: var(--aura-space-6); box-shadow: inset 0 -1px 0 var(--aura-border-default); overflow-x: auto; scrollbar-width: none; }
675
678
  .aura-tab {
676
679
  position: relative; display: inline-flex; align-items: center; gap: var(--aura-space-2); flex: none;
677
- height: var(--aura-input-height); padding: 0; margin-bottom: -1px;
680
+ height: var(--aura-input-height); padding: 0;
678
681
  border: 0; border-bottom: 2px solid transparent; background: transparent;
679
682
  color: var(--aura-fg-secondary); font: inherit; font-size: 13px; font-weight: 500; cursor: pointer;
680
683
  transition: color var(--aura-duration-fast) var(--aura-ease), border-color var(--aura-duration-fast) var(--aura-ease);
@@ -1337,9 +1340,8 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1337
1340
  * ring is drawn inside the pill, so neither the scrolling list (many tabs on a phone) nor the next pill can cover it;
1338
1341
  * full-width tabs share the track but never shrink below their label (the track scrolls instead). The phone rule's
1339
1342
  * wider tab gap doesn't apply. */
1340
- .aura-tabs--segmented .aura-tabs__list.aura-segmented { gap: 2px; }
1343
+ .aura-tabs--segmented .aura-tabs__list.aura-segmented { gap: 2px; box-shadow: none; }
1341
1344
  .aura-tabs--segmented .aura-tabs__list.aura-segmented.is-full .aura-tab { min-width: max-content; }
1342
- .aura-tabs--segmented .aura-tab.aura-segmented__option { margin-bottom: 0; }
1343
1345
  /* 5.15 (Chamber-OS 90): underline tabs sharing the width, always or below a breakpoint; the segmented track below one. */
1344
1346
  .aura-tabs__list.is-fill { gap: 0; }
1345
1347
  .aura-tabs__list.is-fill > .aura-tab { flex: 1 1 0; min-width: max-content; justify-content: center; padding: 0 var(--aura-space-3); }
@@ -1863,6 +1865,8 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1863
1865
  .aura-table__row > .aura-table__sel { align-self: flex-start; margin-top: 2px; }
1864
1866
  /* Actions top-right sit on that first line too (a 32px button centred on 20px, the same 24px footprint as before). */
1865
1867
  .aura-table__td[data-card='actions'] { align-self: flex-start; margin-top: calc(-1 * var(--aura-space-1) - 2px); margin-bottom: -2px; }
1868
+ /* 5.23 (Chamber-OS 120): card: 'wide' — a field on its own full-width line after the half-width ones, wrapping. */
1869
+ .aura-table__td[data-card='wide'] { order: 90; flex: 0 0 100%; white-space: normal; overflow: visible; overflow-wrap: anywhere; }
1866
1870
  /* 5.22 (Chamber-OS 118): card: 'footer' — the card's last row, full width; a Button in it grows, an IconButton or a
1867
1871
  * menu keeps its size. */
1868
1872
  .aura-table__td[data-card='footer'] {
@@ -1903,6 +1907,8 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1903
1907
  .aura-segmented__option.is-selected { outline: 2px solid Highlight; outline-offset: -2px; }
1904
1908
  .aura-tab { border-bottom-color: Canvas; }
1905
1909
  .aura-tab.is-active { border-bottom-color: Highlight; }
1910
+ /* Shadows are dropped in forced colours: the track is a real border again, the indicator just above it. */
1911
+ .aura-tabs__list:not(.aura-segmented) { border-bottom: 1px solid CanvasText; }
1906
1912
  /* 5.10: segmented tabs mark the selection with a border and focus with a dashed ring inside it, so a focused tab
1907
1913
  * and the selected one never look alike (manual activation moves focus without selecting). */
1908
1914
  .aura-tabs--segmented .aura-tab.aura-segmented__option.is-selected { outline: none; border: 2px solid Highlight; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jirawatpyk/aura-react",
3
- "version": "5.22.0",
3
+ "version": "5.23.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",