@angular/cdk 17.3.4 → 17.3.6

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/fesm2022/cdk.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Version } from '@angular/core';
2
2
 
3
3
  /** Current version of the Angular Component Development Kit. */
4
- const VERSION = new Version('17.3.4');
4
+ const VERSION = new Version('17.3.6');
5
5
 
6
6
  export { VERSION };
7
7
  //# sourceMappingURL=cdk.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"cdk.mjs","sources":["../../../../../../src/cdk/version.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {Version} from '@angular/core';\n\n/** Current version of the Angular Component Development Kit. */\nexport const VERSION = new Version('17.3.4');\n"],"names":[],"mappings":";;AAUA;MACa,OAAO,GAAG,IAAI,OAAO,CAAC,mBAAmB;;;;"}
1
+ {"version":3,"file":"cdk.mjs","sources":["../../../../../../src/cdk/version.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\nimport {Version} from '@angular/core';\n\n/** Current version of the Angular Component Development Kit. */\nexport const VERSION = new Version('17.3.6');\n"],"names":[],"mappings":";;AAUA;MACa,OAAO,GAAG,IAAI,OAAO,CAAC,mBAAmB;;;;"}
@@ -71,34 +71,25 @@ function combineTransforms(transform, initialTransform) {
71
71
  ? transform + ' ' + initialTransform
72
72
  : transform;
73
73
  }
74
-
75
- /** Parses a CSS time value to milliseconds. */
76
- function parseCssTimeUnitsToMs(value) {
77
- // Some browsers will return it in seconds, whereas others will return milliseconds.
78
- const multiplier = value.toLowerCase().indexOf('ms') > -1 ? 1 : 1000;
79
- return parseFloat(value) * multiplier;
80
- }
81
- /** Gets the transform transition duration, including the delay, of an element in milliseconds. */
82
- function getTransformTransitionDurationInMs(element) {
83
- const computedStyle = getComputedStyle(element);
84
- const transitionedProperties = parseCssPropertyValue(computedStyle, 'transition-property');
85
- const property = transitionedProperties.find(prop => prop === 'transform' || prop === 'all');
86
- // If there's no transition for `all` or `transform`, we shouldn't do anything.
87
- if (!property) {
88
- return 0;
89
- }
90
- // Get the index of the property that we're interested in and match
91
- // it up to the same index in `transition-delay` and `transition-duration`.
92
- const propertyIndex = transitionedProperties.indexOf(property);
93
- const rawDurations = parseCssPropertyValue(computedStyle, 'transition-duration');
94
- const rawDelays = parseCssPropertyValue(computedStyle, 'transition-delay');
95
- return (parseCssTimeUnitsToMs(rawDurations[propertyIndex]) +
96
- parseCssTimeUnitsToMs(rawDelays[propertyIndex]));
74
+ /**
75
+ * Matches the target element's size to the source's size.
76
+ * @param target Element that needs to be resized.
77
+ * @param sourceRect Dimensions of the source element.
78
+ */
79
+ function matchElementSize(target, sourceRect) {
80
+ target.style.width = `${sourceRect.width}px`;
81
+ target.style.height = `${sourceRect.height}px`;
82
+ target.style.transform = getTransform(sourceRect.left, sourceRect.top);
97
83
  }
98
- /** Parses out multiple values from a computed style into an array. */
99
- function parseCssPropertyValue(computedStyle, name) {
100
- const value = computedStyle.getPropertyValue(name);
101
- return value.split(',').map(part => part.trim());
84
+ /**
85
+ * Gets a 3d `transform` that can be applied to an element.
86
+ * @param x Desired position of the element along the X axis.
87
+ * @param y Desired position of the element along the Y axis.
88
+ */
89
+ function getTransform(x, y) {
90
+ // Round the transforms since some browsers will
91
+ // blur the elements for sub-pixel transforms.
92
+ return `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`;
102
93
  }
103
94
 
104
95
  /** Gets a mutable version of an element's bounding `DOMRect`. */
@@ -283,10 +274,182 @@ function transferCanvasData(source, clone) {
283
274
  }
284
275
  }
285
276
 
277
+ /**
278
+ * Gets the root HTML element of an embedded view.
279
+ * If the root is not an HTML element it gets wrapped in one.
280
+ */
281
+ function getRootNode(viewRef, _document) {
282
+ const rootNodes = viewRef.rootNodes;
283
+ if (rootNodes.length === 1 && rootNodes[0].nodeType === _document.ELEMENT_NODE) {
284
+ return rootNodes[0];
285
+ }
286
+ const wrapper = _document.createElement('div');
287
+ rootNodes.forEach(node => wrapper.appendChild(node));
288
+ return wrapper;
289
+ }
290
+
291
+ /** Parses a CSS time value to milliseconds. */
292
+ function parseCssTimeUnitsToMs(value) {
293
+ // Some browsers will return it in seconds, whereas others will return milliseconds.
294
+ const multiplier = value.toLowerCase().indexOf('ms') > -1 ? 1 : 1000;
295
+ return parseFloat(value) * multiplier;
296
+ }
297
+ /** Gets the transform transition duration, including the delay, of an element in milliseconds. */
298
+ function getTransformTransitionDurationInMs(element) {
299
+ const computedStyle = getComputedStyle(element);
300
+ const transitionedProperties = parseCssPropertyValue(computedStyle, 'transition-property');
301
+ const property = transitionedProperties.find(prop => prop === 'transform' || prop === 'all');
302
+ // If there's no transition for `all` or `transform`, we shouldn't do anything.
303
+ if (!property) {
304
+ return 0;
305
+ }
306
+ // Get the index of the property that we're interested in and match
307
+ // it up to the same index in `transition-delay` and `transition-duration`.
308
+ const propertyIndex = transitionedProperties.indexOf(property);
309
+ const rawDurations = parseCssPropertyValue(computedStyle, 'transition-duration');
310
+ const rawDelays = parseCssPropertyValue(computedStyle, 'transition-delay');
311
+ return (parseCssTimeUnitsToMs(rawDurations[propertyIndex]) +
312
+ parseCssTimeUnitsToMs(rawDelays[propertyIndex]));
313
+ }
314
+ /** Parses out multiple values from a computed style into an array. */
315
+ function parseCssPropertyValue(computedStyle, name) {
316
+ const value = computedStyle.getPropertyValue(name);
317
+ return value.split(',').map(part => part.trim());
318
+ }
319
+
320
+ /** Inline styles to be set as `!important` while dragging. */
321
+ const importantProperties = new Set([
322
+ // Needs to be important, because some `mat-table` sets `position: sticky !important`. See #22781.
323
+ 'position',
324
+ ]);
325
+ class PreviewRef {
326
+ constructor(_document, _rootElement, _direction, _initialDomRect, _previewTemplate, _previewClass, _pickupPositionOnPage, _initialTransform, _zIndex) {
327
+ this._document = _document;
328
+ this._rootElement = _rootElement;
329
+ this._direction = _direction;
330
+ this._initialDomRect = _initialDomRect;
331
+ this._previewTemplate = _previewTemplate;
332
+ this._previewClass = _previewClass;
333
+ this._pickupPositionOnPage = _pickupPositionOnPage;
334
+ this._initialTransform = _initialTransform;
335
+ this._zIndex = _zIndex;
336
+ }
337
+ attach(parent) {
338
+ this._wrapper = this._createWrapper();
339
+ this._preview = this._createPreview();
340
+ this._wrapper.appendChild(this._preview);
341
+ parent.appendChild(this._wrapper);
342
+ // The null check is necessary for browsers that don't support the popover API.
343
+ if (this._wrapper.showPopover) {
344
+ this._wrapper.showPopover();
345
+ }
346
+ }
347
+ destroy() {
348
+ this._wrapper?.remove();
349
+ this._previewEmbeddedView?.destroy();
350
+ this._preview = this._wrapper = this._previewEmbeddedView = null;
351
+ }
352
+ setTransform(value) {
353
+ this._preview.style.transform = value;
354
+ }
355
+ getBoundingClientRect() {
356
+ return this._preview.getBoundingClientRect();
357
+ }
358
+ addClass(className) {
359
+ this._preview.classList.add(className);
360
+ }
361
+ getTransitionDuration() {
362
+ return getTransformTransitionDurationInMs(this._preview);
363
+ }
364
+ addEventListener(name, handler) {
365
+ this._preview.addEventListener(name, handler);
366
+ }
367
+ removeEventListener(name, handler) {
368
+ this._preview.removeEventListener(name, handler);
369
+ }
370
+ _createWrapper() {
371
+ const wrapper = this._document.createElement('div');
372
+ wrapper.setAttribute('popover', 'manual');
373
+ wrapper.setAttribute('dir', this._direction);
374
+ wrapper.classList.add('cdk-drag-preview-container');
375
+ extendStyles(wrapper.style, {
376
+ // This is redundant, but we need it for browsers that don't support the popover API.
377
+ 'position': 'fixed',
378
+ 'top': '0',
379
+ 'left': '0',
380
+ 'width': '100%',
381
+ 'height': '100%',
382
+ 'z-index': this._zIndex + '',
383
+ // Reset the user agent styles.
384
+ 'background': 'none',
385
+ 'border': 'none',
386
+ 'pointer-events': 'none',
387
+ 'margin': '0',
388
+ 'padding': '0',
389
+ });
390
+ toggleNativeDragInteractions(wrapper, false);
391
+ return wrapper;
392
+ }
393
+ _createPreview() {
394
+ const previewConfig = this._previewTemplate;
395
+ const previewClass = this._previewClass;
396
+ const previewTemplate = previewConfig ? previewConfig.template : null;
397
+ let preview;
398
+ if (previewTemplate && previewConfig) {
399
+ // Measure the element before we've inserted the preview
400
+ // since the insertion could throw off the measurement.
401
+ const rootRect = previewConfig.matchSize ? this._initialDomRect : null;
402
+ const viewRef = previewConfig.viewContainer.createEmbeddedView(previewTemplate, previewConfig.context);
403
+ viewRef.detectChanges();
404
+ preview = getRootNode(viewRef, this._document);
405
+ this._previewEmbeddedView = viewRef;
406
+ if (previewConfig.matchSize) {
407
+ matchElementSize(preview, rootRect);
408
+ }
409
+ else {
410
+ preview.style.transform = getTransform(this._pickupPositionOnPage.x, this._pickupPositionOnPage.y);
411
+ }
412
+ }
413
+ else {
414
+ preview = deepCloneNode(this._rootElement);
415
+ matchElementSize(preview, this._initialDomRect);
416
+ if (this._initialTransform) {
417
+ preview.style.transform = this._initialTransform;
418
+ }
419
+ }
420
+ extendStyles(preview.style, {
421
+ // It's important that we disable the pointer events on the preview, because
422
+ // it can throw off the `document.elementFromPoint` calls in the `CdkDropList`.
423
+ 'pointer-events': 'none',
424
+ // We have to reset the margin, because it can throw off positioning relative to the viewport.
425
+ 'margin': '0',
426
+ 'position': 'absolute',
427
+ 'top': '0',
428
+ 'left': '0',
429
+ }, importantProperties);
430
+ toggleNativeDragInteractions(preview, false);
431
+ preview.classList.add('cdk-drag-preview');
432
+ if (previewClass) {
433
+ if (Array.isArray(previewClass)) {
434
+ previewClass.forEach(className => preview.classList.add(className));
435
+ }
436
+ else {
437
+ preview.classList.add(previewClass);
438
+ }
439
+ }
440
+ return preview;
441
+ }
442
+ }
443
+
286
444
  /** Options that can be used to bind a passive event listener. */
287
445
  const passiveEventListenerOptions = normalizePassiveListenerOptions({ passive: true });
288
446
  /** Options that can be used to bind an active event listener. */
289
447
  const activeEventListenerOptions = normalizePassiveListenerOptions({ passive: false });
448
+ /** Event options that can be used to bind an active, capturing event. */
449
+ const activeCapturingEventOptions$1 = normalizePassiveListenerOptions({
450
+ passive: false,
451
+ capture: true,
452
+ });
290
453
  /**
291
454
  * Time in milliseconds for which to ignore mouse events, after
292
455
  * receiving a touch event. Used to avoid doing double work for
@@ -593,7 +756,7 @@ class DragRef {
593
756
  this._destroyPreview();
594
757
  this._destroyPlaceholder();
595
758
  this._dragDropRegistry.removeDragItem(this);
596
- this._removeSubscriptions();
759
+ this._removeListeners();
597
760
  this.beforeStarted.complete();
598
761
  this.started.complete();
599
762
  this.released.complete();
@@ -691,16 +854,16 @@ class DragRef {
691
854
  }
692
855
  }
693
856
  /** Unsubscribes from the global subscriptions. */
694
- _removeSubscriptions() {
857
+ _removeListeners() {
695
858
  this._pointerMoveSubscription.unsubscribe();
696
859
  this._pointerUpSubscription.unsubscribe();
697
860
  this._scrollSubscription.unsubscribe();
861
+ this._getShadowRoot()?.removeEventListener('selectstart', shadowDomSelectStart, activeCapturingEventOptions$1);
698
862
  }
699
863
  /** Destroys the preview element and its ViewRef. */
700
864
  _destroyPreview() {
701
- this._preview?.remove();
702
- this._previewRef?.destroy();
703
- this._preview = this._previewRef = null;
865
+ this._preview?.destroy();
866
+ this._preview = null;
704
867
  }
705
868
  /** Destroys the placeholder element and its ViewRef. */
706
869
  _destroyPlaceholder() {
@@ -720,7 +883,7 @@ class DragRef {
720
883
  if (!this._dragDropRegistry.isDragging(this)) {
721
884
  return;
722
885
  }
723
- this._removeSubscriptions();
886
+ this._removeListeners();
724
887
  this._dragDropRegistry.stopDragging(this);
725
888
  this._toggleNativeDragInteractions();
726
889
  if (this._handles) {
@@ -765,14 +928,21 @@ class DragRef {
765
928
  this._lastTouchEventTime = Date.now();
766
929
  }
767
930
  this._toggleNativeDragInteractions();
931
+ // Needs to happen before the root element is moved.
932
+ const shadowRoot = this._getShadowRoot();
768
933
  const dropContainer = this._dropContainer;
934
+ if (shadowRoot) {
935
+ // In some browsers the global `selectstart` that we maintain in the `DragDropRegistry`
936
+ // doesn't cross the shadow boundary so we have to prevent it at the shadow root (see #28792).
937
+ this._ngZone.runOutsideAngular(() => {
938
+ shadowRoot.addEventListener('selectstart', shadowDomSelectStart, activeCapturingEventOptions$1);
939
+ });
940
+ }
769
941
  if (dropContainer) {
770
942
  const element = this._rootElement;
771
943
  const parent = element.parentNode;
772
944
  const placeholder = (this._placeholder = this._createPlaceholderElement());
773
945
  const anchor = (this._anchor = this._anchor || this._document.createComment(''));
774
- // Needs to happen before the root element is moved.
775
- const shadowRoot = this._getShadowRoot();
776
946
  // Insert an anchor node so that we can restore the element's position in the DOM.
777
947
  parent.insertBefore(anchor, element);
778
948
  // There's no risk of transforms stacking when inside a drop container so
@@ -780,13 +950,13 @@ class DragRef {
780
950
  this._initialTransform = element.style.transform || '';
781
951
  // Create the preview after the initial transform has
782
952
  // been cached, because it can be affected by the transform.
783
- this._preview = this._createPreviewElement();
953
+ this._preview = new PreviewRef(this._document, this._rootElement, this._direction, this._initialDomRect, this._previewTemplate || null, this.previewClass || null, this._pickupPositionOnPage, this._initialTransform, this._config.zIndex || 1000);
954
+ this._preview.attach(this._getPreviewInsertionPoint(parent, shadowRoot));
784
955
  // We move the element out at the end of the body and we make it hidden, because keeping it in
785
956
  // place will throw off the consumer's `:last-child` selectors. We can't remove the element
786
957
  // from the DOM completely, because iOS will stop firing all subsequent events in the chain.
787
958
  toggleVisibility(element, false, dragImportantProperties);
788
959
  this._document.body.appendChild(parent.replaceChild(placeholder, element));
789
- this._getPreviewInsertionPoint(parent, shadowRoot).appendChild(this._preview);
790
960
  this.started.next({ source: this, event }); // Emit before notifying the container.
791
961
  dropContainer.start();
792
962
  this._initialContainer = dropContainer;
@@ -847,7 +1017,7 @@ class DragRef {
847
1017
  this._hasStartedDragging = this._hasMoved = false;
848
1018
  // Avoid multiple subscriptions and memory leaks when multi touch
849
1019
  // (isDragging check above isn't enough because of possible temporal and/or dimensional delays)
850
- this._removeSubscriptions();
1020
+ this._removeListeners();
851
1021
  this._initialDomRect = this._rootElement.getBoundingClientRect();
852
1022
  this._pointerMoveSubscription = this._dragDropRegistry.pointerMove.subscribe(this._pointerMove);
853
1023
  this._pointerUpSubscription = this._dragDropRegistry.pointerUp.subscribe(this._pointerUp);
@@ -959,61 +1129,6 @@ class DragRef {
959
1129
  }
960
1130
  }
961
1131
  }
962
- /**
963
- * Creates the element that will be rendered next to the user's pointer
964
- * and will be used as a preview of the element that is being dragged.
965
- */
966
- _createPreviewElement() {
967
- const previewConfig = this._previewTemplate;
968
- const previewClass = this.previewClass;
969
- const previewTemplate = previewConfig ? previewConfig.template : null;
970
- let preview;
971
- if (previewTemplate && previewConfig) {
972
- // Measure the element before we've inserted the preview
973
- // since the insertion could throw off the measurement.
974
- const rootRect = previewConfig.matchSize ? this._initialDomRect : null;
975
- const viewRef = previewConfig.viewContainer.createEmbeddedView(previewTemplate, previewConfig.context);
976
- viewRef.detectChanges();
977
- preview = getRootNode(viewRef, this._document);
978
- this._previewRef = viewRef;
979
- if (previewConfig.matchSize) {
980
- matchElementSize(preview, rootRect);
981
- }
982
- else {
983
- preview.style.transform = getTransform(this._pickupPositionOnPage.x, this._pickupPositionOnPage.y);
984
- }
985
- }
986
- else {
987
- preview = deepCloneNode(this._rootElement);
988
- matchElementSize(preview, this._initialDomRect);
989
- if (this._initialTransform) {
990
- preview.style.transform = this._initialTransform;
991
- }
992
- }
993
- extendStyles(preview.style, {
994
- // It's important that we disable the pointer events on the preview, because
995
- // it can throw off the `document.elementFromPoint` calls in the `CdkDropList`.
996
- 'pointer-events': 'none',
997
- // We have to reset the margin, because it can throw off positioning relative to the viewport.
998
- 'margin': '0',
999
- 'position': 'fixed',
1000
- 'top': '0',
1001
- 'left': '0',
1002
- 'z-index': `${this._config.zIndex || 1000}`,
1003
- }, dragImportantProperties);
1004
- toggleNativeDragInteractions(preview, false);
1005
- preview.classList.add('cdk-drag-preview');
1006
- preview.setAttribute('dir', this._direction);
1007
- if (previewClass) {
1008
- if (Array.isArray(previewClass)) {
1009
- previewClass.forEach(className => preview.classList.add(className));
1010
- }
1011
- else {
1012
- preview.classList.add(previewClass);
1013
- }
1014
- }
1015
- return preview;
1016
- }
1017
1132
  /**
1018
1133
  * Animates the preview element from its current position to the location of the drop placeholder.
1019
1134
  * @returns Promise that resolves when the animation completes.
@@ -1025,14 +1140,14 @@ class DragRef {
1025
1140
  }
1026
1141
  const placeholderRect = this._placeholder.getBoundingClientRect();
1027
1142
  // Apply the class that adds a transition to the preview.
1028
- this._preview.classList.add('cdk-drag-animating');
1143
+ this._preview.addClass('cdk-drag-animating');
1029
1144
  // Move the preview to the placeholder position.
1030
1145
  this._applyPreviewTransform(placeholderRect.left, placeholderRect.top);
1031
1146
  // If the element doesn't have a `transition`, the `transitionend` event won't fire. Since
1032
1147
  // we need to trigger a style recalculation in order for the `cdk-drag-animating` class to
1033
1148
  // apply its style, we take advantage of the available info to figure out whether we need to
1034
1149
  // bind the event in the first place.
1035
- const duration = getTransformTransitionDurationInMs(this._preview);
1150
+ const duration = this._preview.getTransitionDuration();
1036
1151
  if (duration === 0) {
1037
1152
  return Promise.resolve();
1038
1153
  }
@@ -1220,7 +1335,7 @@ class DragRef {
1220
1335
  // it could be completely different and the transform might not make sense anymore.
1221
1336
  const initialTransform = this._previewTemplate?.template ? undefined : this._initialTransform;
1222
1337
  const transform = getTransform(x, y);
1223
- this._preview.style.transform = combineTransforms(transform, initialTransform);
1338
+ this._preview.setTransform(combineTransforms(transform, initialTransform));
1224
1339
  }
1225
1340
  /**
1226
1341
  * Gets the distance that the user has dragged during the current drag sequence.
@@ -1379,16 +1494,6 @@ class DragRef {
1379
1494
  });
1380
1495
  }
1381
1496
  }
1382
- /**
1383
- * Gets a 3d `transform` that can be applied to an element.
1384
- * @param x Desired position of the element along the X axis.
1385
- * @param y Desired position of the element along the Y axis.
1386
- */
1387
- function getTransform(x, y) {
1388
- // Round the transforms since some browsers will
1389
- // blur the elements for sub-pixel transforms.
1390
- return `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`;
1391
- }
1392
1497
  /** Clamps a value between a minimum and a maximum. */
1393
1498
  function clamp$1(value, min, max) {
1394
1499
  return Math.max(min, Math.min(max, value));
@@ -1400,28 +1505,9 @@ function isTouchEvent(event) {
1400
1505
  // that if the event's name starts with `t`, it's a touch event.
1401
1506
  return event.type[0] === 't';
1402
1507
  }
1403
- /**
1404
- * Gets the root HTML element of an embedded view.
1405
- * If the root is not an HTML element it gets wrapped in one.
1406
- */
1407
- function getRootNode(viewRef, _document) {
1408
- const rootNodes = viewRef.rootNodes;
1409
- if (rootNodes.length === 1 && rootNodes[0].nodeType === _document.ELEMENT_NODE) {
1410
- return rootNodes[0];
1411
- }
1412
- const wrapper = _document.createElement('div');
1413
- rootNodes.forEach(node => wrapper.appendChild(node));
1414
- return wrapper;
1415
- }
1416
- /**
1417
- * Matches the target element's size to the source's size.
1418
- * @param target Element that needs to be resized.
1419
- * @param sourceRect Dimensions of the source element.
1420
- */
1421
- function matchElementSize(target, sourceRect) {
1422
- target.style.width = `${sourceRect.width}px`;
1423
- target.style.height = `${sourceRect.height}px`;
1424
- target.style.transform = getTransform(sourceRect.left, sourceRect.top);
1508
+ /** Callback invoked for `selectstart` events inside the shadow DOM. */
1509
+ function shadowDomSelectStart(event) {
1510
+ event.preventDefault();
1425
1511
  }
1426
1512
 
1427
1513
  /**