@brightspace-ui/core 1.210.1 → 1.213.1

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/README.md CHANGED
@@ -55,6 +55,8 @@ npm install @brightspace-ui/core
55
55
  * [Tooltip](components/tooltip/): tooltip components
56
56
  * [Typography](components/typography/): typography styles and components
57
57
  * [Validation](components/validation/): plugin custom validation logic to native and custom form elements
58
+ * Controllers
59
+ * [Subscriber](controllers/subscriber/): for managing a registry of subscribers in a many-to-many relationship
58
60
  * Directives
59
61
  * [Animate](directives/animate/): animate showing, hiding and removal of elements
60
62
  * Helpers
@@ -212,6 +212,25 @@ class Filter extends LocalizeCoreElement(RtlMixin(LitElement)) {
212
212
  `;
213
213
  }
214
214
 
215
+ focus() {
216
+ const opener = this.shadowRoot.querySelector('d2l-dropdown-button-subtle');
217
+ if (opener) opener.focus();
218
+ }
219
+
220
+ requestFilterClearAll() {
221
+ this._handleClearAll();
222
+ }
223
+
224
+ requestFilterValueClear(keyObject) {
225
+ const dimension = this._dimensions.find(dimension => dimension.key === keyObject.dimension);
226
+
227
+ switch (dimension.type) {
228
+ case 'd2l-filter-dimension-set':
229
+ this._performChangeSetDimension(dimension, keyObject.value, false);
230
+ break;
231
+ }
232
+ }
233
+
215
234
  _buildDimension(dimension, singleDimension) {
216
235
  let dimensionHTML;
217
236
  switch (dimension.type) {
@@ -433,20 +452,9 @@ class Filter extends LocalizeCoreElement(RtlMixin(LitElement)) {
433
452
  const dimensionKey = e.target.id.slice(SET_DIMENSION_ID_PREFIX.length);
434
453
  const dimension = this._dimensions.find(dimension => dimension.key === dimensionKey);
435
454
  const valueKey = e.detail.key;
436
- const value = dimension.values.find(value => value.key === valueKey);
437
455
  const selected = e.detail.selected;
438
456
 
439
- value.selected = selected;
440
-
441
- if (selected) {
442
- dimension.appliedCount++;
443
- this._totalAppliedCount++;
444
- } else {
445
- dimension.appliedCount--;
446
- this._totalAppliedCount--;
447
- }
448
-
449
- this._dispatchChangeEvent(dimension, { valueKey: valueKey, selected: selected });
457
+ this._performChangeSetDimension(dimension, valueKey, selected);
450
458
  }
451
459
 
452
460
  _handleClear() {
@@ -621,6 +629,22 @@ class Filter extends LocalizeCoreElement(RtlMixin(LitElement)) {
621
629
  return false;
622
630
  }
623
631
 
632
+ _performChangeSetDimension(dimension, valueKey, selected) {
633
+ const value = dimension.values.find(value => value.key === valueKey);
634
+ if (value.selected === selected) return;
635
+ value.selected = selected;
636
+
637
+ if (selected) {
638
+ dimension.appliedCount++;
639
+ this._totalAppliedCount++;
640
+ } else {
641
+ dimension.appliedCount--;
642
+ this._totalAppliedCount--;
643
+ }
644
+
645
+ this._dispatchChangeEvent(dimension, { valueKey: valueKey, selected: selected });
646
+ }
647
+
624
648
  _performDimensionClear(dimension) {
625
649
  this._totalAppliedCount = this._totalAppliedCount - dimension.appliedCount;
626
650
  dimension.appliedCount = 0;
@@ -1,6 +1,6 @@
1
1
  import '../colors/colors.js';
2
2
  import { css, LitElement } from 'lit-element/lit-element.js';
3
- import { HtmlAttributeObserverController } from '../../helpers/htmlAttributeObserverController.js';
3
+ import { HtmlAttributeObserverController } from '../../controllers/attributeObserver/htmlAttributeObserverController.js';
4
4
  import { HtmlBlockMathRenderer } from '../../helpers/mathjax.js';
5
5
  import { requestInstance } from '../../mixins/provider-mixin.js';
6
6
 
@@ -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 ListDemoDragAndDropUsage extends LitElement {
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-demo-drag-and-drop-usage', ListDemoDragAndDropUsage);
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-demo-drag-and-drop-usage.js';
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>Draggable</h2>
17
+ <h2>Position Change Event</h2>
17
18
 
18
19
  <d2l-demo-snippet>
19
20
  <template>
20
- <d2l-list-demo-drag-and-drop-usage></d2l-list-demo-drag-and-drop-usage>
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>Draggable and Selectable</h2>
25
+ <h2>Move Event</h2>
25
26
 
26
27
  <d2l-demo-snippet>
27
28
  <template>
28
- <d2l-list-demo-drag-and-drop-usage selectable></d2l-list-demo-drag-and-drop-usage>
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
- <d2l-demo-snippet>
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
- <d2l-demo-snippet>
43
- <template>
44
- <d2l-list-demo-drag-and-drop-usage grid selectable hrefs></d2l-list-demo-drag-and-drop-usage>
45
- </template>
46
- </d2l-demo-snippet>
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();