@jirawatpyk/aura-react 5.51.0 → 5.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/Table.js CHANGED
@@ -2,6 +2,7 @@
2
2
  import * as React from "react";
3
3
  import { cx, devWarnOnce, uid, useIsoLayoutEffect } from "./internal.js";
4
4
  import { useDensity } from "./locale.js";
5
+ import { inertProps, skeletonBody, skeletonColgroup } from "./TableSkeleton.js";
5
6
  const StackLabels = React.createContext(null);
6
7
  const ColumnIndex = React.createContext(-1);
7
8
  function flat(children) {
@@ -47,6 +48,33 @@ function headerLabels(children) {
47
48
  });
48
49
  return out;
49
50
  }
51
+ function headerColumns(children) {
52
+ const out = [];
53
+ flat(children).forEach(function(c) {
54
+ if (out.length || !React.isValidElement(c) || c.type !== THead) return;
55
+ const row = flat(c.props.children).find(function(r) {
56
+ return React.isValidElement(r);
57
+ });
58
+ if (!row) return;
59
+ flat(row.props.children).forEach(function(cell) {
60
+ if (!React.isValidElement(cell)) return;
61
+ const p = cell.props;
62
+ const t = text(p.children);
63
+ const style = p.style;
64
+ const span = Math.max(1, Number(p.colSpan) || 1);
65
+ for (let i = 0; i < span; i++)
66
+ out.push({
67
+ label: p.label != null ? p.label : t != null ? t.replace(/\s+/g, " ").trim() || void 0 : void 0,
68
+ width: span > 1 ? void 0 : p.skeletonWidth != null ? p.skeletonWidth : p.width != null ? p.width : style && style.width,
69
+ align: p.align,
70
+ numeric: p.numeric,
71
+ card: p.card,
72
+ skeleton: p.skeleton
73
+ });
74
+ });
75
+ });
76
+ return out;
77
+ }
50
78
  const Table = React.forwardRef(function Table2(props, ref) {
51
79
  const {
52
80
  caption,
@@ -61,10 +89,24 @@ const Table = React.forwardRef(function Table2(props, ref) {
61
89
  maxHeight,
62
90
  stackStyle,
63
91
  rowHeight,
92
+ loading,
93
+ loadingRows,
64
94
  className,
65
95
  children,
66
96
  ...rest
67
97
  } = props;
98
+ const skeletonCols = loading ? headerColumns(children) : null;
99
+ if (skeletonCols && !skeletonCols.length)
100
+ devWarnOnce(
101
+ "tbl-loading-cols",
102
+ "Table loading: no THead > Tr > Th found among its children, so there are no columns to draw. Put the THead directly inside Table (a function call, not your own component)."
103
+ );
104
+ const shownChildren = skeletonCols ? [
105
+ flat(children).filter(function(c) {
106
+ return React.isValidElement(c) && c.type === THead;
107
+ }),
108
+ skeletonBody(skeletonCols, loadingRows != null ? Math.max(0, loadingRows) : 5, !!stackBelow)
109
+ ] : children;
68
110
  const cards = !!stackBelow && stackStyle === "cards";
69
111
  if (maxHeight != null && caption == null && !rest["aria-label"] && !rest["aria-labelledby"])
70
112
  devWarnOnce(
@@ -118,10 +160,11 @@ const Table = React.forwardRef(function Table2(props, ref) {
118
160
  ),
119
161
  style: maxHeight != null ? { maxHeight: typeof maxHeight === "number" ? maxHeight + "px" : maxHeight } : void 0,
120
162
  "data-density": density || pageDensity,
121
- tabIndex: scrolls ? 0 : void 0,
122
- role: scrolls && (caption != null || rest["aria-label"] || rest["aria-labelledby"]) ? "region" : void 0,
123
- "aria-labelledby": scrolls ? caption != null ? capId : rest["aria-labelledby"] : void 0,
124
- "aria-label": scrolls && caption == null ? rest["aria-label"] : void 0
163
+ ...loading ? inertProps() : null,
164
+ tabIndex: scrolls && !loading ? 0 : void 0,
165
+ role: scrolls && !loading && (caption != null || rest["aria-label"] || rest["aria-labelledby"]) ? "region" : void 0,
166
+ "aria-labelledby": scrolls && !loading ? caption != null ? capId : rest["aria-labelledby"] : void 0,
167
+ "aria-label": scrolls && !loading && caption == null ? rest["aria-label"] : void 0
125
168
  },
126
169
  /* @__PURE__ */ React.createElement(
127
170
  "table",
@@ -134,13 +177,15 @@ const Table = React.forwardRef(function Table2(props, ref) {
134
177
  (align === "middle" || rowHeight === "density" && align !== "top") && "aura-tbl--middle",
135
178
  rowHeight === "density" && "aura-tbl--row-density",
136
179
  cards && "aura-tbl--cards",
180
+ loading && "aura-tbl--skeleton",
137
181
  className
138
182
  ),
139
183
  role: stackBelow ? "table" : void 0,
140
184
  ...rest
141
185
  },
142
186
  caption != null ? /* @__PURE__ */ React.createElement("caption", { id: capId, className: cx("aura-tbl__caption", captionHidden && "aura-sr-only") }, caption) : null,
143
- labels ? /* @__PURE__ */ React.createElement(StackLabels.Provider, { value: labels }, children) : outer ? /* @__PURE__ */ React.createElement(StackLabels.Provider, { value: null }, children) : children
187
+ skeletonCols ? skeletonColgroup(skeletonCols) : null,
188
+ labels ? /* @__PURE__ */ React.createElement(StackLabels.Provider, { value: labels }, shownChildren) : outer ? /* @__PURE__ */ React.createElement(StackLabels.Provider, { value: null }, shownChildren) : shownChildren
144
189
  )
145
190
  );
146
191
  return cards ? /* @__PURE__ */ React.createElement(
@@ -194,7 +239,7 @@ function cellClass(base, p) {
194
239
  );
195
240
  }
196
241
  const Th = React.forwardRef(function Th2(props, ref) {
197
- const { align, numeric, mono, className, scope, label, card, ...rest } = props;
242
+ const { align, numeric, mono, className, scope, label, card, skeleton, skeletonWidth, ...rest } = props;
198
243
  const stacked = React.useContext(StackLabels) != null;
199
244
  return /* @__PURE__ */ React.createElement(
200
245
  "th",
@@ -209,7 +254,7 @@ const Th = React.forwardRef(function Th2(props, ref) {
209
254
  );
210
255
  });
211
256
  const Td = React.forwardRef(function Td2(props, ref) {
212
- const { align, numeric, mono, className, scope, label, card, ...rest } = props;
257
+ const { align, numeric, mono, className, scope, label, card, skeleton, skeletonWidth, ...rest } = props;
213
258
  const labels = React.useContext(StackLabels), col = React.useContext(ColumnIndex);
214
259
  const slot = labels && (card === "title" || card === "action") ? card : void 0;
215
260
  const shown = labels && !slot ? label != null ? label : col >= 0 ? labels[col] : void 0 : void 0;
@@ -0,0 +1,170 @@
1
+ 'use client';
2
+ import * as React from "react";
3
+ import { cx } from "./classes.js";
4
+ const h = React.createElement;
5
+ function inertProps() {
6
+ return { inert: parseInt(React.version, 10) >= 19 ? true : "", "aria-hidden": true };
7
+ }
8
+ function widthOf(w) {
9
+ return w == null || w === "" ? void 0 : typeof w === "number" ? w + "px" : w;
10
+ }
11
+ function skeletonColgroup(cols) {
12
+ return h(
13
+ "colgroup",
14
+ null,
15
+ cols.map(function(c, i) {
16
+ const w = widthOf(c.width);
17
+ return h("col", { key: i, style: w ? { width: w } : void 0 });
18
+ })
19
+ );
20
+ }
21
+ function placeholder(c) {
22
+ const s = c.skeleton || {};
23
+ if (s.kind === "pill") return h("span", { className: "aura-skel aura-skel--pill" });
24
+ if (s.kind === "action") return h("span", { className: cx("aura-skel aura-skel--action", s.touch && "is-touch") });
25
+ if (s.lines === 2)
26
+ return h(
27
+ "span",
28
+ { className: "aura-skel-lines" },
29
+ h("span", { className: "aura-skel aura-skel--text", style: { width: "100%" } }),
30
+ h("span", { className: "aura-skel aura-skel--text", style: { width: "60%" } })
31
+ );
32
+ return h("span", { className: "aura-skel aura-skel--text", style: { width: "80%" } });
33
+ }
34
+ function cellCls(base, c) {
35
+ const align = c.align || (c.numeric ? "end" : void 0);
36
+ return cx(base, align === "end" && "is-end", align === "center" && "is-center", c.numeric && "is-numeric");
37
+ }
38
+ function skeletonBody(cols, n, stacked) {
39
+ const rows = [];
40
+ for (let r = 0; r < n; r++)
41
+ rows.push(
42
+ h(
43
+ "tr",
44
+ { key: r, className: "aura-tbl__row aura-tbl__row--skeleton", role: stacked ? "row" : void 0 },
45
+ cols.map(function(c, i) {
46
+ const slot = stacked && (c.card === "title" || c.card === "action") ? c.card : void 0;
47
+ return h(
48
+ "td",
49
+ {
50
+ key: i,
51
+ className: cellCls("aura-tbl__td", c),
52
+ role: stacked ? "cell" : void 0,
53
+ "data-label": stacked && !slot && c.label ? c.label : void 0,
54
+ "data-card": slot
55
+ },
56
+ placeholder(c)
57
+ );
58
+ })
59
+ )
60
+ );
61
+ return h(
62
+ "tbody",
63
+ { key: "aura-skeleton", className: "aura-tbl__body", role: stacked ? "rowgroup" : void 0 },
64
+ rows
65
+ );
66
+ }
67
+ function tableWrapClass(p) {
68
+ return cx(
69
+ "aura-tbl-wrap",
70
+ p.stackBelow && "is-stackable",
71
+ p.bordered === false && "is-flush",
72
+ p.bleed && "aura-bleed-frame",
73
+ p.bleed && !p.cards && "aura-bleed",
74
+ p.bleed && p.bleedEnd && !p.cards && "aura-bleed-end"
75
+ );
76
+ }
77
+ function tableClass(p) {
78
+ return cx(
79
+ "aura-tbl",
80
+ p.stackBelow && "aura-tbl--stack-" + p.stackBelow,
81
+ (p.align === "middle" || p.rowHeight === "density" && p.align !== "top") && "aura-tbl--middle",
82
+ p.rowHeight === "density" && "aura-tbl--row-density",
83
+ p.cards && "aura-tbl--cards",
84
+ p.className
85
+ );
86
+ }
87
+ function cardsFrame(el, p) {
88
+ return p.cards ? h(
89
+ "div",
90
+ {
91
+ className: cx(
92
+ "aura-tbl-cards aura-tbl-cards--" + p.stackBelow,
93
+ p.bleed && "aura-bleed",
94
+ p.bleed && p.bleedEnd && "aura-bleed-end"
95
+ )
96
+ },
97
+ el
98
+ ) : el;
99
+ }
100
+ function TableSkeleton(props) {
101
+ const cols = props.columns || [];
102
+ const n = props.rows != null ? Math.max(0, props.rows) : 5;
103
+ const stacked = !!props.stackBelow;
104
+ const cards = stacked && props.stackStyle === "cards";
105
+ const head = h(
106
+ "thead",
107
+ { className: "aura-tbl__head", role: stacked ? "rowgroup" : void 0 },
108
+ h(
109
+ "tr",
110
+ { className: "aura-tbl__row", role: stacked ? "row" : void 0 },
111
+ cols.map(function(c, i) {
112
+ return h(
113
+ "th",
114
+ { key: i, scope: "col", className: cellCls("aura-tbl__th", c), role: stacked ? "columnheader" : void 0 },
115
+ c.label
116
+ );
117
+ })
118
+ )
119
+ );
120
+ const table = h(
121
+ "div",
122
+ Object.assign(
123
+ {
124
+ className: tableWrapClass({
125
+ stackBelow: props.stackBelow,
126
+ bordered: props.bordered,
127
+ bleed: props.bleed,
128
+ bleedEnd: props.bleedEnd,
129
+ cards
130
+ }),
131
+ "data-density": props.density || "comfortable"
132
+ },
133
+ inertProps()
134
+ ),
135
+ h(
136
+ "table",
137
+ {
138
+ className: cx(
139
+ tableClass({
140
+ stackBelow: props.stackBelow,
141
+ align: props.align,
142
+ rowHeight: props.rowHeight,
143
+ cards,
144
+ className: props.className
145
+ }),
146
+ "aura-tbl--skeleton"
147
+ ),
148
+ role: stacked ? "table" : void 0
149
+ },
150
+ skeletonColgroup(cols),
151
+ head,
152
+ skeletonBody(cols, n, stacked)
153
+ )
154
+ );
155
+ return cardsFrame(table, {
156
+ stackBelow: props.stackBelow,
157
+ bleed: props.bleed,
158
+ bleedEnd: props.bleedEnd,
159
+ cards
160
+ });
161
+ }
162
+ export {
163
+ TableSkeleton,
164
+ cardsFrame,
165
+ inertProps,
166
+ skeletonBody,
167
+ skeletonColgroup,
168
+ tableClass,
169
+ tableWrapClass
170
+ };
package/dist/esm/index.js CHANGED
@@ -42,6 +42,7 @@ import { AppShell } from "./AppShell.js";
42
42
  import { ActionBar } from "./ActionBar.js";
43
43
  import { Separator } from "./Separator.js";
44
44
  import { Table, THead, TBody, TFoot, Tr, Th, Td } from "./Table.js";
45
+ import { TableSkeleton } from "./TableSkeleton.js";
45
46
  import { BottomNav } from "./BottomNav.js";
46
47
  import { useBreakpoint, useResponsive, breakpoints } from "./responsive.js";
47
48
  import { Surface } from "./Surface.js";
@@ -125,6 +126,7 @@ export {
125
126
  TFoot,
126
127
  THead,
127
128
  Table,
129
+ TableSkeleton,
128
130
  Tabs,
129
131
  Tag,
130
132
  Td,
package/dist/index.d.cts CHANGED
@@ -1365,9 +1365,54 @@ export interface TableProps extends Omit<React$1.TableHTMLAttributes<HTMLTableEl
1365
1365
  * `rowHeight="auto"`. Content is centred on the row unless `align="top"`. Rows whose text wraps still grow (with the
1366
1366
  * smaller padding). Header and footer rows, and stacked rows (`stackBelow`), are unchanged. */
1367
1367
  rowHeight?: "density" | undefined;
1368
+ /** 5.52 (Chamber-OS 164): draw the table while its rows load — the head as given, then `loadingRows` placeholder
1369
+ * rows in the same columns (and, below `stackBelow`, the same cards). Each column's placeholder follows its header
1370
+ * cell's `skeleton` hint, width (`skeletonWidth`, else its `width`, else an even share) and `card` role. The whole
1371
+ * table is `aria-hidden` and `inert` meanwhile: announce the load in your own status line. TBody and TFoot children
1372
+ * are not rendered. For a Server Component (a route's loading.tsx) use `TableSkeleton` from `/server`. */
1373
+ loading?: boolean | undefined;
1374
+ /** Placeholder rows while `loading` (default 5). */
1375
+ loadingRows?: number | undefined;
1368
1376
  className?: string | undefined;
1369
1377
  children?: React$1.ReactNode | undefined;
1370
1378
  }
1379
+ /** 5.52 (Chamber-OS 164): what a loading column's placeholder cell looks like. */
1380
+ export interface TableSkeletonHint {
1381
+ /** Text lines: 2 for a value over its caption. Default 1. */
1382
+ lines?: 1 | 2 | undefined;
1383
+ /** `text` (default) bars, a status `pill`, or an `action` block as tall as a small Button (44px on a phone card or a
1384
+ * touch screen with `touch`). */
1385
+ kind?: "text" | "pill" | "action" | undefined;
1386
+ /** An `action` block 44px below 640px and on a coarse pointer, as `touchHeight` buttons are. */
1387
+ touch?: boolean | undefined;
1388
+ }
1389
+ /** 5.52 (Chamber-OS 164): one column of a `TableSkeleton` — the same facts a header cell gives a loading Table. */
1390
+ export interface TableSkeletonColumn {
1391
+ /** Header text (and the stacked card's field label). */
1392
+ label?: string | undefined;
1393
+ /** Column width: a share such as `'22%'`, or px. Columns without one split what is left evenly. */
1394
+ width?: string | number | undefined;
1395
+ align?: "start" | "center" | "end" | undefined;
1396
+ numeric?: boolean | undefined;
1397
+ /** Its place in a stacked row: `title`, `action` or `field` (default), as on a Td. */
1398
+ card?: "title" | "action" | "field" | undefined;
1399
+ skeleton?: TableSkeletonHint | undefined;
1400
+ }
1401
+ /** 5.52 (Chamber-OS 164): a loading Table for Server Components. Same frame, density, stacking and cards as Table. */
1402
+ export interface TableSkeletonProps {
1403
+ columns: TableSkeletonColumn[];
1404
+ /** Placeholder rows (default 5). */
1405
+ rows?: number | undefined;
1406
+ density?: "comfortable" | "compact" | undefined;
1407
+ stackBelow?: "sm" | "md" | undefined;
1408
+ stackStyle?: "list" | "cards" | undefined;
1409
+ bordered?: boolean | undefined;
1410
+ bleed?: boolean | undefined;
1411
+ bleedEnd?: boolean | undefined;
1412
+ rowHeight?: "density" | undefined;
1413
+ align?: "top" | "middle" | undefined;
1414
+ className?: string | undefined;
1415
+ }
1371
1416
  export interface TableSectionProps extends React$1.HTMLAttributes<HTMLTableSectionElement> {
1372
1417
  className?: string | undefined;
1373
1418
  }
@@ -1389,6 +1434,12 @@ export interface TableCellProps extends Omit<React$1.TdHTMLAttributes<HTMLTableC
1389
1434
  * without a label; `action` sits at the end of that line at its natural size; `field` (default) is a labelled field,
1390
1435
  * two to a line under them. */
1391
1436
  card?: "title" | "action" | "field" | undefined;
1437
+ /** Th in the head only (5.52, Chamber-OS 164): what this column's placeholder cells look like while the Table is
1438
+ * `loading`. On a head cell, `card` also gives the placeholder cells their place in a stacked row. */
1439
+ skeleton?: TableSkeletonHint | undefined;
1440
+ /** Th in the head only (5.52): this column's width while loading — a share such as `'22%'` — when the loaded table
1441
+ * sizes it from its content. Default: the cell's `width`, else an even share. */
1442
+ skeletonWidth?: string | number | undefined;
1392
1443
  className?: string | undefined;
1393
1444
  }
1394
1445
  export interface ActionBarProps {
@@ -2168,6 +2219,9 @@ export declare const Tr: React$1.ForwardRefExoticComponent<TableRowProps & React
2168
2219
  export declare const Th: React$1.ForwardRefExoticComponent<TableCellProps & React$1.RefAttributes<HTMLTableCellElement>>;
2169
2220
  /** Data cell. `numeric` right-aligns with tabular figures (money, counts). */
2170
2221
  export declare const Td: React$1.ForwardRefExoticComponent<TableCellProps & React$1.RefAttributes<HTMLTableCellElement>>;
2222
+ /** A loading Table (5.52, Chamber-OS 164), for Server Components — e.g. a route's loading.tsx. `aria-hidden` and
2223
+ * `inert`: announce the load in the page's own status line. */
2224
+ export declare function TableSkeleton(props: TableSkeletonProps): React$1.ReactElement;
2171
2225
  /** BottomNav — a phone tab bar: icon over a short label, a count or dot, the current page marked. Fixed to the bottom,
2172
2226
  * padded for the home indicator, with a spacer of the same height in the flow so nothing sits under it. Which
2173
2227
  * breakpoints show it is decided in CSS, so the server's HTML is already right and nothing shifts on hydration. */
package/dist/index.d.ts CHANGED
@@ -1365,9 +1365,54 @@ export interface TableProps extends Omit<React$1.TableHTMLAttributes<HTMLTableEl
1365
1365
  * `rowHeight="auto"`. Content is centred on the row unless `align="top"`. Rows whose text wraps still grow (with the
1366
1366
  * smaller padding). Header and footer rows, and stacked rows (`stackBelow`), are unchanged. */
1367
1367
  rowHeight?: "density" | undefined;
1368
+ /** 5.52 (Chamber-OS 164): draw the table while its rows load — the head as given, then `loadingRows` placeholder
1369
+ * rows in the same columns (and, below `stackBelow`, the same cards). Each column's placeholder follows its header
1370
+ * cell's `skeleton` hint, width (`skeletonWidth`, else its `width`, else an even share) and `card` role. The whole
1371
+ * table is `aria-hidden` and `inert` meanwhile: announce the load in your own status line. TBody and TFoot children
1372
+ * are not rendered. For a Server Component (a route's loading.tsx) use `TableSkeleton` from `/server`. */
1373
+ loading?: boolean | undefined;
1374
+ /** Placeholder rows while `loading` (default 5). */
1375
+ loadingRows?: number | undefined;
1368
1376
  className?: string | undefined;
1369
1377
  children?: React$1.ReactNode | undefined;
1370
1378
  }
1379
+ /** 5.52 (Chamber-OS 164): what a loading column's placeholder cell looks like. */
1380
+ export interface TableSkeletonHint {
1381
+ /** Text lines: 2 for a value over its caption. Default 1. */
1382
+ lines?: 1 | 2 | undefined;
1383
+ /** `text` (default) bars, a status `pill`, or an `action` block as tall as a small Button (44px on a phone card or a
1384
+ * touch screen with `touch`). */
1385
+ kind?: "text" | "pill" | "action" | undefined;
1386
+ /** An `action` block 44px below 640px and on a coarse pointer, as `touchHeight` buttons are. */
1387
+ touch?: boolean | undefined;
1388
+ }
1389
+ /** 5.52 (Chamber-OS 164): one column of a `TableSkeleton` — the same facts a header cell gives a loading Table. */
1390
+ export interface TableSkeletonColumn {
1391
+ /** Header text (and the stacked card's field label). */
1392
+ label?: string | undefined;
1393
+ /** Column width: a share such as `'22%'`, or px. Columns without one split what is left evenly. */
1394
+ width?: string | number | undefined;
1395
+ align?: "start" | "center" | "end" | undefined;
1396
+ numeric?: boolean | undefined;
1397
+ /** Its place in a stacked row: `title`, `action` or `field` (default), as on a Td. */
1398
+ card?: "title" | "action" | "field" | undefined;
1399
+ skeleton?: TableSkeletonHint | undefined;
1400
+ }
1401
+ /** 5.52 (Chamber-OS 164): a loading Table for Server Components. Same frame, density, stacking and cards as Table. */
1402
+ export interface TableSkeletonProps {
1403
+ columns: TableSkeletonColumn[];
1404
+ /** Placeholder rows (default 5). */
1405
+ rows?: number | undefined;
1406
+ density?: "comfortable" | "compact" | undefined;
1407
+ stackBelow?: "sm" | "md" | undefined;
1408
+ stackStyle?: "list" | "cards" | undefined;
1409
+ bordered?: boolean | undefined;
1410
+ bleed?: boolean | undefined;
1411
+ bleedEnd?: boolean | undefined;
1412
+ rowHeight?: "density" | undefined;
1413
+ align?: "top" | "middle" | undefined;
1414
+ className?: string | undefined;
1415
+ }
1371
1416
  export interface TableSectionProps extends React$1.HTMLAttributes<HTMLTableSectionElement> {
1372
1417
  className?: string | undefined;
1373
1418
  }
@@ -1389,6 +1434,12 @@ export interface TableCellProps extends Omit<React$1.TdHTMLAttributes<HTMLTableC
1389
1434
  * without a label; `action` sits at the end of that line at its natural size; `field` (default) is a labelled field,
1390
1435
  * two to a line under them. */
1391
1436
  card?: "title" | "action" | "field" | undefined;
1437
+ /** Th in the head only (5.52, Chamber-OS 164): what this column's placeholder cells look like while the Table is
1438
+ * `loading`. On a head cell, `card` also gives the placeholder cells their place in a stacked row. */
1439
+ skeleton?: TableSkeletonHint | undefined;
1440
+ /** Th in the head only (5.52): this column's width while loading — a share such as `'22%'` — when the loaded table
1441
+ * sizes it from its content. Default: the cell's `width`, else an even share. */
1442
+ skeletonWidth?: string | number | undefined;
1392
1443
  className?: string | undefined;
1393
1444
  }
1394
1445
  export interface ActionBarProps {
@@ -2168,6 +2219,9 @@ export declare const Tr: React$1.ForwardRefExoticComponent<TableRowProps & React
2168
2219
  export declare const Th: React$1.ForwardRefExoticComponent<TableCellProps & React$1.RefAttributes<HTMLTableCellElement>>;
2169
2220
  /** Data cell. `numeric` right-aligns with tabular figures (money, counts). */
2170
2221
  export declare const Td: React$1.ForwardRefExoticComponent<TableCellProps & React$1.RefAttributes<HTMLTableCellElement>>;
2222
+ /** A loading Table (5.52, Chamber-OS 164), for Server Components — e.g. a route's loading.tsx. `aria-hidden` and
2223
+ * `inert`: announce the load in the page's own status line. */
2224
+ export declare function TableSkeleton(props: TableSkeletonProps): React$1.ReactElement;
2171
2225
  /** BottomNav — a phone tab bar: icon over a short label, a count or dot, the current page marked. Fixed to the bottom,
2172
2226
  * padded for the home indicator, with a spacer of the same height in the flow so nothing sits under it. Which
2173
2227
  * breakpoints show it is decided in CSS, so the server's HTML is already right and nothing shifts on hydration. */