UNPKG

angular-resizable-element

Version:

An angular 20.0+ directive that allows an element to be dragged and resized

1 lines 57.1 kB
{"version":3,"file":"angular-resizable-element.mjs","sources":["../../../projects/angular-resizable-element/src/lib/util/is-touch-device.ts","../../../projects/angular-resizable-element/src/lib/util/clone-node.ts","../../../projects/angular-resizable-element/src/lib/resizable.directive.ts","../../../projects/angular-resizable-element/src/lib/resize-handle.directive.ts","../../../projects/angular-resizable-element/src/lib/resizable.module.ts","../../../projects/angular-resizable-element/src/public-api.ts","../../../projects/angular-resizable-element/src/angular-resizable-element.ts"],"sourcesContent":["/**\n * @hidden\n */\nexport const IS_TOUCH_DEVICE: boolean = (() => {\n // In case we're in Node.js environment.\n if (typeof window === 'undefined') {\n return false;\n } else {\n return (\n 'ontouchstart' in window ||\n navigator.maxTouchPoints > 0 ||\n (navigator as unknown as { msMaxTouchPoints: number }).msMaxTouchPoints >\n 0\n );\n }\n})();\n","/** Creates a deep clone of an element. */\nexport function deepCloneNode(node: HTMLElement): HTMLElement {\n const clone = node.cloneNode(true) as HTMLElement;\n const descendantsWithId = clone.querySelectorAll('[id]');\n const nodeName = node.nodeName.toLowerCase();\n\n // Remove the `id` to avoid having multiple elements with the same id on the page.\n clone.removeAttribute('id');\n\n descendantsWithId.forEach((descendant) => {\n descendant.removeAttribute('id');\n });\n\n if (nodeName === 'canvas') {\n transferCanvasData(node as HTMLCanvasElement, clone as HTMLCanvasElement);\n } else if (\n nodeName === 'input' ||\n nodeName === 'select' ||\n nodeName === 'textarea'\n ) {\n transferInputData(node as HTMLInputElement, clone as HTMLInputElement);\n }\n\n transferData('canvas', node, clone, transferCanvasData);\n transferData('input, textarea, select', node, clone, transferInputData);\n return clone;\n}\n\n/** Matches elements between an element and its clone and allows for their data to be cloned. */\nfunction transferData<T extends Element>(\n selector: string,\n node: HTMLElement,\n clone: HTMLElement,\n callback: (source: T, clone: T) => void,\n) {\n const descendantElements = node.querySelectorAll<T>(selector);\n\n if (descendantElements.length) {\n const cloneElements = clone.querySelectorAll<T>(selector);\n\n for (let i = 0; i < descendantElements.length; i++) {\n callback(descendantElements[i], cloneElements[i]);\n }\n }\n}\n\n// Counter for unique cloned radio button names.\nlet cloneUniqueId = 0;\n\n/** Transfers the data of one input element to another. */\nfunction transferInputData(\n source: Element & { value: string },\n clone: Element & { value: string; name: string; type: string },\n) {\n // Browsers throw an error when assigning the value of a file input programmatically.\n if (clone.type !== 'file') {\n clone.value = source.value;\n }\n\n // Radio button `name` attributes must be unique for radio button groups\n // otherwise original radio buttons can lose their checked state\n // once the clone is inserted in the DOM.\n if (clone.type === 'radio' && clone.name) {\n clone.name = `mat-clone-${clone.name}-${cloneUniqueId++}`;\n }\n}\n\n/** Transfers the data of one canvas element to another. */\nfunction transferCanvasData(\n source: HTMLCanvasElement,\n clone: HTMLCanvasElement,\n) {\n const context = clone.getContext('2d');\n\n if (context) {\n // In some cases `drawImage` can throw (e.g. if the canvas size is 0x0).\n // We can't do much about it so just ignore the error.\n try {\n context.drawImage(source, 0, 0);\n } catch {}\n }\n}\n","import {\n Directive,\n Renderer2,\n ElementRef,\n OnInit,\n Output,\n Input,\n EventEmitter,\n OnDestroy,\n NgZone,\n PLATFORM_ID,\n inject,\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { Subject, Observable, Observer, merge } from 'rxjs';\nimport {\n map,\n mergeMap,\n takeUntil,\n filter,\n pairwise,\n take,\n share,\n tap,\n} from 'rxjs/operators';\nimport { Edges } from './interfaces/edges.interface';\nimport { BoundingRectangle } from './interfaces/bounding-rectangle.interface';\nimport { ResizeEvent } from './interfaces/resize-event.interface';\nimport { IS_TOUCH_DEVICE } from './util/is-touch-device';\nimport { deepCloneNode } from './util/clone-node';\n\ninterface PointerEventCoordinate {\n clientX: number;\n clientY: number;\n event: MouseEvent | TouchEvent;\n}\n\ninterface Coordinate {\n x: number;\n y: number;\n}\n\nfunction getNewBoundingRectangle(\n startingRect: BoundingRectangle,\n edges: Edges,\n clientX: number,\n clientY: number,\n): BoundingRectangle {\n const newBoundingRect: BoundingRectangle = {\n top: startingRect.top,\n bottom: startingRect.bottom,\n left: startingRect.left,\n right: startingRect.right,\n };\n\n if (edges.top) {\n newBoundingRect.top += clientY;\n }\n if (edges.bottom) {\n newBoundingRect.bottom += clientY;\n }\n if (edges.left) {\n newBoundingRect.left += clientX;\n }\n if (edges.right) {\n newBoundingRect.right += clientX;\n }\n newBoundingRect.height = newBoundingRect.bottom - newBoundingRect.top;\n newBoundingRect.width = newBoundingRect.right - newBoundingRect.left;\n\n return newBoundingRect;\n}\n\nfunction getElementRect(\n element: ElementRef,\n ghostElementPositioning: string,\n): BoundingRectangle {\n let translateX = 0;\n let translateY = 0;\n const style = element.nativeElement.style;\n const transformProperties = [\n 'transform',\n '-ms-transform',\n '-moz-transform',\n '-o-transform',\n ];\n const transform = transformProperties\n .map((property) => style[property])\n .find((value) => !!value);\n if (transform && transform.includes('translate')) {\n translateX = transform.replace(\n /.*translate3?d?\\((-?[0-9]*)px, (-?[0-9]*)px.*/,\n '$1',\n );\n translateY = transform.replace(\n /.*translate3?d?\\((-?[0-9]*)px, (-?[0-9]*)px.*/,\n '$2',\n );\n }\n\n if (ghostElementPositioning === 'absolute') {\n return {\n height: element.nativeElement.offsetHeight,\n width: element.nativeElement.offsetWidth,\n top: element.nativeElement.offsetTop - translateY,\n bottom:\n element.nativeElement.offsetHeight +\n element.nativeElement.offsetTop -\n translateY,\n left: element.nativeElement.offsetLeft - translateX,\n right:\n element.nativeElement.offsetWidth +\n element.nativeElement.offsetLeft -\n translateX,\n };\n } else {\n const boundingRect: BoundingRectangle =\n element.nativeElement.getBoundingClientRect();\n return {\n height: boundingRect.height,\n width: boundingRect.width,\n top: boundingRect.top - translateY,\n bottom: boundingRect.bottom - translateY,\n left: boundingRect.left - translateX,\n right: boundingRect.right - translateX,\n scrollTop: element.nativeElement.scrollTop,\n scrollLeft: element.nativeElement.scrollLeft,\n };\n }\n}\n\nexport interface ResizeCursors {\n topLeft: string;\n topRight: string;\n bottomLeft: string;\n bottomRight: string;\n leftOrRight: string;\n topOrBottom: string;\n}\n\nconst DEFAULT_RESIZE_CURSORS: ResizeCursors = Object.freeze({\n topLeft: 'nw-resize',\n topRight: 'ne-resize',\n bottomLeft: 'sw-resize',\n bottomRight: 'se-resize',\n leftOrRight: 'col-resize',\n topOrBottom: 'row-resize',\n});\n\nfunction getResizeCursor(edges: Edges, cursors: ResizeCursors): string {\n if (edges.left && edges.top) {\n return cursors.topLeft;\n } else if (edges.right && edges.top) {\n return cursors.topRight;\n } else if (edges.left && edges.bottom) {\n return cursors.bottomLeft;\n } else if (edges.right && edges.bottom) {\n return cursors.bottomRight;\n } else if (edges.left || edges.right) {\n return cursors.leftOrRight;\n } else if (edges.top || edges.bottom) {\n return cursors.topOrBottom;\n } else {\n return '';\n }\n}\n\nfunction getEdgesDiff({\n edges,\n initialRectangle,\n newRectangle,\n}: {\n edges: Edges;\n initialRectangle: BoundingRectangle;\n newRectangle: BoundingRectangle;\n}): Edges {\n const edgesDiff: Edges = {};\n Object.keys(edges).forEach((edge) => {\n edgesDiff[edge] = (newRectangle[edge] || 0) - (initialRectangle[edge] || 0);\n });\n return edgesDiff;\n}\n\nconst RESIZE_ACTIVE_CLASS: string = 'resize-active';\nconst RESIZE_GHOST_ELEMENT_CLASS: string = 'resize-ghost-element';\n\nexport const MOUSE_MOVE_THROTTLE_MS: number = 50;\n\n/**\n * Place this on an element to make it resizable. For example:\n *\n * ```html\n * <div\n * mwlResizable\n * [resizeEdges]=\"{bottom: true, right: true, top: true, left: true}\"\n * [enableGhostResize]=\"true\">\n * </div>\n * ```\n * Or in case they are sibling elements:\n * ```html\n * <div mwlResizable #resizableElement=\"mwlResizable\"></div>\n * <div mwlResizeHandle [resizableContainer]=\"resizableElement\" [resizeEdges]=\"{bottom: true, right: true}\"></div>\n * ```\n */\n@Directive({\n selector: '[mwlResizable]',\n exportAs: 'mwlResizable',\n})\nexport class ResizableDirective implements OnInit, OnDestroy {\n /**\n * A function that will be called before each resize event. Return `true` to allow the resize event to propagate or `false` to cancel it\n */\n @Input() validateResize: (resizeEvent: ResizeEvent) => boolean;\n\n /**\n * Set to `true` to enable a temporary resizing effect of the element in between the `resizeStart` and `resizeEnd` events.\n */\n @Input() enableGhostResize: boolean = false;\n\n /**\n * A snap grid that resize events will be locked to.\n *\n * e.g. to only allow the element to be resized every 10px set it to `{left: 10, right: 10}`\n */\n @Input() resizeSnapGrid: Edges = {};\n\n /**\n * The mouse cursors that will be set on the resize edges\n */\n @Input() resizeCursors: Partial<ResizeCursors> = DEFAULT_RESIZE_CURSORS;\n\n /**\n * Define the positioning of the ghost element (can be fixed or absolute)\n */\n @Input() ghostElementPositioning: 'fixed' | 'absolute' = 'fixed';\n\n /**\n * Allow elements to be resized to negative dimensions\n */\n @Input() allowNegativeResizes: boolean = false;\n\n /**\n * The mouse move throttle in milliseconds, default: 50 ms\n */\n @Input() mouseMoveThrottleMS: number = MOUSE_MOVE_THROTTLE_MS;\n\n /**\n * Called when the mouse is pressed and a resize event is about to begin. `$event` is a `ResizeEvent` object.\n */\n @Output() resizeStart = new EventEmitter<ResizeEvent>();\n\n /**\n * Called as the mouse is dragged after a resize event has begun. `$event` is a `ResizeEvent` object.\n */\n @Output() resizing = new EventEmitter<ResizeEvent>();\n\n /**\n * Called after the mouse is released after a resize event. `$event` is a `ResizeEvent` object.\n */\n @Output() resizeEnd = new EventEmitter<ResizeEvent>();\n\n /**\n * @hidden\n */\n public mouseup = new Subject<{\n clientX: number;\n clientY: number;\n edges?: Edges;\n }>();\n\n /**\n * @hidden\n */\n public mousedown = new Subject<{\n clientX: number;\n clientY: number;\n edges?: Edges;\n }>();\n\n /**\n * @hidden\n */\n public mousemove = new Subject<{\n clientX: number;\n clientY: number;\n edges?: Edges;\n event: MouseEvent | TouchEvent;\n }>();\n\n private pointerEventListeners: PointerEventListeners;\n\n private destroy$ = new Subject<void>();\n\n private platformId = inject(PLATFORM_ID);\n\n private renderer = inject(Renderer2);\n\n private elm = inject(ElementRef);\n\n private zone = inject(NgZone);\n\n /**\n * @hidden\n */\n constructor() {\n this.pointerEventListeners = PointerEventListeners.getInstance(\n this.renderer,\n this.zone,\n );\n }\n\n /**\n * @hidden\n */\n ngOnInit(): void {\n const mousedown$: Observable<{\n clientX: number;\n clientY: number;\n edges?: Edges;\n }> = merge(this.pointerEventListeners.pointerDown, this.mousedown);\n\n const mousemove$ = merge(\n this.pointerEventListeners.pointerMove,\n this.mousemove,\n ).pipe(\n tap(({ event }) => {\n if (currentResize && event.cancelable) {\n event.preventDefault();\n }\n }),\n share(),\n );\n\n const mouseup$ = merge(this.pointerEventListeners.pointerUp, this.mouseup);\n\n let currentResize: {\n edges: Edges;\n startingRect: BoundingRectangle;\n currentRect: BoundingRectangle;\n clonedNode?: HTMLElement;\n } | null;\n\n const removeGhostElement = () => {\n if (currentResize && currentResize.clonedNode) {\n this.elm.nativeElement.parentElement.removeChild(\n currentResize.clonedNode,\n );\n this.renderer.setStyle(this.elm.nativeElement, 'visibility', 'inherit');\n }\n };\n\n const getResizeCursors = (): ResizeCursors => {\n return {\n ...DEFAULT_RESIZE_CURSORS,\n ...this.resizeCursors,\n };\n };\n\n const mousedrag: Observable<any> = mousedown$\n .pipe(\n mergeMap((startCoords) => {\n function getDiff(moveCoords: { clientX: number; clientY: number }) {\n return {\n clientX: moveCoords.clientX - startCoords.clientX,\n clientY: moveCoords.clientY - startCoords.clientY,\n };\n }\n\n const getSnapGrid = () => {\n const snapGrid: Coordinate = { x: 1, y: 1 };\n\n if (currentResize) {\n if (this.resizeSnapGrid.left && currentResize.edges.left) {\n snapGrid.x = +this.resizeSnapGrid.left;\n } else if (\n this.resizeSnapGrid.right &&\n currentResize.edges.right\n ) {\n snapGrid.x = +this.resizeSnapGrid.right;\n }\n\n if (this.resizeSnapGrid.top && currentResize.edges.top) {\n snapGrid.y = +this.resizeSnapGrid.top;\n } else if (\n this.resizeSnapGrid.bottom &&\n currentResize.edges.bottom\n ) {\n snapGrid.y = +this.resizeSnapGrid.bottom;\n }\n }\n\n return snapGrid;\n };\n\n function getGrid(\n coords: { clientX: number; clientY: number },\n snapGrid: Coordinate,\n ) {\n return {\n x: Math.ceil(coords.clientX / snapGrid.x),\n y: Math.ceil(coords.clientY / snapGrid.y),\n };\n }\n\n return (\n merge(\n mousemove$.pipe(take(1)).pipe(map((coords) => [, coords])),\n mousemove$.pipe(pairwise()),\n ) as Observable<\n [\n { clientX: number; clientY: number },\n { clientX: number; clientY: number },\n ]\n >\n )\n .pipe(\n map(([previousCoords, newCoords]) => {\n return [\n previousCoords ? getDiff(previousCoords) : previousCoords,\n getDiff(newCoords),\n ];\n }),\n )\n .pipe(\n filter(([previousCoords, newCoords]) => {\n if (!previousCoords) {\n return true;\n }\n\n const snapGrid: Coordinate = getSnapGrid();\n const previousGrid: Coordinate = getGrid(\n previousCoords,\n snapGrid,\n );\n const newGrid: Coordinate = getGrid(newCoords, snapGrid);\n\n return (\n previousGrid.x !== newGrid.x || previousGrid.y !== newGrid.y\n );\n }),\n )\n .pipe(\n map(([, newCoords]) => {\n const snapGrid: Coordinate = getSnapGrid();\n return {\n clientX:\n Math.round(newCoords.clientX / snapGrid.x) * snapGrid.x,\n clientY:\n Math.round(newCoords.clientY / snapGrid.y) * snapGrid.y,\n };\n }),\n )\n .pipe(takeUntil(merge(mouseup$, mousedown$)));\n }),\n )\n .pipe(filter(() => !!currentResize));\n\n mousedrag\n .pipe(\n map(({ clientX, clientY }) => {\n return getNewBoundingRectangle(\n currentResize!.startingRect,\n currentResize!.edges,\n clientX,\n clientY,\n );\n }),\n )\n .pipe(\n filter((newBoundingRect: BoundingRectangle) => {\n return (\n this.allowNegativeResizes ||\n !!(\n newBoundingRect.height &&\n newBoundingRect.width &&\n newBoundingRect.height > 0 &&\n newBoundingRect.width > 0\n )\n );\n }),\n )\n .pipe(\n filter((newBoundingRect: BoundingRectangle) => {\n return this.validateResize\n ? this.validateResize({\n rectangle: newBoundingRect,\n edges: getEdgesDiff({\n edges: currentResize!.edges,\n initialRectangle: currentResize!.startingRect,\n newRectangle: newBoundingRect,\n }),\n })\n : true;\n }),\n takeUntil(this.destroy$),\n )\n .subscribe((newBoundingRect: BoundingRectangle) => {\n if (currentResize && currentResize.clonedNode) {\n this.renderer.setStyle(\n currentResize.clonedNode,\n 'height',\n `${newBoundingRect.height}px`,\n );\n this.renderer.setStyle(\n currentResize.clonedNode,\n 'width',\n `${newBoundingRect.width}px`,\n );\n this.renderer.setStyle(\n currentResize.clonedNode,\n 'top',\n `${newBoundingRect.top}px`,\n );\n this.renderer.setStyle(\n currentResize.clonedNode,\n 'left',\n `${newBoundingRect.left}px`,\n );\n }\n\n if (this.resizing.observers.length > 0) {\n this.zone.run(() => {\n this.resizing.emit({\n edges: getEdgesDiff({\n edges: currentResize!.edges,\n initialRectangle: currentResize!.startingRect,\n newRectangle: newBoundingRect,\n }),\n rectangle: newBoundingRect,\n });\n });\n }\n currentResize!.currentRect = newBoundingRect;\n });\n\n mousedown$\n .pipe(\n map(({ edges }) => {\n return edges || {};\n }),\n filter((edges: Edges) => {\n return Object.keys(edges).length > 0;\n }),\n takeUntil(this.destroy$),\n )\n .subscribe((edges: Edges) => {\n if (currentResize) {\n removeGhostElement();\n }\n const startingRect: BoundingRectangle = getElementRect(\n this.elm,\n this.ghostElementPositioning,\n );\n currentResize = {\n edges,\n startingRect,\n currentRect: startingRect,\n };\n const resizeCursors = getResizeCursors();\n const cursor = getResizeCursor(currentResize.edges, resizeCursors);\n this.renderer.setStyle(document.body, 'cursor', cursor);\n this.setElementClass(this.elm, RESIZE_ACTIVE_CLASS, true);\n if (this.enableGhostResize) {\n currentResize.clonedNode = deepCloneNode(this.elm.nativeElement);\n this.elm.nativeElement.parentElement.appendChild(\n currentResize.clonedNode,\n );\n this.renderer.setStyle(\n this.elm.nativeElement,\n 'visibility',\n 'hidden',\n );\n this.renderer.setStyle(\n currentResize.clonedNode,\n 'position',\n this.ghostElementPositioning,\n );\n this.renderer.setStyle(\n currentResize.clonedNode,\n 'left',\n `${currentResize.startingRect.left}px`,\n );\n this.renderer.setStyle(\n currentResize.clonedNode,\n 'top',\n `${currentResize.startingRect.top}px`,\n );\n this.renderer.setStyle(\n currentResize.clonedNode,\n 'height',\n `${currentResize.startingRect.height}px`,\n );\n this.renderer.setStyle(\n currentResize.clonedNode,\n 'width',\n `${currentResize.startingRect.width}px`,\n );\n this.renderer.setStyle(\n currentResize.clonedNode,\n 'cursor',\n getResizeCursor(currentResize.edges, resizeCursors),\n );\n this.renderer.addClass(\n currentResize.clonedNode,\n RESIZE_GHOST_ELEMENT_CLASS,\n );\n currentResize.clonedNode!.scrollTop = currentResize.startingRect\n .scrollTop as number;\n currentResize.clonedNode!.scrollLeft = currentResize.startingRect\n .scrollLeft as number;\n }\n if (this.resizeStart.observers.length > 0) {\n this.zone.run(() => {\n this.resizeStart.emit({\n edges: getEdgesDiff({\n edges,\n initialRectangle: startingRect,\n newRectangle: startingRect,\n }),\n rectangle: getNewBoundingRectangle(startingRect, {}, 0, 0),\n });\n });\n }\n });\n\n mouseup$.pipe(takeUntil(this.destroy$)).subscribe(() => {\n if (currentResize) {\n this.renderer.removeClass(this.elm.nativeElement, RESIZE_ACTIVE_CLASS);\n this.renderer.setStyle(document.body, 'cursor', '');\n this.renderer.setStyle(this.elm.nativeElement, 'cursor', '');\n if (this.resizeEnd.observers.length > 0) {\n this.zone.run(() => {\n this.resizeEnd.emit({\n edges: getEdgesDiff({\n edges: currentResize!.edges,\n initialRectangle: currentResize!.startingRect,\n newRectangle: currentResize!.currentRect,\n }),\n rectangle: currentResize!.currentRect,\n });\n });\n }\n removeGhostElement();\n currentResize = null;\n }\n });\n }\n\n /**\n * @hidden\n */\n ngOnDestroy(): void {\n // browser check for angular universal, because it doesn't know what document is\n if (isPlatformBrowser(this.platformId)) {\n this.renderer.setStyle(document.body, 'cursor', '');\n }\n this.mousedown.complete();\n this.mouseup.complete();\n this.mousemove.complete();\n this.destroy$.next();\n }\n\n private setElementClass(elm: ElementRef, name: string, add: boolean): void {\n if (add) {\n this.renderer.addClass(elm.nativeElement, name);\n } else {\n this.renderer.removeClass(elm.nativeElement, name);\n }\n }\n}\n\nclass PointerEventListeners {\n public pointerDown: Observable<PointerEventCoordinate>;\n\n public pointerMove: Observable<PointerEventCoordinate>;\n\n public pointerUp: Observable<PointerEventCoordinate>;\n\n private static instance: PointerEventListeners;\n\n public static getInstance(\n renderer: Renderer2,\n zone: NgZone,\n ): PointerEventListeners {\n if (!PointerEventListeners.instance) {\n PointerEventListeners.instance = new PointerEventListeners(\n renderer,\n zone,\n );\n }\n return PointerEventListeners.instance;\n }\n\n constructor(renderer: Renderer2, zone: NgZone) {\n this.pointerDown = new Observable(\n (observer: Observer<PointerEventCoordinate>) => {\n let unsubscribeMouseDown: () => void;\n let unsubscribeTouchStart: (() => void) | undefined;\n\n zone.runOutsideAngular(() => {\n unsubscribeMouseDown = renderer.listen(\n 'document',\n 'mousedown',\n (event: MouseEvent) => {\n observer.next({\n clientX: event.clientX,\n clientY: event.clientY,\n event,\n });\n },\n );\n\n if (IS_TOUCH_DEVICE) {\n unsubscribeTouchStart = renderer.listen(\n 'document',\n 'touchstart',\n (event: TouchEvent) => {\n observer.next({\n clientX: event.touches[0].clientX,\n clientY: event.touches[0].clientY,\n event,\n });\n },\n );\n }\n });\n\n return () => {\n unsubscribeMouseDown();\n if (IS_TOUCH_DEVICE) {\n unsubscribeTouchStart!();\n }\n };\n },\n ).pipe(share());\n\n this.pointerMove = new Observable(\n (observer: Observer<PointerEventCoordinate>) => {\n let unsubscribeMouseMove: () => void;\n let unsubscribeTouchMove: (() => void) | undefined;\n\n zone.runOutsideAngular(() => {\n unsubscribeMouseMove = renderer.listen(\n 'document',\n 'mousemove',\n (event: MouseEvent) => {\n observer.next({\n clientX: event.clientX,\n clientY: event.clientY,\n event,\n });\n },\n );\n\n if (IS_TOUCH_DEVICE) {\n unsubscribeTouchMove = renderer.listen(\n 'document',\n 'touchmove',\n (event: TouchEvent) => {\n observer.next({\n clientX: event.targetTouches[0].clientX,\n clientY: event.targetTouches[0].clientY,\n event,\n });\n },\n );\n }\n });\n\n return () => {\n unsubscribeMouseMove();\n if (IS_TOUCH_DEVICE) {\n unsubscribeTouchMove!();\n }\n };\n },\n ).pipe(share());\n\n this.pointerUp = new Observable(\n (observer: Observer<PointerEventCoordinate>) => {\n let unsubscribeMouseUp: () => void;\n let unsubscribeTouchEnd: (() => void) | undefined;\n let unsubscribeTouchCancel: (() => void) | undefined;\n\n zone.runOutsideAngular(() => {\n unsubscribeMouseUp = renderer.listen(\n 'document',\n 'mouseup',\n (event: MouseEvent) => {\n observer.next({\n clientX: event.clientX,\n clientY: event.clientY,\n event,\n });\n },\n );\n\n if (IS_TOUCH_DEVICE) {\n unsubscribeTouchEnd = renderer.listen(\n 'document',\n 'touchend',\n (event: TouchEvent) => {\n observer.next({\n clientX: event.changedTouches[0].clientX,\n clientY: event.changedTouches[0].clientY,\n event,\n });\n },\n );\n\n unsubscribeTouchCancel = renderer.listen(\n 'document',\n 'touchcancel',\n (event: TouchEvent) => {\n observer.next({\n clientX: event.changedTouches[0].clientX,\n clientY: event.changedTouches[0].clientY,\n event,\n });\n },\n );\n }\n });\n\n return () => {\n unsubscribeMouseUp();\n if (IS_TOUCH_DEVICE) {\n unsubscribeTouchEnd!();\n unsubscribeTouchCancel!();\n }\n };\n },\n ).pipe(share());\n }\n}\n","import {\n Directive,\n Input,\n Renderer2,\n ElementRef,\n OnInit,\n OnDestroy,\n NgZone,\n inject,\n} from '@angular/core';\nimport { fromEvent, merge, Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { ResizableDirective } from './resizable.directive';\nimport { Edges } from './interfaces/edges.interface';\nimport { IS_TOUCH_DEVICE } from './util/is-touch-device';\n\n/**\n * An element placed inside a `mwlResizable` directive to be used as a drag and resize handle\n *\n * For example\n *\n * ```html\n * <div mwlResizable>\n * <div mwlResizeHandle [resizeEdges]=\"{bottom: true, right: true}\"></div>\n * </div>\n * ```\n * Or in case they are sibling elements:\n * ```html\n * <div mwlResizable #resizableElement=\"mwlResizable\"></div>\n * <div mwlResizeHandle [resizableContainer]=\"resizableElement\" [resizeEdges]=\"{bottom: true, right: true}\"></div>\n * ```\n */\n@Directive({ selector: '[mwlResizeHandle]' })\nexport class ResizeHandleDirective implements OnInit, OnDestroy {\n private renderer = inject(Renderer2);\n private element = inject(ElementRef);\n private zone = inject(NgZone);\n private resizableDirective = inject(ResizableDirective, { optional: true });\n\n /**\n * The `Edges` object that contains the edges of the parent element that dragging the handle will trigger a resize on\n */\n @Input() resizeEdges: Edges = {};\n /**\n * Reference to ResizableDirective in case if handle is not located inside of element with ResizableDirective\n */\n @Input() resizableContainer: ResizableDirective;\n\n private eventListeners: {\n touchmove?: () => void;\n mousemove?: () => void;\n [key: string]: (() => void) | undefined;\n } = {};\n\n private destroy$ = new Subject<void>();\n\n ngOnInit(): void {\n this.zone.runOutsideAngular(() => {\n this.listenOnTheHost<MouseEvent>('mousedown').subscribe((event) => {\n this.onMousedown(event, event.clientX, event.clientY);\n });\n\n this.listenOnTheHost<MouseEvent>('mouseup').subscribe((event) => {\n this.onMouseup(event.clientX, event.clientY);\n });\n\n if (IS_TOUCH_DEVICE) {\n this.listenOnTheHost<TouchEvent>('touchstart').subscribe((event) => {\n this.onMousedown(\n event,\n event.touches[0].clientX,\n event.touches[0].clientY,\n );\n });\n\n merge(\n this.listenOnTheHost<TouchEvent>('touchend'),\n this.listenOnTheHost<TouchEvent>('touchcancel'),\n ).subscribe((event) => {\n this.onMouseup(\n event.changedTouches[0].clientX,\n event.changedTouches[0].clientY,\n );\n });\n }\n });\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.unsubscribeEventListeners();\n }\n\n /**\n * @hidden\n */\n onMousedown(\n event: MouseEvent | TouchEvent,\n clientX: number,\n clientY: number,\n ): void {\n if (event.cancelable) {\n event.preventDefault();\n }\n if (!this.eventListeners.touchmove) {\n this.eventListeners.touchmove = this.renderer.listen(\n this.element.nativeElement,\n 'touchmove',\n (touchMoveEvent: TouchEvent) => {\n this.onMousemove(\n touchMoveEvent,\n touchMoveEvent.targetTouches[0].clientX,\n touchMoveEvent.targetTouches[0].clientY,\n );\n },\n );\n }\n if (!this.eventListeners.mousemove) {\n this.eventListeners.mousemove = this.renderer.listen(\n this.element.nativeElement,\n 'mousemove',\n (mouseMoveEvent: MouseEvent) => {\n this.onMousemove(\n mouseMoveEvent,\n mouseMoveEvent.clientX,\n mouseMoveEvent.clientY,\n );\n },\n );\n }\n this.resizable.mousedown.next({\n clientX,\n clientY,\n edges: this.resizeEdges,\n });\n }\n\n /**\n * @hidden\n */\n onMouseup(clientX: number, clientY: number): void {\n this.unsubscribeEventListeners();\n this.resizable.mouseup.next({\n clientX,\n clientY,\n edges: this.resizeEdges,\n });\n }\n\n // directive might be passed from DI or as an input\n private get resizable(): ResizableDirective {\n return this.resizableDirective || this.resizableContainer;\n }\n\n private onMousemove(\n event: MouseEvent | TouchEvent,\n clientX: number,\n clientY: number,\n ): void {\n this.resizable.mousemove.next({\n clientX,\n clientY,\n edges: this.resizeEdges,\n event,\n });\n }\n\n private unsubscribeEventListeners(): void {\n Object.keys(this.eventListeners).forEach((type) => {\n (this as any).eventListeners[type]();\n delete this.eventListeners[type];\n });\n }\n\n private listenOnTheHost<T extends Event>(eventName: string) {\n return fromEvent<T>(this.element.nativeElement, eventName).pipe(\n takeUntil(this.destroy$),\n );\n }\n}\n","import { NgModule } from '@angular/core';\nimport { ResizableDirective } from './resizable.directive';\nimport { ResizeHandleDirective } from './resize-handle.directive';\n\n/**\n * @deprecated import standalone `ResizableDirective` / `ResizeHandleDirective` directives instead\n */\n@NgModule({\n imports: [ResizableDirective, ResizeHandleDirective],\n exports: [ResizableDirective, ResizeHandleDirective],\n})\nexport class ResizableModule {}\n","/*\n * Public API Surface of angular-resizable-element\n */\n\nexport * from './lib/resizable.module';\nexport { BoundingRectangle } from './lib/interfaces/bounding-rectangle.interface';\nexport { Edges } from './lib/interfaces/edges.interface';\nexport { ResizeEvent } from './lib/interfaces/resize-event.interface';\nexport { ResizableDirective, ResizeCursors } from './lib/resizable.directive';\nexport { ResizeHandleDirective } from './lib/resize-handle.directive';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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