UNPKG

@extclp/vexip-ui

Version:

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

1 lines 10.1 kB
{"version":3,"file":"popup.vue2.mjs","sources":["../../../components/popup/popup.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, provide, reactive, ref, watch } from 'vue'\n\nimport PopupItem from './popup-item.vue'\nimport { classProp, useNameHelper } from '@vexip-ui/config'\nimport { getGlobalCount, isFunction, noop } from '@vexip-ui/utils'\nimport { DELETE_HANDLER, popupPlacements } from './symbol'\n\nimport type { CSSProperties } from 'vue'\nimport type { Key, PopupItemState, PopupPlacement } from './symbol'\n\ntype QueueState =\n | {\n type: 'add',\n param: Record<string, unknown>\n }\n | {\n type: 'clear',\n param: Key\n }\n\ndefineOptions({ name: 'Popup' })\n\nconst props = defineProps({\n transitionName: {\n type: String,\n default: null\n },\n innerClass: {\n type: classProp,\n default: null\n },\n startOffset: {\n type: Number,\n default: 30\n },\n placement: {\n default: 'top-right' as PopupPlacement,\n validator: (value: PopupPlacement) => popupPlacements.includes(value)\n },\n itemOffset: {\n type: Number,\n default: 16\n },\n itemType: {\n type: Function\n }\n})\n\ndefineSlots<{ item: (item: any) => any }>()\n\nconst nh = useNameHelper('popup')\nconst items = ref<PopupItemState[]>([])\nconst queue: QueueState[] = []\n\nconst wrapper = ref<HTMLElement>()\n\nlet pending = false\n\nconst placementArray = computed(() => {\n return props.placement.split('-') as ['top' | 'bottom', 'right' | 'center' | 'left']\n})\nconst transition = computed(() => props.transitionName || nh.ns('popup-top'))\n\nwatch(\n () => props.startOffset,\n (value, prevValue) => {\n items.value.forEach(item => {\n item.verticalPosition += value - prevValue\n })\n }\n)\n\nprovide(DELETE_HANDLER, deleteItem)\n\ndefineExpose({\n items,\n wrapper,\n add,\n remove,\n has,\n find,\n clear\n})\n\nfunction getItemStyle(item: PopupItemState) {\n const [verticalStyle, horizontalStyle] = placementArray.value\n const style: CSSProperties = { [verticalStyle]: `${item.verticalPosition}px` }\n\n if (horizontalStyle === 'center') {\n style.left = '50%'\n style.transform = 'translateX(-50%)'\n } else {\n style[horizontalStyle] = '24px'\n }\n\n const zIndex = parseInt(item.zIndex as string)\n\n if (!Number.isNaN(zIndex)) {\n style.zIndex = zIndex\n }\n\n return style\n}\n\nfunction add(options: Record<string, any>) {\n return new Promise<Key>(resolve => {\n const onOpen = isFunction(options.onOpen) ? options.onOpen : noop\n\n options.onOpen = (key: Key) => {\n resolve(key)\n onOpen()\n }\n\n queue.push({\n type: 'add',\n param: options\n })\n\n if (!pending) {\n pending = true\n queueOut()\n }\n })\n}\n\nfunction remove(key: Key) {\n return new Promise<boolean>(resolve => {\n const item = find(key)\n\n if (!item) return resolve(false)\n\n const onClose = isFunction(item.onClose) ? item.onClose : noop\n\n item.onClose = (result: boolean) => {\n resolve(result)\n onClose(result)\n }\n\n queue.push({\n type: 'clear',\n param: key\n })\n\n if (!pending) {\n pending = true\n queueOut()\n }\n })\n}\n\nfunction queueOut() {\n if (queue.length) {\n const state = queue.shift()!\n\n if (state.type === 'add') {\n renderItem(state.param)\n } else {\n removeItem(state.param)\n }\n\n requestAnimationFrame(queueOut)\n } else {\n pending = false\n }\n}\n\nfunction renderItem(options: Record<string, any>) {\n let item = options.key ? find(options.key as Key) : null\n\n if (!item?.visible) {\n const index = getGlobalCount()\n const key = (options.key as Key) ?? nh.bs(`${index}`)\n\n let currentVertical = props.startOffset\n\n items.value.forEach(existingItem => {\n if (existingItem.visible) {\n currentVertical += existingItem.height + props.itemOffset\n }\n })\n\n item = reactive(\n Object.assign(\n {\n key,\n content: '',\n closable: false,\n onOpen: noop,\n onClose: noop,\n onEnter: noop,\n onLeave: noop\n },\n options,\n {\n height: 0,\n visible: true,\n verticalPosition: currentVertical\n }\n )\n )\n\n items.value.push(item)\n }\n\n // 使用 options 上的回调以防止重复 key 时指向不正确\n isFunction(options.onOpen) && options.onOpen(item.key)\n}\n\nfunction removeItem(key: Key) {\n const index = items.value.findIndex(item => item.key === key)\n\n if (~index) {\n const item = items.value[index]\n const removeHeight = item.height\n\n item.visible = false\n\n for (let i = index + 1, len = items.value.length; i < len; ++i) {\n items.value[i].verticalPosition -= removeHeight + props.itemOffset\n }\n\n // 关闭回调\n isFunction(item.onClose) && item.onClose(true)\n }\n}\n\nfunction deleteItem(key: Key) {\n const index = items.value.findIndex(item => item.key === key)\n\n if (~index) {\n items.value.splice(index, 1)\n }\n}\n\nfunction has(key: Key) {\n return !~items.value.findIndex(item => item.key === key)\n}\n\nfunction find(key: Key) {\n return items.value.find(item => item.key === key)\n}\n\nfunction clear() {\n queue.length = 0\n items.value = []\n}\n\nfunction enterItem(item: PopupItemState) {\n isFunction(item.onEnter) && item.onEnter()\n}\n\nfunction leaveItem(item: PopupItemState) {\n isFunction(item.onLeave) && item.onLeave()\n}\n</script>\n\n<template>\n <div :class=\"[nh.b(), nh.bm(placement)]\">\n <PopupItem\n v-for=\"item in items\"\n :key=\"item.key\"\n :state=\"item\"\n :transition-name=\"transition\"\n :inner-class=\"innerClass\"\n :style=\"getItemStyle(item)\"\n @enter=\"enterItem(item)\"\n @leave=\"leaveItem(item)\"\n >\n <template #default=\"{ item: itemData }\">\n <slot name=\"item\" :item=\"itemData\"></slot>\n </template>\n </PopupItem>\n </div>\n</template>\n"],"names":["props","__props","nh","useNameHelper","items","ref","queue","wrapper","pending","placementArray","computed","transition","watch","value","prevValue","item","provide","DELETE_HANDLER","deleteItem","__expose","add","remove","has","find","clear","getItemStyle","verticalStyle","horizontalStyle","style","zIndex","options","resolve","onOpen","isFunction","noop","key","queueOut","onClose","result","state","renderItem","removeItem","index","getGlobalCount","currentVertical","existingItem","reactive","removeHeight","i","len","enterItem","leaveItem"],"mappings":"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"}