XauiXaui

BottomSheet

Beta

Swipeable bottom surface for transient content and actions.

Installation

npm install @xaui/native

Import

import { BottomSheet } from '@xaui/native/bottom-sheet'

Basic Usage

Minimal example showing the component with its default configuration.

import { BottomSheet } from '@xaui/native/bottom-sheet'
export function Example() {
return <BottomSheet />
}

Basic

Open a sheet with a single snap point.

import { useState } from 'react'
import { BottomSheet } from '@xaui/native/bottom-sheet'
import { Button } from '@xaui/native/button'
import { Typography } from '@xaui/native/typography'
import { Column, Padding } from '@xaui/native/view'
export function BasicExample() {
const [open, setOpen] = useState(false)
return (
<>
<Button onPress={() => setOpen(true)}>Open Sheet</Button>
<BottomSheet isOpen={open} onClose={() => setOpen(false)}>
<Padding all={24}>
<Column gap={12}>
<Typography variant="titleMedium">Bottom Sheet</Typography>
<Typography variant="bodyMedium">
Swipe down or tap the backdrop to dismiss.
</Typography>
<Button onPress={() => setOpen(false)}>Close</Button>
</Column>
</Padding>
</BottomSheet>
</>
)
}

Multiple Snap Points

Define several heights the sheet can snap to.

import { useState } from 'react'
import { BottomSheet } from '@xaui/native/bottom-sheet'
import { Button } from '@xaui/native/button'
import { Typography } from '@xaui/native/typography'
import { Column, Padding } from '@xaui/native/view'
export function MultiSnapExample() {
const [open, setOpen] = useState(false)
const [snapIndex, setSnapIndex] = useState(0)
return (
<>
<Button onPress={() => setOpen(true)}>Open Sheet</Button>
<BottomSheet
isOpen={open}
snapPoints={[0.3, 0.6, 0.9]}
initialSnapIndex={0}
onClose={() => setOpen(false)}
onSnapChange={setSnapIndex}
>
<Padding all={24}>
<Column gap={12}>
<Typography variant="titleMedium">
Snap index: {snapIndex}
</Typography>
<Typography variant="bodyMedium">
Drag the handle up or down to snap between 30 %, 60 %, and 90 % heights.
</Typography>
</Column>
</Padding>
</BottomSheet>
</>
)
}

Custom Handle

Replace the default handle with your own element.

import { useState } from 'react'
import { BottomSheet } from '@xaui/native/bottom-sheet'
import { Button } from '@xaui/native/button'
import { Typography } from '@xaui/native/typography'
import { Column, Padding, Row } from '@xaui/native/view'
import { View } from 'react-native'
export function CustomHandleExample() {
const [open, setOpen] = useState(false)
const handle = (
<Padding horizontal={24} vertical={16}>
<Row justifyContent="space-between" alignItems="center">
<Typography variant="titleSmall">Options</Typography>
<Button size="sm" variant="light" onPress={() => setOpen(false)}>
Done
</Button>
</Row>
</Padding>
)
return (
<>
<Button onPress={() => setOpen(true)}>Open Sheet</Button>
<BottomSheet
isOpen={open}
showHandle={false}
handleContent={handle}
onClose={() => setOpen(false)}
>
<Padding horizontal={24} bottom={32}>
<Column gap={8}>
{['Option A', 'Option B', 'Option C'].map(label => (
<Button key={label} variant="flat" fullWidth onPress={() => setOpen(false)}>
{label}
</Button>
))}
</Column>
</Padding>
</BottomSheet>
</>
)
}

Theme Colors

Style the sheet surface with a theme color.

import { useState } from 'react'
import { BottomSheet } from '@xaui/native/bottom-sheet'
import { Button } from '@xaui/native/button'
import { Typography } from '@xaui/native/typography'
import { Column, Padding } from '@xaui/native/view'
export function ThemeColorsExample() {
const [color, setColor] = useState<string | null>(null)
return (
<Column gap={8}>
{(['primary', 'success', 'warning', 'danger'] as const).map(c => (
<Button key={c} themeColor={c} onPress={() => setColor(c)}>
Open {c}
</Button>
))}
<BottomSheet
isOpen={color !== null}
themeColor={color as 'primary' | 'success' | 'warning' | 'danger'}
onClose={() => setColor(null)}
>
<Padding all={24}>
<Typography variant="titleMedium" style={{ textTransform: 'capitalize' }}>
{color} sheet
</Typography>
</Padding>
</BottomSheet>
</Column>
)
}