UNPKG

@opensig/opendesign

Version:

299 lines (298 loc) 9.78 kB
"use strict"; const vue = require("vue"); const index = require("../popover/index.js"); const keycode = require("../_utils/keycode.js"); const vueUtils = require("../_utils/vue-utils.js"); const provide = require("./provide.js"); const types = require("./types.js"); const _hoisted_1 = ["tabindex"]; const _hoisted_2 = { key: 0, class: "o-slider-circle" }; const _sfc_main = /* @__PURE__ */ vue.defineComponent({ __name: "OSliderButton", props: types.sliderButtonProps, emits: ["update:modelValue"], setup(__props, { expose: __expose, emit: __emit }) { const props = __props; const emit = __emit; const initData = vue.reactive({ hovering: false, dragging: false, isClick: false, startX: 0, currentX: 0, startY: 0, currentY: 0, startPosition: 0, newPosition: 0, oldValue: props.modelValue }); const { disabled, min, max, step, sliderSize, emitChange, resetSize, updateDragging } = vue.inject(provide.sliderInjectKey); const button = vue.ref(); const { hovering, dragging } = vue.toRefs(initData); const formatValue = vue.computed(() => { return props.modelValue; }); const showToolTip = vue.computed(() => { return initData.hovering || initData.dragging; }); const currentPosition = vue.computed(() => { return `${(props.modelValue - min.value) / (max.value - min.value) * 100}%`; }); const wrapperStyle = vue.computed(() => { return { left: currentPosition.value }; }); const handleMouseEnter = () => { initData.hovering = true; }; const handleMouseLeave = () => { initData.hovering = false; }; const onButtonDown = (event) => { if (disabled.value) { return; } event.preventDefault(); handleDragStart(event); window.addEventListener("mousemove", handleDragging); window.addEventListener("touchmove", handleDragging); window.addEventListener("mouseup", handleDragEnd); window.addEventListener("touchend", handleDragEnd); window.addEventListener("contextmenu", handleDragEnd); button.value.focus(); }; const incrementPosition = (amount) => { if (disabled.value) { return; } initData.newPosition = Number.parseFloat(currentPosition.value) + amount / (max.value - min.value) * 100; setPosition(initData.newPosition); emitChange(); }; const onLeftKeyDown = () => { incrementPosition(-step.value); }; const onRightKeyDown = () => { incrementPosition(step.value); }; const onPageDownKeyDown = () => { incrementPosition(-step.value * 4); }; const onPageUpKeyDown = () => { incrementPosition(step.value * 4); }; const onHomeKeyDown = () => { if (disabled.value) { return; } setPosition(0); emitChange(); }; const onEndKeyDown = () => { if (disabled.value) { return; } setPosition(100); emitChange(); }; const onKeyDown = (event) => { const code = event.code; let isPreventDefault = true; switch (code) { case keycode.ArrowLeft.key: case keycode.ArrowDown.key: onLeftKeyDown(); break; case keycode.ArrowRight.key: case keycode.ArrowUp.key: onRightKeyDown(); break; case keycode.Home.key: onHomeKeyDown(); break; case keycode.End.key: onEndKeyDown(); break; case keycode.pageDown.key: onPageDownKeyDown(); break; case keycode.pageUp.key: onPageUpKeyDown(); break; default: isPreventDefault = false; break; } isPreventDefault && event.preventDefault(); }; const getClientXY = (event) => { let clientX; let clientY; if (event.type.startsWith("touch")) { clientY = event.touches[0].clientY; clientX = event.touches[0].clientX; } else { clientY = event.clientY; clientX = event.clientX; } return { clientX, clientY }; }; const handleDragStart = (event) => { initData.dragging = true; initData.isClick = true; const { clientX, clientY } = getClientXY(event); if (props.direction === "v") { initData.startY = clientY; } else { initData.startX = clientX; } initData.startPosition = Number.parseFloat(currentPosition.value); initData.newPosition = initData.startPosition; }; const handleDragging = (event) => { if (initData.dragging) { initData.isClick = false; resetSize(); let diff; const { clientX, clientY } = getClientXY(event); if (props.direction === "v") { initData.currentY = clientY; diff = (initData.startY - initData.currentY) / sliderSize.value * 100; } else { initData.currentX = clientX; diff = (initData.currentX - initData.startX) / sliderSize.value * 100; } initData.newPosition = initData.startPosition + diff; setPosition(initData.newPosition); } }; const handleDragEnd = () => { if (initData.dragging) { setTimeout(() => { initData.dragging = false; if (!initData.isClick) { setPosition(initData.newPosition); } emitChange(); }, 0); window.removeEventListener("mousemove", handleDragging); window.removeEventListener("touchmove", handleDragging); window.removeEventListener("mouseup", handleDragEnd); window.removeEventListener("touchend", handleDragEnd); window.removeEventListener("contextmenu", handleDragEnd); } }; const clamp = (num, lower, upper) => { return Math.max(lower, Math.min(num, upper)); }; const setPosition = async (newPosition) => { if (newPosition === null || Number.isNaN(+newPosition)) { return; } newPosition = clamp(newPosition, 0, 100); const fullSteps = Math.floor((max.value - min.value) / step.value); const fullRangePercentage = fullSteps * step.value / (max.value - min.value) * 100; const threshold = fullRangePercentage + (100 - fullRangePercentage) / 2; let value; if (newPosition < fullRangePercentage) { const valueBetween = fullRangePercentage / fullSteps; const steps = Math.round(newPosition / valueBetween); value = min.value + steps * step.value; } else if (newPosition < threshold) { value = min.value + fullSteps * step.value; } else { value = max.value; } value = Number.parseFloat(value.toFixed()); if (value !== props.modelValue) { emit("update:modelValue", value); } if (!initData.dragging && props.modelValue !== initData.oldValue) { initData.oldValue = props.modelValue; } }; vue.watch( () => initData.dragging, (val) => { updateDragging(val); } ); vue.onMounted(() => { var _a; (_a = button.value) == null ? void 0 : _a.addEventListener("touchstart", onButtonDown, { passive: false }); }); vue.onUnmounted(() => { var _a; (_a = button.value) == null ? void 0 : _a.removeEventListener("touchstart", onButtonDown); }); __expose({ onButtonDown, onKeyDown, setPosition, hovering, dragging }); return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock( vue.Fragment, null, [ vue.createElementVNode("div", { ref_key: "button", ref: button, class: vue.normalizeClass(["o-slider-btn-wrap", { "o-slider-btn-wrap-hover": showToolTip.value && !props.showSolidCircle && !vue.unref(disabled) }]), style: vue.normalizeStyle(wrapperStyle.value), tabindex: vue.unref(disabled) ? void 0 : 0, onMouseenter: handleMouseEnter, onMouseleave: handleMouseLeave, onMousedown: onButtonDown, onFocus: handleMouseEnter, onBlur: handleMouseLeave, onKeydown: onKeyDown }, [ vue.createElementVNode( "div", { class: vue.normalizeClass(["o-slider-btn", { "o-slider-btn-hover": showToolTip.value && !props.showSolidCircle && !vue.unref(disabled) }]) }, [ props.showSolidCircle ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2)) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ) ], 46, _hoisted_1), _ctx.showPopover ? (vue.openBlock(), vue.createBlock(vue.unref(index.OPopover), { key: 0, trigger: "none", position: props.position, visible: showToolTip.value && !vue.unref(disabled), "adjust-width": false, "adjust-min-width": false, target: button.value, wrapper: button.value, "wrap-class": vue.unref(vueUtils.mergeClass)("o-slider-popover", props.wrapClass) }, { default: vue.withCtx(() => [ vue.createTextVNode( vue.toDisplayString(formatValue.value), 1 /* TEXT */ ) ]), _: 1 /* STABLE */ }, 8, ["position", "visible", "target", "wrapper", "wrap-class"])) : vue.createCommentVNode("v-if", true) ], 64 /* STABLE_FRAGMENT */ ); }; } }); module.exports = _sfc_main;