UNPKG

vexip-ui

Version:

A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good

1 lines 16.6 kB
{"version":3,"file":"cascader-panel.vue2.cjs","sources":["../../../components/cascader/cascader-panel.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { Checkbox } from '@/components/checkbox'\nimport { Icon } from '@/components/icon'\nimport { Option } from '@/components/option'\nimport { VirtualList } from '@/components/virtual-list'\n\nimport { onBeforeUnmount, onMounted, ref, watch } from 'vue'\n\nimport { useIcons, useNameHelper } from '@vexip-ui/config'\nimport { useModifier, useRtl } from '@vexip-ui/hooks'\nimport { boundRange, decide } from '@vexip-ui/utils'\n\nimport type { PropType } from 'vue'\nimport type { VirtualListExposed } from '@/components/virtual-list'\nimport type { CascaderOptionState, CascaderPanelSlots } from './symbol'\n\ndefineOptions({ name: 'CascaderPanel' })\n\nconst props = defineProps({\n options: {\n type: Array as PropType<CascaderOptionState[]>,\n default: () => [],\n },\n openedId: {\n type: Number,\n default: null,\n },\n values: {\n type: Array as PropType<string[]>,\n default: () => [],\n },\n ready: {\n type: Boolean,\n default: false,\n },\n multiple: {\n type: Boolean,\n default: false,\n },\n checkIcon: {\n type: Object,\n default: null,\n },\n isAsync: {\n type: Boolean,\n default: false,\n },\n merged: {\n type: Boolean,\n default: false,\n },\n noCascaded: {\n type: Boolean,\n default: false,\n },\n visible: {\n type: Boolean,\n default: false,\n },\n labeledBy: {\n type: String,\n default: undefined,\n },\n})\n\nconst emit = defineEmits(['select', 'check', 'hover', 'open', 'back', 'close'])\n\ndefineSlots<CascaderPanelSlots>()\n\nconst nh = useNameHelper('cascader')\nconst icons = useIcons()\nconst { isRtl } = useRtl()\nconst currentHitting = ref(-1)\n\nconst list = ref<VirtualListExposed>()\n\nconst { target: wrapper } = useModifier({\n passive: false,\n onKeyDown: (event, modifier) => {\n if (modifier.escape) {\n emit('close')\n return\n }\n\n decide(\n [\n [\n () => modifier.up || modifier.down,\n () => {\n if (currentHitting.value < 0) {\n currentHitting.value = props.options.findIndex(isSelected)\n\n if (currentHitting.value < 0) {\n currentHitting.value = 0\n }\n\n return\n }\n\n currentHitting.value = boundRange(\n findEnabledIndex(currentHitting.value + (modifier.up ? -1 : 1), modifier.up ? -1 : 1),\n 0,\n props.options.length - 1,\n )\n ensureOptionInView(currentHitting.value, modifier.up ? 'top' : 'bottom')\n },\n ],\n [\n () => modifier.left || modifier.right,\n () => {\n if (modifier.right) {\n const option = props.options[currentHitting.value]\n\n if (option && hasChildren(option)) {\n emit('open', option)\n }\n } else {\n emit('back')\n }\n },\n ],\n [\n () => modifier.enter || modifier.space,\n () => {\n event.stopPropagation()\n\n const option = props.options[currentHitting.value]\n\n if (option) {\n if (props.multiple) {\n handleToggleCheck(option)\n } else {\n handleSelect(option, currentHitting.value)\n }\n }\n },\n ],\n ],\n {\n beforeMatchAny: () => event.preventDefault(),\n afterMatchAny: modifier.resetAll,\n },\n )\n },\n})\n\nlet listHeight = 0\nlet hoverTimer: ReturnType<typeof setTimeout>\n\nwatch([() => props.ready, () => props.options], () => {\n requestAnimationFrame(computeListHeight)\n\n if (props.ready) {\n list.value?.refresh()\n currentHitting.value = props.options.findIndex(isSelected)\n } else {\n currentHitting.value = -1\n }\n})\n\nonMounted(() => {\n requestAnimationFrame(computeListHeight)\n})\n\nonBeforeUnmount(handleMouseLeave)\n\ndefineExpose({ currentHitting })\n\nfunction hasChildren(option: CascaderOptionState) {\n return !!(option.hasChild || option.children?.length)\n}\n\nfunction isSelected(option: CascaderOptionState) {\n return (\n (hasChildren(option) && option.id === props.openedId) || props.values.includes(option.fullValue)\n )\n}\n\nfunction isCheckboxDisabled(option: CascaderOptionState) {\n return (\n option.disabled ||\n (!props.merged &&\n props.multiple &&\n props.isAsync &&\n hasChildren(option) &&\n !option.childrenLoaded)\n )\n}\n\nfunction handleSelect(option: CascaderOptionState, index: number) {\n if (option.disabled) return\n\n currentHitting.value = index\n\n if (props.multiple || props.noCascaded) {\n hasChildren(option) ? emit('select', option) : handleToggleCheck(option)\n } else {\n emit('select', option)\n }\n}\n\nfunction handleToggleCheck(option: CascaderOptionState) {\n !isCheckboxDisabled(option) && emit('check', option)\n}\n\nfunction handleMouseEnter(option: CascaderOptionState) {\n clearTimeout(hoverTimer)\n\n hoverTimer = setTimeout(() => {\n !option.disabled && emit('hover', option)\n }, 100)\n}\n\nfunction handleMouseLeave() {\n clearTimeout(hoverTimer)\n}\n\nfunction computeListHeight() {\n const el = list.value?.wrapper\n\n if (el) {\n const style = getComputedStyle(el)\n const paddingTop = parseInt(style.paddingTop)\n const paddingBottom = parseInt(style.paddingBottom)\n\n listHeight = el.offsetHeight - paddingTop - paddingBottom\n }\n}\n\nfunction queryEnabledIndex(index: number, step: number) {\n const options = props.options\n step = step / Math.abs(step)\n\n while (options[index]?.disabled) {\n index += step\n\n if (index < 0 || index >= options.length) break\n }\n\n return index\n}\n\nfunction findEnabledIndex(index: number, sign: 1 | -1 = 1) {\n const options = props.options\n\n if (options[index]?.disabled) {\n index = queryEnabledIndex(index, sign)\n\n if (sign > 0 ? index >= options.length : index < 0) {\n index = queryEnabledIndex(index, -sign)\n\n // 全禁用\n if (sign > 0 ? index < 0 : index >= options.length) index = -1\n }\n }\n\n return index\n}\n\nfunction ensureOptionInView(index: number, direction: 'top' | 'bottom') {\n const option = props.options[index]\n const optionHeight = 32\n\n if (!option || !list.value) return\n\n if (direction === 'bottom') {\n const target = (index + 1) * optionHeight\n\n if (list.value.scrollOffset + listHeight < target) {\n list.value.scrollTo(target - listHeight)\n }\n } else {\n const target = index * optionHeight\n\n if (list.value.scrollOffset > target) {\n list.value.scrollTo(target)\n }\n }\n}\n</script>\n\n<template>\n <div\n ref=\"wrapper\"\n :class=\"nh.be('panel')\"\n tabindex=\"-1\"\n :aria-labelledby=\"labeledBy\"\n @mouseleave=\"handleMouseLeave\"\n >\n <VirtualList\n ref=\"list\"\n inherit\n :items=\"options\"\n :item-size=\"32\"\n height=\"100%\"\n id-key=\"id\"\n :items-attrs=\"{\n class: [\n nh.be('options'),\n multiple ? nh.bem('options', 'multiple') : null,\n noCascaded ? nh.bem('options', 'no-cascaded') : null\n ],\n role: 'listbox',\n ariaMultiselectable: multiple\n }\"\n @resize=\"computeListHeight\"\n >\n <template #default=\"{ item, index }\">\n <Option\n :class=\"{\n [nh.ns('option--error')]: item.error\n }\"\n :value=\"item.value\"\n :label=\"item.label\"\n :disabled=\"item.disabled\"\n :selected=\"isSelected(item)\"\n :hitting=\"index === currentHitting\"\n @select=\"handleSelect(item, index)\"\n @mouseenter=\"handleMouseEnter(item)\"\n >\n <slot\n :option=\"item\"\n :index=\"index\"\n :selected=\"isSelected(item)\"\n :can-check=\"isCheckboxDisabled(item)\"\n :has-child=\"hasChildren(item)\"\n >\n <Checkbox\n v-if=\"multiple || noCascaded\"\n inherit\n :class=\"nh.be('checkbox')\"\n :checked=\"item.checked\"\n :control=\"hasChildren(item)\"\n :partial=\"item.partial\"\n :disabled=\"isCheckboxDisabled(item)\"\n size=\"small\"\n @click.prevent.stop=\"handleToggleCheck(item)\"\n ></Checkbox>\n <span :class=\"nh.be('label')\">\n <slot\n name=\"label\"\n :option=\"item\"\n :index=\"index\"\n :selected=\"isSelected(item)\"\n :can-check=\"isCheckboxDisabled(item)\"\n :has-child=\"hasChildren(item)\"\n :handle-select=\"() => handleSelect(item, index)\"\n >\n {{ item.label }}\n </slot>\n </span>\n <div :class=\"nh.be('icon')\">\n <Icon v-if=\"item.loading\" v-bind=\"icons.loading\"></Icon>\n <Icon v-else-if=\"item.error\" v-bind=\"icons.refresh\"></Icon>\n <template v-else-if=\"hasChildren(item)\">\n <Icon v-if=\"isRtl\" v-bind=\"icons.angleLeft\"></Icon>\n <Icon v-else v-bind=\"icons.angleRight\"></Icon>\n </template>\n <Icon\n v-else-if=\"!multiple && !noCascaded && checkIcon && values.includes(item.fullValue)\"\n v-bind=\"icons.check\"\n :icon=\"checkIcon || icons.check.icon\"\n ></Icon>\n </div>\n </slot>\n </Option>\n </template>\n </VirtualList>\n </div>\n</template>\n"],"names":["props","__props","emit","__emit","nh","useNameHelper","icons","useIcons","isRtl","useRtl","currentHitting","ref","list","wrapper","useModifier","event","modifier","decide","isSelected","boundRange","findEnabledIndex","ensureOptionInView","option","hasChildren","handleToggleCheck","handleSelect","listHeight","hoverTimer","watch","computeListHeight","_a","onMounted","onBeforeUnmount","handleMouseLeave","__expose","isCheckboxDisabled","index","handleMouseEnter","el","style","paddingTop","paddingBottom","queryEnabledIndex","step","options","sign","direction","optionHeight","target","_createElementBlock","_normalizeClass","_unref","_createVNode","VirtualList","_withCtx","item","Option","$event","_renderSlot","_ctx","_createBlock","Checkbox","_withModifiers","_createElementVNode","_createTextVNode","_toDisplayString","Icon","_normalizeProps","_mergeProps","_Fragment","_openBlock"],"mappings":"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"}