Skip to main content

Accordion

A flexible, theme-aware collapsible container for FAQs, settings, or any expandable content.

Import

import { Accordion } from '@lazy-panda-ui/lazy-panda-ui';

Usage

Basic

function Basic() {
return (
<Accordion title="What is Lazy Panda UI?" subtitle="Tap to learn more">
<Text>
Lazy Panda UI is a modern React Native component library for building beautiful cross-platform apps.
</Text>
</Accordion>
);
}

Variants

function Variants() {
return (
<>
<Accordion title="Default" variant="default">
<Text>Default variant with bottom border.</Text>
</Accordion>

<Accordion title="Outlined" variant="outlined">
<Text>Outlined container with border and radius.</Text>
</Accordion>

<Accordion title="Contained" variant="contained">
<Text>Contained with themed surface variant background.</Text>
</Accordion>
</>
);
}

Custom icons and position

function Icons() {
return (
<Accordion
title="Custom Icons"
expandIcon={<Text></Text>}
collapseIcon={<Text></Text>}
iconPosition="start"
>
<Text>Icon can be at start or end and fully custom.</Text>
</Accordion>
);
}

Controlled

function Controlled() {
const [expanded, setExpanded] = useState(false);
return (
<Accordion
title="Controlled Accordion"
expanded={expanded}
onChange={setExpanded}
>
<Text>This accordion's state is controlled externally.</Text>
</Accordion>
);
}

Imperative control (ref)

import type { AccordionRef } from '@lazy-panda-ui/lazy-panda-ui';

function Imperative() {
const ref = useRef<AccordionRef>(null);
return (
<>
<Accordion ref={ref} title="Imperative Accordion">
<Text>Use the buttons below to control me.</Text>
</Accordion>
<Button title="Expand" onPress={() => ref.current?.expand()} />
<Button title="Collapse" onPress={() => ref.current?.collapse()} />
<Button title="Toggle" onPress={() => ref.current?.toggle()} />
</>
);
}

Header actions and styles

function HeaderRightActions() {
return (
<Accordion
title="With Actions"
subtitle="You can place controls on the right"
headerRight={<Button title="Action" onPress={() => {}} />}
headerStyle={{ padding: 20 }}
containerStyle={{ borderRadius: 12 }}
>
<Text>Customize container, header, title, subtitle and content styles.</Text>
</Accordion>
);
}

Props

Main

PropTypeDefaultDescription
titlestringrequiredHeader title
subtitlestring-Optional subtitle
childrenReact.ReactNoderequiredContent shown when expanded
expandedboolean-Controlled expanded state
onChange(expanded: boolean) => void-Called on toggle (for controlled use)
variant'default' \'outlined' \'contained'
iconPosition'start' \'end''end'
disabledbooleanfalseDisables interaction
expandIconReact.ReactNode-Custom icon when expanded
collapseIconReact.ReactNode-Custom icon when collapsed
headerRightReact.ReactNode-Extra content aligned to the right in header

Style props

All style props accept React Native StyleProp wrappers for better compatibility.

PropTypeDescription
containerStyleStyleProp<ViewStyle>Container styles
headerStyleStyleProp<ViewStyle>Header row styles
titleStyleStyleProp<TextStyle>Title text styles
subtitleStyleStyleProp<TextStyle>Subtitle text styles
contentStyleStyleProp<ViewStyle>Content container styles

Accessibility

PropTypeDescription
testIDstringTest identifier

Theming

Accordion is fully themeable via ThemeProvider tokens. Override only what you need.

import { ThemeProvider, createTheme } from '@lazy-panda-ui/lazy-panda-ui';

const customTheme = createTheme({
accordion: {
container: {
borderRadius: 16,
borderColor: '#E5E7EB',
borderWidth: 1,
backgroundColor: '#FFFFFF',
},
header: {
padding: 20,
minHeight: 56,
titleColor: '#111827',
subtitleColor: '#6B7280',
backgroundColor: '#FFFFFF',
borderColor: '#E5E7EB',
borderWidth: 0,
},
content: {
padding: 16,
backgroundColor: '#FFFFFF',
},
icon: {
size: 24,
color: '#6B7280',
},
animation: {
duration: 200,
easing: 'easeInOut',
},
},
});

export function App() {
return (
<ThemeProvider theme={customTheme}>
<Accordion title="Themed Accordion" subtitle="Using theme overrides">
<Text>All styles are driven by theme tokens.</Text>
</Accordion>
</ThemeProvider>
);
}

Notes:

  • Rotation uses the native driver and LayoutAnimation on Android.
  • The component supports both controlled and uncontrolled modes.
  • No useInsertionEffect usage; safe with React 18/19.