@gradeui/ui 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,16 +6,24 @@ props:
6
6
  - Sheet: open?, defaultOpen?, onOpenChange?, modal? (default true)
7
7
  - SheetTrigger: asChild?: boolean
8
8
  - SheetContent: side? "top" | "right" | "bottom" | "left" (default "right")
9
+ - SheetContent: surface? (solid | translucent | glass | glass-strong) — what the sheet panel is *made of*. `solid` is the default opaque `bg-background`. Reach for `glass` whenever the canvas behind the sheet (a layout in progress, a media gallery, a dashboard) should remain visible.
9
10
  - SheetContent: className?: string — usually set a width (right/left) or height (top/bottom)
10
11
  - SheetTitle / SheetDescription: identify the sheet to screen readers; required for accessibility even if visually styled differently
11
12
  - SheetClose: asChild? — usually wraps a Button labelled Cancel or Done
12
- when_to_use: A panel that slides in from a screen edge — mobile nav drawers, side panels for editing a single record without leaving the list, filter trays on small viewports. For a centered focus modal use Dialog. For a transient announcement use Toast (Sonner). For inline reveals use Collapsible.
13
- composes_with: [Form controls (an inline edit sheet), Button (trigger + close), AppShellNav (mobile-only swap)]
14
- aliases: [sheet, drawer, side panel, slide-in, nav drawer, mobile drawer, slide-over, action sheet, modal sheet, bottom sheet, side sheet, react native modal sheet, bottom-sheet, ios action sheet]
13
+ when_to_use: A panel that slides in from a screen edge — mobile nav drawers, side panels for editing a single record without leaving the list, filter trays on small viewports, Studio-style inspector panels. For a centered focus modal use Dialog. For a transient announcement use Toast (Sonner). For inline reveals use Collapsible.
14
+ composes_with: [Form controls (an inline edit sheet), Button (trigger + close), AppShellNav (mobile-only swap), Code (changelog drawers), MediaSurface (image-detail sheets)]
15
+ aliases: [sheet, drawer, side panel, slide-in, nav drawer, mobile drawer, slide-over, action sheet, modal sheet, bottom sheet, side sheet, react native modal sheet, bottom-sheet, ios action sheet, inspector panel, glass sheet, frosted drawer]
15
16
  ---
16
17
 
18
+ SheetContent sits at elevation-5. The `surface` axis controls material independently of `side` (which controls layout direction) — every combination is valid.
19
+
20
+ ---
21
+
22
+ ### Scenario 1 — Edit-record drawer (default opaque)
23
+
24
+ A right-edge drawer that lets a user edit one record without losing their place in a list. The list is the user's context — the drawer doesn't need to blur it; it just needs to be visibly distinct.
25
+
17
26
  ```jsx
18
- // Edit-record drawer from the right edge.
19
27
  <Sheet>
20
28
  <SheetTrigger asChild>
21
29
  <Button variant="outline">Edit user</Button>
@@ -45,8 +53,92 @@ aliases: [sheet, drawer, side panel, slide-in, nav drawer, mobile drawer, slide-
45
53
  </Sheet>
46
54
  ```
47
55
 
48
- SheetContent ships at elevation-5. Opt into a frosted glass sheet when the canvas behind it should remain visible:
56
+ `solid` is the right default for editing workflows. Form fields need maximum legibility; blur behind them works against that.
57
+
58
+ ---
59
+
60
+ ### Scenario 2 — Glass inspector panel (creative tool aesthetic)
61
+
62
+ You're building a creative tool. The canvas is the work — a Studio layout, an image being annotated, a presentation slide. The inspector panel needs to live alongside the work without obscuring it. Glass is the canonical "I am chrome, not content" signal.
63
+
64
+ ```jsx
65
+ <Sheet open={hasSelection} modal={false}>
66
+ <SheetContent
67
+ side="right"
68
+ surface="glass"
69
+ className="w-96 shadow-elevation-5"
70
+ >
71
+ <SheetHeader>
72
+ <SheetTitle>Selection</SheetTitle>
73
+ <SheetDescription>Button — Toolbar &gt; trailing</SheetDescription>
74
+ </SheetHeader>
75
+
76
+ <Stack gap="md" className="py-4">
77
+ <Stack gap="xs">
78
+ <Label>Variant</Label>
79
+ <Select defaultValue="raised">{/* … */}</Select>
80
+ </Stack>
81
+ <Stack gap="xs">
82
+ <Label>Size</Label>
83
+ <ToggleGroup type="single" defaultValue="md">
84
+ <ToggleGroupItem value="sm">sm</ToggleGroupItem>
85
+ <ToggleGroupItem value="md">md</ToggleGroupItem>
86
+ <ToggleGroupItem value="lg">lg</ToggleGroupItem>
87
+ </ToggleGroup>
88
+ </Stack>
89
+ </Stack>
90
+ </SheetContent>
91
+ </Sheet>
92
+ ```
93
+
94
+ Three things to notice: `modal={false}` so the user keeps interacting with the canvas while the inspector is open; `surface="glass"` so the canvas reads through; `shadow-elevation-5` to lift the panel cleanly off the canvas. This is the Studio inspector pattern.
95
+
96
+ ---
97
+
98
+ ### Scenario 3 — Bottom action sheet (mobile, glass for iOS feel)
99
+
100
+ The iOS-native action sheet has glass behind it. Matching that material on mobile flows is "feels like a native app" by default.
101
+
102
+ ```jsx
103
+ <Sheet open={pickerOpen} onOpenChange={setPickerOpen}>
104
+ <SheetContent
105
+ side="bottom"
106
+ surface="glass"
107
+ className="rounded-t-2xl"
108
+ >
109
+ <SheetHeader className="text-center">
110
+ <SheetTitle>Share screen</SheetTitle>
111
+ </SheetHeader>
112
+ <Stack gap="xs" className="py-4">
113
+ <Button variant="ghost" className="justify-start"><Mail /> Email</Button>
114
+ <Button variant="ghost" className="justify-start"><MessageCircle /> Message</Button>
115
+ <Button variant="ghost" className="justify-start"><Copy /> Copy link</Button>
116
+ </Stack>
117
+ <SheetClose asChild>
118
+ <Button variant="outline" className="w-full">Cancel</Button>
119
+ </SheetClose>
120
+ </SheetContent>
121
+ </Sheet>
122
+ ```
123
+
124
+ `side="bottom"` + `surface="glass"` + `rounded-t-2xl` is the iOS action-sheet recipe. The rounded top corners signal "this can be dismissed by dragging down" even before any gesture handler is wired up.
125
+
126
+ ---
127
+
128
+ ### Anti-patterns
129
+
130
+ **DO NOT roll glass by hand on SheetContent.**
49
131
 
50
132
  ```jsx
51
- <SheetContent className="gds-surface-glass">…</SheetContent>
133
+ {/* ❌ Tailwind soup — no edge highlight, blur isn't theme-tuned. */}
134
+ <SheetContent className="bg-background/60 backdrop-blur-md">
135
+
136
+ {/* ✅ */}
137
+ <SheetContent surface="glass">
52
138
  ```
139
+
140
+ **DO NOT use `surface="glass"` for a modal sheet that contains a long form.** Form legibility wins over aesthetic. If the user is going to spend 30 seconds in this sheet, give them an opaque background.
141
+
142
+ **DO NOT pair `surface="glass"` with `modal={true}` and the default scrim.** The scrim already dims the canvas — adding glass on top of a dimmed canvas reads as "two competing layers of de-emphasis". Either turn off the scrim (`modal={false}`), or use `surface="solid"`.
143
+
144
+ **DO NOT skip SheetTitle.** Screen readers announce it on open. If the design has no visible title, wrap a `sr-only` one.