@brightspace-ui/core 3.316.0 → 3.317.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/components/tabs/README.md +0 -5
- package/components/tabs/tab-panel-mixin.js +0 -40
- package/components/tabs/tabs.js +28 -369
- package/custom-elements.json +1 -111
- package/package.json +1 -1
- package/components/tabs/tab-internal.js +0 -144
|
@@ -257,11 +257,6 @@ Selecting a tab in the tab bar causes the related tab panel to be displayed. Tab
|
|
|
257
257
|
|--|--|--|
|
|
258
258
|
| `labelled-by` | String, required | Id of the tab that labels this panel |
|
|
259
259
|
| `no-padding` | Boolean | Used to opt out of default padding/whitespace around the panel |
|
|
260
|
-
| `text` | String | DEPRECATED: The text used for the tab, as well as labelling the panel. Required if not using d2l-tab/d2l-tab-panel implementation. |
|
|
261
|
-
| `selected` | Boolean | DEPRECATED: Use to select the tab. Do NOT set if using the d2l-tab/d2l-tab-panel implementation. |
|
|
262
|
-
|
|
263
|
-
### Events
|
|
264
|
-
- `d2l-tab-panel-selected`: DEPRECATED: Dispatched when a tab is selected
|
|
265
260
|
<!-- docs: end hidden content -->
|
|
266
261
|
|
|
267
262
|
## Accessibility
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
2
|
import { getUniqueId } from '../../helpers/uniqueId.js';
|
|
3
|
-
import { getUseNewTabsStructureFlag } from './tabs.js';
|
|
4
3
|
|
|
5
4
|
export const TabPanelMixin = superclass => class extends superclass {
|
|
6
5
|
|
|
@@ -20,18 +19,6 @@ export const TabPanelMixin = superclass => class extends superclass {
|
|
|
20
19
|
*/
|
|
21
20
|
// eslint-disable-next-line lit/no-native-attributes
|
|
22
21
|
role: { type: String, reflect: true },
|
|
23
|
-
/**
|
|
24
|
-
* DEPRECATED: Use to select the tab. Do NOT set if using the d2l-tab/d2l-tab-panel implementation.
|
|
25
|
-
* Remove with GAUD-8299-core-tabs-use-new-structure flag clean up.
|
|
26
|
-
* @type {boolean}
|
|
27
|
-
*/
|
|
28
|
-
selected: { type: Boolean, reflect: true },
|
|
29
|
-
/**
|
|
30
|
-
* DEPRECATED: The text used for the tab, as well as labelling the panel. Required if not using d2l-tab/d2l-tab-panel implementation.
|
|
31
|
-
* Remove with GAUD-8299-core-tabs-use-new-structure flag clean up.
|
|
32
|
-
* @type {string}
|
|
33
|
-
*/
|
|
34
|
-
text: { type: String },
|
|
35
22
|
_selected: { type: Boolean, attribute: '_selected', reflect: true }
|
|
36
23
|
};
|
|
37
24
|
|
|
@@ -44,10 +31,6 @@ export const TabPanelMixin = superclass => class extends superclass {
|
|
|
44
31
|
:host([no-padding]) {
|
|
45
32
|
margin: 0;
|
|
46
33
|
}
|
|
47
|
-
/* clean up with GAUD-8299-core-tabs-use-new-structure flag clean up */
|
|
48
|
-
:host([selected]) {
|
|
49
|
-
display: block;
|
|
50
|
-
}
|
|
51
34
|
:host([_selected]) {
|
|
52
35
|
display: block;
|
|
53
36
|
}
|
|
@@ -59,7 +42,6 @@ export const TabPanelMixin = superclass => class extends superclass {
|
|
|
59
42
|
/** @ignore */
|
|
60
43
|
this.role = 'tabpanel';
|
|
61
44
|
this._selected = false;
|
|
62
|
-
if (!this.#useTabsNewStructure) this.selected = false; // clean up with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
63
45
|
}
|
|
64
46
|
|
|
65
47
|
connectedCallback() {
|
|
@@ -74,29 +56,7 @@ export const TabPanelMixin = superclass => class extends superclass {
|
|
|
74
56
|
if (prop === 'labelledBy') {
|
|
75
57
|
this.setAttribute('aria-labelledby', this.labelledBy);
|
|
76
58
|
}
|
|
77
|
-
|
|
78
|
-
// clean up below with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
79
|
-
if (this.#useTabsNewStructure) return;
|
|
80
|
-
|
|
81
|
-
if (prop === 'selected') {
|
|
82
|
-
if (this.selected) {
|
|
83
|
-
requestAnimationFrame(() => {
|
|
84
|
-
/** DEPRECATED: Dispatched when a tab is selected */
|
|
85
|
-
this.dispatchEvent(new CustomEvent(
|
|
86
|
-
'd2l-tab-panel-selected', { bubbles: true, composed: true }
|
|
87
|
-
));
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
} else if (prop === 'text') {
|
|
91
|
-
this.setAttribute('aria-label', this.text);
|
|
92
|
-
/** DEPRECATED: Dispatched when the text attribute is changed */
|
|
93
|
-
this.dispatchEvent(new CustomEvent(
|
|
94
|
-
'd2l-tab-panel-text-changed', { bubbles: true, composed: true, detail: { text: this.text } }
|
|
95
|
-
));
|
|
96
|
-
}
|
|
97
59
|
});
|
|
98
60
|
}
|
|
99
61
|
|
|
100
|
-
#useTabsNewStructure = getUseNewTabsStructureFlag();
|
|
101
|
-
|
|
102
62
|
};
|
package/components/tabs/tabs.js
CHANGED
|
@@ -1,24 +1,17 @@
|
|
|
1
1
|
import '../colors/colors.js';
|
|
2
2
|
import '../icons/icon.js';
|
|
3
|
-
import '
|
|
4
|
-
import { css, html, LitElement, nothing, unsafeCSS } from 'lit';
|
|
3
|
+
import { css, html, LitElement, unsafeCSS } from 'lit';
|
|
5
4
|
import { findComposedAncestor, getOffsetParent, isVisible } from '../../helpers/dom.js';
|
|
6
5
|
import { getFocusPseudoClass, getFocusRingStyles } from '../../helpers/focus.js';
|
|
7
6
|
import { ArrowKeysMixin } from '../../mixins/arrow-keys/arrow-keys-mixin.js';
|
|
8
7
|
import { bodyCompactStyles } from '../typography/styles.js';
|
|
9
8
|
import { classMap } from 'lit/directives/class-map.js';
|
|
10
|
-
import { getFlag } from '../../helpers/flags.js';
|
|
11
9
|
import { getOverflowDeclarations } from '../../helpers/overflow.js';
|
|
12
10
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
13
11
|
import { LocalizeCoreElement } from '../../helpers/localize-core-element.js';
|
|
14
|
-
import { repeat } from 'lit/directives/repeat.js';
|
|
15
12
|
import { SkeletonMixin } from '../skeleton/skeleton-mixin.js';
|
|
16
13
|
import { styleMap } from 'lit/directives/style-map.js';
|
|
17
14
|
|
|
18
|
-
export function getUseNewTabsStructureFlag() {
|
|
19
|
-
return getFlag('GAUD-8299-core-tabs-use-new-structure', true);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
15
|
const reduceMotion = matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
23
16
|
|
|
24
17
|
const scrollButtonWidth = 56;
|
|
@@ -30,7 +23,6 @@ function getOffsetLeft(tab, tabRect) {
|
|
|
30
23
|
|
|
31
24
|
/**
|
|
32
25
|
* A component for tabbed content. It supports the "d2l-tab" component and "TabMixin" consumers for tabs, the "d2l-tab-panel" component for the tab content, renders tabs responsively, and provides virtual scrolling for large tab lists.
|
|
33
|
-
* @slot - DEPRECATED: Contains the tab panels (e.g., "d2l-tab-panel" components)
|
|
34
26
|
* @slot ext - Additional content (e.g., a button) positioned at right
|
|
35
27
|
* @slot tabs - Contains the tabs (e.g., "d2l-tab" components or custom components that use `TabMixin`)
|
|
36
28
|
* @slot panels - Contains the tab panels (e.g., "d2l-tab-panel" components)
|
|
@@ -50,11 +42,9 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
50
42
|
text: { type: String },
|
|
51
43
|
_allowScrollNext: { type: Boolean },
|
|
52
44
|
_allowScrollPrevious: { type: Boolean },
|
|
53
|
-
_defaultSlotBehavior: { state: true },
|
|
54
45
|
_maxWidth: { type: Number },
|
|
55
46
|
_scrollCollapsed: { type: Boolean },
|
|
56
47
|
_state: { type: String },
|
|
57
|
-
_tabInfos: { type: Array },
|
|
58
48
|
_translationValue: {}
|
|
59
49
|
};
|
|
60
50
|
|
|
@@ -169,12 +159,10 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
169
159
|
transition: margin-top 200ms ease-out;
|
|
170
160
|
}
|
|
171
161
|
|
|
172
|
-
|
|
162
|
+
::slotted([role="tab"]) {
|
|
173
163
|
-webkit-transition: max-width 200ms ease-out, opacity 200ms ease-out, transform 200ms ease-out;
|
|
174
164
|
transition: max-width 200ms ease-out, opacity 200ms ease-out, transform 200ms ease-out;
|
|
175
165
|
}
|
|
176
|
-
d2l-tab-internal[data-state="adding"],
|
|
177
|
-
d2l-tab-internal[data-state="removing"],
|
|
178
166
|
::slotted([role="tab"][data-state="adding"]),
|
|
179
167
|
::slotted([role="tab"][data-state="removing"]) {
|
|
180
168
|
max-width: 0;
|
|
@@ -200,7 +188,7 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
200
188
|
-webkit-transition: none;
|
|
201
189
|
transition: none;
|
|
202
190
|
}
|
|
203
|
-
|
|
191
|
+
::slotted([role="tab"]) {
|
|
204
192
|
-webkit-transition: none;
|
|
205
193
|
transition: none;
|
|
206
194
|
}
|
|
@@ -229,13 +217,6 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
229
217
|
this.maxToShow = -1;
|
|
230
218
|
this._allowScrollNext = false;
|
|
231
219
|
this._allowScrollPrevious = false;
|
|
232
|
-
|
|
233
|
-
/*
|
|
234
|
-
* Remove this._defaultSlotBehavior and related code with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
235
|
-
* NOTE: remove the TRUE case of _defaultSlotBehavior
|
|
236
|
-
*/
|
|
237
|
-
this._defaultSlotBehavior = !this.#newTabsPanelStructure;
|
|
238
|
-
|
|
239
220
|
this._loadingCompleteResolve = undefined;
|
|
240
221
|
this._loadingCompletePromise = new Promise(resolve => this._loadingCompleteResolve = resolve);
|
|
241
222
|
this._maxWidth = null;
|
|
@@ -243,7 +224,6 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
243
224
|
this._state = 'shown';
|
|
244
225
|
this._tabIds = {};
|
|
245
226
|
this._tabs = [];
|
|
246
|
-
if (this._defaultSlotBehavior) this._tabInfos = [];
|
|
247
227
|
this._translationValue = 0;
|
|
248
228
|
}
|
|
249
229
|
|
|
@@ -268,61 +248,32 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
268
248
|
super.firstUpdated(changedProperties);
|
|
269
249
|
|
|
270
250
|
this.arrowKeysFocusablesProvider = async() => {
|
|
271
|
-
return this.
|
|
251
|
+
return this._tabs;
|
|
272
252
|
};
|
|
273
253
|
|
|
274
254
|
this.arrowKeysOnBeforeFocus = async(tab) => {
|
|
275
|
-
|
|
276
|
-
// remove this section with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
277
|
-
const tabInfo = this._getTabInfo(tab.controlsPanel);
|
|
278
|
-
this._setFocusableDefaultSlotBehavior(tabInfo);
|
|
255
|
+
this._setFocusable(tab);
|
|
279
256
|
|
|
280
|
-
|
|
281
|
-
|
|
257
|
+
this.requestUpdate();
|
|
258
|
+
await this.updateComplete;
|
|
282
259
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
} else {
|
|
286
|
-
const measures = this._getMeasures();
|
|
287
|
-
const newTranslationValue = this._calculateScrollPositionDefaultSlotBehavior(tabInfo, measures);
|
|
288
|
-
|
|
289
|
-
if (!this.#isRTL()) {
|
|
290
|
-
if (newTranslationValue >= 0) return;
|
|
291
|
-
} else {
|
|
292
|
-
if (newTranslationValue <= 0) return;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
const expanded = await this._tryExpandTabsContainer(measures);
|
|
296
|
-
if (expanded) {
|
|
297
|
-
return;
|
|
298
|
-
} else {
|
|
299
|
-
return this._updateScrollPositionDefaultSlotBehavior(tabInfo);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
260
|
+
if (!this._scrollCollapsed) {
|
|
261
|
+
return this._updateScrollPosition(tab);
|
|
302
262
|
} else {
|
|
303
|
-
this.
|
|
263
|
+
const measures = this._getMeasures();
|
|
264
|
+
const newTranslationValue = this._calculateScrollPosition(tab, measures);
|
|
304
265
|
|
|
305
|
-
this
|
|
306
|
-
|
|
266
|
+
if (!this.#isRTL()) {
|
|
267
|
+
if (newTranslationValue >= 0) return;
|
|
268
|
+
} else {
|
|
269
|
+
if (newTranslationValue <= 0) return;
|
|
270
|
+
}
|
|
307
271
|
|
|
308
|
-
|
|
309
|
-
|
|
272
|
+
const expanded = await this._tryExpandTabsContainer(measures);
|
|
273
|
+
if (expanded) {
|
|
274
|
+
return;
|
|
310
275
|
} else {
|
|
311
|
-
|
|
312
|
-
const newTranslationValue = this._calculateScrollPosition(tab, measures);
|
|
313
|
-
|
|
314
|
-
if (!this.#isRTL()) {
|
|
315
|
-
if (newTranslationValue >= 0) return;
|
|
316
|
-
} else {
|
|
317
|
-
if (newTranslationValue <= 0) return;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
const expanded = await this._tryExpandTabsContainer(measures);
|
|
321
|
-
if (expanded) {
|
|
322
|
-
return;
|
|
323
|
-
} else {
|
|
324
|
-
return this._updateScrollPosition(tab);
|
|
325
|
-
}
|
|
276
|
+
return this._updateScrollPosition(tab);
|
|
326
277
|
}
|
|
327
278
|
}
|
|
328
279
|
};
|
|
@@ -377,15 +328,6 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
377
328
|
aria-label="${ifDefined(this.text)}"
|
|
378
329
|
role="tablist"
|
|
379
330
|
style="${styleMap(tabsContainerListStyles)}">
|
|
380
|
-
${!this.#newTabsPanelStructure ? repeat(this._tabInfos, (tabInfo) => tabInfo.id, (tabInfo) => html`
|
|
381
|
-
<d2l-tab-internal aria-selected="${tabInfo.selected ? 'true' : 'false'}"
|
|
382
|
-
.controlsPanel="${tabInfo.id}"
|
|
383
|
-
data-state="${tabInfo.state}"
|
|
384
|
-
?skeleton="${this.skeleton}"
|
|
385
|
-
tabindex="${tabInfo.activeFocusable ? 0 : -1}"
|
|
386
|
-
text="${tabInfo.text}">
|
|
387
|
-
</d2l-tab-internal>
|
|
388
|
-
`) : nothing}
|
|
389
331
|
<slot name="tabs" @slotchange="${this._handleTabsSlotChange}"></slot>
|
|
390
332
|
</div>
|
|
391
333
|
`)}
|
|
@@ -399,10 +341,7 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
399
341
|
</div>
|
|
400
342
|
<div class="d2l-tabs-container-ext"><slot name="ext"></slot></div>
|
|
401
343
|
</div>
|
|
402
|
-
<div class="${classMap(panelContainerClasses)}"
|
|
403
|
-
@d2l-tab-panel-selected="${ifDefined(!this.#newTabsPanelStructure ? this._handlePanelSelected : undefined)}"
|
|
404
|
-
@d2l-tab-panel-text-changed="${ifDefined(!this.#newTabsPanelStructure ? this._handlePanelTextChange : undefined)}">
|
|
405
|
-
${!this.#newTabsPanelStructure ? html`<slot @slotchange="${this._handleDefaultSlotChange}"></slot>` : nothing}
|
|
344
|
+
<div class="${classMap(panelContainerClasses)}">
|
|
406
345
|
<slot name="panels" @slotchange="${this._handlePanelsSlotChange}"></slot>
|
|
407
346
|
</div>
|
|
408
347
|
`;
|
|
@@ -427,7 +366,6 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
427
366
|
}
|
|
428
367
|
|
|
429
368
|
#checkTabPanelMatchRequested;
|
|
430
|
-
#newTabsPanelStructure = getUseNewTabsStructureFlag();
|
|
431
369
|
#panels;
|
|
432
370
|
#updateAriaControlsRequested;
|
|
433
371
|
|
|
@@ -452,24 +390,6 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
452
390
|
});
|
|
453
391
|
}
|
|
454
392
|
|
|
455
|
-
// remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
456
|
-
_animateTabAdditionDefaultSlotBehavior(tabInfo) {
|
|
457
|
-
const tab = this.shadowRoot
|
|
458
|
-
&& this.shadowRoot.querySelector(`d2l-tab-internal[controls-panel="${CSS.escape(tabInfo.id)}"]`);
|
|
459
|
-
if (!tab) Promise.resolve();
|
|
460
|
-
|
|
461
|
-
return new Promise((resolve) => {
|
|
462
|
-
const handleTransitionEnd = (e) => {
|
|
463
|
-
if (e.propertyName !== 'max-width') return;
|
|
464
|
-
tab.removeEventListener('transitionend', handleTransitionEnd);
|
|
465
|
-
resolve();
|
|
466
|
-
};
|
|
467
|
-
tab.addEventListener('transitionend', handleTransitionEnd);
|
|
468
|
-
tabInfo.state = '';
|
|
469
|
-
this.requestUpdate();
|
|
470
|
-
});
|
|
471
|
-
}
|
|
472
|
-
|
|
473
393
|
_animateTabRemoval(tab) {
|
|
474
394
|
if (!tab || reduceMotion) return Promise.resolve();
|
|
475
395
|
|
|
@@ -484,42 +404,13 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
484
404
|
});
|
|
485
405
|
}
|
|
486
406
|
|
|
487
|
-
// remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
488
|
-
_animateTabRemovalDefaultSlotBehavior(tabInfo) {
|
|
489
|
-
const tab = this.shadowRoot &&
|
|
490
|
-
this.shadowRoot.querySelector(`d2l-tab-internal[controls-panel="${CSS.escape(tabInfo.id)}"]`);
|
|
491
|
-
if (!tab) Promise.resolve();
|
|
492
|
-
|
|
493
|
-
return new Promise((resolve) => {
|
|
494
|
-
const handleTransitionEnd = (e) => {
|
|
495
|
-
if (e.propertyName !== 'max-width') return;
|
|
496
|
-
tab.removeEventListener('transitionend', handleTransitionEnd);
|
|
497
|
-
this._tabInfos.splice(this._tabInfos.findIndex(info => info.id === tabInfo.id), 1);
|
|
498
|
-
this.requestUpdate();
|
|
499
|
-
resolve();
|
|
500
|
-
};
|
|
501
|
-
tab.addEventListener('transitionend', handleTransitionEnd);
|
|
502
|
-
});
|
|
503
|
-
}
|
|
504
|
-
|
|
505
407
|
_calculateScrollPosition(selectedTab, measures) {
|
|
506
408
|
const tabs = this._tabs;
|
|
507
409
|
const selectedTabIndex = tabs.indexOf(selectedTab);
|
|
508
410
|
return this.#calculateScrollPositionLogic(tabs, selectedTabIndex, measures);
|
|
509
411
|
}
|
|
510
412
|
|
|
511
|
-
// remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
512
|
-
_calculateScrollPositionDefaultSlotBehavior(selectedTabInfo, measures) {
|
|
513
|
-
const selectedTabIndex = this._tabInfos.indexOf(selectedTabInfo);
|
|
514
|
-
return this.#calculateScrollPositionLogic(this._tabInfos, selectedTabIndex, measures);
|
|
515
|
-
}
|
|
516
|
-
|
|
517
413
|
async _focusSelected() {
|
|
518
|
-
if (this._defaultSlotBehavior) {
|
|
519
|
-
this._focusSelectedDefaultSlotBehavior();
|
|
520
|
-
return;
|
|
521
|
-
}
|
|
522
|
-
|
|
523
414
|
const selectedTab = this._tabs.find(ti => ti.selected);
|
|
524
415
|
if (!selectedTab) return;
|
|
525
416
|
|
|
@@ -528,17 +419,6 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
528
419
|
selectedTab.focus();
|
|
529
420
|
}
|
|
530
421
|
|
|
531
|
-
// remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
532
|
-
async _focusSelectedDefaultSlotBehavior() {
|
|
533
|
-
const selectedTab = this.shadowRoot && this.shadowRoot.querySelector('d2l-tab-internal[aria-selected="true"]');
|
|
534
|
-
if (!selectedTab) return;
|
|
535
|
-
|
|
536
|
-
const selectedTabInfo = this._getTabInfo(selectedTab.controlsPanel);
|
|
537
|
-
await this._updateScrollPositionDefaultSlotBehavior(selectedTabInfo);
|
|
538
|
-
|
|
539
|
-
selectedTab.focus();
|
|
540
|
-
}
|
|
541
|
-
|
|
542
422
|
_getComputedBackgroundColor() {
|
|
543
423
|
let bgColor = null;
|
|
544
424
|
|
|
@@ -559,158 +439,21 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
559
439
|
}
|
|
560
440
|
|
|
561
441
|
_getPanel(id) {
|
|
562
|
-
if (this._defaultSlotBehavior) return this._getPanelDefaultSlotBehavior(id);
|
|
563
|
-
|
|
564
442
|
if (!this.#panels) return;
|
|
565
443
|
return this.#panels.find(panel => panel.labelledBy === id);
|
|
566
444
|
}
|
|
567
445
|
|
|
568
|
-
// remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
569
|
-
_getPanelDefaultSlotBehavior(id) {
|
|
570
|
-
if (!this.shadowRoot) return;
|
|
571
|
-
// use simple selector for slot (Edge)
|
|
572
|
-
const slot = this.shadowRoot.querySelector('.d2l-panels-container').querySelector('slot');
|
|
573
|
-
const panels = this._getPanelsDefaultSlotBehavior(slot);
|
|
574
|
-
for (let i = 0; i < panels.length; i++) {
|
|
575
|
-
if (panels[i].nodeType === Node.ELEMENT_NODE && panels[i].role === 'tabpanel' && panels[i].id === id) {
|
|
576
|
-
return panels[i];
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
// rremove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
582
|
-
_getPanelsDefaultSlotBehavior(slot) {
|
|
583
|
-
if (!slot) return;
|
|
584
|
-
return slot.assignedElements({ flatten: true }).filter((node) => node.role === 'tabpanel');
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
// remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
588
|
-
_getTabInfo(id) {
|
|
589
|
-
return this._tabInfos.find((t) => t.id === id);
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
// remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
593
|
-
async _handleDefaultSlotChange(e) {
|
|
594
|
-
if (!this._defaultSlotBehavior) return;
|
|
595
|
-
|
|
596
|
-
const panels = this._getPanelsDefaultSlotBehavior(e.target);
|
|
597
|
-
|
|
598
|
-
// handle case where there are less than two tabs initially
|
|
599
|
-
this._updateTabListVisibility(panels);
|
|
600
|
-
|
|
601
|
-
if (!this._initialized && panels.length === 0) return;
|
|
602
|
-
|
|
603
|
-
let selectedTabInfo = null;
|
|
604
|
-
|
|
605
|
-
const newTabInfos = panels.map((panel) => {
|
|
606
|
-
let state = '';
|
|
607
|
-
if (this._initialized && !reduceMotion && panels.length !== this._tabInfos.length) {
|
|
608
|
-
// if it's a new tab, update state to animate addition
|
|
609
|
-
if (this._tabInfos.findIndex(info => info.id === panel.id) === -1) {
|
|
610
|
-
state = 'adding';
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
const tabInfo = {
|
|
614
|
-
id: panel.id,
|
|
615
|
-
text: panel.text,
|
|
616
|
-
selected: panel.selected,
|
|
617
|
-
state: state
|
|
618
|
-
};
|
|
619
|
-
if (tabInfo.selected) {
|
|
620
|
-
selectedTabInfo = tabInfo;
|
|
621
|
-
this._setFocusableDefaultSlotBehavior(tabInfo);
|
|
622
|
-
}
|
|
623
|
-
return tabInfo;
|
|
624
|
-
});
|
|
625
|
-
|
|
626
|
-
if (this._initialized && !reduceMotion && this._tabInfos.length !== newTabInfos.length) {
|
|
627
|
-
this._tabInfos.forEach((info, index) => {
|
|
628
|
-
// if a tab was removed, include old info to animate it away
|
|
629
|
-
if (newTabInfos.findIndex(newInfo => newInfo.id === info.id) === -1) {
|
|
630
|
-
info.state = 'removing';
|
|
631
|
-
info.selected = false;
|
|
632
|
-
newTabInfos.splice(index, 0, info);
|
|
633
|
-
}
|
|
634
|
-
});
|
|
635
|
-
}
|
|
636
|
-
this._tabInfos = newTabInfos;
|
|
637
|
-
|
|
638
|
-
if (this._tabInfos.length > 0 && !selectedTabInfo) {
|
|
639
|
-
selectedTabInfo = this._tabInfos.find(tabInfo => tabInfo.state !== 'removing');
|
|
640
|
-
if (selectedTabInfo) {
|
|
641
|
-
selectedTabInfo.activeFocusable = true;
|
|
642
|
-
selectedTabInfo.selected = true;
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
await this.updateComplete;
|
|
647
|
-
|
|
648
|
-
const animPromises = [];
|
|
649
|
-
if (!this._initialized && this._tabInfos.length > 0) {
|
|
650
|
-
|
|
651
|
-
this._initialized = true;
|
|
652
|
-
await this._updateTabsContainerWidthDefaultSlotBehavior(selectedTabInfo);
|
|
653
|
-
|
|
654
|
-
} else {
|
|
655
|
-
|
|
656
|
-
if (this._tabInfos.length > 1) {
|
|
657
|
-
this._tabInfos.forEach((info) => {
|
|
658
|
-
if (info.state === 'adding') animPromises.push(this._animateTabAdditionDefaultSlotBehavior(info));
|
|
659
|
-
else if (info.state === 'removing') animPromises.push(this._animateTabRemovalDefaultSlotBehavior(info));
|
|
660
|
-
});
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
// required for animation
|
|
664
|
-
this._updateMeasures();
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
if (selectedTabInfo) {
|
|
668
|
-
Promise.all(animPromises).then(() => {
|
|
669
|
-
this._updateMeasures();
|
|
670
|
-
return this._updateScrollPositionDefaultSlotBehavior(selectedTabInfo);
|
|
671
|
-
});
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
}
|
|
675
|
-
|
|
676
446
|
_handleFocusOut(e) {
|
|
677
447
|
if (e.relatedTarget && e.relatedTarget.role === 'tab') return;
|
|
678
448
|
this._resetFocusables();
|
|
679
449
|
}
|
|
680
450
|
|
|
681
|
-
// remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
682
|
-
_handlePanelSelected(e) {
|
|
683
|
-
if (!this._defaultSlotBehavior) return;
|
|
684
|
-
|
|
685
|
-
const tabInfo = this._getTabInfo(e.target.id);
|
|
686
|
-
// event could be from nested tabs
|
|
687
|
-
if (!tabInfo) return;
|
|
688
|
-
|
|
689
|
-
this._setFocusableDefaultSlotBehavior(tabInfo);
|
|
690
|
-
tabInfo.selected = true;
|
|
691
|
-
this.requestUpdate();
|
|
692
|
-
}
|
|
693
|
-
|
|
694
451
|
_handlePanelsSlotChange(e) {
|
|
695
|
-
if (this._defaultSlotBehavior) return;
|
|
696
|
-
|
|
697
452
|
this.#panels = e.target.assignedElements({ flatten: true }).filter((node) => node.role === 'tabpanel');
|
|
698
453
|
this.#checkTabPanelMatch();
|
|
699
454
|
this.#setAriaControls();
|
|
700
455
|
}
|
|
701
456
|
|
|
702
|
-
// remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
703
|
-
async _handlePanelTextChange(e) {
|
|
704
|
-
const tabInfo = this._getTabInfo(e.target.id);
|
|
705
|
-
// event could be from nested tabs
|
|
706
|
-
if (!tabInfo) return;
|
|
707
|
-
tabInfo.text = e.target.text;
|
|
708
|
-
this.requestUpdate();
|
|
709
|
-
await this.updateComplete;
|
|
710
|
-
this._updateMeasures();
|
|
711
|
-
await this._updateScrollVisibility(this._getMeasures());
|
|
712
|
-
}
|
|
713
|
-
|
|
714
457
|
_handleResize(entries) {
|
|
715
458
|
const measures = this._getMeasures();
|
|
716
459
|
if (entries.length === 1 && entries[0].contentRect.width === measures.tabsContainerListRect.width) return;
|
|
@@ -801,48 +544,13 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
801
544
|
}
|
|
802
545
|
|
|
803
546
|
async _handleTabSelected(e) {
|
|
804
|
-
if (this._defaultSlotBehavior) {
|
|
805
|
-
this._handleTabSelectedDefaultSlotBehavior(e);
|
|
806
|
-
return;
|
|
807
|
-
}
|
|
808
|
-
|
|
809
547
|
const selectedTab = e.target;
|
|
810
548
|
this.#updateSelectedTab(selectedTab);
|
|
811
549
|
await this.updateComplete;
|
|
812
550
|
this._updateScrollPosition(selectedTab);
|
|
813
551
|
}
|
|
814
552
|
|
|
815
|
-
// remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
816
|
-
async _handleTabSelectedDefaultSlotBehavior(e) {
|
|
817
|
-
e.stopPropagation();
|
|
818
|
-
|
|
819
|
-
const selectedTab = e.target;
|
|
820
|
-
const selectedPanel = this._getPanel(selectedTab.controlsPanel);
|
|
821
|
-
const selectedTabInfo = this._getTabInfo(selectedTab.controlsPanel);
|
|
822
|
-
selectedTabInfo.activeFocusable = true;
|
|
823
|
-
|
|
824
|
-
await this.updateComplete;
|
|
825
|
-
this._updateScrollPositionDefaultSlotBehavior(selectedTabInfo);
|
|
826
|
-
|
|
827
|
-
selectedPanel.selected = true;
|
|
828
|
-
this._tabInfos.forEach((tabInfo) => {
|
|
829
|
-
if (tabInfo.id !== selectedTab.controlsPanel) {
|
|
830
|
-
if (tabInfo.selected) {
|
|
831
|
-
tabInfo.selected = false;
|
|
832
|
-
const panel = this._getPanel(tabInfo.id);
|
|
833
|
-
// panel may not exist if it's being removed
|
|
834
|
-
if (panel) panel.selected = false;
|
|
835
|
-
}
|
|
836
|
-
if (tabInfo.activeFocusable) tabInfo.activeFocusable = false;
|
|
837
|
-
}
|
|
838
|
-
});
|
|
839
|
-
|
|
840
|
-
this.requestUpdate();
|
|
841
|
-
}
|
|
842
|
-
|
|
843
553
|
async _handleTabsSlotChange(e) {
|
|
844
|
-
this._defaultSlotBehavior = false;
|
|
845
|
-
|
|
846
554
|
this._tabs = e.target.assignedElements({ flatten: true }).filter((node) => node.role === 'tab');
|
|
847
555
|
|
|
848
556
|
// handle case where there are less than two tabs initially
|
|
@@ -912,13 +620,8 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
912
620
|
}
|
|
913
621
|
|
|
914
622
|
_resetFocusables() {
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
if (selectedTab) this._setFocusableDefaultSlotBehavior(selectedTab);
|
|
918
|
-
} else {
|
|
919
|
-
const selectedTab = this._tabs.find(ti => ti.selected);
|
|
920
|
-
if (selectedTab) this._setFocusable(selectedTab);
|
|
921
|
-
}
|
|
623
|
+
const selectedTab = this._tabs.find(ti => ti.selected);
|
|
624
|
+
if (selectedTab) this._setFocusable(selectedTab);
|
|
922
625
|
this.requestUpdate();
|
|
923
626
|
}
|
|
924
627
|
|
|
@@ -950,14 +653,6 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
950
653
|
tab.tabIndex = 0;
|
|
951
654
|
}
|
|
952
655
|
|
|
953
|
-
// remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
954
|
-
_setFocusableDefaultSlotBehavior(tabInfo) {
|
|
955
|
-
const currentFocusable = this._tabInfos.find(ti => ti.activeFocusable);
|
|
956
|
-
if (currentFocusable) currentFocusable.activeFocusable = false;
|
|
957
|
-
|
|
958
|
-
tabInfo.activeFocusable = true;
|
|
959
|
-
}
|
|
960
|
-
|
|
961
656
|
async _tryExpandTabsContainer(measures) {
|
|
962
657
|
|
|
963
658
|
if (!this._scrollCollapsed) return false;
|
|
@@ -1005,11 +700,11 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
1005
700
|
_updateMeasures() {
|
|
1006
701
|
let totalTabsWidth = 0;
|
|
1007
702
|
if (!this.shadowRoot) return;
|
|
1008
|
-
const tabs = this.
|
|
703
|
+
const tabs = this._tabs;
|
|
1009
704
|
|
|
1010
705
|
const tabRects = tabs.map((tab) => {
|
|
1011
706
|
const tabRect = tab.getBoundingClientRect();
|
|
1012
|
-
const offsetLeft =
|
|
707
|
+
const offsetLeft = getOffsetLeft(tab, tabRect);
|
|
1013
708
|
|
|
1014
709
|
const measures = {
|
|
1015
710
|
rect: tabRect,
|
|
@@ -1033,13 +728,6 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
1033
728
|
return this.#updateScrollPositionLogic(measures, newTranslationValue);
|
|
1034
729
|
}
|
|
1035
730
|
|
|
1036
|
-
// remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
1037
|
-
_updateScrollPositionDefaultSlotBehavior(selectedTabInfo) {
|
|
1038
|
-
const measures = this._getMeasures();
|
|
1039
|
-
const newTranslationValue = this._calculateScrollPositionDefaultSlotBehavior(selectedTabInfo, measures);
|
|
1040
|
-
return this.#updateScrollPositionLogic(measures, newTranslationValue);
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
731
|
_updateScrollVisibility(measures) {
|
|
1044
732
|
|
|
1045
733
|
const lastTabMeasures = measures.tabRects[measures.tabRects.length - 1];
|
|
@@ -1061,19 +749,6 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
1061
749
|
}
|
|
1062
750
|
|
|
1063
751
|
_updateTabListVisibility(tabs) {
|
|
1064
|
-
// remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
1065
|
-
if (!this.#newTabsPanelStructure) {
|
|
1066
|
-
if (this._state === 'shown' && tabs.length < 2) {
|
|
1067
|
-
this.#hideTabsList();
|
|
1068
|
-
} else if (this._state === 'hidden' && tabs.length > 1) {
|
|
1069
|
-
this.#showTabsList();
|
|
1070
|
-
} else if (this._state === 'shown' && tabs.length > 1) {
|
|
1071
|
-
// check if there are hidden tabs and tab list container should actually be hidden
|
|
1072
|
-
this.#handleTabHiddenChange();
|
|
1073
|
-
}
|
|
1074
|
-
return;
|
|
1075
|
-
}
|
|
1076
|
-
|
|
1077
752
|
const visibleCount = tabs.filter(tab => !tab.hidden).length;
|
|
1078
753
|
if (this._state === 'shown' && visibleCount < 2) {
|
|
1079
754
|
this.#hideTabsList();
|
|
@@ -1092,13 +767,6 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
1092
767
|
return this.#updateTabsContainerWidthLogic();
|
|
1093
768
|
}
|
|
1094
769
|
|
|
1095
|
-
// remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
1096
|
-
_updateTabsContainerWidthDefaultSlotBehavior(selectedTabInfo) {
|
|
1097
|
-
if (!this.maxToShow || this.maxToShow <= 0 || this.maxToShow >= this._tabInfos.length) return;
|
|
1098
|
-
if (this._tabInfos.indexOf(selectedTabInfo) > this.maxToShow - 1) return;
|
|
1099
|
-
return this.#updateTabsContainerWidthLogic();
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
770
|
#calculateScrollPositionLogic(tabsDataStructure, selectedTabIndex, measures) {
|
|
1103
771
|
if (!measures.tabRects[selectedTabIndex]) return 0;
|
|
1104
772
|
|
|
@@ -1199,10 +867,7 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
1199
867
|
|
|
1200
868
|
#handleTabDeselected(e) {
|
|
1201
869
|
const panel = this._getPanel(e.target.id);
|
|
1202
|
-
if (panel)
|
|
1203
|
-
if (this.#newTabsPanelStructure) panel._selected = false;
|
|
1204
|
-
else panel.selected = false; // remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
1205
|
-
}
|
|
870
|
+
if (panel) panel._selected = false;
|
|
1206
871
|
}
|
|
1207
872
|
|
|
1208
873
|
#handleTabHiddenChange() {
|
|
@@ -1290,20 +955,14 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(SkeletonMixin(LitElement))
|
|
|
1290
955
|
selectedTab.tabIndex = 0;
|
|
1291
956
|
|
|
1292
957
|
const selectedPanel = this._getPanel(selectedTab.id);
|
|
1293
|
-
if (selectedPanel)
|
|
1294
|
-
if (this.#newTabsPanelStructure) selectedPanel._selected = true;
|
|
1295
|
-
else selectedPanel.selected = true; // remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
1296
|
-
}
|
|
958
|
+
if (selectedPanel) selectedPanel._selected = true;
|
|
1297
959
|
this._tabs.forEach((tab) => {
|
|
1298
960
|
if (tab.id !== selectedTab.id) {
|
|
1299
961
|
if (tab.selected) {
|
|
1300
962
|
tab.selected = false;
|
|
1301
963
|
const panel = this._getPanel(tab.id);
|
|
1302
964
|
// panel may not exist if it's being removed
|
|
1303
|
-
if (panel)
|
|
1304
|
-
if (this.#newTabsPanelStructure) panel._selected = false;
|
|
1305
|
-
else panel.selected = false; // remove with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
1306
|
-
}
|
|
965
|
+
if (panel) panel._selected = false;
|
|
1307
966
|
}
|
|
1308
967
|
if (tab.tabIndex === 0) tab.tabIndex = -1;
|
|
1309
968
|
}
|
package/custom-elements.json
CHANGED
|
@@ -16765,80 +16765,6 @@
|
|
|
16765
16765
|
"name": "d2l-tabs-array",
|
|
16766
16766
|
"path": "./components/tabs/demo/tabs-array.js"
|
|
16767
16767
|
},
|
|
16768
|
-
{
|
|
16769
|
-
"name": "d2l-tab-internal",
|
|
16770
|
-
"path": "./components/tabs/tab-internal.js",
|
|
16771
|
-
"attributes": [
|
|
16772
|
-
{
|
|
16773
|
-
"name": "controls-panel",
|
|
16774
|
-
"type": "string"
|
|
16775
|
-
},
|
|
16776
|
-
{
|
|
16777
|
-
"name": "text",
|
|
16778
|
-
"type": "string"
|
|
16779
|
-
},
|
|
16780
|
-
{
|
|
16781
|
-
"name": "aria-selected",
|
|
16782
|
-
"type": "string",
|
|
16783
|
-
"default": "\"false\""
|
|
16784
|
-
},
|
|
16785
|
-
{
|
|
16786
|
-
"name": "role",
|
|
16787
|
-
"type": "string",
|
|
16788
|
-
"default": "\"tab\""
|
|
16789
|
-
},
|
|
16790
|
-
{
|
|
16791
|
-
"name": "skeleton",
|
|
16792
|
-
"description": "Render the component as a [skeleton loader](https://github.com/BrightspaceUI/core/tree/main/components/skeleton).",
|
|
16793
|
-
"type": "boolean"
|
|
16794
|
-
}
|
|
16795
|
-
],
|
|
16796
|
-
"properties": [
|
|
16797
|
-
{
|
|
16798
|
-
"name": "controlsPanel",
|
|
16799
|
-
"attribute": "controls-panel",
|
|
16800
|
-
"type": "string"
|
|
16801
|
-
},
|
|
16802
|
-
{
|
|
16803
|
-
"name": "text",
|
|
16804
|
-
"attribute": "text",
|
|
16805
|
-
"type": "string"
|
|
16806
|
-
},
|
|
16807
|
-
{
|
|
16808
|
-
"name": "styles",
|
|
16809
|
-
"type": "array",
|
|
16810
|
-
"default": "[\"styles\",null]"
|
|
16811
|
-
},
|
|
16812
|
-
{
|
|
16813
|
-
"name": "ariaSelected",
|
|
16814
|
-
"attribute": "aria-selected",
|
|
16815
|
-
"type": "string",
|
|
16816
|
-
"default": "\"false\""
|
|
16817
|
-
},
|
|
16818
|
-
{
|
|
16819
|
-
"name": "role",
|
|
16820
|
-
"attribute": "role",
|
|
16821
|
-
"type": "string",
|
|
16822
|
-
"default": "\"tab\""
|
|
16823
|
-
},
|
|
16824
|
-
{
|
|
16825
|
-
"name": "tabIndex",
|
|
16826
|
-
"type": "number",
|
|
16827
|
-
"default": "-1"
|
|
16828
|
-
},
|
|
16829
|
-
{
|
|
16830
|
-
"name": "skeleton",
|
|
16831
|
-
"attribute": "skeleton",
|
|
16832
|
-
"description": "Render the component as a [skeleton loader](https://github.com/BrightspaceUI/core/tree/main/components/skeleton).",
|
|
16833
|
-
"type": "boolean"
|
|
16834
|
-
}
|
|
16835
|
-
],
|
|
16836
|
-
"events": [
|
|
16837
|
-
{
|
|
16838
|
-
"name": "d2l-tab-selected"
|
|
16839
|
-
}
|
|
16840
|
-
]
|
|
16841
|
-
},
|
|
16842
16768
|
{
|
|
16843
16769
|
"name": "d2l-tab-panel",
|
|
16844
16770
|
"path": "./components/tabs/tab-panel.js",
|
|
@@ -16849,16 +16775,6 @@
|
|
|
16849
16775
|
"description": "REQUIRED: Id of the tab that labels this panel",
|
|
16850
16776
|
"type": "string"
|
|
16851
16777
|
},
|
|
16852
|
-
{
|
|
16853
|
-
"name": "selected",
|
|
16854
|
-
"description": "DEPRECATED: Use to select the tab. Do NOT set if using the d2l-tab/d2l-tab-panel implementation.\nRemove with GAUD-8299-core-tabs-use-new-structure flag clean up.",
|
|
16855
|
-
"type": "boolean"
|
|
16856
|
-
},
|
|
16857
|
-
{
|
|
16858
|
-
"name": "text",
|
|
16859
|
-
"description": "DEPRECATED: The text used for the tab, as well as labelling the panel. Required if not using d2l-tab/d2l-tab-panel implementation.\nRemove with GAUD-8299-core-tabs-use-new-structure flag clean up.",
|
|
16860
|
-
"type": "string"
|
|
16861
|
-
},
|
|
16862
16778
|
{
|
|
16863
16779
|
"name": "no-padding",
|
|
16864
16780
|
"description": "Opt out of default padding/whitespace around the panel",
|
|
@@ -16873,21 +16789,9 @@
|
|
|
16873
16789
|
"description": "REQUIRED: Id of the tab that labels this panel",
|
|
16874
16790
|
"type": "string"
|
|
16875
16791
|
},
|
|
16876
|
-
{
|
|
16877
|
-
"name": "selected",
|
|
16878
|
-
"attribute": "selected",
|
|
16879
|
-
"description": "DEPRECATED: Use to select the tab. Do NOT set if using the d2l-tab/d2l-tab-panel implementation.\nRemove with GAUD-8299-core-tabs-use-new-structure flag clean up.",
|
|
16880
|
-
"type": "boolean"
|
|
16881
|
-
},
|
|
16882
|
-
{
|
|
16883
|
-
"name": "text",
|
|
16884
|
-
"attribute": "text",
|
|
16885
|
-
"description": "DEPRECATED: The text used for the tab, as well as labelling the panel. Required if not using d2l-tab/d2l-tab-panel implementation.\nRemove with GAUD-8299-core-tabs-use-new-structure flag clean up.",
|
|
16886
|
-
"type": "string"
|
|
16887
|
-
},
|
|
16888
16792
|
{
|
|
16889
16793
|
"name": "styles",
|
|
16890
|
-
"default": "\"css`\\n\\t\\t:host {\\n\\t\\t\\tbox-sizing: border-box;\\n\\t\\t\\tdisplay: none;\\n\\t\\t\\tmargin: 1.2rem 0 0 0;\\n\\t\\t}\\n\\t\\t:host([no-padding]) {\\n\\t\\t\\tmargin: 0;\\n\\t\\t}\\n\\t\\t
|
|
16794
|
+
"default": "\"css`\\n\\t\\t:host {\\n\\t\\t\\tbox-sizing: border-box;\\n\\t\\t\\tdisplay: none;\\n\\t\\t\\tmargin: 1.2rem 0 0 0;\\n\\t\\t}\\n\\t\\t:host([no-padding]) {\\n\\t\\t\\tmargin: 0;\\n\\t\\t}\\n\\t\\t:host([_selected]) {\\n\\t\\t\\tdisplay: block;\\n\\t\\t}\\n\\t`\""
|
|
16891
16795
|
},
|
|
16892
16796
|
{
|
|
16893
16797
|
"name": "noPadding",
|
|
@@ -16897,16 +16801,6 @@
|
|
|
16897
16801
|
"default": "false"
|
|
16898
16802
|
}
|
|
16899
16803
|
],
|
|
16900
|
-
"events": [
|
|
16901
|
-
{
|
|
16902
|
-
"name": "d2l-tab-panel-selected",
|
|
16903
|
-
"description": "DEPRECATED: Dispatched when a tab is selected"
|
|
16904
|
-
},
|
|
16905
|
-
{
|
|
16906
|
-
"name": "d2l-tab-panel-text-changed",
|
|
16907
|
-
"description": "DEPRECATED: Dispatched when the text attribute is changed"
|
|
16908
|
-
}
|
|
16909
|
-
],
|
|
16910
16804
|
"slots": [
|
|
16911
16805
|
{
|
|
16912
16806
|
"name": "",
|
|
@@ -17060,10 +16954,6 @@
|
|
|
17060
16954
|
}
|
|
17061
16955
|
],
|
|
17062
16956
|
"slots": [
|
|
17063
|
-
{
|
|
17064
|
-
"name": "",
|
|
17065
|
-
"description": "DEPRECATED: Contains the tab panels (e.g., \"d2l-tab-panel\" components)"
|
|
17066
|
-
},
|
|
17067
16957
|
{
|
|
17068
16958
|
"name": "ext",
|
|
17069
16959
|
"description": "Additional content (e.g., a button) positioned at right"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brightspace-ui/core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.317.0",
|
|
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",
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import '../colors/colors.js';
|
|
2
|
-
import { css, html, LitElement } from 'lit';
|
|
3
|
-
import { classMap } from 'lit/directives/class-map.js';
|
|
4
|
-
import { getFocusRingStyles } from '../../helpers/focus.js';
|
|
5
|
-
import { overflowEllipsisDeclarations } from '../../helpers/overflow.js';
|
|
6
|
-
import { SkeletonMixin } from '../skeleton/skeleton-mixin.js';
|
|
7
|
-
|
|
8
|
-
const keyCodes = {
|
|
9
|
-
ENTER: 13,
|
|
10
|
-
SPACE: 32
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
// remove file with GAUD-8299-core-tabs-use-new-structure flag clean up
|
|
14
|
-
class Tab extends SkeletonMixin(LitElement) {
|
|
15
|
-
|
|
16
|
-
static properties = {
|
|
17
|
-
ariaSelected: { type: String, reflect: true, attribute: 'aria-selected' },
|
|
18
|
-
controlsPanel: { type: String, reflect: true, attribute: 'controls-panel' },
|
|
19
|
-
// eslint-disable-next-line lit/no-native-attributes
|
|
20
|
-
role: { type: String, reflect: true },
|
|
21
|
-
text: { type: String }
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
static styles = [super.styles, css`
|
|
25
|
-
:host {
|
|
26
|
-
box-sizing: border-box;
|
|
27
|
-
display: inline-block;
|
|
28
|
-
max-width: 200px;
|
|
29
|
-
outline: none;
|
|
30
|
-
position: relative;
|
|
31
|
-
vertical-align: middle;
|
|
32
|
-
}
|
|
33
|
-
.d2l-tab-text {
|
|
34
|
-
--d2l-focus-ring-offset: 0;
|
|
35
|
-
margin: 0.5rem;
|
|
36
|
-
padding: 0.1rem;
|
|
37
|
-
${overflowEllipsisDeclarations}
|
|
38
|
-
}
|
|
39
|
-
:host([skeleton]) .d2l-tab-text.d2l-skeletize::before {
|
|
40
|
-
bottom: 0.15rem;
|
|
41
|
-
top: 0.15rem;
|
|
42
|
-
}
|
|
43
|
-
:host(:first-child) .d2l-tab-text {
|
|
44
|
-
margin-inline-start: 0;
|
|
45
|
-
}
|
|
46
|
-
.d2l-tab-selected-indicator {
|
|
47
|
-
border-top: 4px solid var(--d2l-theme-brand-color-primary-default);
|
|
48
|
-
border-top-left-radius: 4px;
|
|
49
|
-
border-top-right-radius: 4px;
|
|
50
|
-
bottom: 0;
|
|
51
|
-
display: none;
|
|
52
|
-
margin: 1px 0.6rem 0 0.6rem;
|
|
53
|
-
position: absolute;
|
|
54
|
-
-webkit-transition: box-shadow 0.2s;
|
|
55
|
-
transition: box-shadow 0.2s;
|
|
56
|
-
width: calc(100% - 1.2rem);
|
|
57
|
-
}
|
|
58
|
-
:host([skeleton]) .d2l-tab-selected-indicator {
|
|
59
|
-
position: absolute; /* make sure skeleton styles do not override this */
|
|
60
|
-
}
|
|
61
|
-
.d2l-tab-text-skeletize-override {
|
|
62
|
-
min-width: 50px;
|
|
63
|
-
}
|
|
64
|
-
:host(:first-child) .d2l-tab-selected-indicator {
|
|
65
|
-
margin-inline-start: 0;
|
|
66
|
-
width: calc(100% - 0.6rem);
|
|
67
|
-
}
|
|
68
|
-
${getFocusRingStyles(pseudoClass => `:host(:${pseudoClass}) > .d2l-tab-text`, { extraStyles: css`border-radius: 0.3rem; color: var(--d2l-theme-text-color-interactive-default);` })}
|
|
69
|
-
:host([aria-selected="true"]:focus) {
|
|
70
|
-
text-decoration: none;
|
|
71
|
-
}
|
|
72
|
-
:host(:hover) {
|
|
73
|
-
color: var(--d2l-theme-text-color-interactive-default);
|
|
74
|
-
cursor: pointer;
|
|
75
|
-
}
|
|
76
|
-
:host([aria-selected="true"]:hover) {
|
|
77
|
-
color: inherit;
|
|
78
|
-
cursor: default;
|
|
79
|
-
}
|
|
80
|
-
:host([aria-selected="true"]) .d2l-tab-selected-indicator {
|
|
81
|
-
display: block;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
@media (prefers-reduced-motion: reduce) {
|
|
85
|
-
.d2l-tab-selected-indicator {
|
|
86
|
-
-webkit-transition: none;
|
|
87
|
-
transition: none;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
`];
|
|
91
|
-
|
|
92
|
-
constructor() {
|
|
93
|
-
super();
|
|
94
|
-
this.ariaSelected = 'false';
|
|
95
|
-
this.role = 'tab';
|
|
96
|
-
this.tabIndex = -1;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
firstUpdated(changedProperties) {
|
|
100
|
-
super.firstUpdated(changedProperties);
|
|
101
|
-
this.addEventListener('click', () => {
|
|
102
|
-
this.ariaSelected = 'true';
|
|
103
|
-
});
|
|
104
|
-
this.addEventListener('keydown', (e) => {
|
|
105
|
-
if (e.keyCode !== keyCodes.SPACE) return;
|
|
106
|
-
e.stopPropagation();
|
|
107
|
-
e.preventDefault();
|
|
108
|
-
});
|
|
109
|
-
this.addEventListener('keyup', (e) => {
|
|
110
|
-
if (e.keyCode !== keyCodes.ENTER && e.keyCode !== keyCodes.SPACE) return;
|
|
111
|
-
this.ariaSelected = 'true';
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
render() {
|
|
116
|
-
const overrideSkeletonText = this.skeleton && (!this.text || this.text.length === 0);
|
|
117
|
-
const textClasses = {
|
|
118
|
-
'd2l-tab-text': true,
|
|
119
|
-
'd2l-skeletize': true,
|
|
120
|
-
'd2l-tab-text-skeletize-override': overrideSkeletonText
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
return html`
|
|
124
|
-
<div class="${classMap(textClasses)}">${overrideSkeletonText ? html` ` : this.text}</div>
|
|
125
|
-
<div class="d2l-tab-selected-indicator d2l-skeletize-container"></div>
|
|
126
|
-
`;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
update(changedProperties) {
|
|
130
|
-
super.update(changedProperties);
|
|
131
|
-
changedProperties.forEach((oldVal, prop) => {
|
|
132
|
-
if (prop === 'ariaSelected' && this.ariaSelected === 'true') {
|
|
133
|
-
this.dispatchEvent(new CustomEvent(
|
|
134
|
-
'd2l-tab-selected', { bubbles: true, composed: true }
|
|
135
|
-
));
|
|
136
|
-
} else if (prop === 'text') {
|
|
137
|
-
this.title = this.text;
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
customElements.define('d2l-tab-internal', Tab);
|