@vollowx/seele 0.13.5 → 0.13.7
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 +1256 -115
- package/package.json +22 -14
- package/src/all.d.ts +34 -0
- package/src/base/autocomplete.d.ts +57 -0
- package/src/base/autocomplete.js +80 -98
- package/src/base/button.d.ts +13 -0
- package/src/base/button.js +21 -19
- package/src/base/checkbox.d.ts +18 -0
- package/src/base/checkbox.js +39 -34
- package/src/base/controllers/list-controller.d.ts +37 -0
- package/src/base/controllers/list-controller.js +23 -15
- package/src/base/controllers/popover-controller.d.ts +35 -0
- package/src/base/controllers/popover-controller.js +37 -29
- package/src/base/dialog.d.ts +20 -0
- package/src/base/dialog.js +11 -9
- package/src/base/field.d.ts +3 -0
- package/src/base/input.d.ts +44 -0
- package/src/base/input.js +57 -65
- package/src/base/item.d.ts +7 -0
- package/src/base/item.js +2 -1
- package/src/base/list-item.d.ts +15 -0
- package/src/base/list-item.js +22 -22
- package/src/base/list.d.ts +54 -0
- package/src/base/list.js +69 -55
- package/src/base/menu-item.d.ts +6 -0
- package/src/base/menu-item.js +4 -3
- package/src/base/menu.d.ts +78 -0
- package/src/base/menu.js +137 -143
- package/src/base/mixins/attachable.d.ts +9 -0
- package/src/base/mixins/attachable.js +22 -18
- package/src/base/mixins/focus-delegated.d.ts +5 -0
- package/src/base/mixins/focus-delegated.js +6 -8
- package/src/base/mixins/form-associated.d.ts +15 -0
- package/src/base/mixins/form-associated.js +11 -18
- package/src/base/mixins/internals-attached.d.ts +6 -0
- package/src/base/mixins/internals-attached.js +1 -1
- package/src/base/option.d.ts +9 -0
- package/src/base/option.js +7 -8
- package/src/base/radio.d.ts +13 -0
- package/src/base/radio.js +49 -42
- package/src/base/select.d.ts +116 -0
- package/src/base/select.js +130 -128
- package/src/base/slider.d.ts +75 -0
- package/src/base/slider.js +115 -118
- package/src/base/tab-panel.d.ts +9 -0
- package/src/base/tab-panel.js +11 -11
- package/src/base/tab.d.ts +18 -0
- package/src/base/tab.js +25 -24
- package/src/base/tabs.d.ts +19 -0
- package/src/base/tabs.js +84 -81
- package/src/base/toggle-button.d.ts +47 -0
- package/src/base/toggle-button.js +56 -52
- package/src/base/tooltip.d.ts +37 -0
- package/src/base/tooltip.js +70 -65
- package/src/core/decorators.d.ts +2 -0
- package/src/core/decorators.js +4 -3
- package/src/core/ensure-ready.d.ts +1 -0
- package/src/core/ensure-ready.js +15 -0
- package/src/core/focus-visible.d.ts +2 -0
- package/src/core/focus-visible.js +4 -4
- package/src/core/shared.d.ts +1 -0
- package/src/core/unique-id.d.ts +4 -0
- package/src/core/unique-id.js +2 -1
- package/src/m3/autocomplete/autocomplete.d.ts +9 -0
- package/src/m3/autocomplete/autocomplete.js +11 -10
- package/src/m3/badge/badge.d.ts +13 -0
- package/src/m3/badge/badge.js +28 -37
- package/src/m3/button/common-button-toggle.d.ts +31 -0
- package/src/m3/button/common-button-toggle.js +44 -41
- package/src/m3/button/common-button.d.ts +29 -0
- package/src/m3/button/common-button.js +40 -40
- package/src/m3/button/icon-button-toggle.d.ts +24 -0
- package/src/m3/button/icon-button-toggle.js +35 -32
- package/src/m3/button/icon-button.d.ts +23 -0
- package/src/m3/button/icon-button.js +33 -31
- package/src/m3/button-group/connected-button-group.d.ts +19 -0
- package/src/m3/button-group/connected-button-group.js +26 -24
- package/src/m3/button-group/standard-button-group.d.ts +24 -0
- package/src/m3/button-group/standard-button-group.js +71 -65
- package/src/m3/checkbox/checkbox.d.ts +25 -0
- package/src/m3/checkbox/checkbox.js +23 -22
- package/src/m3/dialog/dialog.d.ts +46 -0
- package/src/m3/dialog/dialog.js +90 -117
- package/src/m3/divider/divider.d.ts +13 -0
- package/src/m3/divider/divider.js +20 -33
- package/src/m3/fab/fab.d.ts +23 -0
- package/src/m3/fab/fab.js +24 -23
- package/src/m3/field/field.d.ts +28 -0
- package/src/m3/field/field.js +40 -55
- package/src/m3/field/filled-field.d.ts +11 -0
- package/src/m3/field/filled-field.js +7 -11
- package/src/m3/field/outlined-field.d.ts +11 -0
- package/src/m3/field/outlined-field.js +8 -12
- package/src/m3/focus-ring/focus-ring.d.ts +32 -0
- package/src/m3/focus-ring/focus-ring.js +38 -23
- package/src/m3/item/item.d.ts +31 -0
- package/src/m3/item/item.js +32 -17
- package/src/m3/list/list-item.d.ts +24 -0
- package/src/m3/list/list-item.js +20 -16
- package/src/m3/list/list.d.ts +15 -0
- package/src/m3/list/list.js +16 -15
- package/src/m3/loading-indicator/loading-indicator.d.ts +26 -0
- package/src/m3/loading-indicator/loading-indicator.js +113 -161
- package/src/m3/menu/menu-item.d.ts +15 -0
- package/src/m3/menu/menu-item.js +10 -4
- package/src/m3/menu/menu.d.ts +22 -0
- package/src/m3/menu/menu.js +20 -18
- package/src/m3/radio/radio-styles.css.js +1 -1
- package/src/m3/radio/radio.d.ts +17 -0
- package/src/m3/radio/radio.js +22 -11
- package/src/m3/ripple/ripple.d.ts +43 -0
- package/src/m3/ripple/ripple.js +82 -89
- package/src/m3/select/filled-select.d.ts +16 -0
- package/src/m3/select/filled-select.js +12 -10
- package/src/m3/select/option.d.ts +15 -0
- package/src/m3/select/option.js +10 -4
- package/src/m3/select/outlined-select.d.ts +16 -0
- package/src/m3/select/outlined-select.js +12 -10
- package/src/m3/select/select.d.ts +14 -0
- package/src/m3/select/select.js +17 -16
- package/src/m3/slider/slider.d.ts +20 -0
- package/src/m3/slider/slider.js +32 -26
- package/src/m3/switch/switch.d.ts +27 -0
- package/src/m3/switch/switch.js +62 -53
- package/src/m3/system/motion.d.ts +12 -0
- package/src/m3/system/motion.js +16 -9
- package/src/m3/tab/tab-panel.d.ts +9 -0
- package/src/m3/tab/tab-panel.js +6 -9
- package/src/m3/tab/tab.d.ts +19 -0
- package/src/m3/tab/tab.js +14 -12
- package/src/m3/tab/tabs.d.ts +25 -0
- package/src/m3/tab/tabs.js +34 -30
- package/src/m3/text-field/filled-text-field.d.ts +13 -0
- package/src/m3/text-field/filled-text-field.js +15 -20
- package/src/m3/text-field/outlined-text-field.d.ts +13 -0
- package/src/m3/text-field/outlined-text-field.js +15 -20
- package/src/m3/toolbar/toolbar.d.ts +26 -0
- package/src/m3/toolbar/toolbar.js +28 -25
- package/src/m3/tooltip/tooltip.d.ts +19 -0
- package/src/m3/tooltip/tooltip.js +15 -14
- package/src/win98/button/button.d.ts +13 -0
- package/src/win98/button/button.js +13 -11
- package/src/m3/dialog/dialog-spring.js +0 -179
- package/src/win98/button/radio.js +0 -8
- package/src/win98/radio/radio.js +0 -8
package/src/base/menu.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
2
|
import { LitElement, html } from 'lit';
|
|
3
3
|
import { property, query, queryAssignedElements } from 'lit/decorators.js';
|
|
4
4
|
import { setFocusVisible } from '../core/focus-visible.js';
|
|
@@ -16,15 +16,75 @@ const Base = FocusDelegated(InternalsAttached(Attachable(LitElement)));
|
|
|
16
16
|
* @fires {Event} close - Fires when the menu is closed.
|
|
17
17
|
* @fires {MenuSelectEvent} select - Fires when an item is selected.
|
|
18
18
|
* @fires {MenuItemFocusEvent} item-focus - Fires when an item is focused
|
|
19
|
-
|
|
19
|
+
*
|
|
20
|
+
* TODO: handle slotchange
|
|
21
|
+
*/
|
|
22
|
+
export class Menu extends Base {
|
|
23
|
+
constructor() {
|
|
24
|
+
super(...arguments);
|
|
25
|
+
this._durations = { show: 0, hide: 0 };
|
|
26
|
+
this._scrollPadding = 0;
|
|
27
|
+
this.type = 'menu';
|
|
28
|
+
this.open = false;
|
|
29
|
+
this.quick = false;
|
|
30
|
+
this.offset = 0;
|
|
31
|
+
this.align = 'bottom-start';
|
|
32
|
+
this.alignStrategy = 'absolute';
|
|
33
|
+
this.keepOpenBlur = false;
|
|
34
|
+
this.keepOpenSelect = false;
|
|
35
|
+
this.keepOpenClickAway = false;
|
|
36
|
+
this.noFocusControl = false;
|
|
37
|
+
this.tabIndex = 0;
|
|
38
|
+
this.$lastFocused = null;
|
|
39
|
+
this.popoverController = new PopoverController(this, {
|
|
40
|
+
popover: () => this.$menu,
|
|
41
|
+
trigger: () => this.$control,
|
|
42
|
+
positioning: {
|
|
43
|
+
placement: () => this.align,
|
|
44
|
+
strategy: () => this.alignStrategy,
|
|
45
|
+
offset: () => this.offset,
|
|
46
|
+
windowPadding: () => 16,
|
|
47
|
+
},
|
|
48
|
+
durations: {
|
|
49
|
+
open: () => (this.quick ? 0 : this._durations.show),
|
|
50
|
+
close: () => (this.quick ? 0 : this._durations.hide),
|
|
51
|
+
},
|
|
52
|
+
onClickAway: () => {
|
|
53
|
+
if (!this.keepOpenClickAway)
|
|
54
|
+
this.open = false;
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
this.listController = new ListController(this, {
|
|
58
|
+
isItem: (item) => item.getAttribute('seele-base') === 'option' &&
|
|
59
|
+
!item.hasAttribute('disabled') &&
|
|
60
|
+
!item.hidden,
|
|
61
|
+
getPossibleItems: () => this.slotItems,
|
|
62
|
+
blurItem: (item) => {
|
|
63
|
+
item.focused = false;
|
|
64
|
+
},
|
|
65
|
+
focusItem: (item) => {
|
|
66
|
+
item.focused = true;
|
|
67
|
+
if (!this.noFocusControl) {
|
|
68
|
+
this.$menu.ariaActiveDescendantElement = item;
|
|
69
|
+
}
|
|
70
|
+
scrollItemIntoView(this.$menu, item, this._scrollPadding);
|
|
71
|
+
this.dispatchEvent(new CustomEvent('item-focus', {
|
|
72
|
+
detail: { item: item },
|
|
73
|
+
bubbles: true,
|
|
74
|
+
composed: true,
|
|
75
|
+
}));
|
|
76
|
+
},
|
|
77
|
+
wrapNavigation: () => false,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
20
80
|
get $items() {
|
|
21
81
|
return this.listController.items || [];
|
|
22
82
|
}
|
|
23
83
|
render() {
|
|
24
|
-
return html`<div part="menu" role="${this.type}" tabindex="${this.tabIndex}" @keydown="${this.#handleKeyDown.bind(this)}" @focusout="${this.#handleFocusOut.bind(this)}">${this.renderItemSlot()}</div>`;
|
|
84
|
+
return html `<div part="menu" role="${this.type}" tabindex="${this.tabIndex}" @keydown="${this.#handleKeyDown.bind(this)}" @focusout="${this.#handleFocusOut.bind(this)}">${this.renderItemSlot()}</div>`;
|
|
25
85
|
}
|
|
26
86
|
renderItemSlot() {
|
|
27
|
-
return html`<slot part="items"></slot>`;
|
|
87
|
+
return html `<slot part="items"></slot>`;
|
|
28
88
|
}
|
|
29
89
|
connectedCallback() {
|
|
30
90
|
super.connectedCallback();
|
|
@@ -33,8 +93,8 @@ const Base = FocusDelegated(InternalsAttached(Attachable(LitElement)));
|
|
|
33
93
|
// TODO: Handle $control change
|
|
34
94
|
this.$control.addEventListener('focusout', this.#handleFocusOut.bind(this));
|
|
35
95
|
}
|
|
36
|
-
this.updateComplete.then(()=>{
|
|
37
|
-
this.$items.forEach((item)=>{
|
|
96
|
+
this.updateComplete.then(() => {
|
|
97
|
+
this.$items.forEach((item) => {
|
|
38
98
|
item.addEventListener('mouseover', this.#handleItemMouseOver.bind(this));
|
|
39
99
|
item.addEventListener('click', this.#handleItemClick.bind(this));
|
|
40
100
|
});
|
|
@@ -49,35 +109,31 @@ const Base = FocusDelegated(InternalsAttached(Attachable(LitElement)));
|
|
|
49
109
|
updated(changed) {
|
|
50
110
|
if (changed.has('open')) {
|
|
51
111
|
if (this.open) {
|
|
52
|
-
this.dispatchEvent(new Event('open', {
|
|
53
|
-
bubbles: true,
|
|
54
|
-
composed: true
|
|
55
|
-
}));
|
|
112
|
+
this.dispatchEvent(new Event('open', { bubbles: true, composed: true }));
|
|
56
113
|
this.$lastFocused = document.activeElement;
|
|
57
114
|
if (this.$control) {
|
|
58
115
|
this.$control.ariaExpanded = 'true';
|
|
59
116
|
}
|
|
60
|
-
this.popoverController.animateOpen().then(()=>{
|
|
117
|
+
this.popoverController.animateOpen().then(() => {
|
|
61
118
|
if (!this.noFocusControl) {
|
|
62
119
|
this.$menu.focus();
|
|
63
120
|
this.listController.focusFirstItem();
|
|
64
121
|
}
|
|
65
122
|
});
|
|
66
|
-
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
67
125
|
if (!this.noFocusControl) {
|
|
68
126
|
this.$menu.ariaActiveDescendantElement = null;
|
|
69
127
|
}
|
|
70
|
-
this.dispatchEvent(new Event('close', {
|
|
71
|
-
bubbles: true,
|
|
72
|
-
composed: true
|
|
73
|
-
}));
|
|
128
|
+
this.dispatchEvent(new Event('close', { bubbles: true, composed: true }));
|
|
74
129
|
this.listController.clearSearch();
|
|
75
130
|
if (this.$control) {
|
|
76
131
|
this.$control.ariaExpanded = 'false';
|
|
77
132
|
}
|
|
78
|
-
this.popoverController.animateClose().then(()=>{
|
|
133
|
+
this.popoverController.animateClose().then(() => {
|
|
79
134
|
if (this.$lastFocused) {
|
|
80
|
-
if (!this.noFocusControl)
|
|
135
|
+
if (!this.noFocusControl)
|
|
136
|
+
this.$lastFocused.focus();
|
|
81
137
|
this.$lastFocused = null;
|
|
82
138
|
}
|
|
83
139
|
});
|
|
@@ -85,12 +141,13 @@ const Base = FocusDelegated(InternalsAttached(Attachable(LitElement)));
|
|
|
85
141
|
}
|
|
86
142
|
}
|
|
87
143
|
#handleKeyDown(event) {
|
|
88
|
-
if (event.defaultPrevented)
|
|
144
|
+
if (event.defaultPrevented)
|
|
145
|
+
return;
|
|
89
146
|
const action = getActionFromKey(event, this.open);
|
|
90
147
|
const items = this.$items;
|
|
91
148
|
const currentIndex = this.listController.currentIndex;
|
|
92
149
|
const maxIndex = items.length - 1;
|
|
93
|
-
switch(action){
|
|
150
|
+
switch (action) {
|
|
94
151
|
case MenuActions.Last:
|
|
95
152
|
case MenuActions.First:
|
|
96
153
|
this.open = true;
|
|
@@ -110,12 +167,13 @@ const Base = FocusDelegated(InternalsAttached(Attachable(LitElement)));
|
|
|
110
167
|
this.dispatchEvent(new CustomEvent('select', {
|
|
111
168
|
detail: {
|
|
112
169
|
item: items[currentIndex],
|
|
113
|
-
index: currentIndex
|
|
170
|
+
index: currentIndex,
|
|
114
171
|
},
|
|
115
172
|
bubbles: true,
|
|
116
|
-
composed: true
|
|
173
|
+
composed: true,
|
|
117
174
|
}));
|
|
118
|
-
if (this.keepOpenSelect)
|
|
175
|
+
if (this.keepOpenSelect)
|
|
176
|
+
return;
|
|
119
177
|
this.open = false;
|
|
120
178
|
}
|
|
121
179
|
return;
|
|
@@ -134,9 +192,12 @@ const Base = FocusDelegated(InternalsAttached(Attachable(LitElement)));
|
|
|
134
192
|
}
|
|
135
193
|
}
|
|
136
194
|
#handleFocusOut(event) {
|
|
137
|
-
if (this.keepOpenBlur)
|
|
195
|
+
if (this.keepOpenBlur)
|
|
196
|
+
return;
|
|
138
197
|
const newFocus = event.relatedTarget;
|
|
139
|
-
const isInside = this.contains(newFocus) ||
|
|
198
|
+
const isInside = this.contains(newFocus) ||
|
|
199
|
+
this.shadowRoot?.contains(newFocus) ||
|
|
200
|
+
this.$control?.contains(newFocus);
|
|
140
201
|
if (!isInside) {
|
|
141
202
|
this.open = false;
|
|
142
203
|
}
|
|
@@ -153,12 +214,13 @@ const Base = FocusDelegated(InternalsAttached(Attachable(LitElement)));
|
|
|
153
214
|
this.dispatchEvent(new CustomEvent('select', {
|
|
154
215
|
detail: {
|
|
155
216
|
item: clickedItem,
|
|
156
|
-
index: index
|
|
217
|
+
index: index,
|
|
157
218
|
},
|
|
158
219
|
bubbles: true,
|
|
159
|
-
composed: true
|
|
220
|
+
composed: true,
|
|
160
221
|
}));
|
|
161
|
-
if (!this.keepOpenSelect)
|
|
222
|
+
if (!this.keepOpenSelect)
|
|
223
|
+
this.open = false;
|
|
162
224
|
}
|
|
163
225
|
get currentIndex() {
|
|
164
226
|
return this.listController?.currentIndex;
|
|
@@ -178,118 +240,45 @@ const Base = FocusDelegated(InternalsAttached(Attachable(LitElement)));
|
|
|
178
240
|
close() {
|
|
179
241
|
this.open = false;
|
|
180
242
|
}
|
|
181
|
-
constructor(...args){
|
|
182
|
-
super(...args), this._durations = {
|
|
183
|
-
show: 0,
|
|
184
|
-
hide: 0
|
|
185
|
-
}, this._scrollPadding = 0, this.type = 'menu', this.open = false, this.quick = false, this.offset = 0, this.align = 'bottom-start', this.alignStrategy = 'absolute', this.keepOpenBlur = false, this.keepOpenSelect = false, this.keepOpenClickAway = false, this.noFocusControl = false, this.tabIndex = 0, this.$lastFocused = null, this.popoverController = new PopoverController(this, {
|
|
186
|
-
popover: ()=>this.$menu,
|
|
187
|
-
trigger: ()=>this.$control,
|
|
188
|
-
positioning: {
|
|
189
|
-
placement: ()=>this.align,
|
|
190
|
-
strategy: ()=>this.alignStrategy,
|
|
191
|
-
offset: ()=>this.offset,
|
|
192
|
-
windowPadding: ()=>16
|
|
193
|
-
},
|
|
194
|
-
durations: {
|
|
195
|
-
open: ()=>this.quick ? 0 : this._durations.show,
|
|
196
|
-
close: ()=>this.quick ? 0 : this._durations.hide
|
|
197
|
-
},
|
|
198
|
-
onClickAway: ()=>{
|
|
199
|
-
if (!this.keepOpenClickAway) this.open = false;
|
|
200
|
-
}
|
|
201
|
-
}), this.listController = new ListController(this, {
|
|
202
|
-
isItem: (item)=>item.getAttribute('seele-base') === 'option' && !item.hasAttribute('disabled') && !item.hidden,
|
|
203
|
-
getPossibleItems: ()=>this.slotItems,
|
|
204
|
-
blurItem: (item)=>{
|
|
205
|
-
item.focused = false;
|
|
206
|
-
},
|
|
207
|
-
focusItem: (item)=>{
|
|
208
|
-
item.focused = true;
|
|
209
|
-
if (!this.noFocusControl) {
|
|
210
|
-
this.$menu.ariaActiveDescendantElement = item;
|
|
211
|
-
}
|
|
212
|
-
scrollItemIntoView(this.$menu, item, this._scrollPadding);
|
|
213
|
-
this.dispatchEvent(new CustomEvent('item-focus', {
|
|
214
|
-
detail: {
|
|
215
|
-
item: item
|
|
216
|
-
},
|
|
217
|
-
bubbles: true,
|
|
218
|
-
composed: true
|
|
219
|
-
}));
|
|
220
|
-
},
|
|
221
|
-
wrapNavigation: ()=>false
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
243
|
}
|
|
225
|
-
|
|
244
|
+
__decorate([
|
|
226
245
|
property()
|
|
227
246
|
], Menu.prototype, "type", void 0);
|
|
228
|
-
|
|
229
|
-
property({
|
|
230
|
-
type: Boolean,
|
|
231
|
-
reflect: true
|
|
232
|
-
})
|
|
247
|
+
__decorate([
|
|
248
|
+
property({ type: Boolean, reflect: true })
|
|
233
249
|
], Menu.prototype, "open", void 0);
|
|
234
|
-
|
|
235
|
-
property({
|
|
236
|
-
type: Boolean
|
|
237
|
-
})
|
|
250
|
+
__decorate([
|
|
251
|
+
property({ type: Boolean })
|
|
238
252
|
], Menu.prototype, "quick", void 0);
|
|
239
|
-
|
|
240
|
-
property({
|
|
241
|
-
type: Number
|
|
242
|
-
})
|
|
253
|
+
__decorate([
|
|
254
|
+
property({ type: Number })
|
|
243
255
|
], Menu.prototype, "offset", void 0);
|
|
244
|
-
|
|
245
|
-
property({
|
|
246
|
-
reflect: true
|
|
247
|
-
})
|
|
256
|
+
__decorate([
|
|
257
|
+
property({ reflect: true })
|
|
248
258
|
], Menu.prototype, "align", void 0);
|
|
249
|
-
|
|
250
|
-
property({
|
|
251
|
-
type: String,
|
|
252
|
-
reflect: true,
|
|
253
|
-
attribute: 'align-strategy'
|
|
254
|
-
})
|
|
259
|
+
__decorate([
|
|
260
|
+
property({ type: String, reflect: true, attribute: 'align-strategy' })
|
|
255
261
|
], Menu.prototype, "alignStrategy", void 0);
|
|
256
|
-
|
|
257
|
-
property({
|
|
258
|
-
type: Boolean,
|
|
259
|
-
attribute: 'keep-open-blur'
|
|
260
|
-
})
|
|
262
|
+
__decorate([
|
|
263
|
+
property({ type: Boolean, attribute: 'keep-open-blur' })
|
|
261
264
|
], Menu.prototype, "keepOpenBlur", void 0);
|
|
262
|
-
|
|
263
|
-
property({
|
|
264
|
-
type: Boolean,
|
|
265
|
-
attribute: 'keep-open-select'
|
|
266
|
-
})
|
|
265
|
+
__decorate([
|
|
266
|
+
property({ type: Boolean, attribute: 'keep-open-select' })
|
|
267
267
|
], Menu.prototype, "keepOpenSelect", void 0);
|
|
268
|
-
|
|
269
|
-
property({
|
|
270
|
-
type: Boolean,
|
|
271
|
-
attribute: 'keep-open-click-away'
|
|
272
|
-
})
|
|
268
|
+
__decorate([
|
|
269
|
+
property({ type: Boolean, attribute: 'keep-open-click-away' })
|
|
273
270
|
], Menu.prototype, "keepOpenClickAway", void 0);
|
|
274
|
-
|
|
275
|
-
property({
|
|
276
|
-
type: Boolean,
|
|
277
|
-
attribute: 'no-focus-control'
|
|
278
|
-
})
|
|
271
|
+
__decorate([
|
|
272
|
+
property({ type: Boolean, attribute: 'no-focus-control' })
|
|
279
273
|
], Menu.prototype, "noFocusControl", void 0);
|
|
280
|
-
|
|
281
|
-
property({
|
|
282
|
-
type: Number,
|
|
283
|
-
attribute: 'data-tabindex'
|
|
284
|
-
})
|
|
274
|
+
__decorate([
|
|
275
|
+
property({ type: Number, attribute: 'data-tabindex' })
|
|
285
276
|
], Menu.prototype, "tabIndex", void 0);
|
|
286
|
-
|
|
277
|
+
__decorate([
|
|
287
278
|
query('[part="menu"]')
|
|
288
279
|
], Menu.prototype, "$menu", void 0);
|
|
289
|
-
|
|
290
|
-
queryAssignedElements({
|
|
291
|
-
flatten: true
|
|
292
|
-
})
|
|
280
|
+
__decorate([
|
|
281
|
+
queryAssignedElements({ flatten: true })
|
|
293
282
|
], Menu.prototype, "slotItems", void 0);
|
|
294
283
|
// Reference: https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-select-only/
|
|
295
284
|
export const MenuActions = {
|
|
@@ -303,22 +292,17 @@ export const MenuActions = {
|
|
|
303
292
|
PageUp: 7,
|
|
304
293
|
Previous: 8,
|
|
305
294
|
Select: 9,
|
|
306
|
-
Type: 10
|
|
295
|
+
Type: 10,
|
|
307
296
|
};
|
|
308
297
|
export function filterOptions(options = [], filter, exclude = []) {
|
|
309
|
-
return options.filter((option)=>{
|
|
298
|
+
return options.filter((option) => {
|
|
310
299
|
const matches = option.toLowerCase().indexOf(filter.toLowerCase()) === 0;
|
|
311
300
|
return matches && exclude.indexOf(option) < 0;
|
|
312
301
|
});
|
|
313
302
|
}
|
|
314
303
|
export function getActionFromKey(event, menuOpen) {
|
|
315
304
|
const { key, altKey, ctrlKey, metaKey } = event;
|
|
316
|
-
const openKeys = [
|
|
317
|
-
'ArrowDown',
|
|
318
|
-
'ArrowUp',
|
|
319
|
-
'Enter',
|
|
320
|
-
' '
|
|
321
|
-
];
|
|
305
|
+
const openKeys = ['ArrowDown', 'ArrowUp', 'Enter', ' '];
|
|
322
306
|
if (!menuOpen && openKeys.includes(key)) {
|
|
323
307
|
return MenuActions.Open;
|
|
324
308
|
}
|
|
@@ -328,23 +312,31 @@ export function getActionFromKey(event, menuOpen) {
|
|
|
328
312
|
if (key === 'End') {
|
|
329
313
|
return MenuActions.Last;
|
|
330
314
|
}
|
|
331
|
-
if (key === 'Backspace' ||
|
|
315
|
+
if (key === 'Backspace' ||
|
|
316
|
+
key === 'Clear' ||
|
|
317
|
+
(key.length === 1 && key !== ' ' && !altKey && !ctrlKey && !metaKey)) {
|
|
332
318
|
return MenuActions.Type;
|
|
333
319
|
}
|
|
334
320
|
if (menuOpen) {
|
|
335
321
|
if (key === 'ArrowUp' && altKey) {
|
|
336
322
|
return MenuActions.CloseSelect;
|
|
337
|
-
}
|
|
323
|
+
}
|
|
324
|
+
else if (key === 'ArrowDown' && !altKey) {
|
|
338
325
|
return MenuActions.Next;
|
|
339
|
-
}
|
|
326
|
+
}
|
|
327
|
+
else if (key === 'ArrowUp') {
|
|
340
328
|
return MenuActions.Previous;
|
|
341
|
-
}
|
|
329
|
+
}
|
|
330
|
+
else if (key === 'PageUp') {
|
|
342
331
|
return MenuActions.PageUp;
|
|
343
|
-
}
|
|
332
|
+
}
|
|
333
|
+
else if (key === 'PageDown') {
|
|
344
334
|
return MenuActions.PageDown;
|
|
345
|
-
}
|
|
335
|
+
}
|
|
336
|
+
else if (key === 'Escape') {
|
|
346
337
|
return MenuActions.Close;
|
|
347
|
-
}
|
|
338
|
+
}
|
|
339
|
+
else if (key === 'Enter' || key === ' ') {
|
|
348
340
|
return MenuActions.CloseSelect;
|
|
349
341
|
}
|
|
350
342
|
}
|
|
@@ -352,7 +344,7 @@ export function getActionFromKey(event, menuOpen) {
|
|
|
352
344
|
}
|
|
353
345
|
export function getUpdatedIndex(currentIndex, maxIndex, action) {
|
|
354
346
|
const pageSize = 10;
|
|
355
|
-
switch(action){
|
|
347
|
+
switch (action) {
|
|
356
348
|
case MenuActions.First:
|
|
357
349
|
return 0;
|
|
358
350
|
case MenuActions.Last:
|
|
@@ -370,13 +362,15 @@ export function getUpdatedIndex(currentIndex, maxIndex, action) {
|
|
|
370
362
|
}
|
|
371
363
|
}
|
|
372
364
|
export function scrollItemIntoView(menu, item, paddingY = 0) {
|
|
373
|
-
if (!menu)
|
|
365
|
+
if (!menu)
|
|
366
|
+
return;
|
|
374
367
|
// Basic scroll into view logic
|
|
375
368
|
const menuRect = menu.getBoundingClientRect();
|
|
376
369
|
const itemRect = item.getBoundingClientRect();
|
|
377
370
|
if (itemRect.bottom + paddingY > menuRect.bottom) {
|
|
378
371
|
menu.scrollTop += itemRect.bottom - menuRect.bottom + paddingY;
|
|
379
|
-
}
|
|
372
|
+
}
|
|
373
|
+
else if (itemRect.top - paddingY < menuRect.top) {
|
|
380
374
|
menu.scrollTop -= menuRect.top - itemRect.top + paddingY;
|
|
381
375
|
}
|
|
382
376
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
export declare class AttachableInterface {
|
|
3
|
+
$control: HTMLElement;
|
|
4
|
+
htmlFor: string | null;
|
|
5
|
+
attach(control: HTMLElement, force?: boolean): void;
|
|
6
|
+
detach(): void;
|
|
7
|
+
handleControlChange(prev: HTMLElement | null, next: HTMLElement | null): void;
|
|
8
|
+
}
|
|
9
|
+
export declare const Attachable: <T extends Constructor<LitElement>>(superClass: T) => Constructor<AttachableInterface> & T;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
2
|
import { property } from 'lit/decorators.js';
|
|
3
|
-
export const Attachable = (superClass)=>{
|
|
3
|
+
export const Attachable = (superClass) => {
|
|
4
4
|
class AttachableElement extends superClass {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
this.currentControl = null;
|
|
8
|
+
}
|
|
5
9
|
connectedCallback() {
|
|
6
10
|
super.connectedCallback();
|
|
7
11
|
this.setCurrentControl(this.$control);
|
|
@@ -11,21 +15,25 @@ export const Attachable = (superClass)=>{
|
|
|
11
15
|
super.disconnectedCallback();
|
|
12
16
|
}
|
|
13
17
|
/**
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
* If has `for` attribute, use it to find the control element.
|
|
19
|
+
* Otherwise, use the parent element as the control.
|
|
20
|
+
*/
|
|
21
|
+
get $control() {
|
|
17
22
|
if (this.hasAttribute('for')) {
|
|
18
23
|
if (!this.htmlFor || !this.isConnected) {
|
|
19
24
|
return null;
|
|
20
25
|
}
|
|
21
26
|
return this.getRootNode().querySelector(`#${this.htmlFor}`);
|
|
22
27
|
}
|
|
23
|
-
return this.currentControl || this.parentNode instanceof ShadowRoot
|
|
28
|
+
return this.currentControl || this.parentNode instanceof ShadowRoot
|
|
29
|
+
? this.parentNode.host
|
|
30
|
+
: this.parentElement;
|
|
24
31
|
}
|
|
25
32
|
set $control(control) {
|
|
26
33
|
if (control) {
|
|
27
34
|
this.attach(control);
|
|
28
|
-
}
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
29
37
|
this.detach();
|
|
30
38
|
}
|
|
31
39
|
}
|
|
@@ -38,7 +46,8 @@ export const Attachable = (superClass)=>{
|
|
|
38
46
|
}
|
|
39
47
|
}
|
|
40
48
|
setCurrentControl(control, force = false) {
|
|
41
|
-
if (control === this.currentControl && !force)
|
|
49
|
+
if (control === this.currentControl && !force)
|
|
50
|
+
return;
|
|
42
51
|
this.handleControlChange(this.currentControl, control);
|
|
43
52
|
this.currentControl = control;
|
|
44
53
|
}
|
|
@@ -51,17 +60,12 @@ export const Attachable = (superClass)=>{
|
|
|
51
60
|
this.setAttribute('for', '');
|
|
52
61
|
}
|
|
53
62
|
/**
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
super(...args), this.currentControl = null;
|
|
58
|
-
}
|
|
63
|
+
* Handles the first attaching and actual control element changing
|
|
64
|
+
*/
|
|
65
|
+
handleControlChange(prev = null, next = null) { }
|
|
59
66
|
}
|
|
60
|
-
|
|
61
|
-
property({
|
|
62
|
-
attribute: 'for',
|
|
63
|
-
type: String
|
|
64
|
-
})
|
|
67
|
+
__decorate([
|
|
68
|
+
property({ attribute: 'for', type: String })
|
|
65
69
|
], AttachableElement.prototype, "htmlFor", void 0);
|
|
66
70
|
return AttachableElement;
|
|
67
71
|
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import { InternalsAttachedInterface } from './internals-attached.js';
|
|
3
|
+
export declare class FocusDelegatedInterface {
|
|
4
|
+
}
|
|
5
|
+
export declare const FocusDelegated: <T extends Constructor<LitElement & InternalsAttachedInterface>>(superClass: T) => Constructor<FocusDelegatedInterface> & T;
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
2
|
import { internals } from './internals-attached.js';
|
|
3
|
-
export const FocusDelegated = (superClass)=>{
|
|
3
|
+
export const FocusDelegated = (superClass) => {
|
|
4
4
|
class FocusDelegatedElement extends superClass {
|
|
5
|
-
static{
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
constructor(...args){
|
|
5
|
+
static { this.shadowRootOptions = {
|
|
6
|
+
...LitElement.shadowRootOptions,
|
|
7
|
+
delegatesFocus: true,
|
|
8
|
+
}; }
|
|
9
|
+
constructor(...args) {
|
|
12
10
|
super();
|
|
13
11
|
this[internals].role = 'presentation';
|
|
14
12
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import { InternalsAttachedInterface } from './internals-attached.js';
|
|
3
|
+
export declare class FormAssociatedInterface {
|
|
4
|
+
form: HTMLFormElement | null;
|
|
5
|
+
labels: NodeList;
|
|
6
|
+
name: string | null;
|
|
7
|
+
disabled: boolean;
|
|
8
|
+
validity: ValidityState;
|
|
9
|
+
validationMessage: string;
|
|
10
|
+
willValidate: boolean;
|
|
11
|
+
formDisabledCallback(disabled: boolean): void;
|
|
12
|
+
checkValidity(): boolean;
|
|
13
|
+
reportValidity(): boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare const FormAssociated: <T extends Constructor<LitElement & InternalsAttachedInterface>>(superClass: T) => Constructor<FormAssociatedInterface> & T;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
2
|
import { property } from 'lit/decorators.js';
|
|
3
3
|
import { internals } from './internals-attached.js';
|
|
4
|
-
export const FormAssociated = (superClass)=>{
|
|
4
|
+
export const FormAssociated = (superClass) => {
|
|
5
5
|
class FormAssociatedElement extends superClass {
|
|
6
|
-
static{
|
|
7
|
-
this.formAssociated = true;
|
|
8
|
-
}
|
|
6
|
+
static { this.formAssociated = true; }
|
|
9
7
|
get form() {
|
|
10
8
|
return this[internals].form;
|
|
11
9
|
}
|
|
@@ -25,16 +23,16 @@ export const FormAssociated = (superClass)=>{
|
|
|
25
23
|
set name(name) {
|
|
26
24
|
// Note: setting name to null or empty does not remove the attribute.
|
|
27
25
|
this.setAttribute('name', name);
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
// We don't need to call `requestUpdate()` since it's called synchronously
|
|
27
|
+
// in `attributeChangedCallback()`.
|
|
30
28
|
}
|
|
31
29
|
get disabled() {
|
|
32
30
|
return this.hasAttribute('disabled');
|
|
33
31
|
}
|
|
34
32
|
set disabled(disabled) {
|
|
35
33
|
this.toggleAttribute('disabled', disabled);
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
// We don't need to call `requestUpdate()` since it's called synchronously
|
|
35
|
+
// in `attributeChangedCallback()`.
|
|
38
36
|
}
|
|
39
37
|
attributeChangedCallback(name, old, value) {
|
|
40
38
|
if (name === 'disabled') {
|
|
@@ -61,16 +59,11 @@ export const FormAssociated = (superClass)=>{
|
|
|
61
59
|
return this[internals].reportValidity();
|
|
62
60
|
}
|
|
63
61
|
}
|
|
64
|
-
|
|
65
|
-
property({
|
|
66
|
-
noAccessor: true
|
|
67
|
-
})
|
|
62
|
+
__decorate([
|
|
63
|
+
property({ noAccessor: true })
|
|
68
64
|
], FormAssociatedElement.prototype, "name", null);
|
|
69
|
-
|
|
70
|
-
property({
|
|
71
|
-
type: Boolean,
|
|
72
|
-
noAccessor: true
|
|
73
|
-
})
|
|
65
|
+
__decorate([
|
|
66
|
+
property({ type: Boolean, noAccessor: true })
|
|
74
67
|
], FormAssociatedElement.prototype, "disabled", null);
|
|
75
68
|
return FormAssociatedElement;
|
|
76
69
|
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
export declare const internals: unique symbol;
|
|
3
|
+
export declare class InternalsAttachedInterface {
|
|
4
|
+
[internals]: ElementInternals;
|
|
5
|
+
}
|
|
6
|
+
export declare const InternalsAttached: <T extends Constructor<LitElement>>(superClass: T) => Constructor<InternalsAttachedInterface> & T;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const internals = Symbol('internals');
|
|
2
2
|
const privateInternals = Symbol('privateInternals');
|
|
3
|
-
export const InternalsAttached = (superClass)=>{
|
|
3
|
+
export const InternalsAttached = (superClass) => {
|
|
4
4
|
class InternalsAttachedElement extends superClass {
|
|
5
5
|
get [internals]() {
|
|
6
6
|
if (!this[privateInternals]) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ListItem } from './list-item.js';
|
|
2
|
+
export declare class OptionInterface {
|
|
3
|
+
value: string;
|
|
4
|
+
}
|
|
5
|
+
export declare const OptionMixin: <T extends Constructor<ListItem>>(superClass: T) => Constructor<OptionInterface> & T;
|
|
6
|
+
declare const Option_base: Constructor<OptionInterface> & typeof ListItem;
|
|
7
|
+
export declare class Option extends Option_base {
|
|
8
|
+
}
|
|
9
|
+
export {};
|