@brightspace-ui/core 2.75.2 → 2.75.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/core",
3
- "version": "2.75.2",
3
+ "version": "2.75.4",
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",
@@ -61,7 +61,7 @@
61
61
  "lit-analyzer": "^1",
62
62
  "messageformat-validator": "^2",
63
63
  "node-sass": "^8",
64
- "rollup": "3.7.5",
64
+ "rollup": "^3",
65
65
  "rollup-plugin-copy": "^3",
66
66
  "rollup-plugin-delete": "^2",
67
67
  "sinon": "^15",
@@ -46,16 +46,22 @@ class Resizer {
46
46
  constructor() {
47
47
  this.contentRect = null;
48
48
  this.contentBounds = null;
49
+ this.isCollapsed = false;
49
50
  this.isMobile = false;
50
- this.panelSize = 0;
51
51
  this.isRtl = false;
52
+ this.panelSize = 0;
52
53
  this.secondaryFirst = false;
54
+ this._wasCollapsed = false;
53
55
  }
54
56
 
55
57
  clampHeight(height) {
56
58
  return clamp(height, this.contentBounds.minHeight, this.contentBounds.maxHeight);
57
59
  }
58
60
 
61
+ clampMaxHeight(height) {
62
+ return Math.min(height, this.contentBounds.maxHeight);
63
+ }
64
+
59
65
  clampWidth(width) {
60
66
  return clamp(width, this.contentBounds.minWidth, this.contentBounds.maxWidth);
61
67
  }
@@ -155,17 +161,18 @@ class DesktopMouseResizer extends Resizer {
155
161
  this._onMouseDown = this._onMouseDown.bind(this);
156
162
  this._onTouchMove = this._onTouchMove.bind(this);
157
163
  this._onMouseMove = this._onMouseMove.bind(this);
158
- this._onResizeEnd = this._onResizeEnd.bind(this);
164
+ this._onMouseUp = this._onMouseUp.bind(this);
165
+ this._onTouchEnd = this._onTouchEnd.bind(this);
159
166
  this._target = null;
160
167
  }
161
168
 
162
169
  connect(target) {
163
170
  target.addEventListener('touchstart', this._onTouchStart);
164
171
  target.addEventListener('touchmove', this._onTouchMove);
165
- target.addEventListener('touchend', this._onResizeEnd);
172
+ target.addEventListener('touchend', this._onTouchEnd);
166
173
  target.addEventListener('mousedown', this._onMouseDown);
167
174
  window.addEventListener('mousemove', this._onMouseMove);
168
- window.addEventListener('mouseup', this._onResizeEnd);
175
+ window.addEventListener('mouseup', this._onMouseUp);
169
176
  this._target = target;
170
177
  }
171
178
 
@@ -173,14 +180,18 @@ class DesktopMouseResizer extends Resizer {
173
180
  if (this._target) {
174
181
  this._target.removeEventListener('touchstart', this._onTouchStart);
175
182
  this._target.removeEventListener('touchmove', this._onTouchMove);
176
- this._target.removeEventListener('touchend', this._onResizeEnd);
183
+ this._target.removeEventListener('touchend', this._onTouchEnd);
177
184
  this._target.removeEventListener('mousedown', this._onMouseDown);
178
185
  }
179
186
  window.removeEventListener('mousemove', this._onMouseMove);
180
- window.removeEventListener('mouseup', this._onResizeEnd);
187
+ window.removeEventListener('mouseup', this._onMouseUp);
181
188
  this._target = null;
182
189
  }
183
190
 
191
+ _clampMaxWidth(width) {
192
+ return Math.min(width, this.contentBounds.maxWidth);
193
+ }
194
+
184
195
  _computeContentX(clientX) {
185
196
  const x = clientX - this.contentRect.left;
186
197
  // The direction of the container is flipped if exactly one of isRtl and secondaryFirst is true
@@ -190,6 +201,7 @@ class DesktopMouseResizer extends Resizer {
190
201
  _onMouseDown(e) {
191
202
  if (!this.isMobile) {
192
203
  e.preventDefault();
204
+ this._wasCollapsed = this.isCollapsed;
193
205
  this._resizeStart(e.clientX);
194
206
  }
195
207
  }
@@ -201,11 +213,19 @@ class DesktopMouseResizer extends Resizer {
201
213
  this._resize(e.clientX);
202
214
  }
203
215
 
204
- _onResizeEnd() {
205
- if (this._isResizing) {
206
- this._isResizing = false;
207
- this.dispatchResizeEnd();
216
+ _onMouseUp(e) {
217
+ if (!this._isResizing) {
218
+ return;
208
219
  }
220
+ this._resizeEnd(e.clientX);
221
+ }
222
+
223
+ _onTouchEnd(e) {
224
+ if (!this._isResizing) {
225
+ return;
226
+ }
227
+ const touch = e.changedTouches[0].clientX;
228
+ this._resizeEnd(touch);
209
229
  }
210
230
 
211
231
  _onTouchMove(e) {
@@ -215,27 +235,39 @@ class DesktopMouseResizer extends Resizer {
215
235
  const touch = e.touches[0];
216
236
  this._resize(touch.clientX);
217
237
  }
218
-
219
238
  _onTouchStart(e) {
220
239
  if (!this.isMobile) {
221
- e.preventDefault();
240
+ if (e.cancelable) e.preventDefault();
241
+ this._wasCollapsed = this.isCollapsed;
222
242
  const touch = e.touches[0];
223
243
  this._resizeStart(touch.clientX);
224
244
  }
225
245
  }
226
-
227
246
  _resize(clientX) {
228
- let actualSecondaryWidth;
229
247
  const x = this._computeContentX(clientX);
230
- const collapseThreshold = this.contentBounds.minWidth / 2;
248
+ const secondaryWidth = x + this._offset;
249
+ this.dispatchResize(this._clampMaxWidth(secondaryWidth), false);
250
+ }
251
+
252
+ _resizeEnd(clientX) {
253
+ if (!this._isResizing) {
254
+ return;
255
+ }
256
+ const expandedCollapseThreshold = this.contentBounds.minWidth * 0.75;
257
+ const collapsedCollapseThreshold = this.contentBounds.minWidth * 0.1;
258
+ const x = this._computeContentX(clientX);
231
259
  const desiredSecondaryWidth = x + this._offset;
232
- if (desiredSecondaryWidth < collapseThreshold) {
233
- actualSecondaryWidth = 0;
234
- } else {
235
- actualSecondaryWidth = this.clampWidth(desiredSecondaryWidth);
260
+ if (
261
+ (this._wasCollapsed && desiredSecondaryWidth < collapsedCollapseThreshold)
262
+ || (!this._wasCollapsed && desiredSecondaryWidth < expandedCollapseThreshold)
263
+ ) {
264
+ this.dispatchResize(0, true);
265
+ }
266
+ else if (desiredSecondaryWidth < this.contentBounds.minWidth) {
267
+ this.dispatchResize(this.contentBounds.minWidth, true);
236
268
  }
237
- const animateResize = desiredSecondaryWidth < actualSecondaryWidth || actualSecondaryWidth === 0;
238
- this.dispatchResize(actualSecondaryWidth, animateResize);
269
+ this._isResizing = false;
270
+ this.dispatchResizeEnd();
239
271
  }
240
272
 
241
273
  _resizeStart(clientX) {
@@ -326,6 +358,7 @@ class MobileMouseResizer extends Resizer {
326
358
 
327
359
  _onMouseDown(e) {
328
360
  if (this.isMobile) {
361
+ this._wasCollapsed = this.isCollapsed;
329
362
  this.dispatchResizeStart();
330
363
  e.preventDefault();
331
364
  const y = e.clientY - this.contentRect.top;
@@ -340,24 +373,29 @@ class MobileMouseResizer extends Resizer {
340
373
  return;
341
374
  }
342
375
  const y = e.clientY - this.contentRect.top;
376
+ const secondaryHeight = this.clampMaxHeight(this.contentRect.height - y + this._offset);
377
+ this.dispatchResize(secondaryHeight, false);
378
+ }
343
379
 
344
- let actualSecondaryHeight;
345
- const collapseThreshold = this.contentBounds.minHeight / 2;
380
+ _onMouseUp(e) {
381
+ if (!this._isResizing) {
382
+ return;
383
+ }
384
+ const expandedCollapseThreshold = this.contentBounds.minHeight * 0.75;
385
+ const collapsedCollapseThreshold = this.contentBounds.minHeight * 0.1;
386
+ const y = e.clientY - this.contentRect.top;
346
387
  const desiredSecondaryHeight = this.contentRect.height - y + this._offset;
347
- if (desiredSecondaryHeight < collapseThreshold) {
348
- actualSecondaryHeight = 0;
349
- } else {
350
- actualSecondaryHeight = this.clampHeight(desiredSecondaryHeight);
388
+ if (
389
+ (this._wasCollapsed && desiredSecondaryHeight < collapsedCollapseThreshold)
390
+ || (!this._wasCollapsed && desiredSecondaryHeight < expandedCollapseThreshold)
391
+ ) {
392
+ if (desiredSecondaryHeight > 0) this.dispatchResize(0, true);
351
393
  }
352
- const animateResize = desiredSecondaryHeight < actualSecondaryHeight || actualSecondaryHeight === 0;
353
- this.dispatchResize(actualSecondaryHeight, animateResize);
354
- }
355
-
356
- _onMouseUp() {
357
- if (this._isResizing) {
358
- this._isResizing = false;
359
- this.dispatchResizeEnd();
394
+ else if (desiredSecondaryHeight < this.contentBounds.minHeight) {
395
+ this.dispatchResize(this.contentBounds.minHeight, true);
360
396
  }
397
+ this._isResizing = false;
398
+ this.dispatchResizeEnd();
361
399
  }
362
400
 
363
401
  }
@@ -365,52 +403,72 @@ class MobileMouseResizer extends Resizer {
365
403
  class MobileTouchResizer extends Resizer {
366
404
  constructor() {
367
405
  super();
406
+ this.isExpanded = false;
407
+ this._wasExpanded = false;
368
408
  this._onResizeStart = this._onResizeStart.bind(this);
369
409
  this._onTouchMove = this._onTouchMove.bind(this);
370
410
  this._onResizeEnd = this._onResizeEnd.bind(this);
371
- this._target = null;
411
+ this._targetDivider = null;
412
+ this._targetSecondary = null;
372
413
  }
373
414
 
374
- connect(target) {
375
- target.addEventListener('touchstart', this._onResizeStart);
376
- target.addEventListener('touchmove', this._onTouchMove);
377
- target.addEventListener('touchend', this._onResizeEnd);
378
- this._target = target;
415
+ connect(targetDivider, targetSecondary) {
416
+ targetDivider.addEventListener('touchstart', this._onResizeStart);
417
+ targetDivider.addEventListener('touchmove', this._onTouchMove);
418
+ targetDivider.addEventListener('touchend', this._onResizeEnd);
419
+ this._targetDivider = targetDivider;
420
+
421
+ targetSecondary.addEventListener('touchstart', this._onResizeStart);
422
+ targetSecondary.addEventListener('touchmove', this._onTouchMove);
423
+ targetSecondary.addEventListener('touchend', this._onResizeEnd);
424
+ this._targetSecondary = targetSecondary;
379
425
  }
380
426
 
381
427
  disconnect() {
382
- if (this._target) {
383
- this._target.removeEventListener('touchstart', this._onResizeStart);
384
- this._target.removeEventListener('touchmove', this._onTouchMove);
385
- this._target.removeEventListener('touchend', this._onResizeEnd);
428
+ if (this._targetDivider) {
429
+ this._targetDivider.removeEventListener('touchstart', this._onResizeStart);
430
+ this._targetDivider.removeEventListener('touchmove', this._onTouchMove);
431
+ this._targetDivider.removeEventListener('touchend', this._onResizeEnd);
386
432
  }
387
- this._target = null;
388
- }
433
+ this._targetDivider = null;
389
434
 
390
- _computeTouchDirection() {
391
- const oldest = this._touches[0];
392
- const newest = this._touches[this._touches.length - 1];
393
- if (oldest === newest) {
394
- return 0;
435
+ if (this._targetSecondary) {
436
+ this._targetSecondary.removeEventListener('touchstart', this._onResizeStart);
437
+ this._targetSecondary.removeEventListener('touchmove', this._onTouchMove);
438
+ this._targetSecondary.removeEventListener('touchend', this._onResizeEnd);
395
439
  }
396
- return newest - oldest;
440
+ this._targetSecondary = null;
397
441
  }
398
442
 
399
443
  _onResizeEnd() {
400
- if (this._isResizing) {
401
- if (this.panelSize > this.contentBounds.minHeight && this.panelSize < this.contentBounds.maxHeight) {
402
- let secondaryHeight;
403
- const touchDirection = this._computeTouchDirection();
404
- if (touchDirection >= 0) {
405
- secondaryHeight = this.contentBounds.minHeight;
406
- } else {
407
- secondaryHeight = this.contentBounds.maxHeight;
408
- }
409
- this.dispatchResize(secondaryHeight, true);
410
- }
411
- this._isResizing = false;
412
- this.dispatchResizeEnd();
444
+ if (!this._isResizing) {
445
+ return;
446
+ }
447
+ let secondaryHeight;
448
+ const expandedShrinkThreshold = this.contentBounds.minHeight + (this.contentBounds.maxHeight - this.contentBounds.minHeight) * 0.9;
449
+ const expandThreshold = this.contentBounds.minHeight + (this.contentBounds.maxHeight - this.contentBounds.minHeight) * 0.1;
450
+ const collapseThreshold = this.contentBounds.minHeight * 0.9;
451
+ const collapsedExpandThreshold = this.contentBounds.minHeight * 0.1;
452
+ if (
453
+ (!this._wasCollapsed && this.panelSize < collapseThreshold)
454
+ || (this._wasCollapsed && this.panelSize < collapsedExpandThreshold)
455
+ ) {
456
+ secondaryHeight = 0;
457
+ }
458
+ else if (
459
+ (this._wasExpanded && this.panelSize < expandedShrinkThreshold)
460
+ || (this._wasCollapsed && this.panelSize < expandThreshold)
461
+ || (!this._wasExpanded && !this._wasCollapsed && this.panelSize < expandThreshold && this.panelSize > collapseThreshold)
462
+ ) {
463
+ secondaryHeight = this.contentBounds.minHeight;
413
464
  }
465
+ else {
466
+ secondaryHeight = this.contentBounds.maxHeight;
467
+ }
468
+ this.dispatchResize(secondaryHeight, true);
469
+
470
+ this._isResizing = false;
471
+ this.dispatchResizeEnd();
414
472
  }
415
473
 
416
474
  _onResizeStart(e) {
@@ -421,6 +479,8 @@ class MobileTouchResizer extends Resizer {
421
479
  this._isResizing = true;
422
480
  this._touches = [];
423
481
  this._trackTouch(touch);
482
+ this._wasCollapsed = this.isCollapsed;
483
+ this._wasExpanded = this.isExpanded;
424
484
  }
425
485
  }
426
486
 
@@ -431,18 +491,19 @@ class MobileTouchResizer extends Resizer {
431
491
  const touch = e.touches[0];
432
492
  const curTouch = touch.screenY;
433
493
  const delta = curTouch - this._prevTouch;
434
- const curScroll = this._target.scrollTop;
494
+ const isScrollingDivider = this._targetDivider.contains(e.target);
495
+ const curScroll = this._targetSecondary.scrollTop;
435
496
  this._trackTouch(touch);
436
497
 
437
498
  let isScrollable;
438
499
  let secondaryHeight = this.panelSize;
439
500
  if (delta > 0) {
440
- if (curScroll === 0) {
441
- secondaryHeight = this.clampHeight(this.panelSize - delta);
501
+ if (isScrollingDivider || curScroll === 0) {
502
+ secondaryHeight = this.clampMaxHeight(this.panelSize - delta);
442
503
  }
443
504
  isScrollable = curScroll > 0;
444
505
  } else if (delta < 0) {
445
- secondaryHeight = this.clampHeight(this.panelSize - delta);
506
+ secondaryHeight = this.clampMaxHeight(this.panelSize - delta);
446
507
  isScrollable = secondaryHeight === this.contentBounds.maxHeight;
447
508
  }
448
509
  if (!isScrollable && e.cancelable) {
@@ -594,7 +655,15 @@ class TemplatePrimarySecondary extends FocusVisiblePolyfillMixin(RtlMixin(Locali
594
655
  background-color: var(--d2l-color-gypsum);
595
656
  }
596
657
  :host([resizable]) [data-is-collapsed] aside {
597
- display: none;
658
+ visibility: hidden;
659
+ }
660
+ :host([resizable]:not([dir="rtl"]):not([secondary-first])) aside,
661
+ :host([resizable][dir="rtl"][secondary-first]) aside {
662
+ float: left;
663
+ }
664
+ :host([resizable][dir="rtl"]:not([secondary-first])) aside,
665
+ :host([resizable]:not([dir="rtl"])[secondary-first]) aside {
666
+ float: right;
598
667
  }
599
668
  .d2l-template-primary-secondary-divider {
600
669
  background-color: var(--d2l-color-mica);
@@ -672,10 +741,12 @@ class TemplatePrimarySecondary extends FocusVisiblePolyfillMixin(RtlMixin(Locali
672
741
  .d2l-template-primary-secondary-divider.focus-visible .d2l-template-primary-secondary-divider-handle-left {
673
742
  display: block;
674
743
  }
675
- :host(:not([dir="rtl"])) [data-is-expanded] .d2l-template-primary-secondary-divider-handle-left {
744
+ :host(:not([dir="rtl"]):not([secondary-first])) [data-is-expanded] .d2l-template-primary-secondary-divider-handle-left,
745
+ :host([dir="rtl"][secondary-first]) [data-is-expanded] .d2l-template-primary-secondary-divider-handle-left {
676
746
  display: none;
677
747
  }
678
- :host([dir="rtl"]) [data-is-expanded] .d2l-template-primary-secondary-divider-handle-right {
748
+ :host(:not([dir="rtl"])[secondary-first]) [data-is-expanded] .d2l-template-primary-secondary-divider-handle-right,
749
+ :host([dir="rtl"]:not([secondary-first])) [data-is-expanded] .d2l-template-primary-secondary-divider-handle-right {
679
750
  display: none;
680
751
  }
681
752
  d2l-icon {
@@ -974,7 +1045,7 @@ class TemplatePrimarySecondary extends FocusVisiblePolyfillMixin(RtlMixin(Locali
974
1045
  </d2l-icon-custom>
975
1046
  </div>
976
1047
  <div class="d2l-template-primary-secondary-divider-handle-mobile">
977
- ${size === 0 ? html`<d2l-icon icon="tier1:chevron-up"></d2l-icon>` : html`<d2l-icon icon="tier1:chevron-down"></d2l-icon>`}
1048
+ <d2l-icon icon=${size === 0 ? 'tier1:chevron-up' : 'tier1:chevron-down'}></d2l-icon>
978
1049
  </div>
979
1050
  </div>
980
1051
  </div>
@@ -989,6 +1060,14 @@ class TemplatePrimarySecondary extends FocusVisiblePolyfillMixin(RtlMixin(Locali
989
1060
 
990
1061
  updated(changedProperties) {
991
1062
  super.updated(changedProperties);
1063
+ if (changedProperties.has('_isCollapsed')) {
1064
+ this._desktopMouseResizer.isCollapsed = this._isCollapsed;
1065
+ this._mobileMouseResizer.isCollapsed = this._isCollapsed;
1066
+ this._mobileTouchResizer.isCollapsed = this._isCollapsed;
1067
+ }
1068
+ if (changedProperties.has('_isExpanded')) {
1069
+ this._mobileTouchResizer.isExpanded = this._isExpanded;
1070
+ }
992
1071
  if (changedProperties.has('_size')) {
993
1072
  if (this.storageKey) {
994
1073
  const key = computeSizeKey(this.storageKey);
@@ -1003,16 +1082,20 @@ class TemplatePrimarySecondary extends FocusVisiblePolyfillMixin(RtlMixin(Locali
1003
1082
  this._desktopKeyboardResizer.secondaryFirst = this.secondaryFirst;
1004
1083
  this._desktopMouseResizer.secondaryFirst = this.secondaryFirst;
1005
1084
  }
1006
- if (!this._secondary) {
1007
- this._secondary = this.shadowRoot.querySelector('aside');
1085
+ if (!this._divider) {
1008
1086
  this._divider = this.shadowRoot.querySelector('.d2l-template-primary-secondary-divider');
1009
1087
  }
1088
+ if (changedProperties.has('_isMobile') && this._isMobile) {
1089
+ this._secondary = this.shadowRoot.querySelector('aside');
1090
+ if (this._divider.isConnected && this._secondary.isConnected) {
1091
+ this._mobileTouchResizer.connect(this._divider, this._secondary);
1092
+ }
1093
+ }
1010
1094
  if (this._divider.isConnected && !this._hasConnectedResizers) {
1011
1095
  this._desktopKeyboardResizer.connect(this._divider);
1012
1096
  this._desktopMouseResizer.connect(this._divider);
1013
1097
  this._mobileKeyboardResizer.connect(this._divider);
1014
1098
  this._mobileMouseResizer.connect(this._divider);
1015
- this._mobileTouchResizer.connect(this._secondary);
1016
1099
  this._hasConnectedResizers = true;
1017
1100
  }
1018
1101
  }