import { For, JSXElement, createEffect, createRenderEffect, createSignal, onCleanup } from "solid-js"; import { useClassList } from "../utils/useProps" import { createStore } from "solid-js/store"; import { useSlots } from "../utils/useSlots"; type SplitProps = { classList?: any, class?: any, dir?: 'v' | 'h', split?: number | string, min?: number, max?: number, children?: JSXElement } export function Split (props: SplitProps) { const dir = props.dir || 'v'; const classList = () => useClassList(props, 'cm-split-wrap', { [`cm-split-wrap-${dir}`]: dir }); let initSplit: any = props.split; if (initSplit && initSplit < 1) { initSplit = initSplit * 100 + '%'; } const [split, setSplit] = createSignal(initSplit || '50%'); const min = props.min || 40; let wrap: any; let prev: any; const handlerClassList = () => ({ 'cm-split-handler': true, 'cm-split-dragging': store.dragging, [`cm-split-handler-${dir}`]: !!dir }); const slots = useSlots(props.children); if (!slots.prev) { console.warn('Split need prev Slot Element'); } if (!slots.next) { console.warn('Split need next Slot Element'); } createEffect(() => { const wrapRect = wrap.getBoundingClientRect(); const wrapSize = dir === 'v' ? wrapRect.width : wrapRect.height; let wh = dir === 'v' ? prev.style.width : prev.style.height; if (wh.indexOf('px') > -1) { wh = parseFloat(wh) / wrapSize * 100; } else { wh = parseFloat(wh); } let max = props.max ? props.max / wrapSize * 100 : 100 - min / wrapSize * 100; wh = wh + (dir === 'v' ? store.deltaX : store.deltaY)/wrapSize * 100; wh = Math.max(wh, min / wrapSize * 100); wh = Math.min(wh, max); setSplit(wh + '%'); }); const prevStyle = () => { return {[`${dir === 'v' ? 'width' : 'height'}`]: split()}; } const handlerStyle = () => { return {[`${dir === 'v' ? 'left' : 'top'}`]: split()}; } const nextStyle = { flex: '1' } const [store, setStore] = createStore({ dragging: false, x: NaN, y: NaN, deltaX: 0, deltaY: 0 }) const onDragStart = (e: any) => { if (typeof e.button === 'number' && e.button !== 0) return false; setStore('dragging', true); const x = e.clientX; const y = e.clientY; setStore('x', x); setStore('y', y); document.addEventListener('mousemove', onDragMove, false); document.addEventListener('mouseup', onDragEnd, false); } const onDragMove = (e: any) => { const deltaX = e.clientX - store.x; const deltaY = e.clientY - store.y; setStore('x', e.clientX); setStore('y', e.clientY); setStore('deltaX', deltaX); setStore('deltaY', deltaY); } const onDragEnd = (e: any) => { setStore('dragging', false); document.removeEventListener('mousemove', onDragMove); document.removeEventListener('mouseup', onDragEnd); setStore('deltaX', 0); setStore('deltaY', 0); } onCleanup(() => { document.removeEventListener('mousemove', onDragMove); document.removeEventListener('mouseup', onDragEnd); }) return
{slots.prev}
{() => { return
}}
{slots.next}
}