@brightspace-ui/core 3.94.1 → 3.94.2

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.
@@ -364,6 +364,10 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
364
364
  return this.shadowRoot.querySelector('.d2l-tabs-container-list').getBoundingClientRect();
365
365
  }
366
366
 
367
+ #checkTabPanelMatchRequested;
368
+ #panels;
369
+ #updateAriaControlsRequested;
370
+
367
371
  _animateTabAddition(tabInfo) {
368
372
  const tab = this.shadowRoot
369
373
  && this.shadowRoot.querySelector(`d2l-tab-internal[controls-panel="${cssEscape(tabInfo.id)}"]`);
@@ -438,10 +442,8 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
438
442
  _getPanel(id) {
439
443
  if (this._defaultSlotBehavior) return this._getPanelDefaultSlotBehavior(id);
440
444
 
441
- if (!this.shadowRoot) return;
442
- const slot = this.shadowRoot.querySelector('slot[name="panels"]');
443
- const panels = this._getPanels(slot);
444
- return panels.find(panel => panel.labelledBy === id);
445
+ if (!this.#panels) return;
446
+ return this.#panels.find(panel => panel.labelledBy === id);
445
447
  }
446
448
 
447
449
  // remove after d2l-tab/d2l-tab-panel backport
@@ -449,7 +451,7 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
449
451
  if (!this.shadowRoot) return;
450
452
  // use simple selector for slot (Edge)
451
453
  const slot = this.shadowRoot.querySelector('.d2l-panels-container').querySelector('slot');
452
- const panels = this._getPanels(slot);
454
+ const panels = this._getPanelsDefaultSlotBehavior(slot);
453
455
  for (let i = 0; i < panels.length; i++) {
454
456
  if (panels[i].nodeType === Node.ELEMENT_NODE && panels[i].role === 'tabpanel' && panels[i].id === id) {
455
457
  return panels[i];
@@ -457,7 +459,8 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
457
459
  }
458
460
  }
459
461
 
460
- _getPanels(slot) {
462
+ // remove after d2l-tab/d2l-tab-panel backport
463
+ _getPanelsDefaultSlotBehavior(slot) {
461
464
  if (!slot) return;
462
465
  return slot.assignedElements({ flatten: true }).filter((node) => node.role === 'tabpanel');
463
466
  }
@@ -470,7 +473,7 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
470
473
  async _handleDefaultSlotChange(e) {
471
474
  if (!this._defaultSlotBehavior) return;
472
475
 
473
- const panels = this._getPanels(e.target);
476
+ const panels = this._getPanelsDefaultSlotBehavior(e.target);
474
477
 
475
478
  // handle case where there are less than two tabs initially
476
479
  this._updateTabListVisibility(panels);
@@ -568,9 +571,11 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
568
571
  this.requestUpdate();
569
572
  }
570
573
 
571
- _handlePanelsSlotChange() {
574
+ _handlePanelsSlotChange(e) {
572
575
  if (this._defaultSlotBehavior) return;
573
576
 
577
+ this.#panels = e.target.assignedElements({ flatten: true }).filter((node) => node.role === 'tabpanel');
578
+ this.#checkTabPanelMatch();
574
579
  this.#setAriaControls();
575
580
  }
576
581
 
@@ -727,9 +732,10 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
727
732
  if (selectedTab) {
728
733
  this.#updateSelectedTab(selectedTab);
729
734
  }
730
- this.#setAriaControls();
731
735
 
732
736
  await this.updateComplete;
737
+ this.#checkTabPanelMatch();
738
+ this.#setAriaControls();
733
739
 
734
740
  if (!this._initialized && this._tabs.length > 0) {
735
741
  this._initialized = true;
@@ -1011,22 +1017,40 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
1011
1017
  return newTranslationValue;
1012
1018
  }
1013
1019
 
1020
+ #checkTabPanelMatch() {
1021
+ // debounce so only runs once when tabs/panels slots changing
1022
+ if (this.#checkTabPanelMatchRequested) return;
1023
+
1024
+ this.#checkTabPanelMatchRequested = true;
1025
+ setTimeout(() => {
1026
+ if ((this._tabs && !this.#panels) || (this.#panels && !this._tabs)) {
1027
+ console.warn('d2l-tabs: tabs and panels are not in sync');
1028
+ } else if (this._tabs.length !== this.#panels.length) {
1029
+ console.warn('d2l-tabs: number of tabs and panels does not match');
1030
+ }
1031
+ this.#checkTabPanelMatchRequested = false;
1032
+ }, 0);
1033
+ }
1034
+
1014
1035
  #isRTL() {
1015
1036
  return document.documentElement.getAttribute('dir') === 'rtl';
1016
1037
  }
1017
1038
 
1018
1039
  #setAriaControls() {
1019
1040
  // debounce so only runs once when tabs/panels slots changing
1020
- if (this._updateAriaControlsRequested) return;
1041
+ if (this.#updateAriaControlsRequested) return;
1021
1042
 
1022
- this._updateAriaControlsRequested = true;
1043
+ this.#updateAriaControlsRequested = true;
1023
1044
  setTimeout(() => {
1024
1045
  this._tabs?.forEach((tab) => {
1025
1046
  const panel = this._getPanel(tab.id);
1026
- if (!panel) return;
1047
+ if (!panel) {
1048
+ console.warn('d2l-tabs: tab without matching panel');
1049
+ return;
1050
+ }
1027
1051
  tab.setAttribute('aria-controls', `${panel.id}`);
1028
1052
  });
1029
- this._updateAriaControlsRequested = false;
1053
+ this.#updateAriaControlsRequested = false;
1030
1054
  }, 0);
1031
1055
  }
1032
1056
 
@@ -1047,12 +1071,12 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
1047
1071
  }
1048
1072
 
1049
1073
  async #updateSelectedTab(selectedTab) {
1050
- const selectedPanel = this._getPanel(selectedTab.id);
1051
1074
  selectedTab.tabIndex = 0;
1052
1075
 
1053
1076
  await this.updateComplete;
1054
1077
 
1055
- selectedPanel.selected = true;
1078
+ const selectedPanel = this._getPanel(selectedTab.id);
1079
+ if (selectedPanel) selectedPanel.selected = true;
1056
1080
  this._tabs.forEach((tab) => {
1057
1081
  if (tab.id !== selectedTab.id) {
1058
1082
  if (tab.selected) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/core",
3
- "version": "3.94.1",
3
+ "version": "3.94.2",
4
4
  "description": "A collection of accessible, free, open-source web components for building Brightspace applications",
5
5
  "type": "module",
6
6
  "repository": "https://github.com/BrightspaceUI/core.git",