Component
Selector
A pill-tab compound component for switching between named content panels. Controlled or uncontrolled, headless-ready.
Usage
useSelector hook
useSelector() reads value and onValueChange from the nearest Selector.Root context. Use it inside any child component to build actions or content wired to the active tab — without prop-drilling.
Controlled
Pass value + onValueChange to drive the selector from outside.
Headless / Unstyled
Pass unstyled on the root to strip all data-cui-* attributes and default styles. All sub-components become bare semantic elements you can style freely.
import { Selector } from '@carabine/ui';
<Selector unstyled defaultValue="a" className="my-selector">
<Selector.Header>
<Selector.Tabs>
<Selector.Tab value="a">Option A</Selector.Tab>
<Selector.Tab value="b">Option B</Selector.Tab>
</Selector.Tabs>
</Selector.Header>
<Selector.Content value="a">Content A</Selector.Content>
<Selector.Content value="b">Content B</Selector.Content>
</Selector>API Reference
Selector.Root
| Prop | Type | Default | Description |
|---|---|---|---|
defaultValue | string | "" | The initially active tab value (uncontrolled). |
value | string | — | Active tab value (controlled). Use with onValueChange. |
onValueChange | (value: string) => void | — | Callback fired when the active tab changes. |
unstyled | boolean | false | Strip all default styles — no data-cui-* attributes attached. |
Selector.Tab
| Prop | Type | Default | Description |
|---|---|---|---|
value* | string | — | The value this tab represents. Must match a Selector.Content value. |
Selector.Content
| Prop | Type | Default | Description |
|---|---|---|---|
value* | string | — | Renders this panel only when it matches the active Selector value. |
CSS variables
[data-cui-selector] {
--cui-selector-header-bg: #fafafa;
--cui-selector-header-border: #ebebeb;
--cui-selector-tab-color: #aaaaaa;
--cui-selector-tab-hover-color: #555555;
--cui-selector-tab-active-color: #111111;
--cui-selector-tab-active-bg: #ffffff;
--cui-selector-tab-active-shadow: 0 1px 3px rgba(0,0,0,.1), 0 1px 2px rgba(0,0,0,.06);
}Data attributes
/* Target the root */
[data-cui-selector] { }
/* Active tab state */
[data-cui-selector-tab][data-state='active'] { }
[data-cui-selector-tab][data-state='inactive'] { }
/* Slots */
[data-cui-selector-header] { }
[data-cui-selector-tabs] { }
[data-cui-selector-actions] { }
[data-cui-selector-content] { }