--- title: ListItem description: Compose consistent rows with icons, descriptions, indicators, and actions. --- import { StoryEmbed } from '/snippets/ui/StoryEmbed.mdx'; import ListItemReference from '/snippets/ui/generated/navigation/list-item.mdx'; `ListItem` supplies the visual layout shared by list and menu rows. Use [Menu](/ui/primitives/surfaces/menu) or [Select](/ui/primitives/input/select) when you need their selection and keyboard behavior. ## Anatomy `ListItem` exposes content slots through props. These slots arrange content inside one row; they are not separately exported components. ```text ListItem ├── startIcon ├── children ├── description ├── actions └── endIcon ``` | Slot | Requirement | Purpose | | ------------------------------------ | -------------------------------- | ------------------------------------------------------------------------------- | | `children` | Required for a visible row label | Supplies the main text. | | `startIcon`, `endIcon` | Optional | Add supporting icons at either end of the row content. | | `description` | Optional | Adds supporting text inline or at the end, according to `descriptionPlacement`. | | `actions` | Optional | Adds trailing content, such as a separately focusable action. | | `indicator`, `hotkeys`, `hasSubmenu` | Optional | Configure built-in selection marks, shortcut hints, and the submenu indicator. | The row supplies layout. Use `render` to choose its element and semantics. For a row with independent action buttons, keep the row itself non-interactive so those buttons remain separate controls. ## Action row ```tsx import { IconCopy } from 'twenty-ui/icon'; import { ListItem } from 'twenty-ui/primitives/navigation'; type DuplicateActionProps = { onDuplicate: () => void }; export const DuplicateAction = ({ onDuplicate }: DuplicateActionProps) => ( } startIcon={} description="Create a copy" onClick={onDuplicate} > Duplicate ); ``` The default element is a `div`. Use `render` to give an interactive row appropriate semantics, such as a button or link. `hotkeys` displays shortcut hints; your application must register the shortcuts. ## Selection indicator ```tsx import { useState } from 'react'; import { ListItem } from 'twenty-ui/primitives/navigation'; export const ShowArchivedToggle = () => { const [selected, setSelected] = useState(false); return ( } selected={selected} indicator="check" onClick={() => setSelected(!selected)} > Show archived records ); }; ``` `selected`, `focused`, and `disabled` control row styling. The `check` and `checkbox` indicators are visual; use a real [Checkbox](/ui/primitives/input/checkbox) for a form control. When using a disabled button or link through `render`, also supply the element's appropriate disabled behavior and semantics. ## Slots Use `startIcon` and `endIcon` for icons, `description` for supporting text, `actions` for trailing content, and `hasSubmenu` for a submenu indicator. `descriptionPlacement` accepts `inline` or `end`. `color="danger"` styles a destructive action. Avoid nesting interactive controls inside a row rendered as a button. ```tsx import { Button } from 'twenty-ui/primitives/input'; import { ListItem } from 'twenty-ui/primitives/navigation'; type ContactRowProps = { onOpen: () => void }; export const ContactRow = ({ onOpen }: ContactRowProps) => ( Open } > Alex Morgan ); ``` ## Props The reference is generated from the public component types. Native attributes, including accessible names and event handlers, are also accepted on parts that render elements.