Expo
ActionSheet
iOS-style bottom sheet with gesture-driven interactions, multiple detents, and optional Liquid Glass effect.
iOSAndroid
Installation
pnpm dlx @docyrus/cli add @docyrus/rn-action-sheet# Optional: expo-glass-effect (for Liquid Glass variant on iOS 26+)
npx expo install expo-glass-effectRequired Packages(4 packages)
pnpm add react-native-gesture-handler react-native-reanimated react-native-worklets expo-glass-effectNote:
expo-glass-effectis optional. ActionSheet works fully without it — theglassvariant gracefully falls back to thedefaultvariant when the module is not installed or when running on non-iOS 26+ devices.
Usage
import { ActionSheet } from '@/components/docyrus-native/action-sheet';
const [visible, setVisible] = useState(false);
<ActionSheet
visible={visible}
onClose={() => setVisible(false)}
title="Choose an action"
actions={[
{ key: 'edit', label: 'Edit', onPress: () => {} },
{ key: 'delete', label: 'Delete', destructive: true, onPress: () => {} },
]}
/>Glass Variant (iOS 26+)
<ActionSheet
visible={visible}
onClose={() => setVisible(false)}
variant="glass"
glassEffectStyle="regular"
title="Liquid Glass"
actions={actions}
/>Programmatic Control
Use SheetManager to show/hide sheets by ID without managing state directly:
import { ActionSheet, SheetManager } from '@/components/docyrus-native/action-sheet';
<ActionSheet
visible={visible}
onClose={() => setVisible(false)}
sheetId="my-sheet"
/>
// From anywhere:
SheetManager.show('my-sheet');
SheetManager.hide('my-sheet');Custom Content
Pass children instead of actions for fully custom sheet content:
<ActionSheet visible={visible} onClose={() => setVisible(false)} detent="large">
<Text>Any custom content here</Text>
</ActionSheet>API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
visible | boolean | — | Whether the sheet is visible |
onClose | () => void | — | Callback when the sheet is closed |
sheetId | string | — | Unique ID for programmatic control via SheetManager |
variant | 'default' | 'elevated' | 'minimal' | 'glass' | 'default' | Sheet visual style variant |
detent | 'small' | 'medium' | 'large' | 'fit' | 'medium' | Sheet height detent |
detents | ActionSheetDetent[] | — | Array of detents for multi-stop snapping |
title | string | — | Sheet header title |
message | string | — | Sheet header message below the title |
actions | ActionSheetAction[] | — | Array of action items to display |
showCancel | boolean | true | Show the cancel button at the bottom |
cancelLabel | string | 'Cancel' | Custom label for the cancel button |
showHandle | boolean | true | Show the drag handle at the top |
closeOnBackdrop | boolean | true | Close when tapping the backdrop |
glassEffectStyle | 'regular' | 'prominent' | 'clear' | — | Glass blur style (only with variant="glass") |
glassTintColor | string | — | Glass tint color override (only with variant="glass") |
children | ReactNode | — | Custom content instead of actions |
className | string | — | Additional CSS classes |
ActionSheetAction
| Prop | Type | Default | Description |
|---|---|---|---|
key | string | — | Unique identifier for the action |
label | string | — | Action button text |
icon | string | — | Emoji or text icon displayed before label |
destructive | boolean | false | Style as destructive (red text) |
disabled | boolean | false | Disable the action |
onPress | () => void | — | Callback when the action is pressed |
Translation Keys
Built-in copy is read through useUiTranslation() — provide these keys via <UiTranslationProvider>. Without a provider the English fallback is shown.
| Key | English fallback | Used for |
|---|---|---|
ui.common.cancel | Cancel | Cancel button (cancelLabel prop wins) |
Type Exports
| Type | Description |
|---|---|
ActionSheetProps | Props for ActionSheet component |
ActionSheetAction | Action item configuration |
ActionSheetDetent | 'small' | 'medium' | 'large' | 'fit' |
Compatibility
| Platform | Support |
|---|---|
| Expo Go | Yes (glass variant falls back to default) |
| Dev Client | Yes |
| Bare RN | Yes (glass variant requires expo-glass-effect config plugin) |