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