Skip to content

Commit d197464

Browse files
committed
Almost ready to go save for flex
1 parent b1476a6 commit d197464

File tree

6 files changed

+97
-119
lines changed

6 files changed

+97
-119
lines changed

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@ export interface ColumnSize {
66
readonly size: number;
77
}
88

9+
export interface ColumnSizeAction extends ColumnSize {
10+
readonly completeImmediately?: boolean;
11+
}
12+
913
@Injectable()
1014
export class _ColumnResizeNotifierSource {
11-
readonly resizeCanceled = new Subject<ColumnSize>();
15+
readonly resizeCanceled = new Subject<ColumnSizeAction>();
1216
readonly resizeCompleted = new Subject<ColumnSize>();
13-
readonly triggerResize = new Subject<ColumnSize>();
17+
readonly triggerResize = new Subject<ColumnSizeAction>();
1418
}
1519

1620
@Injectable()
@@ -20,6 +24,6 @@ export class ColumnResizeNotifier {
2024
constructor(private readonly _source: _ColumnResizeNotifierSource) {}
2125

2226
resize(columnId: string, size: number): void {
23-
this._source.triggerResize.next({columnId, size});
27+
this._source.triggerResize.next({columnId, size, completeImmediately: true});
2428
}
2529
}

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {AfterViewInit, Directive, ElementRef, NgZone, OnDestroy} from '@angular/core';
22
import {Directionality} from '@angular/cdk/bidi';
33
import {fromEvent, merge, ReplaySubject} from 'rxjs';
4-
import {filter, map, mapTo, pairwise, startWith, take, takeUntil, tap} from 'rxjs/operators';
4+
import {filter, map, mapTo, pairwise, startWith, take, takeUntil} from 'rxjs/operators';
55

66
import {matches} from '../popover-edit/polyfill';
77

@@ -64,17 +64,15 @@ export abstract class ColumnResize implements AfterViewInit, OnDestroy {
6464
}
6565

6666
private _listenForRowHoverEvents() {
67-
this.ngZone.runOutsideAngular(() => {console.log(1);
67+
this.ngZone.runOutsideAngular(() => {
6868
const element = this.elementRef.nativeElement!;
6969

7070
fromEvent<MouseEvent>(element, 'mouseover').pipe(
7171
takeUntil(this.destroyed),
7272
map(event => closest(event.target, HEADER_CELL_SELECTOR)),
73-
tap(cell => console.log('hovered', cell)),
7473
).subscribe(this.eventDispatcher.headerCellHovered);
7574
fromEvent<MouseEvent>(element, 'mouseleave').pipe(
7675
takeUntil(this.destroyed),
77-
tap(event => console.log('mouseleave related target', event.relatedTarget)),
7876
filter(event => !!event.relatedTarget && !matches(event.relatedTarget as Element, RESIZE_OVERLAY_SELECTOR)),
7977
mapTo(null),
8078
).subscribe(this.eventDispatcher.headerCellHovered);
@@ -89,7 +87,7 @@ export abstract class ColumnResize implements AfterViewInit, OnDestroy {
8987
).pipe(
9088
takeUntil(this.destroyed),
9189
take(1),
92-
).subscribe(() => {console.log('do it!');
90+
).subscribe(() => {
9391
this.elementRef.nativeElement!.classList.add(this.getWithResizedColumnClass());
9492
});
9593
}

src/cdk-experimental/column-resize/event-dispatcher.ts

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {Injectable, NgZone} from '@angular/core';
22
import {combineLatest, MonoTypeOperatorFunction, Observable, Subject} from 'rxjs';
3-
import {/*auditTime,*/ distinctUntilChanged, finalize, map, share, skip, startWith, tap} from 'rxjs/operators';
3+
import {distinctUntilChanged, map, share, skip, startWith} from 'rxjs/operators';
44

55
import {closest} from '../popover-edit/polyfill';
66

@@ -13,24 +13,7 @@ export class _HeaderRowEventDispatcher {
1313
// element refers to header row
1414
readonly overlayHandleActiveForCell = new Subject<Element|null>();
1515

16-
constructor(private readonly _ngZone: NgZone) {
17-
this.headerCellHovered.pipe(finalize(() => console.log('it stopped?')))
18-
.subscribe(() => console.log('starting up'));
19-
}
20-
21-
/* private readonly _headerRowHoveredDistinct = this.headerRowHovered.pipe(
22-
startWith(null),
23-
distinctUntilChanged(),
24-
share(),
25-
tap(row => console.log('row hovered', row)),
26-
);
27-
28-
private readonly _overlayActiveOrHoveredDistinct = this.overlayHandleActive.pipe(
29-
startWith(null),
30-
distinctUntilChanged(),
31-
share(),
32-
tap(row => console.log('overlay active', cell)),
33-
);*/
16+
constructor(private readonly _ngZone: NgZone) {}
3417

3518
readonly headerCellHoveredDistinct = this.headerCellHovered.pipe(
3619
distinctUntilChanged(),
@@ -40,16 +23,13 @@ export class _HeaderRowEventDispatcher {
4023
readonly headerRowHoveredOrActiveDistinct = combineLatest(
4124
this.headerCellHoveredDistinct.pipe(
4225
map(cell => closest(cell, HEADER_ROW_SELECTOR)),
43-
tap(row => console.log('hovered row', row)),
4426
startWith(null),
4527
distinctUntilChanged(),
46-
tap(row => console.log('row hovered', row)),
4728
),
4829
this.overlayHandleActiveForCell.pipe(
4930
map(cell => closest(cell, HEADER_ROW_SELECTOR)),
5031
startWith(null),
5132
distinctUntilChanged(),
52-
tap(row => console.log('overlay active', row)),
5333
),
5434
).pipe(
5535
skip(1),
@@ -82,20 +62,6 @@ export class _HeaderRowEventDispatcher {
8262
return this._lastSeenRowHover!;
8363
}
8464

85-
cellOrRelatedOverlayHovered(cell: Element): Observable<boolean> {
86-
return this.headerCellHoveredDistinct.pipe(
87-
map(hoveredCell => hoveredCell === cell),
88-
distinctUntilChanged(),
89-
);
90-
}
91-
92-
nextCellOrRelatedOverlayHovered(cell: Element): Observable<boolean> {
93-
return this.headerCellHoveredDistinct.pipe(
94-
map(hoveredCell => !!hoveredCell && hoveredCell.previousElementSibling === cell),
95-
distinctUntilChanged(),
96-
);
97-
}
98-
9965
private _enterZone<T>(): MonoTypeOperatorFunction<T> {
10066
return (source: Observable<T>) =>
10167
new Observable<T>((observer) => source.subscribe({

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@ import {Directionality} from '@angular/cdk/bidi';
44
import {ESCAPE} from '@angular/cdk/keycodes';
55
import {CdkColumnDef} from '@angular/cdk/table';
66
import {fromEvent, ReplaySubject} from 'rxjs';
7-
import {distinctUntilChanged, filter, map, mapTo, pairwise, startWith, takeUntil} from 'rxjs/operators';
7+
import {
8+
distinctUntilChanged,
9+
filter,
10+
map,
11+
mapTo,
12+
pairwise,
13+
startWith,
14+
takeUntil,
15+
} from 'rxjs/operators';
816

917
import {closest} from '../popover-edit/polyfill';
1018

@@ -71,11 +79,13 @@ export abstract class ResizeOverlayHandle implements AfterViewInit, OnDestroy {
7179
mouseup.pipe(takeUntil(escape), takeUntilDestroyed).subscribe(({pageX}) => {
7280
this.updateResizeActive(false);
7381

74-
if (pageX !== startX) {
75-
this.ngZone.run(() => {
82+
this.ngZone.run(() => {
83+
if (pageX !== startX) {
7684
this.resizeNotifier.resizeCompleted.next({columnId, size});
77-
});
78-
}
85+
} else {
86+
this.resizeNotifier.resizeCanceled.next({columnId, size});
87+
}
88+
});
7989
});
8090

8191
escape.pipe(takeUntil(mouseup), takeUntil(this.destroyed)).subscribe(() => {

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

Lines changed: 53 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
ElementRef,
44
Inject,
55
Injector,
6+
NgZone,
67
OnDestroy,
78
Type,
89
ViewContainerRef
@@ -20,7 +21,7 @@ import {closest} from '../popover-edit/polyfill';
2021
import {HEADER_ROW_SELECTOR} from './constants';
2122
import {ResizeOverlayHandle} from './overlay-handle';
2223
import {ColumnResize} from './column-resize';
23-
import {ColumnSize, _ColumnResizeNotifierSource} from './column-resize-notifier';
24+
import {ColumnSizeAction, _ColumnResizeNotifierSource} from './column-resize-notifier';
2425
import {_HeaderRowEventDispatcher} from './event-dispatcher';
2526
import {ResizeRef} from './resize-ref';
2627

@@ -29,6 +30,7 @@ export abstract class Resizable<HandleComponent extends ResizeOverlayHandle>
2930
minPx: number = 0;
3031
maxPx: number = Number.MAX_SAFE_INTEGER;
3132

33+
protected inlineHandle?: HTMLElement;
3234
protected overlayRef?: OverlayRef;
3335
protected readonly destroyed = new ReplaySubject<void>();
3436
protected readonly document: Document;
@@ -42,6 +44,7 @@ export abstract class Resizable<HandleComponent extends ResizeOverlayHandle>
4244
protected readonly elementRef: ElementRef,
4345
protected readonly eventDispatcher: _HeaderRowEventDispatcher,
4446
protected readonly injector: Injector,
47+
protected readonly ngZone: NgZone,
4548
protected readonly overlay: Overlay,
4649
protected readonly resizeNotifier: _ColumnResizeNotifierSource,
4750
protected readonly viewContainerRef: ViewContainerRef) {
@@ -57,6 +60,10 @@ export abstract class Resizable<HandleComponent extends ResizeOverlayHandle>
5760
ngOnDestroy(): void {
5861
this.destroyed.next();
5962
this.destroyed.complete();
63+
64+
if (this.inlineHandle) {
65+
this.elementRef.nativeElement!.removeChild(this.inlineHandle);
66+
}
6067

6168
if (this.overlayRef) {
6269
this.overlayRef.dispose();
@@ -77,14 +84,13 @@ export abstract class Resizable<HandleComponent extends ResizeOverlayHandle>
7784
protected abstract getColumnCssClassName(): string;
7885

7986
private _listenForRowHoverEvents(): void {
80-
console.log('init', this.columnDef.name);
8187
const element = this.elementRef.nativeElement!;
8288
const takeUntilDestroyed = takeUntil<boolean>(this.destroyed);
8389

8490

8591
this.eventDispatcher.resizeOverlayVisibleForHeaderRow(closest(element, HEADER_ROW_SELECTOR)!)
8692
.pipe(takeUntilDestroyed).subscribe(hoveringRow => {
87-
if (hoveringRow) {console.log('a', hoveringRow, this.columnDef.name);
93+
if (hoveringRow) {
8894
if (!this.overlayRef) {
8995
this.overlayRef = this.createOverlayForHandle();
9096
}
@@ -95,50 +101,44 @@ export abstract class Resizable<HandleComponent extends ResizeOverlayHandle>
95101
this.overlayRef.detach();
96102
}
97103
});
98-
99-
this.eventDispatcher.cellOrRelatedOverlayHovered(element)
100-
.pipe(takeUntilDestroyed).subscribe(hovering => {
101-
// TODO: Use toggle once we're off IE11.
102-
if (hovering) {
103-
element.classList.add('resizable-hover');
104-
} else {
105-
element.classList.remove('resizable-hover');
106-
}
107-
});
108-
109-
this.eventDispatcher.nextCellOrRelatedOverlayHovered(element)
110-
.pipe(takeUntilDestroyed).subscribe(hoveringNext => {
111-
// TODO: Use toggle once we're off IE11.
112-
if (hoveringNext) {
113-
element.classList.add('next-resizable-hover');
114-
} else {
115-
element.classList.remove('next-resizable-hover');
116-
}
117-
});
118104
}
119105

120106
private _listenForResizeEvents() {
121-
const takeUntilDestroyed = takeUntil<ColumnSize>(this.destroyed);
107+
const takeUntilDestroyed = takeUntil<ColumnSizeAction>(this.destroyed);
122108

123109
merge(
124110
this.resizeNotifier.resizeCanceled,
125111
this.resizeNotifier.triggerResize,
126112
).pipe(
127113
takeUntilDestroyed,
128114
filter(columnSize => columnSize.columnId === this.columnDef.name),
129-
).subscribe(({size}) => {
130-
this._applySize(size);
115+
).subscribe(({size, completeImmediately}) => {
131116
this.elementRef.nativeElement!.classList.add('resizable-overlay-thumb-active');
117+
this._applySize(size);
118+
119+
if (completeImmediately) {
120+
this.ngZone.run(() => {
121+
this.resizeNotifier.resizeCompleted.next({
122+
columnId: this.columnDef.name,
123+
size: this.elementRef.nativeElement!.offsetWidth,
124+
});
125+
});
126+
}
132127
});
133128

134129
merge(
135130
this.resizeNotifier.resizeCanceled,
136131
this.resizeNotifier.resizeCompleted,
137-
).pipe(takeUntilDestroyed).subscribe(() => {
132+
).pipe(takeUntilDestroyed).subscribe(columnSize => {
133+
this.elementRef.nativeElement!.classList.remove('resizable-overlay-thumb-active');
134+
138135
if (this.overlayRef && this.overlayRef.hasAttached()) {
139136
this._updateOverlayHandleHeight();
140-
this.elementRef.nativeElement!.classList.remove('resizable-overlay-thumb-active');
141137
this.overlayRef.updatePosition();
138+
139+
if (columnSize.columnId === this.columnDef.name) {
140+
this.inlineHandle!.focus();
141+
}
142142
}
143143
});
144144
}
@@ -150,9 +150,9 @@ export abstract class Resizable<HandleComponent extends ResizeOverlayHandle>
150150
return new ComponentPortal(this.getOverlayHandleComponentType(), this.viewContainerRef, injector);
151151
}
152152

153-
private _showHandleOverlay(): void {console.log('b');
153+
private _showHandleOverlay(): void {
154154
this._updateOverlayHandleHeight();
155-
this.overlayRef!.attach(this._createHandlePortal());console.log('c');
155+
this.overlayRef!.attach(this._createHandlePortal());
156156
}
157157

158158
private _updateOverlayHandleHeight() {
@@ -161,20 +161,18 @@ export abstract class Resizable<HandleComponent extends ResizeOverlayHandle>
161161

162162
private _applySize(sizeInPixels: number): void {
163163
const sizeToApply = Math.min(Math.max(sizeInPixels, this.minPx, 0), this.maxPx);
164-
const columnClassName = this.getColumnCssClassName();
164+
/* const columnClassName = this.getColumnCssClassName();
165165
const tableClassName = this.columnResize.getIdClass();
166166
167-
const selector = `.${tableClassName} .${columnClassName}`;
167+
const selector = `.${tableClassName} .${columnClassName}`;*/
168168
const width = coerceCssPixelValue(sizeToApply);
169169

170-
console.time('apply size');
171-
172170
// approach 0 (issues if number or order of cols change)
173171
// also does not work, seemingly
174172
/* const table = document.querySelector(`.${tableClassName}`);
175173
const cols = table!.querySelectorAll('col');
176174
const index = Array.from(this.elementRef.nativeElement!.parentNode.childNodes).indexOf(this.elementRef.nativeElement!);
177-
console.log(cols, index);
175+
178176
cols[index].style.width = width;*/
179177

180178
// approach 1 (no subsequent updates though)
@@ -186,16 +184,29 @@ export abstract class Resizable<HandleComponent extends ResizeOverlayHandle>
186184
// approach 1a
187185
/* cells[0].style.width = width;*/
188186

187+
// approach 1b
188+
189+
// With table-layout: fixed, all we have to do is set the size on the
190+
// header element and the whole column will update.
191+
// This is by far the fastest way to resize a table column tested.
192+
// Also tested: resizing by adding CSS selectors, selectors with CSS variables.
193+
this.elementRef.nativeElement!.style.boxSizing = 'border-box';
194+
this.elementRef.nativeElement!.style.width = width;
195+
196+
//////////
197+
// todo: for flex-based tables, we'll need a different approach.
198+
//////////
199+
189200
// approach 2
190-
if (!this._styleElement) {
201+
/* if (!this._styleElement) {
191202
this._styleElement = this.document.createElement('style');
192203
this._styleElement.appendChild(this.document.createTextNode(''));
193204
this.document.head.appendChild(this._styleElement);
194205
} else {
195206
(this._styleElement.sheet as CSSStyleSheet).deleteRule(0);
196207
}
197208
(this._styleElement.sheet as CSSStyleSheet).insertRule(
198-
`${selector} {box-sizing: border-box;width:${width}}`, 0);
209+
`${selector} {box-sizing: border-box;width:${width}}`, 0);*/
199210

200211
// approach 2.5
201212

@@ -208,20 +219,18 @@ export abstract class Resizable<HandleComponent extends ResizeOverlayHandle>
208219
209220
210221
const sheet = this._styleElement.sheet as CSSStyleSheet;
211-
console.log(`${selector} {width:${cssVar}}`);
222+
212223
sheet.insertRule(`${selector} {width:var(${cssVar})}`, 0);
213224
}*/
214-
215-
console.timeEnd('apply size');
216225
}
217226

218227
private _appendInlineHandle(): void {
219-
const handle = document.createElement('div');
220-
handle.tabIndex = 0;
221-
handle.className = this.getInlineHandleCssClassName();
228+
this.inlineHandle = document.createElement('div');
229+
this.inlineHandle.tabIndex = 0;
230+
this.inlineHandle.className = this.getInlineHandleCssClassName();
222231

223232
// TODO: Apply correct aria role (probably slider) after a11y spec questions resolved.
224233

225-
this.elementRef.nativeElement!.appendChild(handle);
234+
this.elementRef.nativeElement!.appendChild(this.inlineHandle);
226235
}
227236
}

0 commit comments

Comments
 (0)