vexip-ui
Version:
A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good
1 lines • 10.9 kB
Source Map (JSON)
{"version":3,"file":"split.vue.mjs","sources":["../../../components/split/split.vue"],"sourcesContent":["<template>\n <div ref=\"wrapper\" :class=\"className\" @transitionend=\"removeTransition\">\n <div\n :class=\"[nh.be('panel'), nh.bem('panel', props.vertical ? 'top' : 'left')]\"\n :style=\"leftPaneStyle\"\n >\n <slot name=\"left\"></slot>\n </div>\n <div\n :class=\"[nh.be('panel'), nh.bem('panel', props.vertical ? 'bottom' : 'right')]\"\n :style=\"rightPaneStyle\"\n >\n <slot name=\"right\"></slot>\n </div>\n <div :class=\"nh.be('trigger')\" :style=\"triggerStyle\">\n <div ref=\"handler\" :class=\"nh.be('handler')\">\n <template v-if=\"props.canFull\">\n <button\n type=\"button\"\n :class=\"[nh.be('button'), nh.bem('button', `${props.vertical ? 'top' : 'left'}-full`)]\"\n @pointerdown.stop\n @click.left=\"handleFull(-1)\"\n >\n <Icon v-bind=\"fullIcons[0]\" :scale=\"+(fullIcons[0].scale || 1) * 0.6\"></Icon>\n </button>\n <button\n type=\"button\"\n :class=\"[\n nh.be('button'),\n nh.bem('button', `${props.vertical ? 'bottom' : 'right'}-full`)\n ]\"\n @pointerdown.stop\n @click.left=\"handleFull(1)\"\n >\n <Icon v-bind=\"fullIcons[1]\" :scale=\"+(fullIcons[1].scale || 1) * 0.6\"></Icon>\n </button>\n </template>\n <template v-else>\n <slot name=\"handler\">\n <span v-for=\"n in 6\" :key=\"n\" :class=\"nh.be('pointer')\"></span>\n </slot>\n </template>\n </div>\n </div>\n <div ref=\"guide\" :class=\"nh.be('guide')\"></div>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { Icon } from '@/components/icon'\n\nimport { computed, defineComponent, ref, watch } from 'vue'\n\nimport { emitEvent, useIcons, useNameHelper, useProps } from '@vexip-ui/config'\nimport { useMoving } from '@vexip-ui/hooks'\nimport { splitProps } from './props'\n\nexport default defineComponent({\n name: 'Split',\n components: {\n Icon,\n },\n props: splitProps,\n emits: ['update:value'],\n setup(_props, { emit }) {\n const props = useProps('split', _props, {\n value: {\n default: 0.5,\n validator: (value: number) => value > 0 && value < 1,\n static: true,\n },\n min: 0.1,\n max: 0.9,\n vertical: false,\n noTransition: false,\n lazy: false,\n canFull: false,\n })\n\n const nh = useNameHelper('split')\n const icons = useIcons()\n const currentValue = ref(props.value)\n const currentFull = ref<0 | 1 | -1>(0)\n const transition = ref(false)\n\n const wrapper = ref<HTMLElement>()\n const guide = ref<HTMLElement>()\n\n const offset = computed(() => {\n return props.vertical ? 'offsetHeight' : 'offsetWidth'\n })\n const position = computed<['top', 'bottom'] | ['left', 'right']>(() => {\n return props.vertical ? ['top', 'bottom'] : ['left', 'right']\n })\n\n const { target: handler, moving } = useMoving({\n lazy: true,\n capture: false,\n onStart: (state, event) => {\n if (currentFull.value || !wrapper.value || event.button > 0) {\n return false\n }\n\n const { min, max, vertical, lazy } = props\n const outer = wrapper.value[offset.value]\n const computedMin = min <= 1 ? min : min / outer\n const computedMax = max <= 1 ? max : max / outer\n\n state.outer = outer\n state.min = computedMin\n state.max = computedMax\n state.vertical = vertical\n state.splitLazy = lazy\n state.start = currentValue.value * outer\n state.target = currentValue.value\n\n if (lazy && guide.value) {\n guide.value.style[position.value[0]] = `${currentValue.value * 100}`\n guide.value.style.display = 'block'\n }\n\n emitEvent(props.onMoveStart, currentValue.value)\n },\n onMove: state => {\n const outer = state.outer as number\n const min = state.min as number\n const max = state.max as number\n const delta = state.vertical ? state.deltaY : state.deltaX\n const start = state.start as number\n const value = Math.min(Math.max(min, (start + delta) / outer), max)\n\n if (state.splitLazy) {\n if (guide.value) {\n guide.value.style[position.value[0]] = `${value * 100}%`\n }\n\n state.target = value\n } else {\n handleChange(value)\n }\n\n emitEvent(props.onMove, value)\n },\n onEnd: state => {\n if (guide.value) {\n guide.value.style.display = ''\n }\n\n if (state.splitLazy) {\n const target = state.target as number\n\n if (Math.abs(target - currentValue.value) > 0.01) {\n setTransition()\n }\n\n handleChange(target)\n }\n\n emitEvent(props.onMoveEnd, currentValue.value)\n },\n })\n\n const className = computed(() => {\n let fullType = ''\n\n if (currentFull.value) {\n if (props.vertical) {\n fullType = currentFull.value < 0 ? 'top' : 'bottom'\n } else {\n fullType = currentFull.value < 0 ? 'left' : 'right'\n }\n }\n\n return {\n [nh.b()]: true,\n [nh.bs('vars')]: true,\n [nh.bm('inherit')]: props.inherit,\n [nh.bm(props.vertical ? 'vertical' : 'horizontal')]: true,\n [nh.bm('moving')]: moving.value,\n [nh.bm(`${fullType}-full`)]: !!fullType,\n [nh.bm('transition')]: transition.value,\n }\n })\n const leftPaneStyle = computed(() => {\n return {\n [position.value[1]]:\n currentFull.value < 0\n ? '0'\n : currentFull.value > 0\n ? '100%'\n : `${(1 - currentValue.value) * 100}%`,\n }\n })\n const rightPaneStyle = computed(() => {\n return {\n [position.value[0]]:\n currentFull.value < 0\n ? '100%'\n : currentFull.value > 0\n ? '0'\n : `${currentValue.value * 100}%`,\n }\n })\n const triggerStyle = computed(() => {\n return {\n [position.value[0]]:\n currentFull.value < 0\n ? '100%'\n : currentFull.value > 0\n ? '0'\n : `calc(${currentValue.value * 100}% - var(${nh.cv('handler-size')}) * 0.5)`,\n }\n })\n const fullIcons = computed(() => {\n return props.vertical\n ? [icons.value.angleDown, icons.value.angleUp]\n : [icons.value.angleRight, icons.value.angleLeft]\n })\n\n watch(\n () => props.value,\n value => {\n if (value.toFixed(5) !== currentValue.value.toFixed(5)) {\n currentValue.value = value\n setTransition()\n }\n },\n )\n watch(currentValue, value => {\n if (guide.value) {\n guide.value.style[position.value[0]] = `${value * 100}%`\n }\n })\n watch(currentFull, value => {\n setTransition()\n\n if (value) {\n let type: 'top' | 'right' | 'bottom' | 'left'\n\n if (props.vertical) {\n type = value < 0 ? 'top' : 'bottom'\n } else {\n type = value < 0 ? 'left' : 'right'\n }\n\n emitEvent(props.onFull, type)\n } else {\n emitEvent(props.onReset)\n }\n })\n\n function setTransition() {\n transition.value = !props.noTransition && !moving.value\n }\n\n function removeTransition() {\n transition.value = false\n }\n\n function handleFull(type: 1 | -1) {\n if (!props.canFull) {\n return\n }\n\n if (currentFull.value) {\n currentFull.value = 0\n } else {\n currentFull.value = type\n }\n }\n\n function handleChange(value: number) {\n if (value.toFixed(5) !== currentValue.value.toFixed(5)) {\n currentValue.value = value\n\n emitEvent(props.onChange, value)\n emit('update:value', value)\n }\n }\n\n return {\n props,\n nh,\n\n className,\n position,\n leftPaneStyle,\n rightPaneStyle,\n triggerStyle,\n fullIcons,\n\n wrapper,\n guide,\n handler,\n\n removeTransition,\n handleFull,\n }\n },\n})\n</script>\n"],"names":["_createElementBlock","_normalizeClass","_ctx","_cache","args","_createElementVNode","_normalizeStyle","_renderSlot","_Fragment","_withModifiers","_createVNode","_component_Icon","_mergeProps","_openBlock","_renderList","n"],"mappings":"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"}