{"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 { Ref, VNode } from 'vue'\nimport type {\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    close: () => {\n      ;(vm.component!.exposed as { visible: Ref<boolean> }).visible.value =\n        false\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      ;(vm.component!.exposed as { visible: Ref<boolean> }).visible.value =\n        false\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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"}