Patterns
Mobile-Like Picker Surface
When to use:
- The flow benefits from bottom-sheet behavior.
Composition notes:
- Use snap points intentionally.
- Keep the first visible state large enough for the primary action or field group.
Trade-offs:
- Good touch ergonomics.
- More interaction complexity than a dialog.
mobile-like-picker-surface.tsx · 71 lines
import { useId, useState, type CSSProperties } from 'react';
import {
Button,
Heading,
Icon,
IconButton,
Sheet,
SheetClose,
SheetContent,
SheetHandle,
SheetTrigger,
Text,Long Scrollable Sheet
When to use:
- Content exceeds the comfortable viewport height.
Composition notes:
- Make the body an element with
overflow: auto; as a flex item ofSheetContentit shrinks on its own. - Keep the header and close affordances stable while the body moves.
Trade-offs:
- Preserves the sheet framing.
- Requires viewport testing.
long-scrollable-sheet.tsx · 47 lines
import { useId } from 'react';
import {
Button,
Heading,
Sheet,
SheetContent,
SheetHandle,
SheetTrigger,
Text,
} from '@vega-ui/react';
const names = ['Blue Harbor Cafe', 'Little Fern', 'Kiln & Co', 'Northside Roasters', 'The Daily Grind', 'Saltwater Bakery'];Blocking Step Sheet
When to use:
- A mobile-first flow must be completed before leaving.
Composition notes:
- Use
closedBy='none'onSheetContentonly when the completion path is obvious; a submit button in a<form method="dialog">still closes the sheet. - Keep the content short enough to work at every active snap point.
Trade-offs:
- Strong task guidance.
- Higher risk of trapping users in a confusing flow if copy is weak.
blocking-step-sheet.tsx · 41 lines
import { useId, useState } from 'react';
import {
Button,
Heading,
Sheet,
SheetContent,
SheetTrigger,
Text,
} from '@vega-ui/react';
export default function BlockingStepSheet() {
const titleId = useId();Comparison
Quick Decision Rule
Choose Sheet when the UX should feel like a touch-friendly or bottom-sheet interaction rather than a side drawer or centered modal.
Sheet vs Dialog
Use Sheet when:
- the presentation should feel sliding and touch-friendly
- content should emerge from the screen edge rather than appear as a centered modal
Use Dialog when:
- a centered modal is more appropriate
Sheet vs Drawer
Use Sheet when:
- bottom-sheet interaction or snap points matter
Use Drawer when:
- the panel should read as side-mounted
Choose This Component When
- snap points matter
- mobile-like panel behavior is intended
- gesture and bottom-entry metaphors are part of the UX
Do Not Choose This Component When
- the task is just a normal confirm modal
- side-panel semantics fit better
Troubleshooting
Snap Points Feel Wrong
Symptom
Intermediate sheet positions are awkward or unusable.
Likely Cause
Snap points were chosen without testing real content height.
How To Verify
- Test each snap point with realistic content.
Fix
- Tune snap points to actual content and viewport behavior.
Gesture And Keyboard Behavior Diverge
Symptom
Touch behavior feels acceptable, but keyboard or dismissal behavior feels broken.
Likely Cause
Only one interaction mode was tested.
How To Verify
- Test touch-like drag behavior.
- Test keyboard open and close flows.
Fix
- Validate all interaction modes together.
Non-Closable Sheet Feels Trapping
Symptom
Users do not understand how to finish or leave the flow.
Likely Cause
closedBy='none' on SheetContent is being used without a clear completion path or strong explanatory copy.
How To Verify
- Test the flow without prior product context.
- Check whether the next action is obvious at first glance.
Fix
- Add explicit completion actions and clearer copy.
- Reconsider whether the sheet really needs to be non-closable.