@brightspace-ui/core 2.9.0 → 2.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -279,7 +279,6 @@ class ListItemDragHandle extends LocalizeCoreElement(RtlMixin(LitElement)) {
|
|
|
279
279
|
return html`
|
|
280
280
|
<button
|
|
281
281
|
aria-label="${this._defaultLabel}"
|
|
282
|
-
aria-live="assertive"
|
|
283
282
|
class="d2l-list-item-drag-handle-keyboard-button"
|
|
284
283
|
@focusin="${this._onFocusInKeyboardButton}"
|
|
285
284
|
@focusout="${this._onFocusOutKeyboardButton}"
|
|
@@ -10,23 +10,48 @@
|
|
|
10
10
|
import '../tag-list-item.js';
|
|
11
11
|
import '../test/tag-list-item-mixin-consumer.js';
|
|
12
12
|
</script>
|
|
13
|
+
<style>
|
|
14
|
+
.actions {
|
|
15
|
+
margin-bottom: 1rem;
|
|
16
|
+
}
|
|
17
|
+
</style>
|
|
13
18
|
</head>
|
|
14
19
|
<body unresolved>
|
|
15
20
|
<d2l-demo-page page-title="d2l-tag-list">
|
|
16
21
|
|
|
17
22
|
<h2>Basic Tag List</h2>
|
|
23
|
+
|
|
24
|
+
<div class="actions">
|
|
25
|
+
<button id="add">add tag (first)</button>
|
|
26
|
+
<button id="remove">remove tag (first)</button>
|
|
27
|
+
</div>
|
|
28
|
+
<script>
|
|
29
|
+
let addIndex = 0;
|
|
30
|
+
document.querySelector('#add').addEventListener('click', () => {
|
|
31
|
+
const tag = document.createElement('d2l-tag-list-item');
|
|
32
|
+
tag.text = `Added Tag ${++addIndex}`;
|
|
33
|
+
document.querySelector('d2l-tag-list').insertBefore(tag, document.querySelector('d2l-tag-list').children[0]);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
document.querySelector('#remove').addEventListener('click', () => {
|
|
37
|
+
const children = document.querySelector('d2l-tag-list').children;
|
|
38
|
+
if (children.length === 0) return;
|
|
39
|
+
document.querySelector('d2l-tag-list').removeChild(children[0]);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
</script>
|
|
18
43
|
<d2l-demo-snippet fullscreen>
|
|
19
44
|
<d2l-tag-list description="A bunch of example tags">
|
|
20
45
|
<d2l-tag-list-item text="Example Tag"></d2l-tag-list-item>
|
|
21
|
-
<d2l-tag-list-item text="Longer Example Tag - much much much much much longer"></d2l-tag-list-item>
|
|
46
|
+
<d2l-tag-list-item text="Longer Example Tag - much much much much much much much much longer"></d2l-tag-list-item>
|
|
22
47
|
<d2l-tag-list-item text="Another Example Tag"></d2l-tag-list-item>
|
|
23
48
|
<d2l-tag-list-item-mixin-consumer name="Custom Tag List Item"></d2l-tag-list-item-mixin-consumer>
|
|
24
49
|
<d2l-tag-list-item text="Example Tag 5"></d2l-tag-list-item>
|
|
25
50
|
<d2l-tag-list-item text="Example Tag 6"></d2l-tag-list-item>
|
|
26
51
|
<d2l-tag-list-item text="Example Tag 7"></d2l-tag-list-item>
|
|
27
|
-
</d2l-tag-list>
|
|
52
|
+
</d2l-tag-list>
|
|
28
53
|
</d2l-demo-snippet>
|
|
29
54
|
|
|
30
55
|
</d2l-demo-page>
|
|
31
56
|
</body>
|
|
32
|
-
</html>
|
|
57
|
+
</html>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import '../colors/colors.js';
|
|
2
|
+
import '../tooltip/tooltip.js';
|
|
2
3
|
import { css, html } from 'lit';
|
|
4
|
+
import { getUniqueId } from '../../helpers/uniqueId.js';
|
|
3
5
|
import { labelStyles } from '../typography/styles.js';
|
|
4
6
|
|
|
5
7
|
export const TagListItemMixin = superclass => class extends superclass {
|
|
@@ -17,19 +19,12 @@ export const TagListItemMixin = superclass => class extends superclass {
|
|
|
17
19
|
return [labelStyles, css`
|
|
18
20
|
:host {
|
|
19
21
|
display: grid;
|
|
22
|
+
max-width: 100%;
|
|
20
23
|
outline: none;
|
|
21
24
|
}
|
|
22
25
|
:host([hidden]) {
|
|
23
26
|
display: none;
|
|
24
27
|
}
|
|
25
|
-
.tag-list-item-content {
|
|
26
|
-
height: 1rem;
|
|
27
|
-
margin: auto;
|
|
28
|
-
min-width: 0;
|
|
29
|
-
overflow: hidden;
|
|
30
|
-
text-overflow: ellipsis;
|
|
31
|
-
white-space: nowrap;
|
|
32
|
-
}
|
|
33
28
|
.tag-list-item-container {
|
|
34
29
|
background-color: var(--d2l-color-regolith);
|
|
35
30
|
border-radius: 6px;
|
|
@@ -37,21 +32,26 @@ export const TagListItemMixin = superclass => class extends superclass {
|
|
|
37
32
|
box-sizing: border-box;
|
|
38
33
|
color: var(--d2l-color-ferrite);
|
|
39
34
|
cursor: pointer;
|
|
40
|
-
|
|
35
|
+
max-width: 320px;
|
|
41
36
|
min-width: 0;
|
|
37
|
+
outline: none;
|
|
38
|
+
overflow: hidden;
|
|
42
39
|
padding: 0.25rem 0.6rem;
|
|
40
|
+
text-overflow: ellipsis;
|
|
43
41
|
transition: background-color 0.2s ease-out, box-shadow 0.2s ease-out;
|
|
42
|
+
white-space: nowrap;
|
|
43
|
+
}
|
|
44
|
+
.tag-list-item-container:focus,
|
|
45
|
+
:host(:hover) .tag-list-item-container:focus {
|
|
46
|
+
box-shadow: inset 0 0 0 2px var(--d2l-color-celestine), 0 2px 4px rgba(0, 0, 0, 0.03);
|
|
44
47
|
}
|
|
45
48
|
:host(:hover) .tag-list-item-container,
|
|
46
|
-
|
|
49
|
+
.tag-list-item-container:focus {
|
|
47
50
|
background-color: var(--d2l-color-sylvite);
|
|
48
51
|
}
|
|
49
52
|
:host(:hover) .tag-list-item-container {
|
|
50
53
|
box-shadow: inset 0 0 0 1px var(--d2l-color-mica), 0 2px 4px rgba(0, 0, 0, 0.03);
|
|
51
54
|
}
|
|
52
|
-
:host(:focus) .tag-list-item-container {
|
|
53
|
-
box-shadow: inset 0 0 0 2px var(--d2l-color-celestine), 0 2px 4px rgba(0, 0, 0, 0.03);
|
|
54
|
-
}
|
|
55
55
|
|
|
56
56
|
@media (prefers-reduced-motion: reduce) {
|
|
57
57
|
.tag-list-item-container {
|
|
@@ -65,12 +65,30 @@ export const TagListItemMixin = superclass => class extends superclass {
|
|
|
65
65
|
super();
|
|
66
66
|
/** @ignore */
|
|
67
67
|
this.role = 'listitem';
|
|
68
|
+
this._id = getUniqueId();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
firstUpdated(changedProperties) {
|
|
72
|
+
super.firstUpdated(changedProperties);
|
|
73
|
+
|
|
74
|
+
const container = this.shadowRoot.querySelector('.tag-list-item-container');
|
|
75
|
+
this.addEventListener('focus', (e) => {
|
|
76
|
+
// ignore focus events coming from inside the tag content
|
|
77
|
+
if (e.composedPath()[0] === this) container.focus();
|
|
78
|
+
});
|
|
79
|
+
this.addEventListener('blur', () => container.blur());
|
|
68
80
|
}
|
|
69
81
|
|
|
70
|
-
_renderTag(tagContent) {
|
|
82
|
+
_renderTag(tagContent, hasTruncationTooltip) {
|
|
83
|
+
const tooltip = hasTruncationTooltip ? html`
|
|
84
|
+
<d2l-tooltip for="${this._id}" show-truncated-only>
|
|
85
|
+
${tagContent}
|
|
86
|
+
</d2l-tooltip>
|
|
87
|
+
` : null;
|
|
71
88
|
return html`
|
|
72
|
-
|
|
73
|
-
|
|
89
|
+
${tooltip}
|
|
90
|
+
<div class="tag-list-item-container d2l-label-text" id="${this._id}" tabindex="-1">
|
|
91
|
+
${tagContent}
|
|
74
92
|
</div>
|
|
75
93
|
`;
|
|
76
94
|
}
|
|
@@ -14,7 +14,7 @@ const PAGE_SIZE_LINES = {
|
|
|
14
14
|
medium: 2,
|
|
15
15
|
small: 3
|
|
16
16
|
};
|
|
17
|
-
const
|
|
17
|
+
const MARGIN_TOP_RIGHT = 6;
|
|
18
18
|
|
|
19
19
|
class TagList extends LocalizeCoreElement(ArrowKeysMixin(LitElement)) {
|
|
20
20
|
|
|
@@ -44,7 +44,6 @@ class TagList extends LocalizeCoreElement(ArrowKeysMixin(LitElement)) {
|
|
|
44
44
|
flex-wrap: wrap;
|
|
45
45
|
margin: -6px -6px 0 0;
|
|
46
46
|
padding: 0;
|
|
47
|
-
position: relative;
|
|
48
47
|
}
|
|
49
48
|
::slotted(*),
|
|
50
49
|
d2l-button-subtle {
|
|
@@ -65,7 +64,7 @@ class TagList extends LocalizeCoreElement(ArrowKeysMixin(LitElement)) {
|
|
|
65
64
|
/** @ignore */
|
|
66
65
|
this.arrowKeysDirection = 'leftrightupdown';
|
|
67
66
|
this._chompIndex = 10000;
|
|
68
|
-
this.
|
|
67
|
+
this._hasResized = false;
|
|
69
68
|
this._resizeObserver = null;
|
|
70
69
|
this._showHiddenTags = false;
|
|
71
70
|
}
|
|
@@ -73,11 +72,18 @@ class TagList extends LocalizeCoreElement(ArrowKeysMixin(LitElement)) {
|
|
|
73
72
|
disconnectedCallback() {
|
|
74
73
|
super.disconnectedCallback();
|
|
75
74
|
if (this._resizeObserver) this._resizeObserver.disconnect();
|
|
75
|
+
if (this._subtleButtonResizeObserver) this._subtleButtonResizeObserver.disconnect();
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
firstUpdated(changedProperties) {
|
|
79
79
|
super.firstUpdated(changedProperties);
|
|
80
80
|
|
|
81
|
+
const subtleButton = this.shadowRoot.querySelector('.d2l-tag-list-hidden-button');
|
|
82
|
+
this._subtleButtonResizeObserver = new ResizeObserver(() => {
|
|
83
|
+
this._subtleButtonWidth = Math.ceil(parseFloat(getComputedStyle(subtleButton).getPropertyValue('width')));
|
|
84
|
+
});
|
|
85
|
+
this._subtleButtonResizeObserver.observe(subtleButton);
|
|
86
|
+
|
|
81
87
|
const container = this.shadowRoot.querySelector('.tag-list-outer-container');
|
|
82
88
|
this._resizeObserver = new ResizeObserver((e) => requestAnimationFrame(() => this._handleResize(e)));
|
|
83
89
|
this._resizeObserver.observe(container);
|
|
@@ -86,15 +92,17 @@ class TagList extends LocalizeCoreElement(ArrowKeysMixin(LitElement)) {
|
|
|
86
92
|
render() {
|
|
87
93
|
let hiddenCount = 0;
|
|
88
94
|
let hasHiddenTags = false;
|
|
89
|
-
this._items
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
if (this._items) {
|
|
96
|
+
this._items.forEach((element, index) => {
|
|
97
|
+
if (index >= this._chompIndex) hasHiddenTags = true;
|
|
98
|
+
if (!this._showHiddenTags && index >= this._chompIndex) {
|
|
99
|
+
hiddenCount++;
|
|
100
|
+
element.setAttribute('data-is-chomped', '');
|
|
101
|
+
} else {
|
|
102
|
+
element.removeAttribute('data-is-chomped');
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
98
106
|
|
|
99
107
|
let button = null;
|
|
100
108
|
if (hasHiddenTags) {
|
|
@@ -123,7 +131,7 @@ class TagList extends LocalizeCoreElement(ArrowKeysMixin(LitElement)) {
|
|
|
123
131
|
`;
|
|
124
132
|
|
|
125
133
|
const outerContainerStyles = {
|
|
126
|
-
maxHeight: (this._showHiddenTags || !this._lines) ? undefined : `${(this._itemHeight +
|
|
134
|
+
maxHeight: (this._showHiddenTags || !this._lines) ? undefined : `${(this._itemHeight + MARGIN_TOP_RIGHT) * this._lines}px`
|
|
127
135
|
};
|
|
128
136
|
|
|
129
137
|
return html`
|
|
@@ -140,15 +148,12 @@ class TagList extends LocalizeCoreElement(ArrowKeysMixin(LitElement)) {
|
|
|
140
148
|
}
|
|
141
149
|
|
|
142
150
|
focus() {
|
|
143
|
-
if (this._items.length > 0) this._items[0].focus();
|
|
151
|
+
if (this._items && this._items.length > 0) this._items[0].focus();
|
|
144
152
|
}
|
|
145
153
|
|
|
146
154
|
_chomp() {
|
|
147
155
|
if (!this.shadowRoot || !this._lines || !this._itemLayouts) return;
|
|
148
156
|
|
|
149
|
-
const subtleButton = this.shadowRoot.querySelector('.d2l-tag-list-hidden-button');
|
|
150
|
-
const subtleButtonWidth = Math.ceil(parseFloat(getComputedStyle(subtleButton).getPropertyValue('width')));
|
|
151
|
-
|
|
152
157
|
const showing = {
|
|
153
158
|
count: 0,
|
|
154
159
|
width: 0
|
|
@@ -166,9 +171,10 @@ class TagList extends LocalizeCoreElement(ArrowKeysMixin(LitElement)) {
|
|
|
166
171
|
|
|
167
172
|
for (let i = overflowingIndex; i < this._itemLayouts.length; i++) {
|
|
168
173
|
const itemLayout = this._itemLayouts[i];
|
|
174
|
+
const itemWidth = Math.min(itemLayout.width, this._availableWidth);
|
|
169
175
|
|
|
170
|
-
if (!isOverflowing && showing.width +
|
|
171
|
-
showing.width +=
|
|
176
|
+
if (!isOverflowing && ((showing.width + itemWidth) <= (this._availableWidth + MARGIN_TOP_RIGHT))) {
|
|
177
|
+
showing.width += itemWidth;
|
|
172
178
|
showing.count += 1;
|
|
173
179
|
itemLayout.trigger = 'soft-show';
|
|
174
180
|
} else if (k < this._lines) {
|
|
@@ -179,7 +185,6 @@ class TagList extends LocalizeCoreElement(ArrowKeysMixin(LitElement)) {
|
|
|
179
185
|
itemLayout.trigger = 'soft-hide';
|
|
180
186
|
}
|
|
181
187
|
}
|
|
182
|
-
|
|
183
188
|
}
|
|
184
189
|
|
|
185
190
|
if (!isOverflowing) {
|
|
@@ -189,7 +194,7 @@ class TagList extends LocalizeCoreElement(ArrowKeysMixin(LitElement)) {
|
|
|
189
194
|
|
|
190
195
|
// calculate if additional item(s) should be hidden due to subtle button needing space
|
|
191
196
|
for (let j = this._itemLayouts.length; j--;) {
|
|
192
|
-
if ((showing.width +
|
|
197
|
+
if ((showing.width + this._subtleButtonWidth) < this._availableWidth) {
|
|
193
198
|
break;
|
|
194
199
|
}
|
|
195
200
|
const itemLayoutOverflowing = this._itemLayouts[j];
|
|
@@ -223,29 +228,39 @@ class TagList extends LocalizeCoreElement(ArrowKeysMixin(LitElement)) {
|
|
|
223
228
|
return slot.assignedNodes({ flatten: true }).filter((node) => {
|
|
224
229
|
if (node.nodeType !== Node.ELEMENT_NODE) return false;
|
|
225
230
|
const role = node.getAttribute('role');
|
|
231
|
+
node.removeAttribute('data-is-chomped');
|
|
226
232
|
return (role === 'listitem');
|
|
227
233
|
});
|
|
228
234
|
}
|
|
229
235
|
|
|
230
236
|
_handleResize(entries) {
|
|
231
|
-
this._availableWidth = Math.
|
|
237
|
+
this._availableWidth = Math.floor(entries[0].contentRect.width);
|
|
232
238
|
if (this._availableWidth >= PAGE_SIZE.large) this._lines = PAGE_SIZE_LINES.large;
|
|
233
239
|
else if (this._availableWidth < PAGE_SIZE.large && this._availableWidth >= PAGE_SIZE.medium) this._lines = PAGE_SIZE_LINES.medium;
|
|
234
240
|
else this._lines = PAGE_SIZE_LINES.small;
|
|
241
|
+
if (!this._hasResized) {
|
|
242
|
+
this._hasResized = true;
|
|
243
|
+
this._handleSlotChange();
|
|
244
|
+
}
|
|
235
245
|
this._chomp();
|
|
236
246
|
}
|
|
237
247
|
|
|
238
248
|
_handleSlotChange() {
|
|
239
|
-
|
|
249
|
+
if (!this._hasResized) return;
|
|
250
|
+
|
|
251
|
+
requestAnimationFrame(async() => {
|
|
240
252
|
this._items = this._getTagListItems();
|
|
241
|
-
this.
|
|
253
|
+
if (!this._items || this._items.length === 0) return;
|
|
242
254
|
|
|
243
|
-
|
|
255
|
+
await Promise.all(this._items.map(item => item.updateComplete));
|
|
256
|
+
|
|
257
|
+
this._itemLayouts = this._getItemLayouts(this._items);
|
|
244
258
|
this._itemHeight = this._items[0].offsetHeight;
|
|
245
259
|
this._items.forEach((item, index) => {
|
|
246
260
|
item.setAttribute('tabIndex', index === 0 ? 0 : -1);
|
|
247
261
|
});
|
|
248
262
|
this._chomp();
|
|
263
|
+
this.requestUpdate();
|
|
249
264
|
});
|
|
250
265
|
}
|
|
251
266
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brightspace-ui/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.10.2",
|
|
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",
|