Overlay Components
Components that render above other content, typically as modals or dropdown menus. Both components handle their own backdrop and dismiss behavior.
import { Dialog, Menu } from '@/common/components';Dialog
A modal dialog with optional title, message, custom content, and action buttons. The dialog renders centered on screen with a dimmed backdrop.
Confirmation Dialog
const [visible, setVisible] = useState(false);
<Dialog
visible={visible}
onDismiss={() => setVisible(false)}
title="Delete Item?"
message="This action cannot be undone. Are you sure you want to delete this item?"
actions={[
{ label: 'Cancel', onPress: () => setVisible(false), variant: 'ghost' },
{ label: 'Delete', onPress: handleDelete, variant: 'primary' },
]}
/>Information Dialog
<Dialog
visible={visible}
onDismiss={() => setVisible(false)}
title="Update Available"
message="A new version of the app is available. Please update to get the latest features."
actions={[
{ label: 'Later', onPress: () => setVisible(false), variant: 'ghost' },
{ label: 'Update Now', onPress: handleUpdate, variant: 'primary' },
]}
/>With Custom Content
<Dialog
visible={visible}
onDismiss={() => setVisible(false)}
title="Rate This App"
actions={[{ label: 'Submit', onPress: handleSubmit, variant: 'primary' }]}
>
<Text color="secondary">How would you rate your experience?</Text>
<SegmentedControl
value={rating}
onChange={setRating}
options={[
{ label: '1', value: '1' },
{ label: '2', value: '2' },
{ label: '3', value: '3' },
{ label: '4', value: '4' },
{ label: '5', value: '5' },
]}
/>
</Dialog>Preventing Backdrop Dismiss
<Dialog
visible={visible}
onDismiss={() => setVisible(false)}
dismissOnBackdropPress={false}
title="Terms of Service"
message="You must accept the terms to continue."
actions={[
{ label: 'Accept', onPress: handleAccept, variant: 'primary' },
]}
/>DialogAction Type
interface DialogAction {
/** Text label on the button. */
label: string;
/** Press handler. */
onPress: () => void;
/** Button variant. Defaults to 'ghost'. */
variant?: 'primary' | 'secondary' | 'outline' | 'ghost';
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
visible | boolean | required | Controls dialog visibility |
onDismiss | () => void | required | Callback when the dialog is dismissed |
title | string | — | Title displayed at the top |
message | string | — | Message body below the title |
actions | DialogAction[] | [] | Action buttons in the footer |
children | ReactNode | — | Custom content between message and actions |
size | 'sm' | 'md' | 'lg' | 'md' | Size of the dialog card |
dismissOnBackdropPress | boolean | true | Whether tapping the backdrop dismisses the dialog |
Action buttons use the Button component internally. The variant on each action maps directly to Button’s variant prop, giving you full control over visual hierarchy (e.g., a ghost “Cancel” next to a primary “Confirm”).
Menu
A dropdown menu anchored to a trigger element. Supports icons, disabled items, and destructive actions.
Basic Usage
const [visible, setVisible] = useState(false);
<Menu
visible={visible}
onDismiss={() => setVisible(false)}
anchor={
<IconButton
icon="ellipsis-vertical"
accessibilityLabel="More options"
onPress={() => setVisible(true)}
/>
}
items={[
{ label: 'Edit', icon: 'create-outline', onPress: handleEdit },
{ label: 'Share', icon: 'share-outline', onPress: handleShare },
{ label: 'Delete', icon: 'trash-outline', onPress: handleDelete, destructive: true },
]}
/>With Disabled Items
<Menu
visible={visible}
onDismiss={() => setVisible(false)}
anchor={<IconButton icon="ellipsis-horizontal" accessibilityLabel="Actions" onPress={() => setVisible(true)} />}
items={[
{ label: 'Copy', icon: 'copy-outline', onPress: handleCopy },
{ label: 'Move', icon: 'move-outline', onPress: handleMove, disabled: true },
{ label: 'Archive', icon: 'archive-outline', onPress: handleArchive },
]}
/>MenuItem Type
interface MenuItem {
/** Display text. */
label: string;
/** Press handler. */
onPress: () => void;
/** Optional Ionicons icon name. */
icon?: IoniconsName;
/** Whether the item is disabled. Defaults to false. */
disabled?: boolean;
/** Destructive action styling (red text). Defaults to false. */
destructive?: boolean;
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
visible | boolean | required | Whether the menu is shown |
onDismiss | () => void | required | Callback when the menu is dismissed |
anchor | ReactNode | required | Trigger element used for positioning |
items | MenuItem[] | required | Array of menu items |
The anchor element should handle opening the menu by calling a state setter. The Menu component only handles rendering and dismissal — it does not automatically toggle visibility on anchor press.