@excom/dismiss-watcher 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/dismiss-watcher.apply-exports.chunks.jsonl +1 -0
- package/.rush/temp/chunked-rush-logs/dismiss-watcher.build_docs.chunks.jsonl +1 -0
- package/.rush/temp/chunked-rush-logs/dismiss-watcher.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 +6 -0
- package/dismiss-watcher.ts +209 -0
- package/index.ts +21 -0
- package/package.json +48 -0
- package/rush-logs/dismiss-watcher.apply-exports.cache.log +1 -0
- package/rush-logs/dismiss-watcher.apply-exports.log +1 -0
- package/rush-logs/dismiss-watcher.build_docs.cache.log +1 -0
- package/rush-logs/dismiss-watcher.build_docs.log +1 -0
- package/rush-logs/dismiss-watcher.build_package-metas.cache.log +1 -0
- package/rush-logs/dismiss-watcher.build_package-metas.log +1 -0
- package/support/custom-elements.json +180 -0
- package/support/demos/drawer.html +19 -0
- package/support/demos/simple.html +24 -0
- package/support/dist-docs/dismiss-watcher.md +176 -0
- package/support/docs/README.md +62 -0
- package/support/package-meta.json +106 -0
- package/support/tests/dismiss-watcher.test.ts +370 -0
- package/support/tests/drawer.view.test.ts +71 -0
- package/support/tests/simple.view.test.ts +57 -0
- package/tsconfig.json +5 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# dismiss-watcher
|
|
2
|
+
|
|
3
|
+
One dismissal Adapter for drawers, menus, dialogs and popovers — Escape / back gesture and outside click, without each panel element owning the logic.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
```html
|
|
7
|
+
<div>
|
|
8
|
+
<quark-sheet>
|
|
9
|
+
:scope {
|
|
10
|
+
@on menu-open { data-is-open: ""; }
|
|
11
|
+
@on dismiss-watcher-dismiss { data-is-open: none; }
|
|
12
|
+
&[data-is-open] dismiss-watcher { is-active: ""; }
|
|
13
|
+
&:not([data-is-open]) dismiss-watcher { is-active: none; }
|
|
14
|
+
}
|
|
15
|
+
</quark-sheet>
|
|
16
|
+
<style>
|
|
17
|
+
[data-demo-menu] { display: none; }
|
|
18
|
+
[data-is-open] > [data-demo-menu] { display: block; }
|
|
19
|
+
</style>
|
|
20
|
+
<event-handler role="button" fire-event="menu-open">Open menu</event-handler>
|
|
21
|
+
<nav data-demo-menu>
|
|
22
|
+
<dismiss-watcher></dismiss-watcher>
|
|
23
|
+
<ul>
|
|
24
|
+
<li><a href="#">Profile</a></li>
|
|
25
|
+
<li><a href="#">Settings</a></li>
|
|
26
|
+
<li><a href="#">Sign out</a></li>
|
|
27
|
+
</ul>
|
|
28
|
+
<p>Press Escape or click outside to close.</p>
|
|
29
|
+
</nav>
|
|
30
|
+
</div>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## Features
|
|
35
|
+
|
|
36
|
+
- **Escape / back gesture** Through a `CloseWatcher` (Android back, Escape) via `watch-escape`
|
|
37
|
+
- **Outside click** A `mouseup` outside the target via `watch-outside-click`
|
|
38
|
+
- **One event** `dismiss-watcher-dismiss` with `detail.reason`; cancel it with `preventDefault()`
|
|
39
|
+
- **Default action** `command-name` commands invoked on the target (`--close`), or `fire-event` names dispatched at it
|
|
40
|
+
- **Any target** The parent by default, or `target-ref` (`:scope`-relative)
|
|
41
|
+
- **Gated by State** Live only while `is-active` — set it from Quark on the panel's open state
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
`@excom/dismiss-watcher` v0.1.0
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pnpm add @excom/dismiss-watcher
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm install @excom/dismiss-watcher
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
yarn add @excom/dismiss-watcher
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Import
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import "@excom/dismiss-watcher";
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
## Usage
|
|
69
|
+
|
|
70
|
+
Drop it inside the element being dismissed, gate `is-active` on that element's open state, and either react to `dismiss-watcher-dismiss` or let `command-name` / `fire-event` close the panel for you. When neither `watch-escape` nor `watch-outside-click` is present, both watchers are on.
|
|
71
|
+
|
|
72
|
+
```html
|
|
73
|
+
<nav>
|
|
74
|
+
<dismiss-watcher fire-event="menu-close"></dismiss-watcher>
|
|
75
|
+
…
|
|
76
|
+
</nav>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```quark
|
|
80
|
+
:scope {
|
|
81
|
+
@on menu-open { data-is-open: ""; }
|
|
82
|
+
@on menu-close { data-is-open: none; }
|
|
83
|
+
&[data-is-open] dismiss-watcher { is-active: ""; }
|
|
84
|
+
&:not([data-is-open]) dismiss-watcher { is-active: none; }
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Why a separate element: dismissal is the same request whether the panel is a drawer, a menu, a dialog or a popover. Panel elements keep their own state (`is-open`); this Adapter only asks them to close. It renders nothing, listens only while `is-active`, and tears down when unset or removed. Write the inverse rule for `is-active` — Quark rules do not revert.
|
|
89
|
+
|
|
90
|
+
`dismiss-watcher-dismiss` bubbles and is cancelable. `detail.reason` is `"escape"` / `"outside-click"`. The default action invokes each `command-name` on the target (a `command` event, as a `<button command commandfor>` would) and dispatches each `fire-event` name at it as a bubbling `CustomEvent`; `preventDefault()` keeps the panel open (an unsaved-changes guard, for instance).
|
|
91
|
+
|
|
92
|
+
### API Reference
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
#### Attributes
|
|
96
|
+
|
|
97
|
+
| Name | Surface | Type | Default | Values | Description |
|
|
98
|
+
| --- | --- | --- | --- | --- | --- |
|
|
99
|
+
| `is-active` | hybrid | `boolean` | | | Watchers are live while set. Gate it from Quark on the panel's open state, and write the inverse rule. |
|
|
100
|
+
| `watch-escape` | option | `boolean` | | | Watch Escape / the back gesture through a `CloseWatcher`. When neither `watch-*` attribute is present both watchers are on. |
|
|
101
|
+
| `watch-outside-click` | option | `boolean` | | | Watch for a `mouseup` on the document outside the target. When neither `watch-*` attribute is present both watchers are on. |
|
|
102
|
+
| `target-ref` | option | `string` | | | Selector for the element being dismissed, `:scope`-relative (`:scope ~ nav`). Unset = the parent element. |
|
|
103
|
+
| `command-name` | option | `tokenlist` | | `<command>…` | Commands invoked on the target as the default action of `dismiss-watcher-dismiss` — `--close` for a `<content-drawer>`, or any `--verb` the panel handles. |
|
|
104
|
+
| `fire-event` | option | `tokenlist` | | | Event names dispatched at the target (bubbling `CustomEvent`s) as the default action of `dismiss-watcher-dismiss`, for panels driven by events rather than commands (`menu-close`). |
|
|
105
|
+
|
|
106
|
+
#### Fires
|
|
107
|
+
|
|
108
|
+
| Name | Type | Description |
|
|
109
|
+
| --- | --- | --- |
|
|
110
|
+
| `dismiss-watcher-dismiss` | `DismissWatcherDismissEvent` (`CustomEvent & { type: "dismiss-watcher-dismiss"; detail: { reason: "escape" \| "outside-click" }; bubbles: true; cancelable: true; composed: true }`) | A dismissal was requested; `detail.reason` is `"escape"` or `"outside-click"`. Default action: invoke each `command-name` on the target and dispatch each `fire-event` name at it as a bubbling `CustomEvent`. `preventDefault()` skips both. |
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
### Examples
|
|
115
|
+
|
|
116
|
+
#### Menu panel
|
|
117
|
+
|
|
118
|
+
Both watchers on (neither `watch-*` set), target = the parent `<nav>`. The sheet opens on `menu-open`, closes on `dismiss-watcher-dismiss`, and gates `is-active` on `data-is-open` with its inverse rule.
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
```html
|
|
122
|
+
<div>
|
|
123
|
+
<quark-sheet>
|
|
124
|
+
:scope {
|
|
125
|
+
@on menu-open { data-is-open: ""; }
|
|
126
|
+
@on dismiss-watcher-dismiss { data-is-open: none; }
|
|
127
|
+
&[data-is-open] dismiss-watcher { is-active: ""; }
|
|
128
|
+
&:not([data-is-open]) dismiss-watcher { is-active: none; }
|
|
129
|
+
}
|
|
130
|
+
</quark-sheet>
|
|
131
|
+
<style>
|
|
132
|
+
[data-demo-menu] { display: none; }
|
|
133
|
+
[data-is-open] > [data-demo-menu] { display: block; }
|
|
134
|
+
</style>
|
|
135
|
+
<event-handler role="button" fire-event="menu-open">Open menu</event-handler>
|
|
136
|
+
<nav data-demo-menu>
|
|
137
|
+
<dismiss-watcher></dismiss-watcher>
|
|
138
|
+
<ul>
|
|
139
|
+
<li><a href="#">Profile</a></li>
|
|
140
|
+
<li><a href="#">Settings</a></li>
|
|
141
|
+
<li><a href="#">Sign out</a></li>
|
|
142
|
+
</ul>
|
|
143
|
+
<p>Press Escape or click outside to close.</p>
|
|
144
|
+
</nav>
|
|
145
|
+
</div>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
#### Content drawer
|
|
150
|
+
|
|
151
|
+
First child of `<content-drawer>`, `command-name="--close"` — the drawer needs no dismissal logic of its own. `is-active` follows `content-drawer[is-open]`.
|
|
152
|
+
|
|
153
|
+
Open with `--open`, not `--toggle`: an outside `mouseup` on the button closes the drawer first, then the button's `click` re-opens it. With `--toggle` the same click would close it again.
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
```html
|
|
157
|
+
<section>
|
|
158
|
+
<quark-sheet>
|
|
159
|
+
:scope {
|
|
160
|
+
content-drawer[is-open] dismiss-watcher { is-active: ""; }
|
|
161
|
+
content-drawer:not([is-open]) dismiss-watcher { is-active: none; }
|
|
162
|
+
}
|
|
163
|
+
</quark-sheet>
|
|
164
|
+
<button type="button" command="--open" commandfor="demo-dismiss-drawer">
|
|
165
|
+
Open drawer
|
|
166
|
+
</button>
|
|
167
|
+
<content-drawer id="demo-dismiss-drawer">
|
|
168
|
+
<dismiss-watcher watch-escape watch-outside-click command-name="--close"></dismiss-watcher>
|
|
169
|
+
<header>
|
|
170
|
+
<h2>Drawer</h2>
|
|
171
|
+
</header>
|
|
172
|
+
<p>Press Escape or click outside to close.</p>
|
|
173
|
+
</content-drawer>
|
|
174
|
+
<event-handler class="tag-backdrop" role="presentation" target-ref="content-drawer:has(+ :scope)" command-name="--close"></event-handler>
|
|
175
|
+
</section>
|
|
176
|
+
```
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# dismiss-watcher
|
|
2
|
+
|
|
3
|
+
One dismissal Adapter for drawers, menus, dialogs and popovers — Escape / back gesture and outside click, without each panel element owning the logic.
|
|
4
|
+
|
|
5
|
+
<include-content data-demo="simple"></include-content>
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Escape / back gesture** Through a `CloseWatcher` (Android back, Escape) via `watch-escape`
|
|
10
|
+
- **Outside click** A `mouseup` outside the target via `watch-outside-click`
|
|
11
|
+
- **One event** `dismiss-watcher-dismiss` with `detail.reason`; cancel it with `preventDefault()`
|
|
12
|
+
- **Default action** `command-name` commands invoked on the target (`--close`), or `fire-event` names dispatched at it
|
|
13
|
+
- **Any target** The parent by default, or `target-ref` (`:scope`-relative)
|
|
14
|
+
- **Gated by State** Live only while `is-active` — set it from Quark on the panel's open state
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
<include-content is-active template-ref="/views/install-section/install-section.html"></include-content>
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
Drop it inside the element being dismissed, gate `is-active` on that element's open state, and either react to `dismiss-watcher-dismiss` or let `command-name` / `fire-event` close the panel for you. When neither `watch-escape` nor `watch-outside-click` is present, both watchers are on.
|
|
23
|
+
|
|
24
|
+
```html
|
|
25
|
+
<nav>
|
|
26
|
+
<dismiss-watcher fire-event="menu-close"></dismiss-watcher>
|
|
27
|
+
…
|
|
28
|
+
</nav>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```quark
|
|
32
|
+
:scope {
|
|
33
|
+
@on menu-open { data-is-open: ""; }
|
|
34
|
+
@on menu-close { data-is-open: none; }
|
|
35
|
+
&[data-is-open] dismiss-watcher { is-active: ""; }
|
|
36
|
+
&:not([data-is-open]) dismiss-watcher { is-active: none; }
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Why a separate element: dismissal is the same request whether the panel is a drawer, a menu, a dialog or a popover. Panel elements keep their own state (`is-open`); this Adapter only asks them to close. It renders nothing, listens only while `is-active`, and tears down when unset or removed. Write the inverse rule for `is-active` — Quark rules do not revert.
|
|
41
|
+
|
|
42
|
+
`dismiss-watcher-dismiss` bubbles and is cancelable. `detail.reason` is `"escape"` / `"outside-click"`. The default action invokes each `command-name` on the target (a `command` event, as a `<button command commandfor>` would) and dispatches each `fire-event` name at it as a bubbling `CustomEvent`; `preventDefault()` keeps the panel open (an unsaved-changes guard, for instance).
|
|
43
|
+
|
|
44
|
+
### API Reference
|
|
45
|
+
|
|
46
|
+
<include-content is-active template-ref="/views/api-reference/api-reference.html"></include-content>
|
|
47
|
+
|
|
48
|
+
### Examples
|
|
49
|
+
|
|
50
|
+
#### Menu panel
|
|
51
|
+
|
|
52
|
+
Both watchers on (neither `watch-*` set), target = the parent `<nav>`. The sheet opens on `menu-open`, closes on `dismiss-watcher-dismiss`, and gates `is-active` on `data-is-open` with its inverse rule.
|
|
53
|
+
|
|
54
|
+
<include-content data-demo="simple"></include-content>
|
|
55
|
+
|
|
56
|
+
#### Content drawer
|
|
57
|
+
|
|
58
|
+
First child of `<content-drawer>`, `command-name="--close"` — the drawer needs no dismissal logic of its own. `is-active` follows `content-drawer[is-open]`.
|
|
59
|
+
|
|
60
|
+
Open with `--open`, not `--toggle`: an outside `mouseup` on the button closes the drawer first, then the button's `click` re-opens it. With `--toggle` the same click would close it again.
|
|
61
|
+
|
|
62
|
+
<include-content data-demo="drawer"></include-content>
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
{
|
|
2
|
+
"shortName": "dismiss-watcher",
|
|
3
|
+
"package": {
|
|
4
|
+
"name": "@excom/dismiss-watcher",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"description": "<dismiss-watcher> custom element",
|
|
7
|
+
"peerDependencies": {},
|
|
8
|
+
"excom": {
|
|
9
|
+
"packageType": "kit-element"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"demos": {
|
|
13
|
+
"drawer": "<section>\n <quark-sheet>\n :scope {\n content-drawer[is-open] dismiss-watcher { is-active: \"\"; }\n content-drawer:not([is-open]) dismiss-watcher { is-active: none; }\n }\n </quark-sheet>\n <button type=\"button\" command=\"--open\" commandfor=\"demo-dismiss-drawer\">\n Open drawer\n </button>\n <content-drawer id=\"demo-dismiss-drawer\">\n <dismiss-watcher watch-escape watch-outside-click command-name=\"--close\"></dismiss-watcher>\n <header>\n <h2>Drawer</h2>\n </header>\n <p>Press Escape or click outside to close.</p>\n </content-drawer>\n <event-handler class=\"tag-backdrop\" role=\"presentation\" target-ref=\"content-drawer:has(+ :scope)\" command-name=\"--close\"></event-handler>\n</section>\n",
|
|
14
|
+
"simple": "<div>\n <quark-sheet>\n :scope {\n @on menu-open { data-is-open: \"\"; }\n @on dismiss-watcher-dismiss { data-is-open: none; }\n &[data-is-open] dismiss-watcher { is-active: \"\"; }\n &:not([data-is-open]) dismiss-watcher { is-active: none; }\n }\n </quark-sheet>\n <style>\n [data-demo-menu] { display: none; }\n [data-is-open] > [data-demo-menu] { display: block; }\n </style>\n <event-handler role=\"button\" fire-event=\"menu-open\">Open menu</event-handler>\n <nav data-demo-menu>\n <dismiss-watcher></dismiss-watcher>\n <ul>\n <li><a href=\"#\">Profile</a></li>\n <li><a href=\"#\">Settings</a></li>\n <li><a href=\"#\">Sign out</a></li>\n </ul>\n <p>Press Escape or click outside to close.</p>\n </nav>\n</div>\n"
|
|
15
|
+
},
|
|
16
|
+
"readme": "<h1 id=\"md-dismiss-watcher\">dismiss-watcher</h1>\n<p>One dismissal Adapter for drawers, menus, dialogs and popovers — Escape / back gesture and outside click, without each panel element owning the logic.</p>\n<p><include-content data-demo=\"simple\"></include-content></p>\n<h2 id=\"md-features\">Features</h2>\n<ul>\n<li><strong>Escape / back gesture</strong> Through a <code>CloseWatcher</code> (Android back, Escape) via <code>watch-escape</code></li>\n<li><strong>Outside click</strong> A <code>mouseup</code> outside the target via <code>watch-outside-click</code></li>\n<li><strong>One event</strong> <code>dismiss-watcher-dismiss</code> with <code>detail.reason</code>; cancel it with <code>preventDefault()</code></li>\n<li><strong>Default action</strong> <code>command-name</code> commands invoked on the target (<code>--close</code>), or <code>fire-event</code> names dispatched at it</li>\n<li><strong>Any target</strong> The parent by default, or <code>target-ref</code> (<code>:scope</code>-relative)</li>\n<li><strong>Gated by State</strong> Live only while <code>is-active</code> — set it from Quark on the panel's open state</li>\n</ul>\n<h2 id=\"md-installation\">Installation</h2>\n<p><include-content is-active template-ref=\"/views/install-section/install-section.html\"></include-content></p>\n<h2 id=\"md-usage\">Usage</h2>\n<p>Drop it inside the element being dismissed, gate <code>is-active</code> on that element's open state, and either react to <code>dismiss-watcher-dismiss</code> or let <code>command-name</code> / <code>fire-event</code> close the panel for you. When neither <code>watch-escape</code> nor <code>watch-outside-click</code> is present, both watchers are on.</p>\n<include-content data-language=\"html\"><template><nav>\n <dismiss-watcher fire-event=\"menu-close\"></dismiss-watcher>\n …\n</nav></template></include-content>\n<include-content data-language=\"quark\"><template>:scope {\n @on menu-open { data-is-open: \"\"; }\n @on menu-close { data-is-open: none; }\n &[data-is-open] dismiss-watcher { is-active: \"\"; }\n &:not([data-is-open]) dismiss-watcher { is-active: none; }\n}</template></include-content>\n<p>Why a separate element: dismissal is the same request whether the panel is a drawer, a menu, a dialog or a popover. Panel elements keep their own state (<code>is-open</code>); this Adapter only asks them to close. It renders nothing, listens only while <code>is-active</code>, and tears down when unset or removed. Write the inverse rule for <code>is-active</code> — Quark rules do not revert.</p>\n<p><code>dismiss-watcher-dismiss</code> bubbles and is cancelable. <code>detail.reason</code> is <code>"escape"</code> / <code>"outside-click"</code>. The default action invokes each <code>command-name</code> on the target (a <code>command</code> event, as a <code><button command commandfor></code> would) and dispatches each <code>fire-event</code> name at it as a bubbling <code>CustomEvent</code>; <code>preventDefault()</code> keeps the panel open (an unsaved-changes guard, for instance).</p>\n<h3 id=\"md-api-reference\">API Reference</h3>\n<p><include-content is-active template-ref=\"/views/api-reference/api-reference.html\"></include-content></p>\n<h3 id=\"md-examples\">Examples</h3>\n<h4 id=\"md-menu-panel\">Menu panel</h4>\n<p>Both watchers on (neither <code>watch-*</code> set), target = the parent <code><nav></code>. The sheet opens on <code>menu-open</code>, closes on <code>dismiss-watcher-dismiss</code>, and gates <code>is-active</code> on <code>data-is-open</code> with its inverse rule.</p>\n<p><include-content data-demo=\"simple\"></include-content></p>\n<h4 id=\"md-content-drawer\">Content drawer</h4>\n<p>First child of <code><content-drawer></code>, <code>command-name="--close"</code> — the drawer needs no dismissal logic of its own. <code>is-active</code> follows <code>content-drawer[is-open]</code>.</p>\n<p>Open with <code>--open</code>, not <code>--toggle</code>: an outside <code>mouseup</code> on the button closes the drawer first, then the button's <code>click</code> re-opens it. With <code>--toggle</code> the same click would close it again.</p>\n<p><include-content data-demo=\"drawer\"></include-content></p>\n",
|
|
17
|
+
"docs": {
|
|
18
|
+
"readme": "<h1 id=\"md-dismiss-watcher\">dismiss-watcher</h1>\n<p>One dismissal Adapter for drawers, menus, dialogs and popovers — Escape / back gesture and outside click, without each panel element owning the logic.</p>\n<p><include-content data-demo=\"simple\"></include-content></p>\n<h2 id=\"md-features\">Features</h2>\n<ul>\n<li><strong>Escape / back gesture</strong> Through a <code>CloseWatcher</code> (Android back, Escape) via <code>watch-escape</code></li>\n<li><strong>Outside click</strong> A <code>mouseup</code> outside the target via <code>watch-outside-click</code></li>\n<li><strong>One event</strong> <code>dismiss-watcher-dismiss</code> with <code>detail.reason</code>; cancel it with <code>preventDefault()</code></li>\n<li><strong>Default action</strong> <code>command-name</code> commands invoked on the target (<code>--close</code>), or <code>fire-event</code> names dispatched at it</li>\n<li><strong>Any target</strong> The parent by default, or <code>target-ref</code> (<code>:scope</code>-relative)</li>\n<li><strong>Gated by State</strong> Live only while <code>is-active</code> — set it from Quark on the panel's open state</li>\n</ul>\n<h2 id=\"md-installation\">Installation</h2>\n<p><include-content is-active template-ref=\"/views/install-section/install-section.html\"></include-content></p>\n<h2 id=\"md-usage\">Usage</h2>\n<p>Drop it inside the element being dismissed, gate <code>is-active</code> on that element's open state, and either react to <code>dismiss-watcher-dismiss</code> or let <code>command-name</code> / <code>fire-event</code> close the panel for you. When neither <code>watch-escape</code> nor <code>watch-outside-click</code> is present, both watchers are on.</p>\n<include-content data-language=\"html\"><template><nav>\n <dismiss-watcher fire-event=\"menu-close\"></dismiss-watcher>\n …\n</nav></template></include-content>\n<include-content data-language=\"quark\"><template>:scope {\n @on menu-open { data-is-open: \"\"; }\n @on menu-close { data-is-open: none; }\n &[data-is-open] dismiss-watcher { is-active: \"\"; }\n &:not([data-is-open]) dismiss-watcher { is-active: none; }\n}</template></include-content>\n<p>Why a separate element: dismissal is the same request whether the panel is a drawer, a menu, a dialog or a popover. Panel elements keep their own state (<code>is-open</code>); this Adapter only asks them to close. It renders nothing, listens only while <code>is-active</code>, and tears down when unset or removed. Write the inverse rule for <code>is-active</code> — Quark rules do not revert.</p>\n<p><code>dismiss-watcher-dismiss</code> bubbles and is cancelable. <code>detail.reason</code> is <code>"escape"</code> / <code>"outside-click"</code>. The default action invokes each <code>command-name</code> on the target (a <code>command</code> event, as a <code><button command commandfor></code> would) and dispatches each <code>fire-event</code> name at it as a bubbling <code>CustomEvent</code>; <code>preventDefault()</code> keeps the panel open (an unsaved-changes guard, for instance).</p>\n<h3 id=\"md-api-reference\">API Reference</h3>\n<p><include-content is-active template-ref=\"/views/api-reference/api-reference.html\"></include-content></p>\n<h3 id=\"md-examples\">Examples</h3>\n<h4 id=\"md-menu-panel\">Menu panel</h4>\n<p>Both watchers on (neither <code>watch-*</code> set), target = the parent <code><nav></code>. The sheet opens on <code>menu-open</code>, closes on <code>dismiss-watcher-dismiss</code>, and gates <code>is-active</code> on <code>data-is-open</code> with its inverse rule.</p>\n<p><include-content data-demo=\"simple\"></include-content></p>\n<h4 id=\"md-content-drawer\">Content drawer</h4>\n<p>First child of <code><content-drawer></code>, <code>command-name="--close"</code> — the drawer needs no dismissal logic of its own. <code>is-active</code> follows <code>content-drawer[is-open]</code>.</p>\n<p>Open with <code>--open</code>, not <code>--toggle</code>: an outside <code>mouseup</code> on the button closes the drawer first, then the button's <code>click</code> re-opens it. With <code>--toggle</code> the same click would close it again.</p>\n<p><include-content data-demo=\"drawer\"></include-content></p>\n"
|
|
19
|
+
},
|
|
20
|
+
"installation": {
|
|
21
|
+
"name": "@excom/dismiss-watcher",
|
|
22
|
+
"shortName": "dismiss-watcher",
|
|
23
|
+
"version": "0.1.0",
|
|
24
|
+
"description": "<dismiss-watcher> custom element",
|
|
25
|
+
"packageType": "kit-element",
|
|
26
|
+
"cdn": "<script src=\"https://unpkg.com/@excom/kit-utils/dist/index.umd.min.js\"></script>\n<script src=\"https://unpkg.com/@excom/neutron/dist/index.umd.min.js\"></script>\n<script src=\"https://unpkg.com/@excom/dismiss-watcher@0.1.0/dist/index.umd.min.js\"></script>",
|
|
27
|
+
"install": {
|
|
28
|
+
"npm": "npm install @excom/dismiss-watcher"
|
|
29
|
+
},
|
|
30
|
+
"imports": {
|
|
31
|
+
"js": "import \"@excom/dismiss-watcher\";",
|
|
32
|
+
"html": "<!-- import path to `node_modules` will depend on your build setup -->\n<script type=\"module\" src=\"/node_modules/@excom/dismiss-watcher\"></script>\n<link rel=\"stylesheet\" href=\"/node_modules/@excom/dismiss-watcher\">"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": []
|
|
35
|
+
},
|
|
36
|
+
"elementApis": [
|
|
37
|
+
{
|
|
38
|
+
"tag": "dismiss-watcher",
|
|
39
|
+
"summary": "Escape / back-gesture and outside-click dismissal for any panel.",
|
|
40
|
+
"kind": "class",
|
|
41
|
+
"attributes": [
|
|
42
|
+
{
|
|
43
|
+
"name": "command-name",
|
|
44
|
+
"type": "tokenlist",
|
|
45
|
+
"description": "Commands invoked on the target as the default action of <code>dismiss-watcher-dismiss</code> — <code>--close</code> for a <code><content-drawer></code>, or any <code>--verb</code> the panel handles.",
|
|
46
|
+
"fieldName": "commandName",
|
|
47
|
+
"surface": "option",
|
|
48
|
+
"values": "<command>…"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": "fire-event",
|
|
52
|
+
"type": "tokenlist",
|
|
53
|
+
"description": "Event names dispatched at the target (bubbling <code>CustomEvent</code>s) as the default action of <code>dismiss-watcher-dismiss</code>, for panels driven by events rather than commands (<code>menu-close</code>).",
|
|
54
|
+
"fieldName": "fireEvent",
|
|
55
|
+
"surface": "option"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"name": "target-ref",
|
|
59
|
+
"type": "string",
|
|
60
|
+
"description": "Selector for the element being dismissed, <code>:scope</code>-relative (<code>:scope ~ nav</code>). Unset = the parent element.",
|
|
61
|
+
"fieldName": "targetRef",
|
|
62
|
+
"surface": "option"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "watch-escape",
|
|
66
|
+
"type": "boolean",
|
|
67
|
+
"description": "Watch Escape / the back gesture through a <code>CloseWatcher</code>. When neither <code>watch-*</code> attribute is present both watchers are on.",
|
|
68
|
+
"fieldName": "watchEscape",
|
|
69
|
+
"surface": "option"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "watch-outside-click",
|
|
73
|
+
"type": "boolean",
|
|
74
|
+
"description": "Watch for a <code>mouseup</code> on the document outside the target. When neither <code>watch-*</code> attribute is present both watchers are on.",
|
|
75
|
+
"fieldName": "watchOutsideClick",
|
|
76
|
+
"surface": "option"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"name": "is-active",
|
|
80
|
+
"type": "boolean",
|
|
81
|
+
"description": "Watchers are live while set. Gate it from Quark on the panel's open state, and write the inverse rule.",
|
|
82
|
+
"fieldName": "isActive",
|
|
83
|
+
"surface": "hybrid"
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
"events": [
|
|
87
|
+
{
|
|
88
|
+
"name": "dismiss-watcher-dismiss",
|
|
89
|
+
"description": "A dismissal was requested; <code>detail.reason</code> is <code>"escape"</code> or <code>"outside-click"</code>. Default action: invoke each <code>command-name</code> on the target and dispatch each <code>fire-event</code> name at it as a bubbling <code>CustomEvent</code>. <code>preventDefault()</code> skips both.",
|
|
90
|
+
"type": "DismissWatcherDismissEvent",
|
|
91
|
+
"typeExpanded": "CustomEvent & { type: \"dismiss-watcher-dismiss\"; detail: { reason: \"escape\" | \"outside-click\" }; bubbles: true; cancelable: true; composed: true }"
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
"slots": [],
|
|
95
|
+
"cssProperties": [],
|
|
96
|
+
"cssClasses": [],
|
|
97
|
+
"cssAliases": [],
|
|
98
|
+
"listens": [],
|
|
99
|
+
"commands": [],
|
|
100
|
+
"defaultActions": [],
|
|
101
|
+
"expectedChildren": [],
|
|
102
|
+
"provisions": []
|
|
103
|
+
}
|
|
104
|
+
],
|
|
105
|
+
"exportedFiles": {}
|
|
106
|
+
}
|