import { defineComponent, ref, computed, unref, nextTick, onMounted, watch, openBlock, createElementBlock, normalizeClass, Fragment, renderList, createBlock, withCtx, createTextVNode, toDisplayString, createCommentVNode, withDirectives, createVNode, createElementVNode } from 'vue'; import { debounce } from 'lodash-unified'; import '../../../../directives/index.mjs'; import { ElScrollbar } from '../../../scrollbar/index.mjs'; import { ElIcon } from '../../../icon/index.mjs'; import { ArrowUp, ArrowDown } from '@element-plus/icons-vue'; import '../../../../hooks/index.mjs'; import '../../../../utils/index.mjs'; import { timeUnits } from '../constants.mjs'; import { buildTimeList } from '../utils.mjs'; import { basicTimeSpinnerProps } from '../props/basic-time-spinner.mjs'; import { getTimeLists } from '../composables/use-time-picker.mjs'; import _export_sfc from '../../../../_virtual/plugin-vue_export-helper.mjs'; import { useNamespace } from '../../../../hooks/use-namespace/index.mjs'; import { getStyle } from '../../../../utils/dom/style.mjs'; import { vRepeatClick } from '../../../../directives/repeat-click/index.mjs'; const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "basic-time-spinner", props: basicTimeSpinnerProps, emits: ["change", "select-range", "set-option"], setup(__props, { emit }) { const props = __props; const ns = useNamespace("time"); const { getHoursList, getMinutesList, getSecondsList } = getTimeLists(props.disabledHours, props.disabledMinutes, props.disabledSeconds); let isScrolling = false; const currentScrollbar = ref(); const listHoursRef = ref(); const listMinutesRef = ref(); const listSecondsRef = ref(); const listRefsMap = { hours: listHoursRef, minutes: listMinutesRef, seconds: listSecondsRef }; const spinnerItems = computed(() => { return props.showSeconds ? timeUnits : timeUnits.slice(0, 2); }); const timePartials = computed(() => { const { spinnerDate } = props; const hours = spinnerDate.hour(); const minutes = spinnerDate.minute(); const seconds = spinnerDate.second(); return { hours, minutes, seconds }; }); const timeList = computed(() => { const { hours, minutes } = unref(timePartials); return { hours: getHoursList(props.role), minutes: getMinutesList(hours, props.role), seconds: getSecondsList(hours, minutes, props.role) }; }); const arrowControlTimeList = computed(() => { const { hours, minutes, seconds } = unref(timePartials); return { hours: buildTimeList(hours, 23), minutes: buildTimeList(minutes, 59), seconds: buildTimeList(seconds, 59) }; }); const debouncedResetScroll = debounce((type) => { isScrolling = false; adjustCurrentSpinner(type); }, 200); const getAmPmFlag = (hour) => { const shouldShowAmPm = !!props.amPmMode; if (!shouldShowAmPm) return ""; const isCapital = props.amPmMode === "A"; let content = hour < 12 ? " am" : " pm"; if (isCapital) content = content.toUpperCase(); return content; }; const emitSelectRange = (type) => { let range; switch (type) { case "hours": range = [0, 2]; break; case "minutes": range = [3, 5]; break; case "seconds": range = [6, 8]; break; } const [left, right] = range; emit("select-range", left, right); currentScrollbar.value = type; }; const adjustCurrentSpinner = (type) => { adjustSpinner(type, unref(timePartials)[type]); }; const adjustSpinners = () => { adjustCurrentSpinner("hours"); adjustCurrentSpinner("minutes"); adjustCurrentSpinner("seconds"); }; const getScrollbarElement = (el) => el.querySelector(`.${ns.namespace.value}-scrollbar__wrap`); const adjustSpinner = (type, value) => { if (props.arrowControl) return; const scrollbar = unref(listRefsMap[type]); if (scrollbar && scrollbar.$el) { getScrollbarElement(scrollbar.$el).scrollTop = Math.max(0, value * typeItemHeight(type)); } }; const typeItemHeight = (type) => { const scrollbar = unref(listRefsMap[type]); const listItem = scrollbar == null ? void 0 : scrollbar.$el.querySelector("li"); if (listItem) { return Number.parseFloat(getStyle(listItem, "height")) || 0; } return 0; }; const onIncrement = () => { scrollDown(1); }; const onDecrement = () => { scrollDown(-1); }; const scrollDown = (step) => { if (!currentScrollbar.value) { emitSelectRange("hours"); } const label = currentScrollbar.value; const now = unref(timePartials)[label]; const total = currentScrollbar.value === "hours" ? 24 : 60; const next = findNextUnDisabled(label, now, step, total); modifyDateField(label, next); adjustSpinner(label, next); nextTick(() => emitSelectRange(label)); }; const findNextUnDisabled = (type, now, step, total) => { let next = (now + step + total) % total; const list = unref(timeList)[type]; while (list[next] && next !== now) { next = (next + step + total) % total; } return next; }; const modifyDateField = (type, value) => { const list = unref(timeList)[type]; const isDisabled = list[value]; if (isDisabled) return; const { hours, minutes, seconds } = unref(timePartials); let changeTo; switch (type) { case "hours": changeTo = props.spinnerDate.hour(value).minute(minutes).second(seconds); break; case "minutes": changeTo = props.spinnerDate.hour(hours).minute(value).second(seconds); break; case "seconds": changeTo = props.spinnerDate.hour(hours).minute(minutes).second(value); break; } emit("change", changeTo); }; const handleClick = (type, { value, disabled }) => { if (!disabled) { modifyDateField(type, value); emitSelectRange(type); adjustSpinner(type, value); } }; const handleScroll = (type) => { isScrolling = true; debouncedResetScroll(type); const value = Math.min(Math.round((getScrollbarElement(unref(listRefsMap[type]).$el).scrollTop - (scrollBarHeight(type) * 0.5 - 10) / typeItemHeight(type) + 3) / typeItemHeight(type)), type === "hours" ? 23 : 59); modifyDateField(type, value); }; const scrollBarHeight = (type) => { return unref(listRefsMap[type]).$el.offsetHeight; }; const bindScrollEvent = () => { const bindFunction = (type) => { const scrollbar = unref(listRefsMap[type]); if (scrollbar && scrollbar.$el) { getScrollbarElement(scrollbar.$el).onscroll = () => { handleScroll(type); }; } }; bindFunction("hours"); bindFunction("minutes"); bindFunction("seconds"); }; onMounted(() => { nextTick(() => { !props.arrowControl && bindScrollEvent(); adjustSpinners(); if (props.role === "start") emitSelectRange("hours"); }); }); const setRef = (scrollbar, type) => { listRefsMap[type].value = scrollbar; }; emit("set-option", [`${props.role}_scrollDown`, scrollDown]); emit("set-option", [`${props.role}_emitSelectRange`, emitSelectRange]); watch(() => props.spinnerDate, () => { if (isScrolling) return; adjustSpinners(); }); return (_ctx, _cache) => { return openBlock(), createElementBlock("div", { class: normalizeClass([unref(ns).b("spinner"), { "has-seconds": _ctx.showSeconds }]) }, [ !_ctx.arrowControl ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(unref(spinnerItems), (item) => { return openBlock(), createBlock(unref(ElScrollbar), { key: item, ref_for: true, ref: (scrollbar) => setRef(scrollbar, item), class: normalizeClass(unref(ns).be("spinner", "wrapper")), "wrap-style": "max-height: inherit;", "view-class": unref(ns).be("spinner", "list"), noresize: "", tag: "ul", onMouseenter: ($event) => emitSelectRange(item), onMousemove: ($event) => adjustCurrentSpinner(item) }, { default: withCtx(() => [ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(timeList)[item], (disabled, key) => { return openBlock(), createElementBlock("li", { key, class: normalizeClass([ unref(ns).be("spinner", "item"), unref(ns).is("active", key === unref(timePartials)[item]), unref(ns).is("disabled", disabled) ]), onClick: ($event) => handleClick(item, { value: key, disabled }) }, [ item === "hours" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [ createTextVNode(toDisplayString(("0" + (_ctx.amPmMode ? key % 12 || 12 : key)).slice(-2)) + toDisplayString(getAmPmFlag(key)), 1) ], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [ createTextVNode(toDisplayString(("0" + key).slice(-2)), 1) ], 64)) ], 10, ["onClick"]); }), 128)) ]), _: 2 }, 1032, ["class", "view-class", "onMouseenter", "onMousemove"]); }), 128)) : createCommentVNode("v-if", true), _ctx.arrowControl ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(unref(spinnerItems), (item) => { return openBlock(), createElementBlock("div", { key: item, class: normalizeClass([unref(ns).be("spinner", "wrapper"), unref(ns).is("arrow")]), onMouseenter: ($event) => emitSelectRange(item) }, [ withDirectives((openBlock(), createBlock(unref(ElIcon), { class: normalizeClass(["arrow-up", unref(ns).be("spinner", "arrow")]) }, { default: withCtx(() => [ createVNode(unref(ArrowUp)) ]), _: 1 }, 8, ["class"])), [ [unref(vRepeatClick), onDecrement] ]), withDirectives((openBlock(), createBlock(unref(ElIcon), { class: normalizeClass(["arrow-down", unref(ns).be("spinner", "arrow")]) }, { default: withCtx(() => [ createVNode(unref(ArrowDown)) ]), _: 1 }, 8, ["class"])), [ [unref(vRepeatClick), onIncrement] ]), createElementVNode("ul", { class: normalizeClass(unref(ns).be("spinner", "list")) }, [ (openBlock(true), createElementBlock(Fragment, null, renderList(unref(arrowControlTimeList)[item], (time, key) => { return openBlock(), createElementBlock("li", { key, class: normalizeClass([ unref(ns).be("spinner", "item"), unref(ns).is("active", time === unref(timePartials)[item]), unref(ns).is("disabled", unref(timeList)[item][time]) ]) }, [ typeof time === "number" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [ item === "hours" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [ createTextVNode(toDisplayString(("0" + (_ctx.amPmMode ? time % 12 || 12 : time)).slice(-2)) + toDisplayString(getAmPmFlag(time)), 1) ], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [ createTextVNode(toDisplayString(("0" + time).slice(-2)), 1) ], 64)) ], 64)) : createCommentVNode("v-if", true) ], 2); }), 128)) ], 2) ], 42, ["onMouseenter"]); }), 128)) : createCommentVNode("v-if", true) ], 2); }; } }); var TimeSpinner = /* @__PURE__ */ _export_sfc(_sfc_main, [["__file", "basic-time-spinner.vue"]]); export { TimeSpinner as default }; //# sourceMappingURL=basic-time-spinner.mjs.map