@momentum-design/components 0.80.5 → 0.81.1

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.
Files changed (33) hide show
  1. package/dist/browser/index.js +276 -239
  2. package/dist/browser/index.js.map +4 -4
  3. package/dist/components/dialog/dialog.component.d.ts +49 -21
  4. package/dist/components/dialog/dialog.component.js +143 -93
  5. package/dist/components/dialog/dialog.constants.d.ts +1 -0
  6. package/dist/components/dialog/dialog.constants.js +1 -0
  7. package/dist/components/popover/popover.component.d.ts +8 -1
  8. package/dist/components/popover/popover.component.js +16 -4
  9. package/dist/components/popover/popover.constants.d.ts +1 -0
  10. package/dist/components/popover/popover.constants.js +1 -0
  11. package/dist/components/popover/popover.utils.js +1 -1
  12. package/dist/components/skeleton/index.d.ts +7 -0
  13. package/dist/components/skeleton/index.js +4 -0
  14. package/dist/components/skeleton/skeleton.component.d.ts +46 -0
  15. package/dist/components/skeleton/skeleton.component.js +86 -0
  16. package/dist/components/skeleton/skeleton.constants.d.ts +11 -0
  17. package/dist/components/skeleton/skeleton.constants.js +12 -0
  18. package/dist/components/skeleton/skeleton.styles.d.ts +2 -0
  19. package/dist/components/skeleton/skeleton.styles.js +40 -0
  20. package/dist/components/skeleton/skeleton.types.d.ts +4 -0
  21. package/dist/components/skeleton/skeleton.types.js +1 -0
  22. package/dist/components/toggletip/toggletip.component.js +1 -0
  23. package/dist/components/tooltip/tooltip.component.js +0 -2
  24. package/dist/custom-elements.json +776 -486
  25. package/dist/index.d.ts +6 -3
  26. package/dist/index.js +4 -2
  27. package/dist/react/index.d.ts +2 -1
  28. package/dist/react/index.js +2 -1
  29. package/dist/react/skeleton/index.d.ts +25 -0
  30. package/dist/react/skeleton/index.js +34 -0
  31. package/dist/utils/mixins/FocusTrapMixin.d.ts +6 -5
  32. package/dist/utils/mixins/FocusTrapMixin.js +51 -22
  33. package/package.json +1 -1
@@ -84,15 +84,25 @@ declare class Dialog extends Dialog_base {
84
84
  * Defines a string value for the aria-label attribute for close button accessibility
85
85
  */
86
86
  closeButtonAriaLabel: string | null;
87
+ /**
88
+ * Defines a string value for the aria-label attribute when header is not used
89
+ */
90
+ ariaLabel: string | null;
87
91
  /**
88
92
  * Defines a string value for the aria-labelledby attribute that refers to the element
89
93
  * labeling the dialog for accessibility
90
94
  */
91
95
  ariaLabelledby: string | null;
92
96
  /**
93
- * Defines a string value for the aria-label attribute when header is not used
97
+ * Defines a string value for the aria-describedby attribute that refers to the element
98
+ * describing the dialog for accessibility
94
99
  */
95
- ariaLabel: string | null;
100
+ ariaDescribedBy: string | null;
101
+ /**
102
+ * Defines a string value for the aria-description attribute that refers to the element
103
+ * describing the dialog for accessibility
104
+ */
105
+ ariaDescription: string | null;
96
106
  /**
97
107
  * Defines a string value to display as the title of the dialog
98
108
  */
@@ -114,19 +124,45 @@ declare class Dialog extends Dialog_base {
114
124
  * @default dialog
115
125
  */
116
126
  role: DialogRole;
127
+ /**
128
+ * Disable setting the aria-haspopup attribute on trigger element.
129
+ * Make sure to set this to true when the popover is extended and its role
130
+ * is not 'dialog' or 'alertdialog' i.e. listbox, menu, etc.
131
+ * @default false
132
+ */
133
+ disableAriaHasPopup: boolean;
134
+ /**
135
+ * For now FocusTrap is always true as the dialog is a modal component only.
136
+ * This means it will always trap focus within the dialog when it is open.
137
+ */
138
+ /** @internal */
139
+ protected focusTrap: boolean;
117
140
  /** @internal */
118
141
  protected triggerElement: HTMLElement | null;
119
142
  /** @internal */
120
143
  protected backdropElement: HTMLElement | null;
121
144
  /** @internal */
122
145
  protected lastActiveElement: HTMLElement | null;
123
- constructor();
146
+ connectedCallback(): void;
147
+ disconnectedCallback(): void;
148
+ protected firstUpdated(changedProperties: PropertyValues): Promise<void>;
149
+ protected updated(changedProperties: PropertyValues): Promise<void>;
124
150
  /**
125
- * Sets up the aria attributes for the dialog based on the header text and aria attributes.
126
- * If no header text or aria attributes are provided, it will use the triggerId if available.
151
+ * Sets up the aria-haspopup attribute for the dialog.
152
+ * This is used to indicate that the dialog can be opened by a trigger element.
153
+ * If the trigger element does not have an aria-haspopup attribute, it will default to 'dialog'.
154
+ *
127
155
  * @internal
128
156
  */
129
- private setupAriaAttributes;
157
+ private setupAriaHasPopup;
158
+ /**
159
+ * Sets up the aria-labelledby and aria-describedby attributes for the dialog.
160
+ * If no header text or description text is provided, it will point to the the triggerId if available.
161
+ * If neither is provided, it will not set the attributes.
162
+ *
163
+ * @internal
164
+ */
165
+ private setupAriaLabelledDescribedBy;
130
166
  /**
131
167
  * Creates a backdrop element for the dialog.
132
168
  * The backdrop is a full-screen overlay that appears behind the dialog when it is open.
@@ -134,17 +170,6 @@ declare class Dialog extends Dialog_base {
134
170
  * @internal
135
171
  */
136
172
  private createBackdrop;
137
- protected firstUpdated(changedProperties: PropertyValues): Promise<void>;
138
- disconnectedCallback(): Promise<void>;
139
- /**
140
- * Sets up the trigger listener for focus trap
141
- */
142
- private setupTriggerListener;
143
- /**
144
- * Removes the trigger event listener
145
- */
146
- private removeEventListeners;
147
- protected updated(changedProperties: PropertyValues): Promise<void>;
148
173
  /**
149
174
  * Handles the escape keydown event to close the dialog.
150
175
  * @internal
@@ -159,6 +184,13 @@ declare class Dialog extends Dialog_base {
159
184
  * @param newValue - The new value of the visible property.
160
185
  */
161
186
  private isOpenUpdated;
187
+ /**
188
+ * Sets the focs back to the trigger element or the last active element.
189
+ * This is called when the dialog is closed to ensure that the user can continue interacting with the application.
190
+ *
191
+ * @internal
192
+ */
193
+ private focusBackToTrigger;
162
194
  /**
163
195
  * Hides the dialog.
164
196
  * @internal
@@ -169,10 +201,6 @@ declare class Dialog extends Dialog_base {
169
201
  * @internal
170
202
  */
171
203
  showDialog: () => void;
172
- /**
173
- * Sets the focusable elements inside the dialog.
174
- */
175
- private handleCreateDialogFirstUpdate;
176
204
  render(): import("lit-html").TemplateResult<1>;
177
205
  static styles: Array<CSSResult>;
178
206
  }
@@ -67,7 +67,7 @@ import { CardAndDialogFooterMixin } from '../../utils/mixins/CardAndDialogFooter
67
67
  */
68
68
  class Dialog extends FocusTrapMixin(CardAndDialogFooterMixin(Component)) {
69
69
  constructor() {
70
- super();
70
+ super(...arguments);
71
71
  /**
72
72
  * The unique ID of the dialog
73
73
  */
@@ -96,15 +96,25 @@ class Dialog extends FocusTrapMixin(CardAndDialogFooterMixin(Component)) {
96
96
  * Defines a string value for the aria-label attribute for close button accessibility
97
97
  */
98
98
  this.closeButtonAriaLabel = null;
99
+ /**
100
+ * Defines a string value for the aria-label attribute when header is not used
101
+ */
102
+ this.ariaLabel = null;
99
103
  /**
100
104
  * Defines a string value for the aria-labelledby attribute that refers to the element
101
105
  * labeling the dialog for accessibility
102
106
  */
103
107
  this.ariaLabelledby = null;
104
108
  /**
105
- * Defines a string value for the aria-label attribute when header is not used
109
+ * Defines a string value for the aria-describedby attribute that refers to the element
110
+ * describing the dialog for accessibility
106
111
  */
107
- this.ariaLabel = null;
112
+ this.ariaDescribedBy = null;
113
+ /**
114
+ * Defines a string value for the aria-description attribute that refers to the element
115
+ * describing the dialog for accessibility
116
+ */
117
+ this.ariaDescription = null;
108
118
  /**
109
119
  * The html tag to be used for the header text
110
120
  */
@@ -118,6 +128,19 @@ class Dialog extends FocusTrapMixin(CardAndDialogFooterMixin(Component)) {
118
128
  * @default dialog
119
129
  */
120
130
  this.role = DEFAULTS.ROLE;
131
+ /**
132
+ * Disable setting the aria-haspopup attribute on trigger element.
133
+ * Make sure to set this to true when the popover is extended and its role
134
+ * is not 'dialog' or 'alertdialog' i.e. listbox, menu, etc.
135
+ * @default false
136
+ */
137
+ this.disableAriaHasPopup = DEFAULTS.DISABLE_ARIA_HAS_POPUP;
138
+ /**
139
+ * For now FocusTrap is always true as the dialog is a modal component only.
140
+ * This means it will always trap focus within the dialog when it is open.
141
+ */
142
+ /** @internal */
143
+ this.focusTrap = true;
121
144
  /** @internal */
122
145
  this.triggerElement = null;
123
146
  /** @internal */
@@ -150,22 +173,94 @@ class Dialog extends FocusTrapMixin(CardAndDialogFooterMixin(Component)) {
150
173
  this.showDialog = () => {
151
174
  this.visible = true;
152
175
  };
153
- document.addEventListener('keydown', this.onEscapeKeydown);
176
+ }
177
+ connectedCallback() {
178
+ super.connectedCallback();
179
+ document.addEventListener('keydown', this.onEscapeKeydown.bind(this));
180
+ }
181
+ disconnectedCallback() {
182
+ var _a, _b, _c;
183
+ super.disconnectedCallback();
184
+ document.removeEventListener('keydown', this.onEscapeKeydown);
185
+ (_a = this.backdropElement) === null || _a === void 0 ? void 0 : _a.remove();
186
+ this.backdropElement = null;
187
+ (_b = this.deactivateFocusTrap) === null || _b === void 0 ? void 0 : _b.call(this);
188
+ // Set aria-expanded attribute on the trigger element to false if it exists
189
+ (_c = this.triggerElement) === null || _c === void 0 ? void 0 : _c.setAttribute('aria-expanded', 'false');
190
+ this.focusBackToTrigger();
191
+ DialogEventManager.onDestroyedDialog(this);
192
+ }
193
+ async firstUpdated(changedProperties) {
194
+ super.firstUpdated(changedProperties);
195
+ this.setAttribute('aria-modal', 'true');
196
+ this.setupAriaLabelledDescribedBy();
197
+ this.style.zIndex = `${this.zIndex}`;
198
+ DialogEventManager.onCreatedDialog(this);
199
+ }
200
+ async updated(changedProperties) {
201
+ super.updated(changedProperties);
202
+ if (changedProperties.has('triggerId')) {
203
+ this.triggerElement = this.getRootNode().querySelector(`[id="${this.triggerId}"]`);
204
+ this.setupAriaHasPopup();
205
+ }
206
+ if (changedProperties.has('visible')) {
207
+ const oldValue = changedProperties.get('visible');
208
+ await this.isOpenUpdated(oldValue, this.visible);
209
+ }
210
+ if (changedProperties.has('zIndex')) {
211
+ this.setAttribute('z-index', `${this.zIndex}`);
212
+ }
213
+ if (changedProperties.has('variant')) {
214
+ this.updateFooterButtonColors(this.variant);
215
+ }
216
+ if (changedProperties.has('ariaLabel')
217
+ || changedProperties.has('ariaLabelledBy')
218
+ || changedProperties.has('ariaDescribedBy')
219
+ || changedProperties.has('ariaDescription')
220
+ || changedProperties.has('headerText')
221
+ || changedProperties.has('descriptionText')) {
222
+ this.setupAriaLabelledDescribedBy();
223
+ }
154
224
  }
155
225
  /**
156
- * Sets up the aria attributes for the dialog based on the header text and aria attributes.
157
- * If no header text or aria attributes are provided, it will use the triggerId if available.
226
+ * Sets up the aria-haspopup attribute for the dialog.
227
+ * This is used to indicate that the dialog can be opened by a trigger element.
228
+ * If the trigger element does not have an aria-haspopup attribute, it will default to 'dialog'.
229
+ *
158
230
  * @internal
159
231
  */
160
- setupAriaAttributes() {
161
- if (this.headerText && !this.ariaLabel && !this.ariaLabelledby) {
162
- this.setAttribute('aria-labelledby', this.headerText);
232
+ setupAriaHasPopup() {
233
+ var _a, _b;
234
+ if (!this.disableAriaHasPopup) {
235
+ (_a = this.triggerElement) === null || _a === void 0 ? void 0 : _a.setAttribute('aria-haspopup', ((_b = this.triggerElement) === null || _b === void 0 ? void 0 : _b.getAttribute('aria-haspopup')) || 'dialog');
163
236
  }
164
- else if (!this.headerText && !this.ariaLabel && !this.ariaLabelledby) {
165
- if (this.triggerId) {
237
+ }
238
+ /**
239
+ * Sets up the aria-labelledby and aria-describedby attributes for the dialog.
240
+ * If no header text or description text is provided, it will point to the the triggerId if available.
241
+ * If neither is provided, it will not set the attributes.
242
+ *
243
+ * @internal
244
+ */
245
+ setupAriaLabelledDescribedBy() {
246
+ // If aria-labelledby or aria-label is already set, do not override it
247
+ if (!this.ariaLabelledby && !this.ariaLabel) {
248
+ if (this.headerText) {
249
+ this.setAttribute('aria-label', this.headerText);
250
+ }
251
+ else if (this.triggerId) {
166
252
  this.setAttribute('aria-labelledby', this.triggerId);
167
253
  }
168
254
  }
255
+ // If aria-describedby or aria-description is already set, do not override it
256
+ if (!this.ariaDescribedBy && !this.ariaDescription) {
257
+ if (this.descriptionText) {
258
+ this.setAttribute('aria-description', this.descriptionText);
259
+ }
260
+ else if (this.triggerId) {
261
+ this.setAttribute('aria-describedby', this.triggerId);
262
+ }
263
+ }
169
264
  }
170
265
  /**
171
266
  * Creates a backdrop element for the dialog.
@@ -193,58 +288,6 @@ class Dialog extends FocusTrapMixin(CardAndDialogFooterMixin(Component)) {
193
288
  (_a = this.parentElement) === null || _a === void 0 ? void 0 : _a.appendChild(backdrop);
194
289
  this.backdropElement = backdrop;
195
290
  }
196
- async firstUpdated(changedProperties) {
197
- super.firstUpdated(changedProperties);
198
- this.setupTriggerListener();
199
- this.setupAriaAttributes();
200
- this.style.zIndex = `${this.zIndex}`;
201
- DialogEventManager.onCreatedDialog(this);
202
- if (this.visible) {
203
- await this.handleCreateDialogFirstUpdate();
204
- }
205
- }
206
- async disconnectedCallback() {
207
- super.disconnectedCallback();
208
- this.removeEventListeners();
209
- document.removeEventListener('keydown', this.onEscapeKeydown);
210
- DialogEventManager.onDestroyedDialog(this);
211
- }
212
- /**
213
- * Sets up the trigger listener for focus trap
214
- */
215
- setupTriggerListener() {
216
- if (!this.triggerId) {
217
- this.addEventListener('focus-trap-exit', this.hideDialog);
218
- return;
219
- }
220
- this.triggerElement = this.getRootNode().querySelector(`[id="${this.triggerId}"]`);
221
- if (!this.triggerElement)
222
- return;
223
- this.addEventListener('focus-trap-exit', this.hideDialog);
224
- }
225
- /**
226
- * Removes the trigger event listener
227
- */
228
- removeEventListeners() {
229
- this.removeEventListener('focus-trap-exit', this.hideDialog);
230
- }
231
- async updated(changedProperties) {
232
- super.updated(changedProperties);
233
- if (changedProperties.has('visible')) {
234
- const oldValue = changedProperties.get('visible');
235
- await this.isOpenUpdated(oldValue, this.visible);
236
- }
237
- if (changedProperties.has('zIndex')) {
238
- this.setAttribute('z-index', `${this.zIndex}`);
239
- }
240
- if (changedProperties.has('variant')) {
241
- this.updateFooterButtonColors(this.variant);
242
- }
243
- if (changedProperties.has('aria-label')
244
- || changedProperties.has('aria-labelledby')) {
245
- this.setupAriaAttributes();
246
- }
247
- }
248
291
  /**
249
292
  * Handles the dialog visibility change.
250
293
  * Handles the exit event to close the dialog.
@@ -253,51 +296,46 @@ class Dialog extends FocusTrapMixin(CardAndDialogFooterMixin(Component)) {
253
296
  * @param newValue - The new value of the visible property.
254
297
  */
255
298
  async isOpenUpdated(oldValue, newValue) {
256
- var _a, _b;
299
+ var _a, _b, _c, _d, _e, _f;
257
300
  if (oldValue === newValue) {
258
301
  return;
259
302
  }
260
303
  if (newValue && !oldValue) {
261
304
  // Store the currently focused element before opening the dialog
262
305
  this.lastActiveElement = document.activeElement;
263
- this.enabledFocusTrap = true;
264
306
  this.enabledPreventScroll = true;
265
307
  this.createBackdrop();
266
- await this.handleCreateDialogFirstUpdate();
267
- // If we have a trigger element, update its attributes
268
- if (this.triggerElement) {
269
- this.triggerElement.setAttribute('aria-expanded', 'true');
270
- this.triggerElement.setAttribute('aria-haspopup', this.triggerElement.getAttribute('aria-haspopup') || 'dialog');
271
- }
308
+ await this.updateComplete;
309
+ (_a = this.activateFocusTrap) === null || _a === void 0 ? void 0 : _a.call(this);
310
+ (_b = this.setInitialFocus) === null || _b === void 0 ? void 0 : _b.call(this);
311
+ // Set aria-expanded attribute on the trigger element to true if it exists
312
+ (_c = this.triggerElement) === null || _c === void 0 ? void 0 : _c.setAttribute('aria-expanded', 'true');
272
313
  DialogEventManager.onShowDialog(this);
273
314
  }
274
315
  else if (!newValue && oldValue) {
275
- (_a = this.backdropElement) === null || _a === void 0 ? void 0 : _a.remove();
316
+ (_d = this.backdropElement) === null || _d === void 0 ? void 0 : _d.remove();
276
317
  this.backdropElement = null;
277
- (_b = this.deactivateFocusTrap) === null || _b === void 0 ? void 0 : _b.call(this);
278
- // If we have a trigger element, restore focus to it
279
- if (this.triggerElement) {
280
- this.triggerElement.removeAttribute('aria-expanded');
281
- this.triggerElement.removeAttribute('aria-haspopup');
282
- this.triggerElement.focus();
283
- }
284
- else if (this.lastActiveElement && this.lastActiveElement.focus) {
285
- // Otherwise restore focus to the last active element
286
- this.lastActiveElement.focus();
287
- }
318
+ (_e = this.deactivateFocusTrap) === null || _e === void 0 ? void 0 : _e.call(this);
319
+ // Set aria-expanded attribute on the trigger element to false if it exists
320
+ (_f = this.triggerElement) === null || _f === void 0 ? void 0 : _f.setAttribute('aria-expanded', 'false');
321
+ this.focusBackToTrigger();
288
322
  DialogEventManager.onHideDialog(this);
289
323
  }
290
324
  }
291
325
  /**
292
- * Sets the focusable elements inside the dialog.
326
+ * Sets the focs back to the trigger element or the last active element.
327
+ * This is called when the dialog is closed to ensure that the user can continue interacting with the application.
328
+ *
329
+ * @internal
293
330
  */
294
- async handleCreateDialogFirstUpdate() {
295
- var _a, _b;
296
- if (this.visible) {
297
- // Wait for the first update to complete before setting focusable elements
298
- await this.updateComplete;
299
- (_a = this.setFocusableElements) === null || _a === void 0 ? void 0 : _a.call(this);
300
- (_b = this.setInitialFocus) === null || _b === void 0 ? void 0 : _b.call(this);
331
+ focusBackToTrigger() {
332
+ // If the trigger element is defined, focus it
333
+ if (this.triggerElement) {
334
+ this.triggerElement.focus();
335
+ }
336
+ else if (this.lastActiveElement && this.lastActiveElement.focus) {
337
+ // If the trigger element is not defined, focus the last active element
338
+ this.lastActiveElement.focus();
301
339
  }
302
340
  }
303
341
  render() {
@@ -369,14 +407,22 @@ __decorate([
369
407
  property({ type: String, attribute: 'close-button-aria-label' }),
370
408
  __metadata("design:type", Object)
371
409
  ], Dialog.prototype, "closeButtonAriaLabel", void 0);
410
+ __decorate([
411
+ property({ type: String, reflect: true, attribute: 'aria-label' }),
412
+ __metadata("design:type", Object)
413
+ ], Dialog.prototype, "ariaLabel", void 0);
372
414
  __decorate([
373
415
  property({ type: String, reflect: true, attribute: 'aria-labelledby' }),
374
416
  __metadata("design:type", Object)
375
417
  ], Dialog.prototype, "ariaLabelledby", void 0);
376
418
  __decorate([
377
- property({ type: String, reflect: true, attribute: 'aria-label' }),
419
+ property({ type: String, reflect: true, attribute: 'aria-describedby' }),
378
420
  __metadata("design:type", Object)
379
- ], Dialog.prototype, "ariaLabel", void 0);
421
+ ], Dialog.prototype, "ariaDescribedBy", void 0);
422
+ __decorate([
423
+ property({ type: String, reflect: true, attribute: 'aria-description' }),
424
+ __metadata("design:type", Object)
425
+ ], Dialog.prototype, "ariaDescription", void 0);
380
426
  __decorate([
381
427
  property({ type: String, reflect: true, attribute: 'header-text' }),
382
428
  __metadata("design:type", String)
@@ -397,4 +443,8 @@ __decorate([
397
443
  property({ type: String, reflect: true }),
398
444
  __metadata("design:type", String)
399
445
  ], Dialog.prototype, "role", void 0);
446
+ __decorate([
447
+ property({ type: Boolean, reflect: true, attribute: 'disable-aria-haspopup' }),
448
+ __metadata("design:type", Boolean)
449
+ ], Dialog.prototype, "disableAriaHasPopup", void 0);
400
450
  export default Dialog;
@@ -12,6 +12,7 @@ declare const DEFAULTS: {
12
12
  readonly DESCRIPTION_TAG_NAME: "p";
13
13
  readonly CANCEL_ICON: "cancel-bold";
14
14
  readonly VARIANT: "default";
15
+ readonly DISABLE_ARIA_HAS_POPUP: false;
15
16
  };
16
17
  declare const DIALOG_SIZE: readonly ["small", "medium", "large"];
17
18
  declare const DIALOG_ROLE: readonly ["dialog", "alertdialog"];
@@ -13,6 +13,7 @@ const DEFAULTS = {
13
13
  DESCRIPTION_TAG_NAME: 'p',
14
14
  CANCEL_ICON: 'cancel-bold',
15
15
  VARIANT: DIALOG_VARIANT.DEFAULT,
16
+ DISABLE_ARIA_HAS_POPUP: false,
16
17
  };
17
18
  const DIALOG_SIZE = ['small', 'medium', 'large'];
18
19
  const DIALOG_ROLE = ['dialog', 'alertdialog'];
@@ -184,11 +184,18 @@ declare class Popover extends Popover_base {
184
184
  */
185
185
  ariaDescribedby: string | null;
186
186
  /**
187
- * Disable aria-expanded attribute on trigger element.
187
+ * Disable setting the aria-expanded attribute on trigger element.
188
188
  * Make sure to set this to false when the popover is interactive.
189
189
  * @default false
190
190
  */
191
191
  disableAriaExpanded: boolean;
192
+ /**
193
+ * Disable setting the aria-haspopup attribute on trigger element.
194
+ * Make sure to set this to true when the popover is extended and its role
195
+ * is not 'dialog' or 'alertdialog' i.e. listbox, menu, etc.
196
+ * @default false
197
+ */
198
+ disableAriaHasPopup: boolean;
192
199
  arrowElement: HTMLElement | null;
193
200
  triggerElement: HTMLElement | null;
194
201
  /** @internal */
@@ -197,11 +197,18 @@ class Popover extends FocusTrapMixin(Component) {
197
197
  */
198
198
  this.ariaDescribedby = null;
199
199
  /**
200
- * Disable aria-expanded attribute on trigger element.
200
+ * Disable setting the aria-expanded attribute on trigger element.
201
201
  * Make sure to set this to false when the popover is interactive.
202
202
  * @default false
203
203
  */
204
204
  this.disableAriaExpanded = DEFAULTS.DISABLE_ARIA_EXPANDED;
205
+ /**
206
+ * Disable setting the aria-haspopup attribute on trigger element.
207
+ * Make sure to set this to true when the popover is extended and its role
208
+ * is not 'dialog' or 'alertdialog' i.e. listbox, menu, etc.
209
+ * @default false
210
+ */
211
+ this.disableAriaHasPopup = DEFAULTS.DISABLE_ARIA_HAS_POPUP;
205
212
  this.arrowElement = null;
206
213
  this.triggerElement = null;
207
214
  /** @internal */
@@ -325,8 +332,10 @@ class Popover extends FocusTrapMixin(Component) {
325
332
  }
326
333
  }
327
334
  async disconnectedCallback() {
335
+ var _a;
328
336
  super.disconnectedCallback();
329
337
  this.removeEventListeners();
338
+ (_a = this.deactivateFocusTrap) === null || _a === void 0 ? void 0 : _a.call(this);
330
339
  PopoverEventManager.onDestroyedPopover(this);
331
340
  popoverStack.remove(this);
332
341
  }
@@ -425,7 +434,7 @@ class Popover extends FocusTrapMixin(Component) {
425
434
  if (changedProperties.has('disableAriaExpanded')) {
426
435
  this.utils.updateAriaExpandedAttribute();
427
436
  }
428
- if (changedProperties.has('interactive')) {
437
+ if (changedProperties.has('interactive') || changedProperties.has('disableAriaHasPopup')) {
429
438
  this.utils.updateAriaHasPopupAttribute();
430
439
  }
431
440
  }
@@ -445,7 +454,6 @@ class Popover extends FocusTrapMixin(Component) {
445
454
  if (popoverStack.peek() !== this) {
446
455
  popoverStack.push(this);
447
456
  }
448
- this.enabledFocusTrap = this.focusTrap;
449
457
  this.enabledPreventScroll = this.preventScroll;
450
458
  if (this.backdrop) {
451
459
  this.utils.createBackdrop();
@@ -509,7 +517,7 @@ class Popover extends FocusTrapMixin(Component) {
509
517
  if (this.visible && this.interactive) {
510
518
  // Wait for the first update to complete before setting focusable elements
511
519
  await this.updateComplete;
512
- (_a = this.setFocusableElements) === null || _a === void 0 ? void 0 : _a.call(this);
520
+ (_a = this.activateFocusTrap) === null || _a === void 0 ? void 0 : _a.call(this);
513
521
  (_b = this.setInitialFocus) === null || _b === void 0 ? void 0 : _b.call(this);
514
522
  }
515
523
  }
@@ -695,4 +703,8 @@ __decorate([
695
703
  property({ type: Boolean, reflect: true, attribute: 'disable-aria-expanded' }),
696
704
  __metadata("design:type", Boolean)
697
705
  ], Popover.prototype, "disableAriaExpanded", void 0);
706
+ __decorate([
707
+ property({ type: Boolean, reflect: true, attribute: 'disable-aria-haspopup' }),
708
+ __metadata("design:type", Boolean)
709
+ ], Popover.prototype, "disableAriaHasPopup", void 0);
698
710
  export default Popover;
@@ -45,5 +45,6 @@ declare const DEFAULTS: {
45
45
  readonly ROLE: "dialog";
46
46
  readonly Z_INDEX: 1000;
47
47
  readonly DISABLE_ARIA_EXPANDED: false;
48
+ readonly DISABLE_ARIA_HAS_POPUP: false;
48
49
  };
49
50
  export { TAG_NAME, POPOVER_PLACEMENT, COLOR, TRIGGER, DEFAULTS };
@@ -46,5 +46,6 @@ const DEFAULTS = {
46
46
  ROLE: 'dialog',
47
47
  Z_INDEX: 1000,
48
48
  DISABLE_ARIA_EXPANDED: false,
49
+ DISABLE_ARIA_HAS_POPUP: false,
49
50
  };
50
51
  export { TAG_NAME, POPOVER_PLACEMENT, COLOR, TRIGGER, DEFAULTS };
@@ -112,7 +112,7 @@ export class PopoverUtils {
112
112
  */
113
113
  updateAriaHasPopupAttribute() {
114
114
  var _a, _b, _c;
115
- if (this.popover.interactive) {
115
+ if (this.popover.interactive && !this.popover.disableAriaHasPopup) {
116
116
  (_a = this.popover.triggerElement) === null || _a === void 0 ? void 0 : _a.setAttribute('aria-haspopup', ((_b = this.popover.triggerElement) === null || _b === void 0 ? void 0 : _b.getAttribute('aria-haspopup')) || 'dialog');
117
117
  }
118
118
  else {
@@ -0,0 +1,7 @@
1
+ import Skeleton from './skeleton.component';
2
+ declare global {
3
+ interface HTMLElementTagNameMap {
4
+ ['mdc-skeleton']: Skeleton;
5
+ }
6
+ }
7
+ export default Skeleton;
@@ -0,0 +1,4 @@
1
+ import Skeleton from './skeleton.component';
2
+ import { TAG_NAME } from './skeleton.constants';
3
+ Skeleton.register(TAG_NAME);
4
+ export default Skeleton;
@@ -0,0 +1,46 @@
1
+ import type { PropertyValues } from 'lit';
2
+ import { CSSResult } from 'lit';
3
+ import { Component } from '../../models';
4
+ import type { SkeletonVariant } from './skeleton.types';
5
+ /**
6
+ * `mdc-skeleton` is a component that shows a grey placeholder area.
7
+ * It provides visual feedback to users that content is being loaded.
8
+ *
9
+ * **Skeleton Variants:**
10
+ * - **rectangular**: Default variant with 0.25rem border radius
11
+ * - **rounded**: Has 0.5rem border radius
12
+ * - **circular**: Has 50% border radius for circular shapes
13
+ * - **button**: Optimized for button placeholders with 1.25rem border radius
14
+ *
15
+ * **Sizing Behavior:**
16
+ * 1. If wrapping content, takes dimensions of wrapped content
17
+ * 2. Otherwise grows to fill parent container
18
+ *
19
+ * @tagname mdc-skeleton
20
+ *
21
+ * @slot - Content to wrap (optional). When provided, skeleton takes dimensions of this content.
22
+ *
23
+ * @cssproperty --mdc-skeleton-background-color - background color of the skeleton
24
+ * @cssproperty --mdc-skeleton-height - height of the skeleton
25
+ * @cssproperty --mdc-skeleton-width - width of the skeleton
26
+ */
27
+ declare class Skeleton extends Component {
28
+ /**
29
+ * The variant of skeleton to display
30
+ * - **rectangular**: Default rectangular shape with 0.25rem border radius
31
+ * - **rounded**: Rounded rectangle with 0.5rem border radius
32
+ * - **circular**: Circular shape with 50% border radius
33
+ * - **button**: Button placeholder with 1.25rem border radius
34
+ * @default rectangular
35
+ */
36
+ variant: SkeletonVariant;
37
+ /**
38
+ * Styles associated with this component.
39
+ */
40
+ static styles: Array<CSSResult>;
41
+ connectedCallback(): void;
42
+ protected firstUpdated(changedProperties: PropertyValues): void;
43
+ private checkSlotContent;
44
+ protected render(): import("lit-html").TemplateResult<1>;
45
+ }
46
+ export default Skeleton;