# Box Kite 2.2.16

_Box Kite 2.2.17 · a markdown copy of https://www.box-kite.dev/releases/2.2.16/_

_2 November 2026 · [npm](https://www.npmjs.com/package/@box-kite/react) · [Compare v2.2.15...v2.2.16](https://github.com/box-kite/box-kite/compare/v2.2.15...v2.2.16)_

The published types are whole again, so a misspelt component, variant or value is a type error rather than `any` — and a `ref` on `Form` and fourteen other components no longer breaks them on React 19.

## Breaking changes

None.

## Fixes

- **From 2.2.6 to 2.2.15 `@box-kite/core` shipped without `core/extends/boxComponents.d.ts`, so the built-in components typed as `any`.** Six of its declaration files import that one, and with `skipLibCheck: true` (every Vite and Next template) the missing file was silent: `<Box component="cardd" />`, `<Box component="button" variant="nonsense" />` and a misspelt value inside a `Box.components()` entry all type-checked. The file is back, at a seventh of its old size, so **an app that compiled on 2.2.15 may now report errors** — each one is a component name, a variant or a value that never rendered anything, and the fix is the one the message names. `BoxComponentStyles` is an interface now rather than a type alias, which is what lets a declaration name it instead of writing out every prop at every use.
- **Five `@box-kite/react` declaration files reached into `@box-kite/core` by a relative path the package does not contain.** `react/componentsContext.d.ts`, three DataGrid files and `DashboardUtils.SCHEMA` named `../core/…` or `../../../types`, which resolve to nothing in an installed package, so the DataGrid's `component` prop and the dashboard schema read as `any` under `skipLibCheck: true` and failed to compile without it. They import `@box-kite/core` by name now, and the package no longer carries declarations for the MCP server, `create`, the registry and Supabase, which nothing could import.
- **A `ChartContainer` series painted with a `Box.extend()` token rendered transparent.** `series={{ completed: 'ui-primary', started: 'ui-primary/35' }}` type-checked and then declared `--color-completed: ui-primary`, which is not a colour, so every bar and legend swatch reading `var(--color-completed)` drew nothing and nothing said why. The same gap was in `vars` and `css` themselves, which resolved the palette's tokens but not an app's. Both now resolve an app token, and its opacity form, exactly as `fill` does: `var(--ui-primary)` and `color-mix(in oklab, var(--ui-primary) 35%, transparent)`. A series paint `fill` would refuse is left out rather than written as text, with a development warning naming the nearest token (`Did you mean "teal-500"?`). A colour written as CSS was never a series paint, and still is not; it goes in [`vars`](https://box-kite.dev/charts#recharts-notes): `vars={{ 'color-completed': 'hsl(var(--primary))' }}`.
- **A hand-written `var(--brand)` naming a `Box.extend()` variable named nothing unless something else used the token.** `fill="var(--brand)"`, a `MiniDonut` colour, a `vars` entry and a variable defined in terms of another all wrote the reference without declaring `--brand` in `:root`, so the paint was transparent. Each one declares it now, the way `fill="brand"` always did.
- **A `ref` on `<Form>` replaced the form's own, so every submit threw `Cannot read properties of null (reading 'elements')`.** React 19 passes `ref` as a prop, and Form handed it to its `<form>` in place of the one it reads its entries from; on React 18 the ref never arrived at all. `<Form ref={formRef}>` now reaches the element and the form still reads its entries, whether the ref is an object, a callback or in `props`. Fourteen more components kept a ref of their own in the same way, and a caller's `ref` broke each one on React 19: `Accordion` and `RadioGroup` lost their arrow keys, `Calendar` and `Tabs.List` their keyboard focus, `Toaster` its hotkey, and `Dialog`, `AlertDialog`, `Popover`, `Menu` and `Menu.Sub` never opened; `Tooltip`, `Slider`, `DashboardGrid` and `Tabs.Panels` lost the element their own behaviour reads. Each one now shares the element between both refs, on React 18 as well as 19.

---

_Every page: https://www.box-kite.dev/llms.txt · every prop, measured: https://www.box-kite.dev/props.md_

