Accessible interactive lists with customizable content and actions.
<ListCell.Root> <ListCell.Item title="WorkOS" description="Authentication and user management" > <ListCell.ItemSlot side="right"> <Badge color="green">Verified</Badge> <IconButton size="1"> <DotsHorizontalIcon /> </IconButton> </ListCell.ItemSlot> </ListCell.Item> <ListCell.Item title="Example Inc" description="Authentication and user management" > <ListCell.ItemSlot side="right"> <IconButton size="1"> <DotsHorizontalIcon /> </IconButton> </ListCell.ItemSlot> </ListCell.Item> </ListCell.Root>
The Root component is based on the Flex component and contains ListCell.Item
components.
Prop | Type | Default |
---|---|---|
children | React.ReactNode | |
size | "1" | "2" | "3" | "1" |
The Item component represents an individual list item.
Prop | Type | Default |
---|---|---|
children | React.ReactNode | |
asChild | boolean | false |
lowContrast | boolean | false |
title | React.ReactNode | required |
description | React.ReactNode |
When asChild
is true, the item becomes a slot that can render as another element (like an anchor tag).
When lowContrast
is true, the item will have muted colors.
Prop | Type | Default |
---|---|---|
children | React.ReactNode | required |
Different sizes applies different padding and gap in each item.
<Flex direction="column" gap="5"> <ListCell.Root size="1"> {[ ['Google', 'google'], ['Entra ID (Azure AD)', 'azure'], ['Okta', 'okta'], ].map(([label, item]) => ( <ListCell.Item asChild key={item} title={label}> <a href={`#${item}`}> <ListCell.ItemSlot side="left"> <ProviderIcon provider={item} size="2" /> </ListCell.ItemSlot> </a> </ListCell.Item> ))} </ListCell.Root> <ListCell.Root size="2"> {[ ['Google', 'google'], ['Entra ID (Azure AD)', 'azure'], ['Okta', 'okta'], ].map(([label, item]) => ( <ListCell.Item asChild key={item} title={label}> <a href={`#${item}`}> <ListCell.ItemSlot side="left"> <ProviderIcon provider={item} size="2" /> </ListCell.ItemSlot> </a> </ListCell.Item> ))} </ListCell.Root> <ListCell.Root size="3"> {[ ['Google', 'google'], ['Entra ID (Azure AD)', 'azure'], ['Okta', 'okta'], ].map(([label, item]) => ( <ListCell.Item asChild key={item} title={label}> <a href={`#${item}`}> <ListCell.ItemSlot side="left"> <ProviderIcon provider={item} size="3" /> </ListCell.ItemSlot> </a> </ListCell.Item> ))} </ListCell.Root> </Flex>
<ListCell.Root> {[1, 2, 3].map((item) => ( <ListCell.Item key={item} title="https://workos.com"> <ListCell.ItemSlot side="right"> <Badge color="green">Verified</Badge> <IconButton size="1"> <DotsHorizontalIcon /> </IconButton> </ListCell.ItemSlot> </ListCell.Item> ))} </ListCell.Root>
Use the asChild
prop to render items as links or buttons.
<ListCell.Root> {[ ['Google', 'google'], ['Entra ID (Azure AD)', 'azure'], ['Okta', 'okta'], ].map(([label, item]) => ( <ListCell.Item asChild key={item} title={label}> <a href={`#${item}`}> <ListCell.ItemSlot side="left"> <ProviderIcon provider={item} size="2" /> </ListCell.ItemSlot> </a> </ListCell.Item> ))} </ListCell.Root>
<ListCell.Root size="3"> {[1, 2, 3].map((item) => ( <ListCell.Item key={item} asChild title="Your WorkOS payment has failed" description="We were unable to collect the payment for your invoice." > <a href="#"> <ListCell.ItemSlot side="left"> <IconPanel size="2"> <CubeIcon style={{ color: 'var(--accent-9)' }} /> </IconPanel> </ListCell.ItemSlot> <ListCell.ItemSlot side="right"> {item === 2 ? ( <Text>Dec 24, 2024</Text> ) : ( <Status color="gray">Dec 24, 2024</Status> )} </ListCell.ItemSlot> </a> </ListCell.Item> ))} </ListCell.Root>
Use the lowContrast
prop to visually de-emphasize specific items.
<ListCell.Root size="3"> {[1, 2, 3].map((item) => ( <ListCell.Item key={item} lowContrast={item === 2} asChild title="Your WorkOS payment has failed" description="We were unable to collect the payment for your invoice." > <a href="#"> <ListCell.ItemSlot side="left"> <IconPanel size="2"> <CubeIcon style={{ color: 'var(--accent-9)' }} /> </IconPanel> </ListCell.ItemSlot> <ListCell.ItemSlot side="right"> {item === 2 ? ( <Text>Dec 24, 2024</Text> ) : ( <Status color="gray">Dec 24, 2024</Status> )} </ListCell.ItemSlot> </a> </ListCell.Item> ))} </ListCell.Root>
Add multiple elements to build complex list items.
<ListCell.Root size="3"> {[1, 2, 3].map((item) => ( <ListCell.Item key={item} title="Another one" description="Member"> <ListCell.ItemSlot side="left"> <IconPanel size="2"> <Text weight="bold">AO</Text> </IconPanel> </ListCell.ItemSlot> <ListCell.ItemSlot side="right"> <Text> <Text color="gray">Created </Text>Dec 24, 2024 </Text> <IconButton size="1"> <DotsHorizontalIcon /> </IconButton> </ListCell.ItemSlot> </ListCell.Item> ))} </ListCell.Root>
<ListCell.Root size="3"> {[1, 2, 3].map((item) => ( <ListCell.Item key={item} title="Bot detection" description="Detect bots and scripted attacks!" > <ListCell.ItemSlot side="left"> <IconPanel size="2"> <CubeIcon style={{ color: 'var(--gray-a11)' }} /> </IconPanel> </ListCell.ItemSlot> <ListCell.ItemSlot side="right"> <Flex align="center" gap="2"> <Marker color="green" size="1"> <CheckIcon height="8" width="8" /> </Marker> <Text size="2" color="green"> Enabled </Text> </Flex> <Button>Button</Button> </ListCell.ItemSlot> </ListCell.Item> ))} </ListCell.Root>
ListCell works seamlessly inside CardList components and will adapt to the CardList
size.
<CardList.Root> <CardList.Header title="Client credentials" description="Generate a private key to authenticate the application." > <Button>Generate new secret</Button> </CardList.Header> <CardList.Body> <ListCell.Root size="3"> {[1, 2, 3].map((item) => ( <ListCell.Item key={item} title={ <Code variant="ghost" weight="regular"> •••••••••••••••••••7963 </Code> } description="Never used" > <ListCell.ItemSlot side="left"> <IconPanel size="2"> <MagicWandIcon style={{ color: 'var(--gray-a11)' }} /> </IconPanel> </ListCell.ItemSlot> <ListCell.ItemSlot side="right"> <Text> <Text color="gray">Created </Text>Dec 24, 2024 </Text> <IconButton size="1"> <TrashIcon /> </IconButton> </ListCell.ItemSlot> </ListCell.Item> ))} </ListCell.Root> </CardList.Body> </CardList.Root>
<CardList.Root> <CardList.Search /> <CardList.Body> <ListCell.Root> {[ ['Google', 'google'], ['Entra ID (Azure AD)', 'azure'], ['Okta', 'okta'], ].map(([label, item]) => ( <ListCell.Item asChild key={item} title={label}> <a href={`#${item}`}> <ListCell.ItemSlot side="left"> <ProviderIcon provider={item} size="2" /> </ListCell.ItemSlot> </a> </ListCell.Item> ))} </ListCell.Root> </CardList.Body> </CardList.Root>