Sheet
A container that slides in from the screen edge while preserving context on the underlying page.
Preview
Usage
"use client";
import { useState } from 'react';
import { AppBar, Button, Sheet, Stack, Text, Toolbar } from '@photonix/ultimate';
export default function SheetBasicExample() {
const [open, setOpen] = useState(false);
return (
<Stack gap="md">
<Button variant="primary" onClick={() => setOpen(true)}>Open Sheet</Button>
<Sheet
open={open}
onClose={() => setOpen(false)}
maxWidth="mobile"
header={<AppBar title="Project details" />}
footer={(
<Toolbar>
<Button variant="secondary" onClick={() => setOpen(false)}>Close</Button>
<Button variant="primary" onClick={() => setOpen(false)}>Save</Button>
</Toolbar>
)}
>
<Text variant="body-md" color="secondary">
Use sheets for focused workflows that keep users in context.
</Text>
</Sheet>
</Stack>
);
}Component API
Sheet
Prop | Type | Default | Description |
|---|---|---|---|
header | React.ReactNode | - | Header content - typically an AppBar component |
children | React.ReactNode | - | Main scrollable content area |
footer | React.ReactNode | - | Footer content - typically a Toolbar component |
open | boolean | true | Whether the sheet is open/visible |
onClose | (() => void) | - | Callback when sheet should close (e.g., clicking overlay) |
maxWidth | "auto" | "full" | "mobile" | "tablet" | "desktop" | 'auto' | Maximum width of the sheet - 'auto': Responsive based on viewport (default) - 'mobile': 360px - 'tablet': 600px - 'desktop': 900px - 'full': 100% |
height | "auto" | "full" | "fixed" | 'auto' | Height behavior - 'auto': Content determines height (default) - 'full': Full viewport height - 'fixed': Fixed height (use with style.height) |
showGrabber | boolean | false | Show grabber bar at top (for mobile bottom sheets) |
showCloseButton | boolean | false | Show a floating close button in the sheet corner. |
closeButtonVariant | "on-surface" | "spotlight" | 'on-surface' | Floating close button surface treatment. - 'on-surface': neutral on-surface background - 'spotlight': primary surface background for image/spotlight sheets |
closeButtonAriaLabel | string | 'Close' | Accessible label for the floating close button. |
footerElevationVariant | "none" | "shadow" | "gradient" | 'shadow' | |
noPadding | boolean | false | Disable default horizontal padding |
initialFocusRef | React.RefObject<HTMLElement | null> | - | Element to focus when the sheet opens |
Variants
Mobile Bottom Sheet
Use a grabber and auto height when the sheet behaves like a mobile action surface.
Mobile Bottom Sheet
"use client";
import { useState } from 'react';
import { AppBar, Box, Button, Flex, IconButton, Sheet, Text, Toolbar } from '@photonix/ultimate';
import { CloseOutline } from '@photonix/icons';
export default function SheetMobileSheetExample() {
const [open, setOpen] = useState(false);
return (
<>
<Button variant="secondary" onClick={() => setOpen(true)}>Open scaffolded sheet</Button>
<Sheet
open={open}
onClose={() => setOpen(false)}
showGrabber
height="auto"
header={
<AppBar
title="Edit Profile"
leading={
<IconButton
variant="tertiary"
icon={<CloseOutline />}
aria-label="Close"
onClick={() => setOpen(false)}
/>
}
/>
}
footer={
<Toolbar>
<Flex gap="xs" w="100%">
<Button variant="secondary" style={{ flex: 1 }} onClick={() => setOpen(false)}>Cancel</Button>
<Button variant="primary" style={{ flex: 1 }}>Save</Button>
</Flex>
</Toolbar>
}
>
<Box py="md">
<Text color="secondary">Use sticky header and footer slots to turn Sheet into a full workflow scaffold.</Text>
</Box>
</Sheet>
</>
);
}Full Screen
Use full width and full height for immersive editing or multi-step flows.
Full Screen
"use client";
import { useState } from 'react';
import { AppBar, Box, Button, Heading, IconButton, Sheet, Text } from '@photonix/ultimate';
import { ChevronLeftOutline } from '@photonix/icons';
export default function SheetFullScreenExample() {
const [open, setOpen] = useState(false);
return (
<>
<Button variant="secondary" onClick={() => setOpen(true)}>Open full-screen sheet</Button>
<Sheet
open={open}
onClose={() => setOpen(false)}
height="full"
maxWidth="full"
header={
<AppBar
title="Project Configuration"
leading={<IconButton variant="tertiary" icon={<ChevronLeftOutline />} aria-label="Back" onClick={() => setOpen(false)} />}
trailing={<Button variant="primary" size="large">Publish</Button>}
/>
}
>
<Box py="xl" display="flex" flexDirection="column" justifyContent="center" minH="100%">
<Heading size="headline-sm">Deep Focus Mode</Heading>
<Box mt="sm">
<Text color="secondary">Move complex configuration flows into a full-screen sheet when the task needs dedicated attention.</Text>
</Box>
</Box>
</Sheet>
</>
);
}On this page
Preview
Component API
Variants