@fusion.dev/helix-core 0.0.0-dev
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/LICENSE +21 -0
- package/custom-elements.json +8005 -0
- package/dist/controllers/aria-forward-controller/aria-forward-controller.d.ts +67 -0
- package/dist/controllers/aria-forward-controller/aria-forward-controller.js +146 -0
- package/dist/controllers/chart-pointer-controller/chart-pointer-controller.d.ts +79 -0
- package/dist/controllers/chart-pointer-controller/chart-pointer-controller.js +140 -0
- package/dist/controllers/command-controller/command-controller.d.ts +83 -0
- package/dist/controllers/command-controller/command-controller.js +93 -0
- package/dist/controllers/copy-controller/copy-controller.d.ts +58 -0
- package/dist/controllers/copy-controller/copy-controller.js +128 -0
- package/dist/controllers/disabled-cascade-controller/disabled-cascade-controller.d.ts +76 -0
- package/dist/controllers/disabled-cascade-controller/disabled-cascade-controller.js +67 -0
- package/dist/controllers/dismiss-controller/dismiss-controller.d.ts +58 -0
- package/dist/controllers/dismiss-controller/dismiss-controller.js +165 -0
- package/dist/controllers/drilldown-controller/drilldown-controller.d.ts +127 -0
- package/dist/controllers/drilldown-controller/drilldown-controller.js +171 -0
- package/dist/controllers/floating-controller/floating-controller.d.ts +123 -0
- package/dist/controllers/floating-controller/floating-controller.js +227 -0
- package/dist/controllers/focus-trap-controller/focus-trap-controller.d.ts +26 -0
- package/dist/controllers/focus-trap-controller/focus-trap-controller.js +93 -0
- package/dist/controllers/indicator-controller/indicator-controller.d.ts +97 -0
- package/dist/controllers/indicator-controller/indicator-controller.js +164 -0
- package/dist/controllers/keyboard-navigation-controller/keyboard-navigation-controller.d.ts +113 -0
- package/dist/controllers/keyboard-navigation-controller/keyboard-navigation-controller.js +117 -0
- package/dist/controllers/popover-controller/popover-controller.d.ts +132 -0
- package/dist/controllers/popover-controller/popover-controller.js +150 -0
- package/dist/controllers/source-controller/source-controller.d.ts +55 -0
- package/dist/controllers/source-controller/source-controller.js +94 -0
- package/dist/controllers/token-color-controller/token-color-controller.d.ts +63 -0
- package/dist/controllers/token-color-controller/token-color-controller.js +105 -0
- package/dist/controllers/virtualize-controller/virtualize-controller.d.ts +127 -0
- package/dist/controllers/virtualize-controller/virtualize-controller.js +216 -0
- package/dist/events/element-events.d.ts +4 -0
- package/dist/events/element-events.js +34 -0
- package/dist/events/events.d.ts +743 -0
- package/dist/events/events.js +799 -0
- package/dist/helix-element/helix-element.d.ts +201 -0
- package/dist/helix-element/helix-element.js +695 -0
- package/dist/helix-form-element/helix-form-element.d.ts +152 -0
- package/dist/helix-form-element/helix-form-element.js +194 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +54 -0
- package/dist/mixins/mixin-chart-source/mixin-chart-source.d.ts +137 -0
- package/dist/mixins/mixin-chart-source/mixin-chart-source.js +140 -0
- package/dist/mixins/mixin-collection/index.d.ts +1 -0
- package/dist/mixins/mixin-collection/index.js +1 -0
- package/dist/mixins/mixin-collection/mixin-collection.d.ts +58 -0
- package/dist/mixins/mixin-collection/mixin-collection.js +154 -0
- package/dist/mixins/mixin-controller-active/mixin-controller-active.d.ts +53 -0
- package/dist/mixins/mixin-controller-active/mixin-controller-active.js +155 -0
- package/dist/mixins/mixin-controller-checked/mixin-controller-checked.d.ts +54 -0
- package/dist/mixins/mixin-controller-checked/mixin-controller-checked.js +157 -0
- package/dist/mixins/mixin-controller-open/mixin-controller-open.d.ts +49 -0
- package/dist/mixins/mixin-controller-open/mixin-controller-open.js +176 -0
- package/dist/mixins/mixin-controller-value/mixin-controller-value.d.ts +73 -0
- package/dist/mixins/mixin-controller-value/mixin-controller-value.js +173 -0
- package/dist/mixins/mixin-dismissible/mixin-dismissible.d.ts +41 -0
- package/dist/mixins/mixin-dismissible/mixin-dismissible.js +79 -0
- package/dist/mixins/mixin-field/mixin-field.d.ts +145 -0
- package/dist/mixins/mixin-field/mixin-field.js +423 -0
- package/dist/utils/anchor-element/anchor-element.d.ts +23 -0
- package/dist/utils/anchor-element/anchor-element.js +39 -0
- package/dist/utils/capture-pointer/capture-pointer.d.ts +22 -0
- package/dist/utils/capture-pointer/capture-pointer.js +30 -0
- package/dist/utils/closest-instance/closest-instance.d.ts +25 -0
- package/dist/utils/closest-instance/closest-instance.js +34 -0
- package/dist/utils/create-sheet/create-sheet.d.ts +16 -0
- package/dist/utils/create-sheet/create-sheet.js +16 -0
- package/dist/utils/custom-element/custom-element.d.ts +26 -0
- package/dist/utils/custom-element/custom-element.js +114 -0
- package/dist/utils/draw-icon/draw-icon.d.ts +38 -0
- package/dist/utils/draw-icon/draw-icon.js +39 -0
- package/dist/utils/draw-tooltip/draw-tooltip.d.ts +56 -0
- package/dist/utils/draw-tooltip/draw-tooltip.js +89 -0
- package/dist/utils/elapsed-time/elapsed-time.d.ts +10 -0
- package/dist/utils/elapsed-time/elapsed-time.js +117 -0
- package/dist/utils/focusable-elements/focusable-elements.d.ts +40 -0
- package/dist/utils/focusable-elements/focusable-elements.js +88 -0
- package/dist/utils/format-numbers/format-numbers.d.ts +1 -0
- package/dist/utils/format-numbers/format-numbers.js +29 -0
- package/dist/utils/host-aria/host-aria.d.ts +38 -0
- package/dist/utils/host-aria/host-aria.js +41 -0
- package/dist/utils/inherit-disabled/inherit-disabled.d.ts +33 -0
- package/dist/utils/inherit-disabled/inherit-disabled.js +55 -0
- package/dist/utils/line-path/line-path.d.ts +23 -0
- package/dist/utils/line-path/line-path.js +107 -0
- package/dist/utils/on-unless-false/on-unless-false.d.ts +28 -0
- package/dist/utils/on-unless-false/on-unless-false.js +32 -0
- package/dist/utils/read-series/read-series.d.ts +78 -0
- package/dist/utils/read-series/read-series.js +187 -0
- package/dist/utils/relative-time/relative-time.d.ts +24 -0
- package/dist/utils/relative-time/relative-time.js +84 -0
- package/dist/utils/request-change/request-change.d.ts +48 -0
- package/dist/utils/request-change/request-change.js +7 -0
- package/dist/utils/resolve-active-item/resolve-active-item.d.ts +28 -0
- package/dist/utils/resolve-active-item/resolve-active-item.js +21 -0
- package/dist/utils/restore-value/restore-value.d.ts +32 -0
- package/dist/utils/restore-value/restore-value.js +84 -0
- package/dist/utils/scale/scale.d.ts +23 -0
- package/dist/utils/scale/scale.js +32 -0
- package/dist/utils/scale/ticks.d.ts +27 -0
- package/dist/utils/scale/ticks.js +52 -0
- package/dist/utils/scroll-item-into-view/scroll-item-into-view.d.ts +10 -0
- package/dist/utils/scroll-item-into-view/scroll-item-into-view.js +98 -0
- package/dist/utils/slot-filled/slot-filled.d.ts +26 -0
- package/dist/utils/slot-filled/slot-filled.js +26 -0
- package/dist/utils/tell-disclosure/tell-disclosure.d.ts +51 -0
- package/dist/utils/tell-disclosure/tell-disclosure.js +76 -0
- package/dist/utils/ticker/ticker.d.ts +8 -0
- package/dist/utils/ticker/ticker.js +55 -0
- package/dist/utils/tone-marks/tone-marks.d.ts +52 -0
- package/dist/utils/tone-marks/tone-marks.js +36 -0
- package/dist/utils/value-as/value-as.d.ts +64 -0
- package/dist/utils/value-as/value-as.js +105 -0
- package/package.json +58 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { property } from 'lit/decorators.js';
|
|
8
|
+
import { HelixBeforeToggleEvent } from '../../events/events.js';
|
|
9
|
+
import { requestChange } from '../../utils/request-change/request-change.js';
|
|
10
|
+
/**
|
|
11
|
+
* Grafts controlled and uncontrolled checked state onto a base class.
|
|
12
|
+
*
|
|
13
|
+
* Which mode it is in is read once, at the first update, from whether anything
|
|
14
|
+
* had set `checked` by then: markup, a hydrating server's attributes and a
|
|
15
|
+
* framework's initial properties have all arrived, and nothing else has
|
|
16
|
+
* happened yet. Set, and the consumer owns it and the element only announces.
|
|
17
|
+
* Unset, and the element owns it and `defaultChecked` says where it starts.
|
|
18
|
+
*
|
|
19
|
+
* Records `:state(checked)` whenever the element is checked, in either mode.
|
|
20
|
+
* Styled tiers select on that rather than on `[checked]`, which is absent for
|
|
21
|
+
* uncontrolled consumers.
|
|
22
|
+
*/
|
|
23
|
+
export const MixinControllerChecked = (Base) => {
|
|
24
|
+
// JSDoc is duplicated from MixinControllerCheckedInterface deliberately. The
|
|
25
|
+
// interface is what TypeScript consumers see; this class is what the manifest
|
|
26
|
+
// analyzer reads when resolving inherited members into dependent packages.
|
|
27
|
+
class CheckedElement extends Base {
|
|
28
|
+
constructor() {
|
|
29
|
+
super(...arguments);
|
|
30
|
+
/**
|
|
31
|
+
* Initial checked state for uncontrolled use, where nothing declared one.
|
|
32
|
+
*/
|
|
33
|
+
this.defaultChecked = false;
|
|
34
|
+
/**
|
|
35
|
+
* The state, whoever set it, and `undefined` until somebody has.
|
|
36
|
+
*
|
|
37
|
+
* One field and not two. Writing always applies, the way a native control
|
|
38
|
+
* does when a script assigns to it. What the write does not do is change
|
|
39
|
+
* which mode the element is in.
|
|
40
|
+
*/
|
|
41
|
+
this.checkedState = undefined;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Whether the control is checked.
|
|
45
|
+
*
|
|
46
|
+
* One property rather than two. Reading gives the real state whichever
|
|
47
|
+
* mode the control is in; writing hands ownership to the consumer, which
|
|
48
|
+
* is what the attribute in `<helix-checkbox checked>` does as well. The
|
|
49
|
+
* same shape all four of these mixins have, for the reason given on
|
|
50
|
+
* `MixinControllerOpen.open`.
|
|
51
|
+
*
|
|
52
|
+
* Not reflected: the attribute is the consumer's input and stays as they
|
|
53
|
+
* wrote it, and `:state(checked)` carries the resolved state for
|
|
54
|
+
* stylesheets.
|
|
55
|
+
*
|
|
56
|
+
*
|
|
57
|
+
*/
|
|
58
|
+
get checked() {
|
|
59
|
+
return this.checkedState ?? this.defaultChecked;
|
|
60
|
+
}
|
|
61
|
+
set checked(next) {
|
|
62
|
+
const previous = this.checked;
|
|
63
|
+
this.checkedState = next;
|
|
64
|
+
this.requestUpdate('checked', previous);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Records the resolved state as the custom state `checked`.
|
|
68
|
+
*
|
|
69
|
+
* **A state and not `data-checked`, which is what this wrote until 27 Aug
|
|
70
|
+
* 2026.** The attribute went on in `willUpdate`, so `<helix-checkbox
|
|
71
|
+
* default-checked>` came back from a consumer's server without it and
|
|
72
|
+
* gained it the moment the definition landed, which React lists as a
|
|
73
|
+
* hydration mismatch and does not patch up. `HelixElement.toggleState` says
|
|
74
|
+
* why the host is the wrong place to keep a component's own bookkeeping.
|
|
75
|
+
*
|
|
76
|
+
* Still in `willUpdate`, which is where the resolved state is first known
|
|
77
|
+
* and is what a subclass rendering from it expects. The old note here said
|
|
78
|
+
* SSR calls `willUpdate` and not `connectedCallback`, so the attribute
|
|
79
|
+
* reached server output: true, and no longer a reason for anything, a
|
|
80
|
+
* custom state being a fact about a running element that a server has
|
|
81
|
+
* nothing to say about.
|
|
82
|
+
*/
|
|
83
|
+
willUpdate(changed) {
|
|
84
|
+
super.willUpdate(changed);
|
|
85
|
+
this.toggleState('checked', this.checked);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Requests a checked change, and reports whether it was applied.
|
|
89
|
+
*
|
|
90
|
+
* Announces before it acts, so `preventDefault()` on the
|
|
91
|
+
* `helix-before-toggle` is a refusal and nothing moves. Nobody refusing means the element updates itself, whether or not a consumer
|
|
92
|
+
* declared the property: a declared property is a seed and a correction,
|
|
93
|
+
* the way `<input value>` is, and a consumer who wants the change for
|
|
94
|
+
* themselves refuses it and assigns their own. See 294.
|
|
95
|
+
*/
|
|
96
|
+
requestChecked(next) {
|
|
97
|
+
if (this.checked === next) {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
const applied = requestChange({
|
|
101
|
+
apply: (checked) => {
|
|
102
|
+
const previous = this.checked;
|
|
103
|
+
this.checkedState = checked;
|
|
104
|
+
this.requestUpdate('checked', previous);
|
|
105
|
+
},
|
|
106
|
+
event: (checked) => new HelixBeforeToggleEvent({ checked }),
|
|
107
|
+
host: this,
|
|
108
|
+
next,
|
|
109
|
+
});
|
|
110
|
+
if (applied) {
|
|
111
|
+
/* `input` here and `change` relayed from the inner control, which is
|
|
112
|
+
the pair a native checkbox sends. Announced after `apply`, so a
|
|
113
|
+
handler reading `currentTarget.checked` reads the new state. */
|
|
114
|
+
this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
|
|
115
|
+
}
|
|
116
|
+
return applied;
|
|
117
|
+
}
|
|
118
|
+
/** Requests the opposite of the current state. */
|
|
119
|
+
toggleChecked() {
|
|
120
|
+
return this.requestChecked(!this.checked);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Restores the control when the browser brings a form back.
|
|
124
|
+
*
|
|
125
|
+
* Hand-written on the checkbox and nowhere else, so `Switch`, the mixin's
|
|
126
|
+
* only other consumer, had no restore at all: a reader who navigated away
|
|
127
|
+
* and came back to a restored form found their switch flipped off. The
|
|
128
|
+
* mixin owns `checked`, so the mixin owns putting it back.
|
|
129
|
+
*
|
|
130
|
+
* Through `checked` rather than the private state, so a controlled consumer
|
|
131
|
+
* is asked the same way every other change asks.
|
|
132
|
+
*/
|
|
133
|
+
formStateRestoreCallback(state) {
|
|
134
|
+
this.checked = state !== null;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Drops the uncontrolled state, so the control reads `defaultChecked`
|
|
138
|
+
* again.
|
|
139
|
+
*
|
|
140
|
+
* A form reset has to return a control to what its markup declared, and
|
|
141
|
+
* clearing `checked` alone only leaves controlled mode. The value the
|
|
142
|
+
* element has been keeping lives here, so this is where it is dropped.
|
|
143
|
+
*/
|
|
144
|
+
resetChecked() {
|
|
145
|
+
const previous = this.checked;
|
|
146
|
+
this.checkedState = undefined;
|
|
147
|
+
this.requestUpdate('checked', previous);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
__decorate([
|
|
151
|
+
property({ type: Boolean })
|
|
152
|
+
], CheckedElement.prototype, "checked", null);
|
|
153
|
+
__decorate([
|
|
154
|
+
property({ attribute: 'default-checked', type: Boolean })
|
|
155
|
+
], CheckedElement.prototype, "defaultChecked", void 0);
|
|
156
|
+
return CheckedElement;
|
|
157
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { HelixElement } from '../../helix-element/helix-element.js';
|
|
2
|
+
type Constructor<T> = new (...args: any[]) => T;
|
|
3
|
+
/**
|
|
4
|
+
* The public surface `MixinControllerOpen` adds.
|
|
5
|
+
*
|
|
6
|
+
* Declared separately because TypeScript cannot emit declarations for an
|
|
7
|
+
* anonymous class that has private members (TS4094). Casting the mixin's return
|
|
8
|
+
* to this interface keeps the internals private and the build working.
|
|
9
|
+
*/
|
|
10
|
+
export declare class MixinControllerOpenInterface {
|
|
11
|
+
/** Initial open state for uncontrolled use. Ignored once `open` is set. */
|
|
12
|
+
defaultOpen: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Whether the element is open.
|
|
15
|
+
*
|
|
16
|
+
* Reading gives the real state, in either mode. Writing hands ownership to
|
|
17
|
+
* the consumer: from then on the element announces changes and applies none
|
|
18
|
+
* of them, and waits to be told.
|
|
19
|
+
*/
|
|
20
|
+
open: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Requests an open-state change, and reports whether it was applied.
|
|
23
|
+
*
|
|
24
|
+
* Announces before it acts: a listener calling `preventDefault()` on the
|
|
25
|
+
* `helix-before-open` or `helix-before-close` refuses the change, and nothing moves.
|
|
26
|
+
*/
|
|
27
|
+
requestOpen(next: boolean): boolean;
|
|
28
|
+
/** Requests the opposite of the current state. */
|
|
29
|
+
toggleOpen(): boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Grafts open state onto a base class, and says so twice.
|
|
33
|
+
*
|
|
34
|
+
* `helix-before-open` and `helix-before-close` announce the change while it is
|
|
35
|
+
* still a request, so `preventDefault()` refuses it and nothing moves. Native
|
|
36
|
+
* `toggle` announces it afterwards, once the state has actually gone, carrying
|
|
37
|
+
* `newState` and `oldState` the way the platform does on `<details>` and on a
|
|
38
|
+
* popover. The first is how a consumer takes the decision; the second is what
|
|
39
|
+
* they bind when they only want to know. See 294 and 296.
|
|
40
|
+
*
|
|
41
|
+
* `open` is a seed and a correction rather than a claim: the element applies
|
|
42
|
+
* its own changes from wherever markup started it, and `defaultOpen` is what a
|
|
43
|
+
* reset returns to.
|
|
44
|
+
*
|
|
45
|
+
* Records `:state(open)` whenever the element is open. Styled tiers select on
|
|
46
|
+
* that rather than on `[open]`, which is absent until somebody writes it.
|
|
47
|
+
*/
|
|
48
|
+
export declare const MixinControllerOpen: <T extends Constructor<HelixElement>>(Base: T) => Constructor<MixinControllerOpenInterface> & T;
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { property } from 'lit/decorators.js';
|
|
8
|
+
import { HelixBeforeCloseEvent, HelixBeforeOpenEvent } from '../../events/events.js';
|
|
9
|
+
import { requestChange } from '../../utils/request-change/request-change.js';
|
|
10
|
+
/**
|
|
11
|
+
* Grafts open state onto a base class, and says so twice.
|
|
12
|
+
*
|
|
13
|
+
* `helix-before-open` and `helix-before-close` announce the change while it is
|
|
14
|
+
* still a request, so `preventDefault()` refuses it and nothing moves. Native
|
|
15
|
+
* `toggle` announces it afterwards, once the state has actually gone, carrying
|
|
16
|
+
* `newState` and `oldState` the way the platform does on `<details>` and on a
|
|
17
|
+
* popover. The first is how a consumer takes the decision; the second is what
|
|
18
|
+
* they bind when they only want to know. See 294 and 296.
|
|
19
|
+
*
|
|
20
|
+
* `open` is a seed and a correction rather than a claim: the element applies
|
|
21
|
+
* its own changes from wherever markup started it, and `defaultOpen` is what a
|
|
22
|
+
* reset returns to.
|
|
23
|
+
*
|
|
24
|
+
* Records `:state(open)` whenever the element is open. Styled tiers select on
|
|
25
|
+
* that rather than on `[open]`, which is absent until somebody writes it.
|
|
26
|
+
*/
|
|
27
|
+
export const MixinControllerOpen = (Base) => {
|
|
28
|
+
// JSDoc is duplicated from MixinControllerOpenInterface deliberately. The interface is
|
|
29
|
+
// what TypeScript consumers see; this class is what the manifest analyzer
|
|
30
|
+
// reads when resolving inherited members into dependent packages.
|
|
31
|
+
class OpenElement extends Base {
|
|
32
|
+
constructor() {
|
|
33
|
+
super(...arguments);
|
|
34
|
+
/**
|
|
35
|
+
* Initial open state for uncontrolled use, where nothing declared one.
|
|
36
|
+
*/
|
|
37
|
+
this.defaultOpen = false;
|
|
38
|
+
/**
|
|
39
|
+
* The state, whoever set it, and `undefined` until somebody has.
|
|
40
|
+
*
|
|
41
|
+
* Prefixed, and it has to be. These mixins compose onto one prototype
|
|
42
|
+
* chain, `Select` takes this one and `MixinControllerValue` together, and
|
|
43
|
+
* TypeScript's `private` is a compile-time fiction: two mixins with a field
|
|
44
|
+
* called `state` share one property on the instance, and the second one
|
|
45
|
+
* silently overwrites the first. Measured, as a select whose `value` came
|
|
46
|
+
* back holding its `open` boolean.
|
|
47
|
+
*
|
|
48
|
+
* One field and not two. Writing always applies, which is what a native
|
|
49
|
+
* control does when a script assigns to it, and is the behavior an
|
|
50
|
+
* imperative `element.open = true` should have whatever mode the element is
|
|
51
|
+
* in. What the write does *not* do is change which mode that is.
|
|
52
|
+
*/
|
|
53
|
+
this.openState = undefined;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Whether the element is open.
|
|
57
|
+
*
|
|
58
|
+
* One property, not two. Reading gives the real state whichever mode the
|
|
59
|
+
* element is in, so `dialog.open` answers the question anyone asking it
|
|
60
|
+
* meant. Writing hands ownership to the consumer, which is what the
|
|
61
|
+
* attribute in `<helix-dialog open>` does as well: from then on the element
|
|
62
|
+
* announces changes and applies none of them.
|
|
63
|
+
*
|
|
64
|
+
* It reads as an accessor pair rather than a field because those are two
|
|
65
|
+
* different questions sharing one name, and the alternative was a second
|
|
66
|
+
* property answering the first. That worked for a boolean, where `isOpen`
|
|
67
|
+
* reads well; there is no such word for a value or an active item, so all
|
|
68
|
+
* four of these mixins now have this shape instead of two shapes.
|
|
69
|
+
*
|
|
70
|
+
* **Not reflected, and that is required rather than tidy.** Reflection
|
|
71
|
+
* writes the resolved state back as an attribute, and writing the attribute
|
|
72
|
+
* is how a consumer says they own it. So an uncontrolled element that
|
|
73
|
+
* opened itself would put `open` on its own host and, from the next thing
|
|
74
|
+
* that read it, be indistinguishable from one the consumer controls:
|
|
75
|
+
* cloned, serialised for hydration, or diffed by a framework, it would come
|
|
76
|
+
* back holding whatever the last reader did rather than what the author
|
|
77
|
+
* wrote. `:state(open)` carries the resolved state for stylesheets, which
|
|
78
|
+
* is what the mirror has always been for.
|
|
79
|
+
*/
|
|
80
|
+
get open() {
|
|
81
|
+
return this.openState ?? this.defaultOpen;
|
|
82
|
+
}
|
|
83
|
+
set open(next) {
|
|
84
|
+
const previous = this.open;
|
|
85
|
+
this.openState = next;
|
|
86
|
+
this.requestUpdate('open', previous);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Records the resolved state as the custom state `open`.
|
|
90
|
+
*
|
|
91
|
+
* **A state and not `data-open`, which is what this wrote until 27 Aug
|
|
92
|
+
* 2026.** An `<helix-accordion-item default-open>` was served without the
|
|
93
|
+
* attribute and gained it on upgrade, which is a hydration mismatch a React
|
|
94
|
+
* consumer reports. See `HelixElement.toggleState`, and see `Toast.Item`
|
|
95
|
+
* for the other answer to the same fault: inverting the hook so the write
|
|
96
|
+
* falls on the side that only happens after somebody acts. Inversion works
|
|
97
|
+
* where the resting state is the loud one and cannot help here, `checked`
|
|
98
|
+
* and `open` being true only because a consumer asked for them.
|
|
99
|
+
*/
|
|
100
|
+
willUpdate(changed) {
|
|
101
|
+
super.willUpdate(changed);
|
|
102
|
+
this.toggleState('open', this.open);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Requests an open-state change, and reports whether it was applied.
|
|
106
|
+
*
|
|
107
|
+
* Announces before it acts, so `preventDefault()` on the `helix-before-open` or
|
|
108
|
+
* `helix-before-close` is a refusal and nothing moves. Nobody refusing means the
|
|
109
|
+
* element opens or closes itself, whether or not a consumer declared
|
|
110
|
+
* `open`: a declared property is a seed and a correction, and a consumer
|
|
111
|
+
* who wants the decision for themselves refuses it and assigns their own.
|
|
112
|
+
* See 294.
|
|
113
|
+
*/
|
|
114
|
+
requestOpen(next) {
|
|
115
|
+
if (this.open === next) {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
const applied = requestChange({
|
|
119
|
+
apply: (open) => {
|
|
120
|
+
const previous = this.open;
|
|
121
|
+
this.openState = open;
|
|
122
|
+
this.requestUpdate('open', previous);
|
|
123
|
+
},
|
|
124
|
+
event: (open) => (open ? new HelixBeforeOpenEvent() : new HelixBeforeCloseEvent()),
|
|
125
|
+
host: this,
|
|
126
|
+
next,
|
|
127
|
+
});
|
|
128
|
+
if (applied) {
|
|
129
|
+
this.announceToggle(next);
|
|
130
|
+
}
|
|
131
|
+
return applied;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Says the state moved, under the platform's own name and in its shape.
|
|
135
|
+
*
|
|
136
|
+
* **`<details>` fires `toggle` and a popover fires `toggle`, and sixteen
|
|
137
|
+
* families here fired neither.** Two of them render a real `<dialog>` and
|
|
138
|
+
* ten show a `popover="manual"` panel, so the browser was already firing
|
|
139
|
+
* something on an element inside a shadow root, where `toggle` neither
|
|
140
|
+
* bubbles nor composes and so reaches nobody. The rest, the disclosures,
|
|
141
|
+
* have no native element to fire anything at all: `AccordionItem` and
|
|
142
|
+
* `TreeItem` are `aria-expanded` and `hidden` written by hand, which is
|
|
143
|
+
* `<details>`'s job done manually.
|
|
144
|
+
*
|
|
145
|
+
* **From here rather than from `PopoverController`, which had it first.**
|
|
146
|
+
* The controller covers eleven families and the mixin covers sixteen, and
|
|
147
|
+
* the overlap is ten that would have announced twice. What `toggle` reports
|
|
148
|
+
* is the *state*, and the state is this mixin's; the controller is a way of
|
|
149
|
+
* putting a panel on the screen.
|
|
150
|
+
*
|
|
151
|
+
* **`newState` and `oldState`, because that is the platform's shape**, so a
|
|
152
|
+
* consumer arriving from `<details>` reads the same two words. Not
|
|
153
|
+
* cancelable: the before events are the request, and a second cancelable
|
|
154
|
+
* event for one transition is two answers to one question.
|
|
155
|
+
*/
|
|
156
|
+
announceToggle(open) {
|
|
157
|
+
const event = new Event('toggle', { bubbles: false, cancelable: false, composed: false });
|
|
158
|
+
Object.assign(event, {
|
|
159
|
+
newState: open ? 'open' : 'closed',
|
|
160
|
+
oldState: open ? 'closed' : 'open',
|
|
161
|
+
});
|
|
162
|
+
this.dispatchEvent(event);
|
|
163
|
+
}
|
|
164
|
+
/** Requests the opposite of the current state. */
|
|
165
|
+
toggleOpen() {
|
|
166
|
+
return this.requestOpen(!this.open);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
__decorate([
|
|
170
|
+
property({ type: Boolean })
|
|
171
|
+
], OpenElement.prototype, "open", null);
|
|
172
|
+
__decorate([
|
|
173
|
+
property({ attribute: 'default-open', type: Boolean })
|
|
174
|
+
], OpenElement.prototype, "defaultOpen", void 0);
|
|
175
|
+
return OpenElement;
|
|
176
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { HelixFormElement } from '../../helix-form-element/helix-form-element.js';
|
|
2
|
+
type Constructor<T> = new (...args: any[]) => T;
|
|
3
|
+
/**
|
|
4
|
+
* The public surface `MixinControllerValue` adds.
|
|
5
|
+
*
|
|
6
|
+
* Declared separately because TypeScript cannot emit declarations for an
|
|
7
|
+
* anonymous class that has private members (TS4094).
|
|
8
|
+
*/
|
|
9
|
+
export declare class MixinControllerValueInterface {
|
|
10
|
+
/**
|
|
11
|
+
* The value the markup declared, which is where a reset returns to.
|
|
12
|
+
*
|
|
13
|
+
* Separate from `value`, which is where the control is now, and gone from the
|
|
14
|
+
* reader's view the moment they change anything.
|
|
15
|
+
*/
|
|
16
|
+
defaultValue: string;
|
|
17
|
+
/**
|
|
18
|
+
* What the control holds now, and what its form submits.
|
|
19
|
+
*
|
|
20
|
+
* Reading gives the real value, in either mode. Writing hands ownership to
|
|
21
|
+
* the consumer: from then on the control announces changes and applies none
|
|
22
|
+
* of them, and waits to be told.
|
|
23
|
+
*/
|
|
24
|
+
value: string;
|
|
25
|
+
/**
|
|
26
|
+
* Whether every edit is announced, rather than every settled value.
|
|
27
|
+
*
|
|
28
|
+
* A control the reader types or drags in moves continuously, and the platform
|
|
29
|
+
* calls that `input`: `<input type="text">` fires one per keystroke and fires
|
|
30
|
+
* `change` once, on commit. Five controls here are that shape, and the rest
|
|
31
|
+
* change in discrete steps where a step *is* the change.
|
|
32
|
+
*
|
|
33
|
+
* It selects the event rather than the timing. `requestValue` is called
|
|
34
|
+
* whenever the value moves either way; this decides whether the control sends
|
|
35
|
+
* `input` alone or `input` and `change` together, so a consumer can read the
|
|
36
|
+
* name and know how often to expect it.
|
|
37
|
+
*/
|
|
38
|
+
protected readonly announcesInput: boolean;
|
|
39
|
+
/** Requests a new value, and reports whether the request stood. */
|
|
40
|
+
requestValue(next: string): boolean;
|
|
41
|
+
/** Returns the control to the value its markup declared. */
|
|
42
|
+
formResetCallback(): void;
|
|
43
|
+
/** Restores the value when the browser brings a form back. */
|
|
44
|
+
formStateRestoreCallback(state: string | null): void;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Grafts `value`, `defaultValue`, and the two callbacks that answer a form.
|
|
48
|
+
*
|
|
49
|
+
* Every control with a value had written this, and by the third it was three
|
|
50
|
+
* copies of the same four members and the same seeding rule: `Input`, then
|
|
51
|
+
* `Toggle.Group`, then `Radio.Group`. The copies had not diverged, which is the
|
|
52
|
+
* argument for the mixin rather than against it, because the next one would
|
|
53
|
+
* have.
|
|
54
|
+
*
|
|
55
|
+
* **Seeded in `willUpdate`, not `connectedCallback`.** SSR never calls the
|
|
56
|
+
* latter, so a control with a `default-value` would serve empty and fill itself
|
|
57
|
+
* at hydration, which is a flash for a reader and a mismatch for React. Seeding
|
|
58
|
+
* once, before the first render, is what makes the server and the client agree.
|
|
59
|
+
*
|
|
60
|
+
* **What it does not own is reporting.** `setFormValue` stays with the
|
|
61
|
+
* component, because what an empty value means is the component's business: a
|
|
62
|
+
* text field submits its emptiness, since `""` is an answer and the field was
|
|
63
|
+
* on the form, while a group with nothing chosen submits nothing at all. One
|
|
64
|
+
* mixin cannot hold both without a flag, and a flag would be this rule written
|
|
65
|
+
* down twice.
|
|
66
|
+
*
|
|
67
|
+
* `Checkbox` deliberately does not take this. Its `value` is what it submits
|
|
68
|
+
* *when it is on* rather than what it holds, so it is configuration rather than
|
|
69
|
+
* state, and the state it does have is `checked`, which is
|
|
70
|
+
* `MixinControllerChecked`'s.
|
|
71
|
+
*/
|
|
72
|
+
export declare const MixinControllerValue: <T extends Constructor<HelixFormElement>>(Base: T) => Constructor<MixinControllerValueInterface> & T;
|
|
73
|
+
export {};
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { property } from 'lit/decorators.js';
|
|
8
|
+
import { HelixBeforeChangeEvent } from '../../events/events.js';
|
|
9
|
+
import { requestChange } from '../../utils/request-change/request-change.js';
|
|
10
|
+
/**
|
|
11
|
+
* Grafts `value`, `defaultValue`, and the two callbacks that answer a form.
|
|
12
|
+
*
|
|
13
|
+
* Every control with a value had written this, and by the third it was three
|
|
14
|
+
* copies of the same four members and the same seeding rule: `Input`, then
|
|
15
|
+
* `Toggle.Group`, then `Radio.Group`. The copies had not diverged, which is the
|
|
16
|
+
* argument for the mixin rather than against it, because the next one would
|
|
17
|
+
* have.
|
|
18
|
+
*
|
|
19
|
+
* **Seeded in `willUpdate`, not `connectedCallback`.** SSR never calls the
|
|
20
|
+
* latter, so a control with a `default-value` would serve empty and fill itself
|
|
21
|
+
* at hydration, which is a flash for a reader and a mismatch for React. Seeding
|
|
22
|
+
* once, before the first render, is what makes the server and the client agree.
|
|
23
|
+
*
|
|
24
|
+
* **What it does not own is reporting.** `setFormValue` stays with the
|
|
25
|
+
* component, because what an empty value means is the component's business: a
|
|
26
|
+
* text field submits its emptiness, since `""` is an answer and the field was
|
|
27
|
+
* on the form, while a group with nothing chosen submits nothing at all. One
|
|
28
|
+
* mixin cannot hold both without a flag, and a flag would be this rule written
|
|
29
|
+
* down twice.
|
|
30
|
+
*
|
|
31
|
+
* `Checkbox` deliberately does not take this. Its `value` is what it submits
|
|
32
|
+
* *when it is on* rather than what it holds, so it is configuration rather than
|
|
33
|
+
* state, and the state it does have is `checked`, which is
|
|
34
|
+
* `MixinControllerChecked`'s.
|
|
35
|
+
*/
|
|
36
|
+
export const MixinControllerValue = (Base) => {
|
|
37
|
+
// JSDoc is duplicated from the interface deliberately. The interface is what
|
|
38
|
+
// TypeScript consumers see; this class is what the manifest analyzer reads
|
|
39
|
+
// when resolving inherited members into dependent packages.
|
|
40
|
+
class ValueElement extends Base {
|
|
41
|
+
constructor() {
|
|
42
|
+
super(...arguments);
|
|
43
|
+
/**
|
|
44
|
+
* The value the markup declared, which is where a reset returns to.
|
|
45
|
+
*/
|
|
46
|
+
this.defaultValue = '';
|
|
47
|
+
/**
|
|
48
|
+
* The state, whoever set it, and `undefined` until somebody has.
|
|
49
|
+
*
|
|
50
|
+
* One field and not two. Writing always applies, the way a native control
|
|
51
|
+
* does when a script assigns to it.
|
|
52
|
+
*/
|
|
53
|
+
this.valueState = undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Whether a reader edits this continuously, which decides the native name.
|
|
56
|
+
*
|
|
57
|
+
* **It used to pick between `helix-input` and `helix-change`**, which was
|
|
58
|
+
* one mechanism under two names and said *phase* where it meant
|
|
59
|
+
* *granularity*. The request event is `helix-before-change` whatever the
|
|
60
|
+
* answer; this decides which native event announces the result, `input`
|
|
61
|
+
* while a reader is editing against `change` when they are done, which is
|
|
62
|
+
* the distinction the platform already draws. See 294.
|
|
63
|
+
*
|
|
64
|
+
* Discrete by default: only a control the reader edits continuously says
|
|
65
|
+
* otherwise.
|
|
66
|
+
*/
|
|
67
|
+
this.announcesInput = false;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* What the control holds now, and what its form submits.
|
|
71
|
+
*
|
|
72
|
+
* One property, not two. Reading gives the real value whichever mode the
|
|
73
|
+
* control is in, so `input.value` answers the question anyone asking it
|
|
74
|
+
* meant. Writing hands ownership to the consumer, which is what
|
|
75
|
+
* `<helix-input value="x">` says too, and matches what a controlled input
|
|
76
|
+
* means in React: the value is theirs and the control waits to be told.
|
|
77
|
+
* `default-value` is how markup seeds one it does not want to own.
|
|
78
|
+
*
|
|
79
|
+
* The same shape as the other three mixins, which is the point of them
|
|
80
|
+
* being four of a kind rather than four of three kinds.
|
|
81
|
+
*
|
|
82
|
+
* helix-input
|
|
83
|
+
*/
|
|
84
|
+
get value() {
|
|
85
|
+
return this.valueState ?? this.defaultValue;
|
|
86
|
+
}
|
|
87
|
+
set value(next) {
|
|
88
|
+
const previous = this.value;
|
|
89
|
+
this.valueState = next;
|
|
90
|
+
this.requestUpdate('value', previous);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Announces the applied value under the platform's own name.
|
|
94
|
+
*
|
|
95
|
+
* **After `apply`, never before**, which is the whole reason this is
|
|
96
|
+
* separate from the request event: a native handler reads
|
|
97
|
+
* `event.target.value`, and it has to be the value that was just applied.
|
|
98
|
+
*
|
|
99
|
+
* **Both, for a discrete control, because that is what the platform does.**
|
|
100
|
+
* A native `<select>` sends `input` and then `change` from one choice: the
|
|
101
|
+
* value moved, and the reader is also done. A continuous control announces
|
|
102
|
+
* `input` here and relays `change` from its inner control when the reader
|
|
103
|
+
* is done, so the pair keeps the platform's timings rather than reporting a
|
|
104
|
+
* commit on every keystroke.
|
|
105
|
+
*/
|
|
106
|
+
announceNatively() {
|
|
107
|
+
this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
|
|
108
|
+
if (!this.announcesInput) {
|
|
109
|
+
this.dispatchEvent(new Event('change', { bubbles: true, composed: false }));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Requests a new value, and reports whether the request stood.
|
|
114
|
+
*
|
|
115
|
+
* Announces before it acts, so `preventDefault()` on the `helix-before-change` is
|
|
116
|
+
* a refusal and nothing moves. Nobody refusing means the control updates
|
|
117
|
+
* itself, whether or not a consumer declared `value`: a declared property
|
|
118
|
+
* is a seed and a correction, the way `<input value>` is, and a consumer
|
|
119
|
+
* who wants the change for themselves refuses it and assigns their own.
|
|
120
|
+
* See 294.
|
|
121
|
+
*/
|
|
122
|
+
requestValue(next) {
|
|
123
|
+
if (this.value === next) {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
const applied = requestChange({
|
|
127
|
+
apply: (value) => {
|
|
128
|
+
const previous = this.value;
|
|
129
|
+
this.valueState = value;
|
|
130
|
+
this.requestUpdate('value', previous);
|
|
131
|
+
},
|
|
132
|
+
event: (value) => new HelixBeforeChangeEvent({ value }),
|
|
133
|
+
host: this,
|
|
134
|
+
next,
|
|
135
|
+
});
|
|
136
|
+
if (applied) {
|
|
137
|
+
this.announceNatively();
|
|
138
|
+
}
|
|
139
|
+
return applied;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Returns the control to the value its markup declared.
|
|
143
|
+
*
|
|
144
|
+
* Both halves are dropped, the consumer's and the control's, because a
|
|
145
|
+
* reset means the form is as it was served. Clearing only the internal one
|
|
146
|
+
* would leave a control that had been written to stuck at that value.
|
|
147
|
+
*/
|
|
148
|
+
formResetCallback() {
|
|
149
|
+
const previous = this.value;
|
|
150
|
+
this.valueState = undefined;
|
|
151
|
+
this.requestUpdate('value', previous);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Restores the value when the browser brings a form back.
|
|
155
|
+
*
|
|
156
|
+
* Falling back to `defaultValue` rather than to empty, because a restore
|
|
157
|
+
* with no state is a form the browser has nothing recorded for, which is
|
|
158
|
+
* the same situation as a fresh one.
|
|
159
|
+
*/
|
|
160
|
+
formStateRestoreCallback(state) {
|
|
161
|
+
const previous = this.value;
|
|
162
|
+
this.valueState = state ?? undefined;
|
|
163
|
+
this.requestUpdate('value', previous);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
__decorate([
|
|
167
|
+
property({ attribute: 'default-value' })
|
|
168
|
+
], ValueElement.prototype, "defaultValue", void 0);
|
|
169
|
+
__decorate([
|
|
170
|
+
property()
|
|
171
|
+
], ValueElement.prototype, "value", null);
|
|
172
|
+
return ValueElement;
|
|
173
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { LitElement } from 'lit';
|
|
2
|
+
import { HelixDismissEvent } from '../../events/events.js';
|
|
3
|
+
type Constructor<T> = new (...args: any[]) => T;
|
|
4
|
+
/**
|
|
5
|
+
* The API a dismissible surface has, as TypeScript sees it.
|
|
6
|
+
*/
|
|
7
|
+
export declare class DismissibleElement {
|
|
8
|
+
/** Whether it offers a control to take it away. */
|
|
9
|
+
dismissible: boolean;
|
|
10
|
+
/** Accessible name for that control. */
|
|
11
|
+
dismissLabel: string;
|
|
12
|
+
/** Announces that it should go, and reports whether the request stood. */
|
|
13
|
+
dismiss(): boolean;
|
|
14
|
+
/** The event, built but not dispatched, for a caller that owns the timing. */
|
|
15
|
+
protected dismissEvent(): HelixDismissEvent;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Grafts `dismissible`, its label, and the event that says so.
|
|
19
|
+
*
|
|
20
|
+
* Three surfaces had written this: `Announcement`, `Tag` and `Toast.Item`, each
|
|
21
|
+
* with the same two properties, the same event, and the same expression for the
|
|
22
|
+
* label. They had not diverged, which is the argument for extracting rather than
|
|
23
|
+
* against it, because the fourth would have.
|
|
24
|
+
*
|
|
25
|
+
* **The label reads the default slot, not the whole element**, and that is a bug
|
|
26
|
+
* fix rather than a move. Every copy said `this.textContent`, which is every
|
|
27
|
+
* light-DOM descendant including the ones assigned elsewhere. On `Announcement`
|
|
28
|
+
* and `Tag` that is the same thing, because they have one slot. On `Toast.Item`
|
|
29
|
+
* it swept in the actions: a message reading "Could not reach the server" with a
|
|
30
|
+
* `Retry` button announced itself as "Could not reach the server Retry", and the
|
|
31
|
+
* consumer removing it from their list got that string to match on.
|
|
32
|
+
*
|
|
33
|
+
* **`dismissEvent()` is separate from `dismiss()` for the one that needs it.**
|
|
34
|
+
* `Announcement` and `Tag` dispatch and are done: they own no state, so a
|
|
35
|
+
* refusal is the whole of the consumer's answer. `Toast.Item` holds an `open`
|
|
36
|
+
* it may or may not own, so its event has to go through the controlled-change
|
|
37
|
+
* path with an `apply` beside it. Giving it the event rather than the method
|
|
38
|
+
* lets it keep the contract and skip the default.
|
|
39
|
+
*/
|
|
40
|
+
export declare const MixinDismissible: <T extends Constructor<LitElement>>(Base: T) => Constructor<DismissibleElement> & T;
|
|
41
|
+
export {};
|