@brightspace-ui/core 3.88.3 → 3.89.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,6 +5,13 @@
5
5
  <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
6
6
  <meta charset="UTF-8">
7
7
  <link rel="stylesheet" href="../../demo/styles.css" type="text/css">
8
+ <script>
9
+ const urlParams = new URLSearchParams(window.location.search);
10
+ window.D2L = { LP: { Web: { UI: { Flags: { Flag: (key) => {
11
+ if (key === 'GAUD-7472-dropdown-popover') return (urlParams.get('popover') === 'true');
12
+ return false;
13
+ } } } } } };
14
+ </script>
8
15
  <script type="module">
9
16
  import '../../demo/demo-page.js';
10
17
  import '../../menu/menu.js';
@@ -5,6 +5,13 @@
5
5
  <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
6
6
  <meta charset="UTF-8">
7
7
  <link rel="stylesheet" href="../../demo/styles.css" type="text/css">
8
+ <script>
9
+ const urlParams = new URLSearchParams(window.location.search);
10
+ window.D2L = { LP: { Web: { UI: { Flags: { Flag: (key) => {
11
+ if (key === 'GAUD-7472-dropdown-popover') return (urlParams.get('popover') === 'true');
12
+ return false;
13
+ } } } } } };
14
+ </script>
8
15
  <script type="module">
9
16
  import '../../demo/demo-page.js';
10
17
  import '../../tabs/tabs.js';
@@ -1,10 +1,16 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
-
4
3
  <head>
5
4
  <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
6
5
  <meta charset="UTF-8">
7
6
  <link rel="stylesheet" href="../../demo/styles.css" type="text/css">
7
+ <script>
8
+ const urlParams = new URLSearchParams(window.location.search);
9
+ window.D2L = { LP: { Web: { UI: { Flags: { Flag: (key) => {
10
+ if (key === 'GAUD-7472-dropdown-popover') return (urlParams.get('popover') === 'true');
11
+ return false;
12
+ } } } } } };
13
+ </script>
8
14
  <script type="module">
9
15
  import '../../demo/demo-page.js';
10
16
  import '../../button/button.js';
@@ -12,7 +18,6 @@
12
18
  import '../dropdown-content.js';
13
19
  </script>
14
20
  </head>
15
-
16
21
  <body unresolved>
17
22
 
18
23
  <d2l-demo-page page-title="d2l-dropdown">
@@ -1,23 +1,40 @@
1
+ import { DropdownPopoverMixin, usePopoverMixin } from './dropdown-popover-mixin.js';
1
2
  import { DropdownContentMixin } from './dropdown-content-mixin.js';
2
3
  import { dropdownContentStyles } from './dropdown-content-styles.js';
3
4
  import { LitElement } from 'lit';
4
5
 
5
- /**
6
- * A generic container for dropdown content. It provides behavior such as sizing, positioning, and managing focus gain/loss.
7
- * @slot - Anything inside of "d2l-dropdown-content" that isn't in the "header" or "footer" slots appears as regular content
8
- * @slot header - Sticky container at the top of the dropdown
9
- * @slot footer - Sticky container at the bottom of the dropdown
10
- * @fires d2l-dropdown-open - Dispatched when the dropdown is opened
11
- */
12
- class DropdownContent extends DropdownContentMixin(LitElement) {
13
-
14
- static get styles() {
15
- return dropdownContentStyles;
16
- }
6
+ if (usePopoverMixin) {
7
+
8
+ /**
9
+ * A generic container for dropdown content. It provides behavior such as sizing, positioning, and managing focus gain/loss.
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 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
+ }
17
36
 
18
- render() {
19
- return this._renderContent();
20
37
  }
38
+ customElements.define('d2l-dropdown-content', DropdownContent);
21
39
 
22
40
  }
23
- customElements.define('d2l-dropdown-content', DropdownContent);
@@ -1,33 +1,31 @@
1
1
  import { css, LitElement } from 'lit';
2
+ import { DropdownPopoverMixin, usePopoverMixin } from './dropdown-popover-mixin.js';
2
3
  import { DropdownContentMixin } from './dropdown-content-mixin.js';
3
4
  import { dropdownContentStyles } from './dropdown-content-styles.js';
4
5
  import { ThemeMixin } from '../../mixins/theme/theme-mixin.js';
5
6
 
6
7
  const reduceMotion = matchMedia('(prefers-reduced-motion: reduce)').matches;
7
8
  const dropdownDelay = 300;
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(DropdownContentMixin(LitElement)) {
16
-
17
- static get properties() {
18
- return {
19
- _closeRadio: {
20
- type: Boolean,
21
- reflect: true,
22
- attribute: '_close-radio'
23
- },
24
- };
25
- }
26
9
 
27
- static get styles() {
28
- return [
29
- dropdownContentStyles,
30
- css`
10
+ if (usePopoverMixin) {
11
+
12
+ /**
13
+ * 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.
14
+ * @slot - Anything inside of "d2l-dropdown-content" that isn't in the "header" or "footer" slots appears as regular content
15
+ * @slot header - Sticky container at the top of the dropdown
16
+ * @slot footer - Sticky container at the bottom of the dropdown
17
+ * @fires d2l-dropdown-open - Dispatched when the dropdown is opened
18
+ */
19
+ class DropdownMenu extends ThemeMixin(DropdownPopoverMixin(LitElement)) {
20
+
21
+ static get properties() {
22
+ return {
23
+ _closeRadio: { type: Boolean, reflect: true, attribute: '_close-radio' },
24
+ };
25
+ }
26
+
27
+ static get styles() {
28
+ return [super.styles, css`
31
29
  :host {
32
30
  --d2l-dropdown-close-animation-name: d2l-dropdown-close-animation;
33
31
  }
@@ -55,134 +53,311 @@ class DropdownMenu extends ThemeMixin(DropdownContentMixin(LitElement)) {
55
53
  0% { opacity: 0.9; transform: translate(0, 0); }
56
54
  100% { opacity: 0; transform: translate(0, -10px); }
57
55
  }
58
- `
59
- ];
60
- }
56
+ `];
57
+ }
61
58
 
62
- constructor() {
63
- super();
64
- this.noAutoFocus = true;
65
- this.noPadding = true;
66
- this._closeRadio = false;
67
- this._initiallyOpenedSuppressFocus = false;
68
- this._maxHeightNonTray = this.maxHeight;
69
- }
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
+ }
70
68
 
71
- firstUpdated(changedProperties) {
72
- super.firstUpdated(changedProperties);
69
+ firstUpdated(changedProperties) {
70
+ super.firstUpdated(changedProperties);
73
71
 
74
- if (this.opened) this._initiallyOpenedSuppressFocus = true;
72
+ if (this.opened) this.#initiallyOpenedSuppressFocus = true;
73
+
74
+ this.#maxHeightNonTray = this.maxHeight;
75
+ if (this._mobile && this.mobileTray) {
76
+ this.maxHeight = null;
77
+ } else {
78
+ this.maxHeight = this.#maxHeightNonTray;
79
+ }
75
80
 
76
- this._maxHeightNonTray = this.maxHeight;
77
- if (this._useMobileStyling && this.mobileTray) {
78
- this.maxHeight = null;
79
- } else {
80
- this.maxHeight = this._maxHeightNonTray;
81
+ this.addEventListener('animationend', this.#handleAnimationEnd);
82
+ this.addEventListener('d2l-dropdown-open', this.#handleOpen);
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);
81
89
  }
82
90
 
83
- this.addEventListener('animationend', this._onAnimationEnd);
84
- this.addEventListener('d2l-dropdown-open', this._onOpen);
85
- this.addEventListener('d2l-dropdown-close', this._onClose);
86
- this.addEventListener('d2l-menu-resize', this._onMenuResize);
87
- this.addEventListener('d2l-menu-item-select', this._onSelect);
88
- this.addEventListener('d2l-selection-action-click', this._onSelect);
89
- this.addEventListener('d2l-menu-item-change', this._onChange);
90
- this.addEventListener('focus', this._onFocus);
91
- }
91
+ #initializingHeight;
92
+ #initiallyOpenedSuppressFocus;
93
+ #maxHeightNonTray;
92
94
 
93
- render() {
94
- return this._renderContent();
95
- }
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
+ }
96
100
 
97
- __getMenuElement() {
98
- if (!this.shadowRoot) return undefined;
99
- return this.shadowRoot.querySelector('.d2l-dropdown-content-slot')
100
- .assignedNodes().filter(node => node.hasAttribute
101
- && (node.getAttribute('role') === 'menu' || node.getAttribute('role') === 'listbox'))[0];
102
- }
101
+ #handleAnimationEnd() {
102
+ if (!this._closeRadio) return;
103
+ this._closeRadio = false;
104
+ this.close();
105
+ }
103
106
 
104
- _onAnimationEnd() {
105
- if (!this._closeRadio) return;
106
- this._closeRadio = false;
107
- this.close();
108
- }
107
+ #handleChange(e) {
108
+ if (e.target.getAttribute('role') !== 'menuitemradio') return;
109
109
 
110
- _onChange(e) {
111
- if (e.target.getAttribute('role') !== 'menuitemradio') {
112
- return;
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;
117
+ }
113
118
  }
114
119
 
115
- if (reduceMotion) {
116
- // Don't trigger the animation but still wait before closing the dropdown
117
- setTimeout(() => {
118
- this.close();
119
- }, dropdownDelay);
120
- } else {
121
- this._closeRadio = true;
120
+ #handleClose(e) {
121
+ if (e.target !== this) return;
122
+
123
+ // reset to root view
124
+ const menu = this.#getMenuElement();
125
+ menu.show({ preventFocus: true });
122
126
  }
123
- }
124
127
 
125
- _onClose(e) {
128
+ #handleFocus(e) {
129
+ // ignore focus events originating from inside dropdown content,
130
+ // such as the mobile tray close button, as to not move focus
131
+ if (e.srcElement === this) return;
132
+ this.#getMenuElement().focus();
133
+ }
134
+
135
+ #handleMenuResize(e) {
136
+
137
+ if (this._mobile && this.mobileTray) {
138
+ this.maxHeight = null;
139
+ } else {
140
+ this.maxHeight = this.#maxHeightNonTray;
141
+ }
126
142
 
127
- if (e.target !== this) {
128
- return;
143
+ this.position(e.detail, { updateLocation: this.#initializingHeight });
144
+ this.#initializingHeight = false;
145
+
146
+ const menu = this.#getMenuElement();
147
+ if (menu.getMenuType() === 'menu-radio') {
148
+ const selected = menu.querySelector('[selected]');
149
+ if (selected !== null) {
150
+ setTimeout(() => selected.scrollIntoView({ block: 'nearest' }), 0);
151
+ }
152
+ }
129
153
  }
130
154
 
131
- // reset to root view
132
- const menu = this.__getMenuElement();
133
- menu.show({ preventFocus: true });
134
- }
155
+ #handleOpen(e) {
156
+ if (e.target !== this) return;
157
+
158
+ this.#initializingHeight = true;
159
+ this._closeRadio = false;
160
+
161
+ const menu = this.#getMenuElement();
162
+ menu.resize();
163
+
164
+ // If dropdown-menu is opened on first render, do not focus
165
+ if (this.#initiallyOpenedSuppressFocus) this.#initiallyOpenedSuppressFocus = false;
166
+ else menu.focus();
167
+ }
168
+
169
+ #handleSelect(e) {
170
+ if (['D2L-MENU-ITEM', 'D2L-MENU-ITEM-LINK', 'D2L-SELECTION-ACTION-MENU-ITEM'].indexOf(e.target.tagName) < 0) {
171
+ return;
172
+ }
173
+ this.close();
174
+ }
135
175
 
136
- _onFocus(e) {
137
- // ignore focus events originating from inside dropdown content,
138
- // such as the mobile tray close button, as to not move focus
139
- if (e.srcElement === this) return;
140
- this.__getMenuElement().focus();
141
176
  }
177
+ customElements.define('d2l-dropdown-menu', DropdownMenu);
178
+
179
+ } else {
180
+
181
+ /**
182
+ * 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.
183
+ * @slot - Anything inside of "d2l-dropdown-content" that isn't in the "header" or "footer" slots appears as regular content
184
+ * @slot header - Sticky container at the top of the dropdown
185
+ * @slot footer - Sticky container at the bottom of the dropdown
186
+ * @fires d2l-dropdown-open - Dispatched when the dropdown is opened
187
+ */
188
+ class DropdownMenu extends ThemeMixin(DropdownContentMixin(LitElement)) {
189
+
190
+ static get properties() {
191
+ return {
192
+ _closeRadio: {
193
+ type: Boolean,
194
+ reflect: true,
195
+ attribute: '_close-radio'
196
+ },
197
+ };
198
+ }
199
+
200
+ static get styles() {
201
+ return [
202
+ dropdownContentStyles,
203
+ css`
204
+ :host {
205
+ --d2l-dropdown-close-animation-name: d2l-dropdown-close-animation;
206
+ }
207
+
208
+ :host([theme="dark"]) {
209
+ --d2l-dropdown-close-animation-name: d2l-dropdown-close-animation-dark;
210
+ }
211
+
212
+ :host([_close-radio]) {
213
+ animation: var(--d2l-dropdown-close-animation-name) ${dropdownDelay}ms ease-out;
214
+ animation-delay: 50ms;
215
+ }
216
+
217
+ @media (prefers-reduced-motion: reduce) {
218
+ :host([_close-radio]) {
219
+ animation: none !important;
220
+ }
221
+ }
222
+ @keyframes d2l-dropdown-close-animation {
223
+ 0% { opacity: 1; transform: translate(0, 0); }
224
+ 100% { opacity: 0; transform: translate(0, -10px); }
225
+ }
142
226
 
143
- _onMenuResize(e) {
227
+ @keyframes d2l-dropdown-close-animation-dark {
228
+ 0% { opacity: 0.9; transform: translate(0, 0); }
229
+ 100% { opacity: 0; transform: translate(0, -10px); }
230
+ }
231
+ `
232
+ ];
233
+ }
144
234
 
145
- if (this._useMobileStyling && this.mobileTray) {
146
- this.maxHeight = null;
147
- } else {
148
- this.maxHeight = this._maxHeightNonTray;
235
+ constructor() {
236
+ super();
237
+ this.noAutoFocus = true;
238
+ this.noPadding = true;
239
+ this._closeRadio = false;
240
+ this._initiallyOpenedSuppressFocus = false;
241
+ this._maxHeightNonTray = this.maxHeight;
149
242
  }
150
243
 
151
- this.__position(e.detail, { updateAboveBelow: this._initializingHeight });
152
- this._initializingHeight = false;
244
+ firstUpdated(changedProperties) {
245
+ super.firstUpdated(changedProperties);
246
+
247
+ if (this.opened) this._initiallyOpenedSuppressFocus = true;
153
248
 
154
- const menu = this.__getMenuElement();
155
- if (menu.getMenuType() === 'menu-radio') {
156
- const selected = menu.querySelector('[selected]');
157
- if (selected !== null) {
158
- setTimeout(() => selected.scrollIntoView({ block: 'nearest' }), 0);
249
+ this._maxHeightNonTray = this.maxHeight;
250
+ if (this._useMobileStyling && this.mobileTray) {
251
+ this.maxHeight = null;
252
+ } else {
253
+ this.maxHeight = this._maxHeightNonTray;
159
254
  }
255
+
256
+ this.addEventListener('animationend', this._onAnimationEnd);
257
+ this.addEventListener('d2l-dropdown-open', this._onOpen);
258
+ this.addEventListener('d2l-dropdown-close', this._onClose);
259
+ this.addEventListener('d2l-menu-resize', this._onMenuResize);
260
+ this.addEventListener('d2l-menu-item-select', this._onSelect);
261
+ this.addEventListener('d2l-selection-action-click', this._onSelect);
262
+ this.addEventListener('d2l-menu-item-change', this._onChange);
263
+ this.addEventListener('focus', this._onFocus);
160
264
  }
161
- }
162
265
 
163
- _onOpen(e) {
266
+ render() {
267
+ return this._renderContent();
268
+ }
164
269
 
165
- if (e.target !== this) {
166
- return;
270
+ __getMenuElement() {
271
+ if (!this.shadowRoot) return undefined;
272
+ return this.shadowRoot.querySelector('.d2l-dropdown-content-slot')
273
+ .assignedNodes().filter(node => node.hasAttribute
274
+ && (node.getAttribute('role') === 'menu' || node.getAttribute('role') === 'listbox'))[0];
167
275
  }
168
- this._initializingHeight = true;
169
- this._closeRadio = false;
170
276
 
171
- const menu = this.__getMenuElement();
277
+ _onAnimationEnd() {
278
+ if (!this._closeRadio) return;
279
+ this._closeRadio = false;
280
+ this.close();
281
+ }
172
282
 
173
- menu.resize();
283
+ _onChange(e) {
284
+ if (e.target.getAttribute('role') !== 'menuitemradio') {
285
+ return;
286
+ }
174
287
 
175
- // If dropdown-menu is opened on first render, do not focus
176
- if (this._initiallyOpenedSuppressFocus) this._initiallyOpenedSuppressFocus = false;
177
- else menu.focus();
178
- }
288
+ if (reduceMotion) {
289
+ // Don't trigger the animation but still wait before closing the dropdown
290
+ setTimeout(() => {
291
+ this.close();
292
+ }, dropdownDelay);
293
+ } else {
294
+ this._closeRadio = true;
295
+ }
296
+ }
297
+
298
+ _onClose(e) {
299
+
300
+ if (e.target !== this) {
301
+ return;
302
+ }
303
+
304
+ // reset to root view
305
+ const menu = this.__getMenuElement();
306
+ menu.show({ preventFocus: true });
307
+ }
308
+
309
+ _onFocus(e) {
310
+ // ignore focus events originating from inside dropdown content,
311
+ // such as the mobile tray close button, as to not move focus
312
+ if (e.srcElement === this) return;
313
+ this.__getMenuElement().focus();
314
+ }
315
+
316
+ _onMenuResize(e) {
317
+
318
+ if (this._useMobileStyling && this.mobileTray) {
319
+ this.maxHeight = null;
320
+ } else {
321
+ this.maxHeight = this._maxHeightNonTray;
322
+ }
323
+
324
+ this.__position(e.detail, { updateAboveBelow: this._initializingHeight });
325
+ this._initializingHeight = false;
326
+
327
+ const menu = this.__getMenuElement();
328
+ if (menu.getMenuType() === 'menu-radio') {
329
+ const selected = menu.querySelector('[selected]');
330
+ if (selected !== null) {
331
+ setTimeout(() => selected.scrollIntoView({ block: 'nearest' }), 0);
332
+ }
333
+ }
334
+ }
335
+
336
+ _onOpen(e) {
337
+
338
+ if (e.target !== this) {
339
+ return;
340
+ }
341
+ this._initializingHeight = true;
342
+ this._closeRadio = false;
343
+
344
+ const menu = this.__getMenuElement();
179
345
 
180
- _onSelect(e) {
181
- if (['D2L-MENU-ITEM', 'D2L-MENU-ITEM-LINK', 'D2L-SELECTION-ACTION-MENU-ITEM'].indexOf(e.target.tagName) < 0) {
182
- return;
346
+ menu.resize();
347
+
348
+ // If dropdown-menu is opened on first render, do not focus
349
+ if (this._initiallyOpenedSuppressFocus) this._initiallyOpenedSuppressFocus = false;
350
+ else menu.focus();
183
351
  }
184
- this.close();
352
+
353
+ _onSelect(e) {
354
+ if (['D2L-MENU-ITEM', 'D2L-MENU-ITEM-LINK', 'D2L-SELECTION-ACTION-MENU-ITEM'].indexOf(e.target.tagName) < 0) {
355
+ return;
356
+ }
357
+ this.close();
358
+ }
359
+
185
360
  }
361
+ customElements.define('d2l-dropdown-menu', DropdownMenu);
186
362
 
187
363
  }
188
- customElements.define('d2l-dropdown-menu', DropdownMenu);
@@ -1,5 +1,6 @@
1
1
  import { getUniqueId } from '../../helpers/uniqueId.js';
2
2
  import { isComposedAncestor } from '../../helpers/dom.js';
3
+ import { usePopoverMixin } from './dropdown-popover-mixin.js';
3
4
 
4
5
  const intersectionObserver = new IntersectionObserver(entries => {
5
6
  entries.forEach(entry => {
@@ -260,7 +261,10 @@ export const DropdownOpenerMixin = superclass => class extends superclass {
260
261
  if (!this.openOnHover) return;
261
262
  // do not respond to hover events on mobile screens
262
263
  const dropdownContent = this.__getContentElement();
263
- if (dropdownContent._useMobileStyling) return;
264
+
265
+ if (usePopoverMixin && dropdownContent._mobile) return;
266
+ else if (!usePopoverMixin && dropdownContent._useMobileStyling) return; // Flag cleanup: GAUD-7472-dropdown-popover
267
+
264
268
  clearTimeout(this._dismissTimerId);
265
269
  if (!this.dropdownOpened) await this.openDropdown(false);
266
270
  this._closeTimerStop();
@@ -271,7 +275,10 @@ export const DropdownOpenerMixin = superclass => class extends superclass {
271
275
  if (!this.openOnHover) return;
272
276
  // do not respond to hover events on mobile screens
273
277
  const dropdownContent = this.__getContentElement();
274
- if (dropdownContent._useMobileStyling) return;
278
+
279
+ if (usePopoverMixin && dropdownContent._mobile) return;
280
+ else if (!usePopoverMixin && dropdownContent._useMobileStyling) return; // Flag cleanup: GAUD-7472-dropdown-popover
281
+
275
282
  this._isHovering = false;
276
283
  if (this._isOpenedViaClick) return;
277
284
  //Wait before closing so we don't lose hover when we jump from opener to card
@@ -317,11 +324,15 @@ export const DropdownOpenerMixin = superclass => class extends superclass {
317
324
  this._isHovering = false;
318
325
  this.openDropdown(false);
319
326
  }
320
- } else this.toggleOpen(true);
327
+ } else {
328
+ this.toggleOpen(true);
329
+ }
321
330
  }
322
331
 
323
332
  __updateContentVisibility(visible) {
324
- this.__getContentElement().offscreen = !visible;
333
+ if (!usePopoverMixin) {
334
+ this.__getContentElement().offscreen = !visible; // Flag cleanup: GAUD-7472-dropdown-popover
335
+ }
325
336
  }
326
337
 
327
338
  /* used by open-on-hover option */
@@ -345,11 +356,15 @@ export const DropdownOpenerMixin = superclass => class extends superclass {
345
356
  /* used by open-on-hover option */
346
357
  _onOutsideClick(e) {
347
358
  if (!this.dropdownOpened) return;
348
- const isWithinDropdown = isComposedAncestor(this.__getContentElement(), e.composedPath()[0]);
359
+ const dropdownContent = this.__getContentElement();
360
+ const isWithinDropdown = isComposedAncestor(dropdownContent, e.composedPath()[0]);
349
361
  const isWithinOpener = isComposedAncestor(this.getOpenerElement(), e.composedPath()[0]);
362
+
363
+ // Flag cleanup: GAUD-7472-dropdown-popover
350
364
  const isBackdropClick = isWithinDropdown
351
- && this.__getContentElement()._useMobileStyling
365
+ && ((!usePopoverMixin && dropdownContent._useMobileStyling) || (usePopoverMixin && dropdownContent._mobile))
352
366
  && e.composedPath().find(node => node.nodeName === 'D2L-BACKDROP');
367
+
353
368
  if (!isWithinOpener && (!isWithinDropdown || isBackdropClick)) {
354
369
  this.closeDropdown();
355
370
  }