Skip to content

Commit 882451c

Browse files
committed
work in progress
1 parent 923c105 commit 882451c

File tree

14 files changed

+80
-34
lines changed

14 files changed

+80
-34
lines changed

src/cdk-experimental/column-resize/column-resize-directives/column-resize-flex.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import {Directive, ElementRef, NgZone} from '@angular/core';
10+
import {CdkTable} from '@angular/cdk/table';
1011

1112
import {ColumnResize} from '../column-resize';
1213
import {ColumnResizeNotifier, ColumnResizeNotifierSource} from '../column-resize-notifier';
@@ -30,7 +31,8 @@ export class CdkColumnResizeFlex extends ColumnResize {
3031
readonly elementRef: ElementRef<HTMLElement>,
3132
protected readonly eventDispatcher: HeaderRowEventDispatcher,
3233
protected readonly ngZone: NgZone,
33-
protected readonly notifier: ColumnResizeNotifierSource) {
34+
protected readonly notifier: ColumnResizeNotifierSource,
35+
protected readonly table: CdkTable<unknown>) {
3436
super();
3537
}
3638
}

src/cdk-experimental/column-resize/column-resize-directives/column-resize.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import {Directive, ElementRef, NgZone} from '@angular/core';
10+
import {CdkTable} from '@angular/cdk/table';
1011

1112
import {ColumnResize} from '../column-resize';
1213
import {ColumnResizeNotifier, ColumnResizeNotifierSource} from '../column-resize-notifier';
@@ -30,7 +31,8 @@ export class CdkColumnResize extends ColumnResize {
3031
readonly elementRef: ElementRef<HTMLElement>,
3132
protected readonly eventDispatcher: HeaderRowEventDispatcher,
3233
protected readonly ngZone: NgZone,
33-
protected readonly notifier: ColumnResizeNotifierSource) {
34+
protected readonly notifier: ColumnResizeNotifierSource,
35+
protected readonly table: CdkTable<unknown>) {
3436
super();
3537
}
3638
}

src/cdk-experimental/column-resize/column-resize-directives/default-enabled-column-resize-flex.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import {Directive, ElementRef, NgZone} from '@angular/core';
10+
import {CdkTable} from '@angular/cdk/table';
1011

1112
import {ColumnResize} from '../column-resize';
1213
import {ColumnResizeNotifier, ColumnResizeNotifierSource} from '../column-resize-notifier';
@@ -30,7 +31,8 @@ export class CdkDefaultEnabledColumnResizeFlex extends ColumnResize {
3031
readonly elementRef: ElementRef<HTMLElement>,
3132
protected readonly eventDispatcher: HeaderRowEventDispatcher,
3233
protected readonly ngZone: NgZone,
33-
protected readonly notifier: ColumnResizeNotifierSource) {
34+
protected readonly notifier: ColumnResizeNotifierSource,
35+
protected readonly table: CdkTable<unknown>) {
3436
super();
3537
}
3638
}

src/cdk-experimental/column-resize/column-resize-directives/default-enabled-column-resize.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import {Directive, ElementRef, NgZone} from '@angular/core';
10+
import {CdkTable} from '@angular/cdk/table';
1011

1112
import {ColumnResize} from '../column-resize';
1213
import {ColumnResizeNotifier, ColumnResizeNotifierSource} from '../column-resize-notifier';
@@ -30,7 +31,8 @@ export class CdkDefaultEnabledColumnResize extends ColumnResize {
3031
readonly elementRef: ElementRef<HTMLElement>,
3132
protected readonly eventDispatcher: HeaderRowEventDispatcher,
3233
protected readonly ngZone: NgZone,
33-
protected readonly notifier: ColumnResizeNotifierSource) {
34+
protected readonly notifier: ColumnResizeNotifierSource,
35+
protected readonly table: CdkTable<unknown>) {
3436
super();
3537
}
3638
}

src/cdk-experimental/column-resize/column-resize-notifier.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ export interface ColumnSizeAction extends ColumnSize {
2929
* for all programatically triggered resizes.
3030
*/
3131
readonly completeImmediately?: boolean;
32+
33+
/**
34+
* Whether the resize action is being applied to a sticky/stickyEnd column.
35+
*/
36+
readonly columnIsSticky?: boolean;
3237
}
3338

3439
/**
@@ -57,6 +62,7 @@ export class ColumnResizeNotifier {
5762

5863
/** Instantly resizes the specified column. */
5964
resize(columnId: string, size: number): void {
60-
this._source.triggerResize.next({columnId, size, completeImmediately: true});
65+
this._source.triggerResize.next(
66+
{columnId, size, completeImmediately: true, columnIsSticky: true});
6167
}
6268
}

src/cdk-experimental/column-resize/overlay-handle.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,12 @@ export abstract class ResizeOverlayHandle implements AfterViewInit, OnDestroy {
138138
computedNewSize = Math.min(
139139
Math.max(computedNewSize, this.resizeRef.minWidthPx, 0), this.resizeRef.maxWidthPx);
140140

141-
this.resizeNotifier.triggerResize.next(
142-
{columnId: this.columnDef.name, size: computedNewSize, previousSize: size});
141+
this.resizeNotifier.triggerResize.next({
142+
columnId: this.columnDef.name,
143+
size: computedNewSize,
144+
previousSize: size,
145+
columnIsSticky: this.columnDef.sticky || this.columnDef.stickyEnd,
146+
});
143147

144148
this.styleScheduler.scheduleEnd(() => {
145149
const originNewSize = this._getOriginWidth();

src/cdk-experimental/column-resize/resize-strategy.ts

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import {Inject, Injectable, OnDestroy, Provider} from '@angular/core';
1010
import {DOCUMENT} from '@angular/common';
1111
import {coerceCssPixelValue} from '@angular/cdk/coercion';
12-
import {_CoalescedStyleScheduler} from '@angular/cdk/table';
12+
import {CdkTable, _CoalescedStyleScheduler} from '@angular/cdk/table';
1313

1414
import {ColumnResize} from './column-resize';
1515

@@ -21,6 +21,9 @@ import {ColumnResize} from './column-resize';
2121
export abstract class ResizeStrategy {
2222
protected abstract readonly columnResize: ColumnResize;
2323
protected abstract readonly styleScheduler: _CoalescedStyleScheduler;
24+
protected abstract readonly table: CdkTable<unknown>;
25+
26+
private pendingResizeDelta: number|null = null;
2427

2528
/** Updates the width of the specified column. */
2629
abstract applyColumnSize(
@@ -42,18 +45,23 @@ export abstract class ResizeStrategy {
4245
minSizeInPx: number): void;
4346

4447
/** Adjusts the width of the table element by the specified delta. */
45-
protected updateTableWidth(delta: number): void {
46-
const table = this.columnResize.elementRef.nativeElement;
48+
protected updateTableWidthAndStickyColumns(delta: number): void {
49+
if (this.pendingResizeDelta === null) {
50+
const tableElement = this.columnResize.elementRef.nativeElement;
51+
const tableWidth = getElementWidth(tableElement);
4752

48-
if (!pendingTableResizes.has(table)) {
49-
const tableWidth = getElementWidth(table);
5053
this.styleScheduler.schedule(() => {
51-
table.style.width = coerceCssPixelValue(tableWidth + pendingTableResizes.get(table)!);
52-
pendingTableResizes.delete(table);
54+
tableElement.style.width = coerceCssPixelValue(tableWidth + this.pendingResizeDelta!);
55+
56+
this.pendingResizeDelta = null;
57+
});
58+
59+
this.styleScheduler.scheduleEnd(() => {
60+
this.table.updateStickyColumnStyles();
5361
});
5462
}
5563

56-
pendingTableResizes.set(table, (pendingTableResizes.get(table) ?? 0) + delta);
64+
this.pendingResizeDelta = (this.pendingResizeDelta ?? 0) + delta;
5765
}
5866
}
5967

@@ -68,7 +76,8 @@ export abstract class ResizeStrategy {
6876
export class TableLayoutFixedResizeStrategy extends ResizeStrategy {
6977
constructor(
7078
protected readonly columnResize: ColumnResize,
71-
protected readonly styleScheduler: _CoalescedStyleScheduler) {
79+
protected readonly styleScheduler: _CoalescedStyleScheduler,
80+
protected readonly table: CdkTable<unknown>) {
7281
super();
7382
}
7483

@@ -84,7 +93,7 @@ export class TableLayoutFixedResizeStrategy extends ResizeStrategy {
8493
columnHeader.style.width = coerceCssPixelValue(sizeInPx);
8594
});
8695

87-
this.updateTableWidth(delta);
96+
this.updateTableWidthAndStickyColumns(delta);
8897
}
8998

9099
applyMinColumnSize(_: string, columnHeader: HTMLElement, sizeInPx: number): void {
@@ -123,6 +132,7 @@ export class CdkFlexTableResizeStrategy extends ResizeStrategy implements OnDest
123132
constructor(
124133
protected readonly columnResize: ColumnResize,
125134
protected readonly styleScheduler: _CoalescedStyleScheduler,
135+
protected readonly table: CdkTable<unknown>,
126136
@Inject(DOCUMENT) document: any) {
127137
super();
128138
this._document = document;
@@ -135,24 +145,30 @@ export class CdkFlexTableResizeStrategy extends ResizeStrategy implements OnDest
135145
const delta = sizeInPx - (previousSizeInPx ??
136146
(this._getAppliedWidth(cssFriendlyColumnName) || columnHeader.offsetWidth));
137147

148+
if (delta === 0) {
149+
return;
150+
}
151+
138152
const cssSize = coerceCssPixelValue(sizeInPx);
139153

140154
this._applyProperty(cssFriendlyColumnName, 'flex', `0 0.01 ${cssSize}`);
141-
this.updateTableWidth(delta);
155+
this.updateTableWidthAndStickyColumns(delta);
142156
}
143157

144158
applyMinColumnSize(cssFriendlyColumnName: string, _: HTMLElement, sizeInPx: number): void {
145159
const cssSize = coerceCssPixelValue(sizeInPx);
146160

147161
this._applyProperty(cssFriendlyColumnName, 'min-width', cssSize,
148162
sizeInPx !== this.defaultMinSize);
163+
this.updateTableWidthAndStickyColumns(0);
149164
}
150165

151166
applyMaxColumnSize(cssFriendlyColumnName: string, _: HTMLElement, sizeInPx: number): void {
152167
const cssSize = coerceCssPixelValue(sizeInPx);
153168

154169
this._applyProperty(cssFriendlyColumnName, 'max-width', cssSize,
155170
sizeInPx !== this.defaultMaxSize);
171+
this.updateTableWidthAndStickyColumns(0);
156172
}
157173

158174
protected getColumnCssClass(cssFriendlyColumnName: string): string {
@@ -259,8 +275,6 @@ function coercePixelsFromFlexValue(flexValue: string|undefined): number {
259275
return Number(flexValue?.match(/0 0\.01 (\d+)px/)?.[1]);
260276
}
261277

262-
const pendingTableResizes = new WeakMap<Element, number>();
263-
264278
export const TABLE_LAYOUT_FIXED_RESIZE_STRATEGY_PROVIDER: Provider = {
265279
provide: ResizeStrategy,
266280
useClass: TableLayoutFixedResizeStrategy,

src/components-examples/material-experimental/column-resize/default-enabled-flex/default-enabled-column-resize-flex-example.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<mat-table [dataSource]="dataSource" class="mat-elevation-z8 example-table">
22
<!-- Position Column -->
3-
<ng-container matColumnDef="position">
3+
<ng-container matColumnDef="position" sticky>
44
<mat-header-cell *matHeaderCellDef [matResizableMaxWidthPx]="100"> No. </mat-header-cell>
55
<mat-cell *matCellDef="let element"> {{element.position}} </mat-cell>
66
</ng-container>
77

88
<!-- Name Column -->
9-
<ng-container matColumnDef="name">
9+
<ng-container matColumnDef="name" sticky>
1010
<mat-header-cell *matHeaderCellDef [matResizableMinWidthPx]="150"> Name </mat-header-cell>
1111
<mat-cell *matCellDef="let element"> {{element.name}} </mat-cell>
1212
</ng-container>

src/components-examples/material-experimental/column-resize/default-enabled/default-enabled-column-resize-example.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8 example-table">
22
<!-- Position Column -->
3-
<ng-container matColumnDef="position">
3+
<ng-container matColumnDef="position" sticky>
44
<th mat-header-cell *matHeaderCellDef [matResizableMaxWidthPx]="100"> No. </th>
55
<td mat-cell *matCellDef="let element"> {{element.position}} </td>
66
</ng-container>
77

88
<!-- Name Column -->
9-
<ng-container matColumnDef="name">
9+
<ng-container matColumnDef="name" sticky>
1010
<th mat-header-cell *matHeaderCellDef [matResizableMinWidthPx]="150"> Name </th>
1111
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
1212
</ng-container>

src/components-examples/material-experimental/column-resize/opt-in/opt-in-column-resize-example.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<table mat-table columnResize [dataSource]="dataSource" class="mat-elevation-z8 example-table">
22
<!-- Position Column -->
3-
<ng-container matColumnDef="position">
3+
<ng-container matColumnDef="position" sticky>
44
<th mat-header-cell *matHeaderCellDef resizable [matResizableMaxWidthPx]="100"> No. </th>
55
<td mat-cell *matCellDef="let element"> {{element.position}} </td>
66
</ng-container>
77

88
<!-- Name Column -->
9-
<ng-container matColumnDef="name">
9+
<ng-container matColumnDef="name" sticky>
1010
<th mat-header-cell *matHeaderCellDef resizable [matResizableMinWidthPx]="150"> Name </th>
1111
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
1212
</ng-container>

src/material-experimental/column-resize/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ ng_module(
1313
deps = [
1414
"//src/cdk-experimental/column-resize",
1515
"//src/cdk/overlay",
16+
"//src/cdk/table",
1617
"//src/material/table",
1718
"@npm//@angular/core",
1819
],

src/material-experimental/column-resize/_column-resize.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
transparent, transparent 7px,
9494
$resizable-active-divider, $resizable-active-divider 1px,
9595
transparent 8px, transparent);
96+
will-change: transform;
9697
}
9798
}
9899
}

src/material-experimental/column-resize/column-resize.spec.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,10 @@ abstract class BaseTestComponent {
196196
}
197197

198198
getOverlayThumbPosition(index: number): number {
199-
const thumbElement = this.getOverlayThumbElement(index);
200-
return parseInt((thumbElement.parentNode as HTMLElement).style.left!, 10);
199+
const thumbPositionElement = this.getOverlayThumbElement(index)!.parentNode as HTMLElement;
200+
const left = parseInt(thumbPositionElement.style.left!, 10);
201+
const translateX = Number(/translateX\((\d+)px\)/.exec(thumbPositionElement.style.transform)?.[1] ?? 0);
202+
return left + translateX;
201203
}
202204

203205
beginColumnResizeWithMouse(index: number, button = 0): void {
@@ -407,6 +409,7 @@ describe('Material Popover Edit', () => {
407409

408410
const initialThumbPosition = component.getOverlayThumbPosition(1);
409411
component.updateResizeWithMouseInProgress(5);
412+
flushMicrotasks();
410413

411414
let thumbPositionDelta = component.getOverlayThumbPosition(1) - initialThumbPosition;
412415
let columnPositionDelta = component.getColumnOriginPosition(1) - initialColumnPosition;
@@ -416,6 +419,7 @@ describe('Material Popover Edit', () => {
416419
(expect(component.getColumnWidth(1)) as any).isApproximately(initialColumnWidth + 5);
417420

418421
component.updateResizeWithMouseInProgress(1);
422+
flushMicrotasks();
419423

420424
thumbPositionDelta = component.getOverlayThumbPosition(1) - initialThumbPosition;
421425
columnPositionDelta = component.getColumnOriginPosition(1) - initialColumnPosition;
@@ -425,6 +429,7 @@ describe('Material Popover Edit', () => {
425429
(expect(component.getColumnWidth(1)) as any).isApproximately(initialColumnWidth + 1);
426430

427431
component.completeResizeWithMouseInProgress(1);
432+
flushMicrotasks();
428433

429434
(expect(component.getColumnWidth(1)) as any).isApproximately(initialColumnWidth + 1);
430435

@@ -447,7 +452,7 @@ describe('Material Popover Edit', () => {
447452
expect(component.getColumnWidth(1)).toBe(initialColumnWidth);
448453
}));
449454

450-
it('cancels an active mouse resize with the escape key', fakeAsync(() => {
455+
fit('cancels an active mouse resize with the escape key', fakeAsync(() => {
451456
const initialTableWidth = component.getTableWidth();
452457
const initialColumnWidth = component.getColumnWidth(1);
453458
const initialColumnPosition = component.getColumnOriginPosition(1);
@@ -459,15 +464,17 @@ describe('Material Popover Edit', () => {
459464
const initialThumbPosition = component.getOverlayThumbPosition(1);
460465

461466
component.updateResizeWithMouseInProgress(5);
467+
flushMicrotasks();
462468

463469
let thumbPositionDelta = component.getOverlayThumbPosition(1) - initialThumbPosition;
464470
let columnPositionDelta = component.getColumnOriginPosition(1) - initialColumnPosition;
465-
expect(thumbPositionDelta).toBe(columnPositionDelta);
471+
(expect(thumbPositionDelta) as any).isApproximately(columnPositionDelta);
466472

467473
(expect(component.getColumnWidth(1)) as any).isApproximately(initialColumnWidth + 5);
468474
(expect(component.getTableWidth()) as any).isApproximately(initialTableWidth + 5);
469475

470476
dispatchKeyboardEvent(document, 'keyup', ESCAPE);
477+
flushMicrotasks();
471478

472479
(expect(component.getColumnWidth(1)) as any).isApproximately(initialColumnWidth);
473480
(expect(component.getTableWidth()) as any).isApproximately(initialTableWidth);
@@ -490,6 +497,7 @@ describe('Material Popover Edit', () => {
490497
expect(resize).toBe(null);
491498

492499
component.resizeColumnWithMouse(1, 5);
500+
flushMicrotasks();
493501

494502
expect(resize).toEqual({columnId: 'name', size: initialColumnWidth + 5} as any);
495503

@@ -508,23 +516,26 @@ describe('Material Popover Edit', () => {
508516
component.beginColumnResizeWithMouse(0);
509517

510518
component.updateResizeWithMouseInProgress(5);
519+
flushMicrotasks();
511520

512521
dispatchKeyboardEvent(document, 'keyup', ESCAPE);
522+
flushMicrotasks();
513523

514524
component.endHoverState();
515525
fixture.detectChanges();
516526

517527
expect(resize).toBe(null);
518528
});
519529

520-
it('performs a column resize triggered via ColumnResizeNotifier', () => {
530+
it('performs a column resize triggered via ColumnResizeNotifier', fakeAsync(() => {
521531
// Pre-verify that we are not updating the size to the initial size.
522532
(expect(component.getColumnWidth(1)) as any).not.isApproximately(173);
523533

524534
component.columnResize.columnResizeNotifier.resize('name', 173);
535+
flushMicrotasks();
525536

526537
(expect(component.getColumnWidth(1)) as any).isApproximately(173);
527-
});
538+
}));
528539
});
529540
}
530541
});

0 commit comments

Comments
 (0)