UNPKG

@fesjs/fes-design

Version:
161 lines (156 loc) 4.81 kB
import { defineComponent, ref, computed, watch, nextTick, onMounted, resolveComponent, openBlock, createBlock, withCtx, createElementVNode, normalizeClass, normalizeStyle, withModifiers, createElementBlock, Fragment, renderList, toDisplayString } from 'vue'; import getPrefixCls from '../_util/getPrefixCls'; import FScrollbar from '../scrollbar/scrollbar.js'; const prefixCls = getPrefixCls('time-picker'); const pickerItemProps = { visible: Boolean, value: { type: String, default: '' }, focus: { type: Number, default: -1 }, times: { type: Array, default() { return []; } }, visibleCount: { type: Number, default: 8 } }; var script = defineComponent({ components: { FScrollbar }, props: pickerItemProps, emits: ['change'], setup(props, _ref) { let { emit } = _ref; const rootRefEl = ref(); const itemHeight = 24; const scrollbarRef = ref(); const selectedIndex = computed(() => { if (props.value) { return props.times.findIndex(item => item.value === props.value); } return -1; }); const scrollToSelected = duration => { // move to selected ite const rootDom = rootRefEl.value; if (!rootDom) { return; } let index = selectedIndex.value; if (index < 0) { index = 0; } const to = rootDom.children[index].offsetTop; const firstTop = rootDom.children[0].offsetTop; scrollbarRef.value.setScrollTop(to - firstTop, duration); }; watch(selectedIndex, () => { nextTick(() => { scrollToSelected(120); }); }); watch(() => props.visible, () => { if (props.visible) { nextTick(() => { // scrollbarRef.value.update(); scrollToSelected(0); }); } }); const paddingBottom = computed(() => (props.visibleCount - 1) * itemHeight); const scrollToView = duration => { const index = props.focus; const rootDom = rootRefEl.value; if (!rootDom || index < 0) { return; } const scrollTop = rootDom.scrollTop; const offsetTop = rootDom.children[index].offsetTop; const difference = offsetTop - scrollTop; if (difference < 0) { scrollbarRef.value.setScrollTop(offsetTop, duration); } else if (difference > paddingBottom.value) { scrollbarRef.value.setScrollTop(scrollTop + (difference - paddingBottom.value), duration); } }; watch(() => props.focus, () => { nextTick(() => { scrollToView(0); }); }); const selectedTime = e => { if (!e.target) { return; } const key = e.target.getAttribute('data-key'); const option = props.times.find(item => item.value === key); if (option && !option.disabled) { emit('change', option); } }; onMounted(() => { nextTick(() => { scrollToSelected(0); }); }); const visibleHeight = computed(() => props.visibleCount * itemHeight); const style = computed(() => ({ 'padding-bottom': `${paddingBottom.value}px` })); return { visibleHeight, style, scrollbarRef, prefixCls, rootRefEl, selectedIndex, selectedTime }; } }); const _hoisted_1 = ["data-key"]; function render(_ctx, _cache, $props, $setup, $data, $options) { const _component_FScrollbar = resolveComponent("FScrollbar"); return openBlock(), createBlock(_component_FScrollbar, { ref: "scrollbarRef", height: _ctx.visibleHeight, noresize: "" }, { default: withCtx(() => [createElementVNode("ul", { ref: "rootRefEl", class: normalizeClass(`${_ctx.prefixCls}-content-item`), style: normalizeStyle(_ctx.style), onMousedown: _cache[0] || (_cache[0] = withModifiers(() => {}, ["prevent"])), onClick: _cache[1] || (_cache[1] = withModifiers(function () { return _ctx.selectedTime && _ctx.selectedTime(...arguments); }, ["stop"])) }, [(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.times, (item, index) => { return openBlock(), createElementBlock("li", { key: item.value, "data-key": item.value, class: normalizeClass({ [`${_ctx.prefixCls}-content-item-child`]: true, 'is-disabled': item.disabled, 'is-active': item.value === _ctx.value, 'is-focus': _ctx.focus === index }) }, toDisplayString(item.value), 11 /* TEXT, CLASS, PROPS */, _hoisted_1); }), 128 /* KEYED_FRAGMENT */))], 38 /* CLASS, STYLE, NEED_HYDRATION */)]), _: 1 /* STABLE */ }, 8 /* PROPS */, ["height"]); } script.render = render; script.__file = "components/time-picker/picker-item.vue"; export { script as default };