css-drawer 0.1.3 → 0.1.4
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.
- package/README.md +57 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ A near drop-in replacement for [Vaul](https://vaul.emilkowal.ski) using native `
|
|
|
12
12
|
| Animation engine | JavaScript | Pure CSS |
|
|
13
13
|
| Nesting | Manual setup | Automatic (CSS `:has()`) |
|
|
14
14
|
| Accessibility | Built-in | Automatic (native `<dialog>` + `inert`) |
|
|
15
|
-
| API | Controlled state | Native refs |
|
|
15
|
+
| API | Controlled state | Native refs or controlled state |
|
|
16
16
|
|
|
17
17
|
## Installation
|
|
18
18
|
|
|
@@ -104,7 +104,11 @@ Provides context for direction. Wrap your drawer content.
|
|
|
104
104
|
|
|
105
105
|
### Drawer.Content
|
|
106
106
|
|
|
107
|
-
The dialog element.
|
|
107
|
+
The dialog element. Supports both uncontrolled (refs) and controlled (state) modes.
|
|
108
|
+
|
|
109
|
+
> **Note:** `open`/`onOpenChange` props are on `Content`, not `Root`. This is intentional - `Content` wraps the native `<dialog>` element, so open/close control lives where the element lives. `Root` only provides configuration (direction).
|
|
110
|
+
|
|
111
|
+
#### Uncontrolled Mode (Refs)
|
|
108
112
|
|
|
109
113
|
```tsx
|
|
110
114
|
const ref = useRef<HTMLDialogElement>(null)
|
|
@@ -118,9 +122,29 @@ ref.current?.close()
|
|
|
118
122
|
<Drawer.Content ref={ref}>...</Drawer.Content>
|
|
119
123
|
```
|
|
120
124
|
|
|
125
|
+
#### Controlled Mode (State)
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
const [isOpen, setIsOpen] = useState(false)
|
|
129
|
+
|
|
130
|
+
<Drawer.Content open={isOpen} onOpenChange={setIsOpen}>
|
|
131
|
+
...
|
|
132
|
+
</Drawer.Content>
|
|
133
|
+
|
|
134
|
+
// Open programmatically
|
|
135
|
+
<button onClick={() => setIsOpen(true)}>Open</button>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The `onOpenChange` callback fires when:
|
|
139
|
+
- User presses Escape
|
|
140
|
+
- User clicks the backdrop (if `closeOnOutsideClick` is true)
|
|
141
|
+
- You call `setIsOpen(false)`
|
|
142
|
+
|
|
121
143
|
| Prop | Type | Default | Description |
|
|
122
144
|
|------|------|---------|-------------|
|
|
123
|
-
| `ref` | `Ref<HTMLDialogElement>` | - | Ref to control the dialog |
|
|
145
|
+
| `ref` | `Ref<HTMLDialogElement>` | - | Ref to control the dialog (uncontrolled mode) |
|
|
146
|
+
| `open` | `boolean` | - | Controlled open state |
|
|
147
|
+
| `onOpenChange` | `(open: boolean) => void` | - | Called when open state changes |
|
|
124
148
|
| `closeOnOutsideClick` | `boolean` | `true` | Close when clicking outside the drawer |
|
|
125
149
|
| `className` | `string` | - | Additional CSS classes |
|
|
126
150
|
| `...props` | `DialogHTMLAttributes` | - | All native dialog props |
|
|
@@ -360,6 +384,8 @@ const isMobile = useMediaQuery('(max-width: 768px)')
|
|
|
360
384
|
|
|
361
385
|
Drawers automatically stack when opened. No configuration needed.
|
|
362
386
|
|
|
387
|
+
### With Refs
|
|
388
|
+
|
|
363
389
|
```tsx
|
|
364
390
|
const drawer1 = useRef<HTMLDialogElement>(null)
|
|
365
391
|
const drawer2 = useRef<HTMLDialogElement>(null)
|
|
@@ -372,6 +398,34 @@ drawer2.current?.showModal()
|
|
|
372
398
|
// drawer1 automatically scales down and dims
|
|
373
399
|
```
|
|
374
400
|
|
|
401
|
+
### With Controlled State
|
|
402
|
+
|
|
403
|
+
```tsx
|
|
404
|
+
const [settingsOpen, setSettingsOpen] = useState(false)
|
|
405
|
+
const [confirmOpen, setConfirmOpen] = useState(false)
|
|
406
|
+
|
|
407
|
+
<>
|
|
408
|
+
<button onClick={() => setSettingsOpen(true)}>Settings</button>
|
|
409
|
+
|
|
410
|
+
<Drawer.Root>
|
|
411
|
+
<Drawer.Content open={settingsOpen} onOpenChange={setSettingsOpen}>
|
|
412
|
+
<button onClick={() => setConfirmOpen(true)}>Delete Account</button>
|
|
413
|
+
</Drawer.Content>
|
|
414
|
+
</Drawer.Root>
|
|
415
|
+
|
|
416
|
+
<Drawer.Root>
|
|
417
|
+
<Drawer.Content open={confirmOpen} onOpenChange={setConfirmOpen}>
|
|
418
|
+
<button onClick={() => {
|
|
419
|
+
setConfirmOpen(false)
|
|
420
|
+
setSettingsOpen(false)
|
|
421
|
+
}}>
|
|
422
|
+
Confirm
|
|
423
|
+
</button>
|
|
424
|
+
</Drawer.Content>
|
|
425
|
+
</Drawer.Root>
|
|
426
|
+
</>
|
|
427
|
+
```
|
|
428
|
+
|
|
375
429
|
Works up to 5 levels. CSS `:has()` selectors handle the visual stacking.
|
|
376
430
|
|
|
377
431
|
---
|