# Cell Select **Category**: react **URL**: https://ui.darkcode.dev/en/docs/react/components/cell-select **Source**: https://raw.githubusercontent.com/DarkCode-Developers/darkcode-ui/refs/heads/main/apps/docs/content/docs/en/react/components/(pickers)/cell-select.mdx > A compact select styled as a settings cell, ideal for preference panels and configuration forms. *** ## Import ```tsx import { CellSelect } from '@darkcode-ui/react'; ``` ## Usage ```tsx "use client"; import {CellSelect, ListBox} from "@darkcode-ui/react"; const languages = [ {id: "en", name: "English"}, {id: "es", name: "Español"}, {id: "fr", name: "Français"}, {id: "de", name: "Deutsch"}, {id: "ja", name: "日本語"}, ]; export function Default() { return ( Language {languages.map((language) => ( {language.name} ))} ); } ``` ## Anatomy Import the CellSelect component and access all parts using dot notation. A simple one-line cell only needs `Label`, `Value`, and `Indicator` inside the `Trigger`. The optional `Icon`, `Content`, and `Description` parts build a richer, two-line settings row, and `Group` fuses multiple cells into one panel. ```tsx import { CellSelect, ListBox } from '@darkcode-ui/react'; export default () => ( ) ``` ## Controlled Pass `value` and `onChange` to control the selected key. ```tsx "use client"; import {CellSelect, ListBox} from "@darkcode-ui/react"; import {useState} from "react"; const languages = [ {id: "en", name: "English"}, {id: "es", name: "Español"}, {id: "fr", name: "Français"}, {id: "de", name: "Deutsch"}, {id: "ja", name: "日本語"}, ]; export function Controlled() { const [value, setValue] = useState("en"); const selected = languages.find((language) => language.id === value); return (
setValue(key)}> Language {languages.map((language) => ( {language.name} ))}

Selected: {selected?.name ?? "None"}

); } ``` ## Custom Value Render a custom display for the selected value with a function child on `CellSelect.Value`. ```tsx "use client"; import {CellSelect, ListBox} from "@darkcode-ui/react"; const statuses = [ {color: "bg-success", id: "online", name: "Online"}, {color: "bg-warning", id: "away", name: "Away"}, {color: "bg-danger", id: "busy", name: "Busy"}, {color: "bg-muted", id: "offline", name: "Offline"}, ]; export function CustomValue() { return ( Status {({defaultChildren, isPlaceholder, state}) => { if (isPlaceholder || state.selectedItems.length === 0) { return defaultChildren; } const status = statuses.find((s) => s.id === state.selectedItems[0]?.key); if (!status) { return defaultChildren; } return ( {status.name} ); }} {statuses.map((status) => ( {status.name} ))} ); } ``` ## Disabled Pass `isDisabled` to disable the cell. ```tsx "use client"; import {CellSelect, ListBox} from "@darkcode-ui/react"; const languages = [ {id: "en", name: "English"}, {id: "es", name: "Español"}, {id: "fr", name: "Français"}, {id: "de", name: "Deutsch"}, {id: "ja", name: "日本語"}, ]; export function Disabled() { return ( Language {languages.map((language) => ( {language.name} ))} ); } ``` ## Font Family Each option and the selected value can be rendered in its own font family. ```tsx "use client"; import {CellSelect, ListBox} from "@darkcode-ui/react"; const fonts = [ {family: "ui-sans-serif, system-ui, sans-serif", id: "sans", name: "Sans Serif"}, {family: "ui-serif, Georgia, serif", id: "serif", name: "Serif"}, {family: "ui-monospace, SFMono-Regular, monospace", id: "mono", name: "Monospace"}, ]; export function FontFamily() { return ( Font Family {({defaultChildren, isPlaceholder, state}) => { if (isPlaceholder || state.selectedItems.length === 0) { return defaultChildren; } const font = fonts.find((f) => f.id === state.selectedItems[0]?.key); if (!font) { return defaultChildren; } return {font.name}; }} {fonts.map((font) => ( {font.name} ))} ); } ``` ## Leading Icon Add a `CellSelect.Icon` before the label. Pass the `tile` prop to render it as a colored rounded "tile" (the icon's color can be customized with `className` or `style`). ```tsx "use client"; import {CellSelect, ListBox} from "@darkcode-ui/react"; import {Icon} from "@iconify/react"; const languages = [ {id: "en", name: "English"}, {id: "es", name: "Español"}, {id: "fr", name: "Français"}, {id: "de", name: "Deutsch"}, ]; export function WithIcon() { return (
Language {languages.map((language) => ( {language.name} ))} Language {languages.map((language) => ( {language.name} ))}
); } ``` ## Two-line Cell Wrap the label and a `CellSelect.Description` in `CellSelect.Content` to build a two-line cell with a muted subtitle. The one-line API keeps working when `Content` is omitted. ```tsx "use client"; import {CellSelect, ListBox} from "@darkcode-ui/react"; import {Icon} from "@iconify/react"; const languages = [ {id: "en", name: "English"}, {id: "es", name: "Español"}, {id: "fr", name: "Français"}, {id: "de", name: "Deutsch"}, ]; export function TwoLine() { return ( Language Choose your preferred language {languages.map((language) => ( {language.name} ))} ); } ``` ## Sizes Use the `size` prop (`sm`, `md`, `lg`) to control the cell height, padding, and text size. ```tsx "use client"; import {CellSelect, ListBox} from "@darkcode-ui/react"; const languages = [ {id: "en", name: "English"}, {id: "es", name: "Español"}, {id: "fr", name: "Français"}, {id: "de", name: "Deutsch"}, ]; export function Sizes() { return (
{(["sm", "md", "lg"] as const).map((size) => ( {size} {languages.map((language) => ( {language.name} ))} ))}
); } ``` ## Settings Group Wrap multiple cells in `CellSelect.Group` to fuse them into a single inset panel with merged corners and hairline dividers. Add an optional `header` and `footer`. ```tsx "use client"; import {CellSelect, ListBox} from "@darkcode-ui/react"; import {Icon} from "@iconify/react"; const languages = [ {id: "en", name: "English"}, {id: "es", name: "Español"}, {id: "fr", name: "Français"}, ]; const themes = [ {id: "system", name: "System"}, {id: "light", name: "Light"}, {id: "dark", name: "Dark"}, ]; const regions = [ {id: "us", name: "United States"}, {id: "eu", name: "Europe"}, {id: "apac", name: "Asia Pacific"}, ]; export function SettingsGroup() { return ( Language {languages.map((language) => ( {language.name} ))} Theme {themes.map((theme) => ( {theme.name} ))} Region {regions.map((region) => ( {region.name} ))} ); } ``` ## Variants Use `variant="secondary"` for an accent-tinted cell. The variant styles the trigger row. ```tsx "use client"; import {CellSelect, ListBox} from "@darkcode-ui/react"; const languages = [ {id: "en", name: "English"}, {id: "es", name: "Español"}, {id: "fr", name: "Français"}, {id: "de", name: "Deutsch"}, ]; export function Variants() { return (
Default {languages.map((language) => ( {language.name} ))} Secondary {languages.map((language) => ( {language.name} ))}
); } ``` ## Styling CellSelect wraps the [Select](/react/components/select) component, so all Select styling patterns apply. The cell layout is provided by the BEM classes below. ### CSS Classes The CellSelect component uses the following CSS classes: #### Base Classes - `.cell-select` - Root wrapper #### Element Classes - `.cell-select__trigger` - The visible cell row (wraps Select.Trigger) - `.cell-select__trigger--default` - Default variant trigger styling - `.cell-select__trigger--secondary` - Secondary variant trigger styling - `.cell-select__trigger--sm` / `.cell-select__trigger--lg` - Size modifiers (base is `md`) - `.cell-select__icon` - Leading icon slot (`[data-tile="true"]` renders the colored tile) - `.cell-select__content` - Column wrapping the label and description (two-line cell) - `.cell-select__label` - Leading text label - `.cell-select__description` - Secondary text under the label - `.cell-select__value` - Selected value display - `.cell-select__indicator` - Chevron icon - `.cell-select__popover` - Dropdown panel - `.cell-select__group-section` - Group wrapper (header + card + footer) - `.cell-select__group` - Inset card that fuses the cells - `.cell-select__group-header` / `.cell-select__group-footer` - Group header and footer text ## API Reference ### CellSelect The root component. Wraps DarkCode UI [Select](/react/components/select) with cell-style layout. | Prop | Type | Default | Description | |------|------|---------|-------------| | `variant` | `'default' \| 'secondary'` | `'default'` | Visual style variant. | | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Cell height, padding, and text size. | Also supports all [DarkCode UI Select](/react/components/select) props except `variant`. ### CellSelect.Trigger The visible cell row containing the icon, label, value, and indicator. Also supports all DarkCode UI `Select.Trigger` props. ### CellSelect.Icon Leading icon slot rendered as a `span`. | Prop | Type | Default | Description | |------|------|---------|-------------| | `tile` | `boolean` | `false` | Render the icon as a colored rounded tile. | | `children` | `ReactNode` | - | Icon element. | Also supports all native `span` HTML attributes. ### CellSelect.Content Column that stacks the label and description for a two-line cell. Rendered as a `div`. Also supports all native `div` HTML attributes. ### CellSelect.Label Leading text label rendered as a `span`. | Prop | Type | Default | Description | |------|------|---------|-------------| | `children` | `ReactNode` | - | Label text. | Also supports all native `span` HTML attributes. ### CellSelect.Description Secondary text rendered under the label (inside `CellSelect.Content`), as a `span`. | Prop | Type | Default | Description | |------|------|---------|-------------| | `children` | `ReactNode` | - | Description text. | Also supports all native `span` HTML attributes. ### CellSelect.Value Display of the currently selected value. Also supports all DarkCode UI `Select.Value` props. ### CellSelect.Indicator Chevron icon. Defaults to a `ChevronsExpandVertical` icon when no children are provided. | Prop | Type | Default | Description | |------|------|---------|-------------| | `children` | `ReactNode` | - | Custom indicator icon. | Also supports all DarkCode UI `Select.Indicator` props. ### CellSelect.Popover Dropdown panel for selection options. | Prop | Type | Default | Description | |------|------|---------|-------------| | `placement` | `Placement` | `'bottom end'` | Popover placement relative to the trigger. | Also supports all DarkCode UI `Select.Popover` props. ### CellSelect.Group Wraps multiple cells into one inset panel with merged corners and hairline dividers. Used outside individual `CellSelect` roots. | Prop | Type | Default | Description | |------|------|---------|-------------| | `header` | `ReactNode` | - | Optional section header rendered above the panel. | | `footer` | `ReactNode` | - | Optional section footer rendered below the panel. | Also supports all native `div` HTML attributes. ## Accessibility CellSelect is built on the same React Aria Select primitive as the [Select](/react/components/select) component and provides: - Full keyboard navigation support (Arrow keys, Home, End, type-ahead) - Screen reader announcements for the listbox and selection - Proper focus management between the trigger and popover - Support for disabled states For more information, see the [React Aria Select documentation](https://react-spectrum.adobe.com/react-aria/Select.html).