vexip-ui
Version:
A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good
1 lines • 10.4 kB
Source Map (JSON)
{"version":3,"file":"popup.vue2.cjs","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","_createElementBlock","_normalizeClass","_unref","_Fragment","_renderList","_createBlock","PopupItem","_normalizeStyle","$event","_withCtx","itemData","_renderSlot","_ctx"],"mappings":"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"}