@box-kite/react 2.3.1 → 2.4.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.
Files changed (40) hide show
  1. package/.claude/rules/box-kite-rules.md +58 -94
  2. package/.claude/skills/box-kite/SKILL.md +69 -104
  3. package/.claude/skills/box-kite/references/components.md +1 -1
  4. package/.claude/skills/box-kite/references/patterns.md +1 -1
  5. package/.claude/skills/box-kite/references/rules.md +115 -0
  6. package/.cursor/rules/box-kite.mdc +60 -96
  7. package/AGENTS.md +61 -97
  8. package/BOX_AI_CONTEXT.md +39 -38
  9. package/BOX_KITE_AI_CONTEXT.md +39 -38
  10. package/README.md +200 -721
  11. package/client.cjs +1 -1
  12. package/client.mjs +81 -81
  13. package/components/combobox/comboboxListbox.d.ts +2 -1
  14. package/components/combobox.cjs +1 -1
  15. package/components/combobox.d.ts +1 -1
  16. package/components/combobox.mjs +199 -188
  17. package/components/dataGrid/contracts/dataGridContract.d.ts +2 -1
  18. package/components/dataGrid/useListLayout.d.ts +1 -1
  19. package/components/dataGrid.cjs +3 -3
  20. package/components/dataGrid.mjs +453 -453
  21. package/components/radioGroup.cjs +1 -1
  22. package/components/radioGroup.mjs +1 -0
  23. package/components/semantics.d.ts +29 -29
  24. package/components/skeleton.cjs +1 -1
  25. package/components/skeleton.d.ts +1 -1
  26. package/components/skeleton.mjs +2 -1
  27. package/components/textarea.d.ts +1 -1
  28. package/components/textbox.d.ts +1 -1
  29. package/components/timeZoneSelect.d.ts +1 -1
  30. package/components/toaster.cjs +1 -1
  31. package/components/toaster.mjs +13 -14
  32. package/docs/a11y.md +1 -2
  33. package/docs/index.md +1 -1
  34. package/effects.cjs +1 -1
  35. package/effects.mjs +2 -2
  36. package/identity.cjs +1 -1
  37. package/identity.mjs +5 -7
  38. package/package.json +9 -9
  39. package/react/effects.d.ts +5 -6
  40. package/react/identity/useIdentifier.d.ts +0 -3
package/BOX_AI_CONTEXT.md CHANGED
@@ -1263,7 +1263,7 @@ import Textbox from '@box-kite/react/components/textbox';
1263
1263
  <Flex d="column" gap={2} md={{ d: 'row', gap: 4 }}>{children}</Flex>
1264
1264
 
1265
1265
  // Grid
1266
- <Grid gridCols={3} gap={4}>{items.map(i => <Box key={i.id}>{i.content}</Box>)}</Grid>
1266
+ <Grid gridTemplateColumns={3} gap={4}>{items.map(i => <Box key={i.id}>{i.content}</Box>)}</Grid>
1267
1267
 
1268
1268
  // Card
1269
1269
  <Box p={4} bgColor="white" borderRadius={8} shadow="medium">{content}</Box>
@@ -1521,16 +1521,16 @@ the association needs no `htmlFor`/`id` pair and the whole row is a click target
1521
1521
  nothing wraps the input — the markup is what it always was. `labelProps` styles that `<label>`;
1522
1522
  every other Box prop styles the control itself.
1523
1523
 
1524
- | Component | Prop | What it does |
1525
- | ------------ | ------------------------ | -------------------------------------------------------------------------------------------- |
1526
- | all three | `label` / `labelProps` | The wrapping `<label>` and its styles. |
1527
- | `Checkbox` | `indeterminate` | Sets the DOM property **and** `aria-checked="mixed"`, which is what is announced. |
1528
- | `Switch` | — | `role="switch"` over the same input; Space **and** Enter toggle, Enter does not submit. |
1529
- | `RadioGroup` | `label` | `role="radiogroup"` named by it — a set of radios with nothing over it is a flat list. |
1530
- | `RadioGroup` | `name` | The field every item submits under. Generated when left out. |
1531
- | `RadioGroup` | `value` / `defaultValue` | The selected item's value (a string — the platform's own model for a radio). |
1532
- | `RadioGroup` | `onValueChange` | `(value, { reason, event })` — `click` or `keyboard`. `onChange` is the deprecated spelling. |
1533
- | `RadioGroup` | `orientation` | `vertical` (default) or `horizontal`. Both arrow pairs navigate either way. |
1524
+ | Component | Prop | What it does |
1525
+ | ------------ | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
1526
+ | all three | `label` / `labelProps` | The wrapping `<label>` and its styles. |
1527
+ | `Checkbox` | `indeterminate` | Sets the DOM property **and** `aria-checked="mixed"`, which is what is announced. |
1528
+ | `Switch` | — | `role="switch"` over the same input; Space **and** Enter toggle, Enter does not submit. |
1529
+ | `RadioGroup` | `label` | `role="radiogroup"` named by it — a set of radios with nothing over it is a flat list. |
1530
+ | `RadioGroup` | `name` | The field every item submits under. Generated when left out. |
1531
+ | `RadioGroup` | `value` / `defaultValue` | The selected item's value (a string — the platform's own model for a radio). |
1532
+ | `RadioGroup` | `onValueChange` | `(value, { reason, event })` — `click` or `keyboard`. `onChange` is the deprecated spelling. |
1533
+ | `RadioGroup` | `orientation` | `vertical` (default) or `horizontal`, which wraps and keeps the label on a line of its own above the radios. Both arrow pairs navigate either way. |
1534
1534
 
1535
1535
  Arrow keys move **and select** inside a group, wrapping at both ends and skipping disabled items;
1536
1536
  Tab enters the group once and leaves it once, because a native radio set is already a single tab
@@ -2790,27 +2790,27 @@ named ones carry the reason.
2790
2790
 
2791
2791
  ### ColumnType
2792
2792
 
2793
- | Prop | Type | Default | Description |
2794
- | ------------------------ | ------------------------------------------------------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
2795
- | `key` | `Key` | required | Column identifier (maps to TRow property) |
2796
- | `header` | `string` | — | Header text |
2797
- | `width` | `number` | `200` | Base width in px |
2798
- | `align` | `'start' \| 'end' \| 'center' \| 'left' \| 'right'` | `'left'` | Cell alignment. `start`/`end` follow the reading order; `left`/`right` stay on the screen side they name |
2799
- | `pin` | `'START' \| 'END'` (also `'LEFT'`/`'RIGHT'`) | — | Pin to an edge of the **inline axis** (sticky on scroll), so it holds under either `dir`. `LEFT`/`RIGHT` are the older spelling of the same two |
2800
- | `columns` | `ColumnType[]` | — | Nested columns (grouped header) |
2801
- | `Cell` | `({ cell }) => ReactNode` | — | Custom renderer. `cell`: `{ value, row, column, grid }`. It redraws when its row changes or the grid does — not when another row is selected |
2802
- | `sortable` / `resizable` | `boolean` | inherits | Override grid-level setting |
2803
- | `flexible` | `boolean` | `true` | Participate in flex width distribution |
2804
- | `filterable` | `boolean \| FilterConfig` | — | `true` (text), `{ type: 'number', min?, max? }`, `{ type: 'multiselect', options? }` |
2805
- | `contextMenu` | `boolean \| ContextMenuConfig` | inherits | Override grid-level context menu. `false` hides entirely. `{ sort?, pin?, group? }` controls sections |
2806
- | `aggregate` | `AggregateName \| (values, rows) => value` | — | Total this column over each group row, and over the footer. See below |
2807
- | `AggregateCell` | `({ cell }) => ReactNode` | — | Renders the aggregate. `cell`: `{ value, column, rows, scope }`, `scope` being `'group'` or `'footer'` |
2808
- | `editable` | `boolean \| (row) => boolean` | inherits | Whether this column’s cells can be edited — every row, or the rows a predicate says |
2809
- | `editor` | `CellEditorType \| CellEditorConfig` | inferred | `text`/`number`/`checkbox`/`select`. Without one it is read off the value in the cell |
2810
- | `EditCell` | `({ cell }) => ReactNode` | — | An editor of your own, bound to `cell.draft` with `cell.commitEdit()`/`cell.cancelEdit()` |
2811
- | `exportValue` | `(row: TRow) => value` | the field | What this column writes to an exported file — an export runs no React, so a `Cell` renderer needs it |
2812
- | `list` | `'title' \| 'kicker' \| 'subtitle' \| 'end' \| 'field' \| 'detail' \| 'hidden'` | inferred | Where the column goes in a list item, on a phone |
2813
- | `exportFormat` | `string` | — | The number format its cells wear in a workbook, `'#,##0.00'` or `'yyyy-mm-dd'` |
2793
+ | Prop | Type | Default | Description |
2794
+ | ------------------------ | ------------------------------------------------------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
2795
+ | `key` | `Key` | required | Column identifier (maps to TRow property) |
2796
+ | `header` | `string` | — | Header text |
2797
+ | `width` | `number` | `200` | Base width in px |
2798
+ | `align` | `'start' \| 'end' \| 'center' \| 'left' \| 'right'` | `'left'` | Cell alignment. `start`/`end` follow the reading order; `left`/`right` stay on the screen side they name |
2799
+ | `pin` | `'START' \| 'END'` (also `'LEFT'`/`'RIGHT'`) | — | Pin to an edge of the **inline axis** (sticky on scroll), so it holds under either `dir`. `LEFT`/`RIGHT` are the older spelling of the same two |
2800
+ | `columns` | `ColumnType[]` | — | Nested columns (grouped header) |
2801
+ | `Cell` | `({ cell }) => ReactNode` | — | Custom renderer. `cell`: `{ value, row, column, grid }`. It fills the cell **edge to edge, with no padding** — the built-in text pads itself `px={3}`, so text of your own does the same. It redraws when its row changes or the grid does — not when another row is selected |
2802
+ | `sortable` / `resizable` | `boolean` | inherits | Override grid-level setting |
2803
+ | `flexible` | `boolean` | `true` | Participate in flex width distribution |
2804
+ | `filterable` | `boolean \| FilterConfig` | — | `true` (text), `{ type: 'number', min?, max? }`, `{ type: 'multiselect', options? }` |
2805
+ | `contextMenu` | `boolean \| ContextMenuConfig` | inherits | Override grid-level context menu. `false` hides entirely. `{ sort?, pin?, group? }` controls sections |
2806
+ | `aggregate` | `AggregateName \| (values, rows) => value` | — | Total this column over each group row, and over the footer. See below |
2807
+ | `AggregateCell` | `({ cell }) => ReactNode` | — | Renders the aggregate. `cell`: `{ value, column, rows, scope }`, `scope` being `'group'` or `'footer'` |
2808
+ | `editable` | `boolean \| (row) => boolean` | inherits | Whether this column’s cells can be edited — every row, or the rows a predicate says |
2809
+ | `editor` | `CellEditorType \| CellEditorConfig` | inferred | `text`/`number`/`checkbox`/`select`. Without one it is read off the value in the cell |
2810
+ | `EditCell` | `({ cell }) => ReactNode` | — | An editor of your own, bound to `cell.draft` with `cell.commitEdit()`/`cell.cancelEdit()` |
2811
+ | `exportValue` | `(row: TRow) => value` | the field | What this column writes to an exported file — an export runs no React, so a `Cell` renderer needs it |
2812
+ | `list` | `'title' \| 'kicker' \| 'subtitle' \| 'end' \| 'field' \| 'detail' \| 'hidden'` | inferred | Where the column goes in a list item, on a phone |
2813
+ | `exportFormat` | `string` | — | The number format its cells wear in a workbook, `'#,##0.00'` or `'yyyy-mm-dd'` |
2814
2814
 
2815
2815
  ### Aggregation
2816
2816
 
@@ -3786,15 +3786,16 @@ with `language` and `code`, `rule`, `image`, `tableWrap`, `table`, `row`, `cell`
3786
3786
 
3787
3787
  Where content will be, while it is being fetched.
3788
3788
 
3789
- | Prop | Type | What it does |
3790
- | -------- | ----------- | ---------------------------------------------------------------------------- |
3791
- | `lines` | `number` | How many bars. Default 1; past that the last one is short. |
3792
- | `circle` | `boolean` | One round bar — an avatar. `width` sets its size and the height follows. |
3793
- | `label` | `ReactNode` | Makes it a `role="status"` naming what is on its way. Absent: `aria-hidden`. |
3789
+ | Prop | Type | What it does |
3790
+ | -------- | ----------- | ------------------------------------------------------------------------------------ |
3791
+ | `lines` | `number` | How many bars. Default 1, which fills the skeleton; past that the last one is short. |
3792
+ | `circle` | `boolean` | One round bar — an avatar. `width` sets its size and the height follows. |
3793
+ | `label` | `ReactNode` | Makes it a `role="status"` naming what is on its way. Absent: `aria-hidden`. |
3794
3794
 
3795
3795
  ```tsx
3796
3796
  <Skeleton lines={3} label="Loading orders" />
3797
3797
  <Skeleton circle width={10} />
3798
+ <Skeleton height={40} /> {/* one bar fills it: an image or a chart placeholder */}
3798
3799
  ```
3799
3800
 
3800
3801
  A `label` belongs on the one skeleton standing for a region and not on each bar — a screen of
@@ -3802,7 +3803,7 @@ placeholders each announcing itself is a screen nobody can listen to, and a regi
3802
3803
  with its text is not reliably announced anyway, so what it really buys is words for somebody who lands
3803
3804
  there. The gloss is a named duration in milliseconds, so it sits outside what `--transitionTime` zeroes
3804
3805
  and stops itself under `prefers-reduced-motion`. It renders on a server. Tree: `skeleton` (+ `bar` with
3805
- `short` and `circle` variants, `gloss`).
3806
+ `short`, `circle` and `fill` variants, `gloss`).
3806
3807
 
3807
3808
  ## The catalog (`@box-kite/react/catalog`)
3808
3809
 
@@ -1263,7 +1263,7 @@ import Textbox from '@box-kite/react/components/textbox';
1263
1263
  <Flex d="column" gap={2} md={{ d: 'row', gap: 4 }}>{children}</Flex>
1264
1264
 
1265
1265
  // Grid
1266
- <Grid gridCols={3} gap={4}>{items.map(i => <Box key={i.id}>{i.content}</Box>)}</Grid>
1266
+ <Grid gridTemplateColumns={3} gap={4}>{items.map(i => <Box key={i.id}>{i.content}</Box>)}</Grid>
1267
1267
 
1268
1268
  // Card
1269
1269
  <Box p={4} bgColor="white" borderRadius={8} shadow="medium">{content}</Box>
@@ -1521,16 +1521,16 @@ the association needs no `htmlFor`/`id` pair and the whole row is a click target
1521
1521
  nothing wraps the input — the markup is what it always was. `labelProps` styles that `<label>`;
1522
1522
  every other Box prop styles the control itself.
1523
1523
 
1524
- | Component | Prop | What it does |
1525
- | ------------ | ------------------------ | -------------------------------------------------------------------------------------------- |
1526
- | all three | `label` / `labelProps` | The wrapping `<label>` and its styles. |
1527
- | `Checkbox` | `indeterminate` | Sets the DOM property **and** `aria-checked="mixed"`, which is what is announced. |
1528
- | `Switch` | — | `role="switch"` over the same input; Space **and** Enter toggle, Enter does not submit. |
1529
- | `RadioGroup` | `label` | `role="radiogroup"` named by it — a set of radios with nothing over it is a flat list. |
1530
- | `RadioGroup` | `name` | The field every item submits under. Generated when left out. |
1531
- | `RadioGroup` | `value` / `defaultValue` | The selected item's value (a string — the platform's own model for a radio). |
1532
- | `RadioGroup` | `onValueChange` | `(value, { reason, event })` — `click` or `keyboard`. `onChange` is the deprecated spelling. |
1533
- | `RadioGroup` | `orientation` | `vertical` (default) or `horizontal`. Both arrow pairs navigate either way. |
1524
+ | Component | Prop | What it does |
1525
+ | ------------ | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
1526
+ | all three | `label` / `labelProps` | The wrapping `<label>` and its styles. |
1527
+ | `Checkbox` | `indeterminate` | Sets the DOM property **and** `aria-checked="mixed"`, which is what is announced. |
1528
+ | `Switch` | — | `role="switch"` over the same input; Space **and** Enter toggle, Enter does not submit. |
1529
+ | `RadioGroup` | `label` | `role="radiogroup"` named by it — a set of radios with nothing over it is a flat list. |
1530
+ | `RadioGroup` | `name` | The field every item submits under. Generated when left out. |
1531
+ | `RadioGroup` | `value` / `defaultValue` | The selected item's value (a string — the platform's own model for a radio). |
1532
+ | `RadioGroup` | `onValueChange` | `(value, { reason, event })` — `click` or `keyboard`. `onChange` is the deprecated spelling. |
1533
+ | `RadioGroup` | `orientation` | `vertical` (default) or `horizontal`, which wraps and keeps the label on a line of its own above the radios. Both arrow pairs navigate either way. |
1534
1534
 
1535
1535
  Arrow keys move **and select** inside a group, wrapping at both ends and skipping disabled items;
1536
1536
  Tab enters the group once and leaves it once, because a native radio set is already a single tab
@@ -2790,27 +2790,27 @@ named ones carry the reason.
2790
2790
 
2791
2791
  ### ColumnType
2792
2792
 
2793
- | Prop | Type | Default | Description |
2794
- | ------------------------ | ------------------------------------------------------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
2795
- | `key` | `Key` | required | Column identifier (maps to TRow property) |
2796
- | `header` | `string` | — | Header text |
2797
- | `width` | `number` | `200` | Base width in px |
2798
- | `align` | `'start' \| 'end' \| 'center' \| 'left' \| 'right'` | `'left'` | Cell alignment. `start`/`end` follow the reading order; `left`/`right` stay on the screen side they name |
2799
- | `pin` | `'START' \| 'END'` (also `'LEFT'`/`'RIGHT'`) | — | Pin to an edge of the **inline axis** (sticky on scroll), so it holds under either `dir`. `LEFT`/`RIGHT` are the older spelling of the same two |
2800
- | `columns` | `ColumnType[]` | — | Nested columns (grouped header) |
2801
- | `Cell` | `({ cell }) => ReactNode` | — | Custom renderer. `cell`: `{ value, row, column, grid }`. It redraws when its row changes or the grid does — not when another row is selected |
2802
- | `sortable` / `resizable` | `boolean` | inherits | Override grid-level setting |
2803
- | `flexible` | `boolean` | `true` | Participate in flex width distribution |
2804
- | `filterable` | `boolean \| FilterConfig` | — | `true` (text), `{ type: 'number', min?, max? }`, `{ type: 'multiselect', options? }` |
2805
- | `contextMenu` | `boolean \| ContextMenuConfig` | inherits | Override grid-level context menu. `false` hides entirely. `{ sort?, pin?, group? }` controls sections |
2806
- | `aggregate` | `AggregateName \| (values, rows) => value` | — | Total this column over each group row, and over the footer. See below |
2807
- | `AggregateCell` | `({ cell }) => ReactNode` | — | Renders the aggregate. `cell`: `{ value, column, rows, scope }`, `scope` being `'group'` or `'footer'` |
2808
- | `editable` | `boolean \| (row) => boolean` | inherits | Whether this column’s cells can be edited — every row, or the rows a predicate says |
2809
- | `editor` | `CellEditorType \| CellEditorConfig` | inferred | `text`/`number`/`checkbox`/`select`. Without one it is read off the value in the cell |
2810
- | `EditCell` | `({ cell }) => ReactNode` | — | An editor of your own, bound to `cell.draft` with `cell.commitEdit()`/`cell.cancelEdit()` |
2811
- | `exportValue` | `(row: TRow) => value` | the field | What this column writes to an exported file — an export runs no React, so a `Cell` renderer needs it |
2812
- | `list` | `'title' \| 'kicker' \| 'subtitle' \| 'end' \| 'field' \| 'detail' \| 'hidden'` | inferred | Where the column goes in a list item, on a phone |
2813
- | `exportFormat` | `string` | — | The number format its cells wear in a workbook, `'#,##0.00'` or `'yyyy-mm-dd'` |
2793
+ | Prop | Type | Default | Description |
2794
+ | ------------------------ | ------------------------------------------------------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
2795
+ | `key` | `Key` | required | Column identifier (maps to TRow property) |
2796
+ | `header` | `string` | — | Header text |
2797
+ | `width` | `number` | `200` | Base width in px |
2798
+ | `align` | `'start' \| 'end' \| 'center' \| 'left' \| 'right'` | `'left'` | Cell alignment. `start`/`end` follow the reading order; `left`/`right` stay on the screen side they name |
2799
+ | `pin` | `'START' \| 'END'` (also `'LEFT'`/`'RIGHT'`) | — | Pin to an edge of the **inline axis** (sticky on scroll), so it holds under either `dir`. `LEFT`/`RIGHT` are the older spelling of the same two |
2800
+ | `columns` | `ColumnType[]` | — | Nested columns (grouped header) |
2801
+ | `Cell` | `({ cell }) => ReactNode` | — | Custom renderer. `cell`: `{ value, row, column, grid }`. It fills the cell **edge to edge, with no padding** — the built-in text pads itself `px={3}`, so text of your own does the same. It redraws when its row changes or the grid does — not when another row is selected |
2802
+ | `sortable` / `resizable` | `boolean` | inherits | Override grid-level setting |
2803
+ | `flexible` | `boolean` | `true` | Participate in flex width distribution |
2804
+ | `filterable` | `boolean \| FilterConfig` | — | `true` (text), `{ type: 'number', min?, max? }`, `{ type: 'multiselect', options? }` |
2805
+ | `contextMenu` | `boolean \| ContextMenuConfig` | inherits | Override grid-level context menu. `false` hides entirely. `{ sort?, pin?, group? }` controls sections |
2806
+ | `aggregate` | `AggregateName \| (values, rows) => value` | — | Total this column over each group row, and over the footer. See below |
2807
+ | `AggregateCell` | `({ cell }) => ReactNode` | — | Renders the aggregate. `cell`: `{ value, column, rows, scope }`, `scope` being `'group'` or `'footer'` |
2808
+ | `editable` | `boolean \| (row) => boolean` | inherits | Whether this column’s cells can be edited — every row, or the rows a predicate says |
2809
+ | `editor` | `CellEditorType \| CellEditorConfig` | inferred | `text`/`number`/`checkbox`/`select`. Without one it is read off the value in the cell |
2810
+ | `EditCell` | `({ cell }) => ReactNode` | — | An editor of your own, bound to `cell.draft` with `cell.commitEdit()`/`cell.cancelEdit()` |
2811
+ | `exportValue` | `(row: TRow) => value` | the field | What this column writes to an exported file — an export runs no React, so a `Cell` renderer needs it |
2812
+ | `list` | `'title' \| 'kicker' \| 'subtitle' \| 'end' \| 'field' \| 'detail' \| 'hidden'` | inferred | Where the column goes in a list item, on a phone |
2813
+ | `exportFormat` | `string` | — | The number format its cells wear in a workbook, `'#,##0.00'` or `'yyyy-mm-dd'` |
2814
2814
 
2815
2815
  ### Aggregation
2816
2816
 
@@ -3786,15 +3786,16 @@ with `language` and `code`, `rule`, `image`, `tableWrap`, `table`, `row`, `cell`
3786
3786
 
3787
3787
  Where content will be, while it is being fetched.
3788
3788
 
3789
- | Prop | Type | What it does |
3790
- | -------- | ----------- | ---------------------------------------------------------------------------- |
3791
- | `lines` | `number` | How many bars. Default 1; past that the last one is short. |
3792
- | `circle` | `boolean` | One round bar — an avatar. `width` sets its size and the height follows. |
3793
- | `label` | `ReactNode` | Makes it a `role="status"` naming what is on its way. Absent: `aria-hidden`. |
3789
+ | Prop | Type | What it does |
3790
+ | -------- | ----------- | ------------------------------------------------------------------------------------ |
3791
+ | `lines` | `number` | How many bars. Default 1, which fills the skeleton; past that the last one is short. |
3792
+ | `circle` | `boolean` | One round bar — an avatar. `width` sets its size and the height follows. |
3793
+ | `label` | `ReactNode` | Makes it a `role="status"` naming what is on its way. Absent: `aria-hidden`. |
3794
3794
 
3795
3795
  ```tsx
3796
3796
  <Skeleton lines={3} label="Loading orders" />
3797
3797
  <Skeleton circle width={10} />
3798
+ <Skeleton height={40} /> {/* one bar fills it: an image or a chart placeholder */}
3798
3799
  ```
3799
3800
 
3800
3801
  A `label` belongs on the one skeleton standing for a region and not on each bar — a screen of
@@ -3802,7 +3803,7 @@ placeholders each announcing itself is a screen nobody can listen to, and a regi
3802
3803
  with its text is not reliably announced anyway, so what it really buys is words for somebody who lands
3803
3804
  there. The gloss is a named duration in milliseconds, so it sits outside what `--transitionTime` zeroes
3804
3805
  and stops itself under `prefers-reduced-motion`. It renders on a server. Tree: `skeleton` (+ `bar` with
3805
- `short` and `circle` variants, `gloss`).
3806
+ `short`, `circle` and `fill` variants, `gloss`).
3806
3807
 
3807
3808
  ## The catalog (`@box-kite/react/catalog`)
3808
3809