first commit
This commit is contained in:
146
docs/ui/react/react-ui/src/components/sheet/sheet.md
Normal file
146
docs/ui/react/react-ui/src/components/sheet/sheet.md
Normal file
@@ -0,0 +1,146 @@
|
||||
# Sheet
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs --> - sheet.variants — `sheetOverlayVariants`, `sheetCont…
|
||||
- [sheet.variants](./sheet.variants.md) — `sheetOverlayVariants`, `sheetContentVariants`, `sheetHeaderVariants`, `sheetFooterVariants`, `sheetTitleVariants`, `sh…
|
||||
- sheet.variants — `sheetOverlayVariants`, `sheetCont…
|
||||
|
||||
- [sheet.variants](./sheet.variants.md) — `sheetOverlayVariants`, `sheetContentVariants`, `sheetHeaderVariants`, `sheetFooterVariants`, `sheetTitleVariants`, `sh…
|
||||
|
||||
- sheet.variants — `sheetOverlayVariants`, `sheetCont…
|
||||
|
||||
- [sheet.variants](./sheet.variants.md) — `sheetOverlayVariants`, `sheetContentVariants`, `sheetHeaderVariants`, `sheetFooterVariants`, `sheetTitleVariants`, `sh…
|
||||
|
||||
- sheet.variants — `sheetOverlayVariants`, `sheetCont…
|
||||
|
||||
- [sheet.variants](./sheet.variants.md) — `sheetOverlayVariants`, `sheetContentVariants`, `sheetHeaderVariants`, `sheetFooterVariants`, `sheetTitleVariants`, `sh…
|
||||
- [sheet.variants](./sheet.variants.md) — `sheetOverlayVariants`, `sheetContentVariants`, `sheetHeaderVariants`, `sheetFooterVariants`, `sheetTitleVariants`, `sh…
|
||||
|
||||
## Purpose
|
||||
|
||||
`<Sheet>` and its sub-components (`<SheetTrigger>`, `<SheetPortal>`, `<SheetOverlay>`, `<SheetContent>`, `<SheetHeader>`, `<SheetFooter>`, `<SheetTitle>`, `<SheetDescription>`, `<SheetClose>`) are the chassis side-anchored panel primitives built on `@radix-ui/react-dialog`. Sheet is structurally a Dialog with side-anchored positioning, so Radix supplies the same WAI-ARIA dialog semantics (focus-trap, restore-focus, Escape closes, click-outside closes) and the chassis adds a `side` axis on `<SheetContent>` (`top` / `right` / `bottom` / `left`).
|
||||
|
||||
Per the WAI-ARIA dialog pattern, every sheet MUST contain a `<SheetTitle>` so the accessible name is announced. Use `className="sr-only"` if the visible UI does not need a heading. Logical-property edges (`start-0` / `end-0`) ensure `left` and `right` automatically swap under `dir="rtl"`.
|
||||
|
||||
## Features
|
||||
|
||||
- Four side anchors (`top`, `right`, `bottom`, `left`) with matching slide-in/slide-out animations.
|
||||
- Focus-trap on open; restore-focus on close (Radix-managed).
|
||||
- Escape closes; click on the overlay backdrop closes the sheet.
|
||||
- Translated close-button `aria-label` via `react-ui.sheet.close` (Close / 关闭 / إغلاق / Cau / Закрыть).
|
||||
- Theme-driven cva overrides for every slot via `useThemedVariants("Sheet<Slot>")`.
|
||||
- All sub-components forward refs to their underlying Radix elements.
|
||||
- `motion-reduce:animate-none` collapses the slide animation under `prefers-reduced-motion: reduce`.
|
||||
- Logical-property anchoring (`start-0` / `end-0`) so `left` and `right` flip in RTL automatically.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```tsx
|
||||
import {
|
||||
Sheet,
|
||||
SheetClose,
|
||||
SheetContent,
|
||||
SheetDescription,
|
||||
SheetFooter,
|
||||
SheetHeader,
|
||||
SheetTitle,
|
||||
SheetTrigger,
|
||||
} from "@suaveplan/react-ui";
|
||||
|
||||
export function FiltersSheet() {
|
||||
return (
|
||||
<Sheet>
|
||||
<SheetTrigger>Filters</SheetTrigger>
|
||||
<SheetContent side="right">
|
||||
<SheetHeader>
|
||||
<SheetTitle>Filters</SheetTitle>
|
||||
<SheetDescription>Refine the results.</SheetDescription>
|
||||
</SheetHeader>
|
||||
<SheetFooter>
|
||||
<SheetClose>Apply</SheetClose>
|
||||
</SheetFooter>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```tsx
|
||||
import {
|
||||
Button,
|
||||
Sheet,
|
||||
SheetContent,
|
||||
SheetDescription,
|
||||
SheetFooter,
|
||||
SheetHeader,
|
||||
SheetTitle,
|
||||
SheetTrigger,
|
||||
} from "@suaveplan/react-ui";
|
||||
import { useState } from "react";
|
||||
|
||||
interface NavItem {
|
||||
readonly id: string;
|
||||
readonly label: string;
|
||||
}
|
||||
|
||||
export function MobileNavSheet({ items }: { items: readonly NavItem[] }) {
|
||||
const [open, setOpen] = useState(false);
|
||||
return (
|
||||
<Sheet open={open} onOpenChange={setOpen}>
|
||||
<SheetTrigger asChild>
|
||||
<Button variant="outline">Open menu</Button>
|
||||
</SheetTrigger>
|
||||
<SheetContent side="left">
|
||||
<SheetHeader>
|
||||
<SheetTitle>Navigation</SheetTitle>
|
||||
<SheetDescription>Browse the app.</SheetDescription>
|
||||
</SheetHeader>
|
||||
<nav className="mt-4 flex flex-col gap-1">
|
||||
{items.map((item) => (
|
||||
<a
|
||||
key={item.id}
|
||||
href={`#${item.id}`}
|
||||
className="rounded px-3 py-2 hover:bg-accent"
|
||||
onClick={() => setOpen(false)}
|
||||
>
|
||||
{item.label}
|
||||
</a>
|
||||
))}
|
||||
</nav>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `<Sheet>`
|
||||
|
||||
Renders the Radix Dialog Root. Same lifecycle props as `<Dialog>`.
|
||||
|
||||
### `<SheetContent>`
|
||||
|
||||
| Prop | Type | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `side` | `"top" \| "right" \| "bottom" \| "left"` | `"right"` | Anchor edge (RTL flips left/right). |
|
||||
| `closeAriaLabelKey` | `TranslationKey` | `react-ui.sheet.close` | Override the close-button accessible name. |
|
||||
|
||||
### `<SheetTitle>`
|
||||
|
||||
REQUIRED — Radix surfaces a dev warning when omitted. Render `className="sr-only"` if no visible heading is needed.
|
||||
|
||||
### `<SheetTrigger>`, `<SheetPortal>`, `<SheetOverlay>`, `<SheetHeader>`, `<SheetFooter>`, `<SheetDescription>`, `<SheetClose>`
|
||||
|
||||
Same as Dialog's analogous sub-components — direct re-exports of the Radix sub-components with the chassis cva applied.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The Radix Content props type is a discriminated union once cva-extra variant props (`side`) are layered on; TS cannot narrow the spread back through the chassis surface, so `<SheetContent>` casts the Radix Content to a relaxed shape via `unknown`. The runtime accepts both shapes equivalently. This mirrors the Wave 3b ToggleGroup reconciliation finding and is documented in the implementation comment.
|
||||
- The chassis NEVER assigns a numeric `z-index` to the overlay or content — Radix portals handle stacking.
|
||||
- `start-0` / `end-0` are logical properties — `left` / `right` automatically swap in RTL without a chevron-flip step.
|
||||
- `motion-reduce:animate-none motion-reduce:transition-none` collapses both the slide and the duration transitions under `prefers-reduced-motion: reduce`.
|
||||
- `<SheetContent>` self-portals via `<SheetPortal>` so consumers do not need to remember to portal manually — matches the shadcn upstream convention exactly.
|
||||
Reference in New Issue
Block a user