@spectrum-web-components/menu 0.33.2 → 0.33.3-overlay.66

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spectrum-web-components/menu",
3
- "version": "0.33.2",
3
+ "version": "0.33.3-overlay.66+30e96d5ea",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -85,16 +85,16 @@
85
85
  ],
86
86
  "dependencies": {
87
87
  "@lit-labs/observers": "^2.0.0",
88
- "@spectrum-web-components/action-button": "^0.33.2",
89
- "@spectrum-web-components/base": "^0.33.2",
90
- "@spectrum-web-components/divider": "^0.33.2",
91
- "@spectrum-web-components/icon": "^0.33.2",
92
- "@spectrum-web-components/icons-ui": "^0.33.2",
93
- "@spectrum-web-components/overlay": "^0.33.2",
94
- "@spectrum-web-components/shared": "^0.33.2"
88
+ "@spectrum-web-components/action-button": "^0.33.3-overlay.66+30e96d5ea",
89
+ "@spectrum-web-components/base": "^0.33.3-overlay.66+30e96d5ea",
90
+ "@spectrum-web-components/divider": "^0.33.3-overlay.66+30e96d5ea",
91
+ "@spectrum-web-components/icon": "^0.33.3-overlay.66+30e96d5ea",
92
+ "@spectrum-web-components/icons-ui": "^0.33.3-overlay.66+30e96d5ea",
93
+ "@spectrum-web-components/overlay": "^0.33.3-overlay.66+30e96d5ea",
94
+ "@spectrum-web-components/shared": "^0.33.3-overlay.66+30e96d5ea"
95
95
  },
96
96
  "devDependencies": {
97
- "@spectrum-css/menu": "^4.0.34"
97
+ "@spectrum-css/menu": "^4.0.42"
98
98
  },
99
99
  "types": "./src/index.d.ts",
100
100
  "customElements": "custom-elements.json",
@@ -102,5 +102,5 @@
102
102
  "./sp-*.js",
103
103
  "./**/*.dev.js"
104
104
  ],
105
- "gitHead": "6d5d6b3c31d92a058202a242a283125d25131f81"
105
+ "gitHead": "30e96d5eaed31b7b2af916d78cabccb722889fe3"
106
106
  }
package/src/Menu.d.ts CHANGED
@@ -22,7 +22,7 @@ export interface MenuChildItem {
22
22
  */
23
23
  export declare class Menu extends SpectrumElement {
24
24
  static get styles(): CSSResultArray;
25
- isSubmenu: boolean;
25
+ private get isSubmenu();
26
26
  label: string;
27
27
  ignore: boolean;
28
28
  selects: undefined | 'inherit' | 'single' | 'multiple';
@@ -51,7 +51,7 @@ export declare class Menu extends SpectrumElement {
51
51
  private resolvedRole?;
52
52
  /**
53
53
  * When a descendant `<sp-menu-item>` element is added or updated it will dispatch
54
- * this event to announce its presence in the DOM. During the capture phase the first
54
+ * this event to announce its presence in the DOM. During the CAPTURE phase the first
55
55
  * Menu based element that the event encounters will manage the focus state of the
56
56
  * dispatching `<sp-menu-item>` element.
57
57
  * @param event
@@ -59,7 +59,7 @@ export declare class Menu extends SpectrumElement {
59
59
  private onFocusableItemAddedOrUpdated;
60
60
  /**
61
61
  * When a descendant `<sp-menu-item>` element is added or updated it will dispatch
62
- * this event to announce its presence in the DOM. During the bubble phase the first
62
+ * this event to announce its presence in the DOM. During the BUBBLE phase the first
63
63
  * Menu based element that the event encounters that does not inherit selection will
64
64
  * manage the selection state of the dispatching `<sp-menu-item>` element.
65
65
  * @param event
@@ -69,24 +69,33 @@ export declare class Menu extends SpectrumElement {
69
69
  private removeChildItem;
70
70
  constructor();
71
71
  focus({ preventScroll }?: FocusOptions): void;
72
- private onClick;
72
+ private handleClick;
73
73
  handleFocusin(event: FocusEvent): void;
74
74
  startListeningToKeyboard(): void;
75
75
  handleFocusout(event: FocusEvent): void;
76
76
  stopListeningToKeyboard(): void;
77
+ private descendentOverlays;
78
+ protected handleDescendentOverlayOpened(event: Event): void;
79
+ protected handleDescendentOverlayClosed(event: Event): void;
80
+ handleSubmenuClosed: (event: Event) => void;
81
+ handleSubmenuOpened: (event: Event) => void;
77
82
  selectOrToggleItem(targetItem: MenuItem): Promise<void>;
78
83
  protected navigateWithinMenu(event: KeyboardEvent): void;
79
- protected navigateBetweenRelatedMenus(code: string): void;
84
+ protected navigateBetweenRelatedMenus(event: KeyboardEvent): void;
80
85
  handleKeydown(event: KeyboardEvent): void;
81
86
  focusMenuItemByOffset(offset: number): MenuItem;
82
87
  private prepareToCleanUp;
88
+ private _hasUpdatedSelectedItemIndex;
83
89
  updateSelectedItemIndex(): void;
84
90
  private _willUpdateItems;
85
91
  private handleItemsChanged;
92
+ private updateCache;
86
93
  private updateItemFocus;
94
+ closeDescendentOverlays(): void;
87
95
  private forwardFocusVisibleToItem;
96
+ private handleSlotchange;
97
+ protected renderMenuItemSlot(): TemplateResult;
88
98
  render(): TemplateResult;
89
- private _notFirstUpdated;
90
99
  protected firstUpdated(changed: PropertyValues): void;
91
100
  protected updated(changes: PropertyValues<this>): void;
92
101
  protected selectsChanged(): void;
@@ -94,5 +103,6 @@ export declare class Menu extends SpectrumElement {
94
103
  disconnectedCallback(): void;
95
104
  protected childItemsUpdated: Promise<unknown[]>;
96
105
  protected cacheUpdated: Promise<void>;
106
+ protected resolveCacheUpdated: () => void;
97
107
  protected getUpdateComplete(): Promise<boolean>;
98
108
  }
package/src/Menu.dev.js CHANGED
@@ -26,7 +26,6 @@ function elementIsOrContains(el, isOrContains) {
26
26
  export class Menu extends SpectrumElement {
27
27
  constructor() {
28
28
  super();
29
- this.isSubmenu = false;
30
29
  this.label = "";
31
30
  this.ignore = false;
32
31
  this.value = "";
@@ -37,9 +36,43 @@ export class Menu extends SpectrumElement {
37
36
  this.focusedItemIndex = 0;
38
37
  this.focusInItemIndex = 0;
39
38
  this.selectedItemsMap = /* @__PURE__ */ new Map();
39
+ this.descendentOverlays = /* @__PURE__ */ new Map();
40
+ this.handleSubmenuClosed = (event) => {
41
+ event.stopPropagation();
42
+ const target = event.composedPath()[0];
43
+ target.dispatchEvent(
44
+ new Event("sp-menu-submenu-closed", {
45
+ bubbles: true,
46
+ composed: true
47
+ })
48
+ );
49
+ };
50
+ this.handleSubmenuOpened = (event) => {
51
+ event.stopPropagation();
52
+ const target = event.composedPath()[0];
53
+ target.dispatchEvent(
54
+ new Event("sp-menu-submenu-opened", {
55
+ bubbles: true,
56
+ composed: true
57
+ })
58
+ );
59
+ const focusedItem = this.childItems[this.focusedItemIndex];
60
+ if (focusedItem) {
61
+ focusedItem.focused = false;
62
+ }
63
+ const openedItem = event.composedPath().find((el) => this.childItemSet.has(el));
64
+ if (!openedItem)
65
+ return;
66
+ const openedItemIndex = this.childItems.indexOf(openedItem);
67
+ this.focusedItemIndex = openedItemIndex;
68
+ this.focusInItemIndex = openedItemIndex;
69
+ };
70
+ this._hasUpdatedSelectedItemIndex = false;
40
71
  this._willUpdateItems = false;
41
- this._notFirstUpdated = false;
42
72
  this.cacheUpdated = Promise.resolve();
73
+ this.resolveCacheUpdated = () => {
74
+ return;
75
+ };
43
76
  this.addEventListener(
44
77
  "sp-menu-item-added-or-updated",
45
78
  this.onSelectableItemAddedOrUpdated
@@ -51,13 +84,18 @@ export class Menu extends SpectrumElement {
51
84
  capture: true
52
85
  }
53
86
  );
54
- this.addEventListener("sp-menu-item-removed", this.removeChildItem);
55
- this.addEventListener("click", this.onClick);
87
+ this.addEventListener("click", this.handleClick);
56
88
  this.addEventListener("focusin", this.handleFocusin);
89
+ this.addEventListener("focusout", this.handleFocusout);
90
+ this.addEventListener("sp-opened", this.handleSubmenuOpened);
91
+ this.addEventListener("sp-closed", this.handleSubmenuClosed);
57
92
  }
58
93
  static get styles() {
59
94
  return [menuStyles];
60
95
  }
96
+ get isSubmenu() {
97
+ return this.slot === "submenu";
98
+ }
61
99
  get childItems() {
62
100
  if (!this.cachedChildItems) {
63
101
  this.cachedChildItems = this.updateCachedMenuItems();
@@ -102,17 +140,37 @@ export class Menu extends SpectrumElement {
102
140
  }
103
141
  /**
104
142
  * When a descendant `<sp-menu-item>` element is added or updated it will dispatch
105
- * this event to announce its presence in the DOM. During the capture phase the first
143
+ * this event to announce its presence in the DOM. During the CAPTURE phase the first
106
144
  * Menu based element that the event encounters will manage the focus state of the
107
145
  * dispatching `<sp-menu-item>` element.
108
146
  * @param event
109
147
  */
110
148
  onFocusableItemAddedOrUpdated(event) {
149
+ event.menuCascade.set(this, {
150
+ hadFocusRoot: !!event.item.menuData.focusRoot,
151
+ ancestorWithSelects: event.currentAncestorWithSelects
152
+ });
153
+ if (this.selects) {
154
+ event.currentAncestorWithSelects = this;
155
+ }
156
+ event.item.menuData.focusRoot = event.item.menuData.focusRoot || this;
157
+ }
158
+ /**
159
+ * When a descendant `<sp-menu-item>` element is added or updated it will dispatch
160
+ * this event to announce its presence in the DOM. During the BUBBLE phase the first
161
+ * Menu based element that the event encounters that does not inherit selection will
162
+ * manage the selection state of the dispatching `<sp-menu-item>` element.
163
+ * @param event
164
+ */
165
+ onSelectableItemAddedOrUpdated(event) {
111
166
  var _a, _b;
112
- if (event.item.menuData.focusRoot && !this.ignore) {
167
+ const cascadeData = event.menuCascade.get(this);
168
+ if (!cascadeData)
169
+ return;
170
+ event.item.menuData.parentMenu = event.item.menuData.parentMenu || this;
171
+ if (cascadeData.hadFocusRoot && !this.ignore) {
113
172
  this.tabIndex = -1;
114
173
  }
115
- event.focusRoot = this;
116
174
  this.addChildItem(event.item);
117
175
  if (this.selects === "inherit") {
118
176
  this.resolvedSelects = "inherit";
@@ -121,34 +179,33 @@ export class Menu extends SpectrumElement {
121
179
  } else if (this.selects) {
122
180
  this.resolvedRole = this.ignore ? "none" : this.getAttribute("role") || void 0;
123
181
  this.resolvedSelects = this.selects;
124
- event.currentAncestorWithSelects = this;
125
182
  } else {
126
183
  this.resolvedRole = this.ignore ? "none" : this.getAttribute("role") || void 0;
127
184
  this.resolvedSelects = this.resolvedRole === "none" ? "ignore" : "none";
128
185
  }
129
- }
130
- /**
131
- * When a descendant `<sp-menu-item>` element is added or updated it will dispatch
132
- * this event to announce its presence in the DOM. During the bubble phase the first
133
- * Menu based element that the event encounters that does not inherit selection will
134
- * manage the selection state of the dispatching `<sp-menu-item>` element.
135
- * @param event
136
- */
137
- onSelectableItemAddedOrUpdated(event) {
138
186
  const selects = this.resolvedSelects === "single" || this.resolvedSelects === "multiple";
187
+ event.item.menuData.cleanupSteps.push(
188
+ (item) => this.removeChildItem(item)
189
+ );
139
190
  if ((selects || !this.selects && this.resolvedSelects !== "ignore") && !event.item.menuData.selectionRoot) {
140
191
  event.item.setRole(this.childRole);
141
- event.selectionRoot = this;
192
+ event.item.menuData.selectionRoot = event.item.menuData.selectionRoot || this;
193
+ if (event.item.selected) {
194
+ this.selectedItemsMap.set(event.item, true);
195
+ this.selectedItems = [...this.selectedItems, event.item];
196
+ this.selected = [...this.selected, event.item.value];
197
+ this.value = this.selected.join(this.valueSeparator);
198
+ }
142
199
  }
143
200
  }
144
201
  addChildItem(item) {
145
202
  this.childItemSet.add(item);
146
203
  this.handleItemsChanged();
147
204
  }
148
- async removeChildItem(event) {
149
- this.childItemSet.delete(event.item);
205
+ async removeChildItem(item) {
206
+ this.childItemSet.delete(item);
150
207
  this.cachedChildItems = void 0;
151
- if (event.item.focused) {
208
+ if (item.focused) {
152
209
  this.handleItemsChanged();
153
210
  await this.updateComplete;
154
211
  this.focus();
@@ -166,12 +223,12 @@ export class Menu extends SpectrumElement {
166
223
  }
167
224
  this.focusMenuItemByOffset(0);
168
225
  super.focus({ preventScroll });
169
- const selectedItem = this.querySelector("[selected]");
226
+ const selectedItem = this.selectedItems[0];
170
227
  if (selectedItem && !preventScroll) {
171
228
  selectedItem.scrollIntoView({ block: "nearest" });
172
229
  }
173
230
  }
174
- onClick(event) {
231
+ handleClick(event) {
175
232
  if (event.defaultPrevented) {
176
233
  return;
177
234
  }
@@ -203,18 +260,18 @@ export class Menu extends SpectrumElement {
203
260
  }
204
261
  handleFocusin(event) {
205
262
  var _a;
206
- const isOrContainsRelatedTarget = elementIsOrContains(
263
+ const wasOrContainedRelatedTarget = elementIsOrContains(
207
264
  this,
208
265
  event.relatedTarget
209
266
  );
210
- if (isOrContainsRelatedTarget || this.childItems.some(
267
+ if (this.childItems.some(
211
268
  (childItem) => childItem.menuData.focusRoot !== this
212
269
  )) {
213
270
  return;
214
271
  }
215
272
  const activeElement = this.getRootNode().activeElement;
216
273
  const selectionRoot = ((_a = this.childItems[this.focusedItemIndex]) == null ? void 0 : _a.menuData.selectionRoot) || this;
217
- if (activeElement !== selectionRoot || !isOrContainsRelatedTarget) {
274
+ if (activeElement !== selectionRoot || !wasOrContainedRelatedTarget && event.target !== this) {
218
275
  selectionRoot.focus({ preventScroll: true });
219
276
  if (activeElement && this.focusedItemIndex === 0) {
220
277
  const offset = this.childItems.findIndex(
@@ -229,27 +286,32 @@ export class Menu extends SpectrumElement {
229
286
  }
230
287
  startListeningToKeyboard() {
231
288
  this.addEventListener("keydown", this.handleKeydown);
232
- this.addEventListener("focusout", this.handleFocusout);
233
289
  }
234
290
  handleFocusout(event) {
235
291
  if (elementIsOrContains(this, event.relatedTarget)) {
236
- event.composedPath()[0].focused = false;
237
292
  return;
238
293
  }
239
294
  this.stopListeningToKeyboard();
240
- if (event.target === this && this.childItems.some(
241
- (childItem) => childItem.menuData.focusRoot === this
242
- )) {
243
- const focusedItem = this.childItems[this.focusedItemIndex];
244
- if (focusedItem) {
245
- focusedItem.focused = false;
246
- }
247
- }
295
+ this.childItems.forEach((child) => child.focused = false);
248
296
  this.removeAttribute("aria-activedescendant");
249
297
  }
250
298
  stopListeningToKeyboard() {
251
299
  this.removeEventListener("keydown", this.handleKeydown);
252
- this.removeEventListener("focusout", this.handleFocusout);
300
+ }
301
+ handleDescendentOverlayOpened(event) {
302
+ const target = event.composedPath()[0];
303
+ if (!target.overlayElement)
304
+ return;
305
+ this.descendentOverlays.set(
306
+ target.overlayElement,
307
+ target.overlayElement
308
+ );
309
+ }
310
+ handleDescendentOverlayClosed(event) {
311
+ const target = event.composedPath()[0];
312
+ if (!target.overlayElement)
313
+ return;
314
+ this.descendentOverlays.delete(target.overlayElement);
253
315
  }
254
316
  async selectOrToggleItem(targetItem) {
255
317
  const resolvedSelects = this.resolvedSelects;
@@ -258,6 +320,7 @@ export class Menu extends SpectrumElement {
258
320
  const oldSelectedItems = this.selectedItems.slice();
259
321
  const oldValue = this.value;
260
322
  this.childItems[this.focusedItemIndex].focused = false;
323
+ this.childItems[this.focusedItemIndex].active = false;
261
324
  this.focusedItemIndex = this.childItems.indexOf(targetItem);
262
325
  this.forwardFocusVisibleToItem(targetItem);
263
326
  if (resolvedSelects === "multiple") {
@@ -321,23 +384,30 @@ export class Menu extends SpectrumElement {
321
384
  return;
322
385
  }
323
386
  event.preventDefault();
387
+ event.stopPropagation();
324
388
  itemToFocus.scrollIntoView({ block: "nearest" });
325
389
  }
326
- navigateBetweenRelatedMenus(code) {
390
+ navigateBetweenRelatedMenus(event) {
391
+ const { code } = event;
327
392
  const shouldOpenSubmenu = this.isLTR && code === "ArrowRight" || !this.isLTR && code === "ArrowLeft";
328
393
  const shouldCloseSelfAsSubmenu = this.isLTR && code === "ArrowLeft" || !this.isLTR && code === "ArrowRight";
329
394
  if (shouldOpenSubmenu) {
395
+ event.stopPropagation();
330
396
  const lastFocusedItem = this.childItems[this.focusedItemIndex];
331
397
  if (lastFocusedItem == null ? void 0 : lastFocusedItem.hasSubmenu) {
332
- this.blur();
333
398
  lastFocusedItem.openOverlay();
334
399
  }
335
400
  } else if (shouldCloseSelfAsSubmenu && this.isSubmenu) {
401
+ event.stopPropagation();
336
402
  this.dispatchEvent(new Event("close", { bubbles: true }));
403
+ this.updateSelectedItemIndex();
337
404
  }
338
405
  }
339
406
  handleKeydown(event) {
340
407
  var _a;
408
+ if (event.target !== this && this !== event.target.parentElement) {
409
+ return;
410
+ }
341
411
  const { code } = event;
342
412
  if (code === "Tab") {
343
413
  this.prepareToCleanUp();
@@ -346,7 +416,6 @@ export class Menu extends SpectrumElement {
346
416
  if (code === "Space") {
347
417
  const lastFocusedItem = this.childItems[this.focusedItemIndex];
348
418
  if (lastFocusedItem == null ? void 0 : lastFocusedItem.hasSubmenu) {
349
- this.blur();
350
419
  lastFocusedItem.openOverlay();
351
420
  return;
352
421
  }
@@ -359,12 +428,15 @@ export class Menu extends SpectrumElement {
359
428
  this.navigateWithinMenu(event);
360
429
  return;
361
430
  }
362
- this.navigateBetweenRelatedMenus(code);
431
+ this.navigateBetweenRelatedMenus(event);
363
432
  }
364
433
  focusMenuItemByOffset(offset) {
365
434
  const step = offset || 1;
366
435
  const focusedItem = this.childItems[this.focusedItemIndex];
367
- focusedItem.focused = false;
436
+ if (focusedItem) {
437
+ focusedItem.focused = false;
438
+ focusedItem.active = false;
439
+ }
368
440
  this.focusedItemIndex = (this.childItems.length + this.focusedItemIndex + offset) % this.childItems.length;
369
441
  let itemToFocus = this.childItems[this.focusedItemIndex];
370
442
  let availableItems = this.childItems.length;
@@ -403,7 +475,7 @@ export class Menu extends SpectrumElement {
403
475
  itemIndex -= 1;
404
476
  const childItem = this.childItems[itemIndex];
405
477
  if (childItem.menuData.selectionRoot === this) {
406
- if (childItem.selected) {
478
+ if (childItem.selected || !this._hasUpdatedSelectedItemIndex && this.selected.includes(childItem.value)) {
407
479
  firstOrFirstSelectedIndex = itemIndex;
408
480
  selectedItemsMap.set(childItem, true);
409
481
  selected.unshift(childItem.value);
@@ -429,21 +501,18 @@ export class Menu extends SpectrumElement {
429
501
  handleItemsChanged() {
430
502
  this.cachedChildItems = void 0;
431
503
  if (!this._willUpdateItems) {
432
- let resolve = () => {
433
- return;
434
- };
435
- this.cacheUpdated = new Promise((res) => resolve = res);
436
504
  this._willUpdateItems = true;
437
- window.requestAnimationFrame(() => {
438
- if (this.cachedChildItems === void 0) {
439
- this.updateSelectedItemIndex();
440
- this.updateItemFocus();
441
- }
442
- this._willUpdateItems = false;
443
- resolve();
444
- });
505
+ this.cacheUpdated = this.updateCache();
445
506
  }
446
507
  }
508
+ async updateCache() {
509
+ await new Promise((res) => requestAnimationFrame(() => res(true)));
510
+ if (this.cachedChildItems === void 0) {
511
+ this.updateSelectedItemIndex();
512
+ this.updateItemFocus();
513
+ }
514
+ this._willUpdateItems = false;
515
+ }
447
516
  updateItemFocus() {
448
517
  if (this.childItems.length == 0) {
449
518
  return;
@@ -453,21 +522,52 @@ export class Menu extends SpectrumElement {
453
522
  this.forwardFocusVisibleToItem(focusInItem);
454
523
  }
455
524
  }
525
+ closeDescendentOverlays() {
526
+ this.descendentOverlays.forEach((overlay) => {
527
+ overlay.open = false;
528
+ });
529
+ this.descendentOverlays = /* @__PURE__ */ new Map();
530
+ }
456
531
  forwardFocusVisibleToItem(item) {
457
532
  if (item.menuData.focusRoot !== this) {
458
533
  return;
459
534
  }
460
- item.focused = this.hasVisibleFocusInTree();
535
+ this.closeDescendentOverlays();
536
+ const focused = this.hasVisibleFocusInTree() || !!this.childItems.find((child) => {
537
+ return child.hasVisibleFocusInTree();
538
+ });
539
+ item.focused = focused;
461
540
  this.setAttribute("aria-activedescendant", item.id);
462
541
  if (item.menuData.selectionRoot && item.menuData.selectionRoot !== this) {
463
542
  item.menuData.selectionRoot.focus();
464
543
  }
465
544
  }
466
- render() {
545
+ handleSlotchange({
546
+ target
547
+ }) {
548
+ const assignedElement = target.assignedElements({
549
+ flatten: true
550
+ });
551
+ if (this.childItems.length !== assignedElement.length) {
552
+ assignedElement.forEach((item) => {
553
+ if (typeof item.triggerUpdate !== "undefined") {
554
+ item.triggerUpdate();
555
+ }
556
+ });
557
+ }
558
+ }
559
+ renderMenuItemSlot() {
467
560
  return html`
468
- <slot></slot>
561
+ <slot
562
+ @sp-menu-submenu-opened=${this.handleDescendentOverlayOpened}
563
+ @sp-menu-submenu-closed=${this.handleDescendentOverlayClosed}
564
+ @slotchange=${this.handleSlotchange}
565
+ ></slot>
469
566
  `;
470
567
  }
568
+ render() {
569
+ return this.renderMenuItemSlot();
570
+ }
471
571
  firstUpdated(changed) {
472
572
  super.firstUpdated(changed);
473
573
  if (!this.hasAttribute("tabindex") && !this.ignore) {
@@ -490,17 +590,16 @@ export class Menu extends SpectrumElement {
490
590
  }
491
591
  updated(changes) {
492
592
  super.updated(changes);
493
- if (changes.has("selects") && this._notFirstUpdated) {
593
+ if (changes.has("selects") && this.hasUpdated) {
494
594
  this.selectsChanged();
495
595
  }
496
- if (changes.has("label")) {
596
+ if (changes.has("label") && (this.label || typeof changes.get("label") !== "undefined")) {
497
597
  if (this.label) {
498
598
  this.setAttribute("aria-label", this.label);
499
599
  } else {
500
600
  this.removeAttribute("aria-label");
501
601
  }
502
602
  }
503
- this._notFirstUpdated = true;
504
603
  }
505
604
  selectsChanged() {
506
605
  const updates = [