import { defineComponent, ref, unref, computed, PropType } from "vue"; import resizer from "./resizer"; import "./index.css"; export interface ContextProps { minPercent: number; defaultPercent: number; split: string; } export default defineComponent({ name: "splitPane", components: { resizer }, props: { splitSet: { type: Object as PropType, require: true, }, }, emits: ["resize"], setup(props, ctx) { let active = ref(false); let hasMoved = ref(false); let percent = ref(props.splitSet?.defaultPercent); let type = props.splitSet?.split === "vertical" ? "width" : "height"; let resizeType = props.splitSet?.split === "vertical" ? "left" : "top"; let leftClass = ref([ "splitter-pane splitter-paneL", props.splitSet?.split, ]); let rightClass = ref([ "splitter-pane splitter-paneR", props.splitSet?.split, ]); const userSelect = computed(() => { return active.value ? "none" : ""; }); const cursor = computed(() => { return active.value ? props.splitSet?.split === "vertical" ? "col-resize" : "row-resize" : ""; }); const onClick = (): void => { if (!hasMoved.value) { percent.value = 50; ctx.emit("resize", percent.value); } }; const onMouseDown = (): void => { active.value = true; hasMoved.value = false; }; const onMouseUp = (): void => { active.value = false; }; const onMouseMove = (e: any): void => { if (e.buttons === 0 || e.which === 0) { active.value = false; } if (active.value) { let offset = 0; let target = e.currentTarget; if (props.splitSet?.split === "vertical") { while (target) { offset += target.offsetLeft; target = target.offsetParent; } } else { while (target) { offset += target.offsetTop; target = target.offsetParent; } } const currentPage = props.splitSet?.split === "vertical" ? e.pageX : e.pageY; const targetOffset = props.splitSet?.split === "vertical" ? e.currentTarget.offsetWidth : e.currentTarget.offsetHeight; const percents = Math.floor(((currentPage - offset) / targetOffset) * 10000) / 100; if ( percents > props.splitSet?.minPercent && percents < 100 - props.splitSet?.minPercent ) { percent.value = percents; } ctx.emit("resize", percent.value); hasMoved.value = true; } }; return () => ( <>
onMouseUp()} onMousemove={() => onMouseMove(event)} >
{ctx.slots.paneL()}
onMouseDown()} onClick={() => onClick()} >
{ctx.slots.paneR()}
); }, });