Listbox
The Listbox component allows users to select one or more items from a list. It can be used to build menus, select inputs, and other list-based UIs.
Installation
$ cbui-cli install @crossbuildui/listbox
cbui-cli
globally and authenticated your account. This will ensure you can access all the necessary features.Import
1import { Listbox, ListboxItem, ListboxSection } from '@/crossbuildui/listbox';
2// import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; // If using icons
3// import { View, Text } from 'react-native'; // For content
ListboxItem
uses react-native-vector-icons/MaterialIcons
. Ensure this library is installed and linked if you rely on the default icon or plan to use custom icons from this library.Basic Usage
Create a listbox by nesting ListboxItem
components within a Listbox
container. Each item needs a unique itemKey
.
1<Listbox aria-label="Basic Listbox Example">
2 <ListboxItem itemKey="item1">Item One</ListboxItem>
3 <ListboxItem itemKey="item2">Item Two</ListboxItem>
4 <ListboxItem itemKey="item3">Item Three</ListboxItem>
5</Listbox>
With Sections
Organize items into groups using the ListboxSection
component. Sections can have titles and optional dividers.
1<Listbox aria-label="Listbox with Sections">
2 <ListboxSection title="Actions" itemKey="actions-section">
3 <ListboxItem itemKey="new">New file</ListboxItem>
4 <ListboxItem itemKey="copy">Copy link</ListboxItem>
5 <ListboxItem itemKey="edit">Edit file</ListboxItem>
6 </ListboxSection>
7 <ListboxSection title="Danger Zone" itemKey="danger-section" showDivider>
8 <ListboxItem itemKey="delete" style={{color: 'red'}}>Delete file</ListboxItem>
9 </ListboxSection>
10</Listbox>
Selection Modes
Control selection behavior with selectionMode
: 'single'
, 'multiple'
, or 'none'
. Use defaultSelectedKeys
for uncontrolled initial selection or selectedKeys
for controlled selection.
1// Single Selection (default behavior if selectionMode is not 'none')
2<Listbox selectionMode="single" defaultSelectedKeys={["cat"]}>
3 <ListboxItem itemKey="dog">Dog</ListboxItem>
4 <ListboxItem itemKey="cat">Cat</ListboxItem>
5 <ListboxItem itemKey="mouse">Mouse</ListboxItem>
6</Listbox>
7
8// Multiple Selection
9<Listbox selectionMode="multiple" defaultSelectedKeys={["apple", "orange"]}>
10 <ListboxItem itemKey="apple">Apple</ListboxItem>
11 <ListboxItem itemKey="banana">Banana</ListboxItem>
12 <ListboxItem itemKey="orange">Orange</ListboxItem>
13</Listbox>
14
15// No Selection
16<Listbox selectionMode="none">
17 <ListboxItem itemKey="view">View Details</ListboxItem>
18 <ListboxItem itemKey="info">Information</ListboxItem>
19</Listbox>
Disabled Items & Listbox
Disable specific items using the disabledKeys
prop on Listbox
or the isDisabled
prop on ListboxItem
. The entire Listbox
can be disabled using its disabled
prop.
1<Listbox disabledKeys={["edit"]}>
2 <ListboxItem itemKey="new">New File</ListboxItem>
3 <ListboxItem itemKey="copy">Copy Link</ListboxItem>
4 <ListboxItem itemKey="edit">Edit File (Disabled)</ListboxItem>
5 <ListboxItem itemKey="delete" isDisabled>Delete File (Explicitly Disabled)</ListboxItem>
6</Listbox>
7
8// Entire Listbox disabled
9<Listbox disabled defaultSelectedKeys={["one"]}>
10 <ListboxItem itemKey="one">One</ListboxItem>
11 <ListboxItem itemKey="two">Two</ListboxItem>
12</Listbox>
Item Content & Structure
ListboxItem
supports title
, description
, startContent
, endContent
, and custom selectedIcon
. Providing children
to ListboxItem
will override the title
.
1<Listbox>
2 <ListboxItem
3 itemKey="profile"
4 title="User Profile"
5 description="Manage your account settings"
6 startContent={<Icon name="account-circle-outline" size={24} />}
7 endContent={<Icon name="chevron-right" size={20} />}
8 >
9 {/* Children override title, so title prop is ignored here */}
10 <View><Text style={{fontWeight: 'bold'}}>Custom Profile View</Text></View>
11 </ListboxItem>
12 <ListboxItem
13 itemKey="notifications"
14 title="Notifications"
15 description="Configure alerts"
16 startContent={<Icon name="bell-outline" size={24} />}
17 selectedIcon={<Icon name="star" size={20} color="gold" />}
18 />
19</Listbox>
Variants & Colors
Listbox supports solid
, bordered
, light
, flat
, faded
, and shadow
variants. Apply thematic colors using the color
prop.
1<View style={{flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-around'}}>
2 <Listbox variant="solid" color="primary" defaultSelectedKeys={["s1"]} style={{margin:5, width: 150}}>
3 <ListboxItem itemKey="s1">Solid Primary</ListboxItem>
4 </Listbox>
5 <Listbox variant="bordered" color="secondary" defaultSelectedKeys={["b1"]} style={{margin:5, width: 150}}>
6 <ListboxItem itemKey="b1">Bordered Secondary</ListboxItem>
7 </Listbox>
8 <Listbox variant="light" color="success" defaultSelectedKeys={["l1"]} style={{margin:5, width: 150}}>
9 <ListboxItem itemKey="l1">Light Success</ListboxItem>
10 </Listbox>
11 <Listbox variant="flat" color="warning" defaultSelectedKeys={["f1"]} style={{margin:5, width: 150}}>
12 <ListboxItem itemKey="f1">Flat Warning</ListboxItem>
13 </Listbox>
14 <Listbox variant="faded" color="danger" defaultSelectedKeys={["fd1"]} style={{margin:5, width: 150}}>
15 <ListboxItem itemKey="fd1">Faded Danger</ListboxItem>
16 </Listbox>
17 <Listbox variant="shadow" color="default" defaultSelectedKeys={["sh1"]} style={{margin:5, width: 150}}>
18 <ListboxItem itemKey="sh1">Shadow Default</ListboxItem>
19 </Listbox>
20</View>
Dynamic Items
Render items dynamically by providing an items
array and a renderItem
function, or by passing a function as children
.
1const users = [
2 { id: '1', name: 'Alice', avatar: 'https://i.pravatar.cc/150?u=alice' },
3 { id: '2', name: 'Bob', avatar: 'https://i.pravatar.cc/150?u=bob' },
4 { id: '3', name: 'Charlie', avatar: 'https://i.pravatar.cc/150?u=charlie' },
5];
6
7<Listbox
8 items={users}
9 renderItem={(user) => (
10 <ListboxItem
11 itemKey={user.id}
12 title={user.name}
13 startContent={<Image source={{ uri: user.avatar }} style={{ width: 30, height: 30, borderRadius: 15 }} />}
14 />
15 )}
16 aria-label="User List"
17/>
18
19// Alternative with children as a function
20<Listbox items={users} aria-label="User List Alt">
21 {(user) => (
22 <ListboxItem
23 itemKey={user.id}
24 title={user.name}
25 description={`User ID: ${user.id}`}
26 />
27 )}
28</Listbox>
Top & Bottom Content
Add custom content at the beginning or end of the list using topContent
and bottomContent
props.
1<Listbox topContent={<Text style={{padding:10, fontWeight:'bold'}}>Available Options</Text>}
2 bottomContent={<Text style={{padding:10, fontSize:10, textAlign:'center'}}>End of list</Text>}>
3 <ListboxItem itemKey="opt1">Option 1</ListboxItem>
4 <ListboxItem itemKey="opt2">Option 2</ListboxItem>
5</Listbox>
Empty State
Display custom content when the list is empty using the emptyContent
prop.
1<Listbox items={[]} emptyContent={<View style={{padding:20, alignItems:'center'}}><Text>No data found.</Text></View>}>
2 {(item) => <ListboxItem itemKey={item.id}>{item.name}</ListboxItem>}
3</Listbox>
Props Overview
Listbox Props
PROP | TYPE | DEFAULT | DESCRIPTION |
---|---|---|---|
children | ReactNode | (item) => ReactElement | - | Static items or render function for dynamic items. |
items | T[] | - | Array of data for dynamic rendering. |
renderItem | (item: T) => ReactElement | - | Function to render each item from the items array. |
variant | ListboxVariant | 'solid' | Visual style. |
color | ListboxColor | 'default' | Thematic color. |
selectionMode | ListboxSelectionMode | 'none' | Selection behavior. |
selectedKeys | Iterable<string|number> | - | Controlled selected item keys. |
defaultSelectedKeys | Iterable<string|number> | [] | Initially selected keys (uncontrolled). |
disabledKeys | Iterable<string|number> | [] | Keys of disabled items. |
disallowEmptySelection | boolean | false | Prevent deselection if it results in no selection. |
topContent | ReactNode | - | Content displayed above the list items. |
bottomContent | ReactNode | - | Content displayed below the list items. |
emptyContent | ReactNode | "No items." | Content displayed when list is empty. |
hideSelectedIcon | boolean | false | Hide selected state icon globally. |
style | StyleProp<ViewStyle> | - | Style for the Listbox container. |
itemStyle | Partial<ListboxItemSlots> | - | Global styles for all ListboxItem slots. |
onSelectionChange | (keys: Set<string|number>) => void | - | Callback when selection changes. |
disabled | boolean | false | Disable the entire Listbox. |
ListboxItem Props
PROP | TYPE | DEFAULT | DESCRIPTION |
---|---|---|---|
children | ReactNode | - | Custom content, overrides title . |
itemKey | string | number | - | Unique key for the item. **Required.** |
title | ReactNode | - | Primary text content of the item. |
textValue | string | - | Plain text representation for accessibility/typeahead. |
description | ReactNode | - | Secondary text content below the title. |
startContent | ReactNode | - | Content displayed before the main text. |
endContent | ReactNode | - | Content displayed after the selected icon (if visible). |
selectedIcon | ReactNode | (props) => ReactNode | Default Icon | Custom icon for selected state. |
showDivider | boolean | false | Show a divider below this item. |
hideSelectedIcon | boolean | Contextual | Override Listbox/Section setting for this item. |
style | StyleProp<ViewStyle> | - | Style for the item's outer Pressable . |
slotStyles | Partial<ListboxItemSlots> | - | Styles for inner parts of the item (title, description, etc.). |
isDisabled | boolean | false | Explicitly disable this item. |
ListboxSection Props
PROP | TYPE | DEFAULT | DESCRIPTION |
---|---|---|---|
children | ReactNode | - | ListboxItem components within this section. |
itemKey | string | number | - | Unique key for the section. Required. |
title | string | - | Title displayed above the section items. |
hideSelectedIcon | boolean | Contextual | Override Listbox's hideSelectedIcon for items in this section. |
showDivider | boolean | false | Show a divider after the section. |
dividerProps | StyleProp<ViewStyle> | - | Custom style for the section divider. |
style | StyleProp<ViewStyle> | - | Style for the section container. |
itemStyle | Partial<ListboxItemSlots> | - | Styles for ListboxItem slots within this section, overrides Listbox's itemStyle . |
Styling
Customize appearance using:
- Listbox:
style
: For the main Listbox container (View
).itemStyle
: Global styles for allListboxItem
slots (e.g.,base
,title
,description
).
- ListboxSection:
style
: For the section wrapperView
.itemStyle
: Styles forListboxItem
slots within this section, overriding Listbox'sitemStyle
.dividerProps
: Style for the section's bottom divider.
- ListboxItem:
style
: For the item's rootPressable
component.slotStyles
: Specific styles for inner parts of this item (e.g.,wrapper
,title
,startContentWrapper
), overriding section and ListboxitemStyle
.
Style precedence for item slots: ListboxItem.slotStyles
> ListboxSection.itemStyle
> Listbox.itemStyle
.
1<Listbox
2 style={{ marginVertical: 10, borderColor: 'purple', borderWidth: 1, borderRadius: 12 }} // Styles the Listbox container
3 itemStyle={{ // Global styles for all ListboxItem slots
4 base: { paddingVertical: 15 },
5 title: { fontWeight: '600', color: 'navy' },
6 description: { fontStyle: 'italic' }
7 }}
8 variant="flat"
9 color="primary"
10>
11 <ListboxSection
12 title="Custom Section"
13 itemKey="custom-sec"
14 style={{ backgroundColor: 'rgba(200,200,255,0.3)' }}
15 itemStyle={{ // Overrides Listbox's itemStyle for this section
16 title: { color: 'darkgreen' }
17 }}
18 >
19 <ListboxItem
20 itemKey="styled1"
21 title="Item with Specific Slot Styles"
22 slotStyles={{ // Styles for slots of this specific item
23 base: { borderLeftWidth: 3, borderLeftColor: 'orange' },
24 wrapper: { paddingLeft: 10 },
25 title: { textDecorationLine: 'underline', color: 'red' } // Overrides section and listbox itemStyle
26 }}
27 style={{ backgroundColor: 'lightyellow' }} // Style for the Pressable of this item
28 />
29 <ListboxItem itemKey="styled2" title="Section Styled Item" description="Inherits from section" />
30 </ListboxSection>
31 <ListboxItem itemKey="styled3" title="Listbox Styled Item" description="Inherits from listbox" />
32</Listbox>
Accessibility
The Listbox components are designed with accessibility in mind:
Listbox
container hasaccessibilityRole="list"
.- Each
ListboxItem
hasaccessibilityRole="menuitem"
(can be adjusted if used as a general selectable list). ListboxItem
includesaccessibilityState
forselected
anddisabled
states.ListboxItem
usestextValue
ortitle
for itsaccessibilityLabel
.