@brightspace-ui/core 1.227.0 → 1.230.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/README.md +2 -1
- package/components/list/demo/list.html +30 -5
- package/components/list/list-header.js +18 -2
- package/components/list/list-item-mixin.js +2 -2
- package/components/overflow-group/overflow-group.js +1 -0
- package/components/selection/README.md +39 -0
- package/components/selection/demo/selection.html +12 -0
- package/components/selection/selection-action-menu-item.js +61 -0
- package/components/selection/selection-action-mixin.js +30 -0
- package/components/selection/selection-action.js +2 -16
- package/components/selection/selection-input.js +1 -0
- package/components/selection/selection-mixin.js +24 -9
- package/components/selection/selection-select-all-pages.js +48 -0
- package/components/selection/selection-select-all.js +2 -2
- package/components/selection/selection-summary.js +5 -1
- package/custom-elements.json +208 -60
- package/lang/ar.js +17 -16
- package/lang/cy.js +17 -16
- package/lang/da.js +17 -16
- package/lang/de.js +17 -16
- package/lang/en.js +1 -0
- package/lang/es-es.js +17 -16
- package/lang/es.js +17 -16
- package/lang/fr-fr.js +17 -16
- package/lang/fr.js +17 -16
- package/lang/ja.js +17 -16
- package/lang/ko.js +17 -16
- package/lang/nl.js +17 -16
- package/lang/pt.js +17 -16
- package/lang/sv.js +17 -16
- package/lang/tr.js +17 -16
- package/lang/zh-tw.js +17 -16
- package/lang/zh.js +17 -16
- package/package.json +2 -2
|
@@ -311,7 +311,8 @@ The `d2l-list-header` component can be placed in the `d2l-list`'s `header` slot
|
|
|
311
311
|
|
|
312
312
|
| Property | Type | Description |
|
|
313
313
|
|---|---|---|
|
|
314
|
-
| `padding-type` | String | Header whitespace (`normal` (default), `slim`)|
|
|
314
|
+
| `padding-type` | String | Header whitespace (`normal` (default), `slim`) |
|
|
315
|
+
| `select-all-pages-allowed` | Boolean | Whether all pages can be selected |
|
|
315
316
|
<!-- docs: end hidden content -->
|
|
316
317
|
|
|
317
318
|
## List Item [d2l-list-item]
|
|
@@ -7,11 +7,13 @@
|
|
|
7
7
|
<script type="module">
|
|
8
8
|
import '../../button/button-icon.js';
|
|
9
9
|
import '../../demo/demo-page.js';
|
|
10
|
+
import '../../dropdown/dropdown-button-subtle.js';
|
|
10
11
|
import '../../dropdown/dropdown-menu.js';
|
|
11
12
|
import '../../dropdown/dropdown-more.js';
|
|
12
13
|
import '../../menu/menu.js';
|
|
13
14
|
import '../../menu/menu-item.js';
|
|
14
15
|
import '../../selection/selection-action.js';
|
|
16
|
+
import '../../selection/selection-action-menu-item.js';
|
|
15
17
|
import '../../tooltip/tooltip.js';
|
|
16
18
|
import '../list-header.js';
|
|
17
19
|
import '../list-item-button.js';
|
|
@@ -64,12 +66,18 @@
|
|
|
64
66
|
|
|
65
67
|
<d2l-demo-snippet>
|
|
66
68
|
<template>
|
|
67
|
-
<d2l-list>
|
|
68
|
-
<d2l-list-header slot="header">
|
|
69
|
-
<d2l-selection-action icon="tier1:
|
|
70
|
-
<d2l-selection-action icon="tier1:share" text="Share" requires-selection></d2l-selection-action>
|
|
71
|
-
<d2l-selection-action icon="tier1:bookmark-hollow" text="Bookmark" requires-selection></d2l-selection-action>
|
|
69
|
+
<d2l-list id="allFeatures" item-count="50">
|
|
70
|
+
<d2l-list-header slot="header" select-all-pages-allowed>
|
|
71
|
+
<d2l-selection-action icon="tier1:plus-default" text="Add"></d2l-selection-action>
|
|
72
72
|
<d2l-selection-action icon="tier1:delete" text="Delete" requires-selection></d2l-selection-action>
|
|
73
|
+
<d2l-dropdown-button-subtle text="Actions">
|
|
74
|
+
<d2l-dropdown-menu>
|
|
75
|
+
<d2l-menu label="Actions">
|
|
76
|
+
<d2l-selection-action-menu-item text="Bookmark (requires selection)" requires-selection></d2l-selection-action-menu-item>
|
|
77
|
+
<d2l-selection-action-menu-item text="Advanced"></d2l-selection-action-menu-item>
|
|
78
|
+
</d2l-menu>
|
|
79
|
+
</d2l-dropdown-menu>
|
|
80
|
+
</d2l-dropdown-button-subtle>
|
|
73
81
|
<d2l-selection-action icon="tier1:gear" text="Settings"></d2l-selection-action>
|
|
74
82
|
</d2l-list-header>
|
|
75
83
|
<d2l-list-item href="http://www.d2l.com" selectable key="1" label="Introductory Earth Sciences">
|
|
@@ -130,6 +138,23 @@
|
|
|
130
138
|
</div>
|
|
131
139
|
</d2l-list-item>
|
|
132
140
|
</d2l-list>
|
|
141
|
+
<script>
|
|
142
|
+
let newItemCount = 0;
|
|
143
|
+
document.querySelector('d2l-selection-action[text="Add"]').addEventListener('d2l-selection-action-click', () => {
|
|
144
|
+
const item = document.createElement('d2l-list-item');
|
|
145
|
+
item.selectable = true;
|
|
146
|
+
item.key = `${++newItemCount}`;
|
|
147
|
+
item.label = 'New Item';
|
|
148
|
+
item.innerHTML = `
|
|
149
|
+
<img slot="illustration" src="https://s.brightspace.com/course-images/images/38e839b1-37fa-470c-8830-b189ce4ae134/tile-high-density-max-size.jpg"></img>
|
|
150
|
+
<d2l-list-item-content>
|
|
151
|
+
<div>New Item ${newItemCount}</div>
|
|
152
|
+
<div slot="supporting-info">Supporting Info</div>
|
|
153
|
+
</d2l-list-item-content>
|
|
154
|
+
`;
|
|
155
|
+
document.querySelector('#allFeatures').appendChild(item);
|
|
156
|
+
});
|
|
157
|
+
</script>
|
|
133
158
|
</template>
|
|
134
159
|
</d2l-demo-snippet>
|
|
135
160
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import '../overflow-group/overflow-group.js';
|
|
2
2
|
import '../selection/selection-select-all.js';
|
|
3
|
+
import '../selection/selection-select-all-pages.js';
|
|
3
4
|
import '../selection/selection-summary.js';
|
|
4
5
|
import { css, html, LitElement } from 'lit-element/lit-element.js';
|
|
5
6
|
import { LocalizeCoreElement } from '../../lang/localize-core-element.js';
|
|
@@ -14,6 +15,7 @@ class ListHeader extends RtlMixin(LocalizeCoreElement(LitElement)) {
|
|
|
14
15
|
static get properties() {
|
|
15
16
|
return {
|
|
16
17
|
/**
|
|
18
|
+
* @ignore
|
|
17
19
|
* Whether to render a header with reduced whitespace
|
|
18
20
|
* TODO: Remove
|
|
19
21
|
* @type {boolean}
|
|
@@ -21,10 +23,14 @@ class ListHeader extends RtlMixin(LocalizeCoreElement(LitElement)) {
|
|
|
21
23
|
slim: { reflect: true, type: Boolean },
|
|
22
24
|
/**
|
|
23
25
|
* How much padding to render list items with
|
|
24
|
-
*
|
|
25
|
-
* @type {string}
|
|
26
|
+
* @type {'normal'|'slim'}
|
|
26
27
|
*/
|
|
27
28
|
paddingType: { type: String, attribute: 'padding-type' },
|
|
29
|
+
/**
|
|
30
|
+
* Whether all pages can be selected
|
|
31
|
+
* @type {boolean}
|
|
32
|
+
*/
|
|
33
|
+
selectAllPagesAllowed: { type: Boolean, attribute: 'select-all-pages-allowed' },
|
|
28
34
|
};
|
|
29
35
|
}
|
|
30
36
|
|
|
@@ -60,6 +66,14 @@ class ListHeader extends RtlMixin(LocalizeCoreElement(LitElement)) {
|
|
|
60
66
|
margin-left: 0;
|
|
61
67
|
margin-right: 0.9rem;
|
|
62
68
|
}
|
|
69
|
+
d2l-selection-select-all-pages {
|
|
70
|
+
flex: none;
|
|
71
|
+
margin-left: 0.45rem;
|
|
72
|
+
}
|
|
73
|
+
:host([dir="rtl"]) d2l-selection-select-all-pages {
|
|
74
|
+
margin-left: 0;
|
|
75
|
+
margin-right: 0.45rem;
|
|
76
|
+
}
|
|
63
77
|
.d2l-list-header-actions {
|
|
64
78
|
--d2l-overflow-group-justify-content: flex-end;
|
|
65
79
|
flex: auto;
|
|
@@ -75,6 +89,7 @@ class ListHeader extends RtlMixin(LocalizeCoreElement(LitElement)) {
|
|
|
75
89
|
super();
|
|
76
90
|
this.slim = false;
|
|
77
91
|
this.paddingType = 'normal';
|
|
92
|
+
this.selectAllPagesAllowed = false;
|
|
78
93
|
}
|
|
79
94
|
|
|
80
95
|
render() {
|
|
@@ -86,6 +101,7 @@ class ListHeader extends RtlMixin(LocalizeCoreElement(LitElement)) {
|
|
|
86
101
|
class="d2l-list-header-summary"
|
|
87
102
|
no-selection-text="${this.localize('components.selection.select-all')}">
|
|
88
103
|
</d2l-selection-summary>
|
|
104
|
+
${this.selectAllPagesAllowed ? html`<d2l-selection-select-all-pages></d2l-selection-select-all-pages>` : null}
|
|
89
105
|
<div class="d2l-list-header-actions">
|
|
90
106
|
<d2l-overflow-group opener-type="icon"><slot></slot></d2l-overflow-group>
|
|
91
107
|
</div>
|
|
@@ -60,11 +60,11 @@ export const ListItemMixin = superclass => class extends LocalizeCoreElement(Lis
|
|
|
60
60
|
dragTargetHandleOnly: { type: Boolean, attribute: 'drag-target-handle-only' },
|
|
61
61
|
/**
|
|
62
62
|
* How much padding to render list items with
|
|
63
|
-
*
|
|
64
|
-
* @type {string}
|
|
63
|
+
* @type {'normal'|'slim'|'none'}
|
|
65
64
|
*/
|
|
66
65
|
paddingType: { type: String, attribute: 'padding-type' },
|
|
67
66
|
/**
|
|
67
|
+
* @ignore
|
|
68
68
|
* Whether to render the list-item with reduced whitespace.
|
|
69
69
|
* TODO: Remove in favor of padding-type="slim"
|
|
70
70
|
* @type {boolean}
|
|
@@ -98,6 +98,7 @@ function convertToDropdownItem(node) {
|
|
|
98
98
|
case 'd2l-dropdown-more':
|
|
99
99
|
return createMenuItemMenu(node);
|
|
100
100
|
case 'd2l-menu-item':
|
|
101
|
+
case 'd2l-selection-action-menu-item':
|
|
101
102
|
// if the menu item has children treat it as a menu item menu
|
|
102
103
|
if (node.children.length > 0) {
|
|
103
104
|
return createMenuItemMenu(node);
|
|
@@ -97,6 +97,7 @@ The `d2l-list` already extends `SelectionMixin` and should always be used for li
|
|
|
97
97
|
|
|
98
98
|
| Property | Type | Description |
|
|
99
99
|
|---|---|---|
|
|
100
|
+
| `item-count` | Number | Total number of items. Required when selecting all pages is allowed. |
|
|
100
101
|
| `selection-single` | Boolean | Whether to render with single selection behaviour. If `selection-single` is specified, the nested `d2l-selection-input` elements will render radios instead of checkboxes, and the selection component will maintain a single selected item. |
|
|
101
102
|
<!-- docs: end hidden content -->
|
|
102
103
|
|
|
@@ -147,6 +148,44 @@ The `d2l-selection-action` is an optional component that provides a button for a
|
|
|
147
148
|
| `d2l-selection-action-click` | Dispatched when the user clicks the action button. The `SelectionInfo` is provided as the event `detail`. If `requires-selection` was specified then the event will only be dispatched if items are selected. |
|
|
148
149
|
<!-- docs: end hidden content -->
|
|
149
150
|
|
|
151
|
+
## Selection Action Menu Item [d2l-selection-action-menu-item]
|
|
152
|
+
|
|
153
|
+
The `d2l-selection-action-menu-item` is an optional component that is a menu item for actions associated with the selection component (ex. bulk actions). The `requires-selection` attribute may be specified to indicate that the button should be non-interactive if nothing is selected.
|
|
154
|
+
|
|
155
|
+
<!-- docs: demo live name:d2l-selection-action-menu-item -->
|
|
156
|
+
```html
|
|
157
|
+
<script type="module">
|
|
158
|
+
import '@brightspace-ui/core/components/dropdown/dropdown-button-subtle.js';
|
|
159
|
+
import '@brightspace-ui/core/components/dropdown/dropdown-menu.js';
|
|
160
|
+
import '@brightspace-ui/core/components/menu/menu.js';
|
|
161
|
+
import '@brightspace-ui/core/components/selection/selection-action-menu-item.js';
|
|
162
|
+
</script>
|
|
163
|
+
<d2l-dropdown-button-subtle text="Actions">
|
|
164
|
+
<d2l-dropdown-menu>
|
|
165
|
+
<d2l-menu label="Actions">
|
|
166
|
+
<d2l-selection-action-menu-item text="Action 1" requires-selection></d2l-selection-action-menu-item>
|
|
167
|
+
<d2l-selection-action-menu-item text="Action 2"></d2l-selection-action-menu-item>
|
|
168
|
+
</d2l-menu>
|
|
169
|
+
</d2l-dropdown-menu>
|
|
170
|
+
</d2l-dropdown-button-subtle>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
<!-- docs: start hidden content -->
|
|
174
|
+
### Properties
|
|
175
|
+
|
|
176
|
+
| Property | Type | Description |
|
|
177
|
+
|---|---|---|
|
|
178
|
+
| `requires-selection` | Boolean | Whether the action menu-item requires one or more selected items. |
|
|
179
|
+
| `selection-for` | String | Id of the corresponding `SelectionMixin` component, if not placed within it. |
|
|
180
|
+
| `text` | String, required | Text to be shown for the action menu-item. |
|
|
181
|
+
|
|
182
|
+
### Events
|
|
183
|
+
|
|
184
|
+
| Event | Description |
|
|
185
|
+
|---|---|
|
|
186
|
+
| `d2l-selection-action-click` | Dispatched when the user clicks the action menu-item. The `SelectionInfo` is provided as the event `detail`. If `requires-selection` was specified then the event will only be dispatched if items are selected. |
|
|
187
|
+
<!-- docs: end hidden content -->
|
|
188
|
+
|
|
150
189
|
## Selection Input [d2l-selection-input]
|
|
151
190
|
|
|
152
191
|
The `d2l-selection-input` is a required component in selection controls - without it, there wouldn't be anything for the user to select! Note: `d2l-list-item` already provides a selection input for selectable list items. If `d2l-selection-input` is placed within a selection control that specifies `selection-single`, then radios will be rendered instead of checkboxes.
|
|
@@ -6,7 +6,11 @@
|
|
|
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 '../../dropdown/dropdown-button-subtle.js';
|
|
10
|
+
import '../../dropdown/dropdown-menu.js';
|
|
11
|
+
import '../../menu/menu.js';
|
|
9
12
|
import '../selection-action.js';
|
|
13
|
+
import '../selection-action-menu-item.js';
|
|
10
14
|
import '../selection-input.js';
|
|
11
15
|
import '../selection-select-all.js';
|
|
12
16
|
import '../selection-summary.js';
|
|
@@ -57,6 +61,14 @@
|
|
|
57
61
|
<d2l-selection-select-all></d2l-selection-select-all>
|
|
58
62
|
<d2l-selection-action text="Bookmark" icon="tier1:bookmark-hollow" requires-selection></d2l-selection-action>
|
|
59
63
|
<d2l-selection-action text="Settings" icon="tier1:gear"></d2l-selection-action>
|
|
64
|
+
<d2l-dropdown-button-subtle text="Actions">
|
|
65
|
+
<d2l-dropdown-menu>
|
|
66
|
+
<d2l-menu label="Actions">
|
|
67
|
+
<d2l-selection-action-menu-item text="Action 1 (requires selection)" requires-selection></d2l-selection-action-menu-item>
|
|
68
|
+
<d2l-selection-action-menu-item text="Action 2"></d2l-selection-action-menu-item>
|
|
69
|
+
</d2l-menu>
|
|
70
|
+
</d2l-dropdown-menu>
|
|
71
|
+
</d2l-dropdown-button-subtle>
|
|
60
72
|
</div>
|
|
61
73
|
<d2l-selection-summary style="flex: none;"></d2l-selection-summary>
|
|
62
74
|
</div>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { css, html, LitElement } from 'lit-element/lit-element.js';
|
|
2
|
+
import { MenuItemMixin } from '../menu/menu-item-mixin.js';
|
|
3
|
+
import { menuItemStyles } from '../menu/menu-item-styles.js';
|
|
4
|
+
import { SelectionActionMixin } from './selection-action-mixin.js';
|
|
5
|
+
import { SelectionInfo } from './selection-mixin.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* An action menu-item component used within selection controls such as d2l-list and d2l-list-header.
|
|
9
|
+
* @slot supporting - Allows supporting information to be displayed on the right-most side of the menu item
|
|
10
|
+
* @fires d2l-selection-action-click - Dispatched when the user clicks the action button. The `SelectionInfo` is provided as the event `detail`. If `requires-selection` was specified then the event will only be dispatched if items are selected.
|
|
11
|
+
* @fires d2l-selection-observer-subscribe - Internal event
|
|
12
|
+
*/
|
|
13
|
+
class MenuItem extends SelectionActionMixin(MenuItemMixin(LitElement)) {
|
|
14
|
+
|
|
15
|
+
static get styles() {
|
|
16
|
+
return [ menuItemStyles,
|
|
17
|
+
css`
|
|
18
|
+
:host {
|
|
19
|
+
align-items: center;
|
|
20
|
+
display: flex;
|
|
21
|
+
padding: 0.75rem 1rem;
|
|
22
|
+
}
|
|
23
|
+
:host([dir="rtl"]) d2l-icon {
|
|
24
|
+
margin-left: 0;
|
|
25
|
+
margin-right: 6px;
|
|
26
|
+
}
|
|
27
|
+
`
|
|
28
|
+
];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
connectedCallback() {
|
|
32
|
+
super.connectedCallback();
|
|
33
|
+
this.addEventListener('d2l-menu-item-select', this._handleMenuItemSelect);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
disconnectedCallback() {
|
|
37
|
+
super.disconnectedCallback();
|
|
38
|
+
this.removeEventListener('d2l-menu-item-select', this._handleMenuItemSelect);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
render() {
|
|
42
|
+
return html`
|
|
43
|
+
<div class="d2l-menu-item-text">${this.text}</div>
|
|
44
|
+
<div class="d2l-menu-item-supporting"><slot name="supporting"></slot></div>
|
|
45
|
+
`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
_handleMenuItemSelect(e) {
|
|
49
|
+
e.stopPropagation();
|
|
50
|
+
|
|
51
|
+
if (this.requiresSelection && this.selectionInfo.state === SelectionInfo.states.none) return;
|
|
52
|
+
|
|
53
|
+
this.dispatchEvent(new CustomEvent('d2l-selection-action-click', {
|
|
54
|
+
bubbles: true,
|
|
55
|
+
detail: this.selectionInfo
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
customElements.define('d2l-selection-action-menu-item', MenuItem);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { SelectionInfo } from './selection-mixin.js';
|
|
2
|
+
import { SelectionObserverMixin } from './selection-observer-mixin.js';
|
|
3
|
+
|
|
4
|
+
export const SelectionActionMixin = superclass => class extends SelectionObserverMixin(superclass) {
|
|
5
|
+
|
|
6
|
+
static get properties() {
|
|
7
|
+
return {
|
|
8
|
+
/**
|
|
9
|
+
* Whether the action requires one or more selected items
|
|
10
|
+
* @type {boolean}
|
|
11
|
+
*/
|
|
12
|
+
requiresSelection: { type: Boolean, attribute: 'requires-selection', reflect: true }
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
constructor() {
|
|
17
|
+
super();
|
|
18
|
+
this.requiresSelection = false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get selectionInfo() {
|
|
22
|
+
return super.selectionInfo;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
set selectionInfo(value) {
|
|
26
|
+
super.selectionInfo = value;
|
|
27
|
+
this.disabled = (this.requiresSelection && this.selectionInfo.state === SelectionInfo.states.none);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
};
|
|
@@ -6,15 +6,15 @@ import { ButtonMixin } from '../button/button-mixin.js';
|
|
|
6
6
|
import { ifDefined } from 'lit-html/directives/if-defined.js';
|
|
7
7
|
import { LocalizeCoreElement } from '../../lang/localize-core-element.js';
|
|
8
8
|
import { RtlMixin } from '../../mixins/rtl-mixin.js';
|
|
9
|
+
import { SelectionActionMixin } from './selection-action-mixin.js';
|
|
9
10
|
import { SelectionInfo } from './selection-mixin.js';
|
|
10
|
-
import { SelectionObserverMixin } from './selection-observer-mixin.js';
|
|
11
11
|
|
|
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 button. The `SelectionInfo` is provided as the event `detail`. If `requires-selection` was specified then the event will only be dispatched if items are selected.
|
|
15
15
|
* @fires d2l-selection-observer-subscribe - Internal event
|
|
16
16
|
*/
|
|
17
|
-
class Action extends LocalizeCoreElement(
|
|
17
|
+
class Action extends LocalizeCoreElement(SelectionActionMixin(ButtonMixin(RtlMixin(LitElement)))) {
|
|
18
18
|
|
|
19
19
|
static get properties() {
|
|
20
20
|
return {
|
|
@@ -23,11 +23,6 @@ class Action extends LocalizeCoreElement(SelectionObserverMixin(ButtonMixin(RtlM
|
|
|
23
23
|
* @type {string}
|
|
24
24
|
*/
|
|
25
25
|
icon: { type: String, reflect: true },
|
|
26
|
-
/**
|
|
27
|
-
* Whether the action requires one or more selected items
|
|
28
|
-
* @type {boolean}
|
|
29
|
-
*/
|
|
30
|
-
requiresSelection: { type: Boolean, attribute: 'requires-selection', reflect: true },
|
|
31
26
|
/**
|
|
32
27
|
* REQUIRED: The text for the action
|
|
33
28
|
* @type {string}
|
|
@@ -47,15 +42,6 @@ class Action extends LocalizeCoreElement(SelectionObserverMixin(ButtonMixin(RtlM
|
|
|
47
42
|
`;
|
|
48
43
|
}
|
|
49
44
|
|
|
50
|
-
get selectionInfo() {
|
|
51
|
-
return super.selectionInfo;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
set selectionInfo(value) {
|
|
55
|
-
super.selectionInfo = value;
|
|
56
|
-
this.disabled = (this.requiresSelection && this.selectionInfo.state === SelectionInfo.states.none);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
45
|
connectedCallback() {
|
|
60
46
|
super.connectedCallback();
|
|
61
47
|
this.addEventListener('d2l-button-ghost-click', this._handleActionClick);
|
|
@@ -28,7 +28,8 @@ export class SelectionInfo {
|
|
|
28
28
|
return {
|
|
29
29
|
none: 'none',
|
|
30
30
|
some: 'some',
|
|
31
|
-
all: 'all'
|
|
31
|
+
all: 'all',
|
|
32
|
+
allPages: 'all-pages'
|
|
32
33
|
};
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -38,6 +39,11 @@ export const SelectionMixin = superclass => class extends RtlMixin(superclass) {
|
|
|
38
39
|
|
|
39
40
|
static get properties() {
|
|
40
41
|
return {
|
|
42
|
+
/**
|
|
43
|
+
* Total number of items. Required when selecting all pages is allowed.
|
|
44
|
+
* @type {number}
|
|
45
|
+
*/
|
|
46
|
+
itemCount: { type: Number, attribute: 'item-count' },
|
|
41
47
|
/**
|
|
42
48
|
* Whether to render with single selection behaviour. If `selection-single` is specified, the nested `d2l-selection-input` elements will render radios instead of checkboxes, and the selection component will maintain a single selected item.
|
|
43
49
|
* @type {boolean}
|
|
@@ -48,7 +54,9 @@ export const SelectionMixin = superclass => class extends RtlMixin(superclass) {
|
|
|
48
54
|
|
|
49
55
|
constructor() {
|
|
50
56
|
super();
|
|
57
|
+
this.itemCount = 0;
|
|
51
58
|
this.selectionSingle = false;
|
|
59
|
+
this._selectAllPages = false;
|
|
52
60
|
this._selectionObservers = new Map();
|
|
53
61
|
this._selectionSelectables = new Map();
|
|
54
62
|
}
|
|
@@ -80,22 +88,28 @@ export const SelectionMixin = superclass => class extends RtlMixin(superclass) {
|
|
|
80
88
|
let state = SelectionInfo.states.none;
|
|
81
89
|
const keys = [];
|
|
82
90
|
|
|
83
|
-
this.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
91
|
+
if (this._selectAllPages) {
|
|
92
|
+
state = SelectionInfo.states.allPages;
|
|
93
|
+
} else {
|
|
94
|
+
this._selectionSelectables.forEach(selectable => {
|
|
95
|
+
if (selectable.selected) keys.push(selectable.key);
|
|
96
|
+
if (selectable._indeterminate) state = SelectionInfo.states.some;
|
|
97
|
+
});
|
|
87
98
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
99
|
+
if (keys.length > 0) {
|
|
100
|
+
if (keys.length === this._selectionSelectables.size) state = SelectionInfo.states.all;
|
|
101
|
+
else state = SelectionInfo.states.some;
|
|
102
|
+
}
|
|
91
103
|
}
|
|
92
104
|
|
|
93
105
|
return new SelectionInfo(keys, state);
|
|
94
106
|
}
|
|
95
107
|
|
|
96
|
-
setSelectionForAll(selected) {
|
|
108
|
+
setSelectionForAll(selected, selectAllPages) {
|
|
97
109
|
if (this.selectionSingle && selected) return;
|
|
98
110
|
|
|
111
|
+
this._selectAllPages = (selected && selectAllPages);
|
|
112
|
+
|
|
99
113
|
this._selectionSelectables.forEach(selectable => {
|
|
100
114
|
if (!!selectable.selected !== selected) {
|
|
101
115
|
selectable.selected = selected;
|
|
@@ -154,6 +168,7 @@ export const SelectionMixin = superclass => class extends RtlMixin(superclass) {
|
|
|
154
168
|
}
|
|
155
169
|
|
|
156
170
|
_handleSelectionChange(e) {
|
|
171
|
+
if (!e.detail.selected) this._selectAllPages = false;
|
|
157
172
|
if (this.selectionSingle && e.detail.selected) {
|
|
158
173
|
const target = e.composedPath().find(elem => elem.tagName === 'D2L-SELECTION-INPUT');
|
|
159
174
|
this._selectionSelectables.forEach(selectable => {
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import '../button/button-subtle.js';
|
|
2
|
+
import { css, html, LitElement } from 'lit-element/lit-element.js';
|
|
3
|
+
import { LocalizeCoreElement } from '../../lang/localize-core-element.js';
|
|
4
|
+
import { SelectionInfo } from './selection-mixin.js';
|
|
5
|
+
import { SelectionObserverMixin } from './selection-observer-mixin.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A subtle button that selects all items for all pages.
|
|
9
|
+
* @fires d2l-selection-observer-subscribe - Internal event
|
|
10
|
+
*/
|
|
11
|
+
class SelectAllPages extends LocalizeCoreElement(SelectionObserverMixin(LitElement)) {
|
|
12
|
+
|
|
13
|
+
static get styles() {
|
|
14
|
+
return css`
|
|
15
|
+
:host {
|
|
16
|
+
display: inline-block;
|
|
17
|
+
}
|
|
18
|
+
:host([hidden]) {
|
|
19
|
+
display: none;
|
|
20
|
+
}
|
|
21
|
+
`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
render() {
|
|
25
|
+
if (!this._provider) return;
|
|
26
|
+
if (!this._provider.itemCount) return;
|
|
27
|
+
if (this._provider.selectionSingle) return;
|
|
28
|
+
if (this.selectionInfo.state !== SelectionInfo.states.all) return;
|
|
29
|
+
|
|
30
|
+
return html`
|
|
31
|
+
<d2l-button-subtle
|
|
32
|
+
@click="${this._handleClick}"
|
|
33
|
+
text="${this.localize('components.selection.select-all-items', 'count', this._provider.itemCount)}">
|
|
34
|
+
</d2l-button-subtle>`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
focus() {
|
|
38
|
+
const elem = this.shadowRoot && this.shadowRoot.querySelector('d2l-button-subtle');
|
|
39
|
+
if (elem) elem.focus();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
_handleClick() {
|
|
43
|
+
if (this._provider) this._provider.setSelectionForAll(true, true);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
customElements.define('d2l-selection-select-all-pages', SelectAllPages);
|
|
@@ -48,7 +48,7 @@ class SelectAll extends LocalizeCoreElement(SelectionObserverMixin(LitElement))
|
|
|
48
48
|
<d2l-input-checkbox
|
|
49
49
|
aria-label="${this.localize('components.selection.select-all')}"
|
|
50
50
|
@change="${this._handleCheckboxChange}"
|
|
51
|
-
?checked="${this.selectionInfo.state === SelectionInfo.states.all}"
|
|
51
|
+
?checked="${this.selectionInfo.state === SelectionInfo.states.all || this.selectionInfo.state === SelectionInfo.states.allPages}"
|
|
52
52
|
?disabled="${this.disabled}"
|
|
53
53
|
description="${ifDefined(this.selectionInfo.state !== SelectionInfo.states.none ? summary : undefined)}"
|
|
54
54
|
?indeterminate="${this.selectionInfo.state === SelectionInfo.states.some}">
|
|
@@ -62,7 +62,7 @@ class SelectAll extends LocalizeCoreElement(SelectionObserverMixin(LitElement))
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
_handleCheckboxChange(e) {
|
|
65
|
-
if (this._provider) this._provider.setSelectionForAll(e.target.checked);
|
|
65
|
+
if (this._provider) this._provider.setSelectionForAll(e.target.checked, false);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
}
|
|
@@ -37,8 +37,12 @@ class Summary extends LocalizeCoreElement(SelectionObserverMixin(LitElement)) {
|
|
|
37
37
|
render() {
|
|
38
38
|
if (this._provider && this._provider.selectionSingle) return;
|
|
39
39
|
|
|
40
|
+
const count = (this.selectionInfo.state === SelectionInfo.states.allPages ?
|
|
41
|
+
this._provider.itemCount : this.selectionInfo.keys.length);
|
|
42
|
+
|
|
40
43
|
const summary = (this.selectionInfo.state === SelectionInfo.states.none && this.noSelectionText ?
|
|
41
|
-
this.noSelectionText : this.localize('components.selection.selected', 'count',
|
|
44
|
+
this.noSelectionText : this.localize('components.selection.selected', 'count', count));
|
|
45
|
+
|
|
42
46
|
return html`
|
|
43
47
|
<p class="d2l-body-compact">${summary}</p>
|
|
44
48
|
`;
|