@jirawatpyk/aura-react 5.20.0 → 5.22.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,17 @@ 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.22 — Chamber-OS addendum 22
190
+
191
+ - **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`).
192
+ - **Stacked titles wrap** (item 119): a card's title (`card: 'title'` or the automatic one) wraps onto more lines instead of being cut, on a 20px line, and the row box, the pill and top-right actions line up with its first line. Visible in every stacked DataTable: long titles wrap; one-line cards without a pill or actions are 4px taller (the 20px line), with a pill about 1px; the grid is unchanged.
193
+ - `card: 'footer'` moves the cell only visually: arrow keys and screen readers keep the grid's column order. A footer holding only an IconButton or a menu sits at the end edge.
194
+
195
+ ## 5.21 — Chamber-OS addendum 21
196
+
197
+ - **Table `rowHeight="density"`** (item 117): every body row is at least the density's row height (48px; 40px compact; 48px on touch screens, as DataTable — unlike the 5.20 cell padding, which stays compact on touch), and its cells' vertical padding shrinks to fit a small Button (7.5px at 48px, 3.5px compact, at most 8px), as in DataTable's `rowHeight="auto"` — so a row with a `sm` Button, an IconButton, a pill or one line of text are all the same height. Content is centred on the row unless you pass `align="top"` (footer cells centre too, as with `align="middle"`). Rows whose text wraps still grow, with the smaller padding. Header and footer row heights, stacked rows and cards (`stackBelow`), and tables without the prop are unchanged.
198
+ - The CSS budget is 27 kB (was 26; 5.19–5.21 added read-only fields, the ActionBar start slot and even rows).
199
+
189
200
  ## 5.20 — Chamber-OS addendum 20, items 115–116
190
201
 
191
202
  - **Table follows the page's density** (item 115): without a `density` prop a Table takes the nearest AuraProvider's density, as its docs said — inside `AuraProvider density="compact"` the wrap carries `data-density="compact"` and cells get 8px vertical padding (were 12px). A `density` prop still wins. The padding comes from the nearest `data-density` (a provider, `<html>`, any element, or the table's own), so `comfortable` inside a compact page switches back as it does for fields. As before with an explicit `compact`, cells stay compact on touch screens. A visible change for Tables inside a compact provider or page.
@@ -7267,7 +7267,19 @@ window.Aura = (() => {
7267
7267
  return out;
7268
7268
  }
7269
7269
  var Table = React44.forwardRef(function Table2(props, ref) {
7270
- const { caption, captionHidden, density, stackBelow, align, bordered, stackStyle, className, children, ...rest } = props;
7270
+ const {
7271
+ caption,
7272
+ captionHidden,
7273
+ density,
7274
+ stackBelow,
7275
+ align,
7276
+ bordered,
7277
+ stackStyle,
7278
+ rowHeight,
7279
+ className,
7280
+ children,
7281
+ ...rest
7282
+ } = props;
7271
7283
  const cards = !!stackBelow && stackStyle === "cards";
7272
7284
  const labels = stackBelow ? headerLabels(children) : null;
7273
7285
  if (labels && !labels.length)
@@ -7311,7 +7323,9 @@ window.Aura = (() => {
7311
7323
  className: cx(
7312
7324
  "aura-tbl",
7313
7325
  stackBelow && "aura-tbl--stack-" + stackBelow,
7314
- align === "middle" && "aura-tbl--middle",
7326
+ /* 5.21: even rows centre their content, as DataTable's auto rows do, unless `align="top"` is asked for. */
7327
+ (align === "middle" || rowHeight === "density" && align !== "top") && "aura-tbl--middle",
7328
+ rowHeight === "density" && "aura-tbl--row-density",
7315
7329
  cards && "aura-tbl--cards",
7316
7330
  className
7317
7331
  ),
@@ -7249,7 +7249,19 @@ function headerLabels(children) {
7249
7249
  return out;
7250
7250
  }
7251
7251
  var Table = React44.forwardRef(function Table2(props, ref) {
7252
- const { caption, captionHidden, density, stackBelow, align, bordered, stackStyle, className, children, ...rest } = props;
7252
+ const {
7253
+ caption,
7254
+ captionHidden,
7255
+ density,
7256
+ stackBelow,
7257
+ align,
7258
+ bordered,
7259
+ stackStyle,
7260
+ rowHeight,
7261
+ className,
7262
+ children,
7263
+ ...rest
7264
+ } = props;
7253
7265
  const cards = !!stackBelow && stackStyle === "cards";
7254
7266
  const labels = stackBelow ? headerLabels(children) : null;
7255
7267
  if (labels && !labels.length)
@@ -7293,7 +7305,9 @@ var Table = React44.forwardRef(function Table2(props, ref) {
7293
7305
  className: cx(
7294
7306
  "aura-tbl",
7295
7307
  stackBelow && "aura-tbl--stack-" + stackBelow,
7296
- align === "middle" && "aura-tbl--middle",
7308
+ /* 5.21: even rows centre their content, as DataTable's auto rows do, unless `align="top"` is asked for. */
7309
+ (align === "middle" || rowHeight === "density" && align !== "top") && "aura-tbl--middle",
7310
+ rowHeight === "density" && "aura-tbl--row-density",
7297
7311
  cards && "aura-tbl--cards",
7298
7312
  className
7299
7313
  ),
package/dist/esm/Table.js CHANGED
@@ -48,7 +48,19 @@ function headerLabels(children) {
48
48
  return out;
49
49
  }
50
50
  const Table = React.forwardRef(function Table2(props, ref) {
51
- const { caption, captionHidden, density, stackBelow, align, bordered, stackStyle, className, children, ...rest } = props;
51
+ const {
52
+ caption,
53
+ captionHidden,
54
+ density,
55
+ stackBelow,
56
+ align,
57
+ bordered,
58
+ stackStyle,
59
+ rowHeight,
60
+ className,
61
+ children,
62
+ ...rest
63
+ } = props;
52
64
  const cards = !!stackBelow && stackStyle === "cards";
53
65
  const labels = stackBelow ? headerLabels(children) : null;
54
66
  if (labels && !labels.length)
@@ -92,7 +104,9 @@ const Table = React.forwardRef(function Table2(props, ref) {
92
104
  className: cx(
93
105
  "aura-tbl",
94
106
  stackBelow && "aura-tbl--stack-" + stackBelow,
95
- align === "middle" && "aura-tbl--middle",
107
+ /* 5.21: even rows centre their content, as DataTable's auto rows do, unless `align="top"` is asked for. */
108
+ (align === "middle" || rowHeight === "density" && align !== "top") && "aura-tbl--middle",
109
+ rowHeight === "density" && "aura-tbl--row-density",
96
110
  cards && "aura-tbl--cards",
97
111
  className
98
112
  ),
package/dist/index.d.cts CHANGED
@@ -106,8 +106,10 @@ export interface DataTableColumn<Row extends Record<string, any> = Record<string
106
106
  actions?: boolean | undefined;
107
107
  /** Its place in a stacked card (5.13): `'hide'` leaves it out of the card (the grid keeps it), `'title'` / `'pill'`
108
108
  * make it the card's title or the pill beside it (instead of the first column / first pill column), `'field'` a
109
- * label/value field. Default: today's rule. */
110
- card?: "hide" | "field" | "title" | "pill" | undefined;
109
+ * label/value field. `'footer'` (5.22, Chamber-OS 118) makes it the card's last row, full width — row actions
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
113
  /** The order of fields in a stacked card (5.13), lowest first; the grid's column order is unchanged. Fields
112
114
  * without one sort by their column index (0-based). Screen readers and arrow keys follow the grid's order. */
113
115
  cardOrder?: number | undefined;
@@ -1147,6 +1149,12 @@ export interface TableProps extends Omit<React$1.TableHTMLAttributes<HTMLTableEl
1147
1149
  * each row its own framed card, spaced like DataTable's cards, with no frame around them. From the `stackBelow`
1148
1150
  * width up the table is unchanged. The table then sits in one more `div` (`.aura-tbl-cards`). */
1149
1151
  stackStyle?: "list" | "cards" | undefined;
1152
+ /** `'density'` (5.21, Chamber-OS 117): every body row is at least the density's row height (48px, 40px compact,
1153
+ * 48px on touch screens, as DataTable) and its cells' vertical padding shrinks to fit a small Button — so a row with
1154
+ * a `sm` Button, an IconButton, a pill or one line of text are all the same height, as in DataTable's
1155
+ * `rowHeight="auto"`. Content is centred on the row unless `align="top"`. Rows whose text wraps still grow (with the
1156
+ * smaller padding). Header and footer rows, and stacked rows (`stackBelow`), are unchanged. */
1157
+ rowHeight?: "density" | undefined;
1150
1158
  className?: string | undefined;
1151
1159
  children?: React$1.ReactNode | undefined;
1152
1160
  }
package/dist/index.d.ts CHANGED
@@ -106,8 +106,10 @@ export interface DataTableColumn<Row extends Record<string, any> = Record<string
106
106
  actions?: boolean | undefined;
107
107
  /** Its place in a stacked card (5.13): `'hide'` leaves it out of the card (the grid keeps it), `'title'` / `'pill'`
108
108
  * make it the card's title or the pill beside it (instead of the first column / first pill column), `'field'` a
109
- * label/value field. Default: today's rule. */
110
- card?: "hide" | "field" | "title" | "pill" | undefined;
109
+ * label/value field. `'footer'` (5.22, Chamber-OS 118) makes it the card's last row, full width — row actions
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
113
  /** The order of fields in a stacked card (5.13), lowest first; the grid's column order is unchanged. Fields
112
114
  * without one sort by their column index (0-based). Screen readers and arrow keys follow the grid's order. */
113
115
  cardOrder?: number | undefined;
@@ -1147,6 +1149,12 @@ export interface TableProps extends Omit<React$1.TableHTMLAttributes<HTMLTableEl
1147
1149
  * each row its own framed card, spaced like DataTable's cards, with no frame around them. From the `stackBelow`
1148
1150
  * width up the table is unchanged. The table then sits in one more `div` (`.aura-tbl-cards`). */
1149
1151
  stackStyle?: "list" | "cards" | undefined;
1152
+ /** `'density'` (5.21, Chamber-OS 117): every body row is at least the density's row height (48px, 40px compact,
1153
+ * 48px on touch screens, as DataTable) and its cells' vertical padding shrinks to fit a small Button — so a row with
1154
+ * a `sm` Button, an IconButton, a pill or one line of text are all the same height, as in DataTable's
1155
+ * `rowHeight="auto"`. Content is centred on the row unless `align="top"`. Rows whose text wraps still grow (with the
1156
+ * smaller padding). Header and footer rows, and stacked rows (`stackBelow`), are unchanged. */
1157
+ rowHeight?: "density" | undefined;
1150
1158
  className?: string | undefined;
1151
1159
  children?: React$1.ReactNode | undefined;
1152
1160
  }
package/dist/styles.css CHANGED
@@ -1697,6 +1697,14 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1697
1697
  /* 5.13 (Chamber-OS 81): align="middle" centres body and footer cells on their row; bordered={false} drops the frame and
1698
1698
  * the outer cells' side padding, so the table lines up with what's around it (a Card's heading). */
1699
1699
  .aura-tbl--middle > .aura-tbl__body > .aura-tbl__row > *, .aura-tbl--middle > .aura-tbl__foot > .aura-tbl__row > * { vertical-align: middle; }
1700
+ /* 5.21 (Chamber-OS 117) rowHeight="density": a body row is at least the density's row height (a table row's height is
1701
+ * a minimum), and its cells' padding shrinks so a 32px small Button still fits it — 7.5px above and below at 48px,
1702
+ * 3.5px compact, never more than 8px — as in DataTable's auto rows. Before the stacked rules, which undo it. */
1703
+ .aura-tbl--row-density > .aura-tbl__body > .aura-tbl__row { height: var(--aura-table-row-height); }
1704
+ .aura-tbl--row-density > .aura-tbl__body > .aura-tbl__row > * {
1705
+ --aura-tbl-row-py: clamp(0px, calc((var(--aura-table-row-height) - 1px - var(--aura-button-height-sm)) / 2), var(--aura-space-2));
1706
+ padding-top: var(--aura-tbl-row-py); padding-bottom: var(--aura-tbl-row-py);
1707
+ }
1700
1708
  .aura-tbl-wrap.is-flush { border: 0; border-radius: 0; background: transparent; }
1701
1709
  .aura-tbl-wrap.is-flush > .aura-tbl > * > .aura-tbl__row > :first-child { padding-inline-start: 0; }
1702
1710
  .aura-tbl-wrap.is-flush > .aura-tbl > * > .aura-tbl__row > :last-child { padding-inline-end: 0; }
@@ -1709,7 +1717,7 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1709
1717
  .aura-tbl--stack-md, .aura-tbl--stack-md > .aura-tbl__body, .aura-tbl--stack-md > .aura-tbl__foot, .aura-tbl--stack-md > .aura-tbl__body > .aura-tbl__row, .aura-tbl--stack-md > .aura-tbl__foot > .aura-tbl__row, .aura-tbl--stack-md > * > .aura-tbl__row > .aura-tbl__th, .aura-tbl--stack-md > * > .aura-tbl__row > .aura-tbl__td { display: block; }
1710
1718
  .aura-tbl--stack-md > .aura-tbl__head { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
1711
1719
  .aura-tbl--stack-md > .aura-tbl__caption { display: block; padding: var(--aura-space-4) var(--aura-space-4) 0; }
1712
- .aura-tbl--stack-md > .aura-tbl__body > .aura-tbl__row, .aura-tbl--stack-md > .aura-tbl__foot > .aura-tbl__row { padding: var(--aura-tbl-cell-py, var(--aura-space-3)) var(--aura-space-4); }
1720
+ .aura-tbl--stack-md > .aura-tbl__body > .aura-tbl__row, .aura-tbl--stack-md > .aura-tbl__foot > .aura-tbl__row { height: auto; padding: var(--aura-tbl-cell-py, var(--aura-space-3)) var(--aura-space-4); }
1713
1721
  .aura-tbl--stack-md > .aura-tbl__body > .aura-tbl__row + .aura-tbl__row, .aura-tbl--stack-md > .aura-tbl__foot > .aura-tbl__row:first-child { border-top: 1px solid var(--aura-border-default); }
1714
1722
  .aura-tbl--stack-md > * > .aura-tbl__row > .aura-tbl__th, .aura-tbl--stack-md > * > .aura-tbl__row > .aura-tbl__td { padding: 0; border-top: 0; background: none; text-align: start; white-space: normal; }
1715
1723
  .aura-tbl--stack-md > * > .aura-tbl__row > * + * { margin-top: var(--aura-space-2); }
@@ -1731,7 +1739,7 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1731
1739
  .aura-tbl--stack-sm, .aura-tbl--stack-sm > .aura-tbl__body, .aura-tbl--stack-sm > .aura-tbl__foot, .aura-tbl--stack-sm > .aura-tbl__body > .aura-tbl__row, .aura-tbl--stack-sm > .aura-tbl__foot > .aura-tbl__row, .aura-tbl--stack-sm > * > .aura-tbl__row > .aura-tbl__th, .aura-tbl--stack-sm > * > .aura-tbl__row > .aura-tbl__td { display: block; }
1732
1740
  .aura-tbl--stack-sm > .aura-tbl__head { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
1733
1741
  .aura-tbl--stack-sm > .aura-tbl__caption { display: block; padding: var(--aura-space-4) var(--aura-space-4) 0; }
1734
- .aura-tbl--stack-sm > .aura-tbl__body > .aura-tbl__row, .aura-tbl--stack-sm > .aura-tbl__foot > .aura-tbl__row { padding: var(--aura-tbl-cell-py, var(--aura-space-3)) var(--aura-space-4); }
1742
+ .aura-tbl--stack-sm > .aura-tbl__body > .aura-tbl__row, .aura-tbl--stack-sm > .aura-tbl__foot > .aura-tbl__row { height: auto; padding: var(--aura-tbl-cell-py, var(--aura-space-3)) var(--aura-space-4); }
1735
1743
  .aura-tbl--stack-sm > .aura-tbl__body > .aura-tbl__row + .aura-tbl__row, .aura-tbl--stack-sm > .aura-tbl__foot > .aura-tbl__row:first-child { border-top: 1px solid var(--aura-border-default); }
1736
1744
  .aura-tbl--stack-sm > * > .aura-tbl__row > .aura-tbl__th, .aura-tbl--stack-sm > * > .aura-tbl__row > .aura-tbl__td { padding: 0; border-top: 0; background: none; text-align: start; white-space: normal; }
1737
1745
  .aura-tbl--stack-sm > * > .aura-tbl__row > * + * { margin-top: var(--aura-space-2); }
@@ -1846,9 +1854,29 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1846
1854
  .aura-table__td[data-card='title'] { order: 1; flex: 1 1 0; font-size: 14px; font-weight: 600; }
1847
1855
  .aura-table__td[data-card='pill'] { order: 2; flex: none; }
1848
1856
  .aura-table__td[data-card='actions'] { order: 3; flex: none; margin: calc(-1 * var(--aura-space-1)) calc(-1 * var(--aura-space-2)) calc(-1 * var(--aura-space-1)) 0; }
1857
+ /* 5.22 (Chamber-OS 119): the title wraps rather than being cut — a member's full name before a one-click action —
1858
+ * and the row box and the pill line up with its first line (a 20px line; the 16px box 2px down). */
1859
+ .aura-table__td[data-card='title'] { white-space: normal; overflow-wrap: anywhere; overflow: visible; line-height: 20px; align-self: flex-start; }
1860
+ .aura-table__td[data-card='pill'] { align-self: flex-start; line-height: 20px; }
1861
+ .aura-table__row > .aura-table__sel { align-self: flex-start; margin-top: 2px; }
1862
+ /* Actions top-right sit on that first line too (a 32px button centred on 20px, the same 24px footprint as before). */
1863
+ .aura-table__td[data-card='actions'] { align-self: flex-start; margin-top: calc(-1 * var(--aura-space-1) - 2px); margin-bottom: -2px; }
1864
+ /* 5.22 (Chamber-OS 118): card: 'footer' — the card's last row, full width; a Button in it grows, an IconButton or a
1865
+ * menu keeps its size. */
1866
+ .aura-table__td[data-card='footer'] {
1867
+ order: 99; flex: 0 0 100%; display: flex; align-items: center; gap: var(--aura-space-2);
1868
+ margin: var(--aura-space-1) 0 0; overflow: visible; white-space: normal;
1869
+ }
1870
+ .aura-table__td[data-card='footer'] > .aura-table__cell { display: flex; flex: 1 1 auto; align-items: center; gap: var(--aura-space-2); min-width: 0; }
1871
+ .aura-table__td[data-card='footer'] > .aura-btn, .aura-table__td[data-card='footer'] > .aura-table__cell > .aura-btn { flex: 1 1 auto; }
1872
+ /* Only an IconButton or a menu: at the end, as a card's ⋯ usually is. A totals row's label isn't shown there. */
1873
+ .aura-table__td[data-card='footer']:not(:has(.aura-btn)), .aura-table__td[data-card='footer'] > .aura-table__cell:not(:has(.aura-btn)) { justify-content: flex-end; }
1874
+ .aura-table__td[data-card='footer']::before { display: none; }
1849
1875
  /* Spacing: 12px under the title line, 8px between field lines (row gap 4 + the break's 4 + each field's 4 below). */
1850
1876
  .aura-table__break { display: block; order: 4; flex: 0 0 100%; height: var(--aura-space-1); }
1851
1877
  .aura-table__row:has(> .aura-table__break) { padding-bottom: calc(var(--aura-space-4) - var(--aura-space-1)); }
1878
+ /* 5.22: a footer row ends the card with no margin under it, so the card keeps its full 16px. */
1879
+ .aura-table__row:has(> [data-card='footer']:not(.is-blank)) { padding-bottom: var(--aura-space-4); }
1852
1880
  .aura-table__row--skeleton .aura-table__td { display: flex; }
1853
1881
  .aura-table__total { background: var(--aura-bg-canvas); }
1854
1882
  .aura-table__total > .is-blank { display: none; }
@@ -1699,6 +1699,14 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1699
1699
  /* 5.13 (Chamber-OS 81): align="middle" centres body and footer cells on their row; bordered={false} drops the frame and
1700
1700
  * the outer cells' side padding, so the table lines up with what's around it (a Card's heading). */
1701
1701
  .aura-tbl--middle > .aura-tbl__body > .aura-tbl__row > *, .aura-tbl--middle > .aura-tbl__foot > .aura-tbl__row > * { vertical-align: middle; }
1702
+ /* 5.21 (Chamber-OS 117) rowHeight="density": a body row is at least the density's row height (a table row's height is
1703
+ * a minimum), and its cells' padding shrinks so a 32px small Button still fits it — 7.5px above and below at 48px,
1704
+ * 3.5px compact, never more than 8px — as in DataTable's auto rows. Before the stacked rules, which undo it. */
1705
+ .aura-tbl--row-density > .aura-tbl__body > .aura-tbl__row { height: var(--aura-table-row-height); }
1706
+ .aura-tbl--row-density > .aura-tbl__body > .aura-tbl__row > * {
1707
+ --aura-tbl-row-py: clamp(0px, calc((var(--aura-table-row-height) - 1px - var(--aura-button-height-sm)) / 2), var(--aura-space-2));
1708
+ padding-top: var(--aura-tbl-row-py); padding-bottom: var(--aura-tbl-row-py);
1709
+ }
1702
1710
  .aura-tbl-wrap.is-flush { border: 0; border-radius: 0; background: transparent; }
1703
1711
  .aura-tbl-wrap.is-flush > .aura-tbl > * > .aura-tbl__row > :first-child { padding-inline-start: 0; }
1704
1712
  .aura-tbl-wrap.is-flush > .aura-tbl > * > .aura-tbl__row > :last-child { padding-inline-end: 0; }
@@ -1711,7 +1719,7 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1711
1719
  .aura-tbl--stack-md, .aura-tbl--stack-md > .aura-tbl__body, .aura-tbl--stack-md > .aura-tbl__foot, .aura-tbl--stack-md > .aura-tbl__body > .aura-tbl__row, .aura-tbl--stack-md > .aura-tbl__foot > .aura-tbl__row, .aura-tbl--stack-md > * > .aura-tbl__row > .aura-tbl__th, .aura-tbl--stack-md > * > .aura-tbl__row > .aura-tbl__td { display: block; }
1712
1720
  .aura-tbl--stack-md > .aura-tbl__head { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
1713
1721
  .aura-tbl--stack-md > .aura-tbl__caption { display: block; padding: var(--aura-space-4) var(--aura-space-4) 0; }
1714
- .aura-tbl--stack-md > .aura-tbl__body > .aura-tbl__row, .aura-tbl--stack-md > .aura-tbl__foot > .aura-tbl__row { padding: var(--aura-tbl-cell-py, var(--aura-space-3)) var(--aura-space-4); }
1722
+ .aura-tbl--stack-md > .aura-tbl__body > .aura-tbl__row, .aura-tbl--stack-md > .aura-tbl__foot > .aura-tbl__row { height: auto; padding: var(--aura-tbl-cell-py, var(--aura-space-3)) var(--aura-space-4); }
1715
1723
  .aura-tbl--stack-md > .aura-tbl__body > .aura-tbl__row + .aura-tbl__row, .aura-tbl--stack-md > .aura-tbl__foot > .aura-tbl__row:first-child { border-top: 1px solid var(--aura-border-default); }
1716
1724
  .aura-tbl--stack-md > * > .aura-tbl__row > .aura-tbl__th, .aura-tbl--stack-md > * > .aura-tbl__row > .aura-tbl__td { padding: 0; border-top: 0; background: none; text-align: start; white-space: normal; }
1717
1725
  .aura-tbl--stack-md > * > .aura-tbl__row > * + * { margin-top: var(--aura-space-2); }
@@ -1733,7 +1741,7 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1733
1741
  .aura-tbl--stack-sm, .aura-tbl--stack-sm > .aura-tbl__body, .aura-tbl--stack-sm > .aura-tbl__foot, .aura-tbl--stack-sm > .aura-tbl__body > .aura-tbl__row, .aura-tbl--stack-sm > .aura-tbl__foot > .aura-tbl__row, .aura-tbl--stack-sm > * > .aura-tbl__row > .aura-tbl__th, .aura-tbl--stack-sm > * > .aura-tbl__row > .aura-tbl__td { display: block; }
1734
1742
  .aura-tbl--stack-sm > .aura-tbl__head { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
1735
1743
  .aura-tbl--stack-sm > .aura-tbl__caption { display: block; padding: var(--aura-space-4) var(--aura-space-4) 0; }
1736
- .aura-tbl--stack-sm > .aura-tbl__body > .aura-tbl__row, .aura-tbl--stack-sm > .aura-tbl__foot > .aura-tbl__row { padding: var(--aura-tbl-cell-py, var(--aura-space-3)) var(--aura-space-4); }
1744
+ .aura-tbl--stack-sm > .aura-tbl__body > .aura-tbl__row, .aura-tbl--stack-sm > .aura-tbl__foot > .aura-tbl__row { height: auto; padding: var(--aura-tbl-cell-py, var(--aura-space-3)) var(--aura-space-4); }
1737
1745
  .aura-tbl--stack-sm > .aura-tbl__body > .aura-tbl__row + .aura-tbl__row, .aura-tbl--stack-sm > .aura-tbl__foot > .aura-tbl__row:first-child { border-top: 1px solid var(--aura-border-default); }
1738
1746
  .aura-tbl--stack-sm > * > .aura-tbl__row > .aura-tbl__th, .aura-tbl--stack-sm > * > .aura-tbl__row > .aura-tbl__td { padding: 0; border-top: 0; background: none; text-align: start; white-space: normal; }
1739
1747
  .aura-tbl--stack-sm > * > .aura-tbl__row > * + * { margin-top: var(--aura-space-2); }
@@ -1848,9 +1856,29 @@ button.aura-stepper__step:hover .aura-stepper__label { text-decoration: underlin
1848
1856
  .aura-table__td[data-card='title'] { order: 1; flex: 1 1 0; font-size: 14px; font-weight: 600; }
1849
1857
  .aura-table__td[data-card='pill'] { order: 2; flex: none; }
1850
1858
  .aura-table__td[data-card='actions'] { order: 3; flex: none; margin: calc(-1 * var(--aura-space-1)) calc(-1 * var(--aura-space-2)) calc(-1 * var(--aura-space-1)) 0; }
1859
+ /* 5.22 (Chamber-OS 119): the title wraps rather than being cut — a member's full name before a one-click action —
1860
+ * and the row box and the pill line up with its first line (a 20px line; the 16px box 2px down). */
1861
+ .aura-table__td[data-card='title'] { white-space: normal; overflow-wrap: anywhere; overflow: visible; line-height: 20px; align-self: flex-start; }
1862
+ .aura-table__td[data-card='pill'] { align-self: flex-start; line-height: 20px; }
1863
+ .aura-table__row > .aura-table__sel { align-self: flex-start; margin-top: 2px; }
1864
+ /* Actions top-right sit on that first line too (a 32px button centred on 20px, the same 24px footprint as before). */
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.22 (Chamber-OS 118): card: 'footer' — the card's last row, full width; a Button in it grows, an IconButton or a
1867
+ * menu keeps its size. */
1868
+ .aura-table__td[data-card='footer'] {
1869
+ order: 99; flex: 0 0 100%; display: flex; align-items: center; gap: var(--aura-space-2);
1870
+ margin: var(--aura-space-1) 0 0; overflow: visible; white-space: normal;
1871
+ }
1872
+ .aura-table__td[data-card='footer'] > .aura-table__cell { display: flex; flex: 1 1 auto; align-items: center; gap: var(--aura-space-2); min-width: 0; }
1873
+ .aura-table__td[data-card='footer'] > .aura-btn, .aura-table__td[data-card='footer'] > .aura-table__cell > .aura-btn { flex: 1 1 auto; }
1874
+ /* Only an IconButton or a menu: at the end, as a card's ⋯ usually is. A totals row's label isn't shown there. */
1875
+ .aura-table__td[data-card='footer']:not(:has(.aura-btn)), .aura-table__td[data-card='footer'] > .aura-table__cell:not(:has(.aura-btn)) { justify-content: flex-end; }
1876
+ .aura-table__td[data-card='footer']::before { display: none; }
1851
1877
  /* Spacing: 12px under the title line, 8px between field lines (row gap 4 + the break's 4 + each field's 4 below). */
1852
1878
  .aura-table__break { display: block; order: 4; flex: 0 0 100%; height: var(--aura-space-1); }
1853
1879
  .aura-table__row:has(> .aura-table__break) { padding-bottom: calc(var(--aura-space-4) - var(--aura-space-1)); }
1880
+ /* 5.22: a footer row ends the card with no margin under it, so the card keeps its full 16px. */
1881
+ .aura-table__row:has(> [data-card='footer']:not(.is-blank)) { padding-bottom: var(--aura-space-4); }
1854
1882
  .aura-table__row--skeleton .aura-table__td { display: flex; }
1855
1883
  .aura-table__total { background: var(--aura-bg-canvas); }
1856
1884
  .aura-table__total > .is-blank { display: none; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jirawatpyk/aura-react",
3
- "version": "5.20.0",
3
+ "version": "5.22.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",