@excom/event-handler 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.
Files changed (52) hide show
  1. package/.rush/temp/chunked-rush-logs/event-handler.apply-exports.chunks.jsonl +1 -0
  2. package/.rush/temp/chunked-rush-logs/event-handler.build_docs.chunks.jsonl +1 -0
  3. package/.rush/temp/chunked-rush-logs/event-handler.build_package-metas.chunks.jsonl +1 -0
  4. package/.rush/temp/operation/apply-exports/all.log +1 -0
  5. package/.rush/temp/operation/apply-exports/log-chunks.jsonl +1 -0
  6. package/.rush/temp/operation/apply-exports/state.json +3 -0
  7. package/.rush/temp/operation/build_docs/all.log +1 -0
  8. package/.rush/temp/operation/build_docs/log-chunks.jsonl +1 -0
  9. package/.rush/temp/operation/build_docs/state.json +3 -0
  10. package/.rush/temp/operation/build_package-metas/all.log +1 -0
  11. package/.rush/temp/operation/build_package-metas/log-chunks.jsonl +1 -0
  12. package/.rush/temp/operation/build_package-metas/state.json +3 -0
  13. package/.rush/temp/shrinkwrap-deps.json +3 -0
  14. package/config/rig.json +5 -0
  15. package/event-handler.ts +178 -0
  16. package/index.css +5 -0
  17. package/index.ts +17 -0
  18. package/package.json +44 -0
  19. package/rush-logs/event-handler.apply-exports.cache.log +1 -0
  20. package/rush-logs/event-handler.apply-exports.log +1 -0
  21. package/rush-logs/event-handler.build_docs.cache.log +1 -0
  22. package/rush-logs/event-handler.build_docs.log +1 -0
  23. package/rush-logs/event-handler.build_package-metas.cache.log +1 -0
  24. package/rush-logs/event-handler.build_package-metas.log +1 -0
  25. package/src/event-handler.css +19 -0
  26. package/support/custom-elements.json +245 -0
  27. package/support/demos/command-dialog.html +9 -0
  28. package/support/demos/debounce.html +21 -0
  29. package/support/demos/enter-close.html +13 -0
  30. package/support/demos/escape-close.html +16 -0
  31. package/support/demos/fire-event.html +13 -0
  32. package/support/demos/prevent-default.html +3 -0
  33. package/support/demos/retarget.html +14 -0
  34. package/support/demos/with-as.html +8 -0
  35. package/support/dist-docs/event-handler.md +277 -0
  36. package/support/docs/INTERNAL.md +1 -0
  37. package/support/docs/README.md +97 -0
  38. package/support/package-meta.json +249 -0
  39. package/support/tests/__snapshots__/debounce.view.test.ts.snap +23 -0
  40. package/support/tests/__snapshots__/fire-event.view.test.ts.snap +23 -0
  41. package/support/tests/__snapshots__/retarget.view.test.ts.snap +23 -0
  42. package/support/tests/command-dialog.view.test.ts +34 -0
  43. package/support/tests/debounce.view.test.ts +43 -0
  44. package/support/tests/enter-close.view.test.ts +35 -0
  45. package/support/tests/escape-close.view.test.ts +44 -0
  46. package/support/tests/event-handler.form-fallback.test.ts +49 -0
  47. package/support/tests/event-handler.test.ts +524 -0
  48. package/support/tests/fire-event.view.test.ts +38 -0
  49. package/support/tests/prevent-default.view.test.ts +21 -0
  50. package/support/tests/retarget.view.test.ts +38 -0
  51. package/support/tests/with-as.view.test.ts +31 -0
  52. package/tsconfig.json +5 -0
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: cd \"$RUSH_PROJECT_FOLDER\" && node ../heft-rig/scripts/apply-exports.mjs \n"}
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs \n"}
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs \n"}
@@ -0,0 +1 @@
1
+ Invoking: cd "$RUSH_PROJECT_FOLDER" && node ../heft-rig/scripts/apply-exports.mjs
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: cd \"$RUSH_PROJECT_FOLDER\" && node ../heft-rig/scripts/apply-exports.mjs \n"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "nonCachedDurationMs": 32.580141999999796
3
+ }
@@ -0,0 +1 @@
1
+ Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs \n"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "nonCachedDurationMs": 53.968691000000035
3
+ }
@@ -0,0 +1 @@
1
+ Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs
@@ -0,0 +1 @@
1
+ {"kind":"O","text":"Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs \n"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "nonCachedDurationMs": 103.61115000000018
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "../../packages/event-handler": "../../packages/event-handler:iu+Gwd294io6cbeYmVbBu6c2aWWWMg9YuILC/ZbWLyY=:"
3
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
3
+ "rigPackageName": "@excom/heft-rig",
4
+ "rigProfile": "default"
5
+ }
@@ -0,0 +1,178 @@
1
+ import {
2
+ attributesToEntries,
3
+ attributesToObject,
4
+ Converter,
5
+ dashToCamel,
6
+ selectOne,
7
+ setAttr,
8
+ } from "@excom/kit-utils";
9
+ import { formToJson } from "@excom/kit-utils";
10
+ import { ListenableElement } from "@excom/listenable-element";
11
+ import { Neutron, TokenList } from "@excom/neutron";
12
+
13
+ const attrFormatters = {
14
+ event: (attr: Attr): [string, string] => [
15
+ dashToCamel(attr.name.replace("detail-", "")),
16
+ attr.value,
17
+ ],
18
+ mutate: (attr: Attr): [string, string] => [
19
+ attr.name.replace("attr-", ""),
20
+ attr.value,
21
+ ],
22
+ };
23
+
24
+ /**
25
+ * Declarative bridge between DOM events and app actions. Listens (default
26
+ * `click`) and either fires custom events or invokes commands — built-in
27
+ * verbs (`show-modal`, `toggle-popover`) and the `--verb` commands elements
28
+ * handle — on any `target-ref` selector, where a `<button commandfor>` needs
29
+ * an id. Event payload comes from `detail-*` attributes and an optional
30
+ * `<form>` via `form-ref`.
31
+ *
32
+ * @summary Rewire clicks / inputs into events or commands.
33
+ *
34
+ * @example
35
+ * <event-handler fire-event="cart-add" detail-sku="sku-1">
36
+ * Add to cart
37
+ * </event-handler>
38
+ */
39
+ export const EventHandler = Neutron.compose([
40
+ ListenableElement,
41
+ Neutron({
42
+ tag: "event-handler",
43
+ props: {
44
+ /**
45
+ * @option
46
+ * Where outgoing events / mutations / commands apply. Unset = this
47
+ * element. Supports `:scope` for relative targeting (e.g.
48
+ * `:scope ~ dialog`).
49
+ * @values <CSS Selector>
50
+ */
51
+ targetRef: String,
52
+ /**
53
+ * @option
54
+ * Space-separated event names to dispatch on the target. Each name
55
+ * gets the same merged `detail`. Ignored when `mutate-target` is set.
56
+ * Pair with `detail-*` attributes for static detail fields.
57
+ * @values <EventName>…
58
+ */
59
+ fireEvent: TokenList,
60
+ /**
61
+ * @option
62
+ * Space-separated commands to invoke on the target: custom `--verb`
63
+ * commands (`--submit`, `--close`) dispatch a `command` event, as a
64
+ * `<button command commandfor>` would; built-in verbs (`show-modal`,
65
+ * `close`, `toggle-popover`) run through the platform.
66
+ * @values <command>…
67
+ */
68
+ commandName: TokenList,
69
+ /**
70
+ * @option
71
+ * Outgoing events use `bubbles: false` (default: bubble).
72
+ */
73
+ notBubbles: Boolean,
74
+ /**
75
+ * @option
76
+ * Outgoing events use `cancelable: false` (default: cancelable).
77
+ */
78
+ notCancelable: Boolean,
79
+ /**
80
+ * @option
81
+ * Outgoing events use `composed: false` (default: composed / cross
82
+ * shadow roots).
83
+ */
84
+ notComposed: Boolean,
85
+ /**
86
+ * @option
87
+ * `<form>` whose fields merge into event `detail`, or become
88
+ * attributes when `mutate-target` is set.
89
+ * @values <CSS Selector>
90
+ */
91
+ formRef: String,
92
+ /**
93
+ * @option
94
+ * @deprecated Write attributes on the target instead of firing events
95
+ * (sources: `attr-*` on this element plus `form-ref` fields). Use a
96
+ * Quark `@on <event> { … }` block instead — it writes State from the
97
+ * event without one element mutating another. Kept for
98
+ * compatibility; will be removed in a future major.
99
+ */
100
+ mutateTarget: Boolean,
101
+ },
102
+ }),
103
+ ])
104
+ .defineMethods({
105
+ actionHandler: (element) => {
106
+ const target = (
107
+ element.targetRef
108
+ ? selectOne(element.targetRef, {
109
+ scope: element,
110
+ })
111
+ : element
112
+ ) as HTMLElement;
113
+ /* `form-ref` → its values; `{}` unless it resolves to a `<form>` */
114
+ const formValues = (): Record<string, unknown> => {
115
+ const form = element.formRef
116
+ ? selectOne(element.formRef, { scope: element })
117
+ : null;
118
+ return form instanceof HTMLFormElement ? formToJson(form) : {};
119
+ };
120
+ if (
121
+ element.mutateTarget &&
122
+ target instanceof HTMLElement &&
123
+ target !== element
124
+ ) {
125
+ const formData = formValues();
126
+ [
127
+ ...Object.entries(formData || {}),
128
+ ...attributesToEntries(
129
+ element.attributes,
130
+ "attr-",
131
+ attrFormatters.mutate
132
+ ),
133
+ ].forEach(([key, value]) => {
134
+ const v = Converter.type(typeof value)?.prop.convert(value);
135
+ setAttr(target, key, v !== undefined ? v : value);
136
+ });
137
+ } else if (element.fireEvent?.length || element.commandName?.length) {
138
+ const { detail, ...otherFormData }: Record<string, unknown> =
139
+ formValues();
140
+ const detailObj = {
141
+ ...(detail || {}),
142
+ ...attributesToObject(
143
+ element.attributes,
144
+ "detail-",
145
+ attrFormatters.event
146
+ ),
147
+ };
148
+ return [
149
+ ...(element.commandName || [])?.map((commandName) => ({
150
+ command: [commandName, { target }],
151
+ })),
152
+ ...(element.fireEvent || [])?.map((eventName) => ({
153
+ emit: [
154
+ eventName,
155
+ {
156
+ bubbles: !element.notBubbles,
157
+ cancelable: !element.notCancelable,
158
+ composed: !element.notComposed,
159
+ ...(Object.keys(otherFormData || {}).length
160
+ ? otherFormData
161
+ : {}),
162
+ ...(Object.keys(detailObj).length ? { detail: detailObj } : {}),
163
+ target,
164
+ },
165
+ ],
166
+ })),
167
+ ];
168
+ }
169
+ },
170
+ })
171
+ .onConnected(
172
+ ({ listenFor, listenForLifecycle, handleEvent, isMoving }) =>
173
+ !isMoving &&
174
+ !listenFor?.length &&
175
+ !listenForLifecycle?.length && {
176
+ addListener: ["click", handleEvent],
177
+ }
178
+ );
package/index.css ADDED
@@ -0,0 +1,5 @@
1
+ @import "./src/event-handler.css";
2
+
3
+ @layer {
4
+ @mixin module-event-handler;
5
+ }
package/index.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { EventHandler } from "./event-handler";
2
+
3
+ EventHandler.define();
4
+
5
+ export { EventHandler };
6
+
7
+ type T_HTMLEventHandlerElement = typeof EventHandler.CustomElement;
8
+ declare global {
9
+ interface HTMLEventHandlerElement extends T_HTMLEventHandlerElement {}
10
+ interface Window {
11
+ HTMLEventHandlerElement: HTMLEventHandlerElement;
12
+ }
13
+ interface HTMLElementTagNameMap {
14
+ "event-handler": HTMLEventHandlerElement;
15
+ }
16
+ }
17
+ export type { HTMLEventHandlerElement };
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@excom/event-handler",
3
+ "version": "0.1.0",
4
+ "description": "<event-handler> custom element",
5
+ "license": "MIT",
6
+ "engines": {
7
+ "node": ">=24.13.0"
8
+ },
9
+ "type": "module",
10
+ "dependencies": {
11
+ "@excom/kit-utils": "^0.1.0",
12
+ "@excom/listenable-element": "^0.1.0",
13
+ "@excom/neutron": "^0.1.0"
14
+ },
15
+ "peerDependencies": {},
16
+ "devDependencies": {
17
+ "@excom/heft-rig": "^0.1.0"
18
+ },
19
+ "repository": {
20
+ "url": "excom-dev/nucleus",
21
+ "directory": "packages/event-handler"
22
+ },
23
+ "homepage": "https://github.com/excom-dev/nucleus/tree/main/packages/event-handler/support/docs/README.md",
24
+ "bugs": "https://github.com/excom-dev/nucleus/issues",
25
+ "keywords": [
26
+ "event-handler",
27
+ "neutron",
28
+ "custom-elements"
29
+ ],
30
+ "excom": {
31
+ "packageType": "kit-element"
32
+ },
33
+ "scripts": {
34
+ "build": "node node_modules/@excom/heft-rig/scripts/vite-build.mjs",
35
+ "build:watch": "node node_modules/@excom/heft-rig/scripts/vite-build-watch.mjs",
36
+ "format": "node node_modules/@excom/heft-rig/scripts/format.mjs",
37
+ "test": "node node_modules/@excom/heft-rig/scripts/vitest.mjs",
38
+ "coverage": "node node_modules/@excom/heft-rig/scripts/coverage.mjs",
39
+ "dev": "node node_modules/@excom/heft-rig/scripts/vite-dev.mjs",
40
+ "preview": "node node_modules/@excom/heft-rig/scripts/vite-preview.mjs",
41
+ "build:package-metas": "node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs",
42
+ "build:docs": "node node_modules/@excom/heft-rig/scripts/build-docs.mjs"
43
+ }
44
+ }
@@ -0,0 +1 @@
1
+ Caching has been disabled for this project's "apply-exports" command.
@@ -0,0 +1 @@
1
+ Invoking: cd "$RUSH_PROJECT_FOLDER" && node ../heft-rig/scripts/apply-exports.mjs
@@ -0,0 +1 @@
1
+ This project does not define the caching behavior of the "build:docs" command, so caching has been disabled.
@@ -0,0 +1 @@
1
+ Invoking: node node_modules/@excom/heft-rig/scripts/build-docs.mjs
@@ -0,0 +1 @@
1
+ This project does not define the caching behavior of the "build:package-metas" command, so caching has been disabled.
@@ -0,0 +1 @@
1
+ Invoking: node node_modules/@excom/heft-rig/scripts/build-package-metas.mjs
@@ -0,0 +1,19 @@
1
+ @import "@excom/listenable-element/src/index.css";
2
+
3
+ /**
4
+ * Styles for `<event-handler>`.
5
+ * @element event-handler
6
+ */
7
+
8
+ /* Aliases */
9
+ @custom-selector :--event-handler event-handler, .tag-event-handler;
10
+
11
+ /**
12
+ * Skip the pointer cursor from the listenable mixin.
13
+ * @cssclass unstyled
14
+ */
15
+ @define-mixin module-event-handler {
16
+ :--event-handler:not(.unstyled) {
17
+ @mixin listenable-element;
18
+ }
19
+ }
@@ -0,0 +1,245 @@
1
+ {
2
+ "schemaVersion": "1.0.0",
3
+ "modules": [
4
+ {
5
+ "kind": "javascript-module",
6
+ "path": "event-handler.ts",
7
+ "declarations": [
8
+ {
9
+ "kind": "class",
10
+ "name": "EventHandler",
11
+ "customElement": true,
12
+ "tagName": "event-handler",
13
+ "mixins": [
14
+ {
15
+ "name": "ListenableElement",
16
+ "package": "@excom/listenable-element"
17
+ }
18
+ ],
19
+ "summary": "Rewire clicks / inputs into events or commands.",
20
+ "description": "Declarative bridge between DOM events and app actions. Listens (default `click`) and either fires custom events or invokes commands — built-in verbs (`show-modal`, `toggle-popover`) and the `--verb` commands elements handle — on any `target-ref` selector, where a `<button commandfor>` needs an id. Event payload comes from `detail-*` attributes and an optional `<form>` via `form-ref`.",
21
+ "attributes": [
22
+ {
23
+ "name": "target-ref",
24
+ "type": {
25
+ "text": "string"
26
+ },
27
+ "description": "Where outgoing events / mutations / commands apply. Unset = this element. Supports `:scope` for relative targeting (e.g. `:scope ~ dialog`).",
28
+ "fieldName": "targetRef",
29
+ "values": [
30
+ "<CSS Selector>"
31
+ ]
32
+ },
33
+ {
34
+ "name": "fire-event",
35
+ "type": {
36
+ "text": "tokenlist"
37
+ },
38
+ "description": "Space-separated event names to dispatch on the target. Each name gets the same merged `detail`. Ignored when `mutate-target` is set. Pair with `detail-*` attributes for static detail fields.",
39
+ "fieldName": "fireEvent",
40
+ "values": [
41
+ "<EventName>…"
42
+ ]
43
+ },
44
+ {
45
+ "name": "command-name",
46
+ "type": {
47
+ "text": "tokenlist"
48
+ },
49
+ "description": "Space-separated commands to invoke on the target: custom `--verb` commands (`--submit`, `--close`) dispatch a `command` event, as a `<button command commandfor>` would; built-in verbs (`show-modal`, `close`, `toggle-popover`) run through the platform.",
50
+ "fieldName": "commandName",
51
+ "values": [
52
+ "<command>…"
53
+ ]
54
+ },
55
+ {
56
+ "name": "not-bubbles",
57
+ "type": {
58
+ "text": "boolean"
59
+ },
60
+ "description": "Outgoing events use `bubbles: false` (default: bubble).",
61
+ "fieldName": "notBubbles"
62
+ },
63
+ {
64
+ "name": "not-cancelable",
65
+ "type": {
66
+ "text": "boolean"
67
+ },
68
+ "description": "Outgoing events use `cancelable: false` (default: cancelable).",
69
+ "fieldName": "notCancelable"
70
+ },
71
+ {
72
+ "name": "not-composed",
73
+ "type": {
74
+ "text": "boolean"
75
+ },
76
+ "description": "Outgoing events use `composed: false` (default: composed / cross shadow roots).",
77
+ "fieldName": "notComposed"
78
+ },
79
+ {
80
+ "name": "form-ref",
81
+ "type": {
82
+ "text": "string"
83
+ },
84
+ "description": "`<form>` whose fields merge into event `detail`, or become attributes when `mutate-target` is set.",
85
+ "fieldName": "formRef",
86
+ "values": [
87
+ "<CSS Selector>"
88
+ ]
89
+ },
90
+ {
91
+ "name": "mutate-target",
92
+ "type": {
93
+ "text": "boolean"
94
+ },
95
+ "description": "@deprecated Write attributes on the target instead of firing events (sources: `attr-*` on this element plus `form-ref` fields). Use a Quark `@on <event> { … }` block instead — it writes State from the event without one element mutating another. Kept for compatibility; will be removed in a future major.",
96
+ "fieldName": "mutateTarget"
97
+ }
98
+ ],
99
+ "members": [
100
+ {
101
+ "kind": "field",
102
+ "name": "targetRef",
103
+ "type": {
104
+ "text": "string"
105
+ },
106
+ "privacy": "public",
107
+ "readonly": false,
108
+ "description": "Where outgoing events / mutations / commands apply. Unset = this element. Supports `:scope` for relative targeting (e.g. `:scope ~ dialog`).",
109
+ "_neutron": {
110
+ "surface": "option"
111
+ }
112
+ },
113
+ {
114
+ "kind": "field",
115
+ "name": "fireEvent",
116
+ "type": {
117
+ "text": "tokenlist"
118
+ },
119
+ "privacy": "public",
120
+ "readonly": false,
121
+ "description": "Space-separated event names to dispatch on the target. Each name gets the same merged `detail`. Ignored when `mutate-target` is set. Pair with `detail-*` attributes for static detail fields.",
122
+ "_neutron": {
123
+ "surface": "option"
124
+ }
125
+ },
126
+ {
127
+ "kind": "field",
128
+ "name": "commandName",
129
+ "type": {
130
+ "text": "tokenlist"
131
+ },
132
+ "privacy": "public",
133
+ "readonly": false,
134
+ "description": "Space-separated commands to invoke on the target: custom `--verb` commands (`--submit`, `--close`) dispatch a `command` event, as a `<button command commandfor>` would; built-in verbs (`show-modal`, `close`, `toggle-popover`) run through the platform.",
135
+ "_neutron": {
136
+ "surface": "option"
137
+ }
138
+ },
139
+ {
140
+ "kind": "field",
141
+ "name": "notBubbles",
142
+ "type": {
143
+ "text": "boolean"
144
+ },
145
+ "privacy": "public",
146
+ "readonly": false,
147
+ "description": "Outgoing events use `bubbles: false` (default: bubble).",
148
+ "_neutron": {
149
+ "surface": "option"
150
+ }
151
+ },
152
+ {
153
+ "kind": "field",
154
+ "name": "notCancelable",
155
+ "type": {
156
+ "text": "boolean"
157
+ },
158
+ "privacy": "public",
159
+ "readonly": false,
160
+ "description": "Outgoing events use `cancelable: false` (default: cancelable).",
161
+ "_neutron": {
162
+ "surface": "option"
163
+ }
164
+ },
165
+ {
166
+ "kind": "field",
167
+ "name": "notComposed",
168
+ "type": {
169
+ "text": "boolean"
170
+ },
171
+ "privacy": "public",
172
+ "readonly": false,
173
+ "description": "Outgoing events use `composed: false` (default: composed / cross shadow roots).",
174
+ "_neutron": {
175
+ "surface": "option"
176
+ }
177
+ },
178
+ {
179
+ "kind": "field",
180
+ "name": "formRef",
181
+ "type": {
182
+ "text": "string"
183
+ },
184
+ "privacy": "public",
185
+ "readonly": false,
186
+ "description": "`<form>` whose fields merge into event `detail`, or become attributes when `mutate-target` is set.",
187
+ "_neutron": {
188
+ "surface": "option"
189
+ }
190
+ },
191
+ {
192
+ "kind": "field",
193
+ "name": "mutateTarget",
194
+ "type": {
195
+ "text": "boolean"
196
+ },
197
+ "privacy": "public",
198
+ "readonly": false,
199
+ "description": "@deprecated Write attributes on the target instead of firing events (sources: `attr-*` on this element plus `form-ref` fields). Use a Quark `@on <event> { … }` block instead — it writes State from the event without one element mutating another. Kept for compatibility; will be removed in a future major.",
200
+ "_neutron": {
201
+ "surface": "option"
202
+ }
203
+ }
204
+ ],
205
+ "_neutron": {
206
+ "cssClasses": [
207
+ {
208
+ "name": "unstyled",
209
+ "description": "Skip the pointer cursor from the listenable mixin."
210
+ }
211
+ ],
212
+ "cssAliases": [
213
+ {
214
+ "name": ":--event-handler",
215
+ "selectors": [
216
+ "event-handler",
217
+ ".tag-event-handler"
218
+ ],
219
+ "kind": "element"
220
+ }
221
+ ]
222
+ }
223
+ }
224
+ ],
225
+ "exports": [
226
+ {
227
+ "kind": "js",
228
+ "name": "EventHandler",
229
+ "declaration": {
230
+ "name": "EventHandler",
231
+ "module": "event-handler.ts"
232
+ }
233
+ },
234
+ {
235
+ "kind": "custom-element-definition",
236
+ "name": "event-handler",
237
+ "declaration": {
238
+ "name": "EventHandler",
239
+ "module": "event-handler.ts"
240
+ }
241
+ }
242
+ ]
243
+ }
244
+ ]
245
+ }
@@ -0,0 +1,9 @@
1
+ <section>
2
+ <event-handler target-ref=":scope + dialog" command-name="show-modal">
3
+ Open dialog
4
+ </event-handler>
5
+ <dialog>
6
+ Hello!
7
+ <form method="dialog"><button>Close</button></form>
8
+ </dialog>
9
+ </section>
@@ -0,0 +1,21 @@
1
+ <div>
2
+ <section>
3
+ <event-handler listen-for="input" delay-ms="200" is-debounced fire-event="search-query" form-ref=":scope form">
4
+ <form>
5
+ <label>
6
+ <input name="detail.q" type="search" placeholder="Type to search…" />
7
+ </label>
8
+ <label>
9
+ Strict search
10
+ <input name="detail.strict" type="checkbox" role="switch" />
11
+ </label>
12
+ </form>
13
+ </event-handler>
14
+ <output>Waiting…</output>
15
+ </section>
16
+ <quark-sheet>
17
+ @use "/demo-utils" as *;
18
+
19
+ section { @on search-query (handle: setOutputFromDetail); }
20
+ </quark-sheet>
21
+ </div>
@@ -0,0 +1,13 @@
1
+ <section>
2
+ <event-handler target-ref=":scope + content-drawer" command-name="--open">
3
+ Open drawer
4
+ </event-handler>
5
+ <content-drawer id="demo-enter-close-drawer" is-open>
6
+ <event-handler listen-for="keydown" keycode-filter="enter" target-ref="#demo-enter-close-drawer" command-name="--close">
7
+ <label>
8
+ Favorite color
9
+ <input type="text" placeholder="Type something, then press Enter to close drawer" autofocus />
10
+ </label>
11
+ </event-handler>
12
+ </content-drawer>
13
+ </section>
@@ -0,0 +1,16 @@
1
+ <section>
2
+ <event-handler target-ref=":scope ~ dialog" command-name="show-modal">
3
+ Open dialog
4
+ </event-handler>
5
+ <event-handler
6
+ host-ref="window"
7
+ listen-for="keydown"
8
+ keycode-filter="escape"
9
+ target-ref=":scope ~ dialog"
10
+ command-name="close"
11
+ ></event-handler>
12
+ <dialog>
13
+ Press Escape anywhere to close.
14
+ <form method="dialog"><button>Close</button></form>
15
+ </dialog>
16
+ </section>