Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(mwlResizeHandle): add resizableContainer input #128

Merged
merged 2 commits into from
Jun 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/resizable.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,15 @@ export const MOUSE_MOVE_THROTTLE_MS: number = 50;
* [enableGhostResize]="true">
* </div>
* ```
* Or in case they are sibling elements:
* ```html
* <div mwlResizable #resizableElement="mwlResizable"></div>
* <div mwlResizeHandle [resizableContainer]="resizableElement" [resizeEdges]="{bottom: true, right: true}"></div>
* ```
*/
@Directive({
selector: '[mwlResizable]'
selector: '[mwlResizable]',
exportAs: 'mwlResizable'
})
export class ResizableDirective implements OnInit, OnChanges, OnDestroy {
/**
Expand Down Expand Up @@ -417,7 +423,12 @@ export class ResizableDirective implements OnInit, OnChanges, OnDestroy {
).pipe(
tap(({ event }) => {
if (currentResize) {
event.preventDefault();
try {
event.preventDefault();
} catch (e) {
// just adding try-catch not to see errors in console if there is a passive listener for same event somewhere
// browser does nothing except of writing errors to console
}
}
}),
share()
Expand Down
19 changes: 17 additions & 2 deletions src/resize-handle.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
ElementRef,
OnInit,
OnDestroy,
NgZone
NgZone,
Optional
} from '@angular/core';
import { fromEvent, merge, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
Expand All @@ -23,6 +24,11 @@ import { IS_TOUCH_DEVICE } from './is-touch-device';
* <div mwlResizeHandle [resizeEdges]="{bottom: true, right: true}"></div>
* </div>
* ```
* Or in case they are sibling elements:
* ```html
* <div mwlResizable #resizableElement="mwlResizable"></div>
* <div mwlResizeHandle [resizableContainer]="resizableElement" [resizeEdges]="{bottom: true, right: true}"></div>
* ```
*/
@Directive({
selector: '[mwlResizeHandle]'
Expand All @@ -32,6 +38,10 @@ export class ResizeHandleDirective implements OnInit, OnDestroy {
* The `Edges` object that contains the edges of the parent element that dragging the handle will trigger a resize on
*/
@Input() resizeEdges: Edges = {};
/**
* Reference to ResizableDirective in case if handle is not located inside of element with ResizableDirective
*/
@Input() resizableContainer: ResizableDirective;

private eventListeners: {
touchmove?: () => void;
Expand All @@ -45,7 +55,7 @@ export class ResizeHandleDirective implements OnInit, OnDestroy {
private renderer: Renderer2,
private element: ElementRef,
private zone: NgZone,
private resizable: ResizableDirective
@Optional() private resizableDirective: ResizableDirective
) {}

ngOnInit(): void {
Expand Down Expand Up @@ -139,6 +149,11 @@ export class ResizeHandleDirective implements OnInit, OnDestroy {
});
}

// directive might be passed from DI or as an input
private get resizable(): ResizableDirective {
return this.resizableDirective || this.resizableContainer;
}

private onMousemove(
event: MouseEvent | TouchEvent,
clientX: number,
Expand Down
71 changes: 69 additions & 2 deletions test/resizable.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* tslint:disable:max-inline-declarations enforce-component-selector */
import { Component, ViewChild } from '@angular/core';
import { Component, ElementRef, ViewChild } from '@angular/core';
import { ResizableDirective } from '../src/resizable.directive';
import { Edges } from '../src/interfaces/edges.interface';
import { ResizeEvent, ResizableModule } from '../src';
import { ResizeEvent, ResizableModule, ResizeHandleDirective } from '../src';
import { MOUSE_MOVE_THROTTLE_MS } from '../src/resizable.directive';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { expect } from 'chai';
Expand Down Expand Up @@ -44,6 +44,7 @@ describe('resizable directive', () => {
})
class TestComponent {
@ViewChild(ResizableDirective) resizable: ResizableDirective;
@ViewChild('handle') handle: ElementRef;
style: object = {};
resizeStart: sinon.SinonSpy = sinon.spy();
resizing: sinon.SinonSpy = sinon.spy();
Expand Down Expand Up @@ -570,6 +571,72 @@ describe('resizable directive', () => {
});
});

describe('handle outside of element', () => {
let domEvents: any[];
let spyName: string;
let expectedEvent: object;

it('should emit a starting resize event', () => {
domEvents = [
{
name: 'mousedown',
data: {
clientX: 150,
clientY: 200
}
}
];
spyName = 'resizeStart';
expectedEvent = {
edges: {
right: 0
},
rectangle: {
top: 200,
left: 100,
width: 300,
height: 150,
right: 400,
bottom: 350
}
};
});

afterEach(() => {
const template: string = `
<div
class="rectangle"
[ngStyle]="style"
mwlResizable
#container='mwlResizable'
(resizeStart)="resizeStart($event)"
>
</div>
<span
style="width: 5px; height: 5px; position: absolute; bottom: 5px; right: 5px"
class="resize-handle"
mwlResizeHandle
#handle
[resizableContainer]='container'
[resizeEdges]="{right: true}">
</span>
`;
const fixture: ComponentFixture<TestComponent> = createComponent(
template
);
const handleElem: HTMLElement =
fixture.componentInstance.handle.nativeElement;

domEvents.forEach(event => {
triggerDomEvent(event.name, handleElem, event.data);
});

expect(
(fixture.componentInstance as any)[spyName]
).to.have.been.calledWith(expectedEvent);
});
});

it('should not resize when clicking and dragging outside of the element edges', () => {
const fixture: ComponentFixture<TestComponent> = createComponent();
const elm: HTMLElement =
Expand Down