@excom/content-drawer 0.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.
- package/.rush/temp/chunked-rush-logs/content-drawer.apply-exports.chunks.jsonl +1 -0
- package/.rush/temp/chunked-rush-logs/content-drawer.build_docs.chunks.jsonl +1 -0
- package/.rush/temp/chunked-rush-logs/content-drawer.build_package-metas.chunks.jsonl +1 -0
- package/.rush/temp/operation/apply-exports/all.log +1 -0
- package/.rush/temp/operation/apply-exports/log-chunks.jsonl +1 -0
- package/.rush/temp/operation/apply-exports/state.json +3 -0
- package/.rush/temp/operation/build_docs/all.log +1 -0
- package/.rush/temp/operation/build_docs/log-chunks.jsonl +1 -0
- package/.rush/temp/operation/build_docs/state.json +3 -0
- package/.rush/temp/operation/build_package-metas/all.log +1 -0
- package/.rush/temp/operation/build_package-metas/log-chunks.jsonl +1 -0
- package/.rush/temp/operation/build_package-metas/state.json +3 -0
- package/.rush/temp/shrinkwrap-deps.json +3 -0
- package/config/rig.json +5 -0
- package/content-drawer.ts +205 -0
- package/index.css +5 -0
- package/index.ts +17 -0
- package/package.json +44 -0
- package/rush-logs/content-drawer.apply-exports.cache.log +1 -0
- package/rush-logs/content-drawer.apply-exports.log +1 -0
- package/rush-logs/content-drawer.build_docs.cache.log +1 -0
- package/rush-logs/content-drawer.build_docs.log +1 -0
- package/rush-logs/content-drawer.build_package-metas.cache.log +1 -0
- package/rush-logs/content-drawer.build_package-metas.log +1 -0
- package/src/content-drawer.css +344 -0
- package/support/custom-elements.json +360 -0
- package/support/demos/disappear.html +8 -0
- package/support/demos/dismiss.html +16 -0
- package/support/demos/from-side.html +9 -0
- package/support/demos/simple.html +12 -0
- package/support/demos/singleton.html +16 -0
- package/support/demos/stages.html +18 -0
- package/support/dist-docs/content-drawer.md +252 -0
- package/support/docs/README.md +69 -0
- package/support/package-meta.json +299 -0
- package/support/tests/content-drawer.test.ts +388 -0
- package/support/tests/disappear.view.test.ts +32 -0
- package/support/tests/dismiss.view.test.ts +61 -0
- package/support/tests/from-side.view.test.ts +32 -0
- package/support/tests/simple.view.test.ts +40 -0
- package/support/tests/singleton.view.test.ts +35 -0
- package/support/tests/stages.view.test.ts +39 -0
- package/tsconfig.json +5 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<section>
|
|
2
|
+
<quark-sheet>
|
|
3
|
+
:scope {
|
|
4
|
+
content-drawer[is-open] dismiss-watcher { is-active: ""; }
|
|
5
|
+
content-drawer:not([is-open]) dismiss-watcher { is-active: none; }
|
|
6
|
+
}
|
|
7
|
+
</quark-sheet>
|
|
8
|
+
<button type="button" command="--open" commandfor="demo-drawer-dismiss">
|
|
9
|
+
Open drawer
|
|
10
|
+
</button>
|
|
11
|
+
<content-drawer id="demo-drawer-dismiss" class="absolute">
|
|
12
|
+
<dismiss-watcher watch-escape watch-outside-click command-name="--close"></dismiss-watcher>
|
|
13
|
+
<nav>Menu</nav>
|
|
14
|
+
</content-drawer>
|
|
15
|
+
<event-handler class="tag-backdrop" role="presentation" target-ref="content-drawer:has(+ :scope)" command-name="--close"></event-handler>
|
|
16
|
+
</section>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<section>
|
|
2
|
+
<button type="button" command="--toggle" commandfor="demo-drawer-side">
|
|
3
|
+
Toggle drawer
|
|
4
|
+
</button>
|
|
5
|
+
<content-drawer id="demo-drawer-side" class="absolute" from-side="left">
|
|
6
|
+
<nav>Menu</nav>
|
|
7
|
+
</content-drawer>
|
|
8
|
+
<event-handler class="tag-backdrop" role="presentation" target-ref="content-drawer:has(+ :scope)" command-name="--close"></event-handler>
|
|
9
|
+
</section>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<section>
|
|
2
|
+
<button type="button" command="--toggle" commandfor="demo-drawer-simple">
|
|
3
|
+
Toggle sheet
|
|
4
|
+
</button>
|
|
5
|
+
<content-drawer id="demo-drawer-simple" class="absolute">
|
|
6
|
+
<header>
|
|
7
|
+
<button type="button" rel="prev" command="--close" commandfor="demo-drawer-simple" aria-label="Close"></button>
|
|
8
|
+
<h2>Sheet open</h2>
|
|
9
|
+
</header>
|
|
10
|
+
</content-drawer>
|
|
11
|
+
<event-handler class="tag-backdrop" role="presentation" target-ref="content-drawer:has(+ :scope)" command-name="--close"></event-handler>
|
|
12
|
+
</section>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<section>
|
|
2
|
+
<button type="button" command="--open" commandfor="drawer-a">Open A</button>
|
|
3
|
+
<button type="button" command="--open" commandfor="drawer-b">Open B</button>
|
|
4
|
+
<content-drawer id="drawer-a" class="absolute" singleton-name="demo">
|
|
5
|
+
<header>
|
|
6
|
+
<button type="button" rel="prev" command="--close" commandfor="drawer-a" aria-label="Close"></button>
|
|
7
|
+
<h2>Drawer A</h2>
|
|
8
|
+
</header>
|
|
9
|
+
</content-drawer>
|
|
10
|
+
<content-drawer id="drawer-b" class="absolute" singleton-name="demo">
|
|
11
|
+
<header>
|
|
12
|
+
<button type="button" rel="prev" command="--close" commandfor="drawer-b" aria-label="Close"></button>
|
|
13
|
+
<h2>Drawer B</h2>
|
|
14
|
+
</header>
|
|
15
|
+
</content-drawer>
|
|
16
|
+
</section>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<section>
|
|
2
|
+
<button type="button" command="--open" commandfor="demo-drawer-stages" data-open-stage="0">
|
|
3
|
+
Full (100%)
|
|
4
|
+
</button>
|
|
5
|
+
<button type="button" command="--open" commandfor="demo-drawer-stages" data-open-stage="1">
|
|
6
|
+
Half (50%)
|
|
7
|
+
</button>
|
|
8
|
+
<button type="button" command="--open" commandfor="demo-drawer-stages" data-open-stage="2">
|
|
9
|
+
Peek (25%)
|
|
10
|
+
</button>
|
|
11
|
+
<content-drawer id="demo-drawer-stages" class="absolute">
|
|
12
|
+
<header>
|
|
13
|
+
<button type="button" rel="prev" command="--close" commandfor="demo-drawer-stages" aria-label="Close"></button>
|
|
14
|
+
<h2>Open stages</h2>
|
|
15
|
+
</header>
|
|
16
|
+
<p>Full / half / peek via <code>data-open-stage</code> on the button.</p>
|
|
17
|
+
</content-drawer>
|
|
18
|
+
</section>
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# content-drawer
|
|
2
|
+
|
|
3
|
+
Slide-in drawers and sheets for nav menus, filters, confirmations, and side panels — any edge, with peek stages.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
```html
|
|
7
|
+
<section>
|
|
8
|
+
<button type="button" command="--toggle" commandfor="demo-drawer-simple">
|
|
9
|
+
Toggle sheet
|
|
10
|
+
</button>
|
|
11
|
+
<content-drawer id="demo-drawer-simple" class="absolute">
|
|
12
|
+
<header>
|
|
13
|
+
<button type="button" rel="prev" command="--close" commandfor="demo-drawer-simple" aria-label="Close"></button>
|
|
14
|
+
<h2>Sheet open</h2>
|
|
15
|
+
</header>
|
|
16
|
+
</content-drawer>
|
|
17
|
+
<event-handler class="tag-backdrop" role="presentation" target-ref="content-drawer:has(+ :scope)" command-name="--close"></event-handler>
|
|
18
|
+
</section>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
|
|
24
|
+
- **Any edge** Bottom (default), top, left, or right via `from-side`
|
|
25
|
+
- **Peek stages** Full, half, or peek via `open-stage`
|
|
26
|
+
- **Command-driven** `--open` / `--close` / `--toggle` from any `<button command commandfor>`
|
|
27
|
+
- **Dismissal** Outside click + Escape via `<dismiss-watcher>`
|
|
28
|
+
- **Backdrop** Valence.css dimmer — sibling `[role="presentation"]` / `.tag-backdrop`
|
|
29
|
+
- **Auto-dismiss** `disappear-after` for toast-style confirmations
|
|
30
|
+
- **Singleton groups** One open drawer per `singleton-name`
|
|
31
|
+
- **Layout modes** Viewport sheet (default, `position: fixed`), `.absolute` (inside its parent), `.relative`, or `.sticky`
|
|
32
|
+
- **Scrubbable** Wrap in [`gesture-handler`](/nucleus/packages/gesture-handler): the sheet follows the finger via `is-scrubbing` + `--content-drawer-open-progress`
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
`@excom/content-drawer` v0.1.0
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pnpm add @excom/content-drawer
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install @excom/content-drawer
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
yarn add @excom/content-drawer
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Import
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import "@excom/content-drawer";
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
## Usage
|
|
60
|
+
|
|
61
|
+
Put content inside `<content-drawer>` and invoke `--open`, `--close`, or `--toggle` on it — a native `<button command commandfor>`, or `<event-handler command-name target-ref>` when the invoker is not a button. Its parent automatically becomes `position: relative; overflow: hidden`, so give the parent a real size along the drawer's axis.
|
|
62
|
+
|
|
63
|
+
```html
|
|
64
|
+
<button type="button" command="--toggle" commandfor="sheet">Toggle sheet</button>
|
|
65
|
+
<content-drawer id="sheet" class="absolute">
|
|
66
|
+
<h2>Saved!</h2>
|
|
67
|
+
</content-drawer>
|
|
68
|
+
<event-handler class="tag-backdrop" role="presentation" target-ref="content-drawer:has(+ :scope)" command-name="--close"></event-handler>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### API Reference
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
#### Attributes
|
|
75
|
+
|
|
76
|
+
| Name | Surface | Type | Default | Values | Description |
|
|
77
|
+
| --- | --- | --- | --- | --- | --- |
|
|
78
|
+
| `from-side` | option | `string` | `"bottom"` | `"bottom"` \| `"top"` \| `"left"` \| `"right"` | Edge the drawer slides from. |
|
|
79
|
+
| `disappear-after` | option | `number` | | | Auto-close after this many seconds once opened — toast-style / transient confirmations. |
|
|
80
|
+
| `singleton-name` | option | `string` | | | Shared group name. Opening one drawer closes others with the same name (singleton coordination). |
|
|
81
|
+
| `open-stage` | hybrid | `number` | | `"0"` \| `"1"` \| `"2"` | How far the drawer opens: `0` full, `1` half, `2` peek. Unset = full. Set statically, or per open through `data-open-stage` on the `--open` / `--toggle` invoker. |
|
|
82
|
+
| `is-open` | hybrid | `boolean` | | | Open state. Toggle directly, or through the `--open` / `--close` / `--toggle` commands. For Escape / outside-click dismissal pair with `<dismiss-watcher command-name="--close">`. |
|
|
83
|
+
|
|
84
|
+
#### Fires
|
|
85
|
+
|
|
86
|
+
| Name | Type | Description |
|
|
87
|
+
| --- | --- | --- |
|
|
88
|
+
| `content-drawer-opened` | `ContentDrawerOpenedEvent` (`CustomEvent & { type: "content-drawer-opened"; detail: HTMLElement; bubbles: true; cancelable: true; composed: true }`) | After open (`is-open` set), `detail` is the drawer. When `singleton-name` is set it is also broadcast so drawers sharing that name close. |
|
|
89
|
+
| `content-drawer-closed` | `ContentDrawerClosedEvent` (`CustomEvent & { type: "content-drawer-closed"; detail: HTMLElement; bubbles: true; cancelable: true; composed: true }`) | After close (`is-open` unset), `detail` is the drawer. |
|
|
90
|
+
|
|
91
|
+
#### Commands
|
|
92
|
+
|
|
93
|
+
| Command | Action |
|
|
94
|
+
| --- | --- |
|
|
95
|
+
| `--open` | Opens the drawer (`is-open` set). `data-*` attributes on the invoker that name a declared prop (`data-open-stage`, `data-from-side`, …) are applied first; unknown, private and `isOpen` keys are ignored. |
|
|
96
|
+
| `--close` | Closes the drawer (`is-open` unset). |
|
|
97
|
+
| `--toggle` | Toggles open / closed. Reads the invoker's `data-*` like `--open`. |
|
|
98
|
+
|
|
99
|
+
#### CSS Custom Properties
|
|
100
|
+
|
|
101
|
+
| Name | Syntax | Default | Description |
|
|
102
|
+
| --- | --- | --- | --- |
|
|
103
|
+
| `--content-drawer-transition-duration` | `<time>` | `0.25s` | Slide transition duration. |
|
|
104
|
+
| `--content-drawer-transition-ease` | `<easing-function>` | `ease-out` | Slide transition easing. |
|
|
105
|
+
| `--content-drawer-closed` | `<percentage>` | `101%` | Off-screen translate amount (closed). |
|
|
106
|
+
| `--content-drawer-open-full` | `<percentage>` | `0%` | Full-open translate (`open-stage` unset or `0`). |
|
|
107
|
+
| `--content-drawer-open-half` | `<percentage>` | `50%` | Half-open translate (`open-stage="1"`). |
|
|
108
|
+
| `--content-drawer-open-peek` | `<percentage>` | `75%` | Peek translate (`open-stage="2"`). |
|
|
109
|
+
| `--content-drawer-relative-max-width` | `<length>` | `200px` | Max width when open in `.relative` mode, used unless `--content-drawer-max-width` is set. |
|
|
110
|
+
| `--content-drawer-z-index` | `<integer>` | `3` | Stack order for the drawer panel. |
|
|
111
|
+
| `--content-drawer-overlay-z-index` | `<integer>` | `2` | Stack order for the sibling backdrop (`:--dialog-backdrop-aliases`). |
|
|
112
|
+
| `--content-drawer-open-progress` | `<number>` | `var(--gesture-progress, 0)` | How far open the drawer is while `is-scrubbing`: `0` closed, `1` full. Declared on the drawer (not `:root`) so it follows a wrapping `<gesture-handler>`'s inherited `--gesture-progress` unless set explicitly — a swipe-to-open / drag-to-close bottom sheet. |
|
|
113
|
+
| `--content-drawer-max-width` | `<length>` | | Overrides `--content-drawer-relative-max-width` for this drawer only. |
|
|
114
|
+
|
|
115
|
+
#### CSS Classes
|
|
116
|
+
|
|
117
|
+
| Name | Description |
|
|
118
|
+
| --- | --- |
|
|
119
|
+
| `.close` | Close control — empty `.close` / `[rel="prev"]` button or link (theme close icon). |
|
|
120
|
+
| `.sticky` | `position: sticky` instead of the default `absolute` placement. |
|
|
121
|
+
| `.absolute` | `position: absolute` instead of the default `fixed` placement — a sheet inside its (`position: relative`) parent. |
|
|
122
|
+
| `.relative` | In-flow mode: the drawer participates in layout and animates `max-width` instead of overlaying via `position`, pushing sibling content aside as it opens. Currently only affects `from-side="left"`. |
|
|
123
|
+
|
|
124
|
+
#### CSS Aliases
|
|
125
|
+
|
|
126
|
+
| Alias | Kind | Matches | Description |
|
|
127
|
+
| --- | --- | --- | --- |
|
|
128
|
+
| `:--content-drawer` | element | `content-drawer`, `.tag-content-drawer` | |
|
|
129
|
+
| `:--content-drawer--is-open` | state | `[is-open]`, `[aria-expanded="true"]` | |
|
|
130
|
+
| `:--content-drawer--is-scrubbing` | state | `[is-scrubbing][is-scrubbing]`, `[data-scrubbing][data-scrubbing]` | |
|
|
131
|
+
| `:--content-drawer--open-stage-1` | state | `[open-stage="1"]`, `[data-open="1"]` | |
|
|
132
|
+
| `:--content-drawer--open-stage-2` | state | `[open-stage="2"]`, `[data-open="2"]` | |
|
|
133
|
+
| `:--content-drawer--from-side` | state | `[from-side]`, `[data-placement]` | |
|
|
134
|
+
| `:--content-drawer--from-side-bottom` | state | `[from-side="bottom"]`, `[data-placement="bottom"]` | |
|
|
135
|
+
| `:--content-drawer--from-side-top` | state | `[from-side="top"]`, `[data-placement="top"]` | |
|
|
136
|
+
| `:--content-drawer--from-side-left` | state | `[from-side="left"]`, `[data-placement="left"]` | |
|
|
137
|
+
| `:--content-drawer--from-side-right` | state | `[from-side="right"]`, `[data-placement="right"]` | |
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
### Examples
|
|
142
|
+
|
|
143
|
+
#### Peek stages
|
|
144
|
+
|
|
145
|
+
`--open` with `data-open-stage` on the button sets the stage — `0` full, `1` half, `2` peek. The exact heights of each stage are configurable through CSS variables.
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
```html
|
|
149
|
+
<section>
|
|
150
|
+
<button type="button" command="--open" commandfor="demo-drawer-stages" data-open-stage="0">
|
|
151
|
+
Full (100%)
|
|
152
|
+
</button>
|
|
153
|
+
<button type="button" command="--open" commandfor="demo-drawer-stages" data-open-stage="1">
|
|
154
|
+
Half (50%)
|
|
155
|
+
</button>
|
|
156
|
+
<button type="button" command="--open" commandfor="demo-drawer-stages" data-open-stage="2">
|
|
157
|
+
Peek (25%)
|
|
158
|
+
</button>
|
|
159
|
+
<content-drawer id="demo-drawer-stages" class="absolute">
|
|
160
|
+
<header>
|
|
161
|
+
<button type="button" rel="prev" command="--close" commandfor="demo-drawer-stages" aria-label="Close"></button>
|
|
162
|
+
<h2>Open stages</h2>
|
|
163
|
+
</header>
|
|
164
|
+
<p>Full / half / peek via <code>data-open-stage</code> on the button.</p>
|
|
165
|
+
</content-drawer>
|
|
166
|
+
</section>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
#### Dismissal
|
|
171
|
+
|
|
172
|
+
`<dismiss-watcher command-name="--close">` as the drawer's first child closes it on outside click or Escape / back gesture; the sheet gates its `is-active` on `content-drawer[is-open]` (with the inverse rule). Open with `--open`, not `--toggle` — an outside `mouseup` on the button closes first, the `click` then re-opens. Immediate next sibling `[role="presentation"]` / `.tag-backdrop` is the Valence.css modal dimmer; `<event-handler command-name="--close">` on that node closes on click.
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
```html
|
|
176
|
+
<section>
|
|
177
|
+
<quark-sheet>
|
|
178
|
+
:scope {
|
|
179
|
+
content-drawer[is-open] dismiss-watcher { is-active: ""; }
|
|
180
|
+
content-drawer:not([is-open]) dismiss-watcher { is-active: none; }
|
|
181
|
+
}
|
|
182
|
+
</quark-sheet>
|
|
183
|
+
<button type="button" command="--open" commandfor="demo-drawer-dismiss">
|
|
184
|
+
Open drawer
|
|
185
|
+
</button>
|
|
186
|
+
<content-drawer id="demo-drawer-dismiss" class="absolute">
|
|
187
|
+
<dismiss-watcher watch-escape watch-outside-click command-name="--close"></dismiss-watcher>
|
|
188
|
+
<nav>Menu</nav>
|
|
189
|
+
</content-drawer>
|
|
190
|
+
<event-handler class="tag-backdrop" role="presentation" target-ref="content-drawer:has(+ :scope)" command-name="--close"></event-handler>
|
|
191
|
+
</section>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
#### Side drawer
|
|
196
|
+
|
|
197
|
+
`from-side` slides from left / right / top instead of the default bottom.
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
```html
|
|
201
|
+
<section>
|
|
202
|
+
<button type="button" command="--toggle" commandfor="demo-drawer-side">
|
|
203
|
+
Toggle drawer
|
|
204
|
+
</button>
|
|
205
|
+
<content-drawer id="demo-drawer-side" class="absolute" from-side="left">
|
|
206
|
+
<nav>Menu</nav>
|
|
207
|
+
</content-drawer>
|
|
208
|
+
<event-handler class="tag-backdrop" role="presentation" target-ref="content-drawer:has(+ :scope)" command-name="--close"></event-handler>
|
|
209
|
+
</section>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
#### Auto-dismiss
|
|
214
|
+
|
|
215
|
+
`disappear-after` closes the drawer after N seconds — useful for success toasts.
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
```html
|
|
219
|
+
<section>
|
|
220
|
+
<button type="button" command="--open" commandfor="demo-drawer-disappear">
|
|
221
|
+
Show success
|
|
222
|
+
</button>
|
|
223
|
+
<content-drawer id="demo-drawer-disappear" class="absolute" disappear-after="2">
|
|
224
|
+
<h2>Saved!</h2>
|
|
225
|
+
</content-drawer>
|
|
226
|
+
</section>
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
#### Singleton group
|
|
231
|
+
|
|
232
|
+
Drawers sharing `singleton-name` — opening one closes the other.
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
```html
|
|
236
|
+
<section>
|
|
237
|
+
<button type="button" command="--open" commandfor="drawer-a">Open A</button>
|
|
238
|
+
<button type="button" command="--open" commandfor="drawer-b">Open B</button>
|
|
239
|
+
<content-drawer id="drawer-a" class="absolute" singleton-name="demo">
|
|
240
|
+
<header>
|
|
241
|
+
<button type="button" rel="prev" command="--close" commandfor="drawer-a" aria-label="Close"></button>
|
|
242
|
+
<h2>Drawer A</h2>
|
|
243
|
+
</header>
|
|
244
|
+
</content-drawer>
|
|
245
|
+
<content-drawer id="drawer-b" class="absolute" singleton-name="demo">
|
|
246
|
+
<header>
|
|
247
|
+
<button type="button" rel="prev" command="--close" commandfor="drawer-b" aria-label="Close"></button>
|
|
248
|
+
<h2>Drawer B</h2>
|
|
249
|
+
</header>
|
|
250
|
+
</content-drawer>
|
|
251
|
+
</section>
|
|
252
|
+
```
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# content-drawer
|
|
2
|
+
|
|
3
|
+
Slide-in drawers and sheets for nav menus, filters, confirmations, and side panels — any edge, with peek stages.
|
|
4
|
+
|
|
5
|
+
<include-content data-demo="simple"></include-content>
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Any edge** Bottom (default), top, left, or right via `from-side`
|
|
10
|
+
- **Peek stages** Full, half, or peek via `open-stage`
|
|
11
|
+
- **Command-driven** `--open` / `--close` / `--toggle` from any `<button command commandfor>`
|
|
12
|
+
- **Dismissal** Outside click + Escape via `<dismiss-watcher>`
|
|
13
|
+
- **Backdrop** Valence.css dimmer — sibling `[role="presentation"]` / `.tag-backdrop`
|
|
14
|
+
- **Auto-dismiss** `disappear-after` for toast-style confirmations
|
|
15
|
+
- **Singleton groups** One open drawer per `singleton-name`
|
|
16
|
+
- **Layout modes** Viewport sheet (default, `position: fixed`), `.absolute` (inside its parent), `.relative`, or `.sticky`
|
|
17
|
+
- **Scrubbable** Wrap in [`gesture-handler`](/nucleus/packages/gesture-handler): the sheet follows the finger via `is-scrubbing` + `--content-drawer-open-progress`
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
<include-content is-active template-ref="/views/install-section/install-section.html"></include-content>
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
Put content inside `<content-drawer>` and invoke `--open`, `--close`, or `--toggle` on it — a native `<button command commandfor>`, or `<event-handler command-name target-ref>` when the invoker is not a button. Its parent automatically becomes `position: relative; overflow: hidden`, so give the parent a real size along the drawer's axis.
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<button type="button" command="--toggle" commandfor="sheet">Toggle sheet</button>
|
|
29
|
+
<content-drawer id="sheet" class="absolute">
|
|
30
|
+
<h2>Saved!</h2>
|
|
31
|
+
</content-drawer>
|
|
32
|
+
<event-handler class="tag-backdrop" role="presentation" target-ref="content-drawer:has(+ :scope)" command-name="--close"></event-handler>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### API Reference
|
|
36
|
+
|
|
37
|
+
<include-content is-active template-ref="/views/api-reference/api-reference.html"></include-content>
|
|
38
|
+
|
|
39
|
+
### Examples
|
|
40
|
+
|
|
41
|
+
#### Peek stages
|
|
42
|
+
|
|
43
|
+
`--open` with `data-open-stage` on the button sets the stage — `0` full, `1` half, `2` peek. The exact heights of each stage are configurable through CSS variables.
|
|
44
|
+
|
|
45
|
+
<include-content data-demo="stages"></include-content>
|
|
46
|
+
|
|
47
|
+
#### Dismissal
|
|
48
|
+
|
|
49
|
+
`<dismiss-watcher command-name="--close">` as the drawer's first child closes it on outside click or Escape / back gesture; the sheet gates its `is-active` on `content-drawer[is-open]` (with the inverse rule). Open with `--open`, not `--toggle` — an outside `mouseup` on the button closes first, the `click` then re-opens. Immediate next sibling `[role="presentation"]` / `.tag-backdrop` is the Valence.css modal dimmer; `<event-handler command-name="--close">` on that node closes on click.
|
|
50
|
+
|
|
51
|
+
<include-content data-demo="dismiss"></include-content>
|
|
52
|
+
|
|
53
|
+
#### Side drawer
|
|
54
|
+
|
|
55
|
+
`from-side` slides from left / right / top instead of the default bottom.
|
|
56
|
+
|
|
57
|
+
<include-content data-demo="from-side"></include-content>
|
|
58
|
+
|
|
59
|
+
#### Auto-dismiss
|
|
60
|
+
|
|
61
|
+
`disappear-after` closes the drawer after N seconds — useful for success toasts.
|
|
62
|
+
|
|
63
|
+
<include-content data-demo="disappear"></include-content>
|
|
64
|
+
|
|
65
|
+
#### Singleton group
|
|
66
|
+
|
|
67
|
+
Drawers sharing `singleton-name` — opening one closes the other.
|
|
68
|
+
|
|
69
|
+
<include-content data-demo="singleton"></include-content>
|