From 8f8b6ee1b7f652857df60806277bd36e241869b4 Mon Sep 17 00:00:00 2001 From: Michelle Feng Date: Wed, 21 Oct 2020 12:17:00 -0700 Subject: [PATCH 1/2] add keyboard controls --- .../src/lib/component/split.component.scss | 1 + .../src/lib/component/split.component.ts | 77 ++++++++++++++----- projects/angular-split/src/lib/utils.ts | 47 ++++++++++- 3 files changed, 106 insertions(+), 19 deletions(-) diff --git a/projects/angular-split/src/lib/component/split.component.scss b/projects/angular-split/src/lib/component/split.component.scss index 0d5077f0..b29fe6a1 100644 --- a/projects/angular-split/src/lib/component/split.component.scss +++ b/projects/angular-split/src/lib/component/split.component.scss @@ -8,6 +8,7 @@ height: 100%; & > .as-split-gutter { + border: none; flex-grow: 0; flex-shrink: 0; background-color: #eeeeee; diff --git a/projects/angular-split/src/lib/component/split.component.ts b/projects/angular-split/src/lib/component/split.component.ts index 0e7caf4b..c674fc27 100644 --- a/projects/angular-split/src/lib/component/split.component.ts +++ b/projects/angular-split/src/lib/component/split.component.ts @@ -29,6 +29,7 @@ import { getElementPixelSize, getGutterSideAbsorptionCapacity, updateAreaSize, + getKeyboardEndpoint } from '../utils' /** @@ -68,19 +69,20 @@ import { styleUrls: [`./split.component.scss`], template: ` -
-
+
`, encapsulation: ViewEncapsulation.Emulated, }) @@ -521,7 +523,38 @@ export class SplitComponent implements AfterViewInit, OnDestroy { } } - public startDragging(event: MouseEvent | TouchEvent, gutterOrder: number, gutterNum: number): void { + public startKeyboardDrag(event: KeyboardEvent, gutterOrder: number, gutterNum: number) { + switch (event.key) { + case 'ArrowLeft': + case 'ArrowRight': + case 'ArrowUp': + case 'ArrowDown': + break + default: + return + } + + if (this.disabled === true || this.isWaitingClear === true) { + return + } + + const endPoint = getKeyboardEndpoint(event, this.direction) + if (endPoint === null) { + return + } + this.endPoint = endPoint + this.startPoint = getPointFromEvent(event) + + event.preventDefault() + event.stopPropagation() + + this.setupForDragEvent(gutterOrder, gutterNum) + this.startDragging() + this.drag() + this.stopDragging() + } + + public startMouseDrag(event: MouseEvent | TouchEvent, gutterOrder: number, gutterNum: number): void { event.preventDefault() event.stopPropagation() @@ -530,6 +563,21 @@ export class SplitComponent implements AfterViewInit, OnDestroy { return } + this.setupForDragEvent(gutterOrder, gutterNum) + + this.dragListeners.push(this.renderer.listen('document', 'mouseup', this.stopDragging.bind(this))) + this.dragListeners.push(this.renderer.listen('document', 'touchend', this.stopDragging.bind(this))) + this.dragListeners.push(this.renderer.listen('document', 'touchcancel', this.stopDragging.bind(this))) + + this.ngZone.runOutsideAngular(() => { + this.dragListeners.push(this.renderer.listen('document', 'mousemove', this.mouseDragEvent.bind(this))) + this.dragListeners.push(this.renderer.listen('document', 'touchmove', this.mouseDragEvent.bind(this))) + }) + + this.startDragging() + } + + private setupForDragEvent(gutterOrder: number, gutterNum: number) { this.snapshot = { gutterNum, lastSteppedOffset: 0, @@ -569,16 +617,9 @@ export class SplitComponent implements AfterViewInit, OnDestroy { if (this.snapshot.areasBeforeGutter.length === 0 || this.snapshot.areasAfterGutter.length === 0) { return } + } - this.dragListeners.push(this.renderer.listen('document', 'mouseup', this.stopDragging.bind(this))) - this.dragListeners.push(this.renderer.listen('document', 'touchend', this.stopDragging.bind(this))) - this.dragListeners.push(this.renderer.listen('document', 'touchcancel', this.stopDragging.bind(this))) - - this.ngZone.runOutsideAngular(() => { - this.dragListeners.push(this.renderer.listen('document', 'mousemove', this.dragEvent.bind(this))) - this.dragListeners.push(this.renderer.listen('document', 'touchmove', this.dragEvent.bind(this))) - }) - + private startDragging() { this.displayedAreas.forEach((area) => area.component.lockEvents()) this.isDragging = true @@ -588,7 +629,7 @@ export class SplitComponent implements AfterViewInit, OnDestroy { this.notify('start', this.snapshot.gutterNum) } - private dragEvent(event: MouseEvent | TouchEvent): void { + private mouseDragEvent(event: MouseEvent | TouchEvent): void { event.preventDefault() event.stopPropagation() @@ -602,10 +643,10 @@ export class SplitComponent implements AfterViewInit, OnDestroy { } this.endPoint = getPointFromEvent(event) - if (this.endPoint === null) { - return - } + this.drag() + } + private drag() { // Calculate steppedOffset let offset = diff --git a/projects/angular-split/src/lib/utils.ts b/projects/angular-split/src/lib/utils.ts index 5b943b26..89270ea6 100644 --- a/projects/angular-split/src/lib/utils.ts +++ b/projects/angular-split/src/lib/utils.ts @@ -2,7 +2,7 @@ import { ElementRef } from '@angular/core' import { IArea, IPoint, IAreaSnapshot, ISplitSideAbsorptionCapacity, IAreaAbsorptionCapacity } from './interface' -export function getPointFromEvent(event: MouseEvent | TouchEvent): IPoint { +export function getPointFromEvent(event: MouseEvent | TouchEvent | KeyboardEvent): IPoint { // TouchEvent if ((event).changedTouches !== undefined && (event).changedTouches.length > 0) { return { @@ -17,9 +17,54 @@ export function getPointFromEvent(event: MouseEvent | TouchEvent): IPoint { y: (event).clientY, } } + // KeyboardEvent + else if ((event).currentTarget !== undefined) { + const gutterEl = event.currentTarget as HTMLElement; + return { + x: gutterEl.offsetLeft, + y: gutterEl.offsetTop + } + } return null } +export function getKeyboardEndpoint(event: KeyboardEvent, direction: 'horizontal' | 'vertical'): IPoint | null { + // Return null if direction keys on the opposite axis were pressed + if (direction === 'horizontal') { + switch (event.key) { + case 'ArrowLeft': + case 'ArrowRight': + break + default: + return null + } + } + if (direction === 'vertical') { + switch (event.key) { + case 'ArrowUp': + case 'ArrowDown': + break + default: + return null + } + } + + const gutterEl = event.currentTarget as HTMLElement + let offsetX = gutterEl.offsetLeft, offsetY = gutterEl.offsetTop + switch (event.key) { + case 'ArrowLeft': offsetX -= 50; break + case 'ArrowRight': offsetX += 50; break + case 'ArrowUp': offsetY -= 50; break + case 'ArrowDown': offsetY += 50; break + default: return null + } + + return { + x: offsetX, + y: offsetY + } +} + export function getElementPixelSize(elRef: ElementRef, direction: 'horizontal' | 'vertical'): number { const rect = (elRef.nativeElement).getBoundingClientRect() From 847c2041b63fd072d0c29bd20a4769bdbc1f07f0 Mon Sep 17 00:00:00 2001 From: Michelle Feng Date: Wed, 21 Oct 2020 17:15:48 -0700 Subject: [PATCH 2/2] add keyboard controls - address comments --- .../src/lib/component/split.component.ts | 10 ---------- projects/angular-split/src/lib/utils.ts | 11 ++++++----- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/projects/angular-split/src/lib/component/split.component.ts b/projects/angular-split/src/lib/component/split.component.ts index c674fc27..32e1200b 100644 --- a/projects/angular-split/src/lib/component/split.component.ts +++ b/projects/angular-split/src/lib/component/split.component.ts @@ -524,16 +524,6 @@ export class SplitComponent implements AfterViewInit, OnDestroy { } public startKeyboardDrag(event: KeyboardEvent, gutterOrder: number, gutterNum: number) { - switch (event.key) { - case 'ArrowLeft': - case 'ArrowRight': - case 'ArrowUp': - case 'ArrowDown': - break - default: - return - } - if (this.disabled === true || this.isWaitingClear === true) { return } diff --git a/projects/angular-split/src/lib/utils.ts b/projects/angular-split/src/lib/utils.ts index 89270ea6..4152bc5e 100644 --- a/projects/angular-split/src/lib/utils.ts +++ b/projects/angular-split/src/lib/utils.ts @@ -19,7 +19,7 @@ export function getPointFromEvent(event: MouseEvent | TouchEvent | KeyboardEvent } // KeyboardEvent else if ((event).currentTarget !== undefined) { - const gutterEl = event.currentTarget as HTMLElement; + const gutterEl = event.currentTarget as HTMLElement return { x: gutterEl.offsetLeft, y: gutterEl.offsetTop @@ -50,12 +50,13 @@ export function getKeyboardEndpoint(event: KeyboardEvent, direction: 'horizontal } const gutterEl = event.currentTarget as HTMLElement + const offset = 50; let offsetX = gutterEl.offsetLeft, offsetY = gutterEl.offsetTop switch (event.key) { - case 'ArrowLeft': offsetX -= 50; break - case 'ArrowRight': offsetX += 50; break - case 'ArrowUp': offsetY -= 50; break - case 'ArrowDown': offsetY += 50; break + case 'ArrowLeft': offsetX -= offset; break + case 'ArrowRight': offsetX += offset; break + case 'ArrowUp': offsetY -= offset; break + case 'ArrowDown': offsetY += offset; break default: return null }