Skip to content

Commit 8d0866d

Browse files
committed
feat(sheet): improve customizability with size prop, actions slot, and layout fixes
- Add `size` prop to Sheet.Content for width variations (sm/md/lg/xl/full) - Add `actions` prop to Sheet.Header for action buttons beside the title - Increase Sheet.Title font size to text-lg for better hierarchy - Move close button from absolute positioning into Header normal flow
1 parent 26c4ecc commit 8d0866d

6 files changed

Lines changed: 373 additions & 61 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
"@tailor-platform/app-shell": minor
3+
---
4+
5+
Improve Sheet component customizability:
6+
7+
- Add `size` prop to `Sheet.Content` for width variations (`sm`, `md`, `lg`, `xl`)
8+
- Add `actions` prop to `Sheet.Header` for placing action buttons to the right of the title
9+
- Increase `Sheet.Title` font size to `text-lg` for better visibility
10+
- Move close button from absolute positioning into `Sheet.Header` normal document flow
11+
12+
```tsx
13+
<Sheet.Root side="right">
14+
<Sheet.Trigger render={<Button />}>Open</Sheet.Trigger>
15+
<Sheet.Content size="lg">
16+
<Sheet.Header actions={<Button size="sm">Save</Button>}>
17+
<Sheet.Title>Edit Record</Sheet.Title>
18+
</Sheet.Header>
19+
</Sheet.Content>
20+
</Sheet.Root>
21+
```

docs/components/sheet.md

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,56 @@ import { Sheet } from "@tailor-platform/app-shell";
5959

6060
### Sheet.Content Props
6161

62-
Accepts `className` and all standard HTML `<div>` props.
62+
| Prop | Type | Default | Description |
63+
| ----------- | ---------------------------------------- | ------- | --------------------------------------------------------------- |
64+
| `size` | `"sm" \| "md" \| "lg" \| "xl" \| "full"` | `"sm"` | Max-width of the sheet panel (applies to left/right sides only) |
65+
| `className` | `string` | - | Additional CSS classes |
66+
67+
Also accepts all standard HTML `<div>` props.
68+
69+
### Sheet.Header Props
70+
71+
| Prop | Type | Default | Description |
72+
| --------- | ----------------- | ------- | ------------------------------------------------------- |
73+
| `actions` | `React.ReactNode` | - | Action buttons displayed to the right of the title area |
74+
75+
The header automatically includes a close button in the normal document flow (no absolute positioning).
6376

6477
### Sheet.Trigger / Sheet.Close Props
6578

6679
Accept a `render` prop for custom element rendering (Base UI render pattern), plus standard button props.
6780

81+
## Sizes
82+
83+
Control the width of the sheet panel using the `size` prop on `Sheet.Content`. This applies to `left` and `right` side sheets.
84+
85+
```tsx
86+
<Sheet.Root side="right">
87+
<Sheet.Trigger render={<Button />}>Open Small</Sheet.Trigger>
88+
<Sheet.Content size="sm">…</Sheet.Content> {/* 384px (24rem) — default */}
89+
</Sheet.Root>
90+
91+
<Sheet.Root side="right">
92+
<Sheet.Trigger render={<Button />}>Open Medium</Sheet.Trigger>
93+
<Sheet.Content size="md">…</Sheet.Content> {/* 512px (32rem) */}
94+
</Sheet.Root>
95+
96+
<Sheet.Root side="right">
97+
<Sheet.Trigger render={<Button />}>Open Large</Sheet.Trigger>
98+
<Sheet.Content size="lg">…</Sheet.Content> {/* 720px (45rem) */}
99+
</Sheet.Root>
100+
101+
<Sheet.Root side="right">
102+
<Sheet.Trigger render={<Button />}>Open XL</Sheet.Trigger>
103+
<Sheet.Content size="xl">…</Sheet.Content> {/* 960px (60rem) */}
104+
</Sheet.Root>
105+
106+
<Sheet.Root side="right">
107+
<Sheet.Trigger render={<Button />}>Open Full</Sheet.Trigger>
108+
<Sheet.Content size="full">…</Sheet.Content> {/* 100% width */}
109+
</Sheet.Root>
110+
```
111+
68112
## Sides
69113

70114
```tsx
@@ -96,6 +140,25 @@ const [open, setOpen] = useState(false);
96140

97141
## Examples
98142

143+
### Header with Actions
144+
145+
Place action buttons (e.g., save, edit) to the right of the title using the `actions` prop on `Sheet.Header`.
146+
147+
```tsx
148+
<Sheet.Root side="right">
149+
<Sheet.Trigger render={<Button />}>Edit Record</Sheet.Trigger>
150+
<Sheet.Content size="lg">
151+
<Sheet.Header actions={<Button size="sm">Save</Button>}>
152+
<Sheet.Title>Edit Customer</Sheet.Title>
153+
<Sheet.Description>Update customer information.</Sheet.Description>
154+
</Sheet.Header>
155+
<div className="astw:p-4">
156+
<Input placeholder="Customer name" />
157+
</div>
158+
</Sheet.Content>
159+
</Sheet.Root>
160+
```
161+
99162
### Filter Panel
100163

101164
```tsx
@@ -151,7 +214,7 @@ function FilterPanel() {
151214
- Sheet title is announced by screen readers via `Sheet.Title`
152215
- Focus is trapped inside the sheet while open
153216
- Pressing `Escape` closes the sheet
154-
- The close button is always present inside `Sheet.Content`
217+
- The close button is rendered inside `Sheet.Header` in the normal document flow
155218

156219
## Related Components
157220

examples/nextjs-app/src/modules/pages/primitives-demo.tsx

Lines changed: 119 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -187,50 +187,125 @@ export const primitiveComponentsDemoResource = defineResource({
187187
<Card.Root>
188188
<Card.Header title="Sheet" />
189189
<Card.Content>
190-
<div style={rowStyle}>
191-
<Sheet.Root side="right">
192-
<Sheet.Trigger render={<Button variant="outline" />}>
193-
Open Sheet (Right)
194-
</Sheet.Trigger>
195-
<Sheet.Content>
196-
<Sheet.Header>
197-
<Sheet.Title>Sheet Title</Sheet.Title>
198-
<Sheet.Description>This sheet slides in from the right.</Sheet.Description>
199-
</Sheet.Header>
200-
<div style={{ padding: "1rem 0" }}>Sheet content goes here.</div>
201-
<Sheet.Footer>
202-
<Sheet.Close render={<Button variant="outline" />}>Close</Sheet.Close>
203-
</Sheet.Footer>
204-
</Sheet.Content>
205-
</Sheet.Root>
206-
<Sheet.Root side="left">
207-
<Sheet.Trigger render={<Button variant="outline" />}>
208-
Open Sheet (Left)
209-
</Sheet.Trigger>
210-
<Sheet.Content>
211-
<Sheet.Header>
212-
<Sheet.Title>Left Sheet</Sheet.Title>
213-
<Sheet.Description>This sheet slides in from the left.</Sheet.Description>
214-
</Sheet.Header>
215-
<Sheet.Footer>
216-
<Sheet.Close render={<Button variant="outline" />}>Close</Sheet.Close>
217-
</Sheet.Footer>
218-
</Sheet.Content>
219-
</Sheet.Root>
220-
<Sheet.Root side="bottom">
221-
<Sheet.Trigger render={<Button variant="outline" />}>
222-
Open Sheet (Bottom)
223-
</Sheet.Trigger>
224-
<Sheet.Content>
225-
<Sheet.Header>
226-
<Sheet.Title>Bottom Sheet</Sheet.Title>
227-
<Sheet.Description>This sheet slides in from the bottom.</Sheet.Description>
228-
</Sheet.Header>
229-
<Sheet.Footer>
230-
<Sheet.Close render={<Button variant="outline" />}>Close</Sheet.Close>
231-
</Sheet.Footer>
232-
</Sheet.Content>
233-
</Sheet.Root>
190+
<div style={{ display: "flex", gap: "2rem", flexWrap: "wrap" }}>
191+
<div>
192+
<div style={labelStyle}>Side</div>
193+
<div style={rowStyle}>
194+
<Sheet.Root side="right">
195+
<Sheet.Trigger render={<Button variant="outline" />}>Right</Sheet.Trigger>
196+
<Sheet.Content>
197+
<Sheet.Header>
198+
<Sheet.Title>Sheet Title</Sheet.Title>
199+
<Sheet.Description>
200+
This sheet slides in from the right.
201+
</Sheet.Description>
202+
</Sheet.Header>
203+
<div style={{ padding: "1rem 0" }}>Sheet content goes here.</div>
204+
<Sheet.Footer>
205+
<Sheet.Close render={<Button variant="outline" />}>Close</Sheet.Close>
206+
</Sheet.Footer>
207+
</Sheet.Content>
208+
</Sheet.Root>
209+
<Sheet.Root side="left">
210+
<Sheet.Trigger render={<Button variant="outline" />}>Left</Sheet.Trigger>
211+
<Sheet.Content>
212+
<Sheet.Header>
213+
<Sheet.Title>Left Sheet</Sheet.Title>
214+
<Sheet.Description>This sheet slides in from the left.</Sheet.Description>
215+
</Sheet.Header>
216+
<Sheet.Footer>
217+
<Sheet.Close render={<Button variant="outline" />}>Close</Sheet.Close>
218+
</Sheet.Footer>
219+
</Sheet.Content>
220+
</Sheet.Root>
221+
<Sheet.Root side="bottom">
222+
<Sheet.Trigger render={<Button variant="outline" />}>Bottom</Sheet.Trigger>
223+
<Sheet.Content>
224+
<Sheet.Header>
225+
<Sheet.Title>Bottom Sheet</Sheet.Title>
226+
<Sheet.Description>
227+
This sheet slides in from the bottom.
228+
</Sheet.Description>
229+
</Sheet.Header>
230+
<Sheet.Footer>
231+
<Sheet.Close render={<Button variant="outline" />}>Close</Sheet.Close>
232+
</Sheet.Footer>
233+
</Sheet.Content>
234+
</Sheet.Root>
235+
</div>
236+
</div>
237+
<div>
238+
<div style={labelStyle}>Size</div>
239+
<div style={rowStyle}>
240+
<Sheet.Root side="right">
241+
<Sheet.Trigger render={<Button variant="outline" />}>
242+
sm (default)
243+
</Sheet.Trigger>
244+
<Sheet.Content size="sm">
245+
<Sheet.Header>
246+
<Sheet.Title>Small Sheet</Sheet.Title>
247+
<Sheet.Description>384px (24rem)</Sheet.Description>
248+
</Sheet.Header>
249+
<div style={{ padding: "1rem 0" }}>Sheet content goes here.</div>
250+
<Sheet.Footer>
251+
<Sheet.Close render={<Button variant="outline" />}>Close</Sheet.Close>
252+
</Sheet.Footer>
253+
</Sheet.Content>
254+
</Sheet.Root>
255+
<Sheet.Root side="right">
256+
<Sheet.Trigger render={<Button variant="outline" />}>md</Sheet.Trigger>
257+
<Sheet.Content size="md">
258+
<Sheet.Header>
259+
<Sheet.Title>Medium Sheet</Sheet.Title>
260+
<Sheet.Description>512px (32rem)</Sheet.Description>
261+
</Sheet.Header>
262+
<div style={{ padding: "1rem 0" }}>Sheet content goes here.</div>
263+
<Sheet.Footer>
264+
<Sheet.Close render={<Button variant="outline" />}>Close</Sheet.Close>
265+
</Sheet.Footer>
266+
</Sheet.Content>
267+
</Sheet.Root>
268+
<Sheet.Root side="right">
269+
<Sheet.Trigger render={<Button variant="outline" />}>lg</Sheet.Trigger>
270+
<Sheet.Content size="lg">
271+
<Sheet.Header>
272+
<Sheet.Title>Large Sheet</Sheet.Title>
273+
<Sheet.Description>720px (45rem)</Sheet.Description>
274+
</Sheet.Header>
275+
<div style={{ padding: "1rem 0" }}>Sheet content goes here.</div>
276+
<Sheet.Footer>
277+
<Sheet.Close render={<Button variant="outline" />}>Close</Sheet.Close>
278+
</Sheet.Footer>
279+
</Sheet.Content>
280+
</Sheet.Root>
281+
<Sheet.Root side="right">
282+
<Sheet.Trigger render={<Button variant="outline" />}>xl</Sheet.Trigger>
283+
<Sheet.Content size="xl">
284+
<Sheet.Header>
285+
<Sheet.Title>Extra Large Sheet</Sheet.Title>
286+
<Sheet.Description>960px (60rem)</Sheet.Description>
287+
</Sheet.Header>
288+
<div style={{ padding: "1rem 0" }}>Sheet content goes here.</div>
289+
<Sheet.Footer>
290+
<Sheet.Close render={<Button variant="outline" />}>Close</Sheet.Close>
291+
</Sheet.Footer>
292+
</Sheet.Content>
293+
</Sheet.Root>
294+
<Sheet.Root side="right">
295+
<Sheet.Trigger render={<Button variant="outline" />}>full</Sheet.Trigger>
296+
<Sheet.Content size="full">
297+
<Sheet.Header>
298+
<Sheet.Title>Full Screen Sheet</Sheet.Title>
299+
<Sheet.Description>Full-width overlay</Sheet.Description>
300+
</Sheet.Header>
301+
<div style={{ padding: "1rem 0" }}>Sheet content goes here.</div>
302+
<Sheet.Footer>
303+
<Sheet.Close render={<Button variant="outline" />}>Close</Sheet.Close>
304+
</Sheet.Footer>
305+
</Sheet.Content>
306+
</Sheet.Root>
307+
</div>
308+
</div>
234309
</div>
235310
</Card.Content>
236311
</Card.Root>

0 commit comments

Comments
 (0)