{"version":3,"file":"notify.mjs","sources":["../../../../../packages/components/notification/src/notify.ts"],"sourcesContent":["import { createVNode, render } from 'vue'\nimport { isClient } from '@vueuse/core'\nimport { useZIndex } from '@element-ultra/hooks'\nimport { isVNode, debugWarn } from '@element-ultra/utils'\nimport NotificationConstructor from './notification.vue'\nimport { notificationTypes } from './notification'\n\nimport type { ComponentPublicInstance, VNode } from 'vue'\nimport type {\n  NotificationOptions,\n  Notify,\n  NotifyFn,\n  NotificationQueue,\n  NotificationProps,\n} from './notification'\n\n// This should be a queue but considering there were `non-autoclosable` notifications.\nconst notifications: Record<\n  NotificationOptions['position'],\n  NotificationQueue\n> = {\n  'top-left': [],\n  'top-right': [],\n  'bottom-left': [],\n  'bottom-right': [],\n}\n\n// the gap size between each notification\nconst GAP_SIZE = 16\nlet seed = 1\n\nconst notify: NotifyFn & Partial<Notify> = function (options = {}) {\n  if (!isClient) return { close: () => undefined }\n\n  if (typeof options === 'string' || isVNode(options)) {\n    options = { message: options }\n  }\n\n  const position = options.position || 'top-right'\n\n  let verticalOffset = options.offset || 0\n  notifications[position].forEach(({ vm }) => {\n    verticalOffset += (vm.el?.offsetHeight || 0) + GAP_SIZE\n  })\n  verticalOffset += GAP_SIZE\n\n  const { nextZIndex } = useZIndex()\n\n  const id = `notification_${seed++}`\n  const userOnClose = options.onClose\n  const props: Partial<NotificationProps> = {\n    // default options end\n    zIndex: nextZIndex(),\n    offset: verticalOffset,\n    ...options,\n    id,\n    onClose: () => {\n      close(id, position, userOnClose)\n    },\n  }\n\n  let appendTo: HTMLElement | null = document.body\n  if (options.appendTo instanceof HTMLElement) {\n    appendTo = options.appendTo\n  } else if (typeof options.appendTo === 'string') {\n    appendTo = document.querySelector(options.appendTo)\n  }\n\n  // should fallback to default value with a warning\n  if (!(appendTo instanceof HTMLElement)) {\n    debugWarn(\n      'ElNotification',\n      'the appendTo option is not an HTMLElement. Falling back to document.body.'\n    )\n    appendTo = document.body\n  }\n\n  const container = document.createElement('div')\n\n  const vm = createVNode(\n    NotificationConstructor,\n    props,\n    isVNode(props.message)\n      ? {\n          default: () => props.message,\n        }\n      : null\n  )\n\n  // clean notification element preventing mem leak\n  vm.props!.onDestroy = () => {\n    render(null, container)\n  }\n\n  // instances will remove this item when close function gets called. So we do not need to worry about it.\n  render(vm, container)\n  notifications[position].push({ vm })\n  appendTo.appendChild(container.firstElementChild!)\n\n  return {\n    // instead of calling the onClose function directly, setting this value so that we can have the full lifecycle\n    // for out component, so that all closing steps will not be skipped.\n    close: () => {\n      ;(\n        vm.component!.proxy as ComponentPublicInstance<{ visible: boolean }>\n      ).visible = false\n    },\n  }\n}\nnotificationTypes.forEach((type) => {\n  notify[type] = (options = {}) => {\n    if (typeof options === 'string' || isVNode(options)) {\n      options = {\n        message: options,\n      }\n    }\n    return notify({\n      ...options,\n      type,\n    })\n  }\n})\n\n/**\n * This function gets called when user click `x` button or press `esc` or the time reached its limitation.\n * Emitted by transition@before-leave event so that we can fetch the current notification.offsetHeight, if this was called\n * by @after-leave the DOM element will be removed from the page thus we can no longer fetch the offsetHeight.\n * @param {String} id notification id to be closed\n * @param {Position} position the positioning strategy\n * @param {Function} userOnClose the callback called when close passed by user\n */\nexport function close(\n  id: string,\n  position: NotificationOptions['position'],\n  userOnClose?: (vm: VNode) => void\n): void {\n  // maybe we can store the index when inserting the vm to notification list.\n  const orientedNotifications = notifications[position]\n  const idx = orientedNotifications.findIndex(\n    ({ vm }) => vm.component?.props.id === id\n  )\n  if (idx === -1) return\n  const { vm } = orientedNotifications[idx]\n  if (!vm) return\n  // calling user's on close function before notification gets removed from DOM.\n  userOnClose?.(vm)\n\n  // note that this is called @before-leave, that's why we were able to fetch this property.\n  const removedHeight = vm.el!.offsetHeight\n  const verticalPos = position.split('-')[0]\n  orientedNotifications.splice(idx, 1)\n  const len = orientedNotifications.length\n  if (len < 1) return\n  // starting from the removing item.\n  for (let i = idx; i < len; i++) {\n    // new position equals the current offsetTop minus removed height plus 16px(the gap size between each item)\n    const { el, component } = orientedNotifications[i].vm\n    const pos = parseInt(el!.style[verticalPos], 10) - removedHeight - GAP_SIZE\n    component!.props.offset = pos\n  }\n}\n\nexport function closeAll(): void {\n  // loop through all directions, close them at once.\n  for (const orientedNotifications of Object.values(notifications)) {\n    orientedNotifications.forEach(({ vm }) => {\n      // same as the previous close method, we'd like to make sure lifecycle gets handle properly.\n      ;(\n        vm.component!.proxy as ComponentPublicInstance<{ visible: boolean }>\n      ).visible = false\n    })\n  }\n}\n\nnotify.closeAll = closeAll\n\nexport default notify as Notify\n"],"names":["vm"],"mappings":"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"}