@momentum-design/components 0.66.4 → 0.68.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.
- package/dist/browser/index.js +369 -211
- package/dist/browser/index.js.map +4 -4
- package/dist/components/card/card.component.d.ts +4 -35
- package/dist/components/card/card.component.js +9 -79
- package/dist/components/dialog/dialog.component.d.ts +150 -0
- package/dist/components/dialog/dialog.component.js +340 -0
- package/dist/components/dialog/dialog.constants.d.ts +18 -0
- package/dist/components/dialog/dialog.constants.js +19 -0
- package/dist/components/dialog/dialog.events.d.ts +34 -0
- package/dist/components/dialog/dialog.events.js +47 -0
- package/dist/components/dialog/dialog.styles.d.ts +2 -0
- package/dist/components/dialog/dialog.styles.js +108 -0
- package/dist/components/dialog/dialog.types.d.ts +12 -0
- package/dist/components/dialog/dialog.types.js +1 -0
- package/dist/components/dialog/dialog.utils.d.ts +7 -0
- package/dist/components/dialog/dialog.utils.js +33 -0
- package/dist/components/dialog/index.d.ts +9 -0
- package/dist/components/dialog/index.js +6 -0
- package/dist/components/popover/popover.styles.js +5 -0
- package/dist/components/toggletip/toggletip.styles.js +8 -0
- package/dist/custom-elements.json +1211 -105
- package/dist/index.d.ts +4 -3
- package/dist/index.js +4 -3
- package/dist/react/dialog/index.d.ts +51 -0
- package/dist/react/dialog/index.js +59 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +1 -0
- package/dist/utils/mixins/CardAndDialogFooterMixin.d.ts +11 -0
- package/dist/utils/mixins/CardAndDialogFooterMixin.js +102 -0
- package/dist/utils/mixins/FocusTrapMixin.js +4 -5
- package/package.json +1 -1
@@ -1,6 +1,6 @@
|
|
1
1
|
import { CSSResult, nothing, PropertyValues } from 'lit';
|
2
2
|
import { Component } from '../../models';
|
3
|
-
declare const Card_base: import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/CardComponentMixin").CardComponentMixinInterface> & typeof Component;
|
3
|
+
declare const Card_base: import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/CardComponentMixin").CardComponentMixinInterface> & import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/CardAndDialogFooterMixin").CardAndDialogFooterMixinInterface> & typeof Component;
|
4
4
|
/**
|
5
5
|
* The card component allows users to organize information in a structured and tangible
|
6
6
|
* format that is visually appealing. `mdc-card` is a static component that supports
|
@@ -51,21 +51,6 @@ declare class Card extends Card_base {
|
|
51
51
|
* @internal
|
52
52
|
*/
|
53
53
|
iconButtons?: Array<HTMLElement>;
|
54
|
-
/**
|
55
|
-
* The links in the footer section
|
56
|
-
* @internal
|
57
|
-
*/
|
58
|
-
footerLink?: Array<HTMLElement>;
|
59
|
-
/**
|
60
|
-
* The primary buttons in the footer section
|
61
|
-
* @internal
|
62
|
-
*/
|
63
|
-
footerButtonPrimary?: Array<HTMLElement>;
|
64
|
-
/**
|
65
|
-
* The secondary buttons in the footer section
|
66
|
-
* @internal
|
67
|
-
*/
|
68
|
-
footerButtonSecondary?: Array<HTMLElement>;
|
69
54
|
update(changedProperties: PropertyValues<Card>): void;
|
70
55
|
/**
|
71
56
|
* Handles the icon buttons in the header section and sets its variant for styling.
|
@@ -74,25 +59,9 @@ declare class Card extends Card_base {
|
|
74
59
|
*/
|
75
60
|
private handleIconButtons;
|
76
61
|
/**
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
* - One primary variant of the mdc-button element in the footer-button-primary slot
|
81
|
-
*
|
82
|
-
* @internal
|
83
|
-
*/
|
84
|
-
private handleFooterSlot;
|
85
|
-
/**
|
86
|
-
* Updates the color of the footer buttons based on the variant.
|
87
|
-
* If the variant is promotional, the color is promotional, else default.
|
88
|
-
*
|
89
|
-
* @internal
|
90
|
-
*/
|
91
|
-
private updateFooterButtonColors;
|
92
|
-
/**
|
93
|
-
* Renders the header of the card if title is provided
|
94
|
-
* @returns The header element
|
95
|
-
*/
|
62
|
+
* Renders the header of the card if title is provided
|
63
|
+
* @returns The header element
|
64
|
+
*/
|
96
65
|
protected renderHeader(): import("lit-html").TemplateResult<1> | typeof nothing;
|
97
66
|
render(): import("lit-html").TemplateResult<1>;
|
98
67
|
static styles: Array<CSSResult>;
|
@@ -11,9 +11,10 @@ import { html, nothing } from 'lit';
|
|
11
11
|
import { queryAssignedElements } from 'lit/decorators.js';
|
12
12
|
import styles from './card.styles';
|
13
13
|
import { Component } from '../../models';
|
14
|
-
import {
|
15
|
-
import {
|
14
|
+
import { DEFAULTS } from './card.constants';
|
15
|
+
import { BUTTON_VARIANTS } from '../button/button.constants';
|
16
16
|
import { CardComponentMixin } from '../../utils/mixins/CardComponentMixin';
|
17
|
+
import { CardAndDialogFooterMixin } from '../../utils/mixins/CardAndDialogFooterMixin';
|
17
18
|
/**
|
18
19
|
* The card component allows users to organize information in a structured and tangible
|
19
20
|
* format that is visually appealing. `mdc-card` is a static component that supports
|
@@ -58,7 +59,7 @@ import { CardComponentMixin } from '../../utils/mixins/CardComponentMixin';
|
|
58
59
|
* @slot after-body - This slot is for passing the content after the body
|
59
60
|
*
|
60
61
|
*/
|
61
|
-
class Card extends CardComponentMixin(Component) {
|
62
|
+
class Card extends CardComponentMixin(CardAndDialogFooterMixin(Component)) {
|
62
63
|
constructor() {
|
63
64
|
super(...arguments);
|
64
65
|
/**
|
@@ -84,70 +85,17 @@ class Card extends CardComponentMixin(Component) {
|
|
84
85
|
}
|
85
86
|
}
|
86
87
|
};
|
87
|
-
/**
|
88
|
-
* Filters and renders only the following content into the footer section and removes anything other than it
|
89
|
-
* - One mdc-link element in the footer-link slot
|
90
|
-
* - One secondary variant of the mdc-button element in the footer-button-secondary slot
|
91
|
-
* - One primary variant of the mdc-button element in the footer-button-primary slot
|
92
|
-
*
|
93
|
-
* @internal
|
94
|
-
*/
|
95
|
-
this.handleFooterSlot = (tagname, variant = '') => {
|
96
|
-
var _a, _b, _c;
|
97
|
-
let arrayItems = [];
|
98
|
-
if (tagname === DEFAULTS.LINK && ((_a = this.footerLink) === null || _a === void 0 ? void 0 : _a.length)) {
|
99
|
-
arrayItems = this.footerLink;
|
100
|
-
}
|
101
|
-
else if (tagname === DEFAULTS.BUTTON && variant === BUTTON_VARIANTS.PRIMARY && ((_b = this.footerButtonPrimary) === null || _b === void 0 ? void 0 : _b.length)) {
|
102
|
-
arrayItems = this.footerButtonPrimary;
|
103
|
-
}
|
104
|
-
else if (tagname === DEFAULTS.BUTTON
|
105
|
-
&& variant === BUTTON_VARIANTS.SECONDARY && ((_c = this.footerButtonSecondary) === null || _c === void 0 ? void 0 : _c.length)) {
|
106
|
-
arrayItems = this.footerButtonSecondary;
|
107
|
-
}
|
108
|
-
// if there are more than one instance, remove them.
|
109
|
-
for (let i = 1; i < arrayItems.length; i += 1) {
|
110
|
-
arrayItems[i].remove();
|
111
|
-
}
|
112
|
-
arrayItems.forEach((element) => {
|
113
|
-
// remove the element if it doesn't match with the tagname
|
114
|
-
if (!element.matches(tagname)) {
|
115
|
-
element.remove();
|
116
|
-
}
|
117
|
-
// set the variant if it is provided
|
118
|
-
if (variant) {
|
119
|
-
element.setAttribute('variant', variant);
|
120
|
-
}
|
121
|
-
});
|
122
|
-
};
|
123
|
-
/**
|
124
|
-
* Updates the color of the footer buttons based on the variant.
|
125
|
-
* If the variant is promotional, the color is promotional, else default.
|
126
|
-
*
|
127
|
-
* @internal
|
128
|
-
*/
|
129
|
-
this.updateFooterButtonColors = () => {
|
130
|
-
const footerButtons = [...(this.footerButtonPrimary || []), ...(this.footerButtonSecondary || [])];
|
131
|
-
footerButtons === null || footerButtons === void 0 ? void 0 : footerButtons.forEach((button) => {
|
132
|
-
if (this.variant === VARIANTS.PROMOTIONAL) {
|
133
|
-
button.setAttribute('color', BUTTON_COLORS.PROMOTIONAL);
|
134
|
-
}
|
135
|
-
else {
|
136
|
-
button.setAttribute('color', BUTTON_COLORS.DEFAULT);
|
137
|
-
}
|
138
|
-
});
|
139
|
-
};
|
140
88
|
}
|
141
89
|
update(changedProperties) {
|
142
90
|
super.update(changedProperties);
|
143
91
|
if (changedProperties.has('variant')) {
|
144
|
-
this.updateFooterButtonColors();
|
92
|
+
this.updateFooterButtonColors(this.variant);
|
145
93
|
}
|
146
94
|
}
|
147
95
|
/**
|
148
|
-
|
149
|
-
|
150
|
-
|
96
|
+
* Renders the header of the card if title is provided
|
97
|
+
* @returns The header element
|
98
|
+
*/
|
151
99
|
renderHeader() {
|
152
100
|
if (!this.cardTitle) {
|
153
101
|
return nothing;
|
@@ -166,13 +114,7 @@ class Card extends CardComponentMixin(Component) {
|
|
166
114
|
<slot name="before-body"></slot>
|
167
115
|
<slot name="body"></slot>
|
168
116
|
<slot name="after-body"></slot>
|
169
|
-
|
170
|
-
<slot name="footer-link" @slotchange=${() => this.handleFooterSlot(DEFAULTS.LINK)}></slot>
|
171
|
-
<slot name="footer-button-secondary"
|
172
|
-
@slotchange=${() => this.handleFooterSlot(DEFAULTS.BUTTON, BUTTON_VARIANTS.SECONDARY)}></slot>
|
173
|
-
<slot name="footer-button-primary"
|
174
|
-
@slotchange=${() => this.handleFooterSlot(DEFAULTS.BUTTON, BUTTON_VARIANTS.PRIMARY)}></slot>
|
175
|
-
</div>
|
117
|
+
${this.renderFooter()}
|
176
118
|
</div>
|
177
119
|
`;
|
178
120
|
}
|
@@ -182,16 +124,4 @@ __decorate([
|
|
182
124
|
queryAssignedElements({ slot: 'icon-button' }),
|
183
125
|
__metadata("design:type", Array)
|
184
126
|
], Card.prototype, "iconButtons", void 0);
|
185
|
-
__decorate([
|
186
|
-
queryAssignedElements({ slot: 'footer-link' }),
|
187
|
-
__metadata("design:type", Array)
|
188
|
-
], Card.prototype, "footerLink", void 0);
|
189
|
-
__decorate([
|
190
|
-
queryAssignedElements({ slot: 'footer-button-primary' }),
|
191
|
-
__metadata("design:type", Array)
|
192
|
-
], Card.prototype, "footerButtonPrimary", void 0);
|
193
|
-
__decorate([
|
194
|
-
queryAssignedElements({ slot: 'footer-button-secondary' }),
|
195
|
-
__metadata("design:type", Array)
|
196
|
-
], Card.prototype, "footerButtonSecondary", void 0);
|
197
127
|
export default Card;
|
@@ -0,0 +1,150 @@
|
|
1
|
+
import { CSSResult, PropertyValues } from 'lit';
|
2
|
+
import { Component } from '../../models';
|
3
|
+
import type { DialogRole, DialogSize, DialogVariant } from './dialog.types';
|
4
|
+
declare const Dialog_base: import("../../utils/mixins/index.types").Constructor<HTMLElement & import("../../utils/mixins/FocusTrapMixin").FocusTrapClassInterface> & import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/CardAndDialogFooterMixin").CardAndDialogFooterMixinInterface> & typeof Component;
|
5
|
+
/**
|
6
|
+
* Dialog component is a modal dialog that can be used to display information or prompt the user for input.
|
7
|
+
* It can be used to create custom dialogs where content for the body and footer actions is provided by the consumer.
|
8
|
+
* The dialog is available in three sizes: small, medium, and large. It may also receive custom styling/sizing.
|
9
|
+
* The dialog interrupts the user and will block interaction with the rest of the application until it is closed.
|
10
|
+
*
|
11
|
+
* Dialog component have 2 variants: default and promotional.
|
12
|
+
*
|
13
|
+
* **Accessibility notes for consuming (have to be explicitly set when you consume the component)**
|
14
|
+
*
|
15
|
+
* - The dialog should have an aria-label or aria-labelledby attribute to provide a label for screen readers.
|
16
|
+
* - Use aria-labelledby to reference the ID of the element that labels the dialog when there is no visible title.
|
17
|
+
*
|
18
|
+
* **Note: Programmatic show/hide requires the ? prefix on the visible attribute**
|
19
|
+
* - Use `?visible=true/false` as an attribute instead of `visible=true/false`
|
20
|
+
* - Reference docs for more info: https://lit.dev/docs/templates/expressions/#boolean-attribute-expressions
|
21
|
+
*
|
22
|
+
* @dependency mdc-button
|
23
|
+
* @dependency mdc-text
|
24
|
+
*
|
25
|
+
* @tagname mdc-dialog
|
26
|
+
*
|
27
|
+
* @event shown - (React: onShown) Dispatched when the dialog is shown
|
28
|
+
* @event hidden - (React: onHidden) Dispatched when the dialog is hidden
|
29
|
+
* @event created - (React: onCreated) Dispatched when the dialog is created (added to the DOM)
|
30
|
+
* @event destroyed - (React: onDestroyed) Dispatched when the dialog is destroyed (removed from the DOM)
|
31
|
+
*
|
32
|
+
* @cssproperty --mdc-dialog-primary-background-color - primary background color of the dialog
|
33
|
+
* @cssproperty --mdc-dialog-border-color - border color of the dialog
|
34
|
+
* @cssproperty --mdc-dialog-header-text-color - text color of the header/title of the dialog
|
35
|
+
* @cssproperty --mdc-dialog-description-text-color - text color of the below header description of the dialog
|
36
|
+
* @cssproperty --mdc-dialog-elevation-3 - elevation of the dialog
|
37
|
+
* @cssproperty --mdc-dialog-width - width of the dialog
|
38
|
+
*
|
39
|
+
* @slot dialog-body - Slot for the dialog body content
|
40
|
+
* @slot footer-link - This slot is for passing `mdc-link` component within the footer section.
|
41
|
+
* @slot footer-button-secondary - This slot is for passing secondary variant of `mdc-button` component
|
42
|
+
* within the footer section.
|
43
|
+
* @slot footer-button-primary - This slot is for passing primary variant of
|
44
|
+
* `mdc-button` component within the footer section.
|
45
|
+
*
|
46
|
+
*/
|
47
|
+
declare class Dialog extends Dialog_base {
|
48
|
+
/**
|
49
|
+
* The unique ID of the dialog
|
50
|
+
*/
|
51
|
+
id: string;
|
52
|
+
/**
|
53
|
+
* The ID of the element that triggers the dialog
|
54
|
+
*/
|
55
|
+
triggerId: string;
|
56
|
+
/**
|
57
|
+
* The visibility of the dialog
|
58
|
+
* @default false
|
59
|
+
*/
|
60
|
+
visible: boolean;
|
61
|
+
/**
|
62
|
+
* The z-index of the dialog
|
63
|
+
* @default 1000
|
64
|
+
*/
|
65
|
+
zIndex: number;
|
66
|
+
/**
|
67
|
+
* The size of the dialog, can be 'small' (432x332), 'medium' (656x356), or 'large' (992x412)
|
68
|
+
* @default small
|
69
|
+
*/
|
70
|
+
size: DialogSize;
|
71
|
+
variant: DialogVariant;
|
72
|
+
/**
|
73
|
+
* Defines a string value for the aria-label attribute for close button accessibility
|
74
|
+
*/
|
75
|
+
closeButtonAriaLabel: string | null;
|
76
|
+
/**
|
77
|
+
* Defines a string value for the aria-labelledby attribute that refers to the element
|
78
|
+
* labeling the dialog for accessibility
|
79
|
+
*/
|
80
|
+
ariaLabelledby: string | null;
|
81
|
+
/**
|
82
|
+
* Defines a string value for the aria-label attribute when header is not used
|
83
|
+
*/
|
84
|
+
ariaLabel: string | null;
|
85
|
+
/**
|
86
|
+
* Defines a string value to display as the title of the dialog
|
87
|
+
*/
|
88
|
+
headerText: string;
|
89
|
+
/**
|
90
|
+
* Defines a string value to display as the under-header description of the dialog
|
91
|
+
*/
|
92
|
+
descriptionText: string;
|
93
|
+
/**
|
94
|
+
* The html tag to be used for the header text
|
95
|
+
*/
|
96
|
+
headerTagName: string;
|
97
|
+
/**
|
98
|
+
* The html tag to be used for the below-header description text
|
99
|
+
*/
|
100
|
+
descriptionTagName: string;
|
101
|
+
/**
|
102
|
+
* Role of the dialog
|
103
|
+
* @default dialog
|
104
|
+
*/
|
105
|
+
role: DialogRole;
|
106
|
+
/** @internal */
|
107
|
+
triggerElement: HTMLElement | null;
|
108
|
+
/** @internal */
|
109
|
+
private utils;
|
110
|
+
/** @internal */
|
111
|
+
backdropElement: HTMLElement | null;
|
112
|
+
constructor();
|
113
|
+
protected firstUpdated(changedProperties: PropertyValues): Promise<void>;
|
114
|
+
disconnectedCallback(): Promise<void>;
|
115
|
+
/**
|
116
|
+
* Sets up the trigger listener for focus trap
|
117
|
+
*/
|
118
|
+
private setupTriggerListener;
|
119
|
+
/**
|
120
|
+
* Removes the trigger event listener
|
121
|
+
*/
|
122
|
+
private removeEventListeners;
|
123
|
+
protected updated(changedProperties: PropertyValues): Promise<void>;
|
124
|
+
/**
|
125
|
+
* Handles the escape keydown event to close the dialog.
|
126
|
+
* @internal
|
127
|
+
* @param event - The keyboard event.
|
128
|
+
*/
|
129
|
+
private onEscapeKeydown;
|
130
|
+
/**
|
131
|
+
* Handles the dialog visibility change.
|
132
|
+
* Handles the exit event to close the dialog.
|
133
|
+
*
|
134
|
+
* @param oldValue - The old value of the visible property.
|
135
|
+
* @param newValue - The new value of the visible property.
|
136
|
+
*/
|
137
|
+
private isOpenUpdated;
|
138
|
+
/**
|
139
|
+
* Hides the dialog.
|
140
|
+
* @internal
|
141
|
+
*/
|
142
|
+
hideDialog: () => void;
|
143
|
+
/**
|
144
|
+
* Sets the focusable elements inside the dialog.
|
145
|
+
*/
|
146
|
+
private handleCreateDialogFirstUpdate;
|
147
|
+
render(): import("lit-html").TemplateResult<1>;
|
148
|
+
static styles: Array<CSSResult>;
|
149
|
+
}
|
150
|
+
export default Dialog;
|
@@ -0,0 +1,340 @@
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
6
|
+
};
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
9
|
+
};
|
10
|
+
import { html, nothing } from 'lit';
|
11
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
12
|
+
import { property } from 'lit/decorators.js';
|
13
|
+
import styles from './dialog.styles';
|
14
|
+
import { Component } from '../../models';
|
15
|
+
import { FocusTrapMixin } from '../../utils/mixins/FocusTrapMixin';
|
16
|
+
import { DEFAULTS } from './dialog.constants';
|
17
|
+
import { DialogUtils } from './dialog.utils';
|
18
|
+
import { TYPE, VALID_TEXT_TAGS } from '../text/text.constants';
|
19
|
+
import { DialogEventManager } from './dialog.events';
|
20
|
+
import { BUTTON_VARIANTS, ICON_BUTTON_SIZES } from '../button/button.constants';
|
21
|
+
import { CardAndDialogFooterMixin } from '../../utils/mixins/CardAndDialogFooterMixin';
|
22
|
+
/**
|
23
|
+
* Dialog component is a modal dialog that can be used to display information or prompt the user for input.
|
24
|
+
* It can be used to create custom dialogs where content for the body and footer actions is provided by the consumer.
|
25
|
+
* The dialog is available in three sizes: small, medium, and large. It may also receive custom styling/sizing.
|
26
|
+
* The dialog interrupts the user and will block interaction with the rest of the application until it is closed.
|
27
|
+
*
|
28
|
+
* Dialog component have 2 variants: default and promotional.
|
29
|
+
*
|
30
|
+
* **Accessibility notes for consuming (have to be explicitly set when you consume the component)**
|
31
|
+
*
|
32
|
+
* - The dialog should have an aria-label or aria-labelledby attribute to provide a label for screen readers.
|
33
|
+
* - Use aria-labelledby to reference the ID of the element that labels the dialog when there is no visible title.
|
34
|
+
*
|
35
|
+
* **Note: Programmatic show/hide requires the ? prefix on the visible attribute**
|
36
|
+
* - Use `?visible=true/false` as an attribute instead of `visible=true/false`
|
37
|
+
* - Reference docs for more info: https://lit.dev/docs/templates/expressions/#boolean-attribute-expressions
|
38
|
+
*
|
39
|
+
* @dependency mdc-button
|
40
|
+
* @dependency mdc-text
|
41
|
+
*
|
42
|
+
* @tagname mdc-dialog
|
43
|
+
*
|
44
|
+
* @event shown - (React: onShown) Dispatched when the dialog is shown
|
45
|
+
* @event hidden - (React: onHidden) Dispatched when the dialog is hidden
|
46
|
+
* @event created - (React: onCreated) Dispatched when the dialog is created (added to the DOM)
|
47
|
+
* @event destroyed - (React: onDestroyed) Dispatched when the dialog is destroyed (removed from the DOM)
|
48
|
+
*
|
49
|
+
* @cssproperty --mdc-dialog-primary-background-color - primary background color of the dialog
|
50
|
+
* @cssproperty --mdc-dialog-border-color - border color of the dialog
|
51
|
+
* @cssproperty --mdc-dialog-header-text-color - text color of the header/title of the dialog
|
52
|
+
* @cssproperty --mdc-dialog-description-text-color - text color of the below header description of the dialog
|
53
|
+
* @cssproperty --mdc-dialog-elevation-3 - elevation of the dialog
|
54
|
+
* @cssproperty --mdc-dialog-width - width of the dialog
|
55
|
+
*
|
56
|
+
* @slot dialog-body - Slot for the dialog body content
|
57
|
+
* @slot footer-link - This slot is for passing `mdc-link` component within the footer section.
|
58
|
+
* @slot footer-button-secondary - This slot is for passing secondary variant of `mdc-button` component
|
59
|
+
* within the footer section.
|
60
|
+
* @slot footer-button-primary - This slot is for passing primary variant of
|
61
|
+
* `mdc-button` component within the footer section.
|
62
|
+
*
|
63
|
+
*/
|
64
|
+
class Dialog extends FocusTrapMixin(CardAndDialogFooterMixin(Component)) {
|
65
|
+
constructor() {
|
66
|
+
super();
|
67
|
+
/**
|
68
|
+
* The unique ID of the dialog
|
69
|
+
*/
|
70
|
+
this.id = '';
|
71
|
+
/**
|
72
|
+
* The ID of the element that triggers the dialog
|
73
|
+
*/
|
74
|
+
this.triggerId = '';
|
75
|
+
/**
|
76
|
+
* The visibility of the dialog
|
77
|
+
* @default false
|
78
|
+
*/
|
79
|
+
this.visible = DEFAULTS.VISIBLE;
|
80
|
+
/**
|
81
|
+
* The z-index of the dialog
|
82
|
+
* @default 1000
|
83
|
+
*/
|
84
|
+
this.zIndex = DEFAULTS.Z_INDEX;
|
85
|
+
/**
|
86
|
+
* The size of the dialog, can be 'small' (432x332), 'medium' (656x356), or 'large' (992x412)
|
87
|
+
* @default small
|
88
|
+
*/
|
89
|
+
this.size = DEFAULTS.SIZE;
|
90
|
+
this.variant = DEFAULTS.VARIANT;
|
91
|
+
/**
|
92
|
+
* Defines a string value for the aria-label attribute for close button accessibility
|
93
|
+
*/
|
94
|
+
this.closeButtonAriaLabel = null;
|
95
|
+
/**
|
96
|
+
* Defines a string value for the aria-labelledby attribute that refers to the element
|
97
|
+
* labeling the dialog for accessibility
|
98
|
+
*/
|
99
|
+
this.ariaLabelledby = null;
|
100
|
+
/**
|
101
|
+
* Defines a string value for the aria-label attribute when header is not used
|
102
|
+
*/
|
103
|
+
this.ariaLabel = null;
|
104
|
+
/**
|
105
|
+
* Defines a string value to display as the title of the dialog
|
106
|
+
*/
|
107
|
+
this.headerText = '';
|
108
|
+
/**
|
109
|
+
* Defines a string value to display as the under-header description of the dialog
|
110
|
+
*/
|
111
|
+
this.descriptionText = '';
|
112
|
+
/**
|
113
|
+
* The html tag to be used for the header text
|
114
|
+
*/
|
115
|
+
this.headerTagName = DEFAULTS.HEADER_TAG_NAME;
|
116
|
+
/**
|
117
|
+
* The html tag to be used for the below-header description text
|
118
|
+
*/
|
119
|
+
this.descriptionTagName = DEFAULTS.DESCRIPTION_TAG_NAME;
|
120
|
+
/**
|
121
|
+
* Role of the dialog
|
122
|
+
* @default dialog
|
123
|
+
*/
|
124
|
+
this.role = DEFAULTS.ROLE;
|
125
|
+
/** @internal */
|
126
|
+
this.triggerElement = null;
|
127
|
+
/** @internal */
|
128
|
+
this.backdropElement = null;
|
129
|
+
/**
|
130
|
+
* Handles the escape keydown event to close the dialog.
|
131
|
+
* @internal
|
132
|
+
* @param event - The keyboard event.
|
133
|
+
*/
|
134
|
+
this.onEscapeKeydown = (event) => {
|
135
|
+
if (!this.visible || event.code !== 'Escape') {
|
136
|
+
return;
|
137
|
+
}
|
138
|
+
event.preventDefault();
|
139
|
+
this.hideDialog();
|
140
|
+
};
|
141
|
+
/**
|
142
|
+
* Hides the dialog.
|
143
|
+
* @internal
|
144
|
+
*/
|
145
|
+
this.hideDialog = () => {
|
146
|
+
this.visible = false;
|
147
|
+
};
|
148
|
+
/** @internal */
|
149
|
+
this.utils = new DialogUtils(this);
|
150
|
+
document.addEventListener('keydown', this.onEscapeKeydown);
|
151
|
+
}
|
152
|
+
async firstUpdated(changedProperties) {
|
153
|
+
super.firstUpdated(changedProperties);
|
154
|
+
this.setupTriggerListener();
|
155
|
+
this.utils.setupAriaAttributes();
|
156
|
+
this.style.zIndex = `${this.zIndex}`;
|
157
|
+
DialogEventManager.onCreatedDialog(this);
|
158
|
+
if (this.visible) {
|
159
|
+
await this.handleCreateDialogFirstUpdate();
|
160
|
+
}
|
161
|
+
}
|
162
|
+
async disconnectedCallback() {
|
163
|
+
super.disconnectedCallback();
|
164
|
+
this.removeEventListeners();
|
165
|
+
document.removeEventListener('keydown', this.onEscapeKeydown);
|
166
|
+
DialogEventManager.onDestroyedDialog(this);
|
167
|
+
}
|
168
|
+
/**
|
169
|
+
* Sets up the trigger listener for focus trap
|
170
|
+
*/
|
171
|
+
setupTriggerListener() {
|
172
|
+
if (!this.triggerId)
|
173
|
+
return;
|
174
|
+
this.triggerElement = this.getRootNode().querySelector(`[id="${this.triggerId}"]`);
|
175
|
+
if (!this.triggerElement)
|
176
|
+
return;
|
177
|
+
this.addEventListener('focus-trap-exit', this.hideDialog);
|
178
|
+
}
|
179
|
+
/**
|
180
|
+
* Removes the trigger event listener
|
181
|
+
*/
|
182
|
+
removeEventListeners() {
|
183
|
+
if (!this.triggerElement)
|
184
|
+
return;
|
185
|
+
this.removeEventListener('focus-trap-exit', this.hideDialog);
|
186
|
+
}
|
187
|
+
async updated(changedProperties) {
|
188
|
+
super.updated(changedProperties);
|
189
|
+
if (changedProperties.has('visible')) {
|
190
|
+
const oldValue = changedProperties.get('visible');
|
191
|
+
await this.isOpenUpdated(oldValue, this.visible);
|
192
|
+
}
|
193
|
+
if (changedProperties.has('zIndex')) {
|
194
|
+
this.setAttribute('z-index', `${this.zIndex}`);
|
195
|
+
}
|
196
|
+
if (changedProperties.has('variant')) {
|
197
|
+
this.updateFooterButtonColors(this.variant);
|
198
|
+
}
|
199
|
+
if (changedProperties.has('aria-label')
|
200
|
+
|| changedProperties.has('aria-labelledby')) {
|
201
|
+
this.utils.setupAriaAttributes();
|
202
|
+
}
|
203
|
+
}
|
204
|
+
/**
|
205
|
+
* Handles the dialog visibility change.
|
206
|
+
* Handles the exit event to close the dialog.
|
207
|
+
*
|
208
|
+
* @param oldValue - The old value of the visible property.
|
209
|
+
* @param newValue - The new value of the visible property.
|
210
|
+
*/
|
211
|
+
async isOpenUpdated(oldValue, newValue) {
|
212
|
+
var _a, _b, _c;
|
213
|
+
if (oldValue === newValue || !this.triggerElement) {
|
214
|
+
return;
|
215
|
+
}
|
216
|
+
if (newValue) {
|
217
|
+
this.enabledFocusTrap = true;
|
218
|
+
this.enabledPreventScroll = true;
|
219
|
+
this.utils.createBackdrop();
|
220
|
+
await this.handleCreateDialogFirstUpdate();
|
221
|
+
this.triggerElement.setAttribute('aria-expanded', 'true');
|
222
|
+
this.triggerElement.setAttribute('aria-haspopup', this.triggerElement.getAttribute('aria-haspopup') || 'dialog');
|
223
|
+
DialogEventManager.onShowDialog(this);
|
224
|
+
}
|
225
|
+
else {
|
226
|
+
(_a = this.backdropElement) === null || _a === void 0 ? void 0 : _a.remove();
|
227
|
+
this.backdropElement = null;
|
228
|
+
(_b = this.deactivateFocusTrap) === null || _b === void 0 ? void 0 : _b.call(this);
|
229
|
+
this.triggerElement.removeAttribute('aria-expanded');
|
230
|
+
this.triggerElement.removeAttribute('aria-haspopup');
|
231
|
+
(_c = this.triggerElement) === null || _c === void 0 ? void 0 : _c.focus();
|
232
|
+
DialogEventManager.onHideDialog(this);
|
233
|
+
}
|
234
|
+
}
|
235
|
+
/**
|
236
|
+
* Sets the focusable elements inside the dialog.
|
237
|
+
*/
|
238
|
+
async handleCreateDialogFirstUpdate() {
|
239
|
+
var _a, _b;
|
240
|
+
if (this.visible) {
|
241
|
+
(_a = this.setFocusableElements) === null || _a === void 0 ? void 0 : _a.call(this);
|
242
|
+
await this.updateComplete;
|
243
|
+
(_b = this.setInitialFocus) === null || _b === void 0 ? void 0 : _b.call(this);
|
244
|
+
}
|
245
|
+
}
|
246
|
+
render() {
|
247
|
+
var _a;
|
248
|
+
return html `
|
249
|
+
${this.headerText
|
250
|
+
? html `
|
251
|
+
<div part="header">
|
252
|
+
<mdc-text
|
253
|
+
part="header-text"
|
254
|
+
tagname="${VALID_TEXT_TAGS[this.headerTagName.toUpperCase()]}"
|
255
|
+
type="${TYPE.BODY_LARGE_BOLD}"
|
256
|
+
>
|
257
|
+
${this.headerText}
|
258
|
+
</mdc-text>
|
259
|
+
<mdc-text
|
260
|
+
part="description-text"
|
261
|
+
tagname="${VALID_TEXT_TAGS[this.descriptionTagName.toUpperCase()]}"
|
262
|
+
type="${TYPE.BODY_MIDSIZE_REGULAR}"
|
263
|
+
>
|
264
|
+
${(_a = this.descriptionText) !== null && _a !== void 0 ? _a : nothing}
|
265
|
+
</mdc-text>
|
266
|
+
</div>`
|
267
|
+
: nothing}
|
268
|
+
<mdc-button
|
269
|
+
part="dialog-close-btn"
|
270
|
+
prefix-icon="${DEFAULTS.CANCEL_ICON}"
|
271
|
+
variant="${BUTTON_VARIANTS.TERTIARY}"
|
272
|
+
size="${ICON_BUTTON_SIZES[20]}"
|
273
|
+
aria-label="${ifDefined(this.closeButtonAriaLabel) || ''}"
|
274
|
+
@click="${this.hideDialog}"
|
275
|
+
></mdc-button>
|
276
|
+
<div part="body">
|
277
|
+
<slot name="dialog-body"></slot>
|
278
|
+
</div>
|
279
|
+
${this.renderFooter()}
|
280
|
+
`;
|
281
|
+
}
|
282
|
+
}
|
283
|
+
Dialog.styles = [...Component.styles, ...styles];
|
284
|
+
__decorate([
|
285
|
+
property({ type: String, reflect: true }),
|
286
|
+
__metadata("design:type", String)
|
287
|
+
], Dialog.prototype, "id", void 0);
|
288
|
+
__decorate([
|
289
|
+
property({ type: String, reflect: true }),
|
290
|
+
__metadata("design:type", String)
|
291
|
+
], Dialog.prototype, "triggerId", void 0);
|
292
|
+
__decorate([
|
293
|
+
property({ type: Boolean, reflect: true }),
|
294
|
+
__metadata("design:type", Boolean)
|
295
|
+
], Dialog.prototype, "visible", void 0);
|
296
|
+
__decorate([
|
297
|
+
property({ type: Number, reflect: true, attribute: 'z-index' }),
|
298
|
+
__metadata("design:type", Number)
|
299
|
+
], Dialog.prototype, "zIndex", void 0);
|
300
|
+
__decorate([
|
301
|
+
property({ type: String, reflect: true }),
|
302
|
+
__metadata("design:type", Object)
|
303
|
+
], Dialog.prototype, "size", void 0);
|
304
|
+
__decorate([
|
305
|
+
property({ type: String, reflect: true }),
|
306
|
+
__metadata("design:type", String)
|
307
|
+
], Dialog.prototype, "variant", void 0);
|
308
|
+
__decorate([
|
309
|
+
property({ type: String, attribute: 'close-button-aria-label' }),
|
310
|
+
__metadata("design:type", Object)
|
311
|
+
], Dialog.prototype, "closeButtonAriaLabel", void 0);
|
312
|
+
__decorate([
|
313
|
+
property({ type: String, reflect: true, attribute: 'aria-labelledby' }),
|
314
|
+
__metadata("design:type", Object)
|
315
|
+
], Dialog.prototype, "ariaLabelledby", void 0);
|
316
|
+
__decorate([
|
317
|
+
property({ type: String, reflect: true, attribute: 'aria-label' }),
|
318
|
+
__metadata("design:type", Object)
|
319
|
+
], Dialog.prototype, "ariaLabel", void 0);
|
320
|
+
__decorate([
|
321
|
+
property({ type: String, reflect: true, attribute: 'header-text' }),
|
322
|
+
__metadata("design:type", String)
|
323
|
+
], Dialog.prototype, "headerText", void 0);
|
324
|
+
__decorate([
|
325
|
+
property({ type: String, reflect: true, attribute: 'description-text' }),
|
326
|
+
__metadata("design:type", String)
|
327
|
+
], Dialog.prototype, "descriptionText", void 0);
|
328
|
+
__decorate([
|
329
|
+
property({ type: String, reflect: true, attribute: 'header-tag-name' }),
|
330
|
+
__metadata("design:type", String)
|
331
|
+
], Dialog.prototype, "headerTagName", void 0);
|
332
|
+
__decorate([
|
333
|
+
property({ type: String, reflect: true, attribute: 'description-tag-name' }),
|
334
|
+
__metadata("design:type", String)
|
335
|
+
], Dialog.prototype, "descriptionTagName", void 0);
|
336
|
+
__decorate([
|
337
|
+
property({ type: String, reflect: true }),
|
338
|
+
__metadata("design:type", String)
|
339
|
+
], Dialog.prototype, "role", void 0);
|
340
|
+
export default Dialog;
|