@brightspace-ui/core 3.219.5 → 3.219.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/components/dropdown/README.md +0 -1
- package/components/dropdown/dropdown-content.js +10 -38
- package/components/dropdown/dropdown-menu.js +126 -316
- package/components/dropdown/dropdown-opener-mixin.js +3 -28
- package/components/dropdown/dropdown-popover-mixin.js +2 -7
- package/components/dropdown/dropdown-tabs.js +45 -113
- package/components/filter/filter.js +1 -20
- package/components/table/table-col-sort-button.js +1 -2
- package/components/table/table-wrapper.js +17 -28
- package/custom-elements.json +99 -144
- package/helpers/README.md +0 -14
- package/helpers/demo/prism.html +0 -1784
- package/helpers/visualReady.js +0 -2
- package/package.json +1 -1
- package/components/dropdown/dropdown-content-mixin.js +0 -1299
- package/components/dropdown/dropdown-content-styles.js +0 -327
|
@@ -215,7 +215,6 @@ To make your usage of `d2l-dropdown-more` accessible, use the following property
|
|
|
215
215
|
| Property | Type | Description |
|
|
216
216
|
|---|---|---|
|
|
217
217
|
| `align` | String | Optionally align dropdown to either `start` or `end`. If not set, the dropdown will attempt to be centred. |
|
|
218
|
-
| `boundary` | Object | Optionally provide boundaries to where the dropdown will appear. Valid properties are `"above"`, `"below"`, `"left"` and `"right"`. |
|
|
219
218
|
| `max-height` | Number | Override default `max-height`. _Note that the default behaviour is to be as tall as necessary within the viewport, so this property is usually not needed_ |
|
|
220
219
|
| `min-height` | Number | Override default height used for required space when `no-auto-fit` is true. Specify a number that would be the px value. _Note that the default behaviour is to be as tall as necessary within the viewport, so this property is usually not needed._ |
|
|
221
220
|
| `max-width` | Number | Override default `max-width` |
|
|
@@ -1,40 +1,12 @@
|
|
|
1
|
-
import { DropdownPopoverMixin
|
|
2
|
-
import { DropdownContentMixin } from './dropdown-content-mixin.js';
|
|
3
|
-
import { dropdownContentStyles } from './dropdown-content-styles.js';
|
|
1
|
+
import { DropdownPopoverMixin } from './dropdown-popover-mixin.js';
|
|
4
2
|
import { LitElement } from 'lit';
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class DropdownContent extends DropdownPopoverMixin(LitElement) { }
|
|
16
|
-
customElements.define('d2l-dropdown-content', DropdownContent);
|
|
17
|
-
|
|
18
|
-
} else {
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* A generic container for dropdown content. It provides behavior such as sizing, positioning, and managing focus gain/loss.
|
|
22
|
-
* @slot - Anything inside of "d2l-dropdown-content" that isn't in the "header" or "footer" slots appears as regular content
|
|
23
|
-
* @slot header - Sticky container at the top of the dropdown
|
|
24
|
-
* @slot footer - Sticky container at the bottom of the dropdown
|
|
25
|
-
* @fires d2l-dropdown-open - Dispatched when the dropdown is opened
|
|
26
|
-
*/
|
|
27
|
-
class DropdownContent extends DropdownContentMixin(LitElement) {
|
|
28
|
-
|
|
29
|
-
static get styles() {
|
|
30
|
-
return dropdownContentStyles;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
render() {
|
|
34
|
-
return this._renderContent();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
customElements.define('d2l-dropdown-content', DropdownContent);
|
|
39
|
-
|
|
40
|
-
}
|
|
4
|
+
/**
|
|
5
|
+
* A generic container for dropdown content. It provides behavior such as sizing, positioning, and managing focus gain/loss.
|
|
6
|
+
* @slot - Anything inside of "d2l-dropdown-content" that isn't in the "header" or "footer" slots appears as regular content
|
|
7
|
+
* @slot header - Sticky container at the top of the dropdown
|
|
8
|
+
* @slot footer - Sticky container at the bottom of the dropdown
|
|
9
|
+
* @fires d2l-dropdown-open - Dispatched when the dropdown is opened
|
|
10
|
+
*/
|
|
11
|
+
class DropdownContent extends DropdownPopoverMixin(LitElement) { }
|
|
12
|
+
customElements.define('d2l-dropdown-content', DropdownContent);
|
|
@@ -1,364 +1,174 @@
|
|
|
1
1
|
import { css, LitElement } from 'lit';
|
|
2
|
-
import { DropdownPopoverMixin
|
|
3
|
-
import { DropdownContentMixin } from './dropdown-content-mixin.js';
|
|
4
|
-
import { dropdownContentStyles } from './dropdown-content-styles.js';
|
|
2
|
+
import { DropdownPopoverMixin } from './dropdown-popover-mixin.js';
|
|
5
3
|
import { ThemeMixin } from '../../mixins/theme/theme-mixin.js';
|
|
6
4
|
|
|
7
5
|
const reduceMotion = matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
8
6
|
const dropdownDelay = 300;
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
static get styles() {
|
|
28
|
-
return [super.styles, css`
|
|
29
|
-
:host {
|
|
30
|
-
--d2l-dropdown-close-animation-name: d2l-dropdown-close-animation;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
:host([theme="dark"]) {
|
|
34
|
-
--d2l-dropdown-close-animation-name: d2l-dropdown-close-animation-dark;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
:host([_close-radio]) {
|
|
38
|
-
animation: var(--d2l-dropdown-close-animation-name) ${dropdownDelay}ms ease-out;
|
|
39
|
-
animation-delay: 50ms;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
@media (prefers-reduced-motion: reduce) {
|
|
43
|
-
:host([_close-radio]) {
|
|
44
|
-
animation: none !important;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
@keyframes d2l-dropdown-close-animation {
|
|
48
|
-
0% { opacity: 1; transform: translate(0, 0); }
|
|
49
|
-
100% { opacity: 0; transform: translate(0, -10px); }
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
@keyframes d2l-dropdown-close-animation-dark {
|
|
53
|
-
0% { opacity: 0.9; transform: translate(0, 0); }
|
|
54
|
-
100% { opacity: 0; transform: translate(0, -10px); }
|
|
55
|
-
}
|
|
56
|
-
`];
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
constructor() {
|
|
60
|
-
super();
|
|
61
|
-
this.noAutoFocus = true;
|
|
62
|
-
this.noPadding = true;
|
|
63
|
-
|
|
64
|
-
this._closeRadio = false;
|
|
65
|
-
this.#initiallyOpenedSuppressFocus = false;
|
|
66
|
-
this.#maxHeightNonTray = this.maxHeight;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
firstUpdated(changedProperties) {
|
|
70
|
-
super.firstUpdated(changedProperties);
|
|
71
|
-
|
|
72
|
-
if (this.opened) this.#initiallyOpenedSuppressFocus = true;
|
|
8
|
+
/**
|
|
9
|
+
* A container for a "d2l-menu". It provides additional support on top of "d2l-dropdown-content" for closing the menu when menu items are selected, resetting to the root of nested menus when reopening and automatic resizing when the menu resizes.
|
|
10
|
+
* @slot - Anything inside of "d2l-dropdown-content" that isn't in the "header" or "footer" slots appears as regular content
|
|
11
|
+
* @slot header - Sticky container at the top of the dropdown
|
|
12
|
+
* @slot footer - Sticky container at the bottom of the dropdown
|
|
13
|
+
* @fires d2l-dropdown-open - Dispatched when the dropdown is opened
|
|
14
|
+
*/
|
|
15
|
+
class DropdownMenu extends ThemeMixin(DropdownPopoverMixin(LitElement)) {
|
|
16
|
+
|
|
17
|
+
static get properties() {
|
|
18
|
+
return {
|
|
19
|
+
_closeRadio: { type: Boolean, reflect: true, attribute: '_close-radio' },
|
|
20
|
+
};
|
|
21
|
+
}
|
|
73
22
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
this.maxHeight = this.#maxHeightNonTray;
|
|
23
|
+
static get styles() {
|
|
24
|
+
return [super.styles, css`
|
|
25
|
+
:host {
|
|
26
|
+
--d2l-dropdown-close-animation-name: d2l-dropdown-close-animation;
|
|
79
27
|
}
|
|
80
28
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
this.addEventListener('d2l-dropdown-close', this.#handleClose);
|
|
84
|
-
this.addEventListener('d2l-menu-resize', this.#handleMenuResize);
|
|
85
|
-
this.addEventListener('d2l-menu-item-select', this.#handleSelect);
|
|
86
|
-
this.addEventListener('d2l-selection-action-click', this.#handleSelect);
|
|
87
|
-
this.addEventListener('d2l-menu-item-change', this.#handleChange);
|
|
88
|
-
this.addEventListener('focus', this.#handleFocus);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
#initializingHeight;
|
|
92
|
-
#initiallyOpenedSuppressFocus;
|
|
93
|
-
#maxHeightNonTray;
|
|
94
|
-
|
|
95
|
-
#getMenuElement() {
|
|
96
|
-
return this.shadowRoot?.querySelector('.dropdown-content > slot')
|
|
97
|
-
.assignedNodes()
|
|
98
|
-
.filter(node => node.hasAttribute && (node.getAttribute('role') === 'menu' || node.getAttribute('role') === 'listbox'))[0];
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
#handleAnimationEnd() {
|
|
102
|
-
if (!this._closeRadio) return;
|
|
103
|
-
this._closeRadio = false;
|
|
104
|
-
this.close();
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
#handleChange(e) {
|
|
108
|
-
if (e.target.getAttribute('role') !== 'menuitemradio') return;
|
|
109
|
-
|
|
110
|
-
if (reduceMotion) {
|
|
111
|
-
// Don't trigger the animation but still wait before closing the dropdown
|
|
112
|
-
setTimeout(() => {
|
|
113
|
-
this.close();
|
|
114
|
-
}, dropdownDelay);
|
|
115
|
-
} else {
|
|
116
|
-
this._closeRadio = true;
|
|
29
|
+
:host([theme="dark"]) {
|
|
30
|
+
--d2l-dropdown-close-animation-name: d2l-dropdown-close-animation-dark;
|
|
117
31
|
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
#handleClose(e) {
|
|
121
|
-
if (e.target !== this) return;
|
|
122
32
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
menu.resetFocusables();
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
#handleFocus(e) {
|
|
130
|
-
// ignore focus events originating from inside dropdown content,
|
|
131
|
-
// such as the mobile tray close button, as to not move focus
|
|
132
|
-
if (e.srcElement === this) return;
|
|
133
|
-
this.#getMenuElement().focus();
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
#handleMenuResize(e) {
|
|
137
|
-
|
|
138
|
-
if (this._mobile && this.mobileTray) {
|
|
139
|
-
this.maxHeight = null;
|
|
140
|
-
} else {
|
|
141
|
-
this.maxHeight = this.#maxHeightNonTray;
|
|
33
|
+
:host([_close-radio]) {
|
|
34
|
+
animation: var(--d2l-dropdown-close-animation-name) ${dropdownDelay}ms ease-out;
|
|
35
|
+
animation-delay: 50ms;
|
|
142
36
|
}
|
|
143
37
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const menu = this.#getMenuElement();
|
|
148
|
-
if (menu.getMenuType() === 'menu-radio') {
|
|
149
|
-
const selected = menu.querySelector('[selected]');
|
|
150
|
-
if (selected !== null) {
|
|
151
|
-
setTimeout(() => selected.scrollIntoView({ block: 'nearest' }), 0);
|
|
38
|
+
@media (prefers-reduced-motion: reduce) {
|
|
39
|
+
:host([_close-radio]) {
|
|
40
|
+
animation: none !important;
|
|
152
41
|
}
|
|
153
42
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if (e.target !== this) return;
|
|
158
|
-
|
|
159
|
-
this.#initializingHeight = true;
|
|
160
|
-
this._closeRadio = false;
|
|
161
|
-
|
|
162
|
-
const menu = this.#getMenuElement();
|
|
163
|
-
menu.resize();
|
|
164
|
-
|
|
165
|
-
// If dropdown-menu is opened on first render, do not focus
|
|
166
|
-
if (this.#initiallyOpenedSuppressFocus) this.#initiallyOpenedSuppressFocus = false;
|
|
167
|
-
else menu.focus();
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
#handleSelect(e) {
|
|
171
|
-
if (['D2L-MENU-ITEM', 'D2L-MENU-ITEM-LINK', 'D2L-SELECTION-ACTION-MENU-ITEM', 'D2L-BUTTON-SPLIT-ITEM'].indexOf(e.target.tagName) < 0) {
|
|
172
|
-
return;
|
|
43
|
+
@keyframes d2l-dropdown-close-animation {
|
|
44
|
+
0% { opacity: 1; transform: translate(0, 0); }
|
|
45
|
+
100% { opacity: 0; transform: translate(0, -10px); }
|
|
173
46
|
}
|
|
174
|
-
this.close();
|
|
175
|
-
}
|
|
176
47
|
|
|
48
|
+
@keyframes d2l-dropdown-close-animation-dark {
|
|
49
|
+
0% { opacity: 0.9; transform: translate(0, 0); }
|
|
50
|
+
100% { opacity: 0; transform: translate(0, -10px); }
|
|
51
|
+
}
|
|
52
|
+
`];
|
|
177
53
|
}
|
|
178
|
-
customElements.define('d2l-dropdown-menu', DropdownMenu);
|
|
179
|
-
|
|
180
|
-
} else {
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* A container for a "d2l-menu". It provides additional support on top of "d2l-dropdown-content" for closing the menu when menu items are selected, resetting to the root of nested menus when reopening and automatic resizing when the menu resizes.
|
|
184
|
-
* @slot - Anything inside of "d2l-dropdown-content" that isn't in the "header" or "footer" slots appears as regular content
|
|
185
|
-
* @slot header - Sticky container at the top of the dropdown
|
|
186
|
-
* @slot footer - Sticky container at the bottom of the dropdown
|
|
187
|
-
* @fires d2l-dropdown-open - Dispatched when the dropdown is opened
|
|
188
|
-
*/
|
|
189
|
-
class DropdownMenu extends ThemeMixin(DropdownContentMixin(LitElement)) {
|
|
190
|
-
|
|
191
|
-
static get properties() {
|
|
192
|
-
return {
|
|
193
|
-
_closeRadio: {
|
|
194
|
-
type: Boolean,
|
|
195
|
-
reflect: true,
|
|
196
|
-
attribute: '_close-radio'
|
|
197
|
-
},
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
static get styles() {
|
|
202
|
-
return [
|
|
203
|
-
dropdownContentStyles,
|
|
204
|
-
css`
|
|
205
|
-
:host {
|
|
206
|
-
--d2l-dropdown-close-animation-name: d2l-dropdown-close-animation;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
:host([theme="dark"]) {
|
|
210
|
-
--d2l-dropdown-close-animation-name: d2l-dropdown-close-animation-dark;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
:host([_close-radio]) {
|
|
214
|
-
animation: var(--d2l-dropdown-close-animation-name) ${dropdownDelay}ms ease-out;
|
|
215
|
-
animation-delay: 50ms;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
@media (prefers-reduced-motion: reduce) {
|
|
219
|
-
:host([_close-radio]) {
|
|
220
|
-
animation: none !important;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
@keyframes d2l-dropdown-close-animation {
|
|
224
|
-
0% { opacity: 1; transform: translate(0, 0); }
|
|
225
|
-
100% { opacity: 0; transform: translate(0, -10px); }
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
@keyframes d2l-dropdown-close-animation-dark {
|
|
229
|
-
0% { opacity: 0.9; transform: translate(0, 0); }
|
|
230
|
-
100% { opacity: 0; transform: translate(0, -10px); }
|
|
231
|
-
}
|
|
232
|
-
`
|
|
233
|
-
];
|
|
234
|
-
}
|
|
235
54
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
this._closeRadio = false;
|
|
241
|
-
this._initiallyOpenedSuppressFocus = false;
|
|
242
|
-
this._maxHeightNonTray = this.maxHeight;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
firstUpdated(changedProperties) {
|
|
246
|
-
super.firstUpdated(changedProperties);
|
|
247
|
-
|
|
248
|
-
if (this.opened) this._initiallyOpenedSuppressFocus = true;
|
|
55
|
+
constructor() {
|
|
56
|
+
super();
|
|
57
|
+
this.noAutoFocus = true;
|
|
58
|
+
this.noPadding = true;
|
|
249
59
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
this.maxHeight = this._maxHeightNonTray;
|
|
255
|
-
}
|
|
60
|
+
this._closeRadio = false;
|
|
61
|
+
this.#initiallyOpenedSuppressFocus = false;
|
|
62
|
+
this.#maxHeightNonTray = this.maxHeight;
|
|
63
|
+
}
|
|
256
64
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
this.addEventListener('d2l-dropdown-close', this._onClose);
|
|
260
|
-
this.addEventListener('d2l-menu-resize', this._onMenuResize);
|
|
261
|
-
this.addEventListener('d2l-menu-item-select', this._onSelect);
|
|
262
|
-
this.addEventListener('d2l-selection-action-click', this._onSelect);
|
|
263
|
-
this.addEventListener('d2l-menu-item-change', this._onChange);
|
|
264
|
-
this.addEventListener('focus', this._onFocus);
|
|
265
|
-
}
|
|
65
|
+
firstUpdated(changedProperties) {
|
|
66
|
+
super.firstUpdated(changedProperties);
|
|
266
67
|
|
|
267
|
-
|
|
268
|
-
return this._renderContent();
|
|
269
|
-
}
|
|
68
|
+
if (this.opened) this.#initiallyOpenedSuppressFocus = true;
|
|
270
69
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
70
|
+
this.#maxHeightNonTray = this.maxHeight;
|
|
71
|
+
if (this._mobile && this.mobileTray) {
|
|
72
|
+
this.maxHeight = null;
|
|
73
|
+
} else {
|
|
74
|
+
this.maxHeight = this.#maxHeightNonTray;
|
|
275
75
|
}
|
|
276
76
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
77
|
+
this.addEventListener('animationend', this.#handleAnimationEnd);
|
|
78
|
+
this.addEventListener('d2l-dropdown-open', this.#handleOpen);
|
|
79
|
+
this.addEventListener('d2l-dropdown-close', this.#handleClose);
|
|
80
|
+
this.addEventListener('d2l-menu-resize', this.#handleMenuResize);
|
|
81
|
+
this.addEventListener('d2l-menu-item-select', this.#handleSelect);
|
|
82
|
+
this.addEventListener('d2l-selection-action-click', this.#handleSelect);
|
|
83
|
+
this.addEventListener('d2l-menu-item-change', this.#handleChange);
|
|
84
|
+
this.addEventListener('focus', this.#handleFocus);
|
|
85
|
+
}
|
|
282
86
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
}
|
|
87
|
+
#initializingHeight;
|
|
88
|
+
#initiallyOpenedSuppressFocus;
|
|
89
|
+
#maxHeightNonTray;
|
|
287
90
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
} else {
|
|
294
|
-
this._closeRadio = true;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
91
|
+
#getMenuElement() {
|
|
92
|
+
return this.shadowRoot?.querySelector('.dropdown-content > slot')
|
|
93
|
+
.assignedNodes()
|
|
94
|
+
.filter(node => node.hasAttribute && (node.getAttribute('role') === 'menu' || node.getAttribute('role') === 'listbox'))[0];
|
|
95
|
+
}
|
|
297
96
|
|
|
298
|
-
|
|
97
|
+
#handleAnimationEnd() {
|
|
98
|
+
if (!this._closeRadio) return;
|
|
99
|
+
this._closeRadio = false;
|
|
100
|
+
this.close();
|
|
101
|
+
}
|
|
299
102
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
103
|
+
#handleChange(e) {
|
|
104
|
+
if (e.target.getAttribute('role') !== 'menuitemradio') return;
|
|
303
105
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
106
|
+
if (reduceMotion) {
|
|
107
|
+
// Don't trigger the animation but still wait before closing the dropdown
|
|
108
|
+
setTimeout(() => {
|
|
109
|
+
this.close();
|
|
110
|
+
}, dropdownDelay);
|
|
111
|
+
} else {
|
|
112
|
+
this._closeRadio = true;
|
|
308
113
|
}
|
|
114
|
+
}
|
|
309
115
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
// such as the mobile tray close button, as to not move focus
|
|
313
|
-
if (e.srcElement === this) return;
|
|
314
|
-
this.__getMenuElement().focus();
|
|
315
|
-
}
|
|
116
|
+
#handleClose(e) {
|
|
117
|
+
if (e.target !== this) return;
|
|
316
118
|
|
|
317
|
-
|
|
119
|
+
// reset to root view
|
|
120
|
+
const menu = this.#getMenuElement();
|
|
121
|
+
menu.show({ preventFocus: true });
|
|
122
|
+
menu.resetFocusables();
|
|
123
|
+
}
|
|
318
124
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
125
|
+
#handleFocus(e) {
|
|
126
|
+
// ignore focus events originating from inside dropdown content,
|
|
127
|
+
// such as the mobile tray close button, as to not move focus
|
|
128
|
+
if (e.srcElement === this) return;
|
|
129
|
+
this.#getMenuElement().focus();
|
|
130
|
+
}
|
|
324
131
|
|
|
325
|
-
|
|
326
|
-
this._initializingHeight = false;
|
|
132
|
+
#handleMenuResize(e) {
|
|
327
133
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
setTimeout(() => selected.scrollIntoView({ block: 'nearest' }), 0);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
134
|
+
if (this._mobile && this.mobileTray) {
|
|
135
|
+
this.maxHeight = null;
|
|
136
|
+
} else {
|
|
137
|
+
this.maxHeight = this.#maxHeightNonTray;
|
|
335
138
|
}
|
|
336
139
|
|
|
337
|
-
|
|
140
|
+
this.position(e.detail, { updateLocation: this.#initializingHeight });
|
|
141
|
+
this.#initializingHeight = false;
|
|
338
142
|
|
|
339
|
-
|
|
340
|
-
|
|
143
|
+
const menu = this.#getMenuElement();
|
|
144
|
+
if (menu.getMenuType() === 'menu-radio') {
|
|
145
|
+
const selected = menu.querySelector('[selected]');
|
|
146
|
+
if (selected !== null) {
|
|
147
|
+
setTimeout(() => selected.scrollIntoView({ block: 'nearest' }), 0);
|
|
341
148
|
}
|
|
342
|
-
|
|
343
|
-
|
|
149
|
+
}
|
|
150
|
+
}
|
|
344
151
|
|
|
345
|
-
|
|
152
|
+
#handleOpen(e) {
|
|
153
|
+
if (e.target !== this) return;
|
|
346
154
|
|
|
347
|
-
|
|
155
|
+
this.#initializingHeight = true;
|
|
156
|
+
this._closeRadio = false;
|
|
348
157
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
else menu.focus();
|
|
352
|
-
}
|
|
158
|
+
const menu = this.#getMenuElement();
|
|
159
|
+
menu.resize();
|
|
353
160
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
this.close();
|
|
359
|
-
}
|
|
161
|
+
// If dropdown-menu is opened on first render, do not focus
|
|
162
|
+
if (this.#initiallyOpenedSuppressFocus) this.#initiallyOpenedSuppressFocus = false;
|
|
163
|
+
else menu.focus();
|
|
164
|
+
}
|
|
360
165
|
|
|
166
|
+
#handleSelect(e) {
|
|
167
|
+
if (['D2L-MENU-ITEM', 'D2L-MENU-ITEM-LINK', 'D2L-SELECTION-ACTION-MENU-ITEM', 'D2L-BUTTON-SPLIT-ITEM'].indexOf(e.target.tagName) < 0) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
this.close();
|
|
361
171
|
}
|
|
362
|
-
customElements.define('d2l-dropdown-menu', DropdownMenu);
|
|
363
172
|
|
|
364
173
|
}
|
|
174
|
+
customElements.define('d2l-dropdown-menu', DropdownMenu);
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
import { getUniqueId } from '../../helpers/uniqueId.js';
|
|
2
2
|
import { isComposedAncestor } from '../../helpers/dom.js';
|
|
3
|
-
import { usePopoverMixin } from './dropdown-popover-mixin.js';
|
|
4
|
-
|
|
5
|
-
const intersectionObserver = new IntersectionObserver(entries => {
|
|
6
|
-
entries.forEach(entry => {
|
|
7
|
-
entry.target.__updateContentVisibility(entry.isIntersecting);
|
|
8
|
-
});
|
|
9
|
-
}, { threshold: 0 }); // 0-1 (0 -> intersection requires any pixel visible, 1 -> intersection requires all pixels visible)
|
|
10
3
|
|
|
11
4
|
export const DropdownOpenerMixin = superclass => class extends superclass {
|
|
12
5
|
|
|
@@ -85,9 +78,6 @@ export const DropdownOpenerMixin = superclass => class extends superclass {
|
|
|
85
78
|
this.addEventListener('mouseenter', this.__onMouseEnter);
|
|
86
79
|
this.addEventListener('mouseleave', this.__onMouseLeave);
|
|
87
80
|
|
|
88
|
-
if (this.dropdownOpened) {
|
|
89
|
-
intersectionObserver.observe(this);
|
|
90
|
-
}
|
|
91
81
|
if (this.openOnHover) {
|
|
92
82
|
document.body.addEventListener('mouseup', this._onOutsideClick);
|
|
93
83
|
}
|
|
@@ -101,8 +91,6 @@ export const DropdownOpenerMixin = superclass => class extends superclass {
|
|
|
101
91
|
this.removeEventListener('mouseenter', this.__onMouseEnter);
|
|
102
92
|
this.removeEventListener('mouseleave', this.__onMouseLeave);
|
|
103
93
|
|
|
104
|
-
intersectionObserver.unobserve(this);
|
|
105
|
-
|
|
106
94
|
if (this.openOnHover) {
|
|
107
95
|
document.body.removeEventListener('mouseup', this._onOutsideClick);
|
|
108
96
|
}
|
|
@@ -195,8 +183,6 @@ export const DropdownOpenerMixin = superclass => class extends superclass {
|
|
|
195
183
|
}
|
|
196
184
|
|
|
197
185
|
__onClosed() {
|
|
198
|
-
intersectionObserver.unobserve(this);
|
|
199
|
-
|
|
200
186
|
if (!this._setOpenerElementAttribute(false, true)) return;
|
|
201
187
|
this.dropdownOpened = false;
|
|
202
188
|
this._isOpenedViaClick = false;
|
|
@@ -231,8 +217,7 @@ export const DropdownOpenerMixin = superclass => class extends superclass {
|
|
|
231
217
|
// do not respond to hover events on mobile screens
|
|
232
218
|
const dropdownContent = this.__getContentElement();
|
|
233
219
|
|
|
234
|
-
if (
|
|
235
|
-
else if (!usePopoverMixin && dropdownContent._useMobileStyling) return; // Flag cleanup: GAUD-7472-dropdown-popover
|
|
220
|
+
if (dropdownContent._mobile) return;
|
|
236
221
|
|
|
237
222
|
clearTimeout(this._dismissTimerId);
|
|
238
223
|
if (!this.dropdownOpened) await this.openDropdown(false);
|
|
@@ -245,8 +230,7 @@ export const DropdownOpenerMixin = superclass => class extends superclass {
|
|
|
245
230
|
// do not respond to hover events on mobile screens
|
|
246
231
|
const dropdownContent = this.__getContentElement();
|
|
247
232
|
|
|
248
|
-
if (
|
|
249
|
-
else if (!usePopoverMixin && dropdownContent._useMobileStyling) return; // Flag cleanup: GAUD-7472-dropdown-popover
|
|
233
|
+
if (dropdownContent._mobile) return;
|
|
250
234
|
|
|
251
235
|
this._isHovering = false;
|
|
252
236
|
if (this._isOpenedViaClick) return;
|
|
@@ -266,8 +250,6 @@ export const DropdownOpenerMixin = superclass => class extends superclass {
|
|
|
266
250
|
__onOpened() {
|
|
267
251
|
if (!this._setOpenerElementAttribute(true, true)) return;
|
|
268
252
|
this._isFading = false;
|
|
269
|
-
|
|
270
|
-
intersectionObserver.observe(this);
|
|
271
253
|
}
|
|
272
254
|
|
|
273
255
|
__onOpenerMouseUp(e) {
|
|
@@ -291,12 +273,6 @@ export const DropdownOpenerMixin = superclass => class extends superclass {
|
|
|
291
273
|
}
|
|
292
274
|
}
|
|
293
275
|
|
|
294
|
-
__updateContentVisibility(visible) {
|
|
295
|
-
if (!usePopoverMixin) {
|
|
296
|
-
this.__getContentElement().offscreen = !visible; // Flag cleanup: GAUD-7472-dropdown-popover
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
276
|
/* used by open-on-hover option */
|
|
301
277
|
_closeTimerStart() {
|
|
302
278
|
if (this.dropdownOpened) return;
|
|
@@ -322,9 +298,8 @@ export const DropdownOpenerMixin = superclass => class extends superclass {
|
|
|
322
298
|
const isWithinDropdown = isComposedAncestor(dropdownContent, e.composedPath()[0]);
|
|
323
299
|
const isWithinOpener = isComposedAncestor(this.getOpenerElement(), e.composedPath()[0]);
|
|
324
300
|
|
|
325
|
-
// Flag cleanup: GAUD-7472-dropdown-popover
|
|
326
301
|
const isBackdropClick = isWithinDropdown
|
|
327
|
-
&&
|
|
302
|
+
&& dropdownContent._mobile
|
|
328
303
|
&& e.composedPath().find(node => node.nodeName === 'D2L-BACKDROP');
|
|
329
304
|
|
|
330
305
|
if (!isWithinOpener && (!isWithinDropdown || isBackdropClick)) {
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
+
import '../button/button.js';
|
|
2
|
+
import '../../helpers/visualReady.js';
|
|
1
3
|
import { css, html } from 'lit';
|
|
2
4
|
import { classMap } from 'lit/directives/class-map.js';
|
|
3
5
|
import { findComposedAncestor } from '../../helpers/dom.js';
|
|
4
|
-
import { getFlag } from '../../helpers/flags.js';
|
|
5
6
|
import { LocalizeCoreElement } from '../../helpers/localize-core-element.js';
|
|
6
7
|
import { PopoverMixin } from '../popover/popover-mixin.js';
|
|
7
8
|
import { styleMap } from 'lit/directives/style-map.js';
|
|
8
9
|
|
|
9
|
-
export const usePopoverMixin = getFlag('GAUD-7472-dropdown-popover', true);
|
|
10
|
-
|
|
11
10
|
export const DropdownPopoverMixin = superclass => class extends LocalizeCoreElement(PopoverMixin(superclass)) {
|
|
12
11
|
|
|
13
12
|
static get properties() {
|
|
@@ -276,10 +275,6 @@ export const DropdownPopoverMixin = superclass => class extends LocalizeCoreElem
|
|
|
276
275
|
super.open(opener, applyFocus);
|
|
277
276
|
}
|
|
278
277
|
|
|
279
|
-
// todo: remove this method when removing GAUD-7472-dropdown-popover flag (d2l-filter calls this)
|
|
280
|
-
requestRepositionNextResize() {
|
|
281
|
-
}
|
|
282
|
-
|
|
283
278
|
/**
|
|
284
279
|
* Private.
|
|
285
280
|
*/
|