@box-kite/react 2.3.0 → 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.
- package/.claude/rules/box-kite-rules.md +58 -92
- package/.claude/skills/box-kite/SKILL.md +81 -114
- package/.claude/skills/box-kite/references/components.md +1 -1
- package/.claude/skills/box-kite/references/patterns.md +1 -1
- package/.claude/skills/box-kite/references/rules.md +115 -0
- package/.claude/skills/box-kite/references/styling.md +2 -2
- package/.cursor/rules/box-kite.mdc +61 -95
- package/AGENTS.md +62 -96
- package/BOX_AI_CONTEXT.md +82 -78
- package/BOX_KITE_AI_CONTEXT.md +82 -78
- package/README.md +201 -716
- package/catalog.cjs +1 -1
- package/catalog.mjs +3 -0
- package/client.cjs +1 -1
- package/client.mjs +81 -81
- package/components/combobox/comboboxListbox.d.ts +2 -1
- package/components/combobox.cjs +1 -1
- package/components/combobox.d.ts +1 -1
- package/components/combobox.mjs +199 -188
- package/components/dataGrid/components/dataGridFooter.d.ts +6 -2
- package/components/dataGrid/contracts/dataGridContract.d.ts +2 -1
- package/components/dataGrid/models/gridModel.d.ts +21 -2
- package/components/dataGrid/models/groupRowModel.d.ts +1 -1
- package/components/dataGrid/models/rowModel.d.ts +1 -1
- package/components/dataGrid/models/sourceGroupRowModel.d.ts +5 -1
- package/components/dataGrid/models/sourceRowModel.d.ts +5 -1
- package/components/dataGrid/useListLayout.d.ts +1 -1
- package/components/dataGrid.cjs +3 -3
- package/components/dataGrid.mjs +732 -682
- package/components/radioGroup.cjs +1 -1
- package/components/radioGroup.mjs +1 -0
- package/components/semantics.d.ts +29 -29
- package/components/skeleton.cjs +1 -1
- package/components/skeleton.d.ts +1 -1
- package/components/skeleton.mjs +2 -1
- package/components/sortableList.cjs +1 -1
- package/components/sortableList.mjs +1 -1
- package/components/svg.d.ts +2 -2
- package/components/swipeItem.cjs +1 -1
- package/components/swipeItem.mjs +1 -1
- package/components/textarea.d.ts +1 -1
- package/components/textbox.d.ts +1 -1
- package/components/timeZoneSelect.d.ts +1 -1
- package/components/toaster.cjs +1 -1
- package/components/toaster.mjs +13 -14
- package/dataGridList.cjs +1 -1
- package/dataGridList.mjs +3 -5
- package/docs/a11y.md +1 -2
- package/docs/index.md +1 -1
- package/docs/props.md +43 -19
- package/effects.cjs +1 -1
- package/effects.mjs +2 -2
- package/identity.cjs +1 -1
- package/identity.mjs +5 -7
- package/package.json +12 -12
- package/react/effects.d.ts +5 -6
- package/react/identity/useIdentifier.d.ts +0 -3
package/BOX_KITE_AI_CONTEXT.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @box-kite/react - AI Assistant Context
|
|
2
2
|
|
|
3
|
-
Runtime CSS-in-JS library. `Box` component accepts
|
|
3
|
+
Runtime CSS-in-JS library. `Box` component accepts CSS properties as typed props and generates CSS classes at runtime. Same prop values share a single class.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -191,7 +191,7 @@ All sizing, spacing, and positioning props also accept percentage strings: `p="5
|
|
|
191
191
|
| `fieldSizing` | field-sizing | `'content'` — a control that grows with what is typed into it, no JavaScript measuring anything — or `'fixed'` |
|
|
192
192
|
| `scrollbarGutter` / `scrollbarWidth` / `scrollbarColor` | scrollbar-gutter / -width / -color | `'stable'` / `'stable both-edges'` reserve the scrollbar's space before there is one, so nothing shifts when content overflows. `scrollbarWidth`: `'auto'`/`'thin'`/`'none'`; `scrollbarColor`: `[thumb, track]`, each a token, a `Box.extend()` colour or either with `/50` |
|
|
193
193
|
| `willChange` | will-change | `'transform'`, `'opacity'`, `'filter'`, `'scroll-position'`, `'contents'`, `'auto'`. A hint with a real cost (a promoted layer holds memory), so it belongs on the few elements that animate, not on a list |
|
|
194
|
-
| `cursor` / `pointerEvents` / `userSelect`
|
|
194
|
+
| `cursor` / `pointerEvents` / `userSelect` / `touchAction` | misc | string values. For `transition`, `animation` and the transform props see _Animation and transitions_ below |
|
|
195
195
|
|
|
196
196
|
### Anchor positioning — a floating layer with no JavaScript
|
|
197
197
|
|
|
@@ -468,26 +468,27 @@ one, nested wherever a prop nests, rendered on a server.
|
|
|
468
468
|
|
|
469
469
|
Twenty-three SVG properties, on any Box, plus twenty element components in `components/svg` — `Svg`, `G`, `Defs`, `Path`, `Circle`, `Ellipse`, `Rect`, `Line`, `Polyline`, `Polygon`, `SvgText`, `TSpan`, `LinearGradient`, `RadialGradient`, `Stop`, `ClipPath`, `Mask`, `Use`, `SvgSymbol`, `Marker`. **Never `<Box tag="path">`.** For an icon from somebody else's set, `<Icon>` (`components/icon`) — see below. (`BaseSvg` is deprecated: it is `Svg` with a 24×24 preset.)
|
|
470
470
|
|
|
471
|
-
| Prop | CSS Property | Accepts
|
|
472
|
-
| ------------------------------- | ----------------------------- |
|
|
473
|
-
| `fill` / `stroke` | fill / stroke | any colour variable, or `'none'`
|
|
474
|
-
| `fillOpacity` / `strokeOpacity` | fill-opacity / stroke-opacity | `0`–`1` in tenths, same scale as `opacity`
|
|
475
|
-
| `fillRule` | fill-rule | `'nonzero'`, `'evenodd'`
|
|
476
|
-
| `strokeWidth` | stroke-width | number, **user units — no divider** (`strokeWidth={2}` → `2`)
|
|
477
|
-
| `strokeLinecap` | stroke-linecap | `'butt'`, `'round'`, `'square'`
|
|
478
|
-
| `strokeLinejoin` | stroke-linejoin | `'miter'`, `'round'`, `'bevel'`
|
|
479
|
-
| `strokeMiterlimit` | stroke-miterlimit | number, 1 or greater
|
|
480
|
-
| `strokeDasharray` | stroke-dasharray | number (`{12}` = dash 12, gap 12)
|
|
481
|
-
| `strokeDashoffset` | stroke-dashoffset | number, or a percentage of the path length (`'40%'`)
|
|
482
|
-
| `paintOrder` | paint-order | `'normal'`, `'fill'
|
|
483
|
-
| `
|
|
484
|
-
| `
|
|
485
|
-
| `
|
|
486
|
-
| `
|
|
487
|
-
| `
|
|
488
|
-
| `
|
|
489
|
-
| `
|
|
490
|
-
| `
|
|
471
|
+
| Prop | CSS Property | Accepts |
|
|
472
|
+
| ------------------------------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
473
|
+
| `fill` / `stroke` | fill / stroke | any colour variable, or `'none'` |
|
|
474
|
+
| `fillOpacity` / `strokeOpacity` | fill-opacity / stroke-opacity | `0`–`1` in tenths, same scale as `opacity` |
|
|
475
|
+
| `fillRule` | fill-rule | `'nonzero'`, `'evenodd'` |
|
|
476
|
+
| `strokeWidth` | stroke-width | number, **user units — no divider** (`strokeWidth={2}` → `2`) |
|
|
477
|
+
| `strokeLinecap` | stroke-linecap | `'butt'`, `'round'`, `'square'` |
|
|
478
|
+
| `strokeLinejoin` | stroke-linejoin | `'miter'`, `'round'`, `'bevel'` |
|
|
479
|
+
| `strokeMiterlimit` | stroke-miterlimit | number, 1 or greater |
|
|
480
|
+
| `strokeDasharray` | stroke-dasharray | number (`{12}` = dash 12, gap 12), the pattern as a string (`"12 4"`), or `'dashed'`/`'dotted'`, which scale with `strokeWidth` |
|
|
481
|
+
| `strokeDashoffset` | stroke-dashoffset | number, or a percentage of the path length (`'40%'`) |
|
|
482
|
+
| `paintOrder` | paint-order | `'normal'`, or up to three of `'fill'`/`'stroke'`/`'markers'` in paint order (`'stroke fill markers'`) |
|
|
483
|
+
| `pointerEvents` | pointer-events | `'none'`, `'auto'`, `'all'`, and which part of a shape takes the press: `'visiblePainted'`, `'visibleFill'`, `'visibleStroke'`, `'visible'`, `'painted'`, `'fill'`, `'stroke'`, `'bounding-box'` (not in Firefox) |
|
|
484
|
+
| `vectorEffect` | vector-effect | `'none'`, `'non-scaling-stroke'` |
|
|
485
|
+
| `shapeRendering` | shape-rendering | `'auto'`, `'optimizeSpeed'`, `'crispEdges'`, `'geometricPrecision'` |
|
|
486
|
+
| `textAnchor` | text-anchor | `'start'`, `'middle'`, `'end'` — which part of a label sits on its `x` |
|
|
487
|
+
| `dominantBaseline` | dominant-baseline | `'auto'`, `'alphabetic'`, `'central'`, `'middle'`, `'hanging'`, `'text-top'`, `'text-bottom'`, `'ideographic'`, `'mathematical'` |
|
|
488
|
+
| `cx` / `cy` | cx / cy | number in user units, or a percentage — `<circle>`, `<ellipse>` |
|
|
489
|
+
| `r` | r | number in user units, or a percentage — `<circle>` |
|
|
490
|
+
| `rx` / `ry` | rx / ry | number, a percentage, or `'auto'` — `<ellipse>` radii, `<rect>` corners |
|
|
491
|
+
| `x` / `y` | x / y | number in user units, or a percentage — `<rect>`, `<image>`, `<use>`, `<foreignObject>`, nested `<svg>`. NOT `<text>` |
|
|
491
492
|
|
|
492
493
|
```tsx
|
|
493
494
|
import { Circle, Path, Rect, Svg, SvgText } from '@box-kite/react/components/svg';
|
|
@@ -515,17 +516,18 @@ import { Circle, Path, Rect, Svg, SvgText } from '@box-kite/react/components/svg
|
|
|
515
516
|
<Rect x={16} y={32} width={24} height={64} rx={3} fill="sky-600" />
|
|
516
517
|
```
|
|
517
518
|
|
|
518
|
-
**
|
|
519
|
+
**Ten things to get right:**
|
|
519
520
|
|
|
520
|
-
1. **No divider on SVG lengths.** `strokeWidth`, `strokeDasharray`, `strokeDashoffset` and `strokeMiterlimit` pass the number through unchanged — they are measured in the coordinate system the `viewBox` sets up.
|
|
521
|
+
1. **No divider on SVG lengths.** `strokeWidth`, `strokeDasharray`, `strokeDashoffset` and `strokeMiterlimit` pass the number through unchanged — they are measured in the coordinate system the `viewBox` sets up. The geometry props (`cx`/`cy`/`r`/`rx`/`ry`/`x`/`y`) write that number as `px` — a user unit in SVG — because Firefox and Safari drop a bare number in them.
|
|
521
522
|
2. **Inheritance does the work.** Put `fill`/`stroke`/`strokeWidth` on the `<svg>`, not on every shape. The exception is a shape carrying its own `fill=` attribute — a presentation attribute on an element beats a value inherited from its parent, so style that shape directly.
|
|
522
523
|
3. **`vectorEffect` and `dominantBaseline` are not inherited**, so their rules target the element _and_ its descendants (`.cls, .cls *`). `vectorEffect="non-scaling-stroke"` on the `<svg>` keeps a hairline one pixel wide at any scale; `dominantBaseline="central"` on the `<svg>` reaches every label inside it.
|
|
523
524
|
4. **Geometry belongs to the shape, and it transitions.** `cx`/`cy`/`r`/`rx`/`ry`/`x`/`y` are real CSS in SVG 2, so a gauge or a growing bar is a pseudo-class and no JavaScript. They are not inherited and should not be — set them on the shape.
|
|
524
|
-
5. **Each component settles the names SVG and Box both use, for its own element.** On `Path`, `d` is path data (not `flexDirection`); on `Rect`, `width`/`height` are user units (not the ÷4 layout scale); on `SvgText` and `TSpan`, `x`/`y`/`dx`/`dy` are attributes, because the CSS geometry properties do not apply to text; on `RadialGradient`, `cx`/`cy`/`r` are attributes, because they do not apply to a gradient either — while on `Circle` the same names stay CSS and transition. `transform` is a prop on every shape and group (`transform="rotate(-90 48 48)"`
|
|
525
|
+
5. **Each component settles the names SVG and Box both use, for its own element.** On `Path`, `d` is path data (not `flexDirection`); on `Rect`, `width`/`height` are user units (not the ÷4 layout scale); on `SvgText` and `TSpan`, `x`/`y`/`dx`/`dy` are attributes, because the CSS geometry properties do not apply to text; on `RadialGradient`, `cx`/`cy`/`r` are attributes, because they do not apply to a gradient either — while on `Circle` the same names stay CSS and transition. `transform` is a prop on every shape and group, for a matrix or an angle that is data (`transform="rotate(-90 48 48)"`); a fixed turn about the shape's own centre is CSS (item 10).
|
|
525
526
|
6. **`Svg` sizes with attributes and names itself with `label`.** `viewBox`, `preserveAspectRatio`, `width` and `height` are the SVG attributes (`width="100%"`, `width={200}`), so the ÷4 layout `width`/`height` are not available on it. No `label` means `aria-hidden` — decoration, which is what most SVG is; `label` makes it `role="img"` with that name. A role or `aria-*` of your own in `props` wins over both.
|
|
526
527
|
7. **An icon from a set is not SVG you draw — it is `<Icon>`.** `<Icon size={5} color="amber-500" label="Sunny"><Sun /></Icon>` from `components/icon`, wrapping one element from lucide, Tabler, react-icons, or a raw `<svg>`. `size` is the ÷4 scale (`size={6}` is 24px, the default) and lands in the _class_, where a CSS declaration outranks the `width`/`height` attributes the icon set writes — which is why `Icon` needs to know no set's API. `strokeWidth` is the same: an ordinary Box prop, so it can change on hover. No `label` means `aria-hidden`; a `label` means `role="img"`. **Reach for `Svg` rather than wrapping one in `Icon`** — `Svg` takes these props directly. (Wrapping one does work: `Icon` asks the child which convention it follows and routes `role`/`aria-label` into `props` for a component of ours. It is still a layer nobody needs.)
|
|
527
528
|
8. **A paint server is a value, not an attribute.** `fill`, `stroke` and `clipPath` take `url(#id)` (a `<LinearGradient>`, a pattern, a `<ClipPath>` the document defines) and `var(--name)` (a variable somebody else declared) beside the colour tokens — so `fill="url(#sky)"` and `clipPath="url(#frame)"`, and both can differ per theme, on `hover` and per breakpoint. Only those two shapes are accepted: anything else emits no rule at all rather than a broken declaration. A gradient stop is still themed the same way — `<Stop stopColor="currentColor" color="amber-300" />`.
|
|
528
529
|
9. **An icon outside lucide comes through the same `<Icon>`.** Iconify carries 300,000+ icons in 200-plus sets, and the choice is only about _when_ the icon becomes markup. One icon: copy its SVG and paste it into an `<Icon>` — no dependency, renders on a server. A set: `unplugin-icons` compiles `~icons/<set>/<name>` into a component at build time from an `@iconify-json/<set>` devDependency (`npm i -D unplugin-icons @iconify-json/<set> @svgr/core @svgr/plugin-jsx`, the plugin with `{ compiler: 'jsx', jsx: 'react' }`, and `/// <reference types="unplugin-icons/types/react" />` in a `.d.ts`) — nothing fetched at runtime, server-renders. A name that is data (from a CMS, from a user): `@iconify/react`'s `<Icon icon="set:name"/>` inside our `<Icon>` — it fetches in the browser, so it is a client component and the server sends no icon. **Turbopack runs no unplugin**, so under Next.js 16 the build-time recipe needs `next build --webpack`; the other two work as they are.
|
|
530
|
+
10. **A shape turns about the viewBox's corner unless told otherwise.** An SVG element's `transform-box` is `view-box`, so `rotate={45}` alone swings a shape round `0 0`. `<G rotate={45} transformBox="fill-box" transformOrigin="center">` turns it about its own centre (measured in Chrome, Firefox and WebKit). `transformOrigin` takes a keyword (`'center'`, `'top left'`), a fraction or a percentage, a number on the ÷4 scale, or two or three positions as CSS writes them (`'48px 48px'` — in SVG a px is a user unit). An edge you can press is `pointerEvents="visibleStroke"` over a wide transparent stroke, and a drag on a touch screen needs `touchAction="none"` on the element pressed, or the page pans instead.
|
|
529
531
|
|
|
530
532
|
---
|
|
531
533
|
|
|
@@ -534,20 +536,21 @@ import { Circle, Path, Rect, Svg, SvgText } from '@box-kite/react/components/svg
|
|
|
534
536
|
Every Box already transitions `all` its properties over `--transitionTime` (0.25s), which is why a
|
|
535
537
|
`hover` colour fades without being asked. On top of that:
|
|
536
538
|
|
|
537
|
-
| Prop | CSS Property
|
|
538
|
-
| ----------------------------------------------------------------- |
|
|
539
|
-
| `animation` | animation
|
|
540
|
-
| `animationName` | animation-name
|
|
541
|
-
| `animationDuration` / `animationDelay` | ms
|
|
542
|
-
| `animationIterationCount` | number
|
|
543
|
-
| `animationDirection` / `animationFillMode` / `animationPlayState` | keywords
|
|
544
|
-
| `animationTimingFunction` / `transitionTimingFunction` | timing function
|
|
545
|
-
| `transition` | transition-property
|
|
546
|
-
| `transitionDuration` / `transitionDelay` | ms
|
|
547
|
-
| `transitionBehavior` | transition-behavior
|
|
548
|
-
| `interpolateSize` | interpolate-size
|
|
549
|
-
| `startingStyle` | `@starting-style`
|
|
550
|
-
| `translateX` / `translateY` / `rotate` / `scale` / `flip` | transform longhands
|
|
539
|
+
| Prop | CSS Property | Notes |
|
|
540
|
+
| ----------------------------------------------------------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
541
|
+
| `animation` | animation | One of four presets: `'spin'`, `'pulse'`, `'bounce'`, `'ping'`, or `'none'`. Keyframes come with the engine |
|
|
542
|
+
| `animationName` | animation-name | A sequence registered with `Box.keyframes()`, a preset name, or a name from any stylesheet |
|
|
543
|
+
| `animationDuration` / `animationDelay` | ms | **Milliseconds, no divider**: `animationDuration={1100}` → `1100ms` |
|
|
544
|
+
| `animationIterationCount` | number | A number or `'infinite'` |
|
|
545
|
+
| `animationDirection` / `animationFillMode` / `animationPlayState` | keywords | `'normal'`/`'reverse'`/`'alternate'`/`'alternate-reverse'`; `'none'`/`'forwards'`/`'backwards'`/`'both'`; `'running'`/`'paused'` |
|
|
546
|
+
| `animationTimingFunction` / `transitionTimingFunction` | timing function | Keywords, the four springs (`'spring'`, `'spring-gentle'`, `'spring-bouncy'`, `'spring-snappy'`), or a curve: `'cubic-bezier(0.4, 0, 0.6, 1)'`, `'steps(4, end)'`, `'linear(0, 0.5, 1)'` |
|
|
547
|
+
| `transition` | transition-property | `'all'`, `'none'`, or a group: `'colors'`, `'opacity'`, `'shadow'`, `'transform'`, `'size'`, `'filter'` |
|
|
548
|
+
| `transitionDuration` / `transitionDelay` | ms | Milliseconds, same as the animation pair. Both duration props also take a spring name — that spring's settling time |
|
|
549
|
+
| `transitionBehavior` | transition-behavior | `'normal'` or `'allow-discrete'`, which lets `display`, `overlay` and `content-visibility` transition — the property that makes an element animate _out_ without unmounting |
|
|
550
|
+
| `interpolateSize` | interpolate-size | `'numeric-only'` or `'allow-keywords'`, which is what makes `height: auto` animate. Inherited, so it belongs on a container. Chromium-only; elsewhere the size snaps |
|
|
551
|
+
| `startingStyle` | `@starting-style` | A nested block of plain props: what they start from the first time the element is styled. `startingStyle={{ opacity: 0, translateY: 2 }}` is an entrance with no JavaScript |
|
|
552
|
+
| `translateX` / `translateY` / `rotate` / `scale` / `flip` | transform longhands | Each writes its own CSS property, so they compose. `scale={1.05}` is unitless; `rotate={45}` is degrees |
|
|
553
|
+
| `transformOrigin` / `transformBox` | transform-origin / transform-box | The point `rotate`/`scale` turn about (`'center'`, `'top left'`, `'1/2 1/4'`, `'48px 48px'`, a ÷4 number) and the box it is measured in (`'fill-box'` for an SVG shape's own) |
|
|
551
554
|
|
|
552
555
|
```tsx
|
|
553
556
|
// A preset: no registration, and it stops under prefers-reduced-motion on its own
|
|
@@ -1260,7 +1263,7 @@ import Textbox from '@box-kite/react/components/textbox';
|
|
|
1260
1263
|
<Flex d="column" gap={2} md={{ d: 'row', gap: 4 }}>{children}</Flex>
|
|
1261
1264
|
|
|
1262
1265
|
// Grid
|
|
1263
|
-
<Grid
|
|
1266
|
+
<Grid gridTemplateColumns={3} gap={4}>{items.map(i => <Box key={i.id}>{i.content}</Box>)}</Grid>
|
|
1264
1267
|
|
|
1265
1268
|
// Card
|
|
1266
1269
|
<Box p={4} bgColor="white" borderRadius={8} shadow="medium">{content}</Box>
|
|
@@ -1518,16 +1521,16 @@ the association needs no `htmlFor`/`id` pair and the whole row is a click target
|
|
|
1518
1521
|
nothing wraps the input — the markup is what it always was. `labelProps` styles that `<label>`;
|
|
1519
1522
|
every other Box prop styles the control itself.
|
|
1520
1523
|
|
|
1521
|
-
| Component | Prop | What it does
|
|
1522
|
-
| ------------ | ------------------------ |
|
|
1523
|
-
| all three | `label` / `labelProps` | The wrapping `<label>` and its styles.
|
|
1524
|
-
| `Checkbox` | `indeterminate` | Sets the DOM property **and** `aria-checked="mixed"`, which is what is announced.
|
|
1525
|
-
| `Switch` | — | `role="switch"` over the same input; Space **and** Enter toggle, Enter does not submit.
|
|
1526
|
-
| `RadioGroup` | `label` | `role="radiogroup"` named by it — a set of radios with nothing over it is a flat list.
|
|
1527
|
-
| `RadioGroup` | `name` | The field every item submits under. Generated when left out.
|
|
1528
|
-
| `RadioGroup` | `value` / `defaultValue` | The selected item's value (a string — the platform's own model for a radio).
|
|
1529
|
-
| `RadioGroup` | `onValueChange` | `(value, { reason, event })` — `click` or `keyboard`. `onChange` is the deprecated spelling.
|
|
1530
|
-
| `RadioGroup` | `orientation` | `vertical` (default) or `horizontal
|
|
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. |
|
|
1531
1534
|
|
|
1532
1535
|
Arrow keys move **and select** inside a group, wrapping at both ends and skipping disabled items;
|
|
1533
1536
|
Tab enters the group once and leaves it once, because a native radio set is already a single tab
|
|
@@ -2787,27 +2790,27 @@ named ones carry the reason.
|
|
|
2787
2790
|
|
|
2788
2791
|
### ColumnType
|
|
2789
2792
|
|
|
2790
|
-
| Prop | Type | Default | Description
|
|
2791
|
-
| ------------------------ | ------------------------------------------------------------------------------- | --------- |
|
|
2792
|
-
| `key` | `Key` | required | Column identifier (maps to TRow property)
|
|
2793
|
-
| `header` | `string` | — | Header text
|
|
2794
|
-
| `width` | `number` | `200` | Base width in px
|
|
2795
|
-
| `align` | `'start' \| 'end' \| 'center' \| 'left' \| 'right'` | `'left'` | Cell alignment. `start`/`end` follow the reading order; `left`/`right` stay on the screen side they name
|
|
2796
|
-
| `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
|
|
2797
|
-
| `columns` | `ColumnType[]` | — | Nested columns (grouped header)
|
|
2798
|
-
| `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
|
|
2799
|
-
| `sortable` / `resizable` | `boolean` | inherits | Override grid-level setting
|
|
2800
|
-
| `flexible` | `boolean` | `true` | Participate in flex width distribution
|
|
2801
|
-
| `filterable` | `boolean \| FilterConfig` | — | `true` (text), `{ type: 'number', min?, max? }`, `{ type: 'multiselect', options? }`
|
|
2802
|
-
| `contextMenu` | `boolean \| ContextMenuConfig` | inherits | Override grid-level context menu. `false` hides entirely. `{ sort?, pin?, group? }` controls sections
|
|
2803
|
-
| `aggregate` | `AggregateName \| (values, rows) => value` | — | Total this column over each group row, and over the footer. See below
|
|
2804
|
-
| `AggregateCell` | `({ cell }) => ReactNode` | — | Renders the aggregate. `cell`: `{ value, column, rows, scope }`, `scope` being `'group'` or `'footer'`
|
|
2805
|
-
| `editable` | `boolean \| (row) => boolean` | inherits | Whether this column’s cells can be edited — every row, or the rows a predicate says
|
|
2806
|
-
| `editor` | `CellEditorType \| CellEditorConfig` | inferred | `text`/`number`/`checkbox`/`select`. Without one it is read off the value in the cell
|
|
2807
|
-
| `EditCell` | `({ cell }) => ReactNode` | — | An editor of your own, bound to `cell.draft` with `cell.commitEdit()`/`cell.cancelEdit()`
|
|
2808
|
-
| `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
|
|
2809
|
-
| `list` | `'title' \| 'kicker' \| 'subtitle' \| 'end' \| 'field' \| 'detail' \| 'hidden'` | inferred | Where the column goes in a list item, on a phone
|
|
2810
|
-
| `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'` |
|
|
2811
2814
|
|
|
2812
2815
|
### Aggregation
|
|
2813
2816
|
|
|
@@ -3783,15 +3786,16 @@ with `language` and `code`, `rule`, `image`, `tableWrap`, `table`, `row`, `cell`
|
|
|
3783
3786
|
|
|
3784
3787
|
Where content will be, while it is being fetched.
|
|
3785
3788
|
|
|
3786
|
-
| Prop | Type | What it does
|
|
3787
|
-
| -------- | ----------- |
|
|
3788
|
-
| `lines` | `number` | How many bars. Default 1; past that the last one is short.
|
|
3789
|
-
| `circle` | `boolean` | One round bar — an avatar. `width` sets its size and the height follows.
|
|
3790
|
-
| `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`. |
|
|
3791
3794
|
|
|
3792
3795
|
```tsx
|
|
3793
3796
|
<Skeleton lines={3} label="Loading orders" />
|
|
3794
3797
|
<Skeleton circle width={10} />
|
|
3798
|
+
<Skeleton height={40} /> {/* one bar fills it: an image or a chart placeholder */}
|
|
3795
3799
|
```
|
|
3796
3800
|
|
|
3797
3801
|
A `label` belongs on the one skeleton standing for a region and not on each bar — a screen of
|
|
@@ -3799,7 +3803,7 @@ placeholders each announcing itself is a screen nobody can listen to, and a regi
|
|
|
3799
3803
|
with its text is not reliably announced anyway, so what it really buys is words for somebody who lands
|
|
3800
3804
|
there. The gloss is a named duration in milliseconds, so it sits outside what `--transitionTime` zeroes
|
|
3801
3805
|
and stops itself under `prefers-reduced-motion`. It renders on a server. Tree: `skeleton` (+ `bar` with
|
|
3802
|
-
`short` and `
|
|
3806
|
+
`short`, `circle` and `fill` variants, `gloss`).
|
|
3803
3807
|
|
|
3804
3808
|
## The catalog (`@box-kite/react/catalog`)
|
|
3805
3809
|
|
|
@@ -3830,7 +3834,7 @@ allowed.tokens; // the colours, the @keyframes names and the style-tree nodes a
|
|
|
3830
3834
|
`DataGrid`'s `def` (required — the columns and the grid-wide flags) and `data`, `DashboardGrid`'s
|
|
3831
3835
|
`layout`/`defaultLayout`/`columns`, `Widget`'s `empty`, `ChartContainer`'s `series`. A column's nested
|
|
3832
3836
|
`columns`, and `dataSource`/`onCellEdit`/`rowDetail`/`treeData`, stay out — they are the app's to pass.
|
|
3833
|
-
- **The allow-list is the app's.** `catalog()` with no options is
|
|
3837
|
+
- **The allow-list is the app's.** `catalog()` with no options is every component and every prop —
|
|
3834
3838
|
~4.6 MB serialized. `include`, `exclude` and `styleProps` are how an app narrows it.
|
|
3835
3839
|
|
|
3836
3840
|
Full reference: `docs/catalog.md`.
|