| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- import { defineComponent, inject, ref, computed, unref, onMounted, nextTick, watch, openBlock, createElementBlock, normalizeClass, Fragment, renderList, createBlock, withCtx, createTextVNode, toDisplayString, createCommentVNode, withDirectives, createVNode, createElementVNode } from 'vue';
- import { debounce } from 'lodash-unified';
- import { ElScrollbar } from '../../../scrollbar/index.mjs';
- import { ElIcon } from '../../../icon/index.mjs';
- import { ArrowUp, ArrowDown } from '@element-plus/icons-vue';
- import { PICKER_BASE_INJECTION_KEY, timeUnits, DEFAULT_FORMATS_TIME } 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 { vRepeatClick } from '../../../../directives/repeat-click/index.mjs';
- import { CHANGE_EVENT } from '../../../../constants/event.mjs';
- import { useNamespace } from '../../../../hooks/use-namespace/index.mjs';
- import { getStyle } from '../../../../utils/dom/style.mjs';
- import { isNumber } from '../../../../utils/types.mjs';
- const _sfc_main = /* @__PURE__ */ defineComponent({
- __name: "basic-time-spinner",
- props: basicTimeSpinnerProps,
- emits: [CHANGE_EVENT, "select-range", "set-option"],
- setup(__props, { emit }) {
- const props = __props;
- const pickerBase = inject(PICKER_BASE_INJECTION_KEY);
- const { isRange, format } = pickerBase.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);
- const { role, spinnerDate } = props;
- const compare = !isRange ? spinnerDate : void 0;
- return {
- hours: getHoursList(role, compare),
- minutes: getMinutesList(hours, role, compare),
- seconds: getSecondsList(hours, minutes, role, compare)
- };
- });
- 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 = [0, 0];
- const actualFormat = format || DEFAULT_FORMATS_TIME;
- const hourIndex = actualFormat.indexOf("HH");
- const minuteIndex = actualFormat.indexOf("mm");
- const secondIndex = actualFormat.indexOf("ss");
- switch (type) {
- case "hours":
- if (hourIndex !== -1) {
- range = [hourIndex, hourIndex + 2];
- }
- break;
- case "minutes":
- if (minuteIndex !== -1) {
- range = [minuteIndex, minuteIndex + 2];
- }
- break;
- case "seconds":
- if (secondIndex !== -1) {
- range = [secondIndex, secondIndex + 2];
- }
- 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_EVENT, changeTo);
- };
- const handleClick = (type, { value, disabled }) => {
- if (!disabled) {
- modifyDateField(type, value);
- emitSelectRange(type);
- adjustSpinner(type, value);
- }
- };
- const handleScroll = (type) => {
- const scrollbar = unref(listRefsMap[type]);
- if (!scrollbar)
- return;
- isScrolling = true;
- debouncedResetScroll(type);
- const value = Math.min(Math.round((getScrollbarElement(scrollbar.$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 != null ? scrollbar : void 0;
- };
- 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])
- ])
- }, [
- unref(isNumber)(time) ? (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
|