@brightspace-ui/core 1.215.0 → 1.219.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/button/button-mixin.js +1 -1
- package/components/calendar/calendar.js +5 -5
- package/components/card/card-footer-link.js +2 -2
- package/components/card/card.js +1 -1
- package/components/count-badge/count-badge-mixin.js +1 -1
- package/components/demo/code-view.js +4 -3
- package/components/demo/demo-snippet.js +5 -2
- package/components/dialog/dialog-confirm.js +1 -0
- package/components/dialog/dialog-mixin.js +7 -2
- package/components/dropdown/dropdown-button-subtle.js +1 -1
- package/components/dropdown/dropdown-button.js +1 -1
- package/components/dropdown/dropdown-content-mixin.js +6 -6
- package/components/dropdown/dropdown-context-menu.js +1 -1
- package/components/dropdown/dropdown-menu.js +1 -0
- package/components/dropdown/dropdown-more.js +1 -1
- package/components/dropdown/dropdown-opener-mixin.js +1 -0
- package/components/dropdown/dropdown-tabs.js +1 -0
- package/components/dropdown/dropdown.js +1 -0
- package/components/expand-collapse/expand-collapse-content.js +4 -4
- package/components/filter/README.md +1 -0
- package/components/filter/filter-dimension-set.js +7 -1
- package/components/filter/filter.js +63 -4
- package/components/focus-trap/focus-trap.js +6 -5
- package/components/form/demo/form-demo.js +1 -1
- package/components/form/demo/form-dialog-demo.js +4 -4
- package/components/form/demo/form-native-demo.js +1 -1
- package/components/form/form-element-mixin.js +12 -3
- package/components/form/form-errory-summary.js +2 -2
- package/components/form/form-native.js +1 -1
- package/components/form/form.js +1 -1
- package/components/hierarchical-view/hierarchical-view-mixin.js +7 -6
- package/components/html-block/html-block.js +1 -0
- package/components/inputs/demo/input-radio-solo-test.js +1 -1
- package/components/inputs/demo/input-radio-spacer-test.js +1 -1
- package/components/inputs/demo/input-select-test.js +1 -1
- package/components/inputs/input-checkbox.js +1 -1
- package/components/inputs/input-date-range.js +4 -3
- package/components/inputs/input-date-time-range-to.js +1 -1
- package/components/inputs/input-date-time-range.js +4 -3
- package/components/inputs/input-date-time.js +6 -5
- package/components/inputs/input-date.js +3 -0
- package/components/inputs/input-number.js +2 -1
- package/components/inputs/input-percent.js +2 -1
- package/components/inputs/input-search.js +3 -3
- package/components/inputs/input-text.js +8 -8
- package/components/inputs/input-textarea.js +5 -5
- package/components/inputs/input-time-range.js +4 -4
- package/components/inputs/input-time.js +1 -1
- package/components/link/link.js +1 -1
- package/components/list/demo/list-drag-and-drop.js +3 -1
- package/components/list/list-item-button-mixin.js +7 -1
- package/components/list/list-item-checkbox-mixin.js +1 -1
- package/components/list/list-item-drag-drop-mixin.js +10 -5
- package/components/list/list-item-drag-handle.js +43 -5
- package/components/list/list-item-generic-layout.js +5 -4
- package/components/list/list-item-link-mixin.js +3 -1
- package/components/list/list-item-mixin.js +55 -3
- package/components/list/list-item-role-mixin.js +2 -1
- package/components/list/list.js +2 -0
- package/components/menu/demo/custom-view.js +1 -1
- package/components/menu/menu-item-link.js +1 -1
- package/components/menu/menu-item-mixin.js +1 -1
- package/components/menu/menu.js +2 -2
- package/components/overflow-group/overflow-group.js +1 -1
- package/components/scroll-wrapper/demo/scroll-wrapper-test.js +1 -1
- package/components/selection/selection-action.js +1 -1
- package/components/selection/selection-input.js +1 -1
- package/components/selection/selection-select-all.js +1 -1
- package/components/switch/switch-mixin.js +1 -1
- package/components/table/table-col-sort-button.js +1 -1
- package/components/tabs/tabs.js +20 -15
- package/components/tooltip/tooltip.js +1 -1
- package/controllers/subscriber/README.md +3 -3
- package/controllers/subscriber/subscriberControllers.js +4 -4
- package/custom-elements.json +13 -0
- package/helpers/demo/announce-test.js +1 -0
- package/lang/ar.js +20 -5
- package/lang/cy.js +20 -5
- package/lang/da.js +20 -5
- package/lang/de.js +20 -5
- package/lang/en.js +16 -0
- package/lang/es-es.js +20 -5
- package/lang/es.js +20 -5
- package/lang/fr-fr.js +20 -5
- package/lang/fr.js +20 -5
- package/lang/ja.js +20 -5
- package/lang/ko.js +20 -5
- package/lang/nl.js +20 -5
- package/lang/pt.js +20 -5
- package/lang/sv.js +20 -5
- package/lang/tr.js +20 -5
- package/lang/zh-tw.js +20 -5
- package/lang/zh.js +20 -5
- package/mixins/arrow-keys-mixin.js +3 -1
- package/package.json +1 -1
- package/templates/primary-secondary/primary-secondary.js +2 -1
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import '../button/button-icon.js';
|
|
2
2
|
import '../icons/icon.js';
|
|
3
|
+
import '../tooltip/tooltip.js';
|
|
3
4
|
import { css, html, LitElement } from 'lit-element/lit-element.js';
|
|
4
5
|
import { buttonStyles } from '../button/button-styles.js';
|
|
5
6
|
import { findComposedAncestor } from '../../helpers/dom.js';
|
|
6
7
|
import { getFirstFocusableDescendant } from '../../helpers/focus.js';
|
|
8
|
+
import { getUniqueId } from '../../helpers/uniqueId.js';
|
|
7
9
|
import { LocalizeCoreElement } from '../../lang/localize-core-element.js';
|
|
8
10
|
import { RtlMixin } from '../../mixins/rtl-mixin.js';
|
|
9
11
|
|
|
@@ -36,6 +38,8 @@ export const dragActions = Object.freeze({
|
|
|
36
38
|
up: 'up'
|
|
37
39
|
});
|
|
38
40
|
|
|
41
|
+
let hasDisplayedKeyboardTooltip = false;
|
|
42
|
+
|
|
39
43
|
/**
|
|
40
44
|
* @fires d2l-list-item-drag-handle-action - Dispatched when an action performed on the drag handle
|
|
41
45
|
*/
|
|
@@ -58,6 +62,7 @@ class ListItemDragHandle extends LocalizeCoreElement(RtlMixin(LitElement)) {
|
|
|
58
62
|
* @type {string}
|
|
59
63
|
*/
|
|
60
64
|
text: { type: String },
|
|
65
|
+
_displayKeyboardTooltip: { type: Boolean },
|
|
61
66
|
_keyboardActive: { type: Boolean }
|
|
62
67
|
};
|
|
63
68
|
}
|
|
@@ -109,6 +114,15 @@ class ListItemDragHandle extends LocalizeCoreElement(RtlMixin(LitElement)) {
|
|
|
109
114
|
cursor: default;
|
|
110
115
|
opacity: 0.5;
|
|
111
116
|
}
|
|
117
|
+
d2l-tooltip > div {
|
|
118
|
+
font-weight: 700;
|
|
119
|
+
}
|
|
120
|
+
d2l-tooltip > ul {
|
|
121
|
+
padding-inline-start: 1rem;
|
|
122
|
+
}
|
|
123
|
+
.d2l-list-item-drag-handle-tooltip-key {
|
|
124
|
+
font-weight: 700;
|
|
125
|
+
}
|
|
112
126
|
`];
|
|
113
127
|
}
|
|
114
128
|
|
|
@@ -117,6 +131,8 @@ class ListItemDragHandle extends LocalizeCoreElement(RtlMixin(LitElement)) {
|
|
|
117
131
|
|
|
118
132
|
this.disabled = false;
|
|
119
133
|
|
|
134
|
+
this._buttonId = getUniqueId();
|
|
135
|
+
this._displayKeyboardTooltip = false;
|
|
120
136
|
this._keyboardActive = false;
|
|
121
137
|
this._movingElement = false;
|
|
122
138
|
}
|
|
@@ -219,7 +235,14 @@ class ListItemDragHandle extends LocalizeCoreElement(RtlMixin(LitElement)) {
|
|
|
219
235
|
this._movingElement = false;
|
|
220
236
|
}
|
|
221
237
|
|
|
222
|
-
|
|
238
|
+
_onFocusInKeyboardButton() {
|
|
239
|
+
if (hasDisplayedKeyboardTooltip) return;
|
|
240
|
+
this._displayKeyboardTooltip = true;
|
|
241
|
+
hasDisplayedKeyboardTooltip = true;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
_onFocusOutKeyboardButton(e) {
|
|
245
|
+
this._displayKeyboardTooltip = false;
|
|
223
246
|
if (this._movingElement) {
|
|
224
247
|
this._movingElement = false;
|
|
225
248
|
e.stopPropagation();
|
|
@@ -266,17 +289,32 @@ class ListItemDragHandle extends LocalizeCoreElement(RtlMixin(LitElement)) {
|
|
|
266
289
|
_renderKeyboardDragging() {
|
|
267
290
|
return html`
|
|
268
291
|
<button
|
|
292
|
+
aria-label="${this._defaultLabel}"
|
|
293
|
+
aria-live="assertive"
|
|
269
294
|
class="d2l-list-item-drag-handle-keyboard-button"
|
|
270
|
-
@
|
|
271
|
-
@
|
|
295
|
+
@focusin="${this._onFocusInKeyboardButton}"
|
|
296
|
+
@focusout="${this._onFocusOutKeyboardButton}"
|
|
297
|
+
id="${this._buttonId}"
|
|
272
298
|
@keydown="${this._onPreventDefault}"
|
|
273
|
-
|
|
274
|
-
aria-label="${this._defaultLabel}">
|
|
299
|
+
@keyup="${this._onActiveKeyboard}">
|
|
275
300
|
<d2l-icon icon="tier1:arrow-toggle-up" @click="${this._dispatchActionUp}" class="d2l-button-icon"></d2l-icon>
|
|
276
301
|
<d2l-icon icon="tier1:arrow-toggle-down" @click="${this._dispatchActionDown}" class="d2l-button-icon"></d2l-icon>
|
|
277
302
|
</button>
|
|
303
|
+
${this._displayKeyboardTooltip ? html`<d2l-tooltip align="start" for="${this._buttonId}" for-type="descriptor">${this._renderTooltipContent()}</d2l-tooltip>` : ''}
|
|
278
304
|
`;
|
|
279
305
|
}
|
|
306
|
+
|
|
307
|
+
_renderTooltipContent() {
|
|
308
|
+
return html`
|
|
309
|
+
<div>${this.localize('components.list-item-drag-handle-tooltip.title')}</div>
|
|
310
|
+
<ul>
|
|
311
|
+
<li><span class="d2l-list-item-drag-handle-tooltip-key">${this.localize('components.list-item-drag-handle-tooltip.enter-key')}</span> - ${this.localize('components.list-item-drag-handle-tooltip.enter-desc')}</li>
|
|
312
|
+
<li><span class="d2l-list-item-drag-handle-tooltip-key">${this.localize('components.list-item-drag-handle-tooltip.up-down-key')}</span> - ${this.localize('components.list-item-drag-handle-tooltip.up-down-desc')}</li>
|
|
313
|
+
<li><span class="d2l-list-item-drag-handle-tooltip-key">${this.localize('components.list-item-drag-handle-tooltip.left-right-key')}</span> - ${this.localize('components.list-item-drag-handle-tooltip.left-right-desc')}</li>
|
|
314
|
+
</ul>
|
|
315
|
+
`;
|
|
316
|
+
}
|
|
317
|
+
|
|
280
318
|
}
|
|
281
319
|
|
|
282
320
|
customElements.define('d2l-list-item-drag-handle', ListItemDragHandle);
|
|
@@ -171,7 +171,7 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
|
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
_focusCellItem(num, itemNum) {
|
|
174
|
-
const cell = this.shadowRoot.querySelector(`[data-cell-num="${num}"]`);
|
|
174
|
+
const cell = this.shadowRoot && this.shadowRoot.querySelector(`[data-cell-num="${num}"]`);
|
|
175
175
|
if (!cell) return;
|
|
176
176
|
|
|
177
177
|
const firstFocusable = getFirstFocusableDescendant(cell);
|
|
@@ -197,7 +197,7 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
|
|
|
197
197
|
let focusable = null;
|
|
198
198
|
let num = 1;
|
|
199
199
|
do {
|
|
200
|
-
cell = this.shadowRoot.querySelector(`[data-cell-num="${num++}"]`);
|
|
200
|
+
cell = this.shadowRoot && this.shadowRoot.querySelector(`[data-cell-num="${num++}"]`);
|
|
201
201
|
if (cell) {
|
|
202
202
|
focusable = getLastFocusableDescendant(cell) || focusable;
|
|
203
203
|
}
|
|
@@ -220,7 +220,7 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
|
|
|
220
220
|
let focusable = null;
|
|
221
221
|
|
|
222
222
|
do {
|
|
223
|
-
cell = this.shadowRoot.querySelector(`[data-cell-num="${num}"]`);
|
|
223
|
+
cell = this.shadowRoot && this.shadowRoot.querySelector(`[data-cell-num="${num}"]`);
|
|
224
224
|
if (cell) {
|
|
225
225
|
focusable = forward ? getFirstFocusableDescendant(cell) : getLastFocusableDescendant(cell);
|
|
226
226
|
}
|
|
@@ -381,7 +381,8 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
|
|
|
381
381
|
}
|
|
382
382
|
|
|
383
383
|
_getThisCell() {
|
|
384
|
-
return this.shadowRoot
|
|
384
|
+
return this.shadowRoot &&
|
|
385
|
+
this.shadowRoot.querySelector(`.d2l-cell[data-cell-num="${this._cellNum}"]`);
|
|
385
386
|
}
|
|
386
387
|
|
|
387
388
|
_onKeydown(event) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import '../colors/colors.js';
|
|
2
2
|
import { css, html } from 'lit-element/lit-element.js';
|
|
3
|
+
import { getUniqueId } from '../../helpers/uniqueId.js';
|
|
3
4
|
import { ListItemMixin } from './list-item-mixin.js';
|
|
4
5
|
|
|
5
6
|
export const ListItemLinkMixin = superclass => class extends ListItemMixin(superclass) {
|
|
@@ -42,6 +43,7 @@ export const ListItemLinkMixin = superclass => class extends ListItemMixin(super
|
|
|
42
43
|
constructor() {
|
|
43
44
|
super();
|
|
44
45
|
this.actionHref = null;
|
|
46
|
+
this._primaryActionId = getUniqueId();
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
_handleLinkClick() {
|
|
@@ -51,7 +53,7 @@ export const ListItemLinkMixin = superclass => class extends ListItemMixin(super
|
|
|
51
53
|
|
|
52
54
|
_renderPrimaryAction(labelledBy) {
|
|
53
55
|
if (!this.actionHref) return;
|
|
54
|
-
return html`<a aria-labelledby="${labelledBy}" href="${this.actionHref}" @click="${this._handleLinkClick}"></a>`;
|
|
56
|
+
return html`<a id="${this._primaryActionId}" aria-labelledby="${labelledBy}" href="${this.actionHref}" @click="${this._handleLinkClick}"></a>`;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import '../colors/colors.js';
|
|
2
2
|
import './list-item-generic-layout.js';
|
|
3
3
|
import './list-item-placement-marker.js';
|
|
4
|
+
import '../tooltip/tooltip.js';
|
|
4
5
|
import { css, html } from 'lit-element/lit-element.js';
|
|
5
6
|
import { findComposedAncestor, getComposedParent } from '../../helpers/dom.js';
|
|
6
7
|
import { classMap } from 'lit-html/directives/class-map.js';
|
|
@@ -10,10 +11,28 @@ import { ifDefined } from 'lit-html/directives/if-defined.js';
|
|
|
10
11
|
import { ListItemCheckboxMixin } from './list-item-checkbox-mixin.js';
|
|
11
12
|
import { ListItemDragDropMixin } from './list-item-drag-drop-mixin.js';
|
|
12
13
|
import { ListItemRoleMixin } from './list-item-role-mixin.js';
|
|
14
|
+
import { LocalizeCoreElement } from '../../lang/localize-core-element.js';
|
|
13
15
|
import { nothing } from 'lit-html';
|
|
14
16
|
import ResizeObserver from 'resize-observer-polyfill';
|
|
15
17
|
import { RtlMixin } from '../../mixins/rtl-mixin.js';
|
|
16
18
|
|
|
19
|
+
let tabPressed = false;
|
|
20
|
+
let tabListenerAdded = false;
|
|
21
|
+
function addTabListener() {
|
|
22
|
+
if (tabListenerAdded) return;
|
|
23
|
+
tabListenerAdded = true;
|
|
24
|
+
document.addEventListener('keydown', e => {
|
|
25
|
+
if (e.keyCode !== 9) return;
|
|
26
|
+
tabPressed = true;
|
|
27
|
+
});
|
|
28
|
+
document.addEventListener('keyup', e => {
|
|
29
|
+
if (e.keyCode !== 9) return;
|
|
30
|
+
tabPressed = false;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let hasDisplayedKeyboardTooltip = false;
|
|
35
|
+
|
|
17
36
|
const ro = new ResizeObserver(entries => {
|
|
18
37
|
entries.forEach(entry => {
|
|
19
38
|
if (!entry || !entry.target || !entry.target.resizedCallback) {
|
|
@@ -25,7 +44,7 @@ const ro = new ResizeObserver(entries => {
|
|
|
25
44
|
|
|
26
45
|
const defaultBreakpoints = [842, 636, 580, 0];
|
|
27
46
|
|
|
28
|
-
export const ListItemMixin = superclass => class extends ListItemDragDropMixin(ListItemCheckboxMixin(ListItemRoleMixin(RtlMixin(superclass)))) {
|
|
47
|
+
export const ListItemMixin = superclass => class extends LocalizeCoreElement(ListItemDragDropMixin(ListItemCheckboxMixin(ListItemRoleMixin(RtlMixin(superclass))))) {
|
|
29
48
|
|
|
30
49
|
static get properties() {
|
|
31
50
|
return {
|
|
@@ -40,6 +59,7 @@ export const ListItemMixin = superclass => class extends ListItemDragDropMixin(L
|
|
|
40
59
|
*/
|
|
41
60
|
slim: { type: Boolean },
|
|
42
61
|
_breakpoint: { type: Number },
|
|
62
|
+
_displayKeyboardTooltip: { type: Boolean },
|
|
43
63
|
_dropdownOpen: { type: Boolean, attribute: '_dropdown-open', reflect: true },
|
|
44
64
|
_hoveringPrimaryAction: { type: Boolean },
|
|
45
65
|
_focusing: { type: Boolean },
|
|
@@ -237,6 +257,15 @@ export const ListItemMixin = superclass => class extends ListItemDragDropMixin(L
|
|
|
237
257
|
:host([draggable][selected]:not([disabled])) d2l-list-item-generic-layout.d2l-focusing + .d2l-list-item-active-border {
|
|
238
258
|
transform: rotate(1deg);
|
|
239
259
|
}
|
|
260
|
+
d2l-tooltip > div {
|
|
261
|
+
font-weight: 700;
|
|
262
|
+
}
|
|
263
|
+
d2l-tooltip > ul {
|
|
264
|
+
padding-inline-start: 1rem;
|
|
265
|
+
}
|
|
266
|
+
.d2l-list-item-tooltip-key {
|
|
267
|
+
font-weight: 700;
|
|
268
|
+
}
|
|
240
269
|
`];
|
|
241
270
|
|
|
242
271
|
super.styles && styles.unshift(super.styles);
|
|
@@ -249,6 +278,7 @@ export const ListItemMixin = superclass => class extends ListItemDragDropMixin(L
|
|
|
249
278
|
this.slim = false;
|
|
250
279
|
this._breakpoint = 0;
|
|
251
280
|
this._contentId = getUniqueId();
|
|
281
|
+
this._displayKeyboardTooltip = false;
|
|
252
282
|
}
|
|
253
283
|
|
|
254
284
|
get breakpoints() {
|
|
@@ -265,6 +295,9 @@ export const ListItemMixin = superclass => class extends ListItemDragDropMixin(L
|
|
|
265
295
|
connectedCallback() {
|
|
266
296
|
super.connectedCallback();
|
|
267
297
|
ro.observe(this);
|
|
298
|
+
if (this.role === 'rowgroup') {
|
|
299
|
+
addTabListener();
|
|
300
|
+
}
|
|
268
301
|
}
|
|
269
302
|
|
|
270
303
|
disconnectedCallback() {
|
|
@@ -303,6 +336,7 @@ export const ListItemMixin = superclass => class extends ListItemDragDropMixin(L
|
|
|
303
336
|
}
|
|
304
337
|
|
|
305
338
|
_getNestedList() {
|
|
339
|
+
if (!this.shadowRoot) return;
|
|
306
340
|
const nestedSlot = this.shadowRoot.querySelector('slot[name="nested"]');
|
|
307
341
|
let nestedNodes = nestedSlot.assignedNodes();
|
|
308
342
|
if (nestedNodes.length === 0) {
|
|
@@ -350,6 +384,9 @@ export const ListItemMixin = superclass => class extends ListItemDragDropMixin(L
|
|
|
350
384
|
|
|
351
385
|
_onFocusIn() {
|
|
352
386
|
this._focusing = true;
|
|
387
|
+
if (this.role !== 'rowgroup' || !tabPressed || hasDisplayedKeyboardTooltip) return;
|
|
388
|
+
this._displayKeyboardTooltip = true;
|
|
389
|
+
hasDisplayedKeyboardTooltip = true;
|
|
353
390
|
}
|
|
354
391
|
|
|
355
392
|
_onFocusInPrimaryAction() {
|
|
@@ -358,6 +395,7 @@ export const ListItemMixin = superclass => class extends ListItemDragDropMixin(L
|
|
|
358
395
|
|
|
359
396
|
_onFocusOut() {
|
|
360
397
|
this._focusing = false;
|
|
398
|
+
this._displayKeyboardTooltip = false;
|
|
361
399
|
}
|
|
362
400
|
|
|
363
401
|
_onFocusOutPrimaryAction() {
|
|
@@ -397,6 +435,7 @@ export const ListItemMixin = superclass => class extends ListItemDragDropMixin(L
|
|
|
397
435
|
};
|
|
398
436
|
|
|
399
437
|
const primaryAction = this._renderPrimaryAction ? this._renderPrimaryAction(this._contentId) : null;
|
|
438
|
+
const tooltipForId = (primaryAction ? this._primaryActionId : (this.selectable ? this._checkboxId : null));
|
|
400
439
|
|
|
401
440
|
return html`
|
|
402
441
|
${this._renderTopPlacementMarker(html`<d2l-list-item-placement-marker></d2l-list-item-placement-marker>`)}
|
|
@@ -412,11 +451,11 @@ export const ListItemMixin = superclass => class extends ListItemDragDropMixin(L
|
|
|
412
451
|
${this._renderDragHandle(this._renderOutsideControl)}
|
|
413
452
|
${this._renderDragTarget(this._renderOutsideControlAction)}
|
|
414
453
|
${this.selectable ? html`
|
|
415
|
-
<div slot="control">${
|
|
454
|
+
<div slot="control">${this._renderCheckbox()}</div>
|
|
416
455
|
<div slot="control-action"
|
|
417
456
|
@mouseenter="${this._onMouseEnter}"
|
|
418
457
|
@mouseleave="${this._onMouseLeave}">
|
|
419
|
-
${
|
|
458
|
+
${this._renderCheckboxAction('')}
|
|
420
459
|
</div>` : nothing }
|
|
421
460
|
${primaryAction ? html`
|
|
422
461
|
<div slot="content-action"
|
|
@@ -445,6 +484,7 @@ export const ListItemMixin = superclass => class extends ListItemDragDropMixin(L
|
|
|
445
484
|
<div class="d2l-list-item-active-border"></div>
|
|
446
485
|
</div>
|
|
447
486
|
${this._renderBottomPlacementMarker(html`<d2l-list-item-placement-marker></d2l-list-item-placement-marker>`)}
|
|
487
|
+
${this._displayKeyboardTooltip && tooltipForId ? html`<d2l-tooltip align="start" announced for="${tooltipForId}" for-type="descriptor">${this._renderTooltipContent()}</d2l-tooltip>` : ''}
|
|
448
488
|
`;
|
|
449
489
|
|
|
450
490
|
}
|
|
@@ -457,4 +497,16 @@ export const ListItemMixin = superclass => class extends ListItemDragDropMixin(L
|
|
|
457
497
|
return html`<div slot="outside-control-action" @mouseenter="${this._onMouseEnter}" @mouseleave="${this._onMouseLeave}">${dragTarget}</div>`;
|
|
458
498
|
}
|
|
459
499
|
|
|
500
|
+
_renderTooltipContent() {
|
|
501
|
+
return html`
|
|
502
|
+
<div>${this.localize('components.list-item-tooltip.title')}</div>
|
|
503
|
+
<ul>
|
|
504
|
+
<li><span class="d2l-list-item-tooltip-key">${this.localize('components.list-item-tooltip.enter-key')}</span> - ${this.localize('components.list-item-tooltip.enter-desc')}</li>
|
|
505
|
+
<li><span class="d2l-list-item-tooltip-key">${this.localize('components.list-item-tooltip.up-down-key')}</span> - ${this.localize('components.list-item-tooltip.up-down-desc')}</li>
|
|
506
|
+
<li><span class="d2l-list-item-tooltip-key">${this.localize('components.list-item-tooltip.left-right-key')}</span> - ${this.localize('components.list-item-tooltip.left-right-desc')}</li>
|
|
507
|
+
<li><span class="d2l-list-item-tooltip-key">${this.localize('components.list-item-tooltip.page-up-down-key')}</span> - ${this.localize('components.list-item-tooltip.page-up-down-desc')}</li>
|
|
508
|
+
</ul>
|
|
509
|
+
`;
|
|
510
|
+
}
|
|
511
|
+
|
|
460
512
|
};
|
|
@@ -19,8 +19,9 @@ export const ListItemRoleMixin = superclass => class extends superclass {
|
|
|
19
19
|
|
|
20
20
|
const separators = parent.getAttribute('separators');
|
|
21
21
|
|
|
22
|
-
this.role = parent.grid ? 'rowgroup' : 'listitem';
|
|
22
|
+
this.role = parent.hasAttribute('grid') ? 'rowgroup' : 'listitem';
|
|
23
23
|
this._separators = separators || undefined;
|
|
24
24
|
this._extendSeparators = parent.hasAttribute('extend-separators');
|
|
25
25
|
}
|
|
26
|
+
|
|
26
27
|
};
|
package/components/list/list.js
CHANGED
|
@@ -101,6 +101,7 @@ class List extends SelectionMixin(LitElement) {
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
getItems() {
|
|
104
|
+
if (!this.shadowRoot) return;
|
|
104
105
|
const slot = this.shadowRoot.querySelector('slot:not([name])');
|
|
105
106
|
if (!slot) return [];
|
|
106
107
|
return slot.assignedNodes({ flatten: true }).filter((node) => {
|
|
@@ -157,6 +158,7 @@ class List extends SelectionMixin(LitElement) {
|
|
|
157
158
|
_handleKeyDown(e) {
|
|
158
159
|
if (!this.grid || this.slot === 'nested' || e.keyCode !== keyCodes.TAB) return;
|
|
159
160
|
e.preventDefault();
|
|
161
|
+
if (!this.shadowRoot) return;
|
|
160
162
|
const focusable = (e.shiftKey ? getPreviousFocusable(this.shadowRoot.querySelector('slot:not([name])'))
|
|
161
163
|
: getNextFocusable(this, false, true, true));
|
|
162
164
|
if (focusable) focusable.focus();
|
|
@@ -48,7 +48,7 @@ class CustomView extends HierarchicalViewMixin(LitElement) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
focus() {
|
|
51
|
-
this.shadowRoot.querySelector('.d2l-custom-view-back-container > a').focus();
|
|
51
|
+
if (this.shadowRoot) this.shadowRoot.querySelector('.d2l-custom-view-back-container > a').focus();
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
_handleHide(e) {
|
|
@@ -84,7 +84,7 @@ class MenuItemLink extends MenuItemMixin(LitElement) {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
_onClick() {
|
|
87
|
-
this.shadowRoot.querySelector('a').dispatchEvent(new CustomEvent('click'));
|
|
87
|
+
if (this.shadowRoot) this.shadowRoot.querySelector('a').dispatchEvent(new CustomEvent('click'));
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
_onKeyDown(e) {
|
|
@@ -109,7 +109,7 @@ export const MenuItemMixin = superclass => class extends FocusVisiblePolyfillMix
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
__initializeItem() {
|
|
112
|
-
const slot = this.shadowRoot.querySelector('slot:not([name])');
|
|
112
|
+
const slot = this.shadowRoot && this.shadowRoot.querySelector('slot:not([name])');
|
|
113
113
|
if (!slot) {
|
|
114
114
|
return;
|
|
115
115
|
}
|
package/components/menu/menu.js
CHANGED
|
@@ -221,11 +221,11 @@ class Menu extends ThemeMixin(HierarchicalViewMixin(FocusVisiblePolyfillMixin(Li
|
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
_getMenuItemReturn() {
|
|
224
|
-
return this.shadowRoot.querySelector('d2l-menu-item-return');
|
|
224
|
+
return this.shadowRoot && this.shadowRoot.querySelector('d2l-menu-item-return');
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
_getMenuItems() {
|
|
228
|
-
const slot = this.shadowRoot.querySelector('slot');
|
|
228
|
+
const slot = this.shadowRoot && this.shadowRoot.querySelector('slot');
|
|
229
229
|
if (!slot) return;
|
|
230
230
|
const items = slot.assignedNodes({ flatten: true }).filter((node) => node.nodeType === Node.ELEMENT_NODE);
|
|
231
231
|
|
|
@@ -318,7 +318,7 @@ class OverflowGroup extends RtlMixin(LocalizeCoreElement(LitElement)) {
|
|
|
318
318
|
}
|
|
319
319
|
|
|
320
320
|
_chomp() {
|
|
321
|
-
if (!this._itemLayouts) return;
|
|
321
|
+
if (!this.shadowRoot || !this._itemLayouts) return;
|
|
322
322
|
|
|
323
323
|
this._overflowMenu = this.shadowRoot.querySelector('.d2l-overflow-dropdown');
|
|
324
324
|
this._overflowMenuMini = this.shadowRoot.querySelector('.d2l-overflow-dropdown-mini');
|
|
@@ -53,7 +53,7 @@ class TestScrollWrapper extends RtlMixin(LitElement) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
focus() {
|
|
56
|
-
forceFocusVisible(this.shadowRoot.querySelector('d2l-scroll-wrapper')._container);
|
|
56
|
+
if (this.shadowRoot) forceFocusVisible(this.shadowRoot.querySelector('d2l-scroll-wrapper')._container);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
}
|
|
@@ -79,7 +79,7 @@ class Action extends LocalizeCoreElement(SelectionObserverMixin(ButtonMixin(RtlM
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
focus() {
|
|
82
|
-
const elem = this.shadowRoot.querySelector('d2l-button-subtle');
|
|
82
|
+
const elem = this.shadowRoot && this.shadowRoot.querySelector('d2l-button-subtle');
|
|
83
83
|
if (elem) elem.focus();
|
|
84
84
|
}
|
|
85
85
|
|
|
@@ -57,7 +57,7 @@ class SelectAll extends LocalizeCoreElement(SelectionObserverMixin(LitElement))
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
focus() {
|
|
60
|
-
const elem = this.shadowRoot.querySelector('d2l-input-checkbox');
|
|
60
|
+
const elem = this.shadowRoot && this.shadowRoot.querySelector('d2l-input-checkbox');
|
|
61
61
|
if (elem) elem.focus();
|
|
62
62
|
}
|
|
63
63
|
|
|
@@ -213,7 +213,7 @@ export const SwitchMixin = superclass => class extends RtlMixin(FocusVisiblePoly
|
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
focus() {
|
|
216
|
-
const elem = this.shadowRoot.querySelector('.d2l-switch-container');
|
|
216
|
+
const elem = this.shadowRoot && this.shadowRoot.querySelector('.d2l-switch-container');
|
|
217
217
|
if (elem) elem.focus();
|
|
218
218
|
}
|
|
219
219
|
|
package/components/tabs/tabs.js
CHANGED
|
@@ -374,34 +374,37 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(RtlMixin(FocusVisiblePolyf
|
|
|
374
374
|
}
|
|
375
375
|
|
|
376
376
|
getTabListRect() {
|
|
377
|
+
if (!this.shadowRoot) return undefined;
|
|
377
378
|
return this.shadowRoot.querySelector('.d2l-tabs-container-list').getBoundingClientRect();
|
|
378
379
|
}
|
|
379
380
|
|
|
380
381
|
_animateTabAddition(tabInfo) {
|
|
381
|
-
const tab = this.shadowRoot
|
|
382
|
+
const tab = this.shadowRoot
|
|
383
|
+
&& this.shadowRoot.querySelector(`d2l-tab-internal[controls-panel="${cssEscape(tabInfo.id)}"]`);
|
|
382
384
|
return new Promise((resolve) => {
|
|
383
385
|
const handleTransitionEnd = (e) => {
|
|
384
386
|
if (e.propertyName !== 'max-width') return;
|
|
385
|
-
tab.removeEventListener('transitionend', handleTransitionEnd);
|
|
387
|
+
if (tab) tab.removeEventListener('transitionend', handleTransitionEnd);
|
|
386
388
|
resolve();
|
|
387
389
|
};
|
|
388
|
-
tab.addEventListener('transitionend', handleTransitionEnd);
|
|
390
|
+
if (tab) tab.addEventListener('transitionend', handleTransitionEnd);
|
|
389
391
|
tabInfo.state = '';
|
|
390
392
|
this.requestUpdate();
|
|
391
393
|
});
|
|
392
394
|
}
|
|
393
395
|
|
|
394
396
|
_animateTabRemoval(tabInfo) {
|
|
395
|
-
const tab = this.shadowRoot
|
|
397
|
+
const tab = this.shadowRoot &&
|
|
398
|
+
this.shadowRoot.querySelector(`d2l-tab-internal[controls-panel="${cssEscape(tabInfo.id)}"]`);
|
|
396
399
|
return new Promise((resolve) => {
|
|
397
400
|
const handleTransitionEnd = (e) => {
|
|
398
401
|
if (e.propertyName !== 'max-width') return;
|
|
399
|
-
tab.removeEventListener('transitionend', handleTransitionEnd);
|
|
402
|
+
if (tab) tab.removeEventListener('transitionend', handleTransitionEnd);
|
|
400
403
|
this._tabInfos.splice(this._tabInfos.findIndex(info => info.id === tabInfo.id), 1);
|
|
401
404
|
this.requestUpdate();
|
|
402
405
|
resolve();
|
|
403
406
|
};
|
|
404
|
-
tab.addEventListener('transitionend', handleTransitionEnd);
|
|
407
|
+
if (tab) tab.addEventListener('transitionend', handleTransitionEnd);
|
|
405
408
|
});
|
|
406
409
|
}
|
|
407
410
|
|
|
@@ -488,7 +491,7 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(RtlMixin(FocusVisiblePolyf
|
|
|
488
491
|
}
|
|
489
492
|
|
|
490
493
|
async _focusSelected() {
|
|
491
|
-
const selectedTab = this.shadowRoot.querySelector('d2l-tab-internal[aria-selected="true"]');
|
|
494
|
+
const selectedTab = this.shadowRoot && this.shadowRoot.querySelector('d2l-tab-internal[aria-selected="true"]');
|
|
492
495
|
if (!selectedTab) return;
|
|
493
496
|
|
|
494
497
|
const selectedTabInfo = this._getTabInfo(selectedTab.controlsPanel);
|
|
@@ -517,6 +520,7 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(RtlMixin(FocusVisiblePolyf
|
|
|
517
520
|
}
|
|
518
521
|
|
|
519
522
|
_getPanel(id) {
|
|
523
|
+
if (!this.shadowRoot) return;
|
|
520
524
|
// use simple selector for slot (Edge)
|
|
521
525
|
const slot = this.shadowRoot.querySelector('.d2l-panels-container').querySelector('slot');
|
|
522
526
|
const panels = this._getPanels(slot);
|
|
@@ -702,7 +706,7 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(RtlMixin(FocusVisiblePolyf
|
|
|
702
706
|
await this._scrollToPosition(newTranslationValue);
|
|
703
707
|
await this._updateScrollVisibility(newMeasures);
|
|
704
708
|
|
|
705
|
-
if (!isOverflowingNext) {
|
|
709
|
+
if (!isOverflowingNext && this.shadowRoot) {
|
|
706
710
|
this.shadowRoot.querySelector('.d2l-tabs-scroll-previous-container button').focus();
|
|
707
711
|
}
|
|
708
712
|
|
|
@@ -735,7 +739,7 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(RtlMixin(FocusVisiblePolyf
|
|
|
735
739
|
await this._scrollToPosition(newTranslationValue);
|
|
736
740
|
await this._updateScrollVisibility(newMeasures);
|
|
737
741
|
|
|
738
|
-
if (!isOverflowingPrevious) {
|
|
742
|
+
if (!isOverflowingPrevious && this.shadowRoot) {
|
|
739
743
|
this.shadowRoot.querySelector('.d2l-tabs-scroll-next-container button').focus();
|
|
740
744
|
}
|
|
741
745
|
|
|
@@ -777,7 +781,7 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(RtlMixin(FocusVisiblePolyf
|
|
|
777
781
|
}
|
|
778
782
|
|
|
779
783
|
this._translationValue = translationValue;
|
|
780
|
-
if (reduceMotion) return this.updateComplete;
|
|
784
|
+
if (!this.shadowRoot || reduceMotion) return this.updateComplete;
|
|
781
785
|
|
|
782
786
|
return new Promise((resolve) => {
|
|
783
787
|
const tabList = this.shadowRoot.querySelector('.d2l-tabs-container-list');
|
|
@@ -805,13 +809,13 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(RtlMixin(FocusVisiblePolyf
|
|
|
805
809
|
expandedPromise = this.updateComplete;
|
|
806
810
|
} else {
|
|
807
811
|
expandedPromise = new Promise((resolve) => {
|
|
808
|
-
const tabsContainer = this.shadowRoot.querySelector('.d2l-tabs-container');
|
|
812
|
+
const tabsContainer = this.shadowRoot && this.shadowRoot.querySelector('.d2l-tabs-container');
|
|
809
813
|
const handleTransitionEnd = (e) => {
|
|
810
814
|
if (e.propertyName !== 'max-width') return;
|
|
811
|
-
tabsContainer.removeEventListener('transitionend', handleTransitionEnd);
|
|
815
|
+
if (tabsContainer) tabsContainer.removeEventListener('transitionend', handleTransitionEnd);
|
|
812
816
|
resolve();
|
|
813
817
|
};
|
|
814
|
-
tabsContainer.addEventListener('transitionend', handleTransitionEnd);
|
|
818
|
+
if (tabsContainer) tabsContainer.addEventListener('transitionend', handleTransitionEnd);
|
|
815
819
|
this._scrollCollapsed = false;
|
|
816
820
|
this._maxWidth = measures.totalTabsWidth + 50;
|
|
817
821
|
});
|
|
@@ -828,7 +832,7 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(RtlMixin(FocusVisiblePolyf
|
|
|
828
832
|
if (!this._allowScrollPrevious) {
|
|
829
833
|
this._focusSelected();
|
|
830
834
|
} else {
|
|
831
|
-
this.shadowRoot.querySelector('.d2l-tabs-scroll-previous-container button').focus();
|
|
835
|
+
if (this.shadowRoot) this.shadowRoot.querySelector('.d2l-tabs-scroll-previous-container button').focus();
|
|
832
836
|
}
|
|
833
837
|
}
|
|
834
838
|
|
|
@@ -838,6 +842,7 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(RtlMixin(FocusVisiblePolyf
|
|
|
838
842
|
|
|
839
843
|
_updateMeasures() {
|
|
840
844
|
let totalTabsWidth = 0;
|
|
845
|
+
if (!this.shadowRoot) return;
|
|
841
846
|
const tabs = [...this.shadowRoot.querySelectorAll('d2l-tab-internal')];
|
|
842
847
|
|
|
843
848
|
const tabRects = tabs.map((tab) => {
|
|
@@ -894,7 +899,7 @@ class Tabs extends LocalizeCoreElement(ArrowKeysMixin(RtlMixin(FocusVisiblePolyf
|
|
|
894
899
|
// don't animate the tabs list visibility if it's the inital render
|
|
895
900
|
if (reduceMotion || !this._initialized) {
|
|
896
901
|
this._state = 'hidden';
|
|
897
|
-
} else {
|
|
902
|
+
} else if (this.shadowRoot) {
|
|
898
903
|
const layout = this.shadowRoot.querySelector('.d2l-tabs-layout');
|
|
899
904
|
const handleTransitionEnd = (e) => {
|
|
900
905
|
if (e.propertyName !== 'max-height') return;
|
|
@@ -715,7 +715,7 @@ class Tooltip extends RtlMixin(LitElement) {
|
|
|
715
715
|
}
|
|
716
716
|
|
|
717
717
|
_getContent() {
|
|
718
|
-
return this.shadowRoot.querySelector('.d2l-tooltip-content');
|
|
718
|
+
return this.shadowRoot && this.shadowRoot.querySelector('.d2l-tooltip-content');
|
|
719
719
|
}
|
|
720
720
|
|
|
721
721
|
_isAboveOrBelow() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Subscriber Controllers
|
|
2
2
|
|
|
3
|
-
The `SubscriberRegistryController` and the corresponding `*SubscriberController`s can be used to create a subscription system within your app. Components can
|
|
3
|
+
The `SubscriberRegistryController` and the corresponding `*SubscriberController`s can be used to create a subscription system within your app. Components can set up a subscriber registry instance to keep track of all components subscribed to them with the `SubscriberRegistryController`. Whenever it makes sense to do so, they can iterate over their subscribers to perform some action, update them with new data, etc. Components can subscribe themselves to different registries using the `IdSubscriberController` or the `EventSubscriberController`. This system supports a many-to-many relationship - registry components can contain multiple registry instances with multiple subscribers in each, and subscriber components can subscribe to multiple different registries.
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
@@ -27,7 +27,7 @@ class CableSubscription extends LitElement {
|
|
|
27
27
|
{ onSubscribe: this._unlockKidsChannels.bind(this) }, {});
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
getSubscriberController(controllerId) {
|
|
31
31
|
if (controllerId === 'sports') {
|
|
32
32
|
return this._sportsSubscribers;
|
|
33
33
|
} else if (controllerId === 'movies') {
|
|
@@ -51,7 +51,7 @@ class CableSubscription extends LitElement {
|
|
|
51
51
|
|
|
52
52
|
When creating the controller, you can pass in callbacks to run whenever a subscriber is added, removed, or `updateSubscribers` is called (which handles request debouncing for you).
|
|
53
53
|
|
|
54
|
-
The `*subscriberController`s will use a `
|
|
54
|
+
The `*subscriberController`s will use a `getSubscriberController` method that needs to be exposed on the registry component. If you only have one `SubscriberRegistryController` you can simple return that. If you have multiple, you will return the proper controller depending on the id the subscriber component passed to you.
|
|
55
55
|
|
|
56
56
|
Once this has been set up, components can subscribe to particular registries two different ways:
|
|
57
57
|
1. Using a matching event name with `EventSubscriberController`. The component will need to be a child of the registry component for this to work.
|