@brightspace-ui/core 2.38.3 → 2.39.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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Overflow Groups
|
|
2
|
-
The `d2l-overflow-group` element can be used to add responsiveness to a set of buttons, links or menus.
|
|
2
|
+
The `d2l-overflow-group` element can be used to add responsiveness to a set of buttons, links or menus. The `OverflowGroupMixin` allows for using the chomping logic without having to use those specific element types.
|
|
3
3
|
|
|
4
4
|
<!-- docs: demo autoSize:false display:block size:medium -->
|
|
5
5
|
```html
|
|
@@ -70,3 +70,41 @@ Items added to this container element will no longer wrap onto a second line whe
|
|
|
70
70
|
|
|
71
71
|
Looking for an enhancement not listed here? Create a GitHub issue!
|
|
72
72
|
<!-- docs: end hidden content -->
|
|
73
|
+
|
|
74
|
+
## OverflowGroupMixin
|
|
75
|
+
This mixin allows for creation of an overflow group that handles chomping when using elements that are not buttons, links, or menus, or when wanting an overflow container that is not a `d2l-dropdown`.
|
|
76
|
+
|
|
77
|
+
### How to Use
|
|
78
|
+
|
|
79
|
+
**Import:**
|
|
80
|
+
```javascript
|
|
81
|
+
import { OverflowGroupMixin } from '@brightspace-ui/core/components/overflow-group/overflow-group-mixin.js';
|
|
82
|
+
|
|
83
|
+
class OtherOverflowGroup extends OverflowGroupMixin(LitElement) {
|
|
84
|
+
...
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Styles:**
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
static get styles() {
|
|
91
|
+
return [ super.styles ];
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Functionality:**
|
|
96
|
+
|
|
97
|
+
The functions `getOverflowContainer` and `convertToOverflowItem` need to be implemented by consumers of the mixin.
|
|
98
|
+
|
|
99
|
+
```javascript
|
|
100
|
+
convertToOverflowItem(node) {
|
|
101
|
+
// return html of overflow item. For example:
|
|
102
|
+
return html`<d2l-menu-item text="${node.text}"></d2l-menu-item>`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
getOverflowContainer(overflowItems, mini) {
|
|
106
|
+
// return html of overflow menu. "mini" specifies if smaller menu option should be used, where applicable. For example:
|
|
107
|
+
if (mini) html`<d2l-dropdown-context-menu text="Overflow Menu"><d2l-dropdown-menu>${overflowItems}</d2l-dropdown-menu></d2l-dropdown-context-menu>`;
|
|
108
|
+
else return html`<d2l-dropdown-button text="Overflow Menu"><d2l-dropdown-menu>${overflowItems}</d2l-dropdown-menu></d2l-dropdown-button>`;
|
|
109
|
+
}
|
|
110
|
+
```
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import { css, html, nothing } from 'lit';
|
|
2
|
+
import { LocalizeCoreElement } from '../../helpers/localize-core-element.js';
|
|
3
|
+
import { offscreenStyles } from '../offscreen/offscreen.js';
|
|
4
|
+
import ResizeObserver from 'resize-observer-polyfill/dist/ResizeObserver.es.js';
|
|
5
|
+
|
|
6
|
+
export const OVERFLOW_CLASS = 'd2l-overflow-container';
|
|
7
|
+
export const OVERFLOW_MINI_CLASS = 'd2l-overflow-container-mini';
|
|
8
|
+
|
|
9
|
+
const AUTO_SHOW_CLASS = 'd2l-button-group-show';
|
|
10
|
+
const AUTO_NO_SHOW_CLASS = 'd2l-button-group-no-show';
|
|
11
|
+
|
|
12
|
+
const OPENER_TYPE = {
|
|
13
|
+
DEFAULT: 'default',
|
|
14
|
+
ICON: 'icon'
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
async function filterAsync(arr, callback) {
|
|
18
|
+
const fail = Symbol();
|
|
19
|
+
const results = await Promise.all(arr.map(async item => {
|
|
20
|
+
const callbackResult = await callback(item);
|
|
21
|
+
return callbackResult ? item : fail;
|
|
22
|
+
}));
|
|
23
|
+
return results.filter(i => i !== fail);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const OverflowGroupMixin = superclass => class extends LocalizeCoreElement(superclass) {
|
|
27
|
+
|
|
28
|
+
static get properties() {
|
|
29
|
+
return {
|
|
30
|
+
/**
|
|
31
|
+
* Use predefined classes on slot elements to set min and max slotted items to show
|
|
32
|
+
* @type {boolean}
|
|
33
|
+
*/
|
|
34
|
+
autoShow: {
|
|
35
|
+
type: Boolean,
|
|
36
|
+
attribute: 'auto-show',
|
|
37
|
+
},
|
|
38
|
+
/**
|
|
39
|
+
* minimum amount of slotted items to show
|
|
40
|
+
* @type {number}
|
|
41
|
+
*/
|
|
42
|
+
minToShow: {
|
|
43
|
+
type: Number,
|
|
44
|
+
reflect: true,
|
|
45
|
+
attribute: 'min-to-show',
|
|
46
|
+
},
|
|
47
|
+
/**
|
|
48
|
+
* maximum amount of slotted items to show
|
|
49
|
+
* @type {number}
|
|
50
|
+
*/
|
|
51
|
+
maxToShow: {
|
|
52
|
+
type: Number,
|
|
53
|
+
reflect: true,
|
|
54
|
+
attribute: 'max-to-show',
|
|
55
|
+
},
|
|
56
|
+
/**
|
|
57
|
+
* @ignore
|
|
58
|
+
*/
|
|
59
|
+
openerType: {
|
|
60
|
+
type: String,
|
|
61
|
+
attribute: 'opener-type'
|
|
62
|
+
},
|
|
63
|
+
_chompIndex: {
|
|
64
|
+
state: true
|
|
65
|
+
},
|
|
66
|
+
_mini: {
|
|
67
|
+
state: true
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static get styles() {
|
|
73
|
+
return [offscreenStyles, css`
|
|
74
|
+
:host {
|
|
75
|
+
display: block;
|
|
76
|
+
}
|
|
77
|
+
:host([hidden]) {
|
|
78
|
+
display: none;
|
|
79
|
+
}
|
|
80
|
+
.d2l-overflow-group-container {
|
|
81
|
+
display: flex;
|
|
82
|
+
flex-wrap: wrap;
|
|
83
|
+
justify-content: var(--d2l-overflow-group-justify-content, normal);
|
|
84
|
+
}
|
|
85
|
+
.d2l-overflow-group-container ::slotted([data-is-chomped]) {
|
|
86
|
+
display: none !important;
|
|
87
|
+
}
|
|
88
|
+
`];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
constructor() {
|
|
92
|
+
super();
|
|
93
|
+
|
|
94
|
+
this._handleItemMutation = this._handleItemMutation.bind(this);
|
|
95
|
+
this._handleResize = this._handleResize.bind(this);
|
|
96
|
+
this._resizeObserver = new ResizeObserver((entries) => requestAnimationFrame(() => this._handleResize(entries)));
|
|
97
|
+
|
|
98
|
+
this._isObserving = false;
|
|
99
|
+
this._mini = this.openerType === OPENER_TYPE.ICON;
|
|
100
|
+
this._overflowContainerHidden = false;
|
|
101
|
+
this._slotItems = [];
|
|
102
|
+
|
|
103
|
+
this.autoShow = false;
|
|
104
|
+
this.maxToShow = -1;
|
|
105
|
+
this.minToShow = 1;
|
|
106
|
+
this.openerType = OPENER_TYPE.DEFAULT;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
disconnectedCallback() {
|
|
110
|
+
super.disconnectedCallback();
|
|
111
|
+
|
|
112
|
+
if (this._isObserving) {
|
|
113
|
+
this._isObserving = false;
|
|
114
|
+
this._resizeObserver.disconnect();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
render() {
|
|
119
|
+
const chompedOverflowItems = this._overflowItems ? this._overflowItems.slice(this._chompIndex) : [];
|
|
120
|
+
const overflowContainer = (!this._overflowContainerHidden && this._overflowItems)
|
|
121
|
+
? this.getOverflowContainer(chompedOverflowItems, this._mini)
|
|
122
|
+
: nothing;
|
|
123
|
+
|
|
124
|
+
this._slotItems.forEach((element, index) => {
|
|
125
|
+
if (!this._overflowContainerHidden && index >= this._chompIndex) {
|
|
126
|
+
element.setAttribute('data-is-chomped', '');
|
|
127
|
+
} else {
|
|
128
|
+
element.removeAttribute('data-is-chomped');
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
return html`
|
|
133
|
+
<div class="d2l-overflow-group-container">
|
|
134
|
+
<slot @slotchange="${this._handleSlotChange}"></slot>
|
|
135
|
+
${overflowContainer}
|
|
136
|
+
</div>
|
|
137
|
+
`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
update(changedProperties) {
|
|
141
|
+
super.update(changedProperties);
|
|
142
|
+
|
|
143
|
+
if (!this._isObserving) {
|
|
144
|
+
this._isObserving = true;
|
|
145
|
+
this._resizeObserver.observe(this.shadowRoot.querySelector('.d2l-overflow-group-container'));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (changedProperties.has('autoShow') && this.autoShow) {
|
|
149
|
+
this._autoDetectBoundaries(this._slotItems);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (changedProperties.has('minToShow')
|
|
153
|
+
|| changedProperties.has('maxToShow')) {
|
|
154
|
+
this._chomp();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Slight hack to get the overflow container width the first time it renders
|
|
158
|
+
if (!this._overflowContainerWidth) {
|
|
159
|
+
// this action needs to be deferred until first render of our overflow container
|
|
160
|
+
requestAnimationFrame(() => {
|
|
161
|
+
this._chomp();
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
_autoDetectBoundaries(items) {
|
|
167
|
+
if (!items) return;
|
|
168
|
+
|
|
169
|
+
let minToShow, maxToShow;
|
|
170
|
+
for (let i = 0; i < items.length; i++) {
|
|
171
|
+
if (!items[i].classList) continue;
|
|
172
|
+
|
|
173
|
+
if (items[i].classList.contains(AUTO_SHOW_CLASS)) {
|
|
174
|
+
minToShow = i + 1;
|
|
175
|
+
}
|
|
176
|
+
if (maxToShow === undefined && items[i].classList.contains(AUTO_NO_SHOW_CLASS)) {
|
|
177
|
+
maxToShow = i;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (minToShow !== undefined) {
|
|
182
|
+
this.minToShow = minToShow;
|
|
183
|
+
}
|
|
184
|
+
if (maxToShow !== undefined) {
|
|
185
|
+
this.maxToShow = maxToShow;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
_chomp() {
|
|
190
|
+
if (!this.shadowRoot || !this._itemLayouts) return;
|
|
191
|
+
|
|
192
|
+
this._overflowContainer = this.shadowRoot.querySelector(`.${OVERFLOW_CLASS}`);
|
|
193
|
+
this._overflowContainerMini = this.shadowRoot.querySelector(`.${OVERFLOW_MINI_CLASS}`);
|
|
194
|
+
if (this.openerType === OPENER_TYPE.ICON && this._overflowContainerMini) {
|
|
195
|
+
this._overflowContainerWidth = this._overflowContainerMini.offsetWidth;
|
|
196
|
+
} else if (this._overflowContainer) {
|
|
197
|
+
this._overflowContainerWidth = this._overflowContainer.offsetWidth;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const showing = {
|
|
201
|
+
count: 0,
|
|
202
|
+
width: 0
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
let isSoftOverflowing, isForcedOverflowing;
|
|
206
|
+
for (let i = 0; i < this._itemLayouts.length; i++) {
|
|
207
|
+
const itemLayout = this._itemLayouts[i];
|
|
208
|
+
|
|
209
|
+
// handle minimum items to show
|
|
210
|
+
if (showing.count < this.minToShow) {
|
|
211
|
+
showing.width += itemLayout.width;
|
|
212
|
+
showing.count += 1;
|
|
213
|
+
itemLayout.trigger = 'force-show';
|
|
214
|
+
itemLayout.isChomped = false;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// handle maximum items to show
|
|
219
|
+
if (this.maxToShow >= 0 && showing.count >= this.maxToShow) {
|
|
220
|
+
isForcedOverflowing = true;
|
|
221
|
+
itemLayout.isChomped = true;
|
|
222
|
+
itemLayout.trigger = 'force-hide';
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// chomp or unchomp based on space available, and we've already handled min/max above
|
|
227
|
+
if (!isSoftOverflowing && showing.width + itemLayout.width < this._availableWidth) {
|
|
228
|
+
showing.width += itemLayout.width;
|
|
229
|
+
showing.count += 1;
|
|
230
|
+
itemLayout.isChomped = false;
|
|
231
|
+
itemLayout.trigger = 'soft-show';
|
|
232
|
+
|
|
233
|
+
} else {
|
|
234
|
+
isSoftOverflowing = true;
|
|
235
|
+
itemLayout.isChomped = true;
|
|
236
|
+
itemLayout.trigger = 'soft-hide';
|
|
237
|
+
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
}
|
|
241
|
+
// if there is at least one showing and no more to be hidden, enable collapsing overflow container to mini overflow container
|
|
242
|
+
this._overflowContainerHidden = this._itemLayouts.length === showing.count;
|
|
243
|
+
if (!this._overflowContainerHidden && (isSoftOverflowing || isForcedOverflowing)) {
|
|
244
|
+
for (let j = this._itemLayouts.length; j--;) {
|
|
245
|
+
if (showing.width + this._overflowContainerWidth < this._availableWidth) {
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
const itemLayoutOverflowing = this._itemLayouts[j];
|
|
249
|
+
if (itemLayoutOverflowing.trigger !== 'soft-show') {
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
showing.width -= itemLayoutOverflowing.width;
|
|
253
|
+
showing.count -= 1;
|
|
254
|
+
isSoftOverflowing = true;
|
|
255
|
+
itemLayoutOverflowing.trigger = 'soft-hide';
|
|
256
|
+
itemLayoutOverflowing.isChomped = true;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
const overflowOverflowing = (showing.width + this._overflowContainerWidth >= this._availableWidth);
|
|
260
|
+
const swapToMini = overflowOverflowing && !this._overflowContainerHidden;
|
|
261
|
+
|
|
262
|
+
this._mini = this.openerType === OPENER_TYPE.ICON || swapToMini;
|
|
263
|
+
this._chompIndex = this._overflowContainerHidden ? null : showing.count;
|
|
264
|
+
|
|
265
|
+
/** Dispatched when there is an update performed to the overflow group */
|
|
266
|
+
this.dispatchEvent(new CustomEvent('d2l-overflow-group-updated', { composed: false, bubbles: true }));
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
_getItemLayouts(filteredNodes) {
|
|
270
|
+
const items = filteredNodes.map((node) => {
|
|
271
|
+
const computedStyles = window.getComputedStyle(node);
|
|
272
|
+
|
|
273
|
+
return {
|
|
274
|
+
type: node.tagName.toLowerCase(),
|
|
275
|
+
isChomped: false,
|
|
276
|
+
isHidden: computedStyles.display === 'none',
|
|
277
|
+
width: Math.ceil(parseFloat(computedStyles.width) || 0)
|
|
278
|
+
+ parseInt(computedStyles.marginRight) || 0
|
|
279
|
+
+ parseInt(computedStyles.marginLeft) || 0,
|
|
280
|
+
node: node
|
|
281
|
+
};
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
return items.filter(({ isHidden }) => !isHidden);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
async _getItems() {
|
|
288
|
+
// get the items from the slot
|
|
289
|
+
this._slotItems = await this._getSlotItems();
|
|
290
|
+
// convert them to layout items (calculate widths)
|
|
291
|
+
this._itemLayouts = this._getItemLayouts(this._slotItems);
|
|
292
|
+
// convert to overflow items (for overflow container)
|
|
293
|
+
this._overflowItems = this._slotItems.map((node) => this.convertToOverflowItem(node));
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
async _getSlotItems() {
|
|
297
|
+
const filteredNodes = await filterAsync(this.shadowRoot.querySelector('slot').assignedNodes({ flatten: true }), async(node) => {
|
|
298
|
+
if (node.nodeType !== Node.ELEMENT_NODE) return false;
|
|
299
|
+
if (node.updateComplete) await node.updateComplete;
|
|
300
|
+
return node.tagName.toLowerCase() !== 'template';
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
return filteredNodes;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
_handleItemMutation(mutations) {
|
|
307
|
+
if (!mutations || mutations.length === 0) return;
|
|
308
|
+
if (this._updateOverflowItemsRequested) return;
|
|
309
|
+
|
|
310
|
+
this._updateOverflowItemsRequested = true;
|
|
311
|
+
setTimeout(() => {
|
|
312
|
+
this._overflowItems = this._slotItems.map(node => this.convertToOverflowItem(node));
|
|
313
|
+
this._updateOverflowItemsRequested = false;
|
|
314
|
+
this.requestUpdate();
|
|
315
|
+
}, 0);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
_handleResize(entries) {
|
|
319
|
+
this._availableWidth = Math.ceil(entries[0].contentRect.width);
|
|
320
|
+
this._chomp();
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
_handleSlotChange() {
|
|
324
|
+
requestAnimationFrame(async() => {
|
|
325
|
+
await this._getItems();
|
|
326
|
+
|
|
327
|
+
this._slotItems.forEach(item => {
|
|
328
|
+
const observer = new MutationObserver(this._handleItemMutation);
|
|
329
|
+
observer.observe(item, {
|
|
330
|
+
attributes: true, /* required for legacy-Edge, otherwise attributeFilter throws a syntax error */
|
|
331
|
+
attributeFilter: ['disabled', 'text', 'selected'],
|
|
332
|
+
childList: false,
|
|
333
|
+
subtree: true
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
if (this.autoShow) {
|
|
338
|
+
this._autoDetectBoundaries(this._slotItems);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
this._chomp();
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
};
|
|
@@ -11,20 +11,10 @@ import '../menu/menu-item.js';
|
|
|
11
11
|
import '../menu/menu-item-separator.js';
|
|
12
12
|
import '../menu/menu-item-link.js';
|
|
13
13
|
import { css, html, LitElement } from 'lit';
|
|
14
|
+
import { OVERFLOW_CLASS, OVERFLOW_MINI_CLASS, OverflowGroupMixin } from './overflow-group-mixin.js';
|
|
14
15
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
15
|
-
import { LocalizeCoreElement } from '../../helpers/localize-core-element.js';
|
|
16
|
-
import { offscreenStyles } from '../offscreen/offscreen.js';
|
|
17
|
-
import ResizeObserver from 'resize-observer-polyfill/dist/ResizeObserver.es.js';
|
|
18
16
|
import { RtlMixin } from '../../mixins/rtl-mixin.js';
|
|
19
17
|
|
|
20
|
-
const AUTO_SHOW_CLASS = 'd2l-button-group-show';
|
|
21
|
-
const AUTO_NO_SHOW_CLASS = 'd2l-button-group-no-show';
|
|
22
|
-
|
|
23
|
-
const OPENER_TYPE = {
|
|
24
|
-
DEFAULT: 'default',
|
|
25
|
-
ICON: 'icon'
|
|
26
|
-
};
|
|
27
|
-
|
|
28
18
|
const OPENER_STYLE = {
|
|
29
19
|
DEFAULT: 'default',
|
|
30
20
|
SUBTLE: 'subtle',
|
|
@@ -61,140 +51,36 @@ function createMenuItemSeparator() {
|
|
|
61
51
|
return html`<d2l-menu-item-separator></d2l-menu-item-separator>`;
|
|
62
52
|
}
|
|
63
53
|
|
|
64
|
-
function createMenuItemMenu(node) {
|
|
65
|
-
const menuOpener =
|
|
66
|
-
node.querySelector('d2l-dropdown-button')
|
|
67
|
-
|| node.querySelector('d2l-dropdown-button-subtle');
|
|
68
|
-
|
|
69
|
-
const openerText = node.text || menuOpener.text;
|
|
70
|
-
const disabled = !!node.disabled;
|
|
71
|
-
const subMenu = node.querySelector('d2l-menu');
|
|
72
|
-
|
|
73
|
-
const subItems = Array.from(subMenu.children).map((node) => convertToDropdownItem(node));
|
|
74
|
-
|
|
75
|
-
return html`<d2l-menu-item
|
|
76
|
-
?disabled=${disabled}
|
|
77
|
-
text="${openerText}">
|
|
78
|
-
<d2l-menu>
|
|
79
|
-
${subItems}
|
|
80
|
-
</d2l-menu>
|
|
81
|
-
</d2l-menu-item>`;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function convertToDropdownItem(node) {
|
|
85
|
-
const tagName = node.tagName.toLowerCase();
|
|
86
|
-
switch (tagName) {
|
|
87
|
-
case 'd2l-button':
|
|
88
|
-
case 'd2l-button-subtle':
|
|
89
|
-
case 'button':
|
|
90
|
-
case 'd2l-button-icon':
|
|
91
|
-
case 'd2l-selection-action':
|
|
92
|
-
return createMenuItem(node);
|
|
93
|
-
case 'a':
|
|
94
|
-
case 'd2l-link':
|
|
95
|
-
return createMenuItemLink(node);
|
|
96
|
-
case 'd2l-menu':
|
|
97
|
-
case 'd2l-dropdown':
|
|
98
|
-
case 'd2l-dropdown-button':
|
|
99
|
-
case 'd2l-dropdown-button-subtle':
|
|
100
|
-
case 'd2l-dropdown-context-menu':
|
|
101
|
-
case 'd2l-dropdown-more':
|
|
102
|
-
case 'd2l-selection-action-dropdown':
|
|
103
|
-
return createMenuItemMenu(node);
|
|
104
|
-
case 'd2l-menu-item':
|
|
105
|
-
case 'd2l-selection-action-menu-item':
|
|
106
|
-
// if the menu item has children treat it as a menu item menu
|
|
107
|
-
if (node.children.length > 0) {
|
|
108
|
-
return createMenuItemMenu(node);
|
|
109
|
-
} else {
|
|
110
|
-
return createMenuItem(node);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
if (node.getAttribute('role') === 'separator') {
|
|
114
|
-
return createMenuItemSeparator();
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
54
|
/**
|
|
119
55
|
*
|
|
120
56
|
* A component that can be used to display a set of buttons, links or menus that will be put into a dropdown menu when they no longer fit on the first line of their container
|
|
121
57
|
* @slot - Buttons, dropdown buttons, links or other items to be added to the container
|
|
122
|
-
* @
|
|
58
|
+
* @attr {'default'|'icon'} [opener-type="default"] - Set the opener type to 'icon' for a `...` menu icon instead of `More actions` text
|
|
123
59
|
*/
|
|
124
|
-
class OverflowGroup extends RtlMixin(
|
|
60
|
+
class OverflowGroup extends OverflowGroupMixin(RtlMixin(LitElement)) {
|
|
125
61
|
|
|
126
62
|
static get properties() {
|
|
127
63
|
return {
|
|
128
|
-
/**
|
|
129
|
-
* Use predefined classes on slot elements to set min and max buttons to show
|
|
130
|
-
* @type {boolean}
|
|
131
|
-
*/
|
|
132
|
-
autoShow: {
|
|
133
|
-
type: Boolean,
|
|
134
|
-
attribute: 'auto-show',
|
|
135
|
-
},
|
|
136
|
-
/**
|
|
137
|
-
* minimum amount of buttons to show
|
|
138
|
-
* @type {number}
|
|
139
|
-
*/
|
|
140
|
-
minToShow: {
|
|
141
|
-
type: Number,
|
|
142
|
-
reflect: true,
|
|
143
|
-
attribute: 'min-to-show',
|
|
144
|
-
},
|
|
145
|
-
/**
|
|
146
|
-
* maximum amount of buttons to show
|
|
147
|
-
* @type {number}
|
|
148
|
-
*/
|
|
149
|
-
maxToShow: {
|
|
150
|
-
type: Number,
|
|
151
|
-
reflect: true,
|
|
152
|
-
attribute: 'max-to-show',
|
|
153
|
-
},
|
|
154
|
-
/**
|
|
155
|
-
* Set the opener type to 'icon' for a `...` menu icon instead of `More actions` text
|
|
156
|
-
* @type {'default'|'icon'}
|
|
157
|
-
*/
|
|
158
|
-
openerType: {
|
|
159
|
-
type: String,
|
|
160
|
-
attribute: 'opener-type'
|
|
161
|
-
},
|
|
162
64
|
/**
|
|
163
65
|
* Setting this property will change the style of the overflow menu opener
|
|
164
66
|
* @type {'default'|'subtle'}
|
|
67
|
+
* @default "default"
|
|
165
68
|
*/
|
|
166
69
|
openerStyle: {
|
|
167
70
|
type: String,
|
|
168
71
|
reflect: true,
|
|
169
72
|
attribute: 'opener-style',
|
|
170
|
-
},
|
|
171
|
-
_mini: {
|
|
172
|
-
type: Boolean,
|
|
173
|
-
reflect: true
|
|
174
|
-
},
|
|
175
|
-
_chompIndex: {
|
|
176
|
-
type: Number,
|
|
177
73
|
}
|
|
178
74
|
};
|
|
179
75
|
}
|
|
180
76
|
|
|
181
77
|
static get styles() {
|
|
182
|
-
return [
|
|
183
|
-
:host {
|
|
184
|
-
display: block;
|
|
185
|
-
}
|
|
186
|
-
:host([hidden]) {
|
|
187
|
-
display: none;
|
|
188
|
-
}
|
|
78
|
+
return [super.styles, css`
|
|
189
79
|
:host([opener-style="subtle"]) {
|
|
190
80
|
--d2l-button-icon-fill-color: var(--d2l-color-celestine);
|
|
191
81
|
--d2l-button-icon-fill-color-hover: var(--d2l-color-celestine-minus-1);
|
|
192
82
|
}
|
|
193
|
-
|
|
194
|
-
display: flex;
|
|
195
|
-
flex-wrap: wrap;
|
|
196
|
-
justify-content: var(--d2l-overflow-group-justify-content, normal);
|
|
197
|
-
}
|
|
83
|
+
|
|
198
84
|
::slotted(d2l-button),
|
|
199
85
|
::slotted(d2l-link),
|
|
200
86
|
::slotted(span),
|
|
@@ -229,291 +115,93 @@ class OverflowGroup extends RtlMixin(LocalizeCoreElement(LitElement)) {
|
|
|
229
115
|
margin-left: 0.2rem;
|
|
230
116
|
margin-right: 0;
|
|
231
117
|
}
|
|
232
|
-
.d2l-overflow-group-container ::slotted([data-is-chomped]) {
|
|
233
|
-
display: none !important;
|
|
234
|
-
}
|
|
235
118
|
`];
|
|
236
119
|
}
|
|
237
120
|
|
|
238
121
|
constructor() {
|
|
239
122
|
super();
|
|
240
|
-
this._handleItemMutation = this._handleItemMutation.bind(this);
|
|
241
|
-
this._handleResize = this._handleResize.bind(this);
|
|
242
|
-
|
|
243
|
-
this._throttledResize = (entries) => requestAnimationFrame(() => this._handleResize(entries));
|
|
244
|
-
|
|
245
|
-
this._overflowHidden = false;
|
|
246
|
-
this.autoShow = false;
|
|
247
|
-
this.maxToShow = -1;
|
|
248
|
-
this.minToShow = 1;
|
|
249
123
|
this.openerStyle = OPENER_STYLE.DEFAULT;
|
|
250
|
-
this.openerType = OPENER_TYPE.DEFAULT;
|
|
251
|
-
this._mini = this.openerType === OPENER_TYPE.ICON;
|
|
252
|
-
this._resizeObserver = null;
|
|
253
|
-
this._slotItems = [];
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
disconnectedCallback() {
|
|
257
|
-
super.disconnectedCallback();
|
|
258
|
-
if (this._resizeObserver) this._resizeObserver.disconnect();
|
|
259
124
|
}
|
|
260
125
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
</div>
|
|
289
|
-
`;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
update(changedProperties) {
|
|
293
|
-
super.update(changedProperties);
|
|
294
|
-
|
|
295
|
-
if (changedProperties.get('autoShow')) {
|
|
296
|
-
this._getItemLayouts(this._slotItems);
|
|
297
|
-
this._autoDetectBoundaries(this._itemLayouts);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
if (changedProperties.get('minToShow')
|
|
301
|
-
|| changedProperties.get('maxToShow')) {
|
|
302
|
-
this._chomp();
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// Slight hack to get the overflow menu width the first time it renders
|
|
306
|
-
if (!this._overflowMenuWidth) {
|
|
307
|
-
// this action needs to be deferred until first render of our overflow button
|
|
308
|
-
requestAnimationFrame(() => {
|
|
309
|
-
this._chomp();
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
_autoDetectBoundaries(items) {
|
|
315
|
-
|
|
316
|
-
let minToShow, maxToShow;
|
|
317
|
-
for (let i = 0; i < items.length; i++) {
|
|
318
|
-
if (items[i].classList.contains(AUTO_SHOW_CLASS)) {
|
|
319
|
-
minToShow = i + 1;
|
|
320
|
-
}
|
|
321
|
-
if (maxToShow === undefined && items[i].classList.contains(AUTO_NO_SHOW_CLASS)) {
|
|
322
|
-
maxToShow = i;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
if (minToShow !== undefined) {
|
|
327
|
-
this.minToShow = minToShow;
|
|
328
|
-
}
|
|
329
|
-
if (maxToShow !== undefined) {
|
|
330
|
-
this.maxToShow = maxToShow;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
_chomp() {
|
|
335
|
-
if (!this.shadowRoot || !this._itemLayouts) return;
|
|
336
|
-
|
|
337
|
-
this._overflowMenu = this.shadowRoot.querySelector('.d2l-overflow-dropdown');
|
|
338
|
-
this._overflowMenuMini = this.shadowRoot.querySelector('.d2l-overflow-dropdown-mini');
|
|
339
|
-
if (this.openerType === OPENER_TYPE.ICON && this._overflowMenuMini) {
|
|
340
|
-
this._overflowMenuWidth = this._overflowMenuMini.offsetWidth;
|
|
341
|
-
} else if (this._overflowMenu) {
|
|
342
|
-
this._overflowMenuWidth = this._overflowMenu.offsetWidth;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
const showing = {
|
|
346
|
-
count: 0,
|
|
347
|
-
width: 0
|
|
348
|
-
};
|
|
349
|
-
|
|
350
|
-
let isSoftOverflowing, isForcedOverflowing;
|
|
351
|
-
for (let i = 0; i < this._itemLayouts.length; i++) {
|
|
352
|
-
const itemLayout = this._itemLayouts[i];
|
|
353
|
-
|
|
354
|
-
// handle minimum items to show
|
|
355
|
-
if (showing.count < this.minToShow) {
|
|
356
|
-
showing.width += itemLayout.width;
|
|
357
|
-
showing.count += 1;
|
|
358
|
-
itemLayout.trigger = 'force-show';
|
|
359
|
-
itemLayout.isChomped = false;
|
|
360
|
-
continue;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// handle maximum items to show
|
|
364
|
-
if (this.maxToShow >= 0 && showing.count >= this.maxToShow) {
|
|
365
|
-
isForcedOverflowing = true;
|
|
366
|
-
itemLayout.isChomped = true;
|
|
367
|
-
itemLayout.trigger = 'force-hide';
|
|
368
|
-
continue;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
// chomp or unchomp based on space available, and we've already handled min/max above
|
|
372
|
-
if (!isSoftOverflowing && showing.width + itemLayout.width < this._availableWidth) {
|
|
373
|
-
showing.width += itemLayout.width;
|
|
374
|
-
showing.count += 1;
|
|
375
|
-
itemLayout.isChomped = false;
|
|
376
|
-
itemLayout.trigger = 'soft-show';
|
|
377
|
-
|
|
378
|
-
} else {
|
|
379
|
-
isSoftOverflowing = true;
|
|
380
|
-
itemLayout.isChomped = true;
|
|
381
|
-
itemLayout.trigger = 'soft-hide';
|
|
382
|
-
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
}
|
|
386
|
-
// if there is at least one showing and no more to be hidden, enable collapsing more button to [...]
|
|
387
|
-
this._overflowMenuHidden = this._itemLayouts.length === showing.count;
|
|
388
|
-
if (!this._overflowMenuHidden && (isSoftOverflowing || isForcedOverflowing)) {
|
|
389
|
-
for (let j = this._itemLayouts.length; j--;) {
|
|
390
|
-
if (showing.width + this._overflowMenuWidth < this._availableWidth) {
|
|
391
|
-
break;
|
|
392
|
-
}
|
|
393
|
-
const itemLayoutOverflowing = this._itemLayouts[j];
|
|
394
|
-
if (itemLayoutOverflowing.trigger !== 'soft-show') {
|
|
395
|
-
continue;
|
|
126
|
+
convertToOverflowItem(node) {
|
|
127
|
+
const tagName = node.tagName.toLowerCase();
|
|
128
|
+
switch (tagName) {
|
|
129
|
+
case 'd2l-button':
|
|
130
|
+
case 'd2l-button-subtle':
|
|
131
|
+
case 'button':
|
|
132
|
+
case 'd2l-button-icon':
|
|
133
|
+
case 'd2l-selection-action':
|
|
134
|
+
return createMenuItem(node);
|
|
135
|
+
case 'a':
|
|
136
|
+
case 'd2l-link':
|
|
137
|
+
return createMenuItemLink(node);
|
|
138
|
+
case 'd2l-menu':
|
|
139
|
+
case 'd2l-dropdown':
|
|
140
|
+
case 'd2l-dropdown-button':
|
|
141
|
+
case 'd2l-dropdown-button-subtle':
|
|
142
|
+
case 'd2l-dropdown-context-menu':
|
|
143
|
+
case 'd2l-dropdown-more':
|
|
144
|
+
case 'd2l-selection-action-dropdown':
|
|
145
|
+
return this._createMenuItemMenu(node);
|
|
146
|
+
case 'd2l-menu-item':
|
|
147
|
+
case 'd2l-selection-action-menu-item':
|
|
148
|
+
// if the menu item has children treat it as a menu item menu
|
|
149
|
+
if (node.children.length > 0) {
|
|
150
|
+
return this._createMenuItemMenu(node);
|
|
151
|
+
} else {
|
|
152
|
+
return createMenuItem(node);
|
|
396
153
|
}
|
|
397
|
-
showing.width -= itemLayoutOverflowing.width;
|
|
398
|
-
showing.count -= 1;
|
|
399
|
-
isSoftOverflowing = true;
|
|
400
|
-
itemLayoutOverflowing.trigger = 'soft-hide';
|
|
401
|
-
itemLayoutOverflowing.isChomped = true;
|
|
402
|
-
}
|
|
403
154
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
this._mini = this.openerType === OPENER_TYPE.ICON || swapToMiniButton;
|
|
408
|
-
this._chompIndex = this._overflowMenuHidden ? null : showing.count;
|
|
409
|
-
|
|
410
|
-
this.dispatchEvent(new CustomEvent('d2l-overflow-group-updated', { composed: false, bubbles: true }));
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
_getItemLayouts(filteredNodes) {
|
|
414
|
-
const items = filteredNodes.map((node) => {
|
|
415
|
-
const computedStyles = window.getComputedStyle(node);
|
|
416
|
-
|
|
417
|
-
return {
|
|
418
|
-
type: node.tagName.toLowerCase(),
|
|
419
|
-
isChomped: false,
|
|
420
|
-
isHidden: computedStyles.display === 'none',
|
|
421
|
-
width: Math.ceil(parseFloat(computedStyles.width) || 0)
|
|
422
|
-
+ parseInt(computedStyles.marginRight) || 0
|
|
423
|
-
+ parseInt(computedStyles.marginLeft) || 0,
|
|
424
|
-
node: node
|
|
425
|
-
};
|
|
426
|
-
});
|
|
427
|
-
|
|
428
|
-
return items.filter(({ isHidden }) => !isHidden);
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
_getItems() {
|
|
432
|
-
// get the items from the button slot
|
|
433
|
-
this._slotItems = this._getSlotItems();
|
|
434
|
-
// convert them to layout items (calculate widths)
|
|
435
|
-
this._itemLayouts = this._getItemLayouts(this._slotItems);
|
|
436
|
-
// convert to dropdown items (for overflow menu)
|
|
437
|
-
this._dropdownItems = this._slotItems.map((node) => convertToDropdownItem(node));
|
|
155
|
+
if (node.getAttribute('role') === 'separator') {
|
|
156
|
+
return createMenuItemSeparator();
|
|
157
|
+
}
|
|
438
158
|
}
|
|
439
159
|
|
|
440
|
-
|
|
441
|
-
if (this._overflowMenuHidden) {
|
|
442
|
-
return;
|
|
443
|
-
}
|
|
160
|
+
getOverflowContainer(overflowItems, mini) {
|
|
444
161
|
const moreActionsText = this.localize('components.overflow-group.moreActions');
|
|
445
|
-
const overflowItems = this._dropdownItems ? this._dropdownItems.slice(this._chompIndex) : [];
|
|
446
162
|
const menu = html`<d2l-dropdown-menu>
|
|
447
163
|
<d2l-menu label="${moreActionsText}">
|
|
448
164
|
${overflowItems}
|
|
449
165
|
</d2l-menu>
|
|
450
166
|
</d2l-dropdown-menu>`;
|
|
451
167
|
|
|
452
|
-
if (
|
|
453
|
-
return html`<d2l-dropdown-more class="d2l-overflow-dropdown-mini" text="${moreActionsText}">
|
|
168
|
+
if (mini) {
|
|
169
|
+
return html`<d2l-dropdown-more class="${OVERFLOW_MINI_CLASS} d2l-overflow-dropdown-mini" text="${moreActionsText}">
|
|
454
170
|
${menu}
|
|
455
171
|
</d2l-dropdown-more>`;
|
|
456
172
|
}
|
|
457
173
|
|
|
458
174
|
if (this.openerStyle === OPENER_STYLE.SUBTLE) {
|
|
459
|
-
return html`<d2l-dropdown-button-subtle class="d2l-overflow-dropdown" text="${moreActionsText}">
|
|
175
|
+
return html`<d2l-dropdown-button-subtle class="${OVERFLOW_CLASS} d2l-overflow-dropdown" text="${moreActionsText}">
|
|
460
176
|
${menu}
|
|
461
177
|
</d2l-dropdown-button-subtle>`;
|
|
462
178
|
}
|
|
463
179
|
|
|
464
|
-
return html`<d2l-dropdown-button class="d2l-overflow-dropdown" text="${moreActionsText}">
|
|
180
|
+
return html`<d2l-dropdown-button class="${OVERFLOW_CLASS} d2l-overflow-dropdown" text="${moreActionsText}">
|
|
465
181
|
${menu}
|
|
466
182
|
</d2l-dropdown-button>`;
|
|
467
183
|
}
|
|
468
184
|
|
|
469
|
-
|
|
470
|
-
const
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
return isNode;
|
|
474
|
-
});
|
|
185
|
+
_createMenuItemMenu(node) {
|
|
186
|
+
const menuOpener =
|
|
187
|
+
node.querySelector('d2l-dropdown-button')
|
|
188
|
+
|| node.querySelector('d2l-dropdown-button-subtle');
|
|
475
189
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
_handleItemMutation(mutations) {
|
|
480
|
-
if (!mutations || mutations.length === 0) return;
|
|
481
|
-
if (this._updateDropdownItemsRequested) return;
|
|
190
|
+
const openerText = node.text || menuOpener.text;
|
|
191
|
+
const disabled = !!node.disabled;
|
|
192
|
+
const subMenu = node.querySelector('d2l-menu');
|
|
482
193
|
|
|
483
|
-
|
|
484
|
-
setTimeout(() => {
|
|
485
|
-
this._dropdownItems = this._slotItems.map(node => convertToDropdownItem(node));
|
|
486
|
-
this._updateDropdownItemsRequested = false;
|
|
487
|
-
this.requestUpdate();
|
|
488
|
-
}, 0);
|
|
489
|
-
}
|
|
194
|
+
const subItems = Array.from(subMenu.children).map((node) => this.convertToOverflowItem(node));
|
|
490
195
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
196
|
+
return html`<d2l-menu-item
|
|
197
|
+
?disabled=${disabled}
|
|
198
|
+
text="${openerText}">
|
|
199
|
+
<d2l-menu>
|
|
200
|
+
${subItems}
|
|
201
|
+
</d2l-menu>
|
|
202
|
+
</d2l-menu-item>`;
|
|
494
203
|
}
|
|
495
204
|
|
|
496
|
-
_handleSlotChange() {
|
|
497
|
-
requestAnimationFrame(() => {
|
|
498
|
-
this._getItems();
|
|
499
|
-
|
|
500
|
-
this._slotItems.forEach(item => {
|
|
501
|
-
const observer = new MutationObserver(this._handleItemMutation);
|
|
502
|
-
observer.observe(item, {
|
|
503
|
-
attributes: true, /* required for legacy-Edge, otherwise attributeFilter throws a syntax error */
|
|
504
|
-
attributeFilter: ['disabled', 'text'],
|
|
505
|
-
childList: false,
|
|
506
|
-
subtree: false
|
|
507
|
-
});
|
|
508
|
-
});
|
|
509
|
-
|
|
510
|
-
if (this.autoShow) {
|
|
511
|
-
this._autoDetectBoundaries(this._slotItems);
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
this._chomp();
|
|
515
|
-
});
|
|
516
|
-
}
|
|
517
205
|
}
|
|
518
206
|
|
|
519
207
|
customElements.define('d2l-overflow-group', OverflowGroup);
|
package/custom-elements.json
CHANGED
|
@@ -8760,71 +8760,69 @@
|
|
|
8760
8760
|
"path": "./components/overflow-group/overflow-group.js",
|
|
8761
8761
|
"description": "\nA component that can be used to display a set of buttons, links or menus that will be put into a dropdown menu when they no longer fit on the first line of their container",
|
|
8762
8762
|
"attributes": [
|
|
8763
|
+
{
|
|
8764
|
+
"name": "opener-style",
|
|
8765
|
+
"description": "Setting this property will change the style of the overflow menu opener",
|
|
8766
|
+
"type": "'default'|'subtle'",
|
|
8767
|
+
"default": "\"\\\"default\\\"\""
|
|
8768
|
+
},
|
|
8763
8769
|
{
|
|
8764
8770
|
"name": "auto-show",
|
|
8765
|
-
"description": "Use predefined classes on slot elements to set min and max
|
|
8771
|
+
"description": "Use predefined classes on slot elements to set min and max slotted items to show",
|
|
8766
8772
|
"type": "boolean",
|
|
8767
8773
|
"default": "false"
|
|
8768
8774
|
},
|
|
8769
8775
|
{
|
|
8770
8776
|
"name": "max-to-show",
|
|
8771
|
-
"description": "maximum amount of
|
|
8777
|
+
"description": "maximum amount of slotted items to show",
|
|
8772
8778
|
"type": "number",
|
|
8773
8779
|
"default": "-1"
|
|
8774
8780
|
},
|
|
8775
8781
|
{
|
|
8776
8782
|
"name": "min-to-show",
|
|
8777
|
-
"description": "minimum amount of
|
|
8783
|
+
"description": "minimum amount of slotted items to show",
|
|
8778
8784
|
"type": "number",
|
|
8779
8785
|
"default": "1"
|
|
8780
8786
|
},
|
|
8781
|
-
{
|
|
8782
|
-
"name": "opener-style",
|
|
8783
|
-
"description": "Setting this property will change the style of the overflow menu opener",
|
|
8784
|
-
"type": "'default'|'subtle'",
|
|
8785
|
-
"default": "\"DEFAULT\""
|
|
8786
|
-
},
|
|
8787
8787
|
{
|
|
8788
8788
|
"name": "opener-type",
|
|
8789
8789
|
"description": "Set the opener type to 'icon' for a `...` menu icon instead of `More actions` text",
|
|
8790
8790
|
"type": "'default'|'icon'",
|
|
8791
|
-
"default": "\"
|
|
8791
|
+
"default": "\"default\""
|
|
8792
8792
|
}
|
|
8793
8793
|
],
|
|
8794
8794
|
"properties": [
|
|
8795
|
+
{
|
|
8796
|
+
"name": "openerStyle",
|
|
8797
|
+
"attribute": "opener-style",
|
|
8798
|
+
"description": "Setting this property will change the style of the overflow menu opener",
|
|
8799
|
+
"type": "'default'|'subtle'",
|
|
8800
|
+
"default": "\"\\\"default\\\"\""
|
|
8801
|
+
},
|
|
8795
8802
|
{
|
|
8796
8803
|
"name": "autoShow",
|
|
8797
8804
|
"attribute": "auto-show",
|
|
8798
|
-
"description": "Use predefined classes on slot elements to set min and max
|
|
8805
|
+
"description": "Use predefined classes on slot elements to set min and max slotted items to show",
|
|
8799
8806
|
"type": "boolean",
|
|
8800
8807
|
"default": "false"
|
|
8801
8808
|
},
|
|
8802
8809
|
{
|
|
8803
8810
|
"name": "maxToShow",
|
|
8804
8811
|
"attribute": "max-to-show",
|
|
8805
|
-
"description": "maximum amount of
|
|
8812
|
+
"description": "maximum amount of slotted items to show",
|
|
8806
8813
|
"type": "number",
|
|
8807
8814
|
"default": "-1"
|
|
8808
8815
|
},
|
|
8809
8816
|
{
|
|
8810
8817
|
"name": "minToShow",
|
|
8811
8818
|
"attribute": "min-to-show",
|
|
8812
|
-
"description": "minimum amount of
|
|
8819
|
+
"description": "minimum amount of slotted items to show",
|
|
8813
8820
|
"type": "number",
|
|
8814
8821
|
"default": "1"
|
|
8815
8822
|
},
|
|
8816
|
-
{
|
|
8817
|
-
"name": "openerStyle",
|
|
8818
|
-
"attribute": "opener-style",
|
|
8819
|
-
"description": "Setting this property will change the style of the overflow menu opener",
|
|
8820
|
-
"type": "'default'|'subtle'",
|
|
8821
|
-
"default": "\"DEFAULT\""
|
|
8822
|
-
},
|
|
8823
8823
|
{
|
|
8824
8824
|
"name": "openerType",
|
|
8825
|
-
"
|
|
8826
|
-
"description": "Set the opener type to 'icon' for a `...` menu icon instead of `More actions` text",
|
|
8827
|
-
"type": "'default'|'icon'",
|
|
8825
|
+
"type": "string",
|
|
8828
8826
|
"default": "\"DEFAULT\""
|
|
8829
8827
|
}
|
|
8830
8828
|
],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brightspace-ui/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.39.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",
|