Tree Select Readback

Reads a nested checkbox selection back in plain words and tells a whole-group tick apart from ticking every item today.

StopsWhole group ticked, future items included

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/tree-select-readback.json

The files land in your project. They're yours to edit.

Usage

tree-select-readback-usage.tsx
import { TreeSelectReadback, type TreeNode } from "@/components/ui/tree-select-readback"

<TreeSelectReadback
  label="Send the Q3 survey to"
  tree={tree}
  defaultValue={["marketing", "w-Pune", "w-Mumbai", "s-Kochi"]}
  defaultExpanded={["marketing", "sales"]}
/>

What it catches

  • Whole-group selections that will include future items
  • Groups partly selected, read back as "3 of 12"
  • Exceptions inside a selected group
  • A pin-to-today option that converts a group rule to today's items

Props

TreeSelectReadback props
PropTypeDefault
label

Legend for the tree.

string"Select"
tree* (required)

The options.

TreeNode[]—
value

Controlled selection: leaf ids, plus parent ids meaning "the whole group, including items added later".

string[]—
defaultValue

Initial selection when uncontrolled.

string[][]
onValueChange

Called with the new selection and the leaf ids it covers today.

(value: string[], leaves: string[]) => void—
defaultExpanded

Parents shown open at first. Defaults to every top-level group.

string[]—
emptyText

Shown when nothing is selected.

string"Nothing selected yet."
futureText

Templates: `{groups}` and `{count}` are filled in.

string"{groups} {verb} ticked as a whole, so anything added lat…
pinLabel

Label of the pin-to-today's-items fix.

string"Only the {count} there now"
newBadge

Badge next to a group ticked as a whole.

string"+ new"

* required. Also accepts the native props of <fieldset> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Expand buttons use aria-expanded/aria-controls and an aria-label
  • Children are a role=group labelled by the parent
  • Checkboxes use <label>s
  • Readback in a polite live region

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • Future-items semantics apply only when the group is open (open !== false)
  • Readback wording is English by default; override the text props

What it stops

Whole group ticked, future items included

Also known as

tree select · nested checkbox · indeterminate · permissions tree · category filter · multi select · folder picker

Dependencies

Pairs well with