Chip
Standalone toggle or value-scoped group item with button/radio/checkbox semantics.
Identity
Section titled “Identity”- Category: Data display
- Status: stable public Registry/export-map component family
- Targets: iOS · Android · Web, subject to the compatibility contract
- Prerequisites:
@beemvp/beeui-uiinstalled (or this component’s source copied via the Registry CLI below) and, on Web, the BeeUI Tailwind/Uniwind theme CSS loaded — see Start for full platform setup. - Source:
packages/ui/src/components/chip.tsx
Import
Section titled “Import”import { Chip, ChipGroup } from '@beemvp/beeui-ui';There is no documented deep/private source import. For source ownership from a BeeUI checkout:
pnpm beeui add chipRegistry (used throughout this page) is BeeUI’s source-ownership manifest — registry/registry.json — that the pnpm beeui/@beemvp/beeui-cli CLI reads to copy a component’s real source into your app and rewrite its internal imports; it is not an npm package index. This component’s own Registry entry: registry/registry.json.
Composition and public API
Section titled “Composition and public API”- Family exports:
ChipChipGroup- Also routed here, outside the Registry family:
chip
- Package export subpath:
@beemvp/beeui-ui/chip
- Also routed here, outside the Registry family:
Exported types: ChipGroupProps, ChipGroupValue, ChipProps, ChipSelectionMode
The generated API inventory is mechanically joined to packages/ui/src/index.ts, Registry metadata, and the component reference contract. Each type’s field table below is parsed directly from that source, not a second hand-maintained copy; for the fuller behavior narrative see the canonical component behavior catalog.
State and behavior contract
Section titled “State and behavior contract”Standalone toggle (selected/onSelectedChange) or, nested in ChipGroup, a value-scoped selection item; a grouped Chip rendered without a value fails safe as disabled and warns in development, and ChipGroup supports controlled/uncontrolled single- or multiple-selection. A standalone Chip set to interactive={false} renders as a static, read-only tag with no button/radio/checkbox role and no press handling; ChipGroup’s allowDeselect lets pressing the already-selected Chip again clear the 'single'-mode selection instead of leaving it always-one-selected.
ChipGroupProps
Section titled “ChipGroupProps”| Prop | Type | Default | Description |
|---|---|---|---|
allowDeselect |
boolean |
false |
'single' mode only: pressing the already-selected Chip again clears the selection (reported as '', the same empty-string sentinel the group already starts from) instead of doing nothing. Off by default — existing single-select filter bars keep their current “always one selected” behavior unless they opt in. Ignored in 'multiple' mode, which can already reach zero selections by unchecking every Chip. |
children |
React.ReactNode |
— | Content rendered inside this element. The family’s composition section states which children it expects. |
className |
string |
— | Extra utility classes, merged after the component’s own via cn(...), so they win on conflict. An escape hatch for source-owned and application work, not a cross-engine portability guarantee. |
defaultValue |
ChipGroupValue |
— | Initial selection for uncontrolled usage: a string in 'single' mode, an array in 'multiple' mode. Defaults to no selection. |
disabled |
boolean |
false |
Disables every Chip inside the group, overriding each item’s own disabled. Defaults to false. |
onValueChange |
(value: ChipGroupValue) => void |
— | Called with the updated selection (a string in 'single' mode, an array in 'multiple' mode) whenever a member Chip is pressed. |
selectionMode |
ChipSelectionMode |
'single' |
'single' renders the group with accessibilityRole="radiogroup" and each Chip as a radio, allowing at most one selection; 'multiple' renders each Chip as a checkbox and allows any number selected. Defaults to 'single'. |
value |
ChipGroupValue |
— | The selected member Chip’s value (a string in 'single' mode, an array of values in 'multiple' mode). Passing this switches the group to controlled mode. |
Also carries every prop of Omit<ViewProps, 'children'> — that upstream contract is not reproduced here.
ChipProps
Section titled “ChipProps”| Prop | Type | Default | Description |
|---|---|---|---|
children |
React.ReactNode |
— | Content rendered inside this element. The family’s composition section states which children it expects. |
className |
string |
— | Extra utility classes, merged after the component’s own via cn(...), so they win on conflict. An escape hatch for source-owned and application work, not a cross-engine portability guarantee. |
defaultSelected |
boolean |
false |
Initial selected state when this Chip is standalone (not inside a ChipGroup) and uncontrolled. Defaults to false. |
interactive |
boolean |
true |
Set false for a read-only tag with no interactive role (button/ radio/checkbox) and no press handling — e.g. a list of stores a staff member belongs to, where button/checkbox semantics would be wrong. Defaults to true. Always treated as true inside a ChipGroup, whose selection semantics require an interactive member. |
labelClassName |
string |
— | Extra utility classes for the label text specifically, merged after the component’s own. |
onSelectedChange |
(selected: boolean) => void |
— | Called with the next selected state when pressed, if this Chip is standalone (not inside a ChipGroup). |
selected |
boolean |
— | Controls whether this standalone Chip is selected. Ignored inside a ChipGroup, which derives selection from value instead. |
value |
string |
— | Identifies this Chip within a parent ChipGroup. Required there — without it the Chip renders disabled with a dev-mode warning. Has no effect on a standalone Chip. |
Also carries every prop of Omit<PressableProps, 'accessibilityRole' | 'children' | 'role'> — that upstream contract is not reproduced here.
Related exported types:
ChipGroupValue— alias ofstring | string[].ChipSelectionMode— one of'single','multiple'.
The executable fixtures below are the source-grounded usage examples; consumers should not infer state ownership from DOM structure or another UI library.
Provider and dependencies
Section titled “Provider and dependencies”- No additional provider is required by this family.
BeeUIProviderremains the recommended application root. - Peer/native dependencies visible to this Registry item:
react,react-native - Registry dependency closure:
core-cn,text,theme - Safe-area ownership remains explicit: shell surfaces touching system edges opt into
SafeArea; components do not silently invent app-shell insets. - Web consumers load the BeeUI semantic theme CSS as documented in Web onboarding.
Platform behavior
Section titled “Platform behavior”This family ships no platform-specific file, and its own source takes no Platform branch.
The same public family is exposed across the supported target matrix; meaningful platform differences remain governed by the compatibility contract.
Evidence classes are not equal and this page does not blur them: Web behavior is exercised in a real browser, while iOS and Android carry package/export and native-compile evidence, which is not device-runtime proof. The compatibility contract records which class each claim rests on.
Accessibility
Section titled “Accessibility”- Roles this family assigns:
button,checkbox,radio,radiogroup— set inchip.tsxby the components themselves, not by the caller. - Accessibility states and properties it sets:
accessibilityLabel,checked,disabled,selected— read fromchip.tsx.
Keyboard/focus behavior, announcements, Dynamic Type/Web zoom, RTL and reduced-motion expectations are not derived here — see Accessibility overview, Keyboard & focus, RTL/localization and Large text & zoom. BeeUI does not claim universal accessibility certification from automated tests.
Styling and theming
Section titled “Styling and theming”- Style axes: none of its own — its appearance comes from tokens and your own classes; it also carries
Omit<PressableProps, 'accessibilityRole' | 'children' | 'role'>,Omit<ViewProps, 'children'>. - Class-name surfaces:
className,labelClassName.
Colors, spacing and typography come from semantic tokens rather than from values written here — see Theming and Density. A className is an escape hatch for source-owned and application work, not a cross-engine portability guarantee.
Executable examples
Section titled “Executable examples”- Primary executable fixture:
apps/showcase/__tests__/chip-static-tag-and-group-deselect.test.tsx - Additional fixture:
apps/showcase/__tests__/component-contracts.test.tsx - Additional fixture:
apps/showcase/__tests__/dynamic-type-contract.test.tsx - Additional fixture:
apps/showcase/__tests__/issue-7-state-edge-cases.test.tsx
Addressable examples
Section titled “Addressable examples”Each link below opens the Showcase at that exact example, not at the top of the gallery:
basic— smallest meaningful complete usage
The Showcase links demonstrate Web behavior; use the native-preview guide for real simulator/emulator/device paths.
Live Web preview
Section titled “Live Web preview”This frame loads the real BeeUI Web Showcase on demand; it is not a second docs-only implementation. It proves browser behavior only. Use native preview for iOS/Android simulator, emulator or device paths.
Composition anatomy
Section titled “Composition anatomy”- Family root / primary export:
Chip- Public composition parts / helpers:
ChipGroup
- Exported type surface:
ChipGroupPropsChipGroupValueChipPropsChipSelectionMode
- Public composition parts / helpers:
The tree above is ordinary document structure so it remains readable with keyboard and assistive technology; it is derived from the real public export family rather than a canvas-only diagram.
Verified example source
Section titled “Verified example source”These are the parts of the typechecked runtime Showcase fixture behind this live preview — apps/showcase/component-gallery/component-gallery.tsx, 1103 lines — where Chip is actually used: 9 lines in 1 place. Each block is copied verbatim from the line range named above it, so it is the same executable source, not a retelling of it. The rest of that file exercises other families and is not reproduced here.
Imports the examples below need (a filtered subset of the fixture’s own top-level imports):
import { Chip, ChipGroup } from '@beemvp/beeui-ui';import * as React from 'react';Fixture state this block reads (same file, line 465):
const [filters, setFilters] = React.useState<string[]>(['mobile']); <ChipGroup onValueChange={(value) => setFilters(Array.isArray(value) ? value : [value])} selectionMode="multiple" value={filters} > <Chip value="mobile">Mobile</Chip> <Chip value="web">Web</Chip> <Chip value="design">Design</Chip> </ChipGroup>Open the fixture itself for the full surrounding component. For a smaller app-specific example, start from the imports and fixture-state blocks above and keep only the state your screen owns.
Limitations
Section titled “Limitations”Inside a ChipGroup, a chip’s own selected, defaultSelected, onSelectedChange and interactive are ignored: selection and role are read from the group’s value and semantics, and a press is routed to the group instead of the item’s callback. allowDeselect has no effect in 'multiple' mode, which can already reach zero selections by unchecking every Chip.