winbox-ui-next
Version:
We Design Vue 2.0: A Vue.js 3 UI Library
198 lines (197 loc) • 6.48 kB
JavaScript
import { defineComponent, toRefs, ref, reactive, computed, resolveComponent, openBlock, createBlock, resolveDynamicComponent, normalizeClass, withCtx, createElementVNode, normalizeStyle, renderSlot, createCommentVNode } from "vue";
import ResizeTrigger from "../_components/resize-trigger.js";
import useMergeState from "../_hooks/use-merge-state.js";
import { getPrefixCls } from "../_utils/global-config.js";
import { on, off } from "../_utils/dom.js";
import _export_sfc from "../_virtual/plugin-vue_export-helper";
function px2percent(numerator, denominator) {
return parseFloat(numerator) / parseFloat(denominator);
}
const _sfc_main = defineComponent({
name: "Split",
components: {
ResizeTrigger
},
props: {
component: {
type: String,
default: "div"
},
direction: {
type: String,
default: "horizontal"
},
size: {
type: [Number, String],
default: void 0
},
defaultSize: {
type: [Number, String],
default: 0.5
},
min: {
type: [Number, String]
},
max: {
type: [Number, String]
},
disabled: {
type: Boolean
}
},
emits: [
"moveStart",
"moving",
"moveEnd",
"update:size"
],
setup(props, { emit }) {
const { direction, size: propSize, defaultSize, min, max } = toRefs(props);
const triggerSize = ref(0);
const record = {
startPageX: 0,
startPageY: 0,
startWidth: 0,
startHeight: 0,
startSize: 0,
moving: false
};
const wrapperRef = ref();
const prefixCls = getPrefixCls("split");
const [size, setSize] = useMergeState(defaultSize.value, reactive({
value: propSize
}));
const numberSize = computed(() => {
return parseFloat(size.value);
});
const isHorizontal = computed(() => direction.value === "horizontal");
const classNames = computed(() => [
prefixCls,
{
[`${prefixCls}-horizontal`]: isHorizontal.value,
[`${prefixCls}-vertical`]: !isHorizontal.value
}
]);
const isPxSize = computed(() => propSize && typeof propSize.value === "string");
const firstPaneStyles = computed(() => {
let firstPaneSize = "0";
if (numberSize.value) {
const unit = isPxSize.value ? "px" : "%";
const baseVal = isPxSize.value ? numberSize.value : numberSize.value * 100;
firstPaneSize = `calc(${baseVal}${unit} - ${triggerSize.value / 2}px)`;
}
return {
flexBasis: firstPaneSize
};
});
function getNewSize({
startWrapperSize,
startSize,
startPosition,
endPosition
}) {
const minOffset = min.value ? parseFloat(min.value) : 0;
const maxOffset = max.value ? parseFloat(max.value) : isPxSize.value ? startWrapperSize : 1;
let newSize = isPxSize.value ? startSize + (endPosition - startPosition) : px2percent(startWrapperSize * startSize + endPosition - startPosition, startWrapperSize);
newSize = Math.max(newSize, minOffset);
newSize = Math.min(newSize, maxOffset);
return newSize;
}
function onMoving(e) {
if (!record.moving)
return;
emit("moving", e);
let newSize = isHorizontal.value ? getNewSize({
startWrapperSize: record.startWidth,
startSize: record.startSize,
startPosition: record.startPageX,
endPosition: e.pageX
}) : getNewSize({
startWrapperSize: record.startHeight,
startSize: record.startSize,
startPosition: record.startPageY,
endPosition: e.pageY
});
if (isPxSize.value)
newSize = `${newSize}px`;
setSize(newSize);
emit("update:size", newSize);
}
function onMovingEnd(e) {
record.moving = false;
off(window, "mousemove", onMoving);
off(window, "mouseup", onMovingEnd);
off(window, "contextmenu", onMovingEnd);
document.body.style.cursor = "default";
emit("moveEnd", e);
}
function onMoveStart(e) {
var _a, _b;
emit("moveStart", e);
record.moving = true;
record.startPageX = e.pageX;
record.startPageY = e.pageY;
record.startWidth = ((_a = wrapperRef.value) == null ? void 0 : _a.clientWidth) || 0;
record.startHeight = ((_b = wrapperRef.value) == null ? void 0 : _b.clientHeight) || 0;
record.startSize = numberSize.value;
on(window, "mousemove", onMoving);
on(window, "mouseup", onMovingEnd);
on(window, "contextmenu", onMovingEnd);
document.body.style.cursor = isHorizontal.value ? "col-resize" : "row-resize";
}
function onTiggerResize(entry) {
const { width, height } = entry.contentRect;
triggerSize.value = isHorizontal.value ? width : height;
}
return {
size1: size,
numberSize,
prefixCls,
classNames,
isHorizontal,
wrapperRef,
onMoveStart,
onTiggerResize,
firstPaneStyles
};
}
});
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_ResizeTrigger = resolveComponent("ResizeTrigger");
return openBlock(), createBlock(resolveDynamicComponent(_ctx.component), {
ref: "wrapperRef",
class: normalizeClass(_ctx.classNames)
}, {
default: withCtx(() => [
createElementVNode("div", {
class: normalizeClass([`${_ctx.prefixCls}-pane`, `${_ctx.prefixCls}-pane-first`]),
style: normalizeStyle(_ctx.firstPaneStyles)
}, [
renderSlot(_ctx.$slots, "first")
], 6),
!_ctx.disabled ? (openBlock(), createBlock(_component_ResizeTrigger, {
key: 0,
"prefix-cls": `${_ctx.prefixCls}-trigger`,
direction: _ctx.isHorizontal ? "vertical" : "horizontal",
onMousedown: _ctx.onMoveStart,
onResize: _ctx.onTiggerResize
}, {
default: withCtx(() => [
renderSlot(_ctx.$slots, "resize-trigger")
]),
icon: withCtx(() => [
renderSlot(_ctx.$slots, "resize-trigger-icon")
]),
_: 3
}, 8, ["prefix-cls", "direction", "onMousedown", "onResize"])) : createCommentVNode("v-if", true),
createElementVNode("div", {
class: normalizeClass([`${_ctx.prefixCls}-pane`, `${_ctx.prefixCls}-pane-second`])
}, [
renderSlot(_ctx.$slots, "second")
], 2)
]),
_: 3
}, 8, ["class"]);
}
var _Split = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export { _Split as default };