ExpansionPanel

Beta

A vertically stacked set of interactive headings that each reveal a section of content.

Preview

Light

ExpansionPanel Light screenshot

Bordered

ExpansionPanel Bordered screenshot

Splitted

ExpansionPanel Splitted screenshot

Installation

npm install @xaui/native

Basic Usage

import { ExpansionPanel, ExpansionPanelItem } from '@xaui/native/expansion-panel'
export function MyComponent() {
return (
<ExpansionPanel variant="light" showDivider>
<ExpansionPanelItem title="Section 1">
<Text>Content for section 1</Text>
</ExpansionPanelItem>
<ExpansionPanelItem title="Section 2">
<Text>Content for section 2</Text>
</ExpansionPanelItem>
</ExpansionPanel>
)
}

Variants

Three visual variants available: light (minimal), bordered (visible borders), and splitted (card-like).

// Light Variant - Clean, minimal appearance
<ExpansionPanel variant="light">
<ExpansionPanelItem title="Light Item">
<Text>Clean and minimal styling</Text>
</ExpansionPanelItem>
</ExpansionPanel>
// Bordered Variant - Visible borders around items
<ExpansionPanel variant="bordered">
<ExpansionPanelItem title="Bordered Item">
<Text>Items have visible borders</Text>
</ExpansionPanelItem>
</ExpansionPanel>
// Splitted Variant - Separated cards appearance
<ExpansionPanel variant="splitted">
<ExpansionPanelItem title="Splitted Item">
<Text>Items appear as separate cards</Text>
</ExpansionPanelItem>
</ExpansionPanel>

Sizing Options

Control the density with isCompact and width with fullWidth props.

// Compact Mode - Reduced padding for dense UIs
<ExpansionPanel isCompact>
<ExpansionPanelItem title="Compact Item">
<Text>Less padding, more items visible</Text>
</ExpansionPanelItem>
</ExpansionPanel>
// Full Width Control
<ExpansionPanel fullWidth={false}>
<ExpansionPanelItem title="Fixed Width">
<Text>Does not stretch to fill container</Text>
</ExpansionPanelItem>
</ExpansionPanel>

Selection Modes

Toggle mode allows only one expanded item at a time. Multiple mode allows multiple items to be expanded simultaneously.

// Toggle Mode - Only one item expanded at a time (default)
<ExpansionPanel selectionMode="toggle">
<ExpansionPanelItem itemKey="a" title="Item A">
<Text>Opening this closes Item B</Text>
</ExpansionPanelItem>
<ExpansionPanelItem itemKey="b" title="Item B">
<Text>Opening this closes Item A</Text>
</ExpansionPanelItem>
</ExpansionPanel>
// Multiple Mode - Multiple items can be expanded
<ExpansionPanel selectionMode="multiple">
<ExpansionPanelItem itemKey="a" title="Item A">
<Text>Can be expanded with Item B</Text>
</ExpansionPanelItem>
<ExpansionPanelItem itemKey="b" title="Item B">
<Text>Can be expanded with Item A</Text>
</ExpansionPanelItem>
</ExpansionPanel>

Events & Controlled State

Handle selection changes with onSelectionChange and individual item selection with onSelected.

import { useState } from 'react'
export function ControlledExample() {
const [expandedKeys, setExpandedKeys] = useState<string[]>(['item1'])
const handleSelectionChange = (keys: string[]) => {
console.log('Expanded items:', keys)
setExpandedKeys(keys)
}
const handleItemSelected = (isSelected: boolean) => {
console.log('Item selected state:', isSelected)
}
return (
<ExpansionPanel
expandedKeys={expandedKeys}
onSelectionChange={handleSelectionChange}
>
<ExpansionPanelItem
itemKey="item1"
title="Controlled Item"
onSelected={handleItemSelected}
>
<Text>This item is controlled externally</Text>
</ExpansionPanelItem>
</ExpansionPanel>
)
}

Disabled Items

Disable specific items by their keys to prevent interaction.

// Disabled Items
<ExpansionPanel disabledKeys={['disabled-item']}>
<ExpansionPanelItem itemKey="enabled" title="Enabled Item">
<Text>This item can be interacted with</Text>
</ExpansionPanelItem>
<ExpansionPanelItem itemKey="disabled-item" title="Disabled Item">
<Text>This item cannot be expanded</Text>
</ExpansionPanelItem>
</ExpansionPanel>

Default Expanded State

Set items to be expanded by default using defaultExpandedKeys.

// Default Expanded Keys
<ExpansionPanel defaultExpandedKeys={['intro', 'details']}>
<ExpansionPanelItem itemKey="intro" title="Introduction">
<Text>Expanded by default</Text>
</ExpansionPanelItem>
<ExpansionPanelItem itemKey="details" title="Details">
<Text>Also expanded by default</Text>
</ExpansionPanelItem>
<ExpansionPanelItem itemKey="extra" title="Extra">
<Text>Collapsed by default</Text>
</ExpansionPanelItem>
</ExpansionPanel>

Customization

Customize appearance with customAppearance prop, hide indicators, or disable animations.

// Custom Appearance
<ExpansionPanel
customAppearance={{
container: { backgroundColor: '#f5f5f5', borderRadius: 12 },
item: { marginVertical: 4 }
}}
>
<ExpansionPanelItem
title="Custom Styled Item"
subtitle="With custom subtitle"
startContent={<Icon name="settings" />}
customAppearance={{
base: { backgroundColor: 'white' },
title: { fontSize: 18, fontWeight: 'bold' },
subtitle: { color: '#666' },
content: { padding: 16 }
}}
>
<Text>Custom styled content</Text>
</ExpansionPanelItem>
</ExpansionPanel>
// Hide Indicator
<ExpansionPanel hideIndicator>
<ExpansionPanelItem title="No Indicator">
<Text>Chevron icon is hidden</Text>
</ExpansionPanelItem>
</ExpansionPanel>
// Disable Animation
<ExpansionPanel disableAnimation>
<ExpansionPanelItem title="No Animation">
<Text>Expands/collapses instantly</Text>
</ExpansionPanelItem>
</ExpansionPanel>