{"version":3,"file":"notify.mjs","names":["NotificationConstructor"],"sources":["../../../../../../packages/components/notification/src/notify.ts"],"sourcesContent":["import { createVNode, isVNode, render } from 'vue'\nimport {\n  debugWarn,\n  isClient,\n  isElement,\n  isFunction,\n  isString,\n  isUndefined,\n} from '@element-plus/utils'\nimport NotificationConstructor from './notification.vue'\nimport { notificationTypes } from './notification'\n\nimport type { VNode } from 'vue'\nimport type {\n  NotificationExposed,\n  NotificationPosition,\n  NotificationProps,\n  NotificationQueue,\n  Notify,\n  NotifyFn,\n} from './notification'\n\n// This should be a queue but considering there were `non-autoclosable` notifications.\nconst notifications: Record<NotificationPosition, NotificationQueue> = {\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 = {}, context) {\n  if (!isClient) return { close: () => undefined }\n\n  if (isString(options) || 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 id = `notification_${seed++}`\n  const userOnClose = options.onClose\n  const props: Partial<NotificationProps> = {\n    ...options,\n    offset: verticalOffset,\n    id,\n    onClose: () => {\n      close(id, position, userOnClose)\n    },\n  }\n\n  let appendTo: HTMLElement | null = document.body\n  if (isElement(options.appendTo)) {\n    appendTo = options.appendTo\n  } else if (isString(options.appendTo)) {\n    appendTo = document.querySelector(options.appendTo)\n  }\n\n  // should fallback to default value with a warning\n  if (!isElement(appendTo)) {\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    isFunction(props.message)\n      ? props.message\n      : isVNode(props.message)\n        ? () => props.message\n        : null\n  )\n  vm.appContext = isUndefined(context) ? notify._context : context\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    // UPDATE: call the exposed close() here rather than setting visible.value = false,\n    // because close() also runs clearTimer() to stop the progress tick and close timeout.\n    close: () => {\n      ;(vm.component!.exposed as NotificationExposed).close()\n    },\n  }\n}\nnotificationTypes.forEach((type) => {\n  notify[type] = (options = {}, appContext) => {\n    if (isString(options) || isVNode(options)) {\n      options = {\n        message: options,\n      }\n    }\n    return notify({ ...options, type }, appContext)\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: NotificationPosition,\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 =\n      Number.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      // UPDATE: call exposed close() so that clearTimer() also runs.\n      ;(vm.component!.exposed as NotificationExposed).close()\n    })\n  }\n}\n\nexport function updateOffsets(position: NotificationPosition = 'top-right') {\n  let verticalOffset =\n    notifications[position][0]?.vm.component?.props?.offset || 0\n\n  for (const { vm } of notifications[position]) {\n    vm.component!.props.offset = verticalOffset\n    verticalOffset += (vm.el?.offsetHeight || 0) + GAP_SIZE\n  }\n}\n\nnotify.closeAll = closeAll\nnotify.updateOffsets = updateOffsets\nnotify._context = null\n\nexport default notify as Notify\n"],"mappings":"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"}