import { defineComponent, onBeforeUnmount, ref, type PropType, watch, } from 'vue' import './interactive-window.scss' interface SlotOptions { onMouseDown: (e: MouseEvent) => void } export default defineComponent({ props: { initialHeight: { type: Number, default: 600, }, initialLeft: { type: Number, default: 0, }, initialTop: { type: Number, default: 0, }, initialWidth: { type: Number, default: 600, }, slot: { type: Function as PropType<(options: SlotOptions) => JSX.Element>, required: true, }, }, setup(props) { const left = ref(props.initialLeft) const top = ref(props.initialTop) const height = ref(props.initialHeight) const width = ref(props.initialWidth) const isSelected = ref(false) const selectWindow = () => { window.dispatchEvent(new Event('arkUiResizeableWindowSelect')) isSelected.value = true } let dragPrevX = 0 let dragPrevY = 0 let isResizing = false let resizeElement: 'top'|'bottom'|'left'|'right'|null = null const startResize = (e: MouseEvent, element: 'top'|'bottom'|'left'|'right') => { dragPrevX = e.clientX dragPrevY = e.clientY isResizing = true resizeElement = element } const doResize = (e: MouseEvent) => { if (!isResizing) return const diffX = e.clientX - dragPrevX const diffY = e.clientY - dragPrevY if (resizeElement === 'top') { if (height.value + diffY < 100) return top.value += diffY height.value -= diffY } if (resizeElement === 'left') { if (width.value + diffX < 100) return left.value += diffX width.value -= diffX } if (resizeElement === 'bottom') { if (height.value + diffY < 100) return height.value += diffY } if (resizeElement === 'right') { if (width.value + diffX < 100) return width.value += diffX } dragPrevX = e.clientX dragPrevY = e.clientY } let isMoving = false const startMove = (e: MouseEvent) => { selectWindow() dragPrevX = e.clientX dragPrevY = e.clientY isMoving = true } const doMove = (e: MouseEvent) => { if (!isMoving) return const diffX = e.clientX - dragPrevX const diffY = e.clientY - dragPrevY left.value += diffX top.value += diffY dragPrevX = e.clientX dragPrevY = e.clientY } const mouseMove = (e: MouseEvent) => { if (isResizing) doResize(e) if (isMoving) doMove(e) } const endMouseMove = () => { isResizing = false isMoving = false } const onSelectListener = () => { isSelected.value = false } window.addEventListener('arkUiResizeableWindowSelect', onSelectListener) window.addEventListener('mousemove', mouseMove) window.addEventListener('mouseup', endMouseMove) onBeforeUnmount(() => { window.removeEventListener('arkUiResizeableWindowSelect', onSelectListener) window.removeEventListener('mousemove', mouseMove) window.removeEventListener('mouseup', endMouseMove) }) return () => { const style = `height: ${height.value}px; left: ${left.value}px; top: ${top.value}px; width: ${width.value}px` return (
startResize(e, 'top')}/>
startResize(e, 'left')}/>
{ props.slot({ onMouseDown: startMove }) }
startResize(e, 'right')}/>
startResize(e, 'bottom')}/>
) } }, })