naive-ui
Version:
A Vue 3 Component Library. Fairly Complete, Theme Customizable, Uses TypeScript, Fast
121 lines • 3.43 kB
JavaScript
import { off, on } from 'evtd';
import { computed, inject, onUnmounted } from 'vue';
import { throwError } from "../../_utils/index.mjs";
import { modalApiInjectionKey, modalReactiveListInjectionKey } from "./context.mjs";
export function useModal() {
const modal = inject(modalApiInjectionKey, null);
if (modal === null) {
throwError('use-modal', 'No outer <n-modal-provider /> founded.');
}
return modal;
}
export function useModalReactiveList() {
const modalReactiveList = inject(modalReactiveListInjectionKey, null);
if (modalReactiveList === null) {
throwError('use-modal-reactive-list', 'No outer <n-modal-provider /> founded.');
}
return modalReactiveList;
}
export const DRAGGABLE_CLASS = 'n-draggable';
export function useDragModal(draggablePropsRef, options) {
let cleanup;
const draggableRef = computed(() => {
return draggablePropsRef.value !== false;
});
const draggableClassRef = computed(() => {
return draggableRef.value ? DRAGGABLE_CLASS : '';
});
const boundsToWindowRef = computed(() => {
const draggableProps = draggablePropsRef.value;
if (draggableProps === true || draggableProps === false) {
return true;
} else if (draggableProps) {
return draggableProps.bounds !== 'none';
} else {
return true;
}
});
function startDrag(modal) {
const header = modal.querySelector(`.${DRAGGABLE_CLASS}`);
if (!header || !draggableClassRef.value) {
return;
}
let maxMoveX = 0;
let minMoveX = 0;
let maxMoveY = 0;
let minMoveY = 0;
let prevMoveY = 0;
let prevMoveX = 0;
let mousedownEvent;
function handleMouseDown(event) {
event.preventDefault();
mousedownEvent = event;
const {
x,
y,
right,
bottom
} = modal.getBoundingClientRect();
minMoveX = x;
minMoveY = y;
maxMoveX = window.innerWidth - right;
maxMoveY = window.innerHeight - bottom;
const {
left,
top
} = modal.style;
prevMoveY = +top.slice(0, -2);
prevMoveX = +left.slice(0, -2);
}
function handleMouseMove(event) {
if (!mousedownEvent) return;
const {
clientX: downX,
clientY: downY
} = mousedownEvent;
let moveX = event.clientX - downX;
let moveY = event.clientY - downY;
if (boundsToWindowRef.value) {
if (moveX > maxMoveX) {
moveX = maxMoveX;
} else if (-moveX > minMoveX) {
moveX = -minMoveX;
}
if (moveY > maxMoveY) {
moveY = maxMoveY;
} else if (-moveY > minMoveY) {
moveY = -minMoveY;
}
}
const x = moveX + prevMoveX;
const y = moveY + prevMoveY;
modal.style.top = `${y}px`;
modal.style.left = `${x}px`;
}
function handleMouseUp() {
mousedownEvent = undefined;
options.onEnd(modal);
}
on('mousedown', header, handleMouseDown);
on('mousemove', window, handleMouseMove);
on('mouseup', window, handleMouseUp);
cleanup = () => {
off('mousedown', header, handleMouseDown);
on('mousemove', window, handleMouseMove);
on('mouseup', window, handleMouseUp);
};
}
function stopDrag() {
if (cleanup) {
cleanup();
cleanup = undefined;
}
}
onUnmounted(stopDrag);
return {
stopDrag,
startDrag,
draggableRef,
draggableClassRef
};
}