import type { Directive, DirectiveBinding } from 'vue';
export interface CoordinateInfo {
pageX: number;
pageY: number;
clientX: number;
clientY: number;
offsetX: number;
offsetY: number;
type: string;
originalEvent: MouseEvent;
}
export type OnResizeEvent = (coordinateInfo: CoordinateInfo) => void;
export interface ResizeDirectiveProp {
enableResize: true;
onPressEvent: OnResizeEvent;
onDragEvent: OnResizeEvent;
onReleaseEvent: OnResizeEvent;
}
export interface CustomElement extends HTMLElement {
resizeProps: {
enableResize: boolean;
onPressEvent: (arg: CoordinateInfo) => void;
onDragEvent: (arg: CoordinateInfo) => void;
onReleaseEvent: (arg: CoordinateInfo) => void;
};
}
function normalizeEvent(evt: MouseEvent) {
return {
pageX: evt.pageX,
pageY: evt.pageY,
clientX: evt.clientX,
clientY: evt.clientY,
offsetX: evt.offsetX,
offsetY: evt.offsetY,
type: evt.type,
originalEvent: evt,
};
}
function bind(
el: HTMLElement | Document,
eventName: string,
callback: EventListenerOrEventListenerObject) {
el.addEventListener && el.addEventListener(eventName, callback);
}
function unbind(
el: HTMLElement | Document,
eventName: string,
callback: EventListenerOrEventListenerObject) {
el.removeEventListener && el.removeEventListener(eventName, callback);
}
function onMousedown(e: Event) {
const resizeProps = (e?.target as CustomElement)?.resizeProps;
if (!resizeProps) {
return;
}
function onMousemove(evt: Event): void {
resizeProps.onDragEvent(normalizeEvent(evt as MouseEvent));
}
function onMouseup(evt: Event) {
unbind(document, 'mousemove', onMousemove);
unbind(document, 'mouseup', onMouseup);
resizeProps.onReleaseEvent(normalizeEvent(evt as MouseEvent));
}
bind(document, 'mousemove', onMousemove);
bind(document, 'mouseup', onMouseup);
resizeProps.onPressEvent(normalizeEvent(e as MouseEvent));
}
function bindEvent(el: HTMLElement) {
bind(el, 'mousedown', onMousedown);
}
const resize: Directive = {
mounted(el: CustomElement, { value }: DirectiveBinding<ResizeDirectiveProp>) {
el.resizeProps= value;
if (value.enableResize) {
bindEvent(el);
}
},
unmounted(el: HTMLElement, { value }: DirectiveBinding<ResizeDirectiveProp>) {
if (value.enableResize) {
unbind(el, 'mousedown', onMousedown);
}
},
};
export default resize;