@brightspace-ui/core 1.210.1 → 1.211.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/list/demo/{list-demo-drag-and-drop-usage.js → list-drag-and-drop-position.js} +3 -2
- package/components/list/demo/list-drag-and-drop.html +12 -19
- package/components/list/demo/list-drag-and-drop.js +171 -0
- package/components/list/list-item-checkbox-mixin.js +4 -10
- package/components/list/list-item-drag-drop-mixin.js +205 -47
- package/components/list/list-item-drag-handle.js +18 -7
- package/components/list/list-item-generic-layout.js +12 -1
- package/components/list/list-item-mixin.js +51 -3
- package/components/list/list.js +30 -12
- package/custom-elements.json +121 -35
- package/package.json +1 -1
package/components/list/demo/{list-demo-drag-and-drop-usage.js → list-drag-and-drop-position.js}
RENAMED
|
@@ -5,7 +5,8 @@ import { html, LitElement } from 'lit-element/lit-element.js';
|
|
|
5
5
|
import { ifDefined } from 'lit-html/directives/if-defined.js';
|
|
6
6
|
import { repeat } from 'lit-html/directives/repeat.js';
|
|
7
7
|
|
|
8
|
-
class
|
|
8
|
+
class ListDemoDragAndDropPosition extends LitElement {
|
|
9
|
+
|
|
9
10
|
static get properties() {
|
|
10
11
|
return {
|
|
11
12
|
list: { type: Array },
|
|
@@ -92,4 +93,4 @@ class ListDemoDragAndDropUsage extends LitElement {
|
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
customElements.define('d2l-list-
|
|
96
|
+
customElements.define('d2l-demo-list-drag-and-drop-position', ListDemoDragAndDropPosition);
|
|
@@ -6,45 +6,38 @@
|
|
|
6
6
|
<link rel="stylesheet" href="../../demo/styles.css" type="text/css">
|
|
7
7
|
<script type="module">
|
|
8
8
|
import '../../demo/demo-page.js';
|
|
9
|
-
import './list-
|
|
9
|
+
import './list-drag-and-drop-position.js';
|
|
10
|
+
import './list-drag-and-drop.js';
|
|
10
11
|
</script>
|
|
11
12
|
</head>
|
|
12
13
|
<body unresolved>
|
|
13
14
|
|
|
14
15
|
<d2l-demo-page page-title="d2l-list (with drag & drop)">
|
|
15
16
|
|
|
16
|
-
<h2>
|
|
17
|
+
<h2>Position Change Event</h2>
|
|
17
18
|
|
|
18
19
|
<d2l-demo-snippet>
|
|
19
20
|
<template>
|
|
20
|
-
<d2l-list-
|
|
21
|
+
<d2l-demo-list-drag-and-drop-position grid selectable hrefs></d2l-demo-list-drag-and-drop-position>
|
|
21
22
|
</template>
|
|
22
23
|
</d2l-demo-snippet>
|
|
23
24
|
|
|
24
|
-
<h2>
|
|
25
|
+
<h2>Move Event</h2>
|
|
25
26
|
|
|
26
27
|
<d2l-demo-snippet>
|
|
27
28
|
<template>
|
|
28
|
-
<d2l-list-
|
|
29
|
+
<d2l-demo-list-drag-and-drop></d2l-demo-list-drag-and-drop>
|
|
29
30
|
</template>
|
|
30
31
|
</d2l-demo-snippet>
|
|
31
32
|
|
|
32
|
-
<h2>Draggable with Grid and Selectable</h2>
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
<template>
|
|
36
|
-
<d2l-list-demo-drag-and-drop-usage grid selectable></d2l-list-demo-drag-and-drop-usage>
|
|
37
|
-
</template>
|
|
38
|
-
</d2l-demo-snippet>
|
|
39
|
-
|
|
40
|
-
<h2>All the Fixins (grid, draggable, selectable, hrefs)</h2>
|
|
34
|
+
</d2l-demo-page>
|
|
41
35
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
36
|
+
<script>
|
|
37
|
+
document.body.addEventListener('d2l-list-items-move', e => {
|
|
38
|
+
console.log('d2l-list-items-move', e.detail);
|
|
39
|
+
});
|
|
40
|
+
</script>
|
|
47
41
|
|
|
48
|
-
</d2l-demo-page>
|
|
49
42
|
</body>
|
|
50
43
|
</html>
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import '../list-item-content.js';
|
|
2
|
+
import '../list-item.js';
|
|
3
|
+
import '../list.js';
|
|
4
|
+
import { html, LitElement } from 'lit-element/lit-element.js';
|
|
5
|
+
import { ifDefined } from 'lit-html/directives/if-defined.js';
|
|
6
|
+
import { moveLocations } from '../list-item-drag-drop-mixin.js';
|
|
7
|
+
import { repeat } from 'lit-html/directives/repeat.js';
|
|
8
|
+
|
|
9
|
+
class ListDemoDragAndDrop extends LitElement {
|
|
10
|
+
|
|
11
|
+
static get properties() {
|
|
12
|
+
return {
|
|
13
|
+
items: { type: Array }
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
constructor() {
|
|
18
|
+
super();
|
|
19
|
+
this.items = [{
|
|
20
|
+
key: '1',
|
|
21
|
+
primaryText: 'Introductory Earth Sciences',
|
|
22
|
+
supportingText: 'This course explores the geological processes of the Earth\'s interior and surface. These include volcanism, earthquakes, mountain building, glaciation and weathering.',
|
|
23
|
+
imgSrc: 'https://s.brightspace.com/course-images/images/63b162ab-b582-4bf9-8c1d-1dad04714121/tile-high-density-max-size.jpg',
|
|
24
|
+
items: [{
|
|
25
|
+
key: '1-1',
|
|
26
|
+
primaryText: 'Glaciation',
|
|
27
|
+
supportingText: 'Supporting Info',
|
|
28
|
+
imgSrc: '',
|
|
29
|
+
items: []
|
|
30
|
+
}, {
|
|
31
|
+
key: '1-2',
|
|
32
|
+
primaryText: 'Weathering',
|
|
33
|
+
supportingText: 'Supporting Info',
|
|
34
|
+
imgSrc: '',
|
|
35
|
+
items: []
|
|
36
|
+
}, {
|
|
37
|
+
key: '1-3',
|
|
38
|
+
primaryText: 'Volcanism',
|
|
39
|
+
supportingText: 'Supporting Info',
|
|
40
|
+
imgSrc: '',
|
|
41
|
+
items: []
|
|
42
|
+
}]
|
|
43
|
+
}, {
|
|
44
|
+
key: '2',
|
|
45
|
+
primaryText: 'Flow and Transport Through Fractured Rocks',
|
|
46
|
+
supportingText: 'Fractures are ubiquitous in geologic media and important in disciplines such as physical and contaminant hydrogeology, geotechnical engineering, civil and environmental engineering, petroleum engineering among other areas.',
|
|
47
|
+
imgSrc: 'https://s.brightspace.com/course-images/images/e5fd575a-bc14-4a80-89e1-46f349a76178/tile-high-density-max-size.jpg',
|
|
48
|
+
items: [{
|
|
49
|
+
key: '2-1',
|
|
50
|
+
primaryText: 'Contaminant Transport',
|
|
51
|
+
supportingText: 'Supporting Info',
|
|
52
|
+
imgSrc: '',
|
|
53
|
+
items: []
|
|
54
|
+
}, {
|
|
55
|
+
key: '2-2',
|
|
56
|
+
primaryText: 'Modelling Flow in Fractured Media',
|
|
57
|
+
supportingText: 'Supporting Info',
|
|
58
|
+
imgSrc: '',
|
|
59
|
+
items: []
|
|
60
|
+
}]
|
|
61
|
+
}, {
|
|
62
|
+
key: '3',
|
|
63
|
+
primaryText: 'Applied Wetland Science',
|
|
64
|
+
supportingText: 'Advanced concepts on wetland ecosystems in the context of regional and global earth systems processes such as carbon and nitrogen cycling and climate change, applications of wetland paleoecology, use of isotopes and other geochemical tools in wetland science, and wetland engineering in landscape rehabilitation and ecotechnology.',
|
|
65
|
+
imgSrc: 'https://s.brightspace.com/course-images/images/38e839b1-37fa-470c-8830-b189ce4ae134/tile-high-density-max-size.jpg',
|
|
66
|
+
items: [{
|
|
67
|
+
key: '3-1',
|
|
68
|
+
primaryText: 'Carbon & Nitrogen Cycling',
|
|
69
|
+
supportingText: 'Supporting Info',
|
|
70
|
+
imgSrc: '',
|
|
71
|
+
items: []
|
|
72
|
+
}, {
|
|
73
|
+
key: '3-2',
|
|
74
|
+
primaryText: 'Wetland Engineering',
|
|
75
|
+
supportingText: 'Supporting Info',
|
|
76
|
+
imgSrc: '',
|
|
77
|
+
items: []
|
|
78
|
+
}]
|
|
79
|
+
}];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
render() {
|
|
83
|
+
const renderList = (items, nested) => {
|
|
84
|
+
return html`
|
|
85
|
+
<d2l-list grid slot="${ifDefined(nested ? 'nested' : undefined)}">
|
|
86
|
+
${repeat(items, item => item.key, item => html`
|
|
87
|
+
<d2l-list-item
|
|
88
|
+
action-href="http://www.d2l.com"
|
|
89
|
+
draggable
|
|
90
|
+
drag-handle-text="${item.primaryText}"
|
|
91
|
+
drop-nested
|
|
92
|
+
key="${item.key}"
|
|
93
|
+
label="${item.primaryText}"
|
|
94
|
+
selectable>
|
|
95
|
+
${nested ? null : html`<img slot="illustration" src="${item.imgSrc}">`}
|
|
96
|
+
<d2l-list-item-content>
|
|
97
|
+
<div>${item.primaryText}</div>
|
|
98
|
+
<div slot="supporting-info">${item.supportingText}</div>
|
|
99
|
+
</d2l-list-item-content>
|
|
100
|
+
${item.items.length > 0 ? renderList(item.items, true) : null}
|
|
101
|
+
</d2l-list-item>
|
|
102
|
+
`)}
|
|
103
|
+
</d2l-list>
|
|
104
|
+
`;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
return html`
|
|
108
|
+
<div @d2l-list-items-move="${this._handleListItemsMove}">
|
|
109
|
+
${renderList(this.items, false)}
|
|
110
|
+
</div>
|
|
111
|
+
`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async _handleListItemsMove(e) {
|
|
115
|
+
|
|
116
|
+
const sourceListItems = e.detail.sourceItems;
|
|
117
|
+
const target = e.detail.target;
|
|
118
|
+
|
|
119
|
+
// helper that gets the array containing item data, the item data, and the index within the array
|
|
120
|
+
const getItemInfo = (items, key) => {
|
|
121
|
+
for (let i = 0; i < items.length; i++) {
|
|
122
|
+
if (items[i].key === key) {
|
|
123
|
+
return { owner: items, item: items[i], index: i };
|
|
124
|
+
}
|
|
125
|
+
if (items[i].items && items[i].items.length > 0) {
|
|
126
|
+
const tempItemData = getItemInfo(items[i].items, key);
|
|
127
|
+
if (tempItemData) return tempItemData;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const dataToMove = [];
|
|
133
|
+
|
|
134
|
+
// remove data elements from original locations
|
|
135
|
+
sourceListItems.forEach(sourceListItem => {
|
|
136
|
+
const info = getItemInfo(this.items, sourceListItem.key);
|
|
137
|
+
info.owner.splice(info.index, 1);
|
|
138
|
+
dataToMove.push(info.item);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// append data elements to new location
|
|
142
|
+
const targetInfo = getItemInfo(this.items, target.item.key);
|
|
143
|
+
let targetItems;
|
|
144
|
+
let targetIndex;
|
|
145
|
+
if (target.location === moveLocations.nest) {
|
|
146
|
+
if (!targetInfo.item.items) targetInfo.item.items = [];
|
|
147
|
+
targetItems = targetInfo.item.items;
|
|
148
|
+
targetIndex = targetItems.length;
|
|
149
|
+
} else {
|
|
150
|
+
targetItems = targetInfo.owner;
|
|
151
|
+
if (target.location === moveLocations.above) targetIndex = targetInfo.index;
|
|
152
|
+
else if (target.location === moveLocations.below) targetIndex = targetInfo.index + 1;
|
|
153
|
+
}
|
|
154
|
+
for (let i = dataToMove.length - 1; i >= 0; i--) {
|
|
155
|
+
targetItems.splice(targetIndex, 0, dataToMove[i]);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
await this.requestUpdate();
|
|
159
|
+
|
|
160
|
+
if (e.detail.keyboardActive) {
|
|
161
|
+
requestAnimationFrame(() => {
|
|
162
|
+
const newItem = this.shadowRoot.querySelector('d2l-list').getListItemByKey(sourceListItems[0].key);
|
|
163
|
+
newItem.activateDragHandle();
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
customElements.define('d2l-demo-list-drag-and-drop', ListDemoDragAndDrop);
|
|
@@ -113,16 +113,6 @@ export const ListItemCheckboxMixin = superclass => class extends SkeletonMixin(L
|
|
|
113
113
|
}));
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
_getNestedList() {
|
|
117
|
-
const nestedSlot = this.shadowRoot.querySelector('slot[name="nested"]');
|
|
118
|
-
let nestedNodes = nestedSlot.assignedNodes();
|
|
119
|
-
if (nestedNodes.length === 0) {
|
|
120
|
-
nestedNodes = [...nestedSlot.childNodes];
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return nestedNodes.find(node => (node.nodeType === Node.ELEMENT_NODE && node.tagName === 'D2L-LIST'));
|
|
124
|
-
}
|
|
125
|
-
|
|
126
116
|
_onCheckboxActionClick(event) {
|
|
127
117
|
event.preventDefault();
|
|
128
118
|
if (this.disabled) return;
|
|
@@ -140,6 +130,10 @@ export const ListItemCheckboxMixin = superclass => class extends SkeletonMixin(L
|
|
|
140
130
|
}
|
|
141
131
|
}
|
|
142
132
|
|
|
133
|
+
_onNestedSlotChange() {
|
|
134
|
+
this._updateNestedSelectionProvider();
|
|
135
|
+
}
|
|
136
|
+
|
|
143
137
|
_onSelectionProviderConnected(e) {
|
|
144
138
|
e.stopPropagation();
|
|
145
139
|
this._updateNestedSelectionProvider();
|
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
import { css, html } from 'lit-element/lit-element.js';
|
|
2
|
+
import { findComposedAncestor, isComposedAncestor } from '../../helpers/dom.js';
|
|
2
3
|
import { announce } from '../../helpers/announce.js';
|
|
3
4
|
import { classMap } from 'lit-html/directives/class-map.js';
|
|
4
5
|
import { dragActions } from './list-item-drag-handle.js';
|
|
5
|
-
import { findComposedAncestor } from '../../helpers/dom.js';
|
|
6
6
|
import { getUniqueId } from '../../helpers/uniqueId.js';
|
|
7
7
|
import { ifDefined } from 'lit-html/directives/if-defined.js';
|
|
8
8
|
import { nothing } from 'lit-html';
|
|
9
|
+
import { SelectionInfo } from '../selection/selection-mixin.js';
|
|
9
10
|
|
|
10
|
-
export const
|
|
11
|
+
export const moveLocations = Object.freeze({
|
|
11
12
|
above: 1,
|
|
12
13
|
below: 2,
|
|
13
14
|
first: 3,
|
|
14
15
|
last: 4,
|
|
15
16
|
shiftDown: 5,
|
|
16
17
|
shiftUp: 6,
|
|
18
|
+
nest: 7,
|
|
17
19
|
void: 0
|
|
18
20
|
});
|
|
19
21
|
|
|
20
|
-
const
|
|
22
|
+
export const dropLocation = moveLocations; // backwards compatibility
|
|
23
|
+
|
|
24
|
+
const dropTargetLeaveDelay = 1000; // ms
|
|
21
25
|
const touchHoldDuration = 400; // length of time user needs to hold down touch before dragging occurs
|
|
22
26
|
const scrollSensitivity = 150; // pixels between top/bottom of viewport to scroll for mobile
|
|
23
27
|
|
|
@@ -38,20 +42,16 @@ const isDragSupported = () => {
|
|
|
38
42
|
};
|
|
39
43
|
|
|
40
44
|
class DragState {
|
|
41
|
-
constructor(
|
|
42
|
-
this.
|
|
45
|
+
constructor(dragTargets) {
|
|
46
|
+
this._dragTargets = dragTargets;
|
|
43
47
|
this._activeDropTarget = null;
|
|
44
48
|
this._dropTargets = new Map();
|
|
45
49
|
this._dropLocation = dropLocation.void;
|
|
46
50
|
this._time = 0;
|
|
47
51
|
}
|
|
48
52
|
|
|
49
|
-
get
|
|
50
|
-
return this.
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
get dragTargetKey() {
|
|
54
|
-
return this._dragTarget && this._dragTarget.key;
|
|
53
|
+
get dragTargets() {
|
|
54
|
+
return this._dragTargets;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
get dropLocation() {
|
|
@@ -117,9 +117,9 @@ class DragState {
|
|
|
117
117
|
|
|
118
118
|
let dragState = null;
|
|
119
119
|
|
|
120
|
-
function createDragState(
|
|
120
|
+
function createDragState(targets) {
|
|
121
121
|
clearDragState();
|
|
122
|
-
dragState = new DragState(
|
|
122
|
+
dragState = new DragState(targets ? targets : []);
|
|
123
123
|
return dragState;
|
|
124
124
|
}
|
|
125
125
|
|
|
@@ -263,6 +263,11 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
263
263
|
* @type {string}
|
|
264
264
|
*/
|
|
265
265
|
dragHandleText: { type: String, attribute: 'drag-handle-text' },
|
|
266
|
+
/**
|
|
267
|
+
* **Drag & drop:** Whether the items can be dropped as nested children
|
|
268
|
+
* @type {boolean}
|
|
269
|
+
*/
|
|
270
|
+
dropNested: { type: Boolean, attribute: 'drop-nested' },
|
|
266
271
|
/**
|
|
267
272
|
* **Drag & drop:** Text to drag and drop
|
|
268
273
|
* @type {string}
|
|
@@ -274,7 +279,7 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
274
279
|
*/
|
|
275
280
|
key: { type: String, reflect: true },
|
|
276
281
|
_draggingOver: { type: Boolean },
|
|
277
|
-
_dropLocation: { type: Number },
|
|
282
|
+
_dropLocation: { type: Number, reflect: true, attribute: '_drop-location' },
|
|
278
283
|
_focusingDragHandle: { type: Boolean },
|
|
279
284
|
_hovering: { type: Boolean },
|
|
280
285
|
_keyboardActive: { type: Boolean },
|
|
@@ -293,6 +298,7 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
293
298
|
}
|
|
294
299
|
.d2l-list-item-drag-bottom-marker,
|
|
295
300
|
.d2l-list-item-drag-top-marker {
|
|
301
|
+
pointer-events: none;
|
|
296
302
|
position: absolute;
|
|
297
303
|
width: 100%;
|
|
298
304
|
z-index: 1;
|
|
@@ -311,16 +317,16 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
311
317
|
display: grid;
|
|
312
318
|
grid-template-columns: 100%;
|
|
313
319
|
grid-template-rows: 1rem 1fr 1fr 1rem;
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
z-index: 100;
|
|
320
|
+
}
|
|
321
|
+
:host([_drop-location="7"]) d2l-list-item-generic-layout {
|
|
322
|
+
border-radius: 6px;
|
|
323
|
+
outline: 2px solid var(--d2l-color-celestine);
|
|
319
324
|
}
|
|
320
325
|
@media only screen and (hover: hover), only screen and (pointer: fine) {
|
|
321
326
|
d2l-list-item-drag-handle {
|
|
322
327
|
opacity: 0;
|
|
323
328
|
}
|
|
329
|
+
:host([selected]) d2l-list-item-drag-handle,
|
|
324
330
|
d2l-list-item-drag-handle.d2l-hovering,
|
|
325
331
|
d2l-list-item-drag-handle.d2l-focusing {
|
|
326
332
|
opacity: 1;
|
|
@@ -335,8 +341,10 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
335
341
|
constructor() {
|
|
336
342
|
super();
|
|
337
343
|
this._itemDragId = getUniqueId();
|
|
344
|
+
this.draggable = false;
|
|
338
345
|
/** @ignore */
|
|
339
346
|
this.dragging = false;
|
|
347
|
+
this.dropNested = false;
|
|
340
348
|
}
|
|
341
349
|
|
|
342
350
|
connectedCallback() {
|
|
@@ -351,6 +359,10 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
351
359
|
super.firstUpdated(changedProperties);
|
|
352
360
|
}
|
|
353
361
|
|
|
362
|
+
activateDragHandle() {
|
|
363
|
+
this.shadowRoot.querySelector(`#${this._itemDragId}`).activateKeyboardMode();
|
|
364
|
+
}
|
|
365
|
+
|
|
354
366
|
_annoucePositionChange(dragTargetKey, dropTargetKey, dropLocation) {
|
|
355
367
|
/** 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). */
|
|
356
368
|
this.dispatchEvent(new CustomEvent('d2l-list-item-position-change', {
|
|
@@ -359,6 +371,84 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
359
371
|
}));
|
|
360
372
|
}
|
|
361
373
|
|
|
374
|
+
_dispatchListItemsMove(sourceItems, targetItem, moveLocation, keyboardActive) {
|
|
375
|
+
if (!keyboardActive) keyboardActive = false;
|
|
376
|
+
const rootList = this._getRootList();
|
|
377
|
+
rootList.dispatchEvent(new CustomEvent('d2l-list-items-move', {
|
|
378
|
+
detail: {
|
|
379
|
+
keyboardActive: keyboardActive,
|
|
380
|
+
sourceItems: sourceItems,
|
|
381
|
+
target: {
|
|
382
|
+
item: targetItem,
|
|
383
|
+
location: moveLocation
|
|
384
|
+
}
|
|
385
|
+
},
|
|
386
|
+
bubbles: true
|
|
387
|
+
}));
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
_dispatchMoveListItemFirst(moveToRoot) {
|
|
391
|
+
const list = (moveToRoot ? this._getRootList() : findComposedAncestor(this, node => node.tagName === 'D2L-LIST'));
|
|
392
|
+
const items = list.getItems();
|
|
393
|
+
this._dispatchListItemsMove([this], items[0], moveLocations.above, true);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
_dispatchMoveListItemLast(moveToRoot) {
|
|
397
|
+
const list = (moveToRoot ? this._getRootList() : findComposedAncestor(this, node => node.tagName === 'D2L-LIST'));
|
|
398
|
+
const items = list.getItems();
|
|
399
|
+
this._dispatchListItemsMove([this], items[items.length - 1], moveLocations.below, true);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
_dispatchMoveListItemNest() {
|
|
403
|
+
const listItem = this._getPreviousListItemSibling();
|
|
404
|
+
if (listItem) {
|
|
405
|
+
this._dispatchListItemsMove([this], listItem, moveLocations.nest, true);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
_dispatchMoveListItemNext() {
|
|
410
|
+
const listItem = this._getNextListItemSibling();
|
|
411
|
+
if (listItem) {
|
|
412
|
+
const nestedList = listItem._getNestedList();
|
|
413
|
+
const items = (nestedList ? nestedList.getItems() : []);
|
|
414
|
+
if (items.length > 0) {
|
|
415
|
+
this._dispatchListItemsMove([this], items[0], moveLocations.above, true);
|
|
416
|
+
} else {
|
|
417
|
+
this._dispatchListItemsMove([this], listItem, moveLocations.below, true);
|
|
418
|
+
}
|
|
419
|
+
} else {
|
|
420
|
+
const parentListItem = this._getParentListItem();
|
|
421
|
+
if (parentListItem) {
|
|
422
|
+
this._dispatchListItemsMove([this], parentListItem, moveLocations.below, true);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
_dispatchMoveListItemPrevious() {
|
|
428
|
+
const listItem = this._getPreviousListItemSibling();
|
|
429
|
+
if (listItem) {
|
|
430
|
+
const nestedList = listItem._getNestedList();
|
|
431
|
+
const items = (nestedList ? nestedList.getItems() : []);
|
|
432
|
+
if (items.length > 0) {
|
|
433
|
+
this._dispatchListItemsMove([this], items[items.length - 1], moveLocations.below, true);
|
|
434
|
+
} else {
|
|
435
|
+
this._dispatchListItemsMove([this], listItem, moveLocations.above, true);
|
|
436
|
+
}
|
|
437
|
+
} else {
|
|
438
|
+
const parentListItem = this._getParentListItem();
|
|
439
|
+
if (parentListItem) {
|
|
440
|
+
this._dispatchListItemsMove([this], parentListItem, moveLocations.above, true);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
_dispatchMoveListItemUnnest() {
|
|
446
|
+
const listItem = this._getParentListItem();
|
|
447
|
+
if (listItem) {
|
|
448
|
+
this._dispatchListItemsMove([this], listItem, moveLocations.below, true);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
362
452
|
_findListItemFromCoordinates(x, y) {
|
|
363
453
|
const listNode = findComposedAncestor(this.parentNode, (node) => node && node.tagName === 'D2L-LIST');
|
|
364
454
|
return listNode.shadowRoot.elementFromPoint(x, y);
|
|
@@ -380,11 +470,27 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
380
470
|
}
|
|
381
471
|
|
|
382
472
|
_onDragEnd(e) {
|
|
473
|
+
|
|
383
474
|
const dragState = getDragState();
|
|
384
475
|
this.dragging = false;
|
|
385
|
-
|
|
386
|
-
|
|
476
|
+
|
|
477
|
+
// check the dropEffect in case the user cancelled by Escape while dragging ('none' set by browser)
|
|
478
|
+
if (e.dataTransfer.dropEffect !== 'none' && dragState.shouldDrop(e.timeStamp)) {
|
|
479
|
+
|
|
480
|
+
const dropTargetList = findComposedAncestor(dragState.dropTarget, node => node.tagName === 'D2L-LIST');
|
|
481
|
+
const shouldDispatchPositionChange = !dragState.dragTargets.find(dragTarget => {
|
|
482
|
+
const dragTargetList = findComposedAncestor(dragTarget, node => node.tagName === 'D2L-LIST');
|
|
483
|
+
return dragTargetList !== dropTargetList;
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
if (shouldDispatchPositionChange && dragState.dragTargets.length === 1) {
|
|
487
|
+
this._annoucePositionChange(dragState.dragTargets[0].key, dragState.dropTargetKey, dragState.dropLocation);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
this._dispatchListItemsMove(dragState.dragTargets, dragState.dropTarget, dragState.dropLocation, false);
|
|
491
|
+
|
|
387
492
|
}
|
|
493
|
+
|
|
388
494
|
clearDragState();
|
|
389
495
|
}
|
|
390
496
|
|
|
@@ -399,15 +505,31 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
399
505
|
break;
|
|
400
506
|
case dragActions.up:
|
|
401
507
|
this._annoucePositionChange(this.key, null, dropLocation.shiftUp);
|
|
508
|
+
this._dispatchMoveListItemPrevious();
|
|
402
509
|
break;
|
|
403
510
|
case dragActions.down:
|
|
404
511
|
this._annoucePositionChange(this.key, null, dropLocation.shiftDown);
|
|
512
|
+
this._dispatchMoveListItemNext();
|
|
513
|
+
break;
|
|
514
|
+
case dragActions.nest:
|
|
515
|
+
this._dispatchMoveListItemNest();
|
|
516
|
+
break;
|
|
517
|
+
case dragActions.unnest:
|
|
518
|
+
this._dispatchMoveListItemUnnest();
|
|
405
519
|
break;
|
|
406
520
|
case dragActions.first:
|
|
407
521
|
this._annoucePositionChange(this.key, null, dropLocation.first);
|
|
522
|
+
this._dispatchMoveListItemFirst();
|
|
523
|
+
break;
|
|
524
|
+
case dragActions.rootFirst:
|
|
525
|
+
this._dispatchMoveListItemFirst(true);
|
|
408
526
|
break;
|
|
409
527
|
case dragActions.last:
|
|
410
528
|
this._annoucePositionChange(this.key, null, dropLocation.last);
|
|
529
|
+
this._dispatchMoveListItemLast();
|
|
530
|
+
break;
|
|
531
|
+
case dragActions.rootLast:
|
|
532
|
+
this._dispatchMoveListItemLast(true);
|
|
411
533
|
break;
|
|
412
534
|
default:
|
|
413
535
|
break;
|
|
@@ -427,13 +549,32 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
427
549
|
e.dataTransfer.setData('text/plain', `${this.dropText}`);
|
|
428
550
|
}
|
|
429
551
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
}
|
|
552
|
+
const nodeImage = this.shadowRoot.querySelector('.d2l-list-item-drag-image') || this;
|
|
553
|
+
e.dataTransfer.setDragImage(nodeImage, 50, 50);
|
|
554
|
+
|
|
555
|
+
const rootList = this._getRootList(this);
|
|
435
556
|
|
|
436
|
-
|
|
557
|
+
// getSelectionInfo(false) is fast so we can quickly check the state
|
|
558
|
+
if (!rootList.dragMultiple || rootList.getSelectionInfo(false).state === SelectionInfo.states.none) {
|
|
559
|
+
createDragState([this]);
|
|
560
|
+
} else {
|
|
561
|
+
|
|
562
|
+
// get the seelcted items, but do not include selected items of selected items
|
|
563
|
+
const getDragTargets = list => {
|
|
564
|
+
let dragTargets = [];
|
|
565
|
+
list.getItems().forEach(item => {
|
|
566
|
+
if (item.selected || item === this) {
|
|
567
|
+
dragTargets.push(item);
|
|
568
|
+
} else if (item._selectionProvider) {
|
|
569
|
+
dragTargets = [...dragTargets, ...getDragTargets(item._selectionProvider)];
|
|
570
|
+
}
|
|
571
|
+
});
|
|
572
|
+
return dragTargets;
|
|
573
|
+
};
|
|
574
|
+
const dragTargets = getDragTargets(rootList);
|
|
575
|
+
|
|
576
|
+
createDragState(dragTargets);
|
|
577
|
+
}
|
|
437
578
|
|
|
438
579
|
setTimeout(() => {
|
|
439
580
|
this.dragging = true;
|
|
@@ -461,35 +602,47 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
461
602
|
dragState.setActiveDropTarget(this, dragState.dropLocation);
|
|
462
603
|
}
|
|
463
604
|
|
|
464
|
-
|
|
605
|
+
_onDropTargetBottomDragEnter(e) {
|
|
465
606
|
e.dataTransfer.dropEffect = 'move';
|
|
466
607
|
const dragState = getDragState();
|
|
467
608
|
dragState.setActiveDropTarget(this, dropLocation.below);
|
|
468
609
|
this._inBottomArea = true;
|
|
469
610
|
}
|
|
470
611
|
|
|
471
|
-
_onDropTargetDragEnter(e) {
|
|
472
|
-
e.dataTransfer.dropEffect = 'move';
|
|
473
|
-
const dragState = getDragState();
|
|
474
|
-
dragState.setActiveDropTarget(this, dropLocation.above);
|
|
475
|
-
this._inTopArea = true;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
612
|
_onDropTargetLowerDragEnter(e) {
|
|
479
613
|
e.dataTransfer.dropEffect = 'move';
|
|
480
|
-
if (this.
|
|
481
|
-
const dragState = getDragState();
|
|
482
|
-
dragState.setActiveDropTarget(this, dropLocation.above);
|
|
614
|
+
if (this.dropNested) {
|
|
483
615
|
this._inBottomArea = false;
|
|
616
|
+
const dragState = getDragState();
|
|
617
|
+
dragState.setActiveDropTarget(this, moveLocations.nest);
|
|
618
|
+
} else {
|
|
619
|
+
if (this._inBottomArea) {
|
|
620
|
+
const dragState = getDragState();
|
|
621
|
+
dragState.setActiveDropTarget(this, dropLocation.above);
|
|
622
|
+
this._inBottomArea = false;
|
|
623
|
+
}
|
|
484
624
|
}
|
|
485
625
|
}
|
|
486
626
|
|
|
627
|
+
_onDropTargetTopDragEnter(e) {
|
|
628
|
+
e.dataTransfer.dropEffect = 'move';
|
|
629
|
+
const dragState = getDragState();
|
|
630
|
+
dragState.setActiveDropTarget(this, dropLocation.above);
|
|
631
|
+
this._inTopArea = true;
|
|
632
|
+
}
|
|
633
|
+
|
|
487
634
|
_onDropTargetUpperDragEnter(e) {
|
|
488
635
|
e.dataTransfer.dropEffect = 'move';
|
|
489
|
-
if (this.
|
|
490
|
-
const dragState = getDragState();
|
|
491
|
-
dragState.setActiveDropTarget(this, dropLocation.below);
|
|
636
|
+
if (this.dropNested) {
|
|
492
637
|
this._inTopArea = false;
|
|
638
|
+
const dragState = getDragState();
|
|
639
|
+
dragState.setActiveDropTarget(this, moveLocations.nest);
|
|
640
|
+
} else {
|
|
641
|
+
if (this._inTopArea) {
|
|
642
|
+
const dragState = getDragState();
|
|
643
|
+
dragState.setActiveDropTarget(this, dropLocation.below);
|
|
644
|
+
this._inTopArea = false;
|
|
645
|
+
}
|
|
493
646
|
}
|
|
494
647
|
}
|
|
495
648
|
|
|
@@ -504,9 +657,14 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
504
657
|
|
|
505
658
|
_onHostDragEnter(e) {
|
|
506
659
|
const dragState = getDragState();
|
|
507
|
-
if (this === dragState.dragTarget)
|
|
508
|
-
|
|
509
|
-
|
|
660
|
+
if (this === dragState.dragTarget) return;
|
|
661
|
+
|
|
662
|
+
// check if any of the drag targets are ancestors of the drop target
|
|
663
|
+
const invalidDropTarget = dragState.dragTargets.find(dragTarget => {
|
|
664
|
+
return isComposedAncestor(dragTarget, this);
|
|
665
|
+
});
|
|
666
|
+
if (invalidDropTarget) return;
|
|
667
|
+
|
|
510
668
|
dragState.addDropTarget(this);
|
|
511
669
|
this._draggingOver = true;
|
|
512
670
|
e.dataTransfer.dropEffect = 'move';
|
|
@@ -635,11 +793,11 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
635
793
|
_renderDropTarget(templateMethod) {
|
|
636
794
|
templateMethod = templateMethod || (DropTarget => DropTarget);
|
|
637
795
|
return this.draggable && this._draggingOver ? templateMethod(html`
|
|
638
|
-
<div class="d2l-list-item-drag-drop-grid" @drop="${this._onDrop}" @dragover="${this._onDragOver}">
|
|
639
|
-
<div @dragenter="${this.
|
|
796
|
+
<div class="d2l-list-item-drag-drop-grid" slot="drop-target" @drop="${this._onDrop}" @dragover="${this._onDragOver}">
|
|
797
|
+
<div @dragenter="${this._onDropTargetTopDragEnter}"></div>
|
|
640
798
|
<div @dragenter="${this._onDropTargetUpperDragEnter}"></div>
|
|
641
799
|
<div @dragenter="${this._onDropTargetLowerDragEnter}"></div>
|
|
642
|
-
<div @dragenter="${this.
|
|
800
|
+
<div @dragenter="${this._onDropTargetBottomDragEnter}"></div>
|
|
643
801
|
</div>
|
|
644
802
|
`) : nothing;
|
|
645
803
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import '../button/button-icon.js';
|
|
3
2
|
import '../icons/icon.js';
|
|
4
3
|
import { css, html, LitElement } from 'lit-element/lit-element.js';
|
|
@@ -6,6 +5,7 @@ import { buttonStyles } from '../button/button-styles.js';
|
|
|
6
5
|
import { findComposedAncestor } from '../../helpers/dom.js';
|
|
7
6
|
import { getFirstFocusableDescendant } from '../../helpers/focus.js';
|
|
8
7
|
import { LocalizeCoreElement } from '../../lang/localize-core-element.js';
|
|
8
|
+
import { RtlMixin } from '../../mixins/rtl-mixin.js';
|
|
9
9
|
|
|
10
10
|
const keyCodes = Object.freeze({
|
|
11
11
|
DOWN: 40,
|
|
@@ -26,16 +26,20 @@ export const dragActions = Object.freeze({
|
|
|
26
26
|
down: 'down',
|
|
27
27
|
first: 'first',
|
|
28
28
|
last: 'last',
|
|
29
|
+
nest: 'nest',
|
|
29
30
|
nextElement: 'next-element',
|
|
30
31
|
previousElement: 'previous-element',
|
|
32
|
+
rootFirst: 'rootFirst',
|
|
33
|
+
rootLast: 'rootLast',
|
|
31
34
|
save: 'keyboard-deactivate-save',
|
|
35
|
+
unnest: 'unnest',
|
|
32
36
|
up: 'up'
|
|
33
37
|
});
|
|
34
38
|
|
|
35
39
|
/**
|
|
36
40
|
* @fires d2l-list-item-drag-handle-action - Dispatched when an action performed on the drag handle
|
|
37
41
|
*/
|
|
38
|
-
class ListItemDragHandle extends LocalizeCoreElement(LitElement) {
|
|
42
|
+
class ListItemDragHandle extends LocalizeCoreElement(RtlMixin(LitElement)) {
|
|
39
43
|
|
|
40
44
|
static get properties() {
|
|
41
45
|
return {
|
|
@@ -176,11 +180,11 @@ class ListItemDragHandle extends LocalizeCoreElement(LitElement) {
|
|
|
176
180
|
break;
|
|
177
181
|
case keyCodes.HOME:
|
|
178
182
|
this._movingElement = true;
|
|
179
|
-
action = dragActions.first;
|
|
183
|
+
action = (e.ctrlKey ? dragActions.rootFirst : dragActions.first);
|
|
180
184
|
break;
|
|
181
185
|
case keyCodes.END:
|
|
182
186
|
this._movingElement = true;
|
|
183
|
-
action = dragActions.last;
|
|
187
|
+
action = (e.ctrlKey ? dragActions.rootLast : dragActions.last);
|
|
184
188
|
break;
|
|
185
189
|
case keyCodes.TAB:
|
|
186
190
|
action = e.shiftKey ? dragActions.previousElement : dragActions.nextElement;
|
|
@@ -189,9 +193,16 @@ class ListItemDragHandle extends LocalizeCoreElement(LitElement) {
|
|
|
189
193
|
action = dragActions.cancel;
|
|
190
194
|
this.updateComplete.then(() => this._keyboardActive = false);
|
|
191
195
|
break;
|
|
196
|
+
case keyCodes.RIGHT:
|
|
197
|
+
this._movingElement = true;
|
|
198
|
+
action = (this.dir === 'rtl' ? dragActions.unnest : dragActions.nest);
|
|
199
|
+
break;
|
|
200
|
+
case keyCodes.LEFT:
|
|
201
|
+
this._movingElement = true;
|
|
202
|
+
action = (this.dir === 'rtl' ? dragActions.nest : dragActions.unnest) ;
|
|
203
|
+
break;
|
|
192
204
|
case keyCodes.ENTER:
|
|
193
205
|
case keyCodes.SPACE:
|
|
194
|
-
case keyCodes.RIGHT:
|
|
195
206
|
action = dragActions.save;
|
|
196
207
|
this.updateComplete.then(() => this._keyboardActive = false);
|
|
197
208
|
break;
|
|
@@ -221,7 +232,7 @@ class ListItemDragHandle extends LocalizeCoreElement(LitElement) {
|
|
|
221
232
|
}
|
|
222
233
|
|
|
223
234
|
_onInactiveKeyboard(e) {
|
|
224
|
-
if (e.type === 'click' || e.keyCode === keyCodes.ENTER || e.keyCode === keyCodes.SPACE
|
|
235
|
+
if (e.type === 'click' || e.keyCode === keyCodes.ENTER || e.keyCode === keyCodes.SPACE) {
|
|
225
236
|
this._dispatchAction(dragActions.active);
|
|
226
237
|
this._keyboardActive = true;
|
|
227
238
|
e.preventDefault();
|
|
@@ -229,7 +240,7 @@ class ListItemDragHandle extends LocalizeCoreElement(LitElement) {
|
|
|
229
240
|
}
|
|
230
241
|
|
|
231
242
|
_onInactiveKeyDown(e) {
|
|
232
|
-
if (e.type === 'click' || e.keyCode === keyCodes.ENTER || e.keyCode === keyCodes.SPACE
|
|
243
|
+
if (e.type === 'click' || e.keyCode === keyCodes.ENTER || e.keyCode === keyCodes.SPACE) {
|
|
233
244
|
e.preventDefault();
|
|
234
245
|
}
|
|
235
246
|
}
|
|
@@ -67,6 +67,17 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
|
|
|
67
67
|
grid-column: content-start / end;
|
|
68
68
|
grid-row: nested-start / nested-end;
|
|
69
69
|
}
|
|
70
|
+
:host(.d2l-dragging-over) ::slotted([slot="nested"]) {
|
|
71
|
+
z-index: 6;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
::slotted([slot="drop-target"]) {
|
|
75
|
+
height: 100%;
|
|
76
|
+
position: absolute;
|
|
77
|
+
top: 0;
|
|
78
|
+
width: 100%;
|
|
79
|
+
z-index: 5;
|
|
80
|
+
}
|
|
70
81
|
|
|
71
82
|
::slotted([slot="outside-control"]),
|
|
72
83
|
::slotted([slot="control"]),
|
|
@@ -115,7 +126,6 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
|
|
|
115
126
|
grid-column: content-start / end;
|
|
116
127
|
z-index: 3;
|
|
117
128
|
}
|
|
118
|
-
|
|
119
129
|
`;
|
|
120
130
|
}
|
|
121
131
|
|
|
@@ -148,6 +158,7 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
|
|
|
148
158
|
|
|
149
159
|
render() {
|
|
150
160
|
return html`
|
|
161
|
+
<slot name="drop-target"></slot>
|
|
151
162
|
<slot name="content-action" class="d2l-cell" data-cell-num="5"></slot>
|
|
152
163
|
<slot name="outside-control-action" class="d2l-cell" data-cell-num="1"></slot>
|
|
153
164
|
<slot name="outside-control" class="d2l-cell" data-cell-num="2"></slot>
|
|
@@ -2,6 +2,7 @@ import '../colors/colors.js';
|
|
|
2
2
|
import './list-item-generic-layout.js';
|
|
3
3
|
import './list-item-placement-marker.js';
|
|
4
4
|
import { css, html } from 'lit-element/lit-element.js';
|
|
5
|
+
import { findComposedAncestor, getComposedParent } from '../../helpers/dom.js';
|
|
5
6
|
import { classMap } from 'lit-html/directives/class-map.js';
|
|
6
7
|
import { getFirstFocusableDescendant } from '../../helpers/focus.js';
|
|
7
8
|
import { getUniqueId } from '../../helpers/uniqueId.js';
|
|
@@ -301,6 +302,52 @@ export const ListItemMixin = superclass => class extends ListItemDragDropMixin(L
|
|
|
301
302
|
});
|
|
302
303
|
}
|
|
303
304
|
|
|
305
|
+
_getNestedList() {
|
|
306
|
+
const nestedSlot = this.shadowRoot.querySelector('slot[name="nested"]');
|
|
307
|
+
let nestedNodes = nestedSlot.assignedNodes();
|
|
308
|
+
if (nestedNodes.length === 0) {
|
|
309
|
+
nestedNodes = [...nestedSlot.childNodes];
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return nestedNodes.find(node => (node.nodeType === Node.ELEMENT_NODE && node.tagName === 'D2L-LIST'));
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
_getNextListItemSibling() {
|
|
316
|
+
let nextElement = this.nextElementSibling;
|
|
317
|
+
while (nextElement) {
|
|
318
|
+
if (this._isListItem(nextElement)) return nextElement;
|
|
319
|
+
nextElement = nextElement.nextElementSibling;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
_getParentListItem() {
|
|
324
|
+
const parentListItem = findComposedAncestor(this.parentNode, node => this._isListItem(node));
|
|
325
|
+
return parentListItem;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
_getPreviousListItemSibling() {
|
|
329
|
+
let previousElement = this.previousElementSibling;
|
|
330
|
+
while (previousElement) {
|
|
331
|
+
if (this._isListItem(previousElement)) return previousElement;
|
|
332
|
+
previousElement = previousElement.previousElementSibling;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
_getRootList(node) {
|
|
337
|
+
if (!node) node = this;
|
|
338
|
+
let rootList;
|
|
339
|
+
while (node) {
|
|
340
|
+
if (node.tagName === 'D2L-LIST') rootList = node;
|
|
341
|
+
node = getComposedParent(node);
|
|
342
|
+
}
|
|
343
|
+
return rootList;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
_isListItem(node) {
|
|
347
|
+
if (!node) node = this;
|
|
348
|
+
return node.role === 'rowgroup' || node.role === 'listitem';
|
|
349
|
+
}
|
|
350
|
+
|
|
304
351
|
_onFocusIn() {
|
|
305
352
|
this._focusing = true;
|
|
306
353
|
}
|
|
@@ -341,18 +388,18 @@ export const ListItemMixin = superclass => class extends ListItemDragDropMixin(L
|
|
|
341
388
|
'd2l-list-item-content-extend-separators': this._extendSeparators,
|
|
342
389
|
'd2l-focusing': this._focusing,
|
|
343
390
|
'd2l-hovering': this._hovering,
|
|
391
|
+
'd2l-dragging-over': this._draggingOver
|
|
344
392
|
};
|
|
345
393
|
const contentClasses = {
|
|
346
394
|
'd2l-list-item-content': true,
|
|
347
395
|
'd2l-hovering': this._hoveringPrimaryAction,
|
|
348
|
-
'd2l-focusing': this._focusingPrimaryAction
|
|
396
|
+
'd2l-focusing': this._focusingPrimaryAction
|
|
349
397
|
};
|
|
350
398
|
|
|
351
399
|
const primaryAction = this._renderPrimaryAction ? this._renderPrimaryAction(this._contentId) : null;
|
|
352
400
|
|
|
353
401
|
return html`
|
|
354
402
|
${this._renderTopPlacementMarker(html`<d2l-list-item-placement-marker></d2l-list-item-placement-marker>`)}
|
|
355
|
-
${this._renderDropTarget()}
|
|
356
403
|
<div class="d2l-list-item-drag-image">
|
|
357
404
|
<d2l-list-item-generic-layout
|
|
358
405
|
@focusin="${this._onFocusIn}"
|
|
@@ -361,6 +408,7 @@ export const ListItemMixin = superclass => class extends ListItemDragDropMixin(L
|
|
|
361
408
|
data-breakpoint="${this._breakpoint}"
|
|
362
409
|
data-separators="${ifDefined(this._separators)}"
|
|
363
410
|
?grid-active="${this.role === 'rowgroup'}">
|
|
411
|
+
${this._renderDropTarget()}
|
|
364
412
|
${this._renderDragHandle(this._renderOutsideControl)}
|
|
365
413
|
${this._renderDragTarget(this._renderOutsideControlAction)}
|
|
366
414
|
${this.selectable ? html`
|
|
@@ -391,7 +439,7 @@ export const ListItemMixin = superclass => class extends ListItemDragDropMixin(L
|
|
|
391
439
|
<slot name="actions" class="d2l-list-item-actions">${actions}</slot>
|
|
392
440
|
</div>
|
|
393
441
|
<div slot="nested" @d2l-selection-provider-connected="${this._onSelectionProviderConnected}">
|
|
394
|
-
<slot name="nested">${nested}</slot>
|
|
442
|
+
<slot name="nested" @slotchange="${this._onNestedSlotChange}">${nested}</slot>
|
|
395
443
|
</div>
|
|
396
444
|
</d2l-list-item-generic-layout>
|
|
397
445
|
<div class="d2l-list-item-active-border"></div>
|
package/components/list/list.js
CHANGED
|
@@ -16,6 +16,11 @@ class List extends SelectionMixin(LitElement) {
|
|
|
16
16
|
|
|
17
17
|
static get properties() {
|
|
18
18
|
return {
|
|
19
|
+
/**
|
|
20
|
+
* Whether to the user can drag multiple items
|
|
21
|
+
* @type {boolean}
|
|
22
|
+
*/
|
|
23
|
+
dragMultiple: { type: Boolean, attribute: 'drag-multiple' },
|
|
19
24
|
/**
|
|
20
25
|
* Whether to extend the separators beyond the content's edge
|
|
21
26
|
* @type {boolean}
|
|
@@ -48,6 +53,7 @@ class List extends SelectionMixin(LitElement) {
|
|
|
48
53
|
|
|
49
54
|
constructor() {
|
|
50
55
|
super();
|
|
56
|
+
this.dragMultiple = false;
|
|
51
57
|
this.extendSeparators = false;
|
|
52
58
|
this.grid = false;
|
|
53
59
|
this._listItemChanges = [];
|
|
@@ -91,17 +97,37 @@ class List extends SelectionMixin(LitElement) {
|
|
|
91
97
|
`;
|
|
92
98
|
}
|
|
93
99
|
|
|
100
|
+
getItems() {
|
|
101
|
+
const slot = this.shadowRoot.querySelector('slot:not([name])');
|
|
102
|
+
if (!slot) return [];
|
|
103
|
+
return slot.assignedNodes({ flatten: true }).filter((node) => {
|
|
104
|
+
return node.nodeType === Node.ELEMENT_NODE && (node.role === 'rowgroup' || node.role === 'listitem');
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
getListItemByKey(key) {
|
|
109
|
+
const items = this.getItems();
|
|
110
|
+
for (let i = 0; i < items.length; i++) {
|
|
111
|
+
if (items[i].key === key) return items[i];
|
|
112
|
+
if (items[i]._selectionProvider) {
|
|
113
|
+
const tempItem = items[i]._selectionProvider.getListItemByKey(key);
|
|
114
|
+
if (tempItem) return tempItem;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
|
|
94
120
|
getListItemCount() {
|
|
95
|
-
return this.
|
|
121
|
+
return this.getItems().length;
|
|
96
122
|
}
|
|
97
123
|
|
|
98
124
|
getListItemIndex(item) {
|
|
99
|
-
return this.
|
|
125
|
+
return this.getItems().indexOf(item);
|
|
100
126
|
}
|
|
101
127
|
|
|
102
128
|
getSelectedListItems(includeNested) {
|
|
103
129
|
let selectedItems = [];
|
|
104
|
-
this.
|
|
130
|
+
this.getItems().forEach(item => {
|
|
105
131
|
if (item.selected) selectedItems.push(item);
|
|
106
132
|
if (includeNested && item._selectionProvider) {
|
|
107
133
|
selectedItems = [...selectedItems, ...item._selectionProvider.getSelectedListItems(includeNested)];
|
|
@@ -116,7 +142,7 @@ class List extends SelectionMixin(LitElement) {
|
|
|
116
142
|
|
|
117
143
|
let keys = selectionInfo.keys;
|
|
118
144
|
|
|
119
|
-
this.
|
|
145
|
+
this.getItems().forEach(item => {
|
|
120
146
|
if (item._selectionProvider) {
|
|
121
147
|
keys = [...keys, ...item._selectionProvider.getSelectionInfo(true).keys];
|
|
122
148
|
}
|
|
@@ -125,14 +151,6 @@ class List extends SelectionMixin(LitElement) {
|
|
|
125
151
|
return new SelectionInfo(keys, selectionInfo.state);
|
|
126
152
|
}
|
|
127
153
|
|
|
128
|
-
_getItems() {
|
|
129
|
-
const slot = this.shadowRoot.querySelector('slot:not([name])');
|
|
130
|
-
if (!slot) return [];
|
|
131
|
-
return slot.assignedNodes({ flatten: true }).filter((node) => {
|
|
132
|
-
return node.nodeType === Node.ELEMENT_NODE && (node.role === 'listitem' || node.tagName.includes('LIST-ITEM'));
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
154
|
_handleKeyDown(e) {
|
|
137
155
|
if (!this.grid || this.slot === 'nested' || e.keyCode !== keyCodes.TAB) return;
|
|
138
156
|
e.preventDefault();
|
package/custom-elements.json
CHANGED
|
@@ -6208,8 +6208,8 @@
|
|
|
6208
6208
|
]
|
|
6209
6209
|
},
|
|
6210
6210
|
{
|
|
6211
|
-
"name": "d2l-list-
|
|
6212
|
-
"path": "./components/list/demo/list-
|
|
6211
|
+
"name": "d2l-demo-list-drag-and-drop-position",
|
|
6212
|
+
"path": "./components/list/demo/list-drag-and-drop-position.js",
|
|
6213
6213
|
"attributes": [
|
|
6214
6214
|
{
|
|
6215
6215
|
"name": "grid",
|
|
@@ -6253,6 +6253,25 @@
|
|
|
6253
6253
|
}
|
|
6254
6254
|
]
|
|
6255
6255
|
},
|
|
6256
|
+
{
|
|
6257
|
+
"name": "d2l-demo-list-drag-and-drop",
|
|
6258
|
+
"path": "./components/list/demo/list-drag-and-drop.js",
|
|
6259
|
+
"attributes": [
|
|
6260
|
+
{
|
|
6261
|
+
"name": "items",
|
|
6262
|
+
"type": "array",
|
|
6263
|
+
"default": "[{\"key\":\"1\",\"primaryText\":\"Introductory Earth Sciences\",\"supportingText\":\"This course explores the geological processes of the Earth's interior and surface. These include volcanism, earthquakes, mountain building, glaciation and weathering.\",\"imgSrc\":\"https://s.brightspace.com/course-images/images/63b162ab-b582-4bf9-8c1d-1dad04714121/tile-high-density-max-size.jpg\",\"items\":[{\"key\":\"1-1\",\"primaryText\":\"Glaciation\",\"supportingText\":\"Supporting Info\",\"imgSrc\":\"\",\"items\":[]},{\"key\":\"1-2\",\"primaryText\":\"Weathering\",\"supportingText\":\"Supporting Info\",\"imgSrc\":\"\",\"items\":[]},{\"key\":\"1-3\",\"primaryText\":\"Volcanism\",\"supportingText\":\"Supporting Info\",\"imgSrc\":\"\",\"items\":[]}]},{\"key\":\"2\",\"primaryText\":\"Flow and Transport Through Fractured Rocks\",\"supportingText\":\"Fractures are ubiquitous in geologic media and important in disciplines such as physical and contaminant hydrogeology, geotechnical engineering, civil and environmental engineering, petroleum engineering among other areas.\",\"imgSrc\":\"https://s.brightspace.com/course-images/images/e5fd575a-bc14-4a80-89e1-46f349a76178/tile-high-density-max-size.jpg\",\"items\":[{\"key\":\"2-1\",\"primaryText\":\"Contaminant Transport\",\"supportingText\":\"Supporting Info\",\"imgSrc\":\"\",\"items\":[]},{\"key\":\"2-2\",\"primaryText\":\"Modelling Flow in Fractured Media\",\"supportingText\":\"Supporting Info\",\"imgSrc\":\"\",\"items\":[]}]},{\"key\":\"3\",\"primaryText\":\"Applied Wetland Science\",\"supportingText\":\"Advanced concepts on wetland ecosystems in the context of regional and global earth systems processes such as carbon and nitrogen cycling and climate change, applications of wetland paleoecology, use of isotopes and other geochemical tools in wetland science, and wetland engineering in landscape rehabilitation and ecotechnology.\",\"imgSrc\":\"https://s.brightspace.com/course-images/images/38e839b1-37fa-470c-8830-b189ce4ae134/tile-high-density-max-size.jpg\",\"items\":[{\"key\":\"3-1\",\"primaryText\":\"Carbon & Nitrogen Cycling\",\"supportingText\":\"Supporting Info\",\"imgSrc\":\"\",\"items\":[]},{\"key\":\"3-2\",\"primaryText\":\"Wetland Engineering\",\"supportingText\":\"Supporting Info\",\"imgSrc\":\"\",\"items\":[]}]}]"
|
|
6264
|
+
}
|
|
6265
|
+
],
|
|
6266
|
+
"properties": [
|
|
6267
|
+
{
|
|
6268
|
+
"name": "items",
|
|
6269
|
+
"attribute": "items",
|
|
6270
|
+
"type": "array",
|
|
6271
|
+
"default": "[{\"key\":\"1\",\"primaryText\":\"Introductory Earth Sciences\",\"supportingText\":\"This course explores the geological processes of the Earth's interior and surface. These include volcanism, earthquakes, mountain building, glaciation and weathering.\",\"imgSrc\":\"https://s.brightspace.com/course-images/images/63b162ab-b582-4bf9-8c1d-1dad04714121/tile-high-density-max-size.jpg\",\"items\":[{\"key\":\"1-1\",\"primaryText\":\"Glaciation\",\"supportingText\":\"Supporting Info\",\"imgSrc\":\"\",\"items\":[]},{\"key\":\"1-2\",\"primaryText\":\"Weathering\",\"supportingText\":\"Supporting Info\",\"imgSrc\":\"\",\"items\":[]},{\"key\":\"1-3\",\"primaryText\":\"Volcanism\",\"supportingText\":\"Supporting Info\",\"imgSrc\":\"\",\"items\":[]}]},{\"key\":\"2\",\"primaryText\":\"Flow and Transport Through Fractured Rocks\",\"supportingText\":\"Fractures are ubiquitous in geologic media and important in disciplines such as physical and contaminant hydrogeology, geotechnical engineering, civil and environmental engineering, petroleum engineering among other areas.\",\"imgSrc\":\"https://s.brightspace.com/course-images/images/e5fd575a-bc14-4a80-89e1-46f349a76178/tile-high-density-max-size.jpg\",\"items\":[{\"key\":\"2-1\",\"primaryText\":\"Contaminant Transport\",\"supportingText\":\"Supporting Info\",\"imgSrc\":\"\",\"items\":[]},{\"key\":\"2-2\",\"primaryText\":\"Modelling Flow in Fractured Media\",\"supportingText\":\"Supporting Info\",\"imgSrc\":\"\",\"items\":[]}]},{\"key\":\"3\",\"primaryText\":\"Applied Wetland Science\",\"supportingText\":\"Advanced concepts on wetland ecosystems in the context of regional and global earth systems processes such as carbon and nitrogen cycling and climate change, applications of wetland paleoecology, use of isotopes and other geochemical tools in wetland science, and wetland engineering in landscape rehabilitation and ecotechnology.\",\"imgSrc\":\"https://s.brightspace.com/course-images/images/38e839b1-37fa-470c-8830-b189ce4ae134/tile-high-density-max-size.jpg\",\"items\":[{\"key\":\"3-1\",\"primaryText\":\"Carbon & Nitrogen Cycling\",\"supportingText\":\"Supporting Info\",\"imgSrc\":\"\",\"items\":[]},{\"key\":\"3-2\",\"primaryText\":\"Wetland Engineering\",\"supportingText\":\"Supporting Info\",\"imgSrc\":\"\",\"items\":[]}]}]"
|
|
6272
|
+
}
|
|
6273
|
+
]
|
|
6274
|
+
},
|
|
6256
6275
|
{
|
|
6257
6276
|
"name": "d2l-demo-list-item-custom",
|
|
6258
6277
|
"path": "./components/list/demo/list-item-custom.js",
|
|
@@ -6269,11 +6288,6 @@
|
|
|
6269
6288
|
"type": "boolean",
|
|
6270
6289
|
"default": "false"
|
|
6271
6290
|
},
|
|
6272
|
-
{
|
|
6273
|
-
"name": "draggable",
|
|
6274
|
-
"description": "**Drag & drop:** Whether the item is draggable",
|
|
6275
|
-
"type": "boolean"
|
|
6276
|
-
},
|
|
6277
6291
|
{
|
|
6278
6292
|
"name": "drag-handle-text",
|
|
6279
6293
|
"description": "**Drag & drop:** The drag-handle label for assistive technology. If implementing drag & drop, you should change this to dynamically announce what the drag-handle is moving for assistive technology in keyboard mode.",
|
|
@@ -6284,6 +6298,18 @@
|
|
|
6284
6298
|
"description": "**Drag & drop:** Text to drag and drop",
|
|
6285
6299
|
"type": "string"
|
|
6286
6300
|
},
|
|
6301
|
+
{
|
|
6302
|
+
"name": "draggable",
|
|
6303
|
+
"description": "**Drag & drop:** Whether the item is draggable",
|
|
6304
|
+
"type": "boolean",
|
|
6305
|
+
"default": "false"
|
|
6306
|
+
},
|
|
6307
|
+
{
|
|
6308
|
+
"name": "drop-nested",
|
|
6309
|
+
"description": "**Drag & drop:** Whether the items can be dropped as nested children",
|
|
6310
|
+
"type": "boolean",
|
|
6311
|
+
"default": "false"
|
|
6312
|
+
},
|
|
6287
6313
|
{
|
|
6288
6314
|
"name": "disabled",
|
|
6289
6315
|
"description": "**Selection:** Disables the input",
|
|
@@ -6338,12 +6364,6 @@
|
|
|
6338
6364
|
"type": "boolean",
|
|
6339
6365
|
"default": "false"
|
|
6340
6366
|
},
|
|
6341
|
-
{
|
|
6342
|
-
"name": "draggable",
|
|
6343
|
-
"attribute": "draggable",
|
|
6344
|
-
"description": "**Drag & drop:** Whether the item is draggable",
|
|
6345
|
-
"type": "boolean"
|
|
6346
|
-
},
|
|
6347
6367
|
{
|
|
6348
6368
|
"name": "dragHandleText",
|
|
6349
6369
|
"attribute": "drag-handle-text",
|
|
@@ -6356,6 +6376,20 @@
|
|
|
6356
6376
|
"description": "**Drag & drop:** Text to drag and drop",
|
|
6357
6377
|
"type": "string"
|
|
6358
6378
|
},
|
|
6379
|
+
{
|
|
6380
|
+
"name": "draggable",
|
|
6381
|
+
"attribute": "draggable",
|
|
6382
|
+
"description": "**Drag & drop:** Whether the item is draggable",
|
|
6383
|
+
"type": "boolean",
|
|
6384
|
+
"default": "false"
|
|
6385
|
+
},
|
|
6386
|
+
{
|
|
6387
|
+
"name": "dropNested",
|
|
6388
|
+
"attribute": "drop-nested",
|
|
6389
|
+
"description": "**Drag & drop:** Whether the items can be dropped as nested children",
|
|
6390
|
+
"type": "boolean",
|
|
6391
|
+
"default": "false"
|
|
6392
|
+
},
|
|
6359
6393
|
{
|
|
6360
6394
|
"name": "disabled",
|
|
6361
6395
|
"attribute": "disabled",
|
|
@@ -6415,6 +6449,9 @@
|
|
|
6415
6449
|
"name": "d2l-list-item-position-change",
|
|
6416
6450
|
"description": "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)."
|
|
6417
6451
|
},
|
|
6452
|
+
{
|
|
6453
|
+
"name": "d2l-list-items-move"
|
|
6454
|
+
},
|
|
6418
6455
|
{
|
|
6419
6456
|
"name": "d2l-list-item-selected",
|
|
6420
6457
|
"description": "Dispatched when the component item is selected"
|
|
@@ -6460,11 +6497,6 @@
|
|
|
6460
6497
|
"type": "boolean",
|
|
6461
6498
|
"default": "false"
|
|
6462
6499
|
},
|
|
6463
|
-
{
|
|
6464
|
-
"name": "draggable",
|
|
6465
|
-
"description": "**Drag & drop:** Whether the item is draggable",
|
|
6466
|
-
"type": "boolean"
|
|
6467
|
-
},
|
|
6468
6500
|
{
|
|
6469
6501
|
"name": "drag-handle-text",
|
|
6470
6502
|
"description": "**Drag & drop:** The drag-handle label for assistive technology. If implementing drag & drop, you should change this to dynamically announce what the drag-handle is moving for assistive technology in keyboard mode.",
|
|
@@ -6475,6 +6507,18 @@
|
|
|
6475
6507
|
"description": "**Drag & drop:** Text to drag and drop",
|
|
6476
6508
|
"type": "string"
|
|
6477
6509
|
},
|
|
6510
|
+
{
|
|
6511
|
+
"name": "draggable",
|
|
6512
|
+
"description": "**Drag & drop:** Whether the item is draggable",
|
|
6513
|
+
"type": "boolean",
|
|
6514
|
+
"default": "false"
|
|
6515
|
+
},
|
|
6516
|
+
{
|
|
6517
|
+
"name": "drop-nested",
|
|
6518
|
+
"description": "**Drag & drop:** Whether the items can be dropped as nested children",
|
|
6519
|
+
"type": "boolean",
|
|
6520
|
+
"default": "false"
|
|
6521
|
+
},
|
|
6478
6522
|
{
|
|
6479
6523
|
"name": "disabled",
|
|
6480
6524
|
"description": "**Selection:** Disables the input",
|
|
@@ -6528,12 +6572,6 @@
|
|
|
6528
6572
|
"type": "boolean",
|
|
6529
6573
|
"default": "false"
|
|
6530
6574
|
},
|
|
6531
|
-
{
|
|
6532
|
-
"name": "draggable",
|
|
6533
|
-
"attribute": "draggable",
|
|
6534
|
-
"description": "**Drag & drop:** Whether the item is draggable",
|
|
6535
|
-
"type": "boolean"
|
|
6536
|
-
},
|
|
6537
6575
|
{
|
|
6538
6576
|
"name": "dragHandleText",
|
|
6539
6577
|
"attribute": "drag-handle-text",
|
|
@@ -6546,6 +6584,20 @@
|
|
|
6546
6584
|
"description": "**Drag & drop:** Text to drag and drop",
|
|
6547
6585
|
"type": "string"
|
|
6548
6586
|
},
|
|
6587
|
+
{
|
|
6588
|
+
"name": "draggable",
|
|
6589
|
+
"attribute": "draggable",
|
|
6590
|
+
"description": "**Drag & drop:** Whether the item is draggable",
|
|
6591
|
+
"type": "boolean",
|
|
6592
|
+
"default": "false"
|
|
6593
|
+
},
|
|
6594
|
+
{
|
|
6595
|
+
"name": "dropNested",
|
|
6596
|
+
"attribute": "drop-nested",
|
|
6597
|
+
"description": "**Drag & drop:** Whether the items can be dropped as nested children",
|
|
6598
|
+
"type": "boolean",
|
|
6599
|
+
"default": "false"
|
|
6600
|
+
},
|
|
6549
6601
|
{
|
|
6550
6602
|
"name": "disabled",
|
|
6551
6603
|
"attribute": "disabled",
|
|
@@ -6608,6 +6660,9 @@
|
|
|
6608
6660
|
"name": "d2l-list-item-position-change",
|
|
6609
6661
|
"description": "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)."
|
|
6610
6662
|
},
|
|
6663
|
+
{
|
|
6664
|
+
"name": "d2l-list-items-move"
|
|
6665
|
+
},
|
|
6611
6666
|
{
|
|
6612
6667
|
"name": "d2l-list-item-selected",
|
|
6613
6668
|
"description": "Dispatched when the component item is selected"
|
|
@@ -6777,11 +6832,6 @@
|
|
|
6777
6832
|
"type": "boolean",
|
|
6778
6833
|
"default": "false"
|
|
6779
6834
|
},
|
|
6780
|
-
{
|
|
6781
|
-
"name": "draggable",
|
|
6782
|
-
"description": "**Drag & drop:** Whether the item is draggable",
|
|
6783
|
-
"type": "boolean"
|
|
6784
|
-
},
|
|
6785
6835
|
{
|
|
6786
6836
|
"name": "drag-handle-text",
|
|
6787
6837
|
"description": "**Drag & drop:** The drag-handle label for assistive technology. If implementing drag & drop, you should change this to dynamically announce what the drag-handle is moving for assistive technology in keyboard mode.",
|
|
@@ -6792,6 +6842,18 @@
|
|
|
6792
6842
|
"description": "**Drag & drop:** Text to drag and drop",
|
|
6793
6843
|
"type": "string"
|
|
6794
6844
|
},
|
|
6845
|
+
{
|
|
6846
|
+
"name": "draggable",
|
|
6847
|
+
"description": "**Drag & drop:** Whether the item is draggable",
|
|
6848
|
+
"type": "boolean",
|
|
6849
|
+
"default": "false"
|
|
6850
|
+
},
|
|
6851
|
+
{
|
|
6852
|
+
"name": "drop-nested",
|
|
6853
|
+
"description": "**Drag & drop:** Whether the items can be dropped as nested children",
|
|
6854
|
+
"type": "boolean",
|
|
6855
|
+
"default": "false"
|
|
6856
|
+
},
|
|
6795
6857
|
{
|
|
6796
6858
|
"name": "disabled",
|
|
6797
6859
|
"description": "**Selection:** Disables the input",
|
|
@@ -6857,12 +6919,6 @@
|
|
|
6857
6919
|
"type": "boolean",
|
|
6858
6920
|
"default": "false"
|
|
6859
6921
|
},
|
|
6860
|
-
{
|
|
6861
|
-
"name": "draggable",
|
|
6862
|
-
"attribute": "draggable",
|
|
6863
|
-
"description": "**Drag & drop:** Whether the item is draggable",
|
|
6864
|
-
"type": "boolean"
|
|
6865
|
-
},
|
|
6866
6922
|
{
|
|
6867
6923
|
"name": "dragHandleText",
|
|
6868
6924
|
"attribute": "drag-handle-text",
|
|
@@ -6875,6 +6931,20 @@
|
|
|
6875
6931
|
"description": "**Drag & drop:** Text to drag and drop",
|
|
6876
6932
|
"type": "string"
|
|
6877
6933
|
},
|
|
6934
|
+
{
|
|
6935
|
+
"name": "draggable",
|
|
6936
|
+
"attribute": "draggable",
|
|
6937
|
+
"description": "**Drag & drop:** Whether the item is draggable",
|
|
6938
|
+
"type": "boolean",
|
|
6939
|
+
"default": "false"
|
|
6940
|
+
},
|
|
6941
|
+
{
|
|
6942
|
+
"name": "dropNested",
|
|
6943
|
+
"attribute": "drop-nested",
|
|
6944
|
+
"description": "**Drag & drop:** Whether the items can be dropped as nested children",
|
|
6945
|
+
"type": "boolean",
|
|
6946
|
+
"default": "false"
|
|
6947
|
+
},
|
|
6878
6948
|
{
|
|
6879
6949
|
"name": "disabled",
|
|
6880
6950
|
"attribute": "disabled",
|
|
@@ -6937,6 +7007,9 @@
|
|
|
6937
7007
|
"name": "d2l-list-item-position-change",
|
|
6938
7008
|
"description": "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)."
|
|
6939
7009
|
},
|
|
7010
|
+
{
|
|
7011
|
+
"name": "d2l-list-items-move"
|
|
7012
|
+
},
|
|
6940
7013
|
{
|
|
6941
7014
|
"name": "d2l-list-item-selected",
|
|
6942
7015
|
"description": "Dispatched when the component item is selected"
|
|
@@ -6968,6 +7041,12 @@
|
|
|
6968
7041
|
"type": "'all'|'between'|'none'",
|
|
6969
7042
|
"default": "\"\\\"all\\\"\""
|
|
6970
7043
|
},
|
|
7044
|
+
{
|
|
7045
|
+
"name": "drag-multiple",
|
|
7046
|
+
"description": "Whether to the user can drag multiple items",
|
|
7047
|
+
"type": "boolean",
|
|
7048
|
+
"default": "false"
|
|
7049
|
+
},
|
|
6971
7050
|
{
|
|
6972
7051
|
"name": "extend-separators",
|
|
6973
7052
|
"description": "Whether to extend the separators beyond the content's edge",
|
|
@@ -6995,6 +7074,13 @@
|
|
|
6995
7074
|
"type": "'all'|'between'|'none'",
|
|
6996
7075
|
"default": "\"\\\"all\\\"\""
|
|
6997
7076
|
},
|
|
7077
|
+
{
|
|
7078
|
+
"name": "dragMultiple",
|
|
7079
|
+
"attribute": "drag-multiple",
|
|
7080
|
+
"description": "Whether to the user can drag multiple items",
|
|
7081
|
+
"type": "boolean",
|
|
7082
|
+
"default": "false"
|
|
7083
|
+
},
|
|
6998
7084
|
{
|
|
6999
7085
|
"name": "extendSeparators",
|
|
7000
7086
|
"attribute": "extend-separators",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brightspace-ui/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.211.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",
|