@fusion.dev/helix-core 0.180.0 → 0.181.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/custom-elements.json
CHANGED
|
@@ -2539,7 +2539,7 @@
|
|
|
2539
2539
|
"declarations": [
|
|
2540
2540
|
{
|
|
2541
2541
|
"kind": "class",
|
|
2542
|
-
"description": "Passes a click on the host itself to the control inside that answers clicks.\n\n**A click dispatched on the host reaches nothing that toggles.** A switch,\na checkbox or a radio renders its control in its shadow root, and only a\nclick that lands there moves it. `element.click()`, a test's or an\nautomation's, is dispatched on the host, and so is the click a `<label for>`\non the page sends the element it names: `helix-switch` left `checked` false\nunder `click()` while a pointer press on it turned it on. A native checkbox\ntoggles on both, and code written against one expects it.\n\n**
|
|
2542
|
+
"description": "Passes a click on the host itself to the control inside that answers clicks.\n\n**A click dispatched on the host reaches nothing that toggles.** A switch,\na checkbox or a radio renders its control in its shadow root, and only a\nclick that lands there moves it. `element.click()`, a test's or an\nautomation's, is dispatched on the host, and so is the click a `<label for>`\non the page sends the element it names: `helix-switch` left `checked` false\nunder `click()` while a pointer press on it turned it on. A native checkbox\ntoggles on both, and code written against one expects it.\n\n**One click reaches the page for each press, as from a native control.**\nThe control's click used to be sent composed, so it crossed the shadow root\nand reached the host after the host's own: a listener on the host heard two\nclicks for one `click()` or one press on a `<label for>`, where one on a\nnative checkbox hears one. So there are two paths, and each leaves exactly\none click outside the shadow root:\n\n- **The host's `click()`** calls {@link click}, which clicks the control\n instead. That click is the only one: it reaches the host retargeted, as a\n click inside a native control does, after the control has moved, so a\n listener reads the new state and `preventDefault()` puts the old one back.\n- **A click that starts at the host** some other way, from a `<label for>`,\n a press on the host's own box, or `dispatchEvent`, is the click the page\n hears. The control is sent a copy that is not composed, so it moves the\n control and stops at the shadow root. The copy goes in the capture phase,\n so the host's own listeners already read the new state, as a native\n checkbox's do. A press inside the shadow root has already landed on its\n control and is left alone.",
|
|
2543
2543
|
"name": "HostClickController",
|
|
2544
2544
|
"members": [
|
|
2545
2545
|
{
|
|
@@ -2560,6 +2560,16 @@
|
|
|
2560
2560
|
}
|
|
2561
2561
|
}
|
|
2562
2562
|
},
|
|
2563
|
+
{
|
|
2564
|
+
"kind": "method",
|
|
2565
|
+
"name": "click",
|
|
2566
|
+
"return": {
|
|
2567
|
+
"type": {
|
|
2568
|
+
"text": "boolean"
|
|
2569
|
+
}
|
|
2570
|
+
},
|
|
2571
|
+
"description": "Clicks the control, for the host's own `click()`. Answers `false` when\nthere is no control yet, before the first render, so the host can fall\nback to its own click."
|
|
2572
|
+
},
|
|
2563
2573
|
{
|
|
2564
2574
|
"kind": "field",
|
|
2565
2575
|
"name": "forward",
|
|
@@ -34084,7 +34094,7 @@
|
|
|
34084
34094
|
"type": {
|
|
34085
34095
|
"text": "string"
|
|
34086
34096
|
},
|
|
34087
|
-
"default": "'0.
|
|
34097
|
+
"default": "'0.181.0'",
|
|
34088
34098
|
"description": "The version of the package this file ships in.\n\n**Written by `fusion/scripts/version.mjs`** wherever it writes the package's\n`package.json`, and stamped back into the repository beside it after a\nrelease, so the two never disagree; a spec beside this holds them to it.\nNothing else in the running code knows which release it is."
|
|
34089
34099
|
}
|
|
34090
34100
|
],
|
|
@@ -34720,6 +34730,6 @@
|
|
|
34720
34730
|
],
|
|
34721
34731
|
"helix": {
|
|
34722
34732
|
"package": "@fusion.dev/helix-core",
|
|
34723
|
-
"version": "0.
|
|
34733
|
+
"version": "0.181.0"
|
|
34724
34734
|
}
|
|
34725
34735
|
}
|
|
@@ -10,10 +10,24 @@ import type { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
|
10
10
|
* under `click()` while a pointer press on it turned it on. A native checkbox
|
|
11
11
|
* toggles on both, and code written against one expects it.
|
|
12
12
|
*
|
|
13
|
-
* **
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* **One click reaches the page for each press, as from a native control.**
|
|
14
|
+
* The control's click used to be sent composed, so it crossed the shadow root
|
|
15
|
+
* and reached the host after the host's own: a listener on the host heard two
|
|
16
|
+
* clicks for one `click()` or one press on a `<label for>`, where one on a
|
|
17
|
+
* native checkbox hears one. So there are two paths, and each leaves exactly
|
|
18
|
+
* one click outside the shadow root:
|
|
19
|
+
*
|
|
20
|
+
* - **The host's `click()`** calls {@link click}, which clicks the control
|
|
21
|
+
* instead. That click is the only one: it reaches the host retargeted, as a
|
|
22
|
+
* click inside a native control does, after the control has moved, so a
|
|
23
|
+
* listener reads the new state and `preventDefault()` puts the old one back.
|
|
24
|
+
* - **A click that starts at the host** some other way, from a `<label for>`,
|
|
25
|
+
* a press on the host's own box, or `dispatchEvent`, is the click the page
|
|
26
|
+
* hears. The control is sent a copy that is not composed, so it moves the
|
|
27
|
+
* control and stops at the shadow root. The copy goes in the capture phase,
|
|
28
|
+
* so the host's own listeners already read the new state, as a native
|
|
29
|
+
* checkbox's do. A press inside the shadow root has already landed on its
|
|
30
|
+
* control and is left alone.
|
|
17
31
|
*/
|
|
18
32
|
export declare class HostClickController implements ReactiveController {
|
|
19
33
|
private readonly host;
|
|
@@ -21,5 +35,11 @@ export declare class HostClickController implements ReactiveController {
|
|
|
21
35
|
constructor(host: ReactiveControllerHost & HTMLElement, target: () => HTMLElement | null | undefined);
|
|
22
36
|
hostConnected(): void;
|
|
23
37
|
hostDisconnected(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Clicks the control, for the host's own `click()`. Answers `false` when
|
|
40
|
+
* there is no control yet, before the first render, so the host can fall
|
|
41
|
+
* back to its own click.
|
|
42
|
+
*/
|
|
43
|
+
click(): boolean;
|
|
24
44
|
private readonly forward;
|
|
25
45
|
}
|
|
@@ -3,17 +3,44 @@ export class HostClickController {
|
|
|
3
3
|
this.host = host;
|
|
4
4
|
this.target = target;
|
|
5
5
|
this.forward = (event) => {
|
|
6
|
-
if (event.composedPath()[0] !== this.host) {
|
|
6
|
+
if (event.composedPath()[0] !== this.host || event.defaultPrevented) {
|
|
7
7
|
return;
|
|
8
8
|
}
|
|
9
|
-
this.target()
|
|
9
|
+
const control = this.target();
|
|
10
|
+
if (!control || control.matches(':disabled')) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
control.dispatchEvent(new MouseEvent('click', {
|
|
14
|
+
altKey: event.altKey,
|
|
15
|
+
bubbles: true,
|
|
16
|
+
button: event.button,
|
|
17
|
+
buttons: event.buttons,
|
|
18
|
+
cancelable: true,
|
|
19
|
+
clientX: event.clientX,
|
|
20
|
+
clientY: event.clientY,
|
|
21
|
+
composed: false,
|
|
22
|
+
ctrlKey: event.ctrlKey,
|
|
23
|
+
detail: event.detail,
|
|
24
|
+
metaKey: event.metaKey,
|
|
25
|
+
screenX: event.screenX,
|
|
26
|
+
screenY: event.screenY,
|
|
27
|
+
shiftKey: event.shiftKey,
|
|
28
|
+
}));
|
|
10
29
|
};
|
|
11
30
|
host.addController(this);
|
|
12
31
|
}
|
|
13
32
|
hostConnected() {
|
|
14
|
-
this.host.addEventListener('click', this.forward);
|
|
33
|
+
this.host.addEventListener('click', this.forward, { capture: true });
|
|
15
34
|
}
|
|
16
35
|
hostDisconnected() {
|
|
17
|
-
this.host.removeEventListener('click', this.forward);
|
|
36
|
+
this.host.removeEventListener('click', this.forward, { capture: true });
|
|
37
|
+
}
|
|
38
|
+
click() {
|
|
39
|
+
const control = this.target();
|
|
40
|
+
if (!control) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
control.click();
|
|
44
|
+
return true;
|
|
18
45
|
}
|
|
19
46
|
}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.
|
|
1
|
+
export const VERSION = '0.181.0';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion.dev/helix-core",
|
|
3
3
|
"description": "Helix element primitives: base classes, mixins, decorators, utilities.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.181.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -74,11 +74,11 @@
|
|
|
74
74
|
"bugs": "https://github.com/project-fusion/fusion/issues",
|
|
75
75
|
"dependencies": {
|
|
76
76
|
"@floating-ui/dom": "^1.8.0",
|
|
77
|
-
"@fusion.dev/helix-icons": "0.
|
|
77
|
+
"@fusion.dev/helix-icons": "0.181.0"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
|
-
"@fusion.dev/helix-cem": "0.
|
|
81
|
-
"@fusion.dev/helix-testing": "0.
|
|
80
|
+
"@fusion.dev/helix-cem": "0.181.0",
|
|
81
|
+
"@fusion.dev/helix-testing": "0.181.0",
|
|
82
82
|
"@lit-labs/ssr": "^4.1.0",
|
|
83
83
|
"lit": "^3.2.1"
|
|
84
84
|
},
|