Accordion

The Accordion component allows users to toggle the visibility of sections of content. It's useful for managing complex information in a compact space.

Installation

$ cbui-cli install @crossbuildui/accordion

Import

index.tsx
1import { Accordion, AccordionItem } from '@/crossbuildui/accordion'; 2// import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; // If using custom icons for indicators or startContent

Basic Usage

Nest AccordionItem components within an Accordion. Each AccordionItem requires a unique itemKey and a title.

index.tsx
1<Accordion> 2 <AccordionItem itemKey="1" title="What is CrossBuild UI?"> 3 CrossBuild UI is a Expo component library designed for building beautiful and consistent user interfaces across platforms. 4 </AccordionItem> 5 <AccordionItem itemKey="2" title="How to install components?"> 6 You can install components using the cbui-cli: `cbui-cli install @crossbuildui/component-name`. 7 </AccordionItem> 8 <AccordionItem itemKey="3" title="Is it customizable?"> 9 Yes, components are highly customizable through props and styling options. 10 </AccordionItem> 11</Accordion>

Selection Modes

Control how many items can be expanded at once using the selectionMode prop:'single' (default) allows only one item to be open, while 'multiple' allows several. Use defaultExpandedKeys to set initially open items.

index.tsx
1// Single selection (default) 2<Accordion selectionMode="single"> 3 <AccordionItem itemKey="s1" title="Section 1">Content for section 1.</AccordionItem> 4 <AccordionItem itemKey="s2" title="Section 2">Content for section 2.</AccordionItem> 5</Accordion> 6 7// Multiple selection 8<Accordion selectionMode="multiple" defaultExpandedKeys={["m1"]}> 9 <AccordionItem itemKey="m1" title="Feature A">Details about Feature A.</AccordionItem> 10 <AccordionItem itemKey="m2" title="Feature B">Details about Feature B.</AccordionItem> 11 <AccordionItem itemKey="m3" title="Feature C">Details about Feature C.</AccordionItem> 12</Accordion>

Variants

Accordion supports several visual variant options: 'default', 'light', 'shadow', 'bordered', and 'splitted'. These variants can be further customized using color props like accordionBackgroundColor, accordionBorderColor, accordionShadowColor, and defaultItemBorderColor.

index.tsx
1<Accordion variant="light"> 2 <AccordionItem itemKey="l1" title="Light Variant Item 1">Content...</AccordionItem> 3</Accordion> 4 5<Accordion variant="bordered"> 6 <AccordionItem itemKey="b1" title="Bordered Variant Item 1">Content...</AccordionItem> 7 <AccordionItem itemKey="b2" title="Bordered Variant Item 2">Content...</AccordionItem> 8</Accordion> 9 10<Accordion variant="shadow"> 11 <AccordionItem itemKey="sh1" title="Shadow Variant Item 1">Content...</AccordionItem> 12</Accordion> 13 14<Accordion variant="splitted"> 15 <AccordionItem itemKey="sp1" title="Splitted Item 1">Content...</AccordionItem> 16 <AccordionItem itemKey="sp2" title="Splitted Item 2">Content...</AccordionItem> 17</Accordion>

Compact Mode

Enable compact mode for a denser layout with reduced padding and smaller text sizes.

index.tsx
1<Accordion compact> 2 <AccordionItem itemKey="c1" title="Compact Item 1" subtitle="A small subtitle"> 3 This is a compact accordion item. 4 </AccordionItem> 5 <AccordionItem itemKey="c2" title="Compact Item 2"> 6 Less padding and smaller text. 7 </AccordionItem> 8</Accordion>

Disabled Items

Prevent specific items from being opened by passing their keys to the disabledKeys array.

index.tsx
1<Accordion disabledKeys={["disabled-2"]}> 2 <AccordionItem itemKey="enabled-1" title="Enabled Item">This item can be opened.</AccordionItem> 3 <AccordionItem itemKey="disabled-2" title="Disabled Item">This item cannot be opened.</AccordionItem> 4 <AccordionItem itemKey="enabled-3" title="Another Enabled Item">This one works too.</AccordionItem> 5</Accordion>

Indicators

Customize the open/close indicator per item using the indicator prop on AccordionItem, or hide all indicators with hideIndicator on Accordion. The default indicator color can be set globally using the defaultIndicatorColor prop on Accordion. A custom indicator function receives isOpen, themeColors, and the resolved color as props.

index.tsx
1// Using a function for the indicator 2const CustomArrowIndicator = ({ isOpen, themeColors, color }) => ( 3 <Icon name={isOpen ? "chevron-up" : "chevron-down"} size={24} color={color} /> // 'color' is the resolved indicator color 4); 5 6<Accordion> 7 <AccordionItem itemKey="ci1" title="Item with Custom Indicator" indicator={CustomArrowIndicator}> 8 Content for item with custom indicator. The 'color' prop passed to CustomArrowIndicator is determined by 'defaultIndicatorColor' or theme. 9 </AccordionItem> 10 <AccordionItem itemKey="ci2" title="Item with Text Indicator" indicator="➡️"> 11 Content for item with text indicator. 12 </AccordionItem> 13</Accordion> 14 15// Hiding indicator 16<Accordion hideIndicator> 17 <AccordionItem itemKey="hi1" title="No Indicator Here"> 18 The indicator is hidden for all items in this accordion. 19 </AccordionItem> 20</Accordion>

Start Content

Add icons or other elements before the title using the startContent prop on AccordionItem.

index.tsx
1<Accordion> 2 <AccordionItem 3 itemKey="sc1" 4 title="User Settings" 5 startContent={<Icon name="account-cog-outline" size={24} color="purple" />} 6 > 7 Manage your profile and preferences. 8 </AccordionItem> 9 <AccordionItem 10 itemKey="sc2" 11 title="Notifications" 12 startContent={<Icon name="bell-outline" size={24} color="orange" />} 13 > 14 Configure your notification settings. 15 </AccordionItem> 16</Accordion>

Animations

Content expansion and collapse are animated by default using fade effects. Customize animations via the motionProps prop on Accordion. You can provide duration for the default fade, or custom entering and exiting animations from react-native-reanimated. Other Animated.View props can also be passed.

index.tsx
1// Using default fade animations (implicitly enabled if motionProps is present) 2<Accordion motionProps={{ duration: 500 }}> 3 <AccordionItem itemKey="anim1" title="Animated Item (Default)"> 4 This content will fade in and out. 5 </AccordionItem> 6</Accordion> 7 8// To disable default animations if motionProps is used for other reasons (e.g. only style) 9// or if you want to provide fully custom reanimated animations: 10import Animated, { SlideInLeft, SlideOutRight } from 'react-native-reanimated'; 11 12<Accordion 13 motionProps={{ 14 entering: SlideInLeft.duration(400), 15 exiting: SlideOutRight.duration(400), 16 // style: { borderWidth: 1, borderColor: 'red' } // Can also pass style to Animated.View 17 }} 18> 19 <AccordionItem itemKey="anim2" title="Custom Animation"> 20 This content uses custom slide animations. 21 </AccordionItem> 22</Accordion>

Dividers

Control the visibility of dividers between items using the showDivider prop on Accordion. By default, dividers are shown for most variants. They are hidden by default for 'splitted' and 'bordered' variants as these items typically manage their own separation or borders. The color of the default divider can be set using defaultDividerColor.

index.tsx
1<Accordion showDivider={false}> 2 <AccordionItem itemKey="d1" title="No Dividers Here">Content.</AccordionItem> 3 <AccordionItem itemKey="d2" title="Still No Dividers">Content.</AccordionItem> 4</Accordion> 5 6// Note: 'splitted' and 'bordered' variants hide dividers by default. 7// To show them, explicitly set showDivider={true} 8<Accordion variant="bordered" showDivider={true}> 9 <AccordionItem itemKey="d3" title="Bordered with Divider">Content.</AccordionItem> 10 <AccordionItem itemKey="d4" title="Another Bordered with Divider">Content.</AccordionItem> 11</Accordion>

Props Overview

Accordion Props

PROPTYPEDEFAULTDESCRIPTION
childrenReactNode-The AccordionItem components.
variant'default' | 'light' | 'shadow' | 'bordered' | 'splitted''default'Visual style.
selectionMode'single' | 'multiple''single'Expansion behavior.
defaultExpandedKeysstring[][]Keys of initially expanded items.
disabledKeysstring[][]Keys of disabled items.
hideIndicatorbooleanfalseHide open/close indicators.
itemClassesPartial<AccordionItemClasses>-Custom styles for AccordionItem slots, applied to all items.
motionPropsobject-Props for item content animations (e.g., duration, entering, exiting from reanimated, other Animated.View props).
compactbooleanfalseEnable compact mode.
showDividerbooleantrue (false for bordered/splitted)Show dividers. Defaults to true, but false for 'bordered'/'splitted' variants unless overridden.
styleStyleProp<ViewStyle>-Style for the Accordion container.
onSelectionChange(keys: Set<string>) => void-Callback when expanded items change.
defaultTitleColorstring-Default color for item titles. Overrides theme, can be overridden by itemClasses.title.color.
defaultSubtitleColorstring-Default color for item subtitles. Overrides theme, can be overridden by itemClasses.subtitle.color.
defaultIndicatorColorstring-Default color for item indicators. Overrides theme, can be overridden by itemClasses.indicator styles.
defaultItemBorderColorstring-Border color for items in 'bordered'/'splitted' variants. Overrides theme, can be overridden byitemClasses.base.borderColor.
defaultDividerColorstring-Color for dividers. Overrides theme, can be overridden by itemClasses.divider.backgroundColor.
accordionBackgroundColorstring-Background color for Accordion container (esp. 'light', 'shadow' variants). Overrides variant defaults.
accordionBorderColorstring-Border color for Accordion container ('bordered' variant). Overrides variant default.
accordionShadowColorstring-Shadow color for Accordion container ('shadow' variant). Overrides variant default.

AccordionItem Props

PROPTYPEDEFAULTDESCRIPTION
itemKeystring-Unique key for the item. Required
titleReactNode-Title of the item. Required
childrenReactNode-Content to display when expanded. Required
subtitleReactNode-Optional subtitle below the title.
startContentReactNode-Content before the title.
indicatorReactNode | (props: { isOpen: boolean; themeColors: ThemeColors; color: string }) => ReactNodeDefault IconCustom indicator. Can be ReactNode or a function receiving isOpen, themeColors, and resolved color.
styleStyleProp<ViewStyle>-Style for the AccordionItem's base wrapper. Overrides itemClasses.base for this item.
onPressPressableProps['onPress']-Callback for press events on the item header.
onFocusPressableProps['onFocus']-Callback for focus events.
onBlurPressableProps['onBlur']-Callback for blur events.

Styling

Customize the appearance using:

  • style prop on Accordion for its main container.
  • Top-level color props on Accordion (e.g., defaultTitleColor, accordionBackgroundColor, defaultItemBorderColor) to set default colors for the accordion container and various parts of its items. These props override theme-based defaults.
  • itemClasses prop on Accordion to provide styles for various slots of all child AccordionItem components. Styles in itemClasses can override the global default...Color props (e.g., itemClasses.title.color overrides defaultTitleColor). Available slots:
    • base: The main wrapper for an AccordionItem.
    • heading: The touchable area containing the trigger.
    • trigger: The interactive element that toggles the item.
    • titleWrapper: Wrapper around title and subtitle.
    • title: The main title text.
    • subtitle: The subtitle text.
    • startContent: Container for content before the title.
    • indicator: The open/close indicator.
    • content: The collapsible content area.
    • divider: The divider line between items.
  • style prop on an individual AccordionItem to style its base wrapper, overriding global itemClasses.base and relevant default color props (like defaultItemBorderColor via borderColor) for that specific item.
  • For fine-grained control over specific elements like title or subtitle within an item, pass a custom ReactNode with inline styles to the respective prop (e.g., title={<Text style={{color: 'red'}}>Custom Title</Text>}).
index.tsx
1<Accordion 2 variant="splitted" // Using splitted to demonstrate item borders 3 accordionBackgroundColor="whitesmoke" // Background for the Accordion container 4 defaultTitleColor="darkslateblue" // Default color for all item titles 5 defaultSubtitleColor="slategray" // Default color for all item subtitles 6 defaultIndicatorColor="teal" // Default color for all item indicators 7 defaultItemBorderColor="mediumseagreen" // Border color for 'splitted' or 'bordered' items 8 // defaultDividerColor would apply if dividers were shown for this variant 9 style={{ paddingHorizontal: 8, marginVertical: 10 }} // Additional styles for Accordion container 10 itemClasses={{ 11 // 'base' styles for splitted items are affected by defaultItemBorderColor 12 heading: { backgroundColor: '#e0f0e0', paddingVertical: 12 }, 13 title: { fontWeight: '600' }, // itemClasses.title.color could override defaultTitleColor 14 subtitle: { fontStyle: 'italic' }, 15 content: { paddingVertical: 12, backgroundColor: '#f0fff0' }, 16 // divider: { backgroundColor: 'red' } // Customize divider if shown 17 }} 18> 19 <AccordionItem 20 itemKey="style1" 21 title="Item 1 with Custom Styling" 22 subtitle="Using global and class-based styles" 23 // 'style' prop on AccordionItem overrides itemClasses.base & defaultItemBorderColor for this specific item's border 24 style={{ shadowColor: 'black', shadowOffset: {width: 0, height: 1}, shadowOpacity: 0.2, shadowRadius: 2, elevation: 3 }} 25 > 26 This item inherits default colors, gets some styles from itemClasses, and has its own shadow via the 'style' prop. 27 </AccordionItem> 28 <AccordionItem itemKey="style2" title="Item 2 (Styled via Accordion Props)"> 29 This item inherits styles from itemClasses. 30 </AccordionItem> 31</Accordion>

Accessibility

The Accordion component is designed with accessibility in mind:

  • The Accordion container has accessibilityRole="list".
  • Each AccordionItem header (Pressable) has accessibilityRole="button".
  • Item headers include accessibilityState indicating if they are expanded or disabled.
  • Item headers have an accessibilityLabel derived from their title.