@brightspace-ui/core 1.196.2 → 1.197.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.
- package/components/backdrop/README.md +5 -6
- package/components/backdrop/backdrop.js +3 -0
- package/components/breadcrumbs/breadcrumbs.js +2 -1
- package/components/button/button-icon.js +1 -0
- package/components/button/button-mixin.js +2 -0
- package/components/button/button-subtle.js +1 -0
- package/components/button/button.js +1 -0
- package/components/button/floating-buttons.js +1 -0
- package/components/calendar/calendar.js +1 -1
- package/components/card/card-footer-link.js +12 -2
- package/components/card/card-loading-shimmer.js +1 -0
- package/components/card/card.js +9 -0
- package/components/dialog/dialog-confirm.js +1 -2
- package/components/dialog/dialog-fullscreen.js +4 -5
- package/components/dialog/dialog-mixin.js +2 -0
- package/components/dialog/dialog.js +0 -2
- package/components/dropdown/dropdown-button-subtle.js +3 -3
- package/components/dropdown/dropdown-button.js +2 -0
- package/components/dropdown/dropdown-content-mixin.js +19 -0
- package/components/dropdown/dropdown-content.js +0 -3
- package/components/dropdown/dropdown-context-menu.js +2 -0
- package/components/dropdown/dropdown-menu.js +0 -3
- package/components/dropdown/dropdown-more.js +2 -0
- package/components/dropdown/dropdown-opener-mixin.js +2 -0
- package/components/dropdown/dropdown-tabs.js +0 -3
- package/components/filter/filter-dimension-set-value.js +3 -0
- package/components/filter/filter-dimension-set.js +5 -1
- package/components/form/form-mixin.js +1 -0
- package/components/form/form-native.js +0 -1
- package/components/form/form.js +0 -1
- package/components/inputs/input-date-range.js +9 -1
- package/components/inputs/input-date-time-range-to.js +3 -0
- package/components/inputs/input-date-time-range.js +10 -1
- package/components/inputs/input-date-time.js +7 -1
- package/components/inputs/input-date.js +7 -1
- package/components/inputs/input-fieldset.js +3 -0
- package/components/inputs/input-radio-styles.js +2 -1
- package/components/inputs/input-time-range.js +10 -1
- package/components/inputs/input-time.js +6 -1
- package/components/link/README.md +1 -1
- package/components/list/README.md +11 -10
- package/components/list/demo/list-item-custom.js +7 -3
- package/components/list/demo/list-nested.html +6 -62
- package/components/list/list-item-button-mixin.js +1 -0
- package/components/list/list-item-button.js +0 -3
- package/components/list/list-item-checkbox-mixin.js +1 -0
- package/components/list/list-item-drag-drop-mixin.js +2 -0
- package/components/list/list-item-generic-layout.js +85 -14
- package/components/list/list-item-link-mixin.js +1 -0
- package/components/list/list-item.js +0 -3
- package/components/list/list.js +29 -2
- package/components/menu/menu-item-checkbox.js +0 -4
- package/components/menu/menu-item-link.js +0 -2
- package/components/menu/menu-item-mixin.js +3 -0
- package/components/menu/menu-item-radio.js +0 -3
- package/components/menu/menu-item-selectable-mixin.js +2 -0
- package/components/menu/menu-item.js +0 -2
- package/components/overflow-group/overflow-group.js +4 -3
- package/components/scroll-wrapper/scroll-wrapper.js +1 -2
- package/components/selection/selection-action.js +4 -0
- package/components/selection/selection-input.js +9 -2
- package/components/selection/selection-mixin.js +3 -1
- package/components/selection/selection-observer-mixin.js +3 -1
- package/components/selection/selection-select-all.js +2 -0
- package/components/selection/selection-summary.js +3 -1
- package/components/skeleton/skeleton-mixin.js +1 -0
- package/components/status-indicator/status-indicator.js +2 -0
- package/components/switch/switch-mixin.js +1 -0
- package/components/switch/switch-visibility.js +3 -0
- package/components/switch/switch.js +3 -0
- package/components/table/table-col-sort-button.js +0 -2
- package/components/table/table-wrapper.js +0 -2
- package/components/tabs/tab-panel-mixin.js +2 -0
- package/components/tabs/tab-panel.js +0 -2
- package/custom-elements.json +86 -119
- package/helpers/focus.js +4 -2
- package/lang/ar.js +7 -7
- package/lang/cy.js +7 -7
- package/lang/da.js +7 -7
- package/lang/de.js +7 -7
- package/lang/es-es.js +7 -7
- package/lang/es.js +8 -8
- package/lang/fr-fr.js +8 -8
- package/lang/fr.js +7 -7
- package/lang/ja.js +8 -8
- package/lang/ko.js +7 -7
- package/lang/nl.js +8 -8
- package/lang/pt.js +7 -7
- package/lang/sv.js +7 -7
- package/lang/tr.js +7 -7
- package/lang/zh-tw.js +7 -7
- package/lang/zh.js +8 -8
- package/mixins/labelled-mixin.js +1 -0
- package/package.json +1 -1
- package/templates/primary-secondary/primary-secondary.js +2 -0
|
@@ -23,13 +23,13 @@
|
|
|
23
23
|
</head>
|
|
24
24
|
<body unresolved>
|
|
25
25
|
|
|
26
|
-
<d2l-demo-page page-title="d2l-list
|
|
26
|
+
<d2l-demo-page page-title="d2l-list (nested)">
|
|
27
27
|
|
|
28
28
|
<h2>Nested</h2>
|
|
29
29
|
|
|
30
30
|
<d2l-demo-snippet>
|
|
31
31
|
<template>
|
|
32
|
-
<d2l-list>
|
|
32
|
+
<d2l-list grid>
|
|
33
33
|
<d2l-list-header slot="header">
|
|
34
34
|
<d2l-selection-action icon="tier1:bookmark-hollow" text="Bookmark" requires-selection></d2l-selection-action>
|
|
35
35
|
<d2l-selection-action icon="tier1:gear" text="Settings"></d2l-selection-action>
|
|
@@ -39,80 +39,24 @@
|
|
|
39
39
|
<div>Earth Sciences (L1)</div>
|
|
40
40
|
<div slot="supporting-info">Earth science or geoscience includes all fields of natural science related to planet Earth. This is a branch of science dealing with the physical and chemical constitution of Earth and its atmosphere. Earth science can be considered to be a branch of planetary science, but with a much older history.</div>
|
|
41
41
|
</d2l-list-item-content>
|
|
42
|
-
<d2l-list slot="nested" separators="all">
|
|
42
|
+
<d2l-list slot="nested" grid separators="all">
|
|
43
43
|
<d2l-list-item selectable key="L2-1" label="Label for L2-1">
|
|
44
44
|
<d2l-list-item-content>
|
|
45
45
|
<div>Introductory Earth Sciences (L2)</div>
|
|
46
46
|
<div slot="supporting-info">This course explores the geological processes of the Earth's interior and surface. These include volcanism, earthquakes, mountain building, glaciation and weathering. Students will gain an appreciation of how these processes have controlled the evolution of our planet and the role of geology in meeting society's current and future demand for sustainable energy and mineral resources.</div>
|
|
47
47
|
</d2l-list-item-content>
|
|
48
|
-
<d2l-list slot="nested" separators="all">
|
|
48
|
+
<d2l-list slot="nested" grid separators="all">
|
|
49
49
|
<d2l-list-item selectable key="L3-1" label="Label for L3-1">
|
|
50
50
|
<d2l-list-item-content>
|
|
51
51
|
<div>Glaciation (L3)</div>
|
|
52
52
|
<div slot="supporting-info">Supporting Info</div>
|
|
53
53
|
</d2l-list-item-content>
|
|
54
|
-
<d2l-list slot="nested" separators="all">
|
|
54
|
+
<d2l-list slot="nested" grid separators="all">
|
|
55
55
|
<d2l-list-item selectable key="L4-1" label="Label for L4-1">
|
|
56
56
|
<d2l-list-item-content>
|
|
57
57
|
<div>Ice Sheets (L4)</div>
|
|
58
58
|
<div slot="supporting-info">Supporting Info</div>
|
|
59
59
|
</d2l-list-item-content>
|
|
60
|
-
<d2l-list slot="nested" separators="all">
|
|
61
|
-
<d2l-list-item selectable key="L5-1" label="Label for L5-1">
|
|
62
|
-
<d2l-list-item-content>
|
|
63
|
-
<div>Topic 1 (L5)</div>
|
|
64
|
-
<div slot="supporting-info">Supporting Info</div>
|
|
65
|
-
</d2l-list-item-content>
|
|
66
|
-
</d2l-list-item>
|
|
67
|
-
<d2l-list-item selectable key="L5-2" label="Label for L5-2">
|
|
68
|
-
<d2l-list-item-content>
|
|
69
|
-
<div>Topic 2 (L5)</div>
|
|
70
|
-
<div slot="supporting-info">Supporting Info</div>
|
|
71
|
-
</d2l-list-item-content>
|
|
72
|
-
<d2l-list slot="nested" separators="all">
|
|
73
|
-
<d2l-list-item selectable key="L6-1" label="Label for L6-1">
|
|
74
|
-
<d2l-list-item-content>
|
|
75
|
-
<div>Sub-Topic 1 (L6)</div>
|
|
76
|
-
<div slot="supporting-info">Supporting Info</div>
|
|
77
|
-
</d2l-list-item-content>
|
|
78
|
-
<d2l-list slot="nested" separators="all">
|
|
79
|
-
<d2l-list-item selectable key="L7-1" label="Label for L7-1">
|
|
80
|
-
<d2l-list-item-content>
|
|
81
|
-
<div>Sub-Topic 1 (L7)</div>
|
|
82
|
-
<div slot="supporting-info">Supporting Info</div>
|
|
83
|
-
</d2l-list-item-content>
|
|
84
|
-
<d2l-list slot="nested" separators="all">
|
|
85
|
-
<d2l-list-item selectable selected key="L8-1" label="Label for L8-1">
|
|
86
|
-
<d2l-list-item-content>
|
|
87
|
-
<div>Sub-Topic 1 (L8)</div>
|
|
88
|
-
<div slot="supporting-info">Supporting Info</div>
|
|
89
|
-
</d2l-list-item-content>
|
|
90
|
-
</d2l-list-item>
|
|
91
|
-
<d2l-list-item selectable key="L8-2" label="Label for L8-2">
|
|
92
|
-
<d2l-list-item-content>
|
|
93
|
-
<div>Sub-Topic 2 (L8)</div>
|
|
94
|
-
<div slot="supporting-info">Supporting Info</div>
|
|
95
|
-
</d2l-list-item-content>
|
|
96
|
-
</d2l-list-item>
|
|
97
|
-
</d2l-list>
|
|
98
|
-
</d2l-list-item>
|
|
99
|
-
<d2l-list-item selectable key="L7-2" label="Label for L7-2">
|
|
100
|
-
<d2l-list-item-content>
|
|
101
|
-
<div>Sub-Topic 2 (L7)</div>
|
|
102
|
-
<div slot="supporting-info">Supporting Info</div>
|
|
103
|
-
</d2l-list-item-content>
|
|
104
|
-
</d2l-list-item>
|
|
105
|
-
</d2l-list>
|
|
106
|
-
</d2l-list-item>
|
|
107
|
-
<d2l-list-item selectable key="L6-2" label="Label for L6-2">
|
|
108
|
-
<d2l-list-item-content>
|
|
109
|
-
<div>Sub-Topic 2 (L6)</div>
|
|
110
|
-
<div slot="supporting-info">Supporting Info</div>
|
|
111
|
-
</d2l-list-item-content>
|
|
112
|
-
</d2l-list-item>
|
|
113
|
-
</d2l-list>
|
|
114
|
-
</d2l-list-item>
|
|
115
|
-
</d2l-list>
|
|
116
60
|
</d2l-list-item>
|
|
117
61
|
<d2l-list-item selectable key="L4-2" label="Label for L4-2">
|
|
118
62
|
<d2l-list-item-content>
|
|
@@ -175,7 +119,7 @@
|
|
|
175
119
|
|
|
176
120
|
<d2l-demo-snippet>
|
|
177
121
|
<template>
|
|
178
|
-
<d2l-list>
|
|
122
|
+
<d2l-list grid>
|
|
179
123
|
<d2l-list-header slot="header">
|
|
180
124
|
<d2l-selection-action icon="tier1:bookmark-hollow" text="Bookmark" requires-selection></d2l-selection-action>
|
|
181
125
|
<d2l-selection-action icon="tier1:gear" text="Settings"></d2l-selection-action>
|
|
@@ -35,6 +35,7 @@ export const ListItemButtonMixin = superclass => class extends ListItemMixin(sup
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
_onButtonClick() {
|
|
38
|
+
/** Dispatched when the item's primary button action is clicked */
|
|
38
39
|
this.dispatchEvent(new CustomEvent('d2l-list-item-button-click', { bubbles: true }));
|
|
39
40
|
}
|
|
40
41
|
|
|
@@ -6,9 +6,6 @@ import { LitElement } from 'lit-element/lit-element.js';
|
|
|
6
6
|
* @slot - Default content placed inside of the component
|
|
7
7
|
* @slot illustration - Image associated with the list item located at the left of the item
|
|
8
8
|
* @slot actions - Actions (e.g., button icons) associated with the listen item located at the right of the item
|
|
9
|
-
* @fires d2l-list-item-button-click - Dispatched when the item's primary button action is clicked
|
|
10
|
-
* @fires d2l-list-item-position-change - Dispatched when a draggable list item's position changes in the list. See [Event Details: d2l-list-item-position-change](#event-details%3A-d2l-list-item-position-change).
|
|
11
|
-
* @fires d2l-list-item-selected - Dispatched when the component item is selected
|
|
12
9
|
*/
|
|
13
10
|
class ListItemButton extends ListItemButtonMixin(LitElement) {
|
|
14
11
|
|
|
@@ -105,6 +105,7 @@ export const ListItemCheckboxMixin = superclass => class extends SkeletonMixin(L
|
|
|
105
105
|
/* wait for internal state to be updated in case of action-click case so that a consumer
|
|
106
106
|
calling getSelectionInfo will get the correct state */
|
|
107
107
|
await this.updateComplete;
|
|
108
|
+
/** Dispatched when the component item is selected */
|
|
108
109
|
this.dispatchEvent(new CustomEvent('d2l-list-item-selected', {
|
|
109
110
|
detail: { key: this.key, selected: value },
|
|
110
111
|
composed: true,
|
|
@@ -265,6 +265,7 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
265
265
|
dragHandleText: { type: String, attribute: 'drag-handle-text' },
|
|
266
266
|
/**
|
|
267
267
|
* **Drag & drop:** Text to drag and drop
|
|
268
|
+
* @type {string}
|
|
268
269
|
*/
|
|
269
270
|
dropText: { type: String, attribute: 'drop-text' },
|
|
270
271
|
/**
|
|
@@ -351,6 +352,7 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
351
352
|
}
|
|
352
353
|
|
|
353
354
|
_annoucePositionChange(dragTargetKey, dropTargetKey, dropLocation) {
|
|
355
|
+
/** Dispatched when a draggable list item's position changes in the list. See [Event Details: d2l-list-item-position-change](#event-details%3A-d2l-list-item-position-change). */
|
|
354
356
|
this.dispatchEvent(new CustomEvent('d2l-list-item-position-change', {
|
|
355
357
|
detail: new NewPositionEventDetails({ dragTargetKey, dropTargetKey, dropLocation }),
|
|
356
358
|
bubbles: true
|
|
@@ -207,6 +207,7 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
|
|
|
207
207
|
_focusNextCell(num, forward = true) {
|
|
208
208
|
let cell = null;
|
|
209
209
|
let focusable = null;
|
|
210
|
+
|
|
210
211
|
do {
|
|
211
212
|
cell = this.shadowRoot.querySelector(`[data-cell-num="${num}"]`);
|
|
212
213
|
if (cell) {
|
|
@@ -215,26 +216,31 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
|
|
|
215
216
|
if (focusable) focusable.focus();
|
|
216
217
|
forward ? ++num : --num;
|
|
217
218
|
} while (cell && !focusable);
|
|
219
|
+
|
|
220
|
+
if (!cell) {
|
|
221
|
+
// wrap to first/last item
|
|
222
|
+
if (forward) this._focusNextCell(1);
|
|
223
|
+
else this._focusLastItem();
|
|
224
|
+
}
|
|
225
|
+
|
|
218
226
|
return focusable;
|
|
219
227
|
}
|
|
220
228
|
|
|
221
229
|
_focusNextRow(previous = false, num = 1) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
listItem = nextItem;
|
|
232
|
-
--num;
|
|
230
|
+
|
|
231
|
+
let listItem = findComposedAncestor(this, node => node.role === 'rowgroup');
|
|
232
|
+
|
|
233
|
+
while (num > 0) {
|
|
234
|
+
const tempListItem = (previous ? this._getPreviousFlattenedListItem(listItem) : this._getNextFlattenedListItem(listItem));
|
|
235
|
+
if (tempListItem) listItem = tempListItem;
|
|
236
|
+
else break;
|
|
237
|
+
num--;
|
|
233
238
|
}
|
|
234
|
-
const row = listItem.shadowRoot.querySelector('[role="gridrow"]');
|
|
235
|
-
if (!row) return;
|
|
236
239
|
|
|
237
|
-
|
|
240
|
+
if (!listItem) return;
|
|
241
|
+
const listItemRow = listItem.shadowRoot.querySelector('[role="gridrow"]');
|
|
242
|
+
listItemRow._focusCellItem(this._cellNum, this._cellFocusedItem);
|
|
243
|
+
|
|
238
244
|
}
|
|
239
245
|
|
|
240
246
|
_focusNextWithinCell(node, num = 1) {
|
|
@@ -280,6 +286,38 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
|
|
|
280
286
|
return position;
|
|
281
287
|
}
|
|
282
288
|
|
|
289
|
+
_getNextFlattenedListItem(listItem) {
|
|
290
|
+
|
|
291
|
+
// check for nested list first; this check needs to account for standard list-items as well as custom
|
|
292
|
+
const nestedList = listItem.querySelector('[slot="nested"]') || listItem.shadowRoot.querySelector('d2l-list');
|
|
293
|
+
if (nestedList) {
|
|
294
|
+
const nestedListItem = [...nestedList.children].find(node => node.role === 'rowgroup');
|
|
295
|
+
if (nestedListItem) return nestedListItem;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const getNextListItem = listItem => {
|
|
299
|
+
|
|
300
|
+
// check for sibling list-item
|
|
301
|
+
let nextElement = listItem.nextElementSibling;
|
|
302
|
+
while (nextElement) {
|
|
303
|
+
if (nextElement.role === 'rowgroup') return nextElement;
|
|
304
|
+
nextElement = nextElement.nextElementSibling;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// no sibling list-item was found so check for sibling of parent list-item if nested, recursively if necessary
|
|
308
|
+
const list = findComposedAncestor(listItem, node => node.tagName === 'D2L-LIST');
|
|
309
|
+
if (list.slot !== 'nested' && !(list.parentNode.tagName === 'SLOT' && list.parentNode.name === 'nested')) return;
|
|
310
|
+
|
|
311
|
+
const parentListItem = findComposedAncestor(list, node => node.role === 'rowgroup');
|
|
312
|
+
return getNextListItem(parentListItem);
|
|
313
|
+
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
// check for sibling list-item or ancestors sibling list-items
|
|
317
|
+
return getNextListItem(listItem);
|
|
318
|
+
|
|
319
|
+
}
|
|
320
|
+
|
|
283
321
|
_getNextSiblingInCell(node) {
|
|
284
322
|
const cell = findComposedAncestor(node, (parent) => parent.classList && parent.classList.contains('d2l-cell'));
|
|
285
323
|
if (!cell || cell.name === node.slot) return null;
|
|
@@ -289,6 +327,39 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
|
|
|
289
327
|
return isComposedAncestor(cell, sibling) ? sibling : null;
|
|
290
328
|
}
|
|
291
329
|
|
|
330
|
+
_getPreviousFlattenedListItem(listItem) {
|
|
331
|
+
|
|
332
|
+
let previousElement = listItem.previousElementSibling;
|
|
333
|
+
|
|
334
|
+
// try to get the previous list-item in the current list sub-tree including nested
|
|
335
|
+
while (previousElement) {
|
|
336
|
+
if (previousElement.role === 'rowgroup') {
|
|
337
|
+
|
|
338
|
+
// this check needs to account for standard list-items as well as custom
|
|
339
|
+
const nestedList = previousElement.querySelector('[slot="nested"]') || previousElement.shadowRoot.querySelector('d2l-list');
|
|
340
|
+
if (nestedList) {
|
|
341
|
+
const nestedListItems = [...nestedList.children].filter(node => node.role === 'rowgroup');
|
|
342
|
+
if (nestedListItems && nestedListItems.length > 0) {
|
|
343
|
+
return nestedListItems[nestedListItems.length - 1];
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return previousElement;
|
|
347
|
+
|
|
348
|
+
}
|
|
349
|
+
previousElement = previousElement.previousElementSibling;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// no previous list-item was found in the current list sub-tree so get the parent list item if currently in nested
|
|
353
|
+
const list = findComposedAncestor(listItem, node => node.tagName === 'D2L-LIST');
|
|
354
|
+
|
|
355
|
+
// this check needs to account for standard list-items as well as custom
|
|
356
|
+
if (list.slot === 'nested' || (list.parentNode.tagName === 'SLOT' && list.parentNode.name === 'nested')) {
|
|
357
|
+
const parentListItem = findComposedAncestor(list, node => node.role === 'rowgroup');
|
|
358
|
+
return parentListItem;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
}
|
|
362
|
+
|
|
292
363
|
_getPrevSiblingInCell(node) {
|
|
293
364
|
const cell = findComposedAncestor(node, (parent) => parent.classList && parent.classList.contains('d2l-cell'));
|
|
294
365
|
if (!cell || cell.name === node.slot) return null;
|
|
@@ -45,6 +45,7 @@ export const ListItemLinkMixin = superclass => class extends ListItemMixin(super
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
_handleLinkClick() {
|
|
48
|
+
/** Dispatched when the item's primary link action is clicked */
|
|
48
49
|
this.dispatchEvent(new CustomEvent('d2l-list-item-link-click', { bubbles: true }));
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -6,9 +6,6 @@ import { LitElement } from 'lit-element/lit-element.js';
|
|
|
6
6
|
* @slot - Default content placed inside of the component
|
|
7
7
|
* @slot illustration - Image associated with the list item located at the left of the item
|
|
8
8
|
* @slot actions - Actions (e.g., button icons) associated with the listen item located at the right of the item
|
|
9
|
-
* @fires d2l-list-item-link-click - Dispatched when the item's primary link action is clicked
|
|
10
|
-
* @fires d2l-list-item-position-change - Dispatched when a draggable list item's position changes in the list. See [Event Details: d2l-list-item-position-change](#event-details%3A-d2l-list-item-position-change).
|
|
11
|
-
* @fires d2l-list-item-selected - Dispatched when the component item is selected
|
|
12
9
|
*/
|
|
13
10
|
class ListItem extends ListItemLinkMixin(LitElement) {
|
|
14
11
|
|
package/components/list/list.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { css, html, LitElement } from 'lit-element/lit-element.js';
|
|
2
|
+
import { getNextFocusable, getPreviousFocusable } from '../../helpers/focus.js';
|
|
2
3
|
import { SelectionInfo, SelectionMixin } from '../selection/selection-mixin.js';
|
|
3
4
|
|
|
5
|
+
const keyCodes = {
|
|
6
|
+
TAB: 9
|
|
7
|
+
};
|
|
8
|
+
|
|
4
9
|
export const listSelectionStates = SelectionInfo.states;
|
|
5
10
|
|
|
6
11
|
/**
|
|
7
12
|
* A container for a styled list of items ("d2l-list-item"). It provides the appropriate "list" semantics as well as options for displaying separators, etc.
|
|
8
13
|
* @slot - List content (e.g., `listitem`s)
|
|
9
|
-
* @fires d2l-list-selection-change - Dispatched when the selection state changes
|
|
10
14
|
*/
|
|
11
15
|
class List extends SelectionMixin(LitElement) {
|
|
12
16
|
|
|
@@ -14,10 +18,12 @@ class List extends SelectionMixin(LitElement) {
|
|
|
14
18
|
return {
|
|
15
19
|
/**
|
|
16
20
|
* Whether to extend the separators beyond the content's edge
|
|
21
|
+
* @type {boolean}
|
|
17
22
|
*/
|
|
18
23
|
extendSeparators: { type: Boolean, reflect: true, attribute: 'extend-separators' },
|
|
19
24
|
/**
|
|
20
25
|
* Use grid to manage focus with arrow keys. See [Accessibility](#accessibility).
|
|
26
|
+
* @type {boolean}
|
|
21
27
|
*/
|
|
22
28
|
grid: { type: Boolean },
|
|
23
29
|
/**
|
|
@@ -54,6 +60,7 @@ class List extends SelectionMixin(LitElement) {
|
|
|
54
60
|
// batch the changes from select-all and nested lists
|
|
55
61
|
if (this._listItemChanges.length === 0) {
|
|
56
62
|
setTimeout(() => {
|
|
63
|
+
/** Dispatched once for a set of selection state changes (ex. select-all); event detail includes an array of objects where each object contains the `key` and `selected` state for each changed item */
|
|
57
64
|
this.dispatchEvent(new CustomEvent('d2l-list-selection-changes', {
|
|
58
65
|
detail: this._listItemChanges
|
|
59
66
|
}));
|
|
@@ -63,6 +70,7 @@ class List extends SelectionMixin(LitElement) {
|
|
|
63
70
|
this._listItemChanges.push(e.detail);
|
|
64
71
|
|
|
65
72
|
setTimeout(() => {
|
|
73
|
+
/** Dispatched when the selection state changes */
|
|
66
74
|
this.dispatchEvent(new CustomEvent('d2l-list-selection-change', {
|
|
67
75
|
bubbles: true,
|
|
68
76
|
composed: true,
|
|
@@ -78,7 +86,7 @@ class List extends SelectionMixin(LitElement) {
|
|
|
78
86
|
return html`
|
|
79
87
|
<div role="${role}" class="d2l-list-container">
|
|
80
88
|
<slot name="header"></slot>
|
|
81
|
-
<slot></slot>
|
|
89
|
+
<slot @keydown="${this._handleKeyDown}"></slot>
|
|
82
90
|
</div>
|
|
83
91
|
`;
|
|
84
92
|
}
|
|
@@ -91,6 +99,17 @@ class List extends SelectionMixin(LitElement) {
|
|
|
91
99
|
return this._getItems().indexOf(item);
|
|
92
100
|
}
|
|
93
101
|
|
|
102
|
+
getSelectedListItems(includeNested) {
|
|
103
|
+
let selectedItems = [];
|
|
104
|
+
this._getItems().forEach(item => {
|
|
105
|
+
if (item.selected) selectedItems.push(item);
|
|
106
|
+
if (includeNested && item._selectionProvider) {
|
|
107
|
+
selectedItems = [...selectedItems, ...item._selectionProvider.getSelectedListItems(includeNested)];
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
return selectedItems;
|
|
111
|
+
}
|
|
112
|
+
|
|
94
113
|
getSelectionInfo(includeNested) {
|
|
95
114
|
const selectionInfo = super.getSelectionInfo();
|
|
96
115
|
if (!includeNested) return selectionInfo;
|
|
@@ -114,6 +133,14 @@ class List extends SelectionMixin(LitElement) {
|
|
|
114
133
|
});
|
|
115
134
|
}
|
|
116
135
|
|
|
136
|
+
_handleKeyDown(e) {
|
|
137
|
+
if (!this.grid || this.slot === 'nested' || e.keyCode !== keyCodes.TAB) return;
|
|
138
|
+
e.preventDefault();
|
|
139
|
+
const focusable = (e.shiftKey ? getPreviousFocusable(this.shadowRoot.querySelector('slot:not([name])'))
|
|
140
|
+
: getNextFocusable(this, false, true, true));
|
|
141
|
+
if (focusable) focusable.focus();
|
|
142
|
+
}
|
|
143
|
+
|
|
117
144
|
}
|
|
118
145
|
|
|
119
146
|
customElements.define('d2l-list', List);
|
|
@@ -6,10 +6,6 @@ import { RtlMixin } from '../../mixins/rtl-mixin.js';
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* A menu item component used for selection. Multiple checkboxes can be selected at once.
|
|
9
|
-
* @fires click - Dispatched when the link is clicked
|
|
10
|
-
* @fires d2l-menu-item-change - Dispatched when the selected menu item changes
|
|
11
|
-
* @fires d2l-menu-item-select - Dispatched when the menu item is selected
|
|
12
|
-
* @fires d2l-menu-item-visibility-change - Dispatched when the visibility of the menu item changes
|
|
13
9
|
*/
|
|
14
10
|
class MenuItemCheckbox extends RtlMixin(MenuItemSelectableMixin(LitElement)) {
|
|
15
11
|
|
|
@@ -6,8 +6,6 @@ import { menuItemStyles } from './menu-item-styles.js';
|
|
|
6
6
|
/**
|
|
7
7
|
* A menu item component used for navigating.
|
|
8
8
|
* @fires click - Dispatched when the link is clicked
|
|
9
|
-
* @fires d2l-menu-item-select - Dispatched when the menu item is selected
|
|
10
|
-
* @fires d2l-menu-item-visibility-change - Dispatched when the visibility of the menu item changes
|
|
11
9
|
*/
|
|
12
10
|
class MenuItemLink extends MenuItemMixin(LitElement) {
|
|
13
11
|
|
|
@@ -4,6 +4,7 @@ export const MenuItemMixin = superclass => class extends superclass {
|
|
|
4
4
|
return {
|
|
5
5
|
/**
|
|
6
6
|
* Disables the menu item
|
|
7
|
+
* @type {boolean}
|
|
7
8
|
*/
|
|
8
9
|
disabled: { type: Boolean, reflect: true },
|
|
9
10
|
/**
|
|
@@ -100,6 +101,7 @@ export const MenuItemMixin = superclass => class extends superclass {
|
|
|
100
101
|
// assumption: single, focusable child view
|
|
101
102
|
this.__children[0].show();
|
|
102
103
|
} else {
|
|
104
|
+
/** Dispatched when the menu item is selected */
|
|
103
105
|
this.dispatchEvent(new CustomEvent('d2l-menu-item-select', { bubbles: true, composed: true }));
|
|
104
106
|
}
|
|
105
107
|
}
|
|
@@ -162,6 +164,7 @@ export const MenuItemMixin = superclass => class extends superclass {
|
|
|
162
164
|
}
|
|
163
165
|
|
|
164
166
|
_onHidden() {
|
|
167
|
+
/** Dispatched when the visibility of the menu item changes */
|
|
165
168
|
this.dispatchEvent(new CustomEvent('d2l-menu-item-visibility-change', { bubbles: true, composed: true }));
|
|
166
169
|
}
|
|
167
170
|
|
|
@@ -6,9 +6,6 @@ import { RtlMixin } from '../../mixins/rtl-mixin.js';
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* A menu item component used for radio selection. Only one radio item in a given d2l-menu may be selected at once (i.e., selecting one option will deselect the other selected "d2l-menu-item-radio" item).
|
|
9
|
-
* @fires d2l-menu-item-change - Dispatched when the selected menu item changes
|
|
10
|
-
* @fires d2l-menu-item-select - Dispatched when a menu item is selected
|
|
11
|
-
* @fires d2l-menu-item-visibility-change - Dispatched when the visibility of the menu item changes
|
|
12
9
|
*/
|
|
13
10
|
class MenuItemRadio extends RtlMixin(MenuItemRadioMixin(LitElement)) {
|
|
14
11
|
|
|
@@ -6,6 +6,7 @@ export const MenuItemSelectableMixin = superclass => class extends MenuItemMixin
|
|
|
6
6
|
return {
|
|
7
7
|
/**
|
|
8
8
|
* This will set the item to be selected by default
|
|
9
|
+
* @type {boolean}
|
|
9
10
|
*/
|
|
10
11
|
selected: { type: Boolean, reflect: true },
|
|
11
12
|
/**
|
|
@@ -42,6 +43,7 @@ export const MenuItemSelectableMixin = superclass => class extends MenuItemMixin
|
|
|
42
43
|
selected: this.selected
|
|
43
44
|
}
|
|
44
45
|
};
|
|
46
|
+
/** Dispatched when the selected menu item changes */
|
|
45
47
|
this.dispatchEvent(new CustomEvent('d2l-menu-item-change', eventDetails));
|
|
46
48
|
}
|
|
47
49
|
|
|
@@ -6,8 +6,6 @@ import { menuItemStyles } from './menu-item-styles.js';
|
|
|
6
6
|
/**
|
|
7
7
|
* A menu item component used with JS handlers.
|
|
8
8
|
* @slot - Default content placed inside of the component
|
|
9
|
-
* @fires d2l-menu-item-select - Dispatched when a menu item is selected
|
|
10
|
-
* @fires d2l-menu-item-visibility-change - Dispatched when the visibility of the menu item changes
|
|
11
9
|
*/
|
|
12
10
|
class MenuItem extends MenuItemMixin(LitElement) {
|
|
13
11
|
|
|
@@ -111,9 +111,7 @@ function convertToDropdownItem(node) {
|
|
|
111
111
|
}
|
|
112
112
|
/**
|
|
113
113
|
*
|
|
114
|
-
* A component that can be used to display a set of buttons, links or menus that will be put into a
|
|
115
|
-
* dropdown menu when they no longer fit on the first line of their container
|
|
116
|
-
*
|
|
114
|
+
* A component that can be used to display a set of buttons, links or menus that will be put into a dropdown menu when they no longer fit on the first line of their container
|
|
117
115
|
* @slot - Buttons, dropdown buttons, links or other items to be added to the container
|
|
118
116
|
* @fires d2l-overflow-group-updated - Dispatched when there is an update performed to the overflow group
|
|
119
117
|
*/
|
|
@@ -123,6 +121,7 @@ class OverflowGroup extends RtlMixin(LocalizeCoreElement(LitElement)) {
|
|
|
123
121
|
return {
|
|
124
122
|
/**
|
|
125
123
|
* Use predefined classes on slot elements to set min and max buttons to show
|
|
124
|
+
* @type {boolean}
|
|
126
125
|
*/
|
|
127
126
|
autoShow: {
|
|
128
127
|
type: Boolean,
|
|
@@ -130,6 +129,7 @@ class OverflowGroup extends RtlMixin(LocalizeCoreElement(LitElement)) {
|
|
|
130
129
|
},
|
|
131
130
|
/**
|
|
132
131
|
* minimum amount of buttons to show
|
|
132
|
+
* @type {number}
|
|
133
133
|
*/
|
|
134
134
|
minToShow: {
|
|
135
135
|
type: Number,
|
|
@@ -138,6 +138,7 @@ class OverflowGroup extends RtlMixin(LocalizeCoreElement(LitElement)) {
|
|
|
138
138
|
},
|
|
139
139
|
/**
|
|
140
140
|
* maximum amount of buttons to show
|
|
141
|
+
* @type {number}
|
|
141
142
|
*/
|
|
142
143
|
maxToShow: {
|
|
143
144
|
type: Number,
|
|
@@ -12,7 +12,6 @@ const SCROLL_AMOUNT = 0.8;
|
|
|
12
12
|
/**
|
|
13
13
|
*
|
|
14
14
|
* Wraps content which may overflow its horizontal boundaries, providing left/right scroll buttons.
|
|
15
|
-
*
|
|
16
15
|
* @slot - User provided content to wrap
|
|
17
16
|
*/
|
|
18
17
|
class ScrollWrapper extends FocusVisiblePolyfillMixin(RtlMixin(LitElement)) {
|
|
@@ -54,7 +53,7 @@ class ScrollWrapper extends FocusVisiblePolyfillMixin(RtlMixin(LitElement)) {
|
|
|
54
53
|
:host([hidden]) {
|
|
55
54
|
display: none;
|
|
56
55
|
}
|
|
57
|
-
|
|
56
|
+
|
|
58
57
|
.d2l-scroll-wrapper-container {
|
|
59
58
|
box-sizing: border-box;
|
|
60
59
|
outline: none;
|
|
@@ -12,6 +12,7 @@ import { SelectionObserverMixin } from './selection-observer-mixin.js';
|
|
|
12
12
|
/**
|
|
13
13
|
* An action associated with a selection component.
|
|
14
14
|
* @fires d2l-selection-action-click - Dispatched when the user clicks the action; provides the selection info
|
|
15
|
+
* @fires d2l-selection-observer-subscribe - Internal event
|
|
15
16
|
*/
|
|
16
17
|
class Action extends LocalizeCoreElement(SelectionObserverMixin(ButtonMixin(RtlMixin(LitElement)))) {
|
|
17
18
|
|
|
@@ -19,14 +20,17 @@ class Action extends LocalizeCoreElement(SelectionObserverMixin(ButtonMixin(RtlM
|
|
|
19
20
|
return {
|
|
20
21
|
/**
|
|
21
22
|
* Preset icon key (e.g. "tier1:gear")
|
|
23
|
+
* @type {string}
|
|
22
24
|
*/
|
|
23
25
|
icon: { type: String, reflect: true },
|
|
24
26
|
/**
|
|
25
27
|
* Whether the action requires one or more selected items
|
|
28
|
+
* @type {boolean}
|
|
26
29
|
*/
|
|
27
30
|
requiresSelection: { type: Boolean, attribute: 'requires-selection', reflect: true },
|
|
28
31
|
/**
|
|
29
32
|
* REQUIRED: The text for the action
|
|
33
|
+
* @type {string}
|
|
30
34
|
*/
|
|
31
35
|
text: { type: String, reflect: true }
|
|
32
36
|
};
|
|
@@ -13,6 +13,7 @@ const keyCodes = {
|
|
|
13
13
|
/**
|
|
14
14
|
* An input (radio or checkbox) for use in selection components such as lists and tables.
|
|
15
15
|
* @fires d2l-selection-change - Dispatched when the selected state changes
|
|
16
|
+
* @fires d2l-selection-input-subscribe - Internal event
|
|
16
17
|
*/
|
|
17
18
|
class Input extends SkeletonMixin(LabelledMixin(LitElement)) {
|
|
18
19
|
|
|
@@ -20,18 +21,22 @@ class Input extends SkeletonMixin(LabelledMixin(LitElement)) {
|
|
|
20
21
|
return {
|
|
21
22
|
/**
|
|
22
23
|
* State of the input
|
|
24
|
+
* @type {boolean}
|
|
23
25
|
*/
|
|
24
26
|
selected: { type: Boolean },
|
|
25
27
|
/**
|
|
26
28
|
* Disables the input
|
|
29
|
+
* @type {boolean}
|
|
27
30
|
*/
|
|
28
31
|
disabled: { type: Boolean },
|
|
29
32
|
/**
|
|
30
33
|
* Private. Force hovering state of input
|
|
34
|
+
* @type {boolean}
|
|
31
35
|
*/
|
|
32
36
|
hovering: { type: Boolean },
|
|
33
37
|
/**
|
|
34
38
|
* Key for the selectable
|
|
39
|
+
* @type {string}
|
|
35
40
|
*/
|
|
36
41
|
key: { type: String },
|
|
37
42
|
_indeterminate: { type: Boolean },
|
|
@@ -89,10 +94,12 @@ class Input extends SkeletonMixin(LabelledMixin(LitElement)) {
|
|
|
89
94
|
'd2l-input-radio': true,
|
|
90
95
|
'd2l-selection-input-radio': true,
|
|
91
96
|
'd2l-skeletize': true,
|
|
92
|
-
'd2l-hovering': this.hovering
|
|
97
|
+
'd2l-hovering': this.hovering,
|
|
98
|
+
'd2l-disabled': this.disabled
|
|
93
99
|
};
|
|
94
100
|
return html`
|
|
95
101
|
<div
|
|
102
|
+
aria-disabled="${ifDefined(this.disabled)}"
|
|
96
103
|
aria-label="${this.label}"
|
|
97
104
|
aria-checked="${this.selected ? 'true' : 'false'}"
|
|
98
105
|
class="${classMap(radioClasses)}"
|
|
@@ -100,7 +107,7 @@ class Input extends SkeletonMixin(LabelledMixin(LitElement)) {
|
|
|
100
107
|
@keydown="${this._handleRadioKeyDown}"
|
|
101
108
|
@keyup="${this._handleRadioKeyUp}"
|
|
102
109
|
role="radio"
|
|
103
|
-
tabindex="0"></div>
|
|
110
|
+
tabindex="${ifDefined(this.disabled ? undefined : 0)}"></div>
|
|
104
111
|
`;
|
|
105
112
|
} else {
|
|
106
113
|
return html`
|
|
@@ -39,7 +39,8 @@ export const SelectionMixin = superclass => class extends RtlMixin(superclass) {
|
|
|
39
39
|
static get properties() {
|
|
40
40
|
return {
|
|
41
41
|
/**
|
|
42
|
-
* Whether the selection control is limited to single selection
|
|
42
|
+
* Whether the selection control is limited to single selection
|
|
43
|
+
* @type {boolean}
|
|
43
44
|
*/
|
|
44
45
|
selectionSingle: { type: Boolean, attribute: 'selection-single' }
|
|
45
46
|
};
|
|
@@ -60,6 +61,7 @@ export const SelectionMixin = superclass => class extends RtlMixin(superclass) {
|
|
|
60
61
|
this.addEventListener('d2l-selection-observer-subscribe', this._handleSelectionObserverSubscribe);
|
|
61
62
|
this.addEventListener('d2l-selection-input-subscribe', this._handleSelectionInputSubscribe);
|
|
62
63
|
requestAnimationFrame(() => {
|
|
64
|
+
/** @ignore */
|
|
63
65
|
this.dispatchEvent(new CustomEvent('d2l-selection-provider-connected', { bubbles: true, composed: true }));
|
|
64
66
|
});
|
|
65
67
|
|
|
@@ -7,10 +7,12 @@ export const SelectionObserverMixin = superclass => class extends superclass {
|
|
|
7
7
|
return {
|
|
8
8
|
/**
|
|
9
9
|
* Id of the SelectionMixin component this component wants to observe (if not located within that component)
|
|
10
|
+
* @type {string}
|
|
10
11
|
*/
|
|
11
12
|
selectionFor: { type: String, reflect: true, attribute: 'selection-for' },
|
|
12
13
|
/**
|
|
13
|
-
* The selection info (set by the selection component)
|
|
14
|
+
* The selection info (set by the selection component)
|
|
15
|
+
* @type {object}
|
|
14
16
|
*/
|
|
15
17
|
selectionInfo: { type: Object },
|
|
16
18
|
_provider: { type: Object, attribute: false }
|
|
@@ -7,6 +7,7 @@ import { SelectionObserverMixin } from './selection-observer-mixin.js';
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* A checkbox that provides select-all behavior for selection components such as tables and lists.
|
|
10
|
+
* @fires d2l-selection-observer-subscribe - Internal event
|
|
10
11
|
*/
|
|
11
12
|
class SelectAll extends LocalizeCoreElement(SelectionObserverMixin(LitElement)) {
|
|
12
13
|
|
|
@@ -14,6 +15,7 @@ class SelectAll extends LocalizeCoreElement(SelectionObserverMixin(LitElement))
|
|
|
14
15
|
return {
|
|
15
16
|
/**
|
|
16
17
|
* Disables the select all checkbox
|
|
18
|
+
* @type {boolean}
|
|
17
19
|
*/
|
|
18
20
|
disabled: { type: Boolean }
|
|
19
21
|
};
|