@angular/cdk 18.2.9 → 18.2.11
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/esm2022/table/sticky-styler.mjs +95 -5
- package/esm2022/tree/tree.mjs +16 -2
- package/esm2022/version.mjs +1 -1
- package/fesm2022/cdk.mjs +1 -1
- package/fesm2022/cdk.mjs.map +1 -1
- package/fesm2022/table.mjs +94 -4
- package/fesm2022/table.mjs.map +1 -1
- package/fesm2022/tree.mjs +16 -2
- package/fesm2022/tree.mjs.map +1 -1
- package/package.json +1 -1
- package/schematics/ng-add/index.js +1 -1
- package/schematics/ng-add/index.mjs +1 -1
- package/table/index.d.ts +20 -1
- package/tree/index.d.ts +3 -2
package/fesm2022/table.mjs
CHANGED
|
@@ -663,6 +663,12 @@ class StickyStyler {
|
|
|
663
663
|
this._isBrowser = _isBrowser;
|
|
664
664
|
this._needsPositionStickyOnElement = _needsPositionStickyOnElement;
|
|
665
665
|
this._positionListener = _positionListener;
|
|
666
|
+
this._elemSizeCache = new WeakMap();
|
|
667
|
+
this._resizeObserver = globalThis?.ResizeObserver
|
|
668
|
+
? new globalThis.ResizeObserver(entries => this._updateCachedSizes(entries))
|
|
669
|
+
: null;
|
|
670
|
+
this._updatedStickyColumnsParamsToReplay = [];
|
|
671
|
+
this._stickyColumnsReplayTimeout = null;
|
|
666
672
|
this._cachedCellWidths = [];
|
|
667
673
|
this._borderCellCss = {
|
|
668
674
|
'top': `${_stickCellCss}-border-elem-top`,
|
|
@@ -678,6 +684,9 @@ class StickyStyler {
|
|
|
678
684
|
* @param stickyDirections The directions that should no longer be set as sticky on the rows.
|
|
679
685
|
*/
|
|
680
686
|
clearStickyPositioning(rows, stickyDirections) {
|
|
687
|
+
if (stickyDirections.includes('left') || stickyDirections.includes('right')) {
|
|
688
|
+
this._removeFromStickyColumnReplayQueue(rows);
|
|
689
|
+
}
|
|
681
690
|
const elementsToClear = [];
|
|
682
691
|
for (const row of rows) {
|
|
683
692
|
// If the row isn't an element (e.g. if it's an `ng-container`),
|
|
@@ -707,8 +716,16 @@ class StickyStyler {
|
|
|
707
716
|
* in this index position should be stuck to the end of the row.
|
|
708
717
|
* @param recalculateCellWidths Whether the sticky styler should recalculate the width of each
|
|
709
718
|
* column cell. If `false` cached widths will be used instead.
|
|
719
|
+
* @param replay Whether to enqueue this call for replay after a ResizeObserver update.
|
|
710
720
|
*/
|
|
711
|
-
updateStickyColumns(rows, stickyStartStates, stickyEndStates, recalculateCellWidths = true) {
|
|
721
|
+
updateStickyColumns(rows, stickyStartStates, stickyEndStates, recalculateCellWidths = true, replay = true) {
|
|
722
|
+
if (replay) {
|
|
723
|
+
this._updateStickyColumnReplayQueue({
|
|
724
|
+
rows: [...rows],
|
|
725
|
+
stickyStartStates: [...stickyStartStates],
|
|
726
|
+
stickyEndStates: [...stickyEndStates],
|
|
727
|
+
});
|
|
728
|
+
}
|
|
712
729
|
if (!rows.length ||
|
|
713
730
|
!this._isBrowser ||
|
|
714
731
|
!(stickyStartStates.some(state => state) || stickyEndStates.some(state => state))) {
|
|
@@ -797,7 +814,7 @@ class StickyStyler {
|
|
|
797
814
|
elementsToStick[rowIndex] = this._isNativeHtmlTable
|
|
798
815
|
? Array.from(row.children)
|
|
799
816
|
: [row];
|
|
800
|
-
const height =
|
|
817
|
+
const height = this._retrieveElementSize(row).height;
|
|
801
818
|
stickyOffset += height;
|
|
802
819
|
stickyCellHeights[rowIndex] = height;
|
|
803
820
|
}
|
|
@@ -931,8 +948,8 @@ class StickyStyler {
|
|
|
931
948
|
const cellWidths = [];
|
|
932
949
|
const firstRowCells = row.children;
|
|
933
950
|
for (let i = 0; i < firstRowCells.length; i++) {
|
|
934
|
-
|
|
935
|
-
cellWidths.push(
|
|
951
|
+
const cell = firstRowCells[i];
|
|
952
|
+
cellWidths.push(this._retrieveElementSize(cell).width);
|
|
936
953
|
}
|
|
937
954
|
this._cachedCellWidths = cellWidths;
|
|
938
955
|
return cellWidths;
|
|
@@ -969,6 +986,79 @@ class StickyStyler {
|
|
|
969
986
|
}
|
|
970
987
|
return positions;
|
|
971
988
|
}
|
|
989
|
+
/**
|
|
990
|
+
* Retreives the most recently observed size of the specified element from the cache, or
|
|
991
|
+
* meaures it directly if not yet cached.
|
|
992
|
+
*/
|
|
993
|
+
_retrieveElementSize(element) {
|
|
994
|
+
const cachedSize = this._elemSizeCache.get(element);
|
|
995
|
+
if (cachedSize) {
|
|
996
|
+
return cachedSize;
|
|
997
|
+
}
|
|
998
|
+
const clientRect = element.getBoundingClientRect();
|
|
999
|
+
const size = { width: clientRect.width, height: clientRect.height };
|
|
1000
|
+
if (!this._resizeObserver) {
|
|
1001
|
+
return size;
|
|
1002
|
+
}
|
|
1003
|
+
this._elemSizeCache.set(element, size);
|
|
1004
|
+
this._resizeObserver.observe(element, { box: 'border-box' });
|
|
1005
|
+
return size;
|
|
1006
|
+
}
|
|
1007
|
+
/**
|
|
1008
|
+
* Conditionally enqueue the requested sticky update and clear previously queued updates
|
|
1009
|
+
* for the same rows.
|
|
1010
|
+
*/
|
|
1011
|
+
_updateStickyColumnReplayQueue(params) {
|
|
1012
|
+
this._removeFromStickyColumnReplayQueue(params.rows);
|
|
1013
|
+
// No need to replay if a flush is pending.
|
|
1014
|
+
if (this._stickyColumnsReplayTimeout) {
|
|
1015
|
+
return;
|
|
1016
|
+
}
|
|
1017
|
+
this._updatedStickyColumnsParamsToReplay.push(params);
|
|
1018
|
+
}
|
|
1019
|
+
/** Remove updates for the specified rows from the queue. */
|
|
1020
|
+
_removeFromStickyColumnReplayQueue(rows) {
|
|
1021
|
+
const rowsSet = new Set(rows);
|
|
1022
|
+
for (const update of this._updatedStickyColumnsParamsToReplay) {
|
|
1023
|
+
update.rows = update.rows.filter(row => !rowsSet.has(row));
|
|
1024
|
+
}
|
|
1025
|
+
this._updatedStickyColumnsParamsToReplay = this._updatedStickyColumnsParamsToReplay.filter(update => !!update.rows.length);
|
|
1026
|
+
}
|
|
1027
|
+
/** Update _elemSizeCache with the observed sizes. */
|
|
1028
|
+
_updateCachedSizes(entries) {
|
|
1029
|
+
let needsColumnUpdate = false;
|
|
1030
|
+
for (const entry of entries) {
|
|
1031
|
+
const newEntry = entry.borderBoxSize?.length
|
|
1032
|
+
? {
|
|
1033
|
+
width: entry.borderBoxSize[0].inlineSize,
|
|
1034
|
+
height: entry.borderBoxSize[0].blockSize,
|
|
1035
|
+
}
|
|
1036
|
+
: {
|
|
1037
|
+
width: entry.contentRect.width,
|
|
1038
|
+
height: entry.contentRect.height,
|
|
1039
|
+
};
|
|
1040
|
+
if (newEntry.width !== this._elemSizeCache.get(entry.target)?.width &&
|
|
1041
|
+
isCell(entry.target)) {
|
|
1042
|
+
needsColumnUpdate = true;
|
|
1043
|
+
}
|
|
1044
|
+
this._elemSizeCache.set(entry.target, newEntry);
|
|
1045
|
+
}
|
|
1046
|
+
if (needsColumnUpdate && this._updatedStickyColumnsParamsToReplay.length) {
|
|
1047
|
+
if (this._stickyColumnsReplayTimeout) {
|
|
1048
|
+
clearTimeout(this._stickyColumnsReplayTimeout);
|
|
1049
|
+
}
|
|
1050
|
+
this._stickyColumnsReplayTimeout = setTimeout(() => {
|
|
1051
|
+
for (const update of this._updatedStickyColumnsParamsToReplay) {
|
|
1052
|
+
this.updateStickyColumns(update.rows, update.stickyStartStates, update.stickyEndStates, true, false);
|
|
1053
|
+
}
|
|
1054
|
+
this._updatedStickyColumnsParamsToReplay = [];
|
|
1055
|
+
this._stickyColumnsReplayTimeout = null;
|
|
1056
|
+
}, 0);
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
function isCell(element) {
|
|
1061
|
+
return ['cdk-cell', 'cdk-header-cell', 'cdk-footer-cell'].some(klass => element.classList.contains(klass));
|
|
972
1062
|
}
|
|
973
1063
|
|
|
974
1064
|
/**
|