@momentum-design/components 0.83.2 → 0.83.4
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/dist/browser/index.js +179 -179
- package/dist/browser/index.js.map +4 -4
- package/dist/components/dialog/dialog.component.d.ts +22 -12
- package/dist/components/dialog/dialog.component.js +47 -25
- package/dist/components/dialog/dialog.events.d.ts +9 -1
- package/dist/components/dialog/dialog.events.js +12 -2
- package/dist/components/dialog/dialog.types.d.ts +1 -0
- package/dist/components/popover/popover.component.d.ts +6 -7
- package/dist/components/popover/popover.component.js +45 -23
- package/dist/components/tooltip/tooltip.component.js +1 -1
- package/dist/custom-elements.json +1958 -1818
- package/dist/react/dialog/index.d.ts +8 -0
- package/dist/react/dialog/index.js +8 -0
- package/dist/react/index.d.ts +5 -5
- package/dist/react/index.js +5 -5
- package/dist/utils/mixins/FocusTrapMixin.d.ts +2 -2
- package/dist/utils/mixins/FocusTrapMixin.js +70 -35
- package/dist/utils/mixins/PreventScrollMixin.d.ts +9 -0
- package/dist/utils/mixins/PreventScrollMixin.js +32 -0
- package/package.json +1 -1
@@ -1,7 +1,7 @@
|
|
1
1
|
import { CSSResult, PropertyValues } from 'lit';
|
2
2
|
import { Component } from '../../models';
|
3
3
|
import type { DialogRole, DialogSize, DialogVariant } from './dialog.types';
|
4
|
-
declare const Dialog_base: import("../../utils/mixins/index.types").Constructor<
|
4
|
+
declare const Dialog_base: import("../../utils/mixins/index.types").Constructor<Component & import("../../utils/mixins/PreventScrollMixin").PreventScrollMixinInterface> & import("../../utils/mixins/index.types").Constructor<Component & import("../../utils/mixins/FocusTrapMixin").FocusTrapClassInterface> & import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/CardAndDialogFooterMixin").CardAndDialogFooterMixinInterface> & typeof Component;
|
5
5
|
/**
|
6
6
|
* Dialog component is a modal dialog that can be used to display information or prompt the user for input.
|
7
7
|
* It can be used to create custom dialogs where content for the body and footer actions is provided by the consumer.
|
@@ -12,6 +12,11 @@ declare const Dialog_base: import("../../utils/mixins/index.types").Constructor<
|
|
12
12
|
* If a `triggerId` is provided, the dialog will manage focus with that element, otherwise it will
|
13
13
|
* remember the previously focused element before the dialog was opened.
|
14
14
|
*
|
15
|
+
* The dialog is a controlled component, meaning it does not have its own state management for visibility.
|
16
|
+
* Use the `visible` property to control the visibility of the dialog.
|
17
|
+
* Use the `onClose` event to handle the close action of the dialog (fired when Close button is clicked
|
18
|
+
* or Escape is pressed).
|
19
|
+
*
|
15
20
|
* Dialog component have 2 variants: default and promotional.
|
16
21
|
*
|
17
22
|
* **Accessibility notes for consuming (have to be explicitly set when you consume the component)**
|
@@ -32,6 +37,8 @@ declare const Dialog_base: import("../../utils/mixins/index.types").Constructor<
|
|
32
37
|
* @event hidden - (React: onHidden) Dispatched when the dialog is hidden
|
33
38
|
* @event created - (React: onCreated) Dispatched when the dialog is created (added to the DOM)
|
34
39
|
* @event destroyed - (React: onDestroyed) Dispatched when the dialog is destroyed (removed from the DOM)
|
40
|
+
* @event close - (React: onClose) Dispatched when the Close Button is clicked or Escape key is pressed
|
41
|
+
* (this does not hide the dialog)
|
35
42
|
*
|
36
43
|
* @cssproperty --mdc-dialog-primary-background-color - primary background color of the dialog
|
37
44
|
* @cssproperty --mdc-dialog-border-color - border color of the dialog
|
@@ -63,6 +70,8 @@ declare class Dialog extends Dialog_base {
|
|
63
70
|
triggerId?: string;
|
64
71
|
/**
|
65
72
|
* The visibility of the dialog
|
73
|
+
*
|
74
|
+
* Dialog is a controlled component, visible is the only property that controls the visibility of the dialog.
|
66
75
|
* @default false
|
67
76
|
*/
|
68
77
|
visible: boolean;
|
@@ -136,8 +145,13 @@ declare class Dialog extends Dialog_base {
|
|
136
145
|
* For now FocusTrap is always true as the dialog is a modal component only.
|
137
146
|
* This means it will always trap focus within the dialog when it is open.
|
138
147
|
*/
|
148
|
+
focusTrap: boolean;
|
149
|
+
/**
|
150
|
+
* For now preventScroll is always true as the dialog is a modal component only.
|
151
|
+
* This means scroll will be prevented when the dialog is open.
|
152
|
+
*/
|
139
153
|
/** @internal */
|
140
|
-
protected
|
154
|
+
protected preventScroll: boolean;
|
141
155
|
/** @internal */
|
142
156
|
protected triggerElement: HTMLElement | null;
|
143
157
|
/** @internal */
|
@@ -171,6 +185,12 @@ declare class Dialog extends Dialog_base {
|
|
171
185
|
* @internal
|
172
186
|
*/
|
173
187
|
private createBackdrop;
|
188
|
+
/**
|
189
|
+
* Fired when Close Button is clicked or Escape key is pressed.
|
190
|
+
* This method dispatches the close event. Setting visible to false
|
191
|
+
* has to be done by the consumer of the component.
|
192
|
+
*/
|
193
|
+
private closeDialog;
|
174
194
|
/**
|
175
195
|
* Handles the escape keydown event to close the dialog.
|
176
196
|
* @internal
|
@@ -192,16 +212,6 @@ declare class Dialog extends Dialog_base {
|
|
192
212
|
* @internal
|
193
213
|
*/
|
194
214
|
private focusBackToTrigger;
|
195
|
-
/**
|
196
|
-
* Hides the dialog.
|
197
|
-
* @internal
|
198
|
-
*/
|
199
|
-
hideDialog: () => void;
|
200
|
-
/**
|
201
|
-
* Shows the dialog.
|
202
|
-
* @internal
|
203
|
-
*/
|
204
|
-
showDialog: () => void;
|
205
215
|
render(): import("lit-html").TemplateResult<1>;
|
206
216
|
static styles: Array<CSSResult>;
|
207
217
|
}
|
@@ -13,6 +13,7 @@ import { property } from 'lit/decorators.js';
|
|
13
13
|
import styles from './dialog.styles';
|
14
14
|
import { Component } from '../../models';
|
15
15
|
import { FocusTrapMixin } from '../../utils/mixins/FocusTrapMixin';
|
16
|
+
import { PreventScrollMixin } from '../../utils/mixins/PreventScrollMixin';
|
16
17
|
import { DEFAULTS } from './dialog.constants';
|
17
18
|
import { TYPE, VALID_TEXT_TAGS } from '../text/text.constants';
|
18
19
|
import { DialogEventManager } from './dialog.events';
|
@@ -28,6 +29,11 @@ import { CardAndDialogFooterMixin } from '../../utils/mixins/CardAndDialogFooter
|
|
28
29
|
* If a `triggerId` is provided, the dialog will manage focus with that element, otherwise it will
|
29
30
|
* remember the previously focused element before the dialog was opened.
|
30
31
|
*
|
32
|
+
* The dialog is a controlled component, meaning it does not have its own state management for visibility.
|
33
|
+
* Use the `visible` property to control the visibility of the dialog.
|
34
|
+
* Use the `onClose` event to handle the close action of the dialog (fired when Close button is clicked
|
35
|
+
* or Escape is pressed).
|
36
|
+
*
|
31
37
|
* Dialog component have 2 variants: default and promotional.
|
32
38
|
*
|
33
39
|
* **Accessibility notes for consuming (have to be explicitly set when you consume the component)**
|
@@ -48,6 +54,8 @@ import { CardAndDialogFooterMixin } from '../../utils/mixins/CardAndDialogFooter
|
|
48
54
|
* @event hidden - (React: onHidden) Dispatched when the dialog is hidden
|
49
55
|
* @event created - (React: onCreated) Dispatched when the dialog is created (added to the DOM)
|
50
56
|
* @event destroyed - (React: onDestroyed) Dispatched when the dialog is destroyed (removed from the DOM)
|
57
|
+
* @event close - (React: onClose) Dispatched when the Close Button is clicked or Escape key is pressed
|
58
|
+
* (this does not hide the dialog)
|
51
59
|
*
|
52
60
|
* @cssproperty --mdc-dialog-primary-background-color - primary background color of the dialog
|
53
61
|
* @cssproperty --mdc-dialog-border-color - border color of the dialog
|
@@ -66,7 +74,7 @@ import { CardAndDialogFooterMixin } from '../../utils/mixins/CardAndDialogFooter
|
|
66
74
|
* @slot footer - This slot is for passing custom footer content. Only use this if really needed,
|
67
75
|
* using the footer-link and footer-button slots is preferred
|
68
76
|
*/
|
69
|
-
class Dialog extends FocusTrapMixin(CardAndDialogFooterMixin(Component)) {
|
77
|
+
class Dialog extends PreventScrollMixin(FocusTrapMixin(CardAndDialogFooterMixin(Component))) {
|
70
78
|
constructor() {
|
71
79
|
super(...arguments);
|
72
80
|
/**
|
@@ -75,6 +83,8 @@ class Dialog extends FocusTrapMixin(CardAndDialogFooterMixin(Component)) {
|
|
75
83
|
this.id = '';
|
76
84
|
/**
|
77
85
|
* The visibility of the dialog
|
86
|
+
*
|
87
|
+
* Dialog is a controlled component, visible is the only property that controls the visibility of the dialog.
|
78
88
|
* @default false
|
79
89
|
*/
|
80
90
|
this.visible = DEFAULTS.VISIBLE;
|
@@ -140,8 +150,13 @@ class Dialog extends FocusTrapMixin(CardAndDialogFooterMixin(Component)) {
|
|
140
150
|
* For now FocusTrap is always true as the dialog is a modal component only.
|
141
151
|
* This means it will always trap focus within the dialog when it is open.
|
142
152
|
*/
|
143
|
-
/** @internal */
|
144
153
|
this.focusTrap = true;
|
154
|
+
/**
|
155
|
+
* For now preventScroll is always true as the dialog is a modal component only.
|
156
|
+
* This means scroll will be prevented when the dialog is open.
|
157
|
+
*/
|
158
|
+
/** @internal */
|
159
|
+
this.preventScroll = true;
|
145
160
|
/** @internal */
|
146
161
|
this.triggerElement = null;
|
147
162
|
/** @internal */
|
@@ -158,36 +173,28 @@ class Dialog extends FocusTrapMixin(CardAndDialogFooterMixin(Component)) {
|
|
158
173
|
return;
|
159
174
|
}
|
160
175
|
event.preventDefault();
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
* @internal
|
166
|
-
*/
|
167
|
-
this.hideDialog = () => {
|
168
|
-
this.visible = false;
|
169
|
-
};
|
170
|
-
/**
|
171
|
-
* Shows the dialog.
|
172
|
-
* @internal
|
173
|
-
*/
|
174
|
-
this.showDialog = () => {
|
175
|
-
this.visible = true;
|
176
|
+
// Prevent the event from propagating to the document level
|
177
|
+
// pressing escape on a dialog should only close the dialog, nothing else
|
178
|
+
event.stopPropagation();
|
179
|
+
this.closeDialog();
|
176
180
|
};
|
177
181
|
}
|
178
182
|
connectedCallback() {
|
179
183
|
super.connectedCallback();
|
180
|
-
|
184
|
+
// event listener can be added to the element directly, since dialog is a modal component
|
185
|
+
// and it will not be allowed to be focused outside of it
|
186
|
+
this.addEventListener('keydown', this.onEscapeKeydown.bind(this));
|
181
187
|
}
|
182
188
|
disconnectedCallback() {
|
183
189
|
var _a, _b, _c;
|
184
190
|
super.disconnectedCallback();
|
185
|
-
|
191
|
+
this.removeEventListener('keydown', this.onEscapeKeydown);
|
186
192
|
(_a = this.backdropElement) === null || _a === void 0 ? void 0 : _a.remove();
|
187
193
|
this.backdropElement = null;
|
188
|
-
(_b = this.deactivateFocusTrap) === null || _b === void 0 ? void 0 : _b.call(this);
|
189
194
|
// Set aria-expanded attribute on the trigger element to false if it exists
|
190
|
-
(
|
195
|
+
(_b = this.triggerElement) === null || _b === void 0 ? void 0 : _b.setAttribute('aria-expanded', 'false');
|
196
|
+
this.deactivatePreventScroll();
|
197
|
+
(_c = this.deactivateFocusTrap) === null || _c === void 0 ? void 0 : _c.call(this);
|
191
198
|
this.focusBackToTrigger();
|
192
199
|
DialogEventManager.onDestroyedDialog(this);
|
193
200
|
}
|
@@ -222,6 +229,12 @@ class Dialog extends FocusTrapMixin(CardAndDialogFooterMixin(Component)) {
|
|
222
229
|
|| changedProperties.has('descriptionText')) {
|
223
230
|
this.setupAriaLabelledDescribedBy();
|
224
231
|
}
|
232
|
+
if (changedProperties.has('focusTrap')) {
|
233
|
+
// if focusTrap turned false and the popover is visible, deactivate the focus trap
|
234
|
+
if (!this.focusTrap && this.visible) {
|
235
|
+
this.deactivateFocusTrap();
|
236
|
+
}
|
237
|
+
}
|
225
238
|
}
|
226
239
|
/**
|
227
240
|
* Sets up the aria-haspopup attribute for the dialog.
|
@@ -289,6 +302,14 @@ class Dialog extends FocusTrapMixin(CardAndDialogFooterMixin(Component)) {
|
|
289
302
|
(_a = this.parentElement) === null || _a === void 0 ? void 0 : _a.appendChild(backdrop);
|
290
303
|
this.backdropElement = backdrop;
|
291
304
|
}
|
305
|
+
/**
|
306
|
+
* Fired when Close Button is clicked or Escape key is pressed.
|
307
|
+
* This method dispatches the close event. Setting visible to false
|
308
|
+
* has to be done by the consumer of the component.
|
309
|
+
*/
|
310
|
+
closeDialog() {
|
311
|
+
DialogEventManager.onCloseDialog(this, false);
|
312
|
+
}
|
292
313
|
/**
|
293
314
|
* Handles the dialog visibility change.
|
294
315
|
* Handles the exit event to close the dialog.
|
@@ -304,8 +325,8 @@ class Dialog extends FocusTrapMixin(CardAndDialogFooterMixin(Component)) {
|
|
304
325
|
if (newValue && !oldValue) {
|
305
326
|
// Store the currently focused element before opening the dialog
|
306
327
|
this.lastActiveElement = document.activeElement;
|
307
|
-
this.enabledPreventScroll = true;
|
308
328
|
this.createBackdrop();
|
329
|
+
this.activatePreventScroll();
|
309
330
|
await this.updateComplete;
|
310
331
|
(_a = this.activateFocusTrap) === null || _a === void 0 ? void 0 : _a.call(this);
|
311
332
|
(_b = this.setInitialFocus) === null || _b === void 0 ? void 0 : _b.call(this);
|
@@ -316,9 +337,10 @@ class Dialog extends FocusTrapMixin(CardAndDialogFooterMixin(Component)) {
|
|
316
337
|
else if (!newValue && oldValue) {
|
317
338
|
(_d = this.backdropElement) === null || _d === void 0 ? void 0 : _d.remove();
|
318
339
|
this.backdropElement = null;
|
319
|
-
(_e = this.deactivateFocusTrap) === null || _e === void 0 ? void 0 : _e.call(this);
|
320
340
|
// Set aria-expanded attribute on the trigger element to false if it exists
|
321
|
-
(
|
341
|
+
(_e = this.triggerElement) === null || _e === void 0 ? void 0 : _e.setAttribute('aria-expanded', 'false');
|
342
|
+
this.deactivatePreventScroll();
|
343
|
+
(_f = this.deactivateFocusTrap) === null || _f === void 0 ? void 0 : _f.call(this);
|
322
344
|
this.focusBackToTrigger();
|
323
345
|
DialogEventManager.onHideDialog(this);
|
324
346
|
}
|
@@ -371,7 +393,7 @@ class Dialog extends FocusTrapMixin(CardAndDialogFooterMixin(Component)) {
|
|
371
393
|
variant="${BUTTON_VARIANTS.TERTIARY}"
|
372
394
|
size="${ICON_BUTTON_SIZES[20]}"
|
373
395
|
aria-label="${ifDefined(this.closeButtonAriaLabel) || ''}"
|
374
|
-
@click="${this.
|
396
|
+
@click="${this.closeDialog}"
|
375
397
|
></mdc-button>
|
376
398
|
<div part="body">
|
377
399
|
<slot name="dialog-body"></slot>
|
@@ -6,7 +6,7 @@ export declare class DialogEventManager {
|
|
6
6
|
* @param eventName - The name of the event.
|
7
7
|
* @param instance - The dialog instance.
|
8
8
|
*/
|
9
|
-
static dispatchDialogEvent(eventName: string, instance: Dialog): void;
|
9
|
+
static dispatchDialogEvent(eventName: string, instance: Dialog, bubbles?: boolean): void;
|
10
10
|
/**
|
11
11
|
* Custom event that is fired when the dialog is shown.
|
12
12
|
*
|
@@ -19,6 +19,14 @@ export declare class DialogEventManager {
|
|
19
19
|
* @param instance - The dialog instance.
|
20
20
|
*/
|
21
21
|
static onHideDialog(instance: Dialog): void;
|
22
|
+
/**
|
23
|
+
* Custom event that is fired when the dialog is closed.
|
24
|
+
* This gets fired when the Close Button is clicked or
|
25
|
+
* when Escape key is pressed.
|
26
|
+
*
|
27
|
+
* @param instance - The dialog instance.
|
28
|
+
*/
|
29
|
+
static onCloseDialog(instance: Dialog, bubbles?: boolean): void;
|
22
30
|
/**
|
23
31
|
* Custom event that is fired when the dialog is created.
|
24
32
|
*
|
@@ -5,11 +5,11 @@ export class DialogEventManager {
|
|
5
5
|
* @param eventName - The name of the event.
|
6
6
|
* @param instance - The dialog instance.
|
7
7
|
*/
|
8
|
-
static dispatchDialogEvent(eventName, instance) {
|
8
|
+
static dispatchDialogEvent(eventName, instance, bubbles = true) {
|
9
9
|
instance.dispatchEvent(new CustomEvent(eventName, {
|
10
10
|
detail: { show: instance.visible },
|
11
11
|
composed: true,
|
12
|
-
bubbles
|
12
|
+
bubbles,
|
13
13
|
}));
|
14
14
|
}
|
15
15
|
/**
|
@@ -28,6 +28,16 @@ export class DialogEventManager {
|
|
28
28
|
static onHideDialog(instance) {
|
29
29
|
this.dispatchDialogEvent('hidden', instance);
|
30
30
|
}
|
31
|
+
/**
|
32
|
+
* Custom event that is fired when the dialog is closed.
|
33
|
+
* This gets fired when the Close Button is clicked or
|
34
|
+
* when Escape key is pressed.
|
35
|
+
*
|
36
|
+
* @param instance - The dialog instance.
|
37
|
+
*/
|
38
|
+
static onCloseDialog(instance, bubbles = true) {
|
39
|
+
this.dispatchDialogEvent('close', instance, bubbles);
|
40
|
+
}
|
31
41
|
/**
|
32
42
|
* Custom event that is fired when the dialog is created.
|
33
43
|
*
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { CSSResult, PropertyValues } from 'lit';
|
2
2
|
import { Component } from '../../models';
|
3
3
|
import { PopoverColor, PopoverPlacement, PopoverTrigger } from './popover.types';
|
4
|
-
declare const Popover_base: import("../../utils/mixins/index.types").Constructor<
|
4
|
+
declare const Popover_base: import("../../utils/mixins/index.types").Constructor<Component & import("../../utils/mixins/PreventScrollMixin").PreventScrollMixinInterface> & import("../../utils/mixins/index.types").Constructor<Component & import("../../utils/mixins/FocusTrapMixin").FocusTrapClassInterface> & typeof Component;
|
5
5
|
/**
|
6
6
|
* Popover component is a lightweight floating UI element that displays additional content when triggered.
|
7
7
|
* It can be used for tooltips, dropdowns, or contextual menus.
|
@@ -94,7 +94,7 @@ declare class Popover extends Popover_base {
|
|
94
94
|
*/
|
95
95
|
focusTrap: boolean;
|
96
96
|
/**
|
97
|
-
* Prevent outside scrolling when popover
|
97
|
+
* Prevent outside scrolling when popover is shown.
|
98
98
|
* @default false
|
99
99
|
*/
|
100
100
|
preventScroll: boolean;
|
@@ -109,7 +109,10 @@ declare class Popover extends Popover_base {
|
|
109
109
|
*/
|
110
110
|
closeButton: boolean;
|
111
111
|
/**
|
112
|
-
* Determines whether the popover is interactive
|
112
|
+
* Determines whether the popover is interactive.
|
113
|
+
* Make sure to set focusTrap to true to keep the focus inside the popover in case necessary.
|
114
|
+
* Setting interactive to true will not automatically set focusTrap!
|
115
|
+
*
|
113
116
|
* @default false
|
114
117
|
*/
|
115
118
|
interactive: boolean;
|
@@ -282,10 +285,6 @@ declare class Popover extends Popover_base {
|
|
282
285
|
* Toggles the popover visibility.
|
283
286
|
*/
|
284
287
|
togglePopoverVisible: () => void;
|
285
|
-
/**
|
286
|
-
* Sets the focusable elements inside the popover.
|
287
|
-
*/
|
288
|
-
private handleCreatePopoverFirstUpdate;
|
289
288
|
/**
|
290
289
|
* Positions the popover based on the trigger element.
|
291
290
|
* It also handles the flip, size and arrow placement.
|
@@ -13,6 +13,7 @@ import { property } from 'lit/decorators.js';
|
|
13
13
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
14
14
|
import { Component } from '../../models';
|
15
15
|
import { FocusTrapMixin } from '../../utils/mixins/FocusTrapMixin';
|
16
|
+
import { PreventScrollMixin } from '../../utils/mixins/PreventScrollMixin';
|
16
17
|
import { COLOR, DEFAULTS, POPOVER_PLACEMENT, TRIGGER } from './popover.constants';
|
17
18
|
import { PopoverEventManager } from './popover.events';
|
18
19
|
import { popoverStack } from './popover.stack';
|
@@ -48,7 +49,7 @@ import { PopoverUtils } from './popover.utils';
|
|
48
49
|
* @slot - Default slot for the popover content
|
49
50
|
*
|
50
51
|
*/
|
51
|
-
class Popover extends FocusTrapMixin(Component) {
|
52
|
+
class Popover extends PreventScrollMixin(FocusTrapMixin(Component)) {
|
52
53
|
constructor() {
|
53
54
|
super();
|
54
55
|
/**
|
@@ -112,7 +113,7 @@ class Popover extends FocusTrapMixin(Component) {
|
|
112
113
|
*/
|
113
114
|
this.focusTrap = DEFAULTS.FOCUS_TRAP;
|
114
115
|
/**
|
115
|
-
* Prevent outside scrolling when popover
|
116
|
+
* Prevent outside scrolling when popover is shown.
|
116
117
|
* @default false
|
117
118
|
*/
|
118
119
|
this.preventScroll = DEFAULTS.PREVENT_SCROLL;
|
@@ -127,7 +128,10 @@ class Popover extends FocusTrapMixin(Component) {
|
|
127
128
|
*/
|
128
129
|
this.closeButton = DEFAULTS.CLOSE_BUTTON;
|
129
130
|
/**
|
130
|
-
* Determines whether the popover is interactive
|
131
|
+
* Determines whether the popover is interactive.
|
132
|
+
* Make sure to set focusTrap to true to keep the focus inside the popover in case necessary.
|
133
|
+
* Setting interactive to true will not automatically set focusTrap!
|
134
|
+
*
|
131
135
|
* @default false
|
132
136
|
*/
|
133
137
|
this.interactive = DEFAULTS.INTERACTIVE;
|
@@ -336,6 +340,7 @@ class Popover extends FocusTrapMixin(Component) {
|
|
336
340
|
this.utils = new PopoverUtils(this);
|
337
341
|
}
|
338
342
|
async firstUpdated(changedProperties) {
|
343
|
+
var _a, _b;
|
339
344
|
super.firstUpdated(changedProperties);
|
340
345
|
this.utils.setupAppendTo();
|
341
346
|
[this.openDelay, this.closeDelay] = this.utils.setupDelay();
|
@@ -345,7 +350,14 @@ class Popover extends FocusTrapMixin(Component) {
|
|
345
350
|
PopoverEventManager.onCreatedPopover(this);
|
346
351
|
if (this.visible) {
|
347
352
|
this.positionPopover();
|
348
|
-
|
353
|
+
this.activatePreventScroll();
|
354
|
+
// If the popover is visible on first update and focustrap is enabled, we need to activate the focus trap
|
355
|
+
if (this.interactive && this.focusTrap) {
|
356
|
+
// Wait for the first update to complete before setting focusable elements
|
357
|
+
await this.updateComplete;
|
358
|
+
(_a = this.activateFocusTrap) === null || _a === void 0 ? void 0 : _a.call(this);
|
359
|
+
(_b = this.setInitialFocus) === null || _b === void 0 ? void 0 : _b.call(this);
|
360
|
+
}
|
349
361
|
}
|
350
362
|
}
|
351
363
|
async disconnectedCallback() {
|
@@ -353,6 +365,7 @@ class Popover extends FocusTrapMixin(Component) {
|
|
353
365
|
super.disconnectedCallback();
|
354
366
|
this.removeEventListeners();
|
355
367
|
(_a = this.deactivateFocusTrap) === null || _a === void 0 ? void 0 : _a.call(this);
|
368
|
+
this.deactivatePreventScroll();
|
356
369
|
PopoverEventManager.onDestroyedPopover(this);
|
357
370
|
popoverStack.remove(this);
|
358
371
|
}
|
@@ -454,6 +467,21 @@ class Popover extends FocusTrapMixin(Component) {
|
|
454
467
|
if (changedProperties.has('interactive') || changedProperties.has('disableAriaHasPopup')) {
|
455
468
|
this.utils.updateAriaHasPopupAttribute();
|
456
469
|
}
|
470
|
+
if (changedProperties.has('focusTrap')) {
|
471
|
+
// if focusTrap turned false and the popover is visible, deactivate the focus trap
|
472
|
+
if (!this.focusTrap && this.visible) {
|
473
|
+
this.deactivateFocusTrap();
|
474
|
+
}
|
475
|
+
}
|
476
|
+
if (changedProperties.has('preventScroll')) {
|
477
|
+
// if preventScroll turned false and the popover is visible, deactivate the prevent scroll
|
478
|
+
if (!this.preventScroll && this.visible) {
|
479
|
+
this.deactivatePreventScroll();
|
480
|
+
}
|
481
|
+
else if (this.preventScroll && this.visible) {
|
482
|
+
this.activatePreventScroll();
|
483
|
+
}
|
484
|
+
}
|
457
485
|
}
|
458
486
|
/**
|
459
487
|
* Handles the popover visibility change and position the popover.
|
@@ -463,7 +491,7 @@ class Popover extends FocusTrapMixin(Component) {
|
|
463
491
|
* @param newValue - The new value of the visible property.
|
464
492
|
*/
|
465
493
|
async isOpenUpdated(oldValue, newValue) {
|
466
|
-
var _a, _b, _c, _d, _e;
|
494
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
467
495
|
if (oldValue === newValue || !this.triggerElement) {
|
468
496
|
return;
|
469
497
|
}
|
@@ -471,13 +499,11 @@ class Popover extends FocusTrapMixin(Component) {
|
|
471
499
|
if (popoverStack.peek() !== this) {
|
472
500
|
popoverStack.push(this);
|
473
501
|
}
|
474
|
-
this.enabledPreventScroll = this.preventScroll;
|
475
502
|
if (this.backdrop) {
|
476
503
|
this.utils.createBackdrop();
|
477
504
|
this.triggerElement.style.zIndex = `${this.zIndex}`;
|
478
505
|
}
|
479
506
|
this.positionPopover();
|
480
|
-
await this.handleCreatePopoverFirstUpdate();
|
481
507
|
if (this.hideOnBlur) {
|
482
508
|
this.addEventListener('focusout', this.onPopoverFocusOut);
|
483
509
|
if (this.trigger === 'click') {
|
@@ -491,6 +517,13 @@ class Popover extends FocusTrapMixin(Component) {
|
|
491
517
|
this.addEventListener('keydown', this.onEscapeKeydown);
|
492
518
|
(_a = this.triggerElement) === null || _a === void 0 ? void 0 : _a.addEventListener('keydown', this.onEscapeKeydown);
|
493
519
|
}
|
520
|
+
this.activatePreventScroll();
|
521
|
+
if (this.interactive && this.focusTrap) {
|
522
|
+
// Wait for the update to complete before setting focusable elements
|
523
|
+
await this.updateComplete;
|
524
|
+
(_b = this.activateFocusTrap) === null || _b === void 0 ? void 0 : _b.call(this);
|
525
|
+
(_c = this.setInitialFocus) === null || _c === void 0 ? void 0 : _c.call(this);
|
526
|
+
}
|
494
527
|
PopoverEventManager.onShowPopover(this);
|
495
528
|
}
|
496
529
|
else {
|
@@ -498,7 +531,7 @@ class Popover extends FocusTrapMixin(Component) {
|
|
498
531
|
popoverStack.pop();
|
499
532
|
}
|
500
533
|
if (this.backdropElement) {
|
501
|
-
(
|
534
|
+
(_d = this.backdropElement) === null || _d === void 0 ? void 0 : _d.remove();
|
502
535
|
this.backdropElement = null;
|
503
536
|
}
|
504
537
|
if (this.hideOnBlur) {
|
@@ -512,9 +545,8 @@ class Popover extends FocusTrapMixin(Component) {
|
|
512
545
|
}
|
513
546
|
if (this.hideOnEscape) {
|
514
547
|
this.removeEventListener('keydown', this.onEscapeKeydown);
|
515
|
-
(
|
548
|
+
(_e = this.triggerElement) === null || _e === void 0 ? void 0 : _e.removeEventListener('keydown', this.onEscapeKeydown);
|
516
549
|
}
|
517
|
-
(_d = this.deactivateFocusTrap) === null || _d === void 0 ? void 0 : _d.call(this);
|
518
550
|
if (!this.disableAriaExpanded) {
|
519
551
|
this.triggerElement.removeAttribute('aria-expanded');
|
520
552
|
}
|
@@ -522,24 +554,14 @@ class Popover extends FocusTrapMixin(Component) {
|
|
522
554
|
if (!this.interactive) {
|
523
555
|
this.triggerElement.removeAttribute('aria-haspopup');
|
524
556
|
}
|
557
|
+
this.deactivatePreventScroll();
|
558
|
+
(_f = this.deactivateFocusTrap) === null || _f === void 0 ? void 0 : _f.call(this);
|
525
559
|
if (this.focusBackToTrigger) {
|
526
|
-
(
|
560
|
+
(_g = this.triggerElement) === null || _g === void 0 ? void 0 : _g.focus();
|
527
561
|
}
|
528
562
|
PopoverEventManager.onHidePopover(this);
|
529
563
|
}
|
530
564
|
}
|
531
|
-
/**
|
532
|
-
* Sets the focusable elements inside the popover.
|
533
|
-
*/
|
534
|
-
async handleCreatePopoverFirstUpdate() {
|
535
|
-
var _a, _b;
|
536
|
-
if (this.visible && this.interactive) {
|
537
|
-
// Wait for the first update to complete before setting focusable elements
|
538
|
-
await this.updateComplete;
|
539
|
-
(_a = this.activateFocusTrap) === null || _a === void 0 ? void 0 : _a.call(this);
|
540
|
-
(_b = this.setInitialFocus) === null || _b === void 0 ? void 0 : _b.call(this);
|
541
|
-
}
|
542
|
-
}
|
543
565
|
/**
|
544
566
|
* Positions the popover based on the trigger element.
|
545
567
|
* It also handles the flip, size and arrow placement.
|
@@ -57,7 +57,7 @@ class Tooltip extends Popover {
|
|
57
57
|
this.placement = this.placement || DEFAULTS.PLACEMENT;
|
58
58
|
this.role = ROLE.TOOLTIP;
|
59
59
|
this.trigger = 'mouseenter focusin';
|
60
|
-
this.
|
60
|
+
this.preventScroll = false;
|
61
61
|
this.flip = true;
|
62
62
|
this.preventScroll = false;
|
63
63
|
this.closeButton = false;
|