@brightspace-ui/core 2.39.1 → 2.42.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/filter/README.md +76 -1
- package/components/filter/demo/filter-overflow-group.html +168 -0
- package/components/filter/filter-overflow-group.js +65 -0
- package/components/overflow-group/overflow-group-mixin.js +50 -7
- package/components/overflow-group/overflow-group.js +1 -0
- package/custom-elements.json +62 -8
- package/helpers/README.md +4 -0
- package/helpers/dom.js +23 -0
- package/package.json +1 -1
|
@@ -254,7 +254,7 @@ A tag-list allowing the user to see (and remove) the currently applied filters.
|
|
|
254
254
|
display: block;
|
|
255
255
|
max-width: 100%;
|
|
256
256
|
}
|
|
257
|
-
|
|
257
|
+
}
|
|
258
258
|
</style>
|
|
259
259
|
<div class="filter-wrapper">
|
|
260
260
|
<d2l-filter-tags filter-ids="core-filter core-filter-2"></d2l-filter-tags>
|
|
@@ -298,6 +298,81 @@ A tag-list allowing the user to see (and remove) the currently applied filters.
|
|
|
298
298
|
| `label` | String | The text displayed in this component's label |
|
|
299
299
|
<!-- docs: end hidden content -->
|
|
300
300
|
|
|
301
|
+
## Filter Overflow Group [d2l-filter-overflow-group]
|
|
302
|
+
|
|
303
|
+
The `d2l-filter-overflow-group` is a container for multiple filters that handles overflow on smaller screens. Overflowing filters are displayed in a single filter.
|
|
304
|
+
|
|
305
|
+
<!-- docs: demo live name:d2l-filter-overflow-group align:start display:block autoSize:false size:medium -->
|
|
306
|
+
```html
|
|
307
|
+
<script type="module">
|
|
308
|
+
import '@brightspace-ui/core/components/filter/filter.js';
|
|
309
|
+
import '@brightspace-ui/core/components/filter/filter-dimension-set.js';
|
|
310
|
+
import '@brightspace-ui/core/components/filter/filter-dimension-set-value.js';
|
|
311
|
+
import '@brightspace-ui/core/components/filter/filter-overflow-group.js';
|
|
312
|
+
</script>
|
|
313
|
+
<d2l-filter-overflow-group>
|
|
314
|
+
<d2l-filter>
|
|
315
|
+
<d2l-filter-dimension-set key="skill" text="Skill">
|
|
316
|
+
<d2l-filter-dimension-set-value key="communication" text="Fall"></d2l-filter-dimension-set-value>
|
|
317
|
+
<d2l-filter-dimension-set-value key="leadership" text="Winter"></d2l-filter-dimension-set-value>
|
|
318
|
+
<d2l-filter-dimension-set-value key="management" text="Spring"></d2l-filter-dimension-set-value>
|
|
319
|
+
<d2l-filter-dimension-set-value key="planning" text="Summer"></d2l-filter-dimension-set-value>
|
|
320
|
+
</d2l-filter-dimension-set>
|
|
321
|
+
</d2l-filter>
|
|
322
|
+
<d2l-filter>
|
|
323
|
+
<d2l-filter-dimension-set key="type" text="Type" selection-single>
|
|
324
|
+
<d2l-filter-dimension-set-value key="certificate" text="Certificate"></d2l-filter-dimension-set-value>
|
|
325
|
+
<d2l-filter-dimension-set-value key="degree" text="Degree"></d2l-filter-dimension-set-value>
|
|
326
|
+
<d2l-filter-dimension-set-value key="diploma" text="Diploma"></d2l-filter-dimension-set-value>
|
|
327
|
+
<d2l-filter-dimension-set-value key="course" text="Course"></d2l-filter-dimension-set-value>
|
|
328
|
+
</d2l-filter-dimension-set>
|
|
329
|
+
</d2l-filter>
|
|
330
|
+
<d2l-filter>
|
|
331
|
+
<d2l-filter-dimension-set key="course" text="Course" select-all>
|
|
332
|
+
<d2l-filter-dimension-set-value key="art" text="Art"></d2l-filter-dimension-set-value>
|
|
333
|
+
<d2l-filter-dimension-set-value key="astronomy" text="Astronomy" selected></d2l-filter-dimension-set-value>
|
|
334
|
+
<d2l-filter-dimension-set-value key="biology" text="Biology"></d2l-filter-dimension-set-value>
|
|
335
|
+
<d2l-filter-dimension-set-value key="chemistry" text="Chemistry"></d2l-filter-dimension-set-value>
|
|
336
|
+
</d2l-filter-dimension-set>
|
|
337
|
+
<d2l-filter-dimension-set key="duration" text="Duration">
|
|
338
|
+
<d2l-filter-dimension-set-value key="lessthanthree" text="< 3 months"></d2l-filter-dimension-set-value>
|
|
339
|
+
<d2l-filter-dimension-set-value key="threetosix" text="3-6 months"></d2l-filter-dimension-set-value>
|
|
340
|
+
<d2l-filter-dimension-set-value key="sixtotwelve" text="6-12 months"></d2l-filter-dimension-set-value>
|
|
341
|
+
</d2l-filter-dimension-set>
|
|
342
|
+
</d2l-filter>
|
|
343
|
+
<d2l-filter>
|
|
344
|
+
<d2l-filter-dimension-set key="provider" text="Semester3">
|
|
345
|
+
<d2l-filter-dimension-set-value key="mcmaster" text="McMaster"></d2l-filter-dimension-set-value>
|
|
346
|
+
<d2l-filter-dimension-set-value key="powered" text="PowerED"></d2l-filter-dimension-set-value>
|
|
347
|
+
<d2l-filter-dimension-set-value key="guelph" text="University of Guelph"></d2l-filter-dimension-set-value>
|
|
348
|
+
<d2l-filter-dimension-set-value key="manitoba" text="University of Manitoba"></d2l-filter-dimension-set-value>
|
|
349
|
+
</d2l-filter-dimension-set>
|
|
350
|
+
</d2l-filter>
|
|
351
|
+
<d2l-filter>
|
|
352
|
+
<d2l-filter-dimension-set key="format" text="Format">
|
|
353
|
+
<d2l-filter-dimension-set-value key="selfpaced" text="Self-Paced"></d2l-filter-dimension-set-value>
|
|
354
|
+
<d2l-filter-dimension-set-value key="instructor" text="Instructor Lead" selected></d2l-filter-dimension-set-value>
|
|
355
|
+
</d2l-filter-dimension-set>
|
|
356
|
+
</d2l-filter>
|
|
357
|
+
<d2l-filter>
|
|
358
|
+
<d2l-filter-dimension-set key="language" text="Language" selection-single>
|
|
359
|
+
<d2l-filter-dimension-set-value key="english" text="English"></d2l-filter-dimension-set-value>
|
|
360
|
+
<d2l-filter-dimension-set-value key="french" text="French"></d2l-filter-dimension-set-value>
|
|
361
|
+
<d2l-filter-dimension-set-value key="spanish" text="Spanish"></d2l-filter-dimension-set-value>
|
|
362
|
+
</d2l-filter-dimension-set>
|
|
363
|
+
</d2l-filter>
|
|
364
|
+
</d2l-filter-overflow-group>
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
<!-- docs: start hidden content -->
|
|
368
|
+
### Properties
|
|
369
|
+
|
|
370
|
+
| Property | Type | Description |
|
|
371
|
+
|---|---|---|
|
|
372
|
+
| `min-to-show` | Number | The minimum number of elements to always show. Please consult the design team when using this attribute. |
|
|
373
|
+
| `max-to-show` | Number | The maximum number of elements to show |
|
|
374
|
+
<!-- docs: end hidden content -->
|
|
375
|
+
|
|
301
376
|
## Filter Dimension: Date [d2l-filter-dimension-date]
|
|
302
377
|
|
|
303
378
|
**Coming Soon!**
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<link rel="stylesheet" href="../../demo/styles.css" type="text/css">
|
|
6
|
+
<script type="module">
|
|
7
|
+
import '../../demo/demo-page.js';
|
|
8
|
+
import '../../filter/filter.js';
|
|
9
|
+
import '../../filter/filter-dimension-set.js';
|
|
10
|
+
import '../../filter/filter-dimension-set-value.js';
|
|
11
|
+
import '../../filter/filter-overflow-group.js';
|
|
12
|
+
import '../../filter/filter-tags.js';
|
|
13
|
+
</script>
|
|
14
|
+
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1.0">
|
|
15
|
+
<meta charset="UTF-8">
|
|
16
|
+
<style>
|
|
17
|
+
d2l-filter-tags {
|
|
18
|
+
padding-top: 1rem;
|
|
19
|
+
}
|
|
20
|
+
</style>
|
|
21
|
+
</head>
|
|
22
|
+
|
|
23
|
+
<body unresolved>
|
|
24
|
+
|
|
25
|
+
<d2l-demo-page page-title="d2l-filter-overflow-group">
|
|
26
|
+
|
|
27
|
+
<h2>Filter Overflow Group</h2>
|
|
28
|
+
<d2l-demo-snippet>
|
|
29
|
+
<template>
|
|
30
|
+
<d2l-filter-overflow-group>
|
|
31
|
+
<d2l-filter>
|
|
32
|
+
<d2l-filter-dimension-set key="skill" text="Skill">
|
|
33
|
+
<d2l-filter-dimension-set-value key="communication" text="Fall"></d2l-filter-dimension-set-value>
|
|
34
|
+
<d2l-filter-dimension-set-value key="leadership" text="Winter"></d2l-filter-dimension-set-value>
|
|
35
|
+
<d2l-filter-dimension-set-value key="management" text="Spring"></d2l-filter-dimension-set-value>
|
|
36
|
+
<d2l-filter-dimension-set-value key="planning" text="Summer"></d2l-filter-dimension-set-value>
|
|
37
|
+
</d2l-filter-dimension-set>
|
|
38
|
+
</d2l-filter>
|
|
39
|
+
<d2l-filter>
|
|
40
|
+
<d2l-filter-dimension-set key="type" text="Type" selection-single>
|
|
41
|
+
<d2l-filter-dimension-set-value key="certificate" text="Certificate"></d2l-filter-dimension-set-value>
|
|
42
|
+
<d2l-filter-dimension-set-value key="degree" text="Degree"></d2l-filter-dimension-set-value>
|
|
43
|
+
<d2l-filter-dimension-set-value key="diploma" text="Diploma"></d2l-filter-dimension-set-value>
|
|
44
|
+
<d2l-filter-dimension-set-value key="course" text="Course"></d2l-filter-dimension-set-value>
|
|
45
|
+
</d2l-filter-dimension-set>
|
|
46
|
+
</d2l-filter>
|
|
47
|
+
<d2l-filter>
|
|
48
|
+
<d2l-filter-dimension-set key="provider" text="Semester3">
|
|
49
|
+
<d2l-filter-dimension-set-value key="mcmaster" text="McMaster"></d2l-filter-dimension-set-value>
|
|
50
|
+
<d2l-filter-dimension-set-value key="powered" text="PowerED"></d2l-filter-dimension-set-value>
|
|
51
|
+
<d2l-filter-dimension-set-value key="guelph" text="University of Guelph"></d2l-filter-dimension-set-value>
|
|
52
|
+
<d2l-filter-dimension-set-value key="manitoba" text="University of Manitoba"></d2l-filter-dimension-set-value>
|
|
53
|
+
</d2l-filter-dimension-set>
|
|
54
|
+
</d2l-filter>
|
|
55
|
+
<d2l-filter>
|
|
56
|
+
<d2l-filter-dimension-set key="format" text="Format">
|
|
57
|
+
<d2l-filter-dimension-set-value key="selfpaced" text="Self-Paced"></d2l-filter-dimension-set-value>
|
|
58
|
+
<d2l-filter-dimension-set-value key="instructor" text="Instructor Lead" selected></d2l-filter-dimension-set-value>
|
|
59
|
+
</d2l-filter-dimension-set>
|
|
60
|
+
</d2l-filter>
|
|
61
|
+
<d2l-filter>
|
|
62
|
+
<d2l-filter-dimension-set key="language" text="Language" selection-single>
|
|
63
|
+
<d2l-filter-dimension-set-value key="english" text="English"></d2l-filter-dimension-set-value>
|
|
64
|
+
<d2l-filter-dimension-set-value key="french" text="French"></d2l-filter-dimension-set-value>
|
|
65
|
+
<d2l-filter-dimension-set-value key="spanish" text="Spanish"></d2l-filter-dimension-set-value>
|
|
66
|
+
</d2l-filter-dimension-set>
|
|
67
|
+
</d2l-filter>
|
|
68
|
+
<d2l-filter>
|
|
69
|
+
<d2l-filter-dimension-set key="course" text="Course" select-all>
|
|
70
|
+
<d2l-filter-dimension-set-value key="art" text="Art"></d2l-filter-dimension-set-value>
|
|
71
|
+
<d2l-filter-dimension-set-value key="astronomy" text="Astronomy" selected></d2l-filter-dimension-set-value>
|
|
72
|
+
<d2l-filter-dimension-set-value key="biology" text="Biology"></d2l-filter-dimension-set-value>
|
|
73
|
+
<d2l-filter-dimension-set-value key="chemistry" text="Chemistry"></d2l-filter-dimension-set-value>
|
|
74
|
+
<d2l-filter-dimension-set-value key="drama" text="Drama"></d2l-filter-dimension-set-value>
|
|
75
|
+
<d2l-filter-dimension-set-value key="english" text="English"></d2l-filter-dimension-set-value>
|
|
76
|
+
<d2l-filter-dimension-set-value key="how-to" text="How To Write a How To Article With a Flashy Title"></d2l-filter-dimension-set-value>
|
|
77
|
+
<d2l-filter-dimension-set-value key="math" text="Math"></d2l-filter-dimension-set-value>
|
|
78
|
+
<d2l-filter-dimension-set-value key="physics" text="Physics"></d2l-filter-dimension-set-value>
|
|
79
|
+
<d2l-filter-dimension-set-value key="stats" text="Statistics"></d2l-filter-dimension-set-value>
|
|
80
|
+
<d2l-filter-dimension-set-value key="writerscraft" text="Writer's Craft"></d2l-filter-dimension-set-value>
|
|
81
|
+
</d2l-filter-dimension-set>
|
|
82
|
+
<d2l-filter-dimension-set key="duration" text="Duration">
|
|
83
|
+
<d2l-filter-dimension-set-value key="lessthanthree" text="< 3 months"></d2l-filter-dimension-set-value>
|
|
84
|
+
<d2l-filter-dimension-set-value key="threetosix" text="3-6 months"></d2l-filter-dimension-set-value>
|
|
85
|
+
<d2l-filter-dimension-set-value key="sixtotwelve" text="6-12 months"></d2l-filter-dimension-set-value>
|
|
86
|
+
</d2l-filter-dimension-set>
|
|
87
|
+
<d2l-filter-dimension-set key="hoursperweek" text="SemesterNested" selection-single>
|
|
88
|
+
<d2l-filter-dimension-set-value key="lessthanfive" text="< 5 hrs/week"></d2l-filter-dimension-set-value>
|
|
89
|
+
<d2l-filter-dimension-set-value key="fivetoten" text="5-10 hrs/week" selected></d2l-filter-dimension-set-value>
|
|
90
|
+
<d2l-filter-dimension-set-value key="tentotwenty" text="10-20 hrs/week"></d2l-filter-dimension-set-value>
|
|
91
|
+
</d2l-filter-dimension-set>
|
|
92
|
+
</d2l-filter>
|
|
93
|
+
</d2l-filter-overflow-group>
|
|
94
|
+
</template>
|
|
95
|
+
</d2l-demo-snippet>
|
|
96
|
+
|
|
97
|
+
<h2>Filter Overflow Group with Tags (external to d2l-filter-overflow-group)</h2>
|
|
98
|
+
<d2l-demo-snippet>
|
|
99
|
+
<template>
|
|
100
|
+
<d2l-filter-overflow-group>
|
|
101
|
+
<d2l-filter id="filter1">
|
|
102
|
+
<d2l-filter-dimension-set key="skill" text="Skill">
|
|
103
|
+
<d2l-filter-dimension-set-value key="communication" text="Fall"></d2l-filter-dimension-set-value>
|
|
104
|
+
<d2l-filter-dimension-set-value key="leadership" text="Winter"></d2l-filter-dimension-set-value>
|
|
105
|
+
<d2l-filter-dimension-set-value key="management" text="Spring"></d2l-filter-dimension-set-value>
|
|
106
|
+
<d2l-filter-dimension-set-value key="planning" text="Summer"></d2l-filter-dimension-set-value>
|
|
107
|
+
</d2l-filter-dimension-set>
|
|
108
|
+
</d2l-filter>
|
|
109
|
+
<d2l-filter id="filter2">
|
|
110
|
+
<d2l-filter-dimension-set key="type" text="Type" selection-single>
|
|
111
|
+
<d2l-filter-dimension-set-value key="certificate" text="Certificate"></d2l-filter-dimension-set-value>
|
|
112
|
+
<d2l-filter-dimension-set-value key="degree" text="Degree"></d2l-filter-dimension-set-value>
|
|
113
|
+
<d2l-filter-dimension-set-value key="diploma" text="Diploma"></d2l-filter-dimension-set-value>
|
|
114
|
+
<d2l-filter-dimension-set-value key="course" text="Course"></d2l-filter-dimension-set-value>
|
|
115
|
+
</d2l-filter-dimension-set>
|
|
116
|
+
</d2l-filter>
|
|
117
|
+
<d2l-filter id="filter3">
|
|
118
|
+
<d2l-filter-dimension-set key="provider" text="Semester3">
|
|
119
|
+
<d2l-filter-dimension-set-value key="mcmaster" text="McMaster"></d2l-filter-dimension-set-value>
|
|
120
|
+
<d2l-filter-dimension-set-value key="powered" text="PowerED"></d2l-filter-dimension-set-value>
|
|
121
|
+
<d2l-filter-dimension-set-value key="guelph" text="University of Guelph"></d2l-filter-dimension-set-value>
|
|
122
|
+
<d2l-filter-dimension-set-value key="manitoba" text="University of Manitoba"></d2l-filter-dimension-set-value>
|
|
123
|
+
</d2l-filter-dimension-set>
|
|
124
|
+
</d2l-filter>
|
|
125
|
+
<d2l-filter id="filter4">
|
|
126
|
+
<d2l-filter-dimension-set key="format" text="Format">
|
|
127
|
+
<d2l-filter-dimension-set-value key="selfpaced" text="Self-Paced"></d2l-filter-dimension-set-value>
|
|
128
|
+
<d2l-filter-dimension-set-value key="instructor" text="Instructor Lead" selected></d2l-filter-dimension-set-value>
|
|
129
|
+
</d2l-filter-dimension-set>
|
|
130
|
+
</d2l-filter>
|
|
131
|
+
<d2l-filter id="filter5">
|
|
132
|
+
<d2l-filter-dimension-set key="language" text="Language" selection-single>
|
|
133
|
+
<d2l-filter-dimension-set-value key="english" text="English"></d2l-filter-dimension-set-value>
|
|
134
|
+
<d2l-filter-dimension-set-value key="french" text="French"></d2l-filter-dimension-set-value>
|
|
135
|
+
<d2l-filter-dimension-set-value key="spanish" text="Spanish"></d2l-filter-dimension-set-value>
|
|
136
|
+
</d2l-filter-dimension-set>
|
|
137
|
+
</d2l-filter>
|
|
138
|
+
<d2l-filter id="filter6">
|
|
139
|
+
<d2l-filter-dimension-set key="course" text="Course" select-all>
|
|
140
|
+
<d2l-filter-dimension-set-value key="art" text="Art"></d2l-filter-dimension-set-value>
|
|
141
|
+
<d2l-filter-dimension-set-value key="astronomy" text="Astronomy" selected></d2l-filter-dimension-set-value>
|
|
142
|
+
<d2l-filter-dimension-set-value key="biology" text="Biology"></d2l-filter-dimension-set-value>
|
|
143
|
+
<d2l-filter-dimension-set-value key="chemistry" text="Chemistry"></d2l-filter-dimension-set-value>
|
|
144
|
+
<d2l-filter-dimension-set-value key="drama" text="Drama"></d2l-filter-dimension-set-value>
|
|
145
|
+
<d2l-filter-dimension-set-value key="english" text="English"></d2l-filter-dimension-set-value>
|
|
146
|
+
<d2l-filter-dimension-set-value key="how-to" text="How To Write a How To Article With a Flashy Title"></d2l-filter-dimension-set-value>
|
|
147
|
+
<d2l-filter-dimension-set-value key="math" text="Math"></d2l-filter-dimension-set-value>
|
|
148
|
+
<d2l-filter-dimension-set-value key="physics" text="Physics"></d2l-filter-dimension-set-value>
|
|
149
|
+
<d2l-filter-dimension-set-value key="stats" text="Statistics"></d2l-filter-dimension-set-value>
|
|
150
|
+
<d2l-filter-dimension-set-value key="writerscraft" text="Writer's Craft"></d2l-filter-dimension-set-value>
|
|
151
|
+
</d2l-filter-dimension-set>
|
|
152
|
+
<d2l-filter-dimension-set key="duration" text="Duration">
|
|
153
|
+
<d2l-filter-dimension-set-value key="lessthanthree" text="< 3 months"></d2l-filter-dimension-set-value>
|
|
154
|
+
<d2l-filter-dimension-set-value key="threetosix" text="3-6 months"></d2l-filter-dimension-set-value>
|
|
155
|
+
<d2l-filter-dimension-set-value key="sixtotwelve" text="6-12 months"></d2l-filter-dimension-set-value>
|
|
156
|
+
</d2l-filter-dimension-set>
|
|
157
|
+
<d2l-filter-dimension-set key="hoursperweek" text="SemesterNested" selection-single>
|
|
158
|
+
<d2l-filter-dimension-set-value key="lessthanfive" text="< 5 hrs/week"></d2l-filter-dimension-set-value>
|
|
159
|
+
<d2l-filter-dimension-set-value key="fivetoten" text="5-10 hrs/week" selected></d2l-filter-dimension-set-value>
|
|
160
|
+
<d2l-filter-dimension-set-value key="tentotwenty" text="10-20 hrs/week"></d2l-filter-dimension-set-value>
|
|
161
|
+
</d2l-filter-dimension-set>
|
|
162
|
+
</d2l-filter-overflow-group>
|
|
163
|
+
<d2l-filter-tags filter-ids="filter1 filter2 filter3 filter4 filter5 filter6" label="Applied Filters:"></d2l-filter-tags>
|
|
164
|
+
</template>
|
|
165
|
+
</d2l-demo-snippet>
|
|
166
|
+
</d2l-demo-page>
|
|
167
|
+
</body>
|
|
168
|
+
</html>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import './filter.js';
|
|
2
|
+
import { css, html, LitElement } from 'lit';
|
|
3
|
+
import { OVERFLOW_CLASS, OverflowGroupMixin } from '../overflow-group/overflow-group-mixin.js';
|
|
4
|
+
import { RtlMixin } from '../../mixins/rtl-mixin.js';
|
|
5
|
+
|
|
6
|
+
function createFilterItem(node) {
|
|
7
|
+
const dimensionSets = node.querySelectorAll('d2l-filter-dimension-set');
|
|
8
|
+
const clones = Array.from(dimensionSets).map((set) => set.cloneNode(true));
|
|
9
|
+
return clones;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A component that can be used to display a group of filters that will be put into an overflow filter when they no longer fit on the first line of their container
|
|
14
|
+
* @slot - d2l-filters to be added to the container
|
|
15
|
+
*/
|
|
16
|
+
class FilterOverflowGroup extends OverflowGroupMixin(RtlMixin(LitElement)) {
|
|
17
|
+
|
|
18
|
+
static get styles() {
|
|
19
|
+
return [super.styles, css`
|
|
20
|
+
::slotted(d2l-filter) {
|
|
21
|
+
margin-right: 0.3rem;
|
|
22
|
+
}
|
|
23
|
+
:host([dir="rtl"]) ::slotted(d2l-filter) {
|
|
24
|
+
margin-left: 0.3rem;
|
|
25
|
+
margin-right: 0;
|
|
26
|
+
}
|
|
27
|
+
`];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
firstUpdated(changedProperties) {
|
|
31
|
+
super.firstUpdated(changedProperties);
|
|
32
|
+
|
|
33
|
+
this.addEventListener('d2l-filter-change', this._handleFilterChange);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
convertToOverflowItem(node) {
|
|
37
|
+
const tagName = node.tagName.toLowerCase();
|
|
38
|
+
if (tagName !== 'd2l-filter') console.warn(`d2l-filter-overflow-group: ${tagName} is invalid in this group. This group should only contain d2l-filter direct child elements.`);
|
|
39
|
+
else return createFilterItem(node);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
getOverflowContainer(overflowItems) {
|
|
43
|
+
return html`
|
|
44
|
+
<d2l-filter class="${OVERFLOW_CLASS}" @d2l-filter-change="${this._handleFilterChange}">
|
|
45
|
+
${overflowItems}
|
|
46
|
+
</d2l-filter>
|
|
47
|
+
`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
_handleFilterChange(e) {
|
|
51
|
+
const target = (e.target.classList && e.target.classList.contains(OVERFLOW_CLASS)) ? this : e.target;
|
|
52
|
+
e.detail.dimensions.forEach((dimension) => {
|
|
53
|
+
const filterSet = target.querySelector(`d2l-filter-dimension-set[key=${dimension.dimensionKey}`);
|
|
54
|
+
if (!filterSet) return;
|
|
55
|
+
dimension.changes.forEach((change) => {
|
|
56
|
+
const filterSetValue = filterSet.querySelector(`d2l-filter-dimension-set-value[key=${change.valueKey}]`);
|
|
57
|
+
if (!filterSetValue) return;
|
|
58
|
+
filterSetValue.selected = change.selected;
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
customElements.define('d2l-filter-overflow-group', FilterOverflowGroup);
|
|
@@ -2,6 +2,7 @@ import { css, html, nothing } from 'lit';
|
|
|
2
2
|
import { LocalizeCoreElement } from '../../helpers/localize-core-element.js';
|
|
3
3
|
import { offscreenStyles } from '../offscreen/offscreen.js';
|
|
4
4
|
import ResizeObserver from 'resize-observer-polyfill/dist/ResizeObserver.es.js';
|
|
5
|
+
import { styleMap } from 'lit/directives/style-map.js';
|
|
5
6
|
|
|
6
7
|
export const OVERFLOW_CLASS = 'd2l-overflow-container';
|
|
7
8
|
export const OVERFLOW_MINI_CLASS = 'd2l-overflow-container-mini';
|
|
@@ -28,8 +29,7 @@ export const OverflowGroupMixin = superclass => class extends LocalizeCoreElemen
|
|
|
28
29
|
static get properties() {
|
|
29
30
|
return {
|
|
30
31
|
/**
|
|
31
|
-
*
|
|
32
|
-
* @type {boolean}
|
|
32
|
+
* @ignore
|
|
33
33
|
*/
|
|
34
34
|
autoShow: {
|
|
35
35
|
type: Boolean,
|
|
@@ -95,7 +95,9 @@ export const OverflowGroupMixin = superclass => class extends LocalizeCoreElemen
|
|
|
95
95
|
this._handleResize = this._handleResize.bind(this);
|
|
96
96
|
this._resizeObserver = new ResizeObserver((entries) => requestAnimationFrame(() => this._handleResize(entries)));
|
|
97
97
|
|
|
98
|
+
this._hasResized = false;
|
|
98
99
|
this._isObserving = false;
|
|
100
|
+
this._itemHeight = 0;
|
|
99
101
|
this._mini = this.openerType === OPENER_TYPE.ICON;
|
|
100
102
|
this._overflowContainerHidden = false;
|
|
101
103
|
this._slotItems = [];
|
|
@@ -129,8 +131,13 @@ export const OverflowGroupMixin = superclass => class extends LocalizeCoreElemen
|
|
|
129
131
|
}
|
|
130
132
|
});
|
|
131
133
|
|
|
134
|
+
const containerStyles = {
|
|
135
|
+
minHeight: this.autoShow ? 'none' : `${this._itemHeight}px`,
|
|
136
|
+
maxHeight: this.autoShow ? 'none' : `${this._itemHeight}px`
|
|
137
|
+
};
|
|
138
|
+
|
|
132
139
|
return html`
|
|
133
|
-
<div class="d2l-overflow-group-container">
|
|
140
|
+
<div class="d2l-overflow-group-container" style="${styleMap(containerStyles)}">
|
|
134
141
|
<slot @slotchange="${this._handleSlotChange}"></slot>
|
|
135
142
|
${overflowContainer}
|
|
136
143
|
</div>
|
|
@@ -163,6 +170,14 @@ export const OverflowGroupMixin = superclass => class extends LocalizeCoreElemen
|
|
|
163
170
|
}
|
|
164
171
|
}
|
|
165
172
|
|
|
173
|
+
convertToOverflowItem() {
|
|
174
|
+
throw new Error('OverflowGroupMixin.convertToOverflowItem must be overridden');
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
getOverflowContainer() {
|
|
178
|
+
throw new Error('OverflowGroupMixin.getOverflowContainer must be overridden');
|
|
179
|
+
}
|
|
180
|
+
|
|
166
181
|
_autoDetectBoundaries(items) {
|
|
167
182
|
if (!items) return;
|
|
168
183
|
|
|
@@ -196,6 +211,7 @@ export const OverflowGroupMixin = superclass => class extends LocalizeCoreElemen
|
|
|
196
211
|
} else if (this._overflowContainer) {
|
|
197
212
|
this._overflowContainerWidth = this._overflowContainer.offsetWidth;
|
|
198
213
|
}
|
|
214
|
+
this._overflowContainerWidth = this._overflowContainerWidth || 0;
|
|
199
215
|
|
|
200
216
|
const showing = {
|
|
201
217
|
count: 0,
|
|
@@ -268,12 +284,15 @@ export const OverflowGroupMixin = superclass => class extends LocalizeCoreElemen
|
|
|
268
284
|
|
|
269
285
|
_getItemLayouts(filteredNodes) {
|
|
270
286
|
const items = filteredNodes.map((node) => {
|
|
287
|
+
node.removeAttribute('data-is-chomped');
|
|
271
288
|
const computedStyles = window.getComputedStyle(node);
|
|
289
|
+
const itemHidden = computedStyles.display === 'none';
|
|
290
|
+
this._itemHeight = !itemHidden ? Math.max(this._itemHeight, Math.ceil(parseFloat(computedStyles.height))) : this._itemHeight;
|
|
272
291
|
|
|
273
292
|
return {
|
|
274
293
|
type: node.tagName.toLowerCase(),
|
|
275
294
|
isChomped: false,
|
|
276
|
-
isHidden:
|
|
295
|
+
isHidden: itemHidden,
|
|
277
296
|
width: Math.ceil(parseFloat(computedStyles.width) || 0)
|
|
278
297
|
+ parseInt(computedStyles.marginRight) || 0
|
|
279
298
|
+ parseInt(computedStyles.marginLeft) || 0,
|
|
@@ -307,20 +326,44 @@ export const OverflowGroupMixin = superclass => class extends LocalizeCoreElemen
|
|
|
307
326
|
if (!mutations || mutations.length === 0) return;
|
|
308
327
|
if (this._updateOverflowItemsRequested) return;
|
|
309
328
|
|
|
329
|
+
let isWidthModifyingMutation = false;
|
|
330
|
+
for (const mutation of mutations) {
|
|
331
|
+
if (mutation.attributeName
|
|
332
|
+
&& (mutation.attributeName === 'selected' || mutation.attributeName === 'text')
|
|
333
|
+
) {
|
|
334
|
+
isWidthModifyingMutation = true;
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
310
339
|
this._updateOverflowItemsRequested = true;
|
|
311
340
|
setTimeout(() => {
|
|
312
|
-
this._overflowItems = this._slotItems.map(node => this.convertToOverflowItem(node));
|
|
341
|
+
this._overflowItems = this._slotItems.map((node) => this.convertToOverflowItem(node));
|
|
342
|
+
|
|
343
|
+
// when certain attributes change the corresponding item width can also change and so we need to re-get the layouts and chomp
|
|
344
|
+
if (isWidthModifyingMutation) {
|
|
345
|
+
this._itemLayouts = this._getItemLayouts(this._slotItems);
|
|
346
|
+
this._chomp();
|
|
347
|
+
}
|
|
313
348
|
this._updateOverflowItemsRequested = false;
|
|
314
349
|
this.requestUpdate();
|
|
315
350
|
}, 0);
|
|
316
351
|
}
|
|
317
352
|
|
|
318
|
-
_handleResize(entries) {
|
|
353
|
+
async _handleResize(entries) {
|
|
354
|
+
await (document.fonts ? document.fonts.ready : Promise.resolve()); // computed widths can be incorrect if we don't wait for fonts to load
|
|
319
355
|
this._availableWidth = Math.ceil(entries[0].contentRect.width);
|
|
320
|
-
|
|
356
|
+
|
|
357
|
+
if (!this._hasResized) {
|
|
358
|
+
this._hasResized = true;
|
|
359
|
+
await this._handleSlotChange();
|
|
360
|
+
} else {
|
|
361
|
+
this._chomp();
|
|
362
|
+
}
|
|
321
363
|
}
|
|
322
364
|
|
|
323
365
|
_handleSlotChange() {
|
|
366
|
+
if (!this._hasResized) return;
|
|
324
367
|
requestAnimationFrame(async() => {
|
|
325
368
|
await this._getItems();
|
|
326
369
|
|
|
@@ -56,6 +56,7 @@ function createMenuItemSeparator() {
|
|
|
56
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
|
|
57
57
|
* @slot - Buttons, dropdown buttons, links or other items to be added to the container
|
|
58
58
|
* @attr {'default'|'icon'} [opener-type="default"] - Set the opener type to 'icon' for a `...` menu icon instead of `More actions` text
|
|
59
|
+
* @attr {boolean} auto-show - Use predefined classes on slot elements to set min and max buttons to show
|
|
59
60
|
*/
|
|
60
61
|
class OverflowGroup extends OverflowGroupMixin(RtlMixin(LitElement)) {
|
|
61
62
|
|
package/custom-elements.json
CHANGED
|
@@ -3359,6 +3359,63 @@
|
|
|
3359
3359
|
}
|
|
3360
3360
|
]
|
|
3361
3361
|
},
|
|
3362
|
+
{
|
|
3363
|
+
"name": "d2l-filter-overflow-group",
|
|
3364
|
+
"path": "./components/filter/filter-overflow-group.js",
|
|
3365
|
+
"description": "A component that can be used to display a group of filters that will be put into an overflow filter when they no longer fit on the first line of their container",
|
|
3366
|
+
"attributes": [
|
|
3367
|
+
{
|
|
3368
|
+
"name": "max-to-show",
|
|
3369
|
+
"description": "maximum amount of slotted items to show",
|
|
3370
|
+
"type": "number",
|
|
3371
|
+
"default": "-1"
|
|
3372
|
+
},
|
|
3373
|
+
{
|
|
3374
|
+
"name": "min-to-show",
|
|
3375
|
+
"description": "minimum amount of slotted items to show",
|
|
3376
|
+
"type": "number",
|
|
3377
|
+
"default": "1"
|
|
3378
|
+
}
|
|
3379
|
+
],
|
|
3380
|
+
"properties": [
|
|
3381
|
+
{
|
|
3382
|
+
"name": "autoShow",
|
|
3383
|
+
"type": "boolean",
|
|
3384
|
+
"default": "false"
|
|
3385
|
+
},
|
|
3386
|
+
{
|
|
3387
|
+
"name": "maxToShow",
|
|
3388
|
+
"attribute": "max-to-show",
|
|
3389
|
+
"description": "maximum amount of slotted items to show",
|
|
3390
|
+
"type": "number",
|
|
3391
|
+
"default": "-1"
|
|
3392
|
+
},
|
|
3393
|
+
{
|
|
3394
|
+
"name": "minToShow",
|
|
3395
|
+
"attribute": "min-to-show",
|
|
3396
|
+
"description": "minimum amount of slotted items to show",
|
|
3397
|
+
"type": "number",
|
|
3398
|
+
"default": "1"
|
|
3399
|
+
},
|
|
3400
|
+
{
|
|
3401
|
+
"name": "openerType",
|
|
3402
|
+
"type": "string",
|
|
3403
|
+
"default": "\"DEFAULT\""
|
|
3404
|
+
}
|
|
3405
|
+
],
|
|
3406
|
+
"events": [
|
|
3407
|
+
{
|
|
3408
|
+
"name": "d2l-overflow-group-updated",
|
|
3409
|
+
"description": "Dispatched when there is an update performed to the overflow group"
|
|
3410
|
+
}
|
|
3411
|
+
],
|
|
3412
|
+
"slots": [
|
|
3413
|
+
{
|
|
3414
|
+
"name": "",
|
|
3415
|
+
"description": "d2l-filters to be added to the container"
|
|
3416
|
+
}
|
|
3417
|
+
]
|
|
3418
|
+
},
|
|
3362
3419
|
{
|
|
3363
3420
|
"name": "d2l-filter-tags",
|
|
3364
3421
|
"path": "./components/filter/filter-tags.js",
|
|
@@ -8766,12 +8823,6 @@
|
|
|
8766
8823
|
"type": "'default'|'subtle'",
|
|
8767
8824
|
"default": "\"\\\"default\\\"\""
|
|
8768
8825
|
},
|
|
8769
|
-
{
|
|
8770
|
-
"name": "auto-show",
|
|
8771
|
-
"description": "Use predefined classes on slot elements to set min and max slotted items to show",
|
|
8772
|
-
"type": "boolean",
|
|
8773
|
-
"default": "false"
|
|
8774
|
-
},
|
|
8775
8826
|
{
|
|
8776
8827
|
"name": "max-to-show",
|
|
8777
8828
|
"description": "maximum amount of slotted items to show",
|
|
@@ -8789,6 +8840,11 @@
|
|
|
8789
8840
|
"description": "Set the opener type to 'icon' for a `...` menu icon instead of `More actions` text",
|
|
8790
8841
|
"type": "'default'|'icon'",
|
|
8791
8842
|
"default": "\"default\""
|
|
8843
|
+
},
|
|
8844
|
+
{
|
|
8845
|
+
"name": "auto-show",
|
|
8846
|
+
"description": "Use predefined classes on slot elements to set min and max buttons to show",
|
|
8847
|
+
"type": "boolean"
|
|
8792
8848
|
}
|
|
8793
8849
|
],
|
|
8794
8850
|
"properties": [
|
|
@@ -8801,8 +8857,6 @@
|
|
|
8801
8857
|
},
|
|
8802
8858
|
{
|
|
8803
8859
|
"name": "autoShow",
|
|
8804
|
-
"attribute": "auto-show",
|
|
8805
|
-
"description": "Use predefined classes on slot elements to set min and max slotted items to show",
|
|
8806
8860
|
"type": "boolean",
|
|
8807
8861
|
"default": "false"
|
|
8808
8862
|
},
|
package/helpers/README.md
CHANGED
|
@@ -107,6 +107,10 @@ isComposedAncestor(ancestorNode, node);
|
|
|
107
107
|
|
|
108
108
|
// returns true/false whether the element is visible regardless of positioning
|
|
109
109
|
isVisible(node);
|
|
110
|
+
|
|
111
|
+
// similar to document.querySelector or element.querySelector,
|
|
112
|
+
// except it queries not just the light DOM but also shadow DOM
|
|
113
|
+
querySelectorComposed(node, selector)
|
|
110
114
|
```
|
|
111
115
|
|
|
112
116
|
## Focus
|
package/helpers/dom.js
CHANGED
|
@@ -227,3 +227,26 @@ export function isVisible(node) {
|
|
|
227
227
|
return true;
|
|
228
228
|
|
|
229
229
|
}
|
|
230
|
+
|
|
231
|
+
export function querySelectorComposed(node, selector) {
|
|
232
|
+
|
|
233
|
+
if (!node || (node.nodeType !== 1 && node.nodeType !== 9 && node.nodeType !== 11)) {
|
|
234
|
+
throw new TypeError('Invalid node. Must be nodeType document, element or document fragment');
|
|
235
|
+
}
|
|
236
|
+
if (typeof selector !== 'string') {
|
|
237
|
+
throw new TypeError('Invalid selector');
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const elem = node.querySelector(selector);
|
|
241
|
+
if (elem) return elem;
|
|
242
|
+
|
|
243
|
+
const allElems = node.querySelectorAll('*');
|
|
244
|
+
for (const elem of allElems) {
|
|
245
|
+
if (elem.shadowRoot) {
|
|
246
|
+
const nestedElem = querySelectorComposed(elem.shadowRoot, selector);
|
|
247
|
+
if (nestedElem) return nestedElem;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return null;
|
|
252
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brightspace-ui/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.42.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",
|