# Charts, dashboards, and a dozen new components

Released 27 Sept 2026. [Components 2.15.0](https://github.com/TicketSolutionsPtyLtd/roadie/blob/main/packages/components/CHANGELOG.md#2150), [Core 2.10.0](https://github.com/TicketSolutionsPtyLtd/roadie/blob/main/packages/core/CHANGELOG.md#2100), [Charts 0.1.0](https://github.com/TicketSolutionsPtyLtd/roadie/blob/main/packages/charts/CHANGELOG.md#010), and [Widgets 3.6.2](https://github.com/TicketSolutionsPtyLtd/roadie/blob/main/packages/widgets/CHANGELOG.md#362)

The first release of Roadie Charts, with nine chart types and dashboards, plus Avatar, Menu, Toast, and more new components.

## Highlights

- **Charts**: Nine chart types for event and ticketing insights, each with a table view, in the new `@oztix/roadie-charts`. See [Charts](https://ticketsolutionsptyltd.github.io/roadie/charts/data-visualisation.md).
- **Dashboards**: Dashboard cards in named sizes that reflow by container width, with stat tiles, deltas, and sparklines. See [Dashboards](https://ticketsolutionsptyltd.github.io/roadie/charts/dashboards.md).
- **Avatar**: A person's photo with initials or an icon behind it, built on Base UI's avatar primitive. See [Avatar](https://ticketsolutionsptyltd.github.io/roadie/components/avatar.md).
- **Menu**: A dropdown list of actions that opens from a button. See [Menu](https://ticketsolutionsptyltd.github.io/roadie/components/menu.md).
- **Toast**: A brief message that confirms an action or reports its result. See [Toast](https://ticketsolutionsptyltd.github.io/roadie/components/toast.md).
- **Callout**: An inline message that sits in the flow of the page. See [Callout](https://ticketsolutionsptyltd.github.io/roadie/components/callout.md).
- **Collapsible**: A single panel that a trigger shows and hides. See [Collapsible](https://ticketsolutionsptyltd.github.io/roadie/components/collapsible.md).
- **Number field**: A number input with decrement and increment buttons, built on Base UI's number field primitive. See [Number field](https://ticketsolutionsptyltd.github.io/roadie/components/number-field.md).
- **OTP field**: A one-time code input with one slot per character. See [OTP field](https://ticketsolutionsptyltd.github.io/roadie/components/otp-field.md).
- **Progress**: A bar for a task underway. See [Progress](https://ticketsolutionsptyltd.github.io/roadie/components/progress.md).
- **Slider**: For picking a number or a range by dragging. See [Slider](https://ticketsolutionsptyltd.github.io/roadie/components/slider.md).
- **Switch**: An on or off control for settings that apply straight away. See [Switch](https://ticketsolutionsptyltd.github.io/roadie/components/switch.md).
- **Toggle and Toggle group**: A button that stays pressed or unpressed, such as favourite or bold. See [Toggle and Toggle group](https://ticketsolutionsptyltd.github.io/roadie/components/toggle.md).

## New

- Add `Avatar`, a person's photo with initials or an icon behind it, built on Base UI's avatar primitive.

  See [Avatar](https://ticketsolutionsptyltd.github.io/roadie/components/avatar.md).

  `<Avatar src name />` covers most uses: it draws initials from `name`, falls back to a user icon without one, and shows whichever is underneath if the photo fails. `Avatar.Image` and `Avatar.Fallback` compose it by hand, and the image stays mounted so it lazy loads and can render through Roadie `Image`. Sizes run `xs` to `xl`, `shape` is `circle` or `square`, and the fallback takes the surrounding intent. `Avatar.Group` overlaps a row of avatars with a ring in the page colour, and `Avatar.GroupCount` ends it with `+N`. `getInitials` is exported too.
- Add `Callout`, an inline message that sits in the flow of the page.

  See [Callout](https://ticketsolutionsptyltd.github.io/roadie/components/callout.md).

  The short form takes `intent`, `title` and the body as children, and shows a status icon for `info`, `success`, `warning` and `danger`. The compound form (`Callout.Icon`, `Callout.Title`, `Callout.Description`, `Callout.Actions`) covers actions and rich bodies; actions sit below the text in a narrow callout and beside it in a wide one. `emphasis` takes Badge's values and defaults to `subtle`, `onDismiss` adds a dismiss button, and `Callout.Title` becomes a heading through `render`.
- Add `Checkbox` and `CheckboxGroup`, styled as siblings of `RadioGroup`.

  See [Checkbox](https://ticketsolutionsptyltd.github.io/roadie/components/checkbox.md), [Radio group](https://ticketsolutionsptyltd.github.io/roadie/components/radio-group.md).

  `Checkbox` takes a `label` and `description`, shows a tick or, when `indeterminate`, a dash, and picks up `invalid`, `required` and `disabled` from a surrounding `Field`. `CheckboxGroup` tracks an array of ticked values, lays out vertically or horizontally in `subtler` or `normal` emphasis, and supports a parent "select all" item through `allValues` and `parent`.
- Add `Collapsible`, a single panel that a trigger shows and hides.

  See [Collapsible](https://ticketsolutionsptyltd.github.io/roadie/components/collapsible.md).

  `Collapsible.Trigger` shows a trailing caret that turns when open (`showCaret={false}` hides it) and renders onto a Roadie `Button` through `render`. `Collapsible.Panel` passes `keepMounted` and `hiddenUntilFound` through. `Collapsible.Text`, placed inside a `Collapsible`, clamps a paragraph to `lines` (3 by default) and ends the last line with an inline "…more" that fades the text behind it. The trigger shows only when the text overflows; `lessLabel={null}` makes it expand only. The `Collapsible` root now owns the open state and shares it with its parts.

  `is-disclosure-animated` now also animates Base UI panels that aren't `<details>`,
  by height from `--collapsible-panel-height`.
- Add the dashboard components: `Dashboard` with named card sizes that reflow by container width, `DataCard`, `StatTile`, `Delta`, `Sparkline`, `Meter`, `DataTable` with inline sparkline and meter columns that hide by priority on narrow cards, and general `Table` primitives.

  See [Dashboard](https://ticketsolutionsptyltd.github.io/roadie/charts/dashboard.md), [DataCard](https://ticketsolutionsptyltd.github.io/roadie/charts/data-card.md), [StatTile](https://ticketsolutionsptyltd.github.io/roadie/charts/stat-tile.md), [Delta](https://ticketsolutionsptyltd.github.io/roadie/charts/delta.md).

  Every one renders completely on the server.
- Nine chart types for event and ticketing insights, built on TanStack Charts: `LineChart` (with band, median, forecast, target, today and annotations), `BarChart`, `RankedBars`, `StackedBars`, `Histogram`, `Funnel`, `Heatmap`, `Scatter` and `SmallMultiples`.

  See [LineChart](https://ticketsolutionsptyltd.github.io/roadie/charts/line-chart.md), [BarChart](https://ticketsolutionsptyltd.github.io/roadie/charts/bar-chart.md), [RankedBars](https://ticketsolutionsptyltd.github.io/roadie/charts/ranked-bars.md), [StackedBars](https://ticketsolutionsptyltd.github.io/roadie/charts/stacked-bars.md).

  Each renders live with Roadie tokens, on the server, and as standalone SVG through `renderChartSvg` in `@oztix/roadie-charts/static`, which also exports each chart's definition. Each chart's Table view rows come from `@oztix/roadie-charts/tables`, which a server can call without the chart engine. A chart inside a `Chart` card now supplies the card's table and summary, so `table` is optional, and a chart that can't draw puts its card in the error state.

  The `Chart` card's Chart and Table switch is now an icon-only `ToggleGroup`,
  because both are views of the same data. Each item is a button with
  `aria-pressed` and `aria-controls`, and the hidden view is `inert` but keeps its
  box, so the card height holds across the switch. There are no `tab` or
  `tabpanel` roles any more. `ToggleGroup` keeps focus on the item you left when
  the window regains focus, instead of moving it to the pressed item.

  Cards take actions at the top right. `Chart` has an `actions` prop that sits
  after the Chart and Table switch, and `DashboardView` has a `cardActions` render
  prop that adds actions to every card kind described as data.
  `DataCard.MoreButton` is the More button that ends a card's actions. It passes
  its props and ref through, so it is the trigger of the card's `Menu`, passed to
  `Menu.Trigger` as its `render`. `@oztix/roadie-charts/tables` adds `plotTable`,
  the Table view rows for any chart plot in a dashboard description, and
  `cardTable`, the table behind any card, for actions such as Download CSV.
  `DataCard` now shows its actions in every state, so a refresh works on a card
  that failed to load; `Chart` hides only its view switch without data. Repeated
  `BarChart` x values add up their bars, and the `line` keeps the first value it
  has.

  In core, a chart card's `plot` accepts every chart kind, each with its own
  schema exported from `@oztix/roadie-core/dashboard`, and `validateDashboard`
  checks plot fields, annotations outside the data and repeated names. A legend
  item takes `median: true` to draw a dashed median through a `band` key, in
  `ChartLegend` and in a dashboard description alike, and `validateDashboard`
  warns when a median sits on any other shape. `parseWallTime` in
  `@oztix/roadie-core/dataviz` reads an ISO string as venue wall time, and
  `isWallTime` says whether a value is one. Both accept a space in place of the
  `T`, as in `2026-11-14 19:30`, read the whole string and refuse a date that
  doesn't exist, such as 31 February. `--chart-highlight` now follows nested
  accent, dark and intent sections. Inline `code` no longer splits a short name
  across lines; it breaks mid-token only when the token can't fit a line.
- Add `Menu`, a dropdown list of actions that opens from a button.

  See [Menu](https://ticketsolutionsptyltd.github.io/roadie/components/menu.md).

  `Menu.Content` wraps the portal, positioner and popup and takes `side`, `align`, `sideOffset` and `alignOffset` directly. Items take a leading `icon`, a trailing `shortcut` and an `intent` (use `danger` for destructive actions). `Menu.Item` takes an `href`, routed through `RoadieLinkProvider`. Checkbox and radio items, groups with labels, separators and submenus are included, and Navigator menus now share the same surface and row styles. On a touch screen a tapped row that keeps the menu open no longer stays highlighted; the keyboard highlight still shows.
- Add `NumberField`, a number input with decrement and increment buttons, built on Base UI's number field primitive.

  See [Number field](https://ticketsolutionsptyltd.github.io/roadie/components/number-field.md).

  `<NumberField min={0} max={10} />` renders the whole stepper; compose `NumberField.Group`, `Input`, `Decrement`, `Increment` and `ScrubArea` when you need a different layout. The buttons turn off at `min` and `max`. `format` takes `Intl.NumberFormat` options for currency, percentages and units. It inherits `invalid`, `required` and `disabled` from `Field`.

  - `size` and `emphasis` work like `Input`. `emphasis='subtler'` drops the field
    box for round buttons, sized like `IconButton`, either side of the value.
  - `Decrement` and `Increment` take `emphasis` and `intent`, so
    `<NumberField.Increment emphasis='strong' intent='accent' />` gives an accent
    add button.
  - `removable` turns the decrease button into a Remove button with a trash icon
    one step above `min`.
  - `editable={false}` stops typing while the buttons and arrow keys still step,
    unlike `readOnly`, which stops every change.
  - The field is only as wide as its widest value, from `min`, `max` and
    `format`. A typeable value keeps a tap target of at least 2.75rem, 3.5rem on
    touch screens, and at `subtler` sits in a chip that behaves like a subtle
    `Input`. Pass `className='w-full'` to stretch the field.
  - The value animates with NumberFlow at every emphasis, using the same `format`
    and `locale`, and stays still for people who prefer reduced motion.
- Add `OTPField`, a one-time code input with one slot per character.

  See [OTP field](https://ticketsolutionsptyltd.github.io/roadie/components/otp-field.md).

  `<OTPField length={6} />` renders every slot, and `groupSize={3}` splits them 3-3 with a separator. Compose `OTPField.Input` and `OTPField.Separator` for other layouts. Slots look like `Input` and match its 32, 40 and 48px heights. Pasting a full code fills every slot, the first slot offers `autoComplete='one-time-code'`, numeric codes bring up the number pad, and `onValueComplete` fires once the last digit lands. It inherits `invalid`, `required` and `disabled` from `Field`.
- Add `Progress`, a bar for a task underway.

  See [Progress](https://ticketsolutionsptyltd.github.io/roadie/components/progress.md).

  `<Progress value={40} label='Uploading' />` renders the label, the value and the track; `valueText` swaps the percentage for text such as "120 of 400" and reads it to screen readers. Pass `value={null}` while the length is unknown and the bar sweeps across the track. The parts (`Label`, `Value`, `Track`, `Indicator`) compose for custom layouts. The fill is the accent by default, like `Meter`, and takes the intent when you pass `intent`, such as `success` or `danger` once a task has ended. Core gains the `animate-indeterminate` utility behind the sweep, which holds a still, soft bar under reduced motion.
- Add `RoadieProvider`, one root provider for a Roadie app: `<RoadieProvider link={NextLink}>{children}</RoadieProvider>`.

  See [Installation](https://ticketsolutionsptyltd.github.io/roadie/overview/getting-started.md#4-mount-roadieprovider).

  It mounts `RoadieLinkProvider`, `ThemeProvider`, `Toast.Provider` with a `Toast.Viewport`, `Tooltip.Provider` and Base UI's `DirectionProvider`. Each part takes its usual options through `theme`, `toast` (plus the viewport's `position` and `container`), `tooltip` and `direction`, and `false` leaves it out. Every individual provider stays exported, and a nested one still overrides its part. In development, Roadie warns when a `RoadieProvider` sits inside another one, or when a `ThemeProvider` or `Toast.Provider` it already mounts wraps it or sits straight inside it.

  Top toasts now clear `Pane.Header`. A `Navigator` frame tracks the bottom of
  the tallest pane header along the top of the window, and keeps it in step as
  the header collapses, so `top-end` and `top-center` toasts sit just below it.
  `--toast-viewport-offset-top` stays yours and adds to that. Bottom positions
  are unchanged.
- Add `Slider`, for picking a number or a range by dragging.

  See [Slider](https://ticketsolutionsptyltd.github.io/roadie/components/slider.md).

  `<Slider label='Price' defaultValue={[20, 80]} />` renders the label, the value, the track and one thumb per value. `format` takes `Intl.NumberFormat` options, such as AUD currency, and formats in `en-AU` unless you pass a `locale`. Inside `Field` it takes its name, helper or error text, and `invalid` and `disabled` from there. The fill is accent, like `Switch` and `Checkbox`, and turns danger when invalid. `size` (`sm`, `md`, `lg`) scales the thumb and track, each keeping a 44px touch target, and `direction='vertical'` runs it up the page. The parts (`Label`, `Value`, `Control`, `Track`, `Indicator`, `Thumb`) compose for custom layouts such as tick marks.
- Add `Switch`, an on or off control for settings that apply straight away.

  See [Switch](https://ticketsolutionsptyltd.github.io/roadie/components/switch.md).

  Pass `label` and `description` for a labelled settings row, or drop it into `Field` and it takes its name, helper or error text, and `invalid`, `required` and `disabled` from there. The checked track is accent with a tick, the thumb slides with a transition that stops under reduced motion, and `size` is `sm` or `md`.
- Add `Toast`, a brief message that confirms an action or reports its result.

  See [Toast](https://ticketsolutionsptyltd.github.io/roadie/components/toast.md).

  Mount `Toast.Provider` with a `Toast.Viewport` once at the app root, then call `useToastManager().add({ title, description, intent, actionProps })` from any component, or `createToastManager()` from outside React. `intent` (`success`, `danger`, `warning` or `info`) colours the toast and leads it with a matching icon, `actionProps` adds a small button such as Undo or Retry, and `promise` shows a spinner until the work settles. A thin `Toast.Progress` bar along the bottom of timed toasts shows how long they have left, pausing whenever their timer pauses (hover, focus, a background window). `Toast.Viewport` takes a `position` (`bottom-end` by default, `bottom-center`, `top-end` or `top-center`); small screens always span the chosen edge. Set `--toast-viewport-offset-bottom` (or `-top`) to clear fixed UI such as a checkout bar. Toasts fan out on hover or focus and swipe away towards their edge. Core adds the `motion-toast` utility that stacks and animates them from either edge: toasts enter, restack and snap back on a spring and leave quickly. Core also adds `--ease-spring-lively`, a spring with a visible bounce (about 9% overshoot) for transforms that should catch the eye.

  The `@base-ui/react` peer range rises to `^1.8.0`. Toast relies on 1.8 for
  `update(id, previous => …)` and for timers that keep their remaining time
  across repeated pauses, which the progress bar follows.
- Add `Toggle` and `ToggleGroup`.

  See [Toggle](https://ticketsolutionsptyltd.github.io/roadie/components/toggle.md), [Toggle group](https://ticketsolutionsptyltd.github.io/roadie/components/toggle-group.md).

  `Toggle` is a pressed or unpressed button that takes Button's sizes and steps up one emphasis when pressed; with only an icon inside it renders square. `ToggleGroup` is a segmented control with a pill that slides to the pressed item. `emphasis` follows Toggle: `normal` (the default) has a bordered track and `subtle` a tinted one, each with a solid pill, and `subtler` has no track and a tinted pill. It is single select by default and never ends up empty, takes `multiple` for independent toggles, and has `size` (matching Button heights), `direction` and `disabled`.
- Make the selected item of a `subtler` `Toggle` or `ToggleGroup` easier to see.

  See [Toggle](https://ticketsolutionsptyltd.github.io/roadie/components/toggle.md), [Toggle group](https://ticketsolutionsptyltd.github.io/roadie/components/toggle-group.md).

  A pressed `subtler` toggle or group item now takes a soft fill with no border and a strong icon or label. The fill alone stays under 3:1 against the surface, so the fill and the icon carry the state together: use `subtler` for quiet controls, and `subtle` or `normal` when the state must stand out. On the unpressed side, a `subtler` `Toggle` now rests in subtle text rather than normal text, like the items of a group. Core adds the `is-selected` utility that carries this look, with a system highlight edge under forced colours. The `subtler` `Tabs` underline keeps its look and now takes the highlight colour under forced colours, where it used to disappear. The chart card's Chart and Table switch moves up to `md`, so each item is 32px, the size of the card's More button.
- Add dashboard support.

  See [Dashboard](https://ticketsolutionsptyltd.github.io/roadie/charts/dashboard.md).

  `@oztix/roadie-core/dashboard` describes a dashboard as JSON, with a Zod schema, a JSON Schema export for tool inputs, and `validateDashboard`, which reports every problem with its path, including rows that leave gaps, copy that will truncate, and unknown keys. A zod-free `@oztix/roadie-core/dashboard-layout` subpath exposes the card sizes, spans, tracks, `findRowGaps` and `COPY_LIMITS` for UI code that must not load Zod. `@oztix/roadie-core/dataviz` gains `formatValue` and delta helpers in the house number formats, and `chartHex` now returns chrome colours for static renderers. Chart ink now follows nested `.dark` and `intent-*` sections, the highlight's hex fallback uses the default accent hue, and chart marks get texture patterns under forced colours and print.
- Add data visualisation colours.

  Charts get `--chart-1` to `--chart-8` for series, `--chart-heat-*` for amounts, `--chart-diverge-*` for ahead of or behind a benchmark, `--chart-status-*` for meaning, and `--chart-highlight`, which follows `--accent-hue`. Each comes with `bg-`, `fill-`, `stroke-` and `text-chart-*` utilities, in light and dark. Canvas, SVG and PDF renderers can read the same values as hex from `@oztix/roadie-core/dataviz`, with the greys tinted by the accent hue as the CSS ones are, and `chartColorVar(i)` gives a CSS variable when the slot is dynamic. The palette is checked for colour-blind separation in CI.
- Add `text-on-strong` (`--intent-text-on-strong`), the label colour for strong fills.

  Each intent takes whichever text colour reads better on its fill, and reaches APCA Lc 60 in both modes, at rest, on hover and when pressed, in browsers that support `color-mix()`. `emphasis-strong`, CalendarTile's strong band, and the strong Tabs and ToggleGroup pills use it.

  - White on brand, accent, info and danger, in both modes. Danger's strong fill
    moves one step deeper, to step 10. In dark mode, hover and press darken the
    fill to steps 8 and 7.
  - Dark text on success, warning and brand-secondary: step 13 in light mode, step
    0 in dark mode. Success and brand-secondary lift their fill 10% toward white.
    Hover and press lighten the fill further in both modes.

  `text-inverted` is unchanged: it's still the page's text colour flipped, and
  pairs with `bg-inverted`. To migrate, use `text-on-strong` for labels on
  `bg-strong` or `emphasis-strong` fills where you used `text-inverted`.

  A custom accent keeps its white text too. The new `getAccentChromaSync(hex)`
  caps an accent's chroma to what sRGB can show at step 9, because browsers clip
  a more saturated fill and the clip makes it lighter. `getBootstrapScript` and
  `generateAccentScale`, which writes the hex fallback scale, now use it, so a
  saturated green or cyan accent no longer renders too light.

  Browsers that draw `oklch()` but not `color-mix()` (Safari 15.4 to 16.1) get
  step 9 for the lifted strong fills and steps 7 and 6 for hover and press, so
  the fills stay solid there. Success and brand-secondary read at about Lc 57 to
  58 at rest in those browsers.

  `generateAccentScale` now reports `fgOnStrong` by APCA, so it matches
  `text-on-strong`: `white` for Oztix blue, where it used to say `black`. It also
  no longer lifts a grey accent to chroma 0.1, so the hex fallback matches the
  CSS.

  White labels on brand, accent, info and danger are 3.2 to 3.5:1 by WCAG 2. That
  meets 3:1, not the 4.5:1 WCAG 2 asks of normal-size text. The accessibility
  page now names strong-fill labels as the APCA exception.

  Hover and press use the new `--intent-bg-strong-hover` and
  `--intent-bg-strong-active` tokens. Neutral is unchanged.

  This is a minor bump because it adds a utility and tokens, and some strong fills
  and their label colours change.
- First release of `@oztix/roadie-charts`: the `Chart` card frame with a Chart and Table switch, `ChartLegend`, `ChartTooltip`, texture patterns for forced colours and print, and `DashboardView`, which renders a dashboard description from `@oztix/roadie-core/dashboard`.

  See [Chart](https://ticketsolutionsptyltd.github.io/roadie/charts/chart.md), [ChartLegend](https://ticketsolutionsptyltd.github.io/roadie/charts/chart-legend.md), [ChartTooltip](https://ticketsolutionsptyltd.github.io/roadie/charts/chart-tooltip.md), [Dashboard design](https://ticketsolutionsptyltd.github.io/roadie/charts/dashboards.md).

  Two reference dashboards ship as data from `@oztix/roadie-charts/examples`. Plots on TanStack Charts follow in a later release.

## Changed

- Align existing form controls and Popover with the newer components.

  - `RadioGroup` and `Select` inherit `disabled` from `Field`. Their own
    `disabled` prop still wins.
  - `RadioGroup.Item` uses `description` to describe the radio, not to name it.
    `label` and `description` accept any React node.
  - `RadioGroup.Label` names the group when you use it.
  - `Popover.Content` takes `side`, `align`, `sideOffset` and `alignOffset`
    directly, like `Tooltip.Content`. They win over the same keys in
    `positionerProps`, which are now deprecated. `Tooltip.Content` gains
    `alignOffset`, so Tooltip, Menu and Popover take the same four.
  - The `intent` prop on `Input`, `Textarea` and `Select.Trigger` is deprecated.
    Form controls take their colour from state, and `is-interactive-field`
    handles it. It still works and will be removed in v3.
- A `Tabs.Tab` that holds only an icon is now a circle at every size and emphasis, with the icon centred and the indicator matching it.

  See [Tabs](https://ticketsolutionsptyltd.github.io/roadie/components/tabs.md).

  It warns in development when it has no `aria-label` or `aria-labelledby`.
- Raise the `@base-ui/react` peer range from `^1.0.0` to `^1.6.0`.

  See [Drawer](https://ticketsolutionsptyltd.github.io/roadie/components/drawer.md), [Combobox](https://ticketsolutionsptyltd.github.io/roadie/components/combobox.md), [Autocomplete](https://ticketsolutionsptyltd.github.io/roadie/components/autocomplete.md), [Select](https://ticketsolutionsptyltd.github.io/roadie/components/select.md).

  Roadie already needed 1.6: `Drawer`, the `InputGroup` parts of `Combobox` and `Autocomplete`, and `Select.Label` don't exist before 1.3, and `Navigator` menus and tooltips fail their tests before 1.6. If you pin `@base-ui/react` below 1.6, upgrade it along with this release.

## Fixed

- `ThemeProvider`, `getAccentStyleSync` and the cart drawer's accent theming cap the accent's chroma to what sRGB can show at step 9, through `getAccentChromaSync` from `@oztix/roadie-core/colors`.

  See [Theming](https://ticketsolutionsptyltd.github.io/roadie/foundations/theming.md), [Colors](https://ticketsolutionsptyltd.github.io/roadie/foundations/colors.md).

  A saturated green or cyan accent no longer renders its strong fill too light for white text.
- Select, Combobox and Autocomplete options no longer stay filled after a tap on a touch screen when the list stays open, such as a multiple select.

  A highlight the pointer made only fills where the pointer can hover, and a keyboard highlight still shows everywhere.

  Switch, Checkbox, CheckboxGroup, RadioGroup, Select, NumberField and OTPField
  now point `aria-describedby` at the text `Field` actually renders. A control
  marked `invalid` inside a valid `Field` pointed at an error text that was never
  rendered, so screen readers lost the helper text.

  `Select.Value` now shows the selected item's label instead of its raw value, on
  the server and first render too. Select reads each `Select.Item`'s text (its
  string children or its `Select.ItemText`), and an `items` or
  `itemToStringLabel` you pass still wins. Values of a multiple select show as
  their labels.
- Select and Combobox now type `multiple`.

  See [Select](https://ticketsolutionsptyltd.github.io/roadie/components/select.md).

  The roots are generic over the value and `multiple`, like Base UI's, so `<Select multiple>` takes an array for `value` and `defaultValue` and hands one to `onValueChange`. A single select infers its value type from `value` or `defaultValue` instead of `unknown`. `SelectProps` and `ComboboxProps` take the same optional type parameters for wrappers.

  A Select trigger no longer grows past its container. A long label truncates
  with the icon kept in view, and a multiple select shows the labels that fit
  then counts the rest, such as "Bee Gees, Custard +2". Screen readers still hear
  every label.
- Emphasis and field hover states now only apply on devices that can hover.

  On a touch screen the last button tapped kept its hover colour and lift, so it looked stuck or half disabled until something else was tapped. A tapped raised field also keeps its rim light, and a translucent field stays see-through. Focus and press states are unchanged.
