Photonix

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
Photonix UI - React Components, Templates & Figma Design System