Skip to content

Commit

Permalink
Switch to using pointer events for column resizing
Browse files Browse the repository at this point in the history
  • Loading branch information
m-akinc committed Oct 11, 2024
1 parent f2cd5e9 commit 7e2f460
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 91 deletions.
38 changes: 8 additions & 30 deletions packages/nimble-components/src/table/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -545,55 +545,33 @@ export class Table<
}

/** @internal */
public onRightDividerMouseDown(
event: MouseEvent,
public onRightDividerPointerDown(
event: PointerEvent,
columnIndex: number
): void {
if (event.button === 0) {
if (event.pointerType !== 'mouse' || event.button === 0) {
this.layoutManager.beginColumnInteractiveSize(
event.clientX,
this.getRightDividerIndex(columnIndex)
);
event.preventDefault();
}
}

/** @internal */
public onRightDividerTouchStart(
event: TouchEvent,
public onLeftDividerPointerDown(
event: PointerEvent,
columnIndex: number
): void {
this.layoutManager.beginColumnInteractiveSize(
event.targetTouches[0]!.clientX,
this.getRightDividerIndex(columnIndex)
);
event.preventDefault();
}

/** @internal */
public onLeftDividerMouseDown(
event: MouseEvent,
columnIndex: number
): void {
if (event.button === 0) {
if (event.pointerType !== 'mouse' || event.button === 0) {
this.layoutManager.beginColumnInteractiveSize(
event.clientX,
this.getLeftDividerIndex(columnIndex)
);
event.preventDefault();
}
}

/** @internal */
public onLeftDividerTouchStart(
event: TouchEvent,
columnIndex: number
): void {
this.layoutManager.beginColumnInteractiveSize(
event.targetTouches[0]!.clientX,
this.getLeftDividerIndex(columnIndex)
);
event.preventDefault();
}

/** @internal */
public getLeftDividerIndex(columnIndex: number): number {
return columnIndex * 2 - 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,8 @@ export class TableLayoutManager<TData extends TableRecord> {
this.initialTableScrollableMinWidth = this.table.tableScrollableMinWidth;
this.initialColumnTotalWidth = this.getTotalColumnFixedWidth();
this.isColumnBeingSized = true;
document.addEventListener('mousemove', this.onDividerMouseMove);
document.addEventListener('touchmove', this.onDividerTouchMove);
document.addEventListener('mouseup', this.onDividerMoveEnd);
document.addEventListener('touchend', this.onDividerMoveEnd);
document.addEventListener('pointermove', this.onDividerPointerMove);
document.addEventListener('pointerup', this.onDividerPointerUp);
}

/**
Expand All @@ -97,20 +95,12 @@ export class TableLayoutManager<TData extends TableRecord> {
return this.getFirstRightResizableColumnIndex(columnIndex) !== -1;
}

private readonly onDividerMouseMove = (event: Event): void => {
this.onDividerMove((event as MouseEvent).clientX);
};

private readonly onDividerTouchMove = (event: Event): void => {
this.onDividerMove((event as TouchEvent).targetTouches[0]!.clientX);
};

private onDividerMove(clientX: number): void {
private readonly onDividerPointerMove = (event: PointerEvent): void => {
for (let i = 0; i < this.visibleColumns.length; i++) {
this.visibleColumns[i]!.columnInternals.currentPixelWidth = this.initialColumnWidths[i]?.initialPixelWidth;
}
this.currentTotalDelta = this.getAllowedSizeDelta(
clientX - this.dragStart
event.clientX - this.dragStart
);
this.performCascadeSizeLeft(
this.leftColumnIndex!,
Expand All @@ -127,13 +117,11 @@ export class TableLayoutManager<TData extends TableRecord> {
} else {
this.table.tableScrollableMinWidth = this.initialTableScrollableMinWidth!;
}
}
};

private readonly onDividerMoveEnd = (): void => {
document.removeEventListener('mousemove', this.onDividerMouseMove);
document.removeEventListener('touchmove', this.onDividerTouchMove);
document.removeEventListener('mouseup', this.onDividerMoveEnd);
document.removeEventListener('touchend', this.onDividerMoveEnd);
private readonly onDividerPointerUp = (): void => {
document.removeEventListener('pointermove', this.onDividerPointerMove);
document.removeEventListener('pointerup', this.onDividerPointerUp);
this.resetGridSizedColumns();
this.isColumnBeingSized = false;
this.activeColumnIndex = undefined;
Expand Down
1 change: 1 addition & 0 deletions packages/nimble-components/src/table/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export const styles = css`
);
left: var(--ni-private-table-scroll-x);
align-items: center;
touch-action: pan-y;
}
.header-row-action-container {
Expand Down
6 changes: 2 additions & 4 deletions packages/nimble-components/src/table/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,7 @@ export const template = html<Table>`
${(_, c) => `${c.parent.layoutManager.activeColumnDivider === c.parent.getLeftDividerIndex(c.index) ? 'divider-active' : ''}`}
${(_, c) => `${c.parent.layoutManager.hasResizableColumnToLeft(c.index - 1) ? 'draggable' : ''}`}
"
@mousedown="${(_, c) => c.parent.onLeftDividerMouseDown(c.event as MouseEvent, c.index)}"
@touchstart="${(_, c) => c.parent.onLeftDividerTouchStart(c.event as TouchEvent, c.index)}">
@pointerdown="${(_, c) => c.parent.onLeftDividerPointerDown(c.event as PointerEvent, c.index)}">
</div>
`)}
<${tableHeaderTag}
Expand All @@ -129,8 +128,7 @@ export const template = html<Table>`
${(_, c) => `${c.parent.layoutManager.activeColumnDivider === c.parent.getRightDividerIndex(c.index) ? 'divider-active' : ''}`}
${(_, c) => `${c.parent.layoutManager.hasResizableColumnToLeft(c.index) ? 'draggable' : ''}`}
"
@mousedown="${(_, c) => c.parent.onRightDividerMouseDown(c.event as MouseEvent, c.index)}"
@touchstart="${(_, c) => c.parent.onRightDividerTouchStart(c.event as TouchEvent, c.index)}">
@pointerdown="${(_, c) => c.parent.onRightDividerPointerDown(c.event as PointerEvent, c.index)}">
</div>
`)}
</div>
Expand Down
64 changes: 27 additions & 37 deletions packages/nimble-components/src/table/testing/table.pageobject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -541,24 +541,7 @@ export class TablePageObject<T extends TableRecord> {
'The provided column index has no right divider associated with it.'
);
}
const dividerRect = divider.getBoundingClientRect();
let currentMouseX = (dividerRect.x + dividerRect.width) / 2;
const mouseDownEvent = new MouseEvent('mousedown', {
clientX: currentMouseX,
clientY: (dividerRect.y + dividerRect.height) / 2
});
divider.dispatchEvent(mouseDownEvent);

for (const delta of deltas) {
currentMouseX += delta;
const mouseMoveEvent = new MouseEvent('mousemove', {
clientX: currentMouseX
});
document.dispatchEvent(mouseMoveEvent);
}

const mouseUpEvent = new MouseEvent('mouseup');
document.dispatchEvent(mouseUpEvent);
this.dragSizeColumnByDivider(divider, deltas);
}

/**
Expand All @@ -576,24 +559,7 @@ export class TablePageObject<T extends TableRecord> {
'The provided column index has no left divider associated with it.'
);
}
const dividerRect = divider.getBoundingClientRect();
let currentMouseX = (dividerRect.x + dividerRect.width) / 2;
const mouseDownEvent = new MouseEvent('mousedown', {
clientX: currentMouseX,
clientY: (dividerRect.y + dividerRect.height) / 2
});
divider.dispatchEvent(mouseDownEvent);

for (const delta of deltas) {
currentMouseX += delta;
const mouseMoveEvent = new MouseEvent('mousemove', {
clientX: currentMouseX
});
document.dispatchEvent(mouseMoveEvent);
}

const mouseUpEvent = new MouseEvent('mouseup');
document.dispatchEvent(mouseUpEvent);
this.dragSizeColumnByDivider(divider, deltas);
}

public getColumnRightDivider(index: number): HTMLElement | null {
Expand Down Expand Up @@ -855,9 +821,33 @@ export class TablePageObject<T extends TableRecord> {
return spinnerOrIcon;
}

private dragSizeColumnByDivider(
divider: HTMLElement,
deltas: readonly number[]
): void {
const dividerRect = divider.getBoundingClientRect();
let currentPointerX = (dividerRect.x + dividerRect.width) / 2;
const mouseDownEvent = new PointerEvent('pointerdown', {
clientX: currentPointerX,
clientY: (dividerRect.y + dividerRect.height) / 2
});
divider.dispatchEvent(mouseDownEvent);

for (const delta of deltas) {
currentPointerX += delta;
const pointerMoveEvent = new PointerEvent('pointermove', {
clientX: currentPointerX
});
document.dispatchEvent(pointerMoveEvent);
}

const pointerUpEvent = new PointerEvent('pointerup');
document.dispatchEvent(pointerUpEvent);
}

private readonly isSlotElement = (
element: Node | undefined
): element is HTMLSlotElement => {
return element?.nodeName === 'SLOT' ?? false;
return element?.nodeName === 'SLOT';
};
}

0 comments on commit 7e2f460

Please sign in to comment.