Using components
How to compose what is here, and how to choose when two components look like they overlap.
Composition over configuration
Compound components are assembled from named parts rather than driven by props. Dialog is DialogTrigger, DialogContent, DialogHeader, DialogFooter — not a <Dialog title=… footer=… showClose /> with a growing config object.
The test for a new prop: does it describe the thing, or arrange it? Describing props (variant, size, tone) belong on the component. Arranging props — anything that takes a ReactNode and puts it somewhere — should almost always be a part instead.
Choosing between similar components
- Switch vs Checkbox — a Switch applies immediately; a Checkbox is collected and submitted. If there is a Save button, it is a Checkbox.
- Toggle vs Tabs — a ToggleGroup sets a value; Tabs change which content is on screen.
- Dialog vs AlertDialog — AlertDialog is for confirming something destructive, and traps focus on the confirmation. Everything else is a Dialog.
- Popover vs DropdownMenu — a menu is a list of actions with menu keyboard semantics; a popover is an arbitrary floating surface. If the contents include a form field, it is a Popover.
- Button vs IconButton — if there is no visible label, use IconButton so the accessible name and tooltip come for free.
When you need to override
Every component takes className, and that is the escape hatch. Two rules when you use it:
- Name tokens, never values. An override that hardcodes a hex or a pixel is an audit failure, and it opts the element out of the contextual accent.
- Rebind the token, do not set the property, when the component derives an inner element from it. Setting
border-radiuson a segmented control leaves its pill computed from the old radius. See Radius & borders.
If you are overriding the same thing in three places, the override belongs in the component as a variant — see Contributing.
Components with no consumers
Thirteen components in here have no consumer anywhere outside the library itself, and are marked No consumers on their page. For those, the library is a proposal rather than a record of what the app uses.
That is not a reason to avoid them — it is a reason to check the fit before you commit. The good pattern is adoption driven by real work: Alert and Checkbox came off this list by being pulled into the auth form when that form was being built anyway.