@brightspace-ui/core 3.266.1 → 3.267.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/list-item-checkbox-mixin.js +9 -1
- package/components/list/list-item-drag-drop-mixin.js +30 -0
- package/components/list/list-item-drag-handle.js +41 -6
- package/components/list/list-item-generic-layout.js +27 -6
- package/components/list/list-item-link-mixin.js +4 -0
- package/components/list/list-item-mixin.js +29 -2
- package/components/list/list-item-placement-marker.js +53 -2
- package/components/page/page-divider-internal.js +154 -0
- package/components/page/page.js +137 -13
- package/custom-elements.json +106 -4
- package/lang/ar.js +5 -0
- package/lang/ca.js +5 -0
- package/lang/cy.js +5 -0
- package/lang/da.js +5 -0
- package/lang/de.js +5 -0
- package/lang/en-gb.js +5 -0
- package/lang/en.js +5 -0
- package/lang/es-es.js +5 -0
- package/lang/es.js +5 -0
- package/lang/fr-fr.js +5 -0
- package/lang/fr.js +5 -0
- package/lang/haw.js +5 -0
- package/lang/hi.js +5 -0
- package/lang/ja.js +5 -0
- package/lang/ko.js +5 -0
- package/lang/mi.js +5 -0
- package/lang/nl.js +5 -0
- package/lang/pt.js +5 -0
- package/lang/sv.js +5 -0
- package/lang/th.js +5 -0
- package/lang/tr.js +5 -0
- package/lang/vi.js +5 -0
- package/lang/zh-cn.js +5 -0
- package/lang/zh-tw.js +5 -0
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import '../selection/selection-input.js';
|
|
2
2
|
import { css, html, nothing } from 'lit';
|
|
3
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
3
4
|
import { getUniqueId } from '../../helpers/uniqueId.js';
|
|
4
5
|
import { isInteractiveInListItemComposedPath } from './list-item-mixin.js';
|
|
5
6
|
import { SelectionInfo } from '../selection/selection-mixin.js';
|
|
@@ -57,6 +58,9 @@ export const ListItemCheckboxMixin = superclass => class extends SkeletonMixin(s
|
|
|
57
58
|
:host([selection-disabled]) [slot="control-action"] [slot="content"] {
|
|
58
59
|
pointer-events: all;
|
|
59
60
|
}
|
|
61
|
+
:host([layout="tile"]) .bump-inline {
|
|
62
|
+
margin-inline-start: 2rem !important;
|
|
63
|
+
}
|
|
60
64
|
` ];
|
|
61
65
|
|
|
62
66
|
super.styles && styles.unshift(super.styles);
|
|
@@ -164,6 +168,9 @@ export const ListItemCheckboxMixin = superclass => class extends SkeletonMixin(s
|
|
|
164
168
|
}
|
|
165
169
|
|
|
166
170
|
_renderCheckbox() {
|
|
171
|
+
const classes = {
|
|
172
|
+
'bump-inline': this._keyboardActive
|
|
173
|
+
};
|
|
167
174
|
return this.selectable ? html`
|
|
168
175
|
<d2l-selection-input
|
|
169
176
|
@d2l-selection-change="${this._onCheckboxChange}"
|
|
@@ -177,7 +184,8 @@ export const ListItemCheckboxMixin = superclass => class extends SkeletonMixin(s
|
|
|
177
184
|
@mouseenter="${this._onMouseEnterSelection}"
|
|
178
185
|
@mouseleave="${this._onMouseLeaveSelection}"
|
|
179
186
|
?selected="${this.selected}"
|
|
180
|
-
?skeleton="${this.skeleton}"
|
|
187
|
+
?skeleton="${this.skeleton}"
|
|
188
|
+
class=${classMap(classes)}>
|
|
181
189
|
</d2l-selection-input>
|
|
182
190
|
` : nothing;
|
|
183
191
|
}
|
|
@@ -311,12 +311,32 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
311
311
|
width: 100%;
|
|
312
312
|
z-index: 1;
|
|
313
313
|
}
|
|
314
|
+
|
|
314
315
|
.d2l-list-item-drag-bottom-marker {
|
|
315
316
|
bottom: -6px;
|
|
316
317
|
}
|
|
317
318
|
.d2l-list-item-drag-top-marker {
|
|
318
319
|
top: -6px;
|
|
319
320
|
}
|
|
321
|
+
|
|
322
|
+
:host([layout="tile"]) .d2l-list-item-drag-bottom-marker,
|
|
323
|
+
:host([layout="tile"]) .d2l-list-item-drag-top-marker {
|
|
324
|
+
height: 100%;
|
|
325
|
+
width: auto;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
:host([layout="tile"]) .d2l-list-item-drag-bottom-marker {
|
|
329
|
+
/* The gap between the cards plus half the width of the marker */
|
|
330
|
+
inset-inline-end: calc(-0.9rem + 3px);
|
|
331
|
+
bottom: 0;
|
|
332
|
+
}
|
|
333
|
+
:host([layout="tile"]) .d2l-list-item-drag-top-marker {
|
|
334
|
+
/* The gap between the cards plus half the width of the marker */
|
|
335
|
+
inset-inline-start: calc(-0.9rem + 3px);
|
|
336
|
+
top: 0;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
|
|
320
340
|
.d2l-list-item-drag-area {
|
|
321
341
|
cursor: move;
|
|
322
342
|
height: 100%;
|
|
@@ -326,6 +346,11 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
326
346
|
grid-template-columns: 100%;
|
|
327
347
|
grid-template-rows: 1rem 1fr 1fr 1rem;
|
|
328
348
|
}
|
|
349
|
+
:host([layout="tile"]) .d2l-list-item-drag-drop-grid {
|
|
350
|
+
display: grid;
|
|
351
|
+
grid-template-columns: 1rem 1fr 1fr 1rem;
|
|
352
|
+
grid-template-rows: 100%;
|
|
353
|
+
}
|
|
329
354
|
:host([_drop-location="7"]) {
|
|
330
355
|
z-index: 1; /* drop target border must render on top of next adjacent border */
|
|
331
356
|
}
|
|
@@ -344,6 +369,10 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
344
369
|
d2l-list-item-drag-handle {
|
|
345
370
|
opacity: 0;
|
|
346
371
|
}
|
|
372
|
+
:host([layout="tile"][draggable]) d2l-list-item-drag-handle {
|
|
373
|
+
opacity: 1;
|
|
374
|
+
}
|
|
375
|
+
|
|
347
376
|
:host([selected]) d2l-list-item-drag-handle,
|
|
348
377
|
:host([current]) d2l-list-item-drag-handle,
|
|
349
378
|
:host([_drag-handle-show-always]) d2l-list-item-drag-handle,
|
|
@@ -858,6 +887,7 @@ export const ListItemDragDropMixin = superclass => class extends superclass {
|
|
|
858
887
|
?disabled="${this.keyboardDragDisabled}"
|
|
859
888
|
text="${ifDefined(this.dragHandleText)}"
|
|
860
889
|
keyboard-text-info="${ifDefined(this._keyboardTextInfo)}"
|
|
890
|
+
layout="${this.layout}"
|
|
861
891
|
@focusin="${this._onFocusinDragHandle}"
|
|
862
892
|
@focusout="${this._onFocusoutDragHandle}"
|
|
863
893
|
@d2l-list-item-drag-handle-action="${this._onDragHandleActions}">
|
|
@@ -38,6 +38,9 @@ export const dragActions = Object.freeze({
|
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
let hasDisplayedKeyboardTooltip = false;
|
|
41
|
+
export const resetDisplayedTooltip = () => {
|
|
42
|
+
hasDisplayedKeyboardTooltip = false;
|
|
43
|
+
};
|
|
41
44
|
|
|
42
45
|
/**
|
|
43
46
|
* @fires d2l-list-item-drag-handle-action - Dispatched when an action performed on the drag handle
|
|
@@ -61,6 +64,10 @@ class ListItemDragHandle extends LocalizeCoreElement(FocusMixin(LitElement)) {
|
|
|
61
64
|
* @type {string}
|
|
62
65
|
*/
|
|
63
66
|
text: { type: String },
|
|
67
|
+
/**
|
|
68
|
+
* When layout = tile, the drag handle become horizontal
|
|
69
|
+
*/
|
|
70
|
+
layout: { type: String },
|
|
64
71
|
_displayKeyboardTooltip: { type: Boolean },
|
|
65
72
|
_keyboardActive: { type: Boolean }
|
|
66
73
|
};
|
|
@@ -117,6 +124,12 @@ class ListItemDragHandle extends LocalizeCoreElement(FocusMixin(LitElement)) {
|
|
|
117
124
|
d2l-button-move {
|
|
118
125
|
pointer-events: auto; /* required since ancestors may set point-events: none; (see generic layout) */
|
|
119
126
|
}
|
|
127
|
+
|
|
128
|
+
:host([layout="tile"]) {
|
|
129
|
+
align-items: center;
|
|
130
|
+
display: flex;
|
|
131
|
+
height: 39px;
|
|
132
|
+
}
|
|
120
133
|
`];
|
|
121
134
|
}
|
|
122
135
|
|
|
@@ -152,7 +165,9 @@ class ListItemDragHandle extends LocalizeCoreElement(FocusMixin(LitElement)) {
|
|
|
152
165
|
get _defaultLabel() {
|
|
153
166
|
const namespace = 'components.list-item-drag-handle';
|
|
154
167
|
const defaultLabel = this.localize(`${namespace}.${'default'}`, 'name', this.text);
|
|
155
|
-
const keyboardTextLabel = this.
|
|
168
|
+
const keyboardTextLabel = this.layout !== 'tile'
|
|
169
|
+
? this.localize(`${namespace}.${'keyboard'}`, 'currentPosition', this.keyboardTextInfo && this.keyboardTextInfo.currentPosition, 'size', this.keyboardTextInfo && this.keyboardTextInfo.count)
|
|
170
|
+
: this.localize(`${namespace}.${'side-to-side.keyboard'}`, 'currentPosition', this.keyboardTextInfo && this.keyboardTextInfo.currentPosition, 'size', this.keyboardTextInfo && this.keyboardTextInfo.count);
|
|
156
171
|
return this._keyboardActive ? keyboardTextLabel : defaultLabel;
|
|
157
172
|
}
|
|
158
173
|
|
|
@@ -182,6 +197,20 @@ class ListItemDragHandle extends LocalizeCoreElement(FocusMixin(LitElement)) {
|
|
|
182
197
|
|
|
183
198
|
const isRtl = document.documentElement.getAttribute('dir') === 'rtl';
|
|
184
199
|
|
|
200
|
+
if (this.layout === 'tile') {
|
|
201
|
+
if (!isRtl) {
|
|
202
|
+
if (e.detail.action === moveActions.right)
|
|
203
|
+
e.detail.action = moveActions.down;
|
|
204
|
+
if (e.detail.action === moveActions.left)
|
|
205
|
+
e.detail.action = moveActions.up;
|
|
206
|
+
} else {
|
|
207
|
+
if (e.detail.action === moveActions.right)
|
|
208
|
+
e.detail.action = moveActions.up;
|
|
209
|
+
if (e.detail.action === moveActions.left)
|
|
210
|
+
e.detail.action = moveActions.down;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
185
214
|
let action = null;
|
|
186
215
|
switch (e.detail.action) {
|
|
187
216
|
case moveActions.up:
|
|
@@ -299,19 +328,25 @@ class ListItemDragHandle extends LocalizeCoreElement(FocusMixin(LitElement)) {
|
|
|
299
328
|
id="${this._buttonId}"
|
|
300
329
|
@keydown="${this._onMoveButtonKeydown}"
|
|
301
330
|
@mousedown="${this._onMoveButtonMouseDown}"
|
|
302
|
-
text="${this._defaultLabel}"
|
|
331
|
+
text="${this._defaultLabel}"
|
|
332
|
+
?side-to-side="${this.layout === 'tile'}">
|
|
303
333
|
</d2l-button-move>
|
|
304
334
|
${this._displayKeyboardTooltip ? html`<d2l-tooltip class="vdiff-target" align="start" announced for="${this._buttonId}" for-type="descriptor">${this._renderTooltipContent()}</d2l-tooltip>` : ''}
|
|
305
335
|
`;
|
|
306
336
|
}
|
|
307
337
|
|
|
308
338
|
_renderTooltipContent() {
|
|
339
|
+
const namespace = 'components.list-item-drag-handle-tooltip';
|
|
340
|
+
const controlNamespace = this.layout === 'tile'
|
|
341
|
+
? `${namespace}.side-to-side`
|
|
342
|
+
: namespace;
|
|
343
|
+
|
|
309
344
|
return html`
|
|
310
|
-
<div>${this.localize(
|
|
345
|
+
<div>${this.localize(`${namespace}.title`)}</div>
|
|
311
346
|
<ul>
|
|
312
|
-
<li><span class="d2l-list-item-drag-handle-tooltip-key">${this.localize(
|
|
313
|
-
<li><span class="d2l-list-item-drag-handle-tooltip-key">${this.localize(
|
|
314
|
-
<li><span class="d2l-list-item-drag-handle-tooltip-key">${this.localize(
|
|
347
|
+
<li><span class="d2l-list-item-drag-handle-tooltip-key">${this.localize(`${namespace}.enter-key`)}</span> - ${this.localize(`${namespace}.enter-desc`)}</li>
|
|
348
|
+
<li><span class="d2l-list-item-drag-handle-tooltip-key">${this.localize(`${namespace}.up-down-key`)}</span> - ${this.localize(`${controlNamespace}.up-down-desc`)}</li>
|
|
349
|
+
<li><span class="d2l-list-item-drag-handle-tooltip-key">${this.localize(`${namespace}.left-right-key`)}</span> - ${this.localize(`${controlNamespace}.left-right-desc`)}</li>
|
|
315
350
|
</ul>
|
|
316
351
|
`;
|
|
317
352
|
}
|
|
@@ -65,8 +65,7 @@ class ListItemGenericLayout extends LitElement {
|
|
|
65
65
|
/**
|
|
66
66
|
* @ignore
|
|
67
67
|
*/
|
|
68
|
-
layout: { type: String, reflect: true }
|
|
69
|
-
|
|
68
|
+
layout: { type: String, reflect: true },
|
|
70
69
|
};
|
|
71
70
|
}
|
|
72
71
|
|
|
@@ -216,7 +215,21 @@ class ListItemGenericLayout extends LitElement {
|
|
|
216
215
|
|
|
217
216
|
:host([layout="tile"]) {
|
|
218
217
|
grid-template-columns:
|
|
219
|
-
[start control-start] minmax(0,
|
|
218
|
+
[start outside-control-start] minmax(0, 26px)
|
|
219
|
+
[outside-control-end control-start] minmax(0, min-content)
|
|
220
|
+
[control-end actions-start] minmax(0, auto)
|
|
221
|
+
[actions-end end];
|
|
222
|
+
grid-template-rows:
|
|
223
|
+
[start header-start] minmax(0, min-content)
|
|
224
|
+
[header-end content-start] auto
|
|
225
|
+
[content-end end];
|
|
226
|
+
height: 100%;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
:host([layout="tile"]:not([is-draggable])) {
|
|
230
|
+
grid-template-columns:
|
|
231
|
+
[start outside-control-start] 0
|
|
232
|
+
[outside-control-end control-start] minmax(0, min-content)
|
|
220
233
|
[control-end actions-start] minmax(0, auto)
|
|
221
234
|
[actions-end end];
|
|
222
235
|
grid-template-rows:
|
|
@@ -258,14 +271,22 @@ class ListItemGenericLayout extends LitElement {
|
|
|
258
271
|
grid-row: content-start / content-end;
|
|
259
272
|
}
|
|
260
273
|
|
|
274
|
+
:host([layout="tile"]) ::slotted([slot="outside-control"]) {
|
|
275
|
+
grid-column: outside-control-start / outside-control-end;
|
|
276
|
+
grid-row: start / start;
|
|
277
|
+
width: min-content;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
:host([layout="tile"]) ::slotted([slot="outside-control-action"]) {
|
|
281
|
+
grid-column: start / end;
|
|
282
|
+
grid-row: start / start;
|
|
283
|
+
}
|
|
284
|
+
|
|
261
285
|
:host(:not([layout="tile"])) slot[name="header"],
|
|
262
286
|
:host([layout="tile"]) slot[name="add-top"],
|
|
263
287
|
:host([layout="tile"]) slot[name="control-container"],
|
|
264
288
|
:host([layout="tile"]) slot[name="before-content"],
|
|
265
|
-
:host([layout="tile"]) slot[name="outside-control"],
|
|
266
|
-
:host([layout="tile"]) slot[name="outside-control-action"],
|
|
267
289
|
:host([layout="tile"]) slot[name="expand-collapse"],
|
|
268
|
-
:host([layout="tile"]) slot[name="drop-target"],
|
|
269
290
|
:host([layout="tile"]) slot[name="nested"],
|
|
270
291
|
:host([layout="tile"]) slot[name="add"] {
|
|
271
292
|
display: none;
|
|
@@ -35,6 +35,10 @@ export const ListItemLinkMixin = superclass => class extends ListItemMixin(super
|
|
|
35
35
|
:host([action-href]:not([action-href=""])) [slot="outside-control-action"] {
|
|
36
36
|
grid-column-end: control-end;
|
|
37
37
|
}
|
|
38
|
+
|
|
39
|
+
:host([action-href]:not([action-href=""])[layout="tile"]) [slot="outside-control-action"] {
|
|
40
|
+
grid-column-end: end;
|
|
41
|
+
}
|
|
38
42
|
` ];
|
|
39
43
|
|
|
40
44
|
super.styles && styles.unshift(super.styles);
|
|
@@ -163,6 +163,11 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
|
163
163
|
background: white;
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
:host([dragging][layout="tile"]) d2l-list-item-generic-layout {
|
|
167
|
+
filter: grayscale(75%);
|
|
168
|
+
opacity: 0.4;
|
|
169
|
+
}
|
|
170
|
+
|
|
166
171
|
[slot="control-container"] {
|
|
167
172
|
pointer-events: none;
|
|
168
173
|
position: relative;
|
|
@@ -333,6 +338,11 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
|
333
338
|
margin: 0.25rem 0.3rem;
|
|
334
339
|
}
|
|
335
340
|
|
|
341
|
+
:host([layout="tile"]) d2l-list-item-drag-handle {
|
|
342
|
+
margin-block: 0;
|
|
343
|
+
margin-inline: 0.3rem 0;
|
|
344
|
+
}
|
|
345
|
+
|
|
336
346
|
[slot="outside-control-container"] {
|
|
337
347
|
border: 1px solid transparent;
|
|
338
348
|
border-radius: 6px;
|
|
@@ -474,6 +484,7 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
|
474
484
|
transform: translateY(-10px);
|
|
475
485
|
transition: opacity 200ms ease-out, transform 0ms ease-out 300ms;
|
|
476
486
|
}
|
|
487
|
+
|
|
477
488
|
:host([layout="tile"][_selection-when-interacted]) [slot="control"]:hover,
|
|
478
489
|
:host([layout="tile"][_selection-when-interacted][_focusing]) [slot="control"],
|
|
479
490
|
:host([layout="tile"][_selection-when-interacted][_force-show-selection]) [slot="control"],
|
|
@@ -484,6 +495,10 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
|
484
495
|
transition: opacity 200ms ease-out, transform 200ms ease-out;
|
|
485
496
|
}
|
|
486
497
|
|
|
498
|
+
:host([layout="tile"][draggable][tile-header]) [slot="control"] {
|
|
499
|
+
margin: 0.25rem 0;
|
|
500
|
+
}
|
|
501
|
+
|
|
487
502
|
@media (prefers-reduced-motion: reduce) {
|
|
488
503
|
:host([layout="tile"][_selection-when-interacted]) [slot="control"] {
|
|
489
504
|
transform: none;
|
|
@@ -587,6 +602,11 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
|
587
602
|
:host([layout="tile"]) d2l-selection-input {
|
|
588
603
|
margin: 0;
|
|
589
604
|
}
|
|
605
|
+
|
|
606
|
+
:host([layout="tile"][draggable]) d2l-selection-input {
|
|
607
|
+
margin: auto;
|
|
608
|
+
margin-inline-start: 0.3rem;
|
|
609
|
+
}
|
|
590
610
|
:host([layout="tile"]:not([tile-header])) d2l-selection-input {
|
|
591
611
|
--d2l-input-checkbox-border-color-hover-focus: var(--d2l-color-celestine-minus-1);
|
|
592
612
|
--d2l-input-radio-border-color-hover-focus: var(--d2l-color-celestine-minus-1);
|
|
@@ -724,6 +744,9 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
|
724
744
|
this._hasListItemContent = !!this.shadowRoot.querySelector('slot:not([name])').assignedElements({ flatten: true })
|
|
725
745
|
.find(elem => elem.tagName === 'D2L-LIST-ITEM-CONTENT');
|
|
726
746
|
}
|
|
747
|
+
if (this.draggable) {
|
|
748
|
+
this.tileHeader = true;
|
|
749
|
+
}
|
|
727
750
|
}
|
|
728
751
|
|
|
729
752
|
focus() {
|
|
@@ -975,6 +998,8 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
|
975
998
|
data-separators="${ifDefined(this._separators)}"
|
|
976
999
|
indentation="${ifDefined(this.indentation)}"
|
|
977
1000
|
?grid-active="${this.role === 'row'}"
|
|
1001
|
+
?selectable="${this.selectable}"
|
|
1002
|
+
?is-draggable="${this.draggable}"
|
|
978
1003
|
layout="${this.layout}"
|
|
979
1004
|
?no-primary-action="${this.noPrimaryAction}">
|
|
980
1005
|
${this._showAddButton && this.first ? html`
|
|
@@ -1038,10 +1063,12 @@ export const ListItemMixin = superclass => class extends composeMixins(
|
|
|
1038
1063
|
</d2l-list-item-generic-layout>
|
|
1039
1064
|
`;
|
|
1040
1065
|
|
|
1066
|
+
const isDraggableTile = this.draggable && this.layout === 'tile';
|
|
1067
|
+
|
|
1041
1068
|
return html`
|
|
1042
|
-
${this._renderTopPlacementMarker(html`<d2l-list-item-placement-marker></d2l-list-item-placement-marker>`)}
|
|
1069
|
+
${this._renderTopPlacementMarker(html`<d2l-list-item-placement-marker ?vertical="${isDraggableTile}"></d2l-list-item-placement-marker>`)}
|
|
1043
1070
|
${this.draggable ? html`<div class="d2l-list-item-drag-image">${innerView}</div>` : innerView}
|
|
1044
|
-
${this._renderBottomPlacementMarker(html`<d2l-list-item-placement-marker></d2l-list-item-placement-marker>`)}
|
|
1071
|
+
${this._renderBottomPlacementMarker(html`<d2l-list-item-placement-marker ?vertical="${isDraggableTile}"></d2l-list-item-placement-marker>`)}
|
|
1045
1072
|
${this._displayKeyboardTooltip && tooltipForId ? html`<d2l-tooltip align="start" announced for="${tooltipForId}" for-type="descriptor">${this.localizeHTML('components.list.keyboard')}</d2l-tooltip>` : ''}
|
|
1046
1073
|
${this.draggable ? this._renderDragMultipleImage() : nothing}
|
|
1047
1074
|
`;
|
|
@@ -3,25 +3,44 @@ import { css, html, LitElement } from 'lit';
|
|
|
3
3
|
|
|
4
4
|
class ListItemPlacementMarker extends LitElement {
|
|
5
5
|
|
|
6
|
+
static properties = {
|
|
7
|
+
vertical: { type: Boolean, reflect: true }
|
|
8
|
+
};
|
|
9
|
+
|
|
6
10
|
static get styles() {
|
|
7
11
|
return css`
|
|
8
12
|
:host {
|
|
9
13
|
display: block;
|
|
10
14
|
}
|
|
11
15
|
|
|
16
|
+
:host([vertical]) {
|
|
17
|
+
height: 100%;
|
|
18
|
+
}
|
|
19
|
+
|
|
12
20
|
:host([hidden]) {
|
|
13
21
|
display: none;
|
|
14
22
|
}
|
|
15
23
|
|
|
24
|
+
:host([vertical]) .d2l-list-drag-marker-line {
|
|
25
|
+
height: 100%;
|
|
26
|
+
margin: -1px 0;
|
|
27
|
+
width: 12px;
|
|
28
|
+
}
|
|
29
|
+
|
|
16
30
|
.d2l-list-drag-marker-line {
|
|
17
31
|
height: 12px;
|
|
18
|
-
margin-
|
|
19
|
-
margin-right: -1px;
|
|
32
|
+
margin-inline: -1px;
|
|
20
33
|
stroke: var(--d2l-color-celestine);
|
|
21
34
|
stroke-width: 3px;
|
|
22
35
|
width: 100%;
|
|
23
36
|
}
|
|
24
37
|
|
|
38
|
+
:host([vertical]) .d2l-list-drag-marker-linecap {
|
|
39
|
+
height: 4px;
|
|
40
|
+
margin-inline: 0 -2px;
|
|
41
|
+
width: 12px;
|
|
42
|
+
}
|
|
43
|
+
|
|
25
44
|
.d2l-list-drag-marker-linecap {
|
|
26
45
|
fill: var(--d2l-color-celestine);
|
|
27
46
|
height: 12px;
|
|
@@ -30,6 +49,11 @@ class ListItemPlacementMarker extends LitElement {
|
|
|
30
49
|
width: 4px;
|
|
31
50
|
}
|
|
32
51
|
|
|
52
|
+
:host([vertical]) .d2l-list-drag-marker-circle {
|
|
53
|
+
margin-inline: 0 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
|
|
33
57
|
.d2l-list-drag-marker-circle {
|
|
34
58
|
fill: none;
|
|
35
59
|
height: 12px;
|
|
@@ -43,10 +67,37 @@ class ListItemPlacementMarker extends LitElement {
|
|
|
43
67
|
display: flex;
|
|
44
68
|
flex-wrap: nowrap;
|
|
45
69
|
}
|
|
70
|
+
|
|
71
|
+
:host([vertical]) .d2l-list-drag-marker {
|
|
72
|
+
flex-direction: column;
|
|
73
|
+
height: 100%;
|
|
74
|
+
}
|
|
46
75
|
`;
|
|
47
76
|
}
|
|
48
77
|
|
|
78
|
+
constructor() {
|
|
79
|
+
super();
|
|
80
|
+
this.vertical = false;
|
|
81
|
+
}
|
|
82
|
+
|
|
49
83
|
render() {
|
|
84
|
+
|
|
85
|
+
if (this.vertical) {
|
|
86
|
+
return html`
|
|
87
|
+
<div class="d2l-list-drag-marker">
|
|
88
|
+
<svg class="d2l-list-drag-marker-circle">
|
|
89
|
+
<circle cx="50%" cy="50%" r="3.8px"/>
|
|
90
|
+
</svg>
|
|
91
|
+
<svg class="d2l-list-drag-marker-line">
|
|
92
|
+
<line x1="50%" y1="0" x2="50%" y2="100%" />
|
|
93
|
+
</svg>
|
|
94
|
+
<svg class="d2l-list-drag-marker-linecap">
|
|
95
|
+
<circle cx="50%" cy="50%" r="1.5px"/>
|
|
96
|
+
</svg>
|
|
97
|
+
</div>
|
|
98
|
+
`;
|
|
99
|
+
}
|
|
100
|
+
|
|
50
101
|
return html`
|
|
51
102
|
<div class="d2l-list-drag-marker">
|
|
52
103
|
<svg class="d2l-list-drag-marker-circle">
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import '../colors/colors.js';
|
|
2
|
+
import { css, html, LitElement } from 'lit';
|
|
3
|
+
import { formatPercent } from '@brightspace-ui/intl';
|
|
4
|
+
import { PropertyRequiredMixin } from '../../mixins/property-required/property-required-mixin.js';
|
|
5
|
+
|
|
6
|
+
export const DIVIDER_WIDTH = 4;
|
|
7
|
+
const KEYBOARD_STEP = 20; // TO DO: Confirm
|
|
8
|
+
const KEYBOARD_STEP_LARGE = 80; // TO DO: Confirm
|
|
9
|
+
|
|
10
|
+
const clampedSize = (size, min, max) => Math.max(min, Math.min(size, max));
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Internal divider used by d2l-page to resize its side-nav and supporting panels.
|
|
14
|
+
*/
|
|
15
|
+
class PageDivider extends PropertyRequiredMixin(LitElement) {
|
|
16
|
+
|
|
17
|
+
static properties = {
|
|
18
|
+
/**
|
|
19
|
+
* Current size of the panel/drawer the divider controls
|
|
20
|
+
* @type {number}
|
|
21
|
+
*/
|
|
22
|
+
currentSize: { type: Number, attribute: 'current-size' },
|
|
23
|
+
/**
|
|
24
|
+
* REQUIRED: label for the divider
|
|
25
|
+
* @type {string}
|
|
26
|
+
*/
|
|
27
|
+
label: { type: String, required: true },
|
|
28
|
+
/**
|
|
29
|
+
* Maximum size of the panel/drawer the divider controls
|
|
30
|
+
* @type {number}
|
|
31
|
+
*/
|
|
32
|
+
maxSize: { type: Number, attribute: 'max-size' },
|
|
33
|
+
/**
|
|
34
|
+
* Minimum size of the panel/drawer the divider controls
|
|
35
|
+
* @type {number}
|
|
36
|
+
*/
|
|
37
|
+
minSize: { type: Number, attribute: 'min-size' },
|
|
38
|
+
/**
|
|
39
|
+
* Inline position of the panel the divider controls
|
|
40
|
+
* @type {'start'|'end'}
|
|
41
|
+
*/
|
|
42
|
+
panelPosition: { type: String, attribute: 'panel-position' },
|
|
43
|
+
/**
|
|
44
|
+
* Whether the divider is controlling a left/right panel or a bottom drawer
|
|
45
|
+
* @type {'panel'|'drawer'}
|
|
46
|
+
*/
|
|
47
|
+
panelType: { type: String, attribute: 'panel-type' }
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
static styles = css`
|
|
51
|
+
:host {
|
|
52
|
+
flex: none;
|
|
53
|
+
}
|
|
54
|
+
.divider {
|
|
55
|
+
background-color: var(--d2l-color-gypsum);
|
|
56
|
+
cursor: ew-resize;
|
|
57
|
+
height: 100%;
|
|
58
|
+
outline: none;
|
|
59
|
+
width: ${DIVIDER_WIDTH}px;
|
|
60
|
+
}
|
|
61
|
+
.divider:hover {
|
|
62
|
+
background-color: var(--d2l-color-mica);
|
|
63
|
+
}
|
|
64
|
+
.divider:focus {
|
|
65
|
+
background-color: var(--d2l-color-celestine);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
:host([panel-type="drawer"]) .divider {
|
|
69
|
+
background-color: var(--d2l-color-celestine);
|
|
70
|
+
cursor: ns-resize;
|
|
71
|
+
height: ${DIVIDER_WIDTH}px;
|
|
72
|
+
width: 100%;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* TO DO: Lots more divider styling to come */
|
|
76
|
+
|
|
77
|
+
`;
|
|
78
|
+
|
|
79
|
+
constructor() {
|
|
80
|
+
super();
|
|
81
|
+
|
|
82
|
+
this.currentSize = 0;
|
|
83
|
+
this.label = '';
|
|
84
|
+
this.maxSize = 0;
|
|
85
|
+
this.minSize = 0;
|
|
86
|
+
this.panelPosition = 'start';
|
|
87
|
+
this.panelType = 'panel';
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
render() {
|
|
91
|
+
const currentSizePercent = formatPercent(Math.round(this.currentSize / this.maxSize) || 0);
|
|
92
|
+
|
|
93
|
+
return html`
|
|
94
|
+
<div
|
|
95
|
+
class="divider"
|
|
96
|
+
role="slider"
|
|
97
|
+
tabindex="0"
|
|
98
|
+
aria-label="${this.label}"
|
|
99
|
+
aria-orientation="${this.panelType === 'panel' ? 'horizontal' : 'vertical'}"
|
|
100
|
+
aria-valuemax="${this.maxSize}"
|
|
101
|
+
aria-valuemin="0"
|
|
102
|
+
aria-valuenow="${this.currentSize}"
|
|
103
|
+
aria-valuetext="${currentSizePercent}"
|
|
104
|
+
@keydown="${this.#handleKeyDown}">
|
|
105
|
+
</div>
|
|
106
|
+
`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
#handleKeyDown(e) {
|
|
110
|
+
if (!['Enter', ' ', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End', 'PageUp', 'PageDown'].includes(e.key)) return;
|
|
111
|
+
e.preventDefault();
|
|
112
|
+
|
|
113
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
114
|
+
/** @ignore */
|
|
115
|
+
this.dispatchEvent(new CustomEvent('d2l-page-divider-toggle'));
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (e.key === 'Home' || e.key === 'End') {
|
|
120
|
+
this.#sendResizeEvent(e.key === 'Home' ? this.minSize : this.maxSize);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (e.key === 'PageUp' || e.key === 'PageDown') {
|
|
125
|
+
this.#sendResizeEvent(this.currentSize + (e.key === 'PageUp' ? 1 : -1) * KEYBOARD_STEP_LARGE);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
let positiveStepKey;
|
|
130
|
+
if (this.panelType === 'panel') {
|
|
131
|
+
if (e.key !== 'ArrowLeft' && e.key !== 'ArrowRight') return;
|
|
132
|
+
const isRtl = (document.documentElement.getAttribute('dir') === 'rtl');
|
|
133
|
+
positiveStepKey = (this.panelPosition === 'start') !== isRtl ? 'ArrowRight' : 'ArrowLeft';
|
|
134
|
+
} else if (this.panelType === 'drawer') {
|
|
135
|
+
if (e.key !== 'ArrowUp' && e.key !== 'ArrowDown') return;
|
|
136
|
+
positiveStepKey = 'ArrowUp';
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const step = (e.key === positiveStepKey ? 1 : -1) * KEYBOARD_STEP;
|
|
140
|
+
const requestedSize = this.currentSize + step;
|
|
141
|
+
this.#sendResizeEvent(requestedSize);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
#sendResizeEvent(requestedSize) {
|
|
145
|
+
const clampedRequestedSize = clampedSize(requestedSize, this.minSize, this.maxSize);
|
|
146
|
+
/** @ignore */
|
|
147
|
+
this.dispatchEvent(new CustomEvent('d2l-page-divider-resize', { detail: {
|
|
148
|
+
requestedSize: clampedRequestedSize
|
|
149
|
+
} }));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
customElements.define('d2l-page-divider-internal', PageDivider);
|