UNPKG

tav-ui

Version:
312 lines (309 loc) 8.48 kB
import { defineComponent, reactive, ref, computed, watch, watchEffect, unref, createVNode } from 'vue'; import { CheckOutlined, DoubleRightOutlined } from '@ant-design/icons-vue'; import { useTimeoutFn } from '../../../hooks/core/useTimeout2.mjs'; import { useEventListener } from '../../../hooks/event/useEventListener2.mjs'; import { getSlot } from '../../../utils/helper/tsxHelper2.mjs'; import { verifyProps } from './types2.mjs'; var Verify = defineComponent({ name: "TaVerify", props: verifyProps, emits: ["success", "update:value", "change", "start", "move", "end"], setup(props, { emit, slots, expose }) { const state = reactive({ isMoving: false, isPassing: false, moveDistance: 0, toLeft: false, startTime: 0, endTime: 0 }); const wrapElRef = ref(null); const barElRef = ref(null); const contentElRef = ref(null); const actionElRef = ref(null); useEventListener({ el: document, name: "mouseup", listener: () => { if (state.isMoving) { resume(); } } }); const getActionStyleRef = computed(() => { const { height, actionStyle } = props; const h = `${parseInt(height)}px`; return { left: 0, width: h, height: h, ...actionStyle }; }); const getWrapStyleRef = computed(() => { const { height, width, circle, wrapStyle } = props; const h = parseInt(height); const w = `${parseInt(width)}px`; return { width: w, height: `${h}px`, lineHeight: `${h}px`, borderRadius: circle ? `${h / 2}px` : 0, ...wrapStyle }; }); const getBarStyleRef = computed(() => { const { height, circle, barStyle } = props; const h = parseInt(height); return { height: `${h}px`, borderRadius: circle ? `${h / 2}px 0 0 ${h / 2}px` : 0, ...barStyle }; }); const getContentStyleRef = computed(() => { const { height, width, contentStyle } = props; const h = `${parseInt(height)}px`; const w = `${parseInt(width)}px`; return { height: h, width: w, ...contentStyle }; }); watch(() => state.isPassing, (isPassing) => { if (isPassing) { const { startTime, endTime } = state; const time = (endTime - startTime) / 1e3; emit("success", { isPassing, time: time.toFixed(1) }); emit("update:value", isPassing); emit("change", isPassing); } }); watchEffect(() => { state.isPassing = !!props.value; }); function getEventPageX(e) { return e.pageX || e.touches[0].pageX; } function handleDragStart(e) { if (state.isPassing) { return; } const actionEl = unref(actionElRef); if (!actionEl) return; emit("start", e); state.moveDistance = getEventPageX(e) - parseInt(actionEl.style.left.replace("px", ""), 10); state.startTime = new Date().getTime(); state.isMoving = true; } function getOffset(el) { const actionWidth = parseInt(el.style.width); const { width } = props; const widthNum = parseInt(width); const offset = widthNum - actionWidth - 6; return { offset, widthNum, actionWidth }; } function handleDragMoving(e) { const { isMoving, moveDistance } = state; if (isMoving) { const actionEl = unref(actionElRef); const barEl = unref(barElRef); if (!actionEl || !barEl) return; const { offset, widthNum, actionWidth } = getOffset(actionEl); const moveX = getEventPageX(e) - moveDistance; emit("move", { event: e, moveDistance, moveX }); if (moveX > 0 && moveX <= offset) { actionEl.style.left = `${moveX}px`; barEl.style.width = `${moveX + actionWidth / 2}px`; } else if (moveX > offset) { actionEl.style.left = `${widthNum - actionWidth}px`; barEl.style.width = `${widthNum - actionWidth / 2}px`; if (!props.isSlot) { checkPass(); } } } } function handleDragOver(e) { const { isMoving, isPassing, moveDistance } = state; if (isMoving && !isPassing) { emit("end", e); const actionEl = unref(actionElRef); const barEl = unref(barElRef); if (!actionEl || !barEl) return; const moveX = getEventPageX(e) - moveDistance; const { offset, widthNum, actionWidth } = getOffset(actionEl); if (moveX < offset) { if (!props.isSlot) { resume(); } else { setTimeout(() => { if (!props.value) { resume(); } else { const contentEl = unref(contentElRef); if (contentEl) { contentEl.style.width = `${parseInt(barEl.style.width)}px`; } } }, 0); } } else { actionEl.style.left = `${widthNum - actionWidth}px`; barEl.style.width = `${widthNum - actionWidth / 2}px`; checkPass(); } state.isMoving = false; } } function checkPass() { if (props.isSlot) { resume(); return; } state.endTime = new Date().getTime(); state.isPassing = true; state.isMoving = false; } function resume() { state.isMoving = false; state.isPassing = false; state.moveDistance = 0; state.toLeft = false; state.startTime = 0; state.endTime = 0; const actionEl = unref(actionElRef); const barEl = unref(barElRef); const contentEl = unref(contentElRef); if (!actionEl || !barEl || !contentEl) return; state.toLeft = true; useTimeoutFn(() => { state.toLeft = false; actionEl.style.left = "0"; barEl.style.width = "0"; }, 300); contentEl.style.width = unref(getContentStyleRef).width; } expose({ resume }); return () => { const renderBar = () => { const cls = [`darg-verify-bar`]; if (state.toLeft) { cls.push("to-left"); } return createVNode("div", { "class": cls, "ref": barElRef, "style": unref(getBarStyleRef) }, null); }; const renderContent = () => { const cls = [`darg-verify-content`]; const { isPassing } = state; const { text, successText } = props; isPassing && cls.push("success"); return createVNode("div", { "class": cls, "ref": contentElRef, "style": unref(getContentStyleRef) }, [getSlot(slots, "text", isPassing) || (isPassing ? successText : text)]); }; const renderAction = () => { const cls = [`darg-verify-action`]; const { toLeft, isPassing } = state; if (toLeft) { cls.push("to-left"); } return createVNode("div", { "class": cls, "onMousedown": handleDragStart, "onTouchstart": handleDragStart, "style": unref(getActionStyleRef), "ref": actionElRef }, [getSlot(slots, "actionIcon", isPassing) || (isPassing ? createVNode(CheckOutlined, { "class": `darg-verify-action__icon` }, null) : createVNode(DoubleRightOutlined, { "class": `darg-verify-action__icon` }, null))]); }; return createVNode("div", { "class": "ta-darg-verify", "ref": wrapElRef, "style": unref(getWrapStyleRef), "onMousemove": handleDragMoving, "onTouchmove": handleDragMoving, "onMouseleave": handleDragOver, "onMouseup": handleDragOver, "onTouchend": handleDragOver }, [renderBar(), renderContent(), renderAction()]); }; } }); export { Verify as default }; //# sourceMappingURL=verify2.mjs.map