{"version":3,"file":"affix2.mjs","names":[],"sources":["../../../../../../packages/components/affix/src/affix.vue"],"sourcesContent":["<template>\n  <div ref=\"root\" :class=\"ns.b()\" :style=\"rootStyle\">\n    <el-teleport :disabled=\"teleportDisabled\" :to=\"appendTo\">\n      <div :class=\"{ [ns.m('fixed')]: fixed }\" :style=\"affixStyle\">\n        <slot />\n      </div>\n    </el-teleport>\n  </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport {\n  computed,\n  nextTick,\n  onActivated,\n  onDeactivated,\n  onMounted,\n  ref,\n  shallowRef,\n  watch,\n  watchEffect,\n} from 'vue'\nimport {\n  useElementBounding,\n  useEventListener,\n  useWindowSize,\n} from '@vueuse/core'\nimport ElTeleport from '@element-plus/components/teleport'\nimport { addUnit, getScrollContainer, throwError } from '@element-plus/utils'\nimport { useNamespace } from '@element-plus/hooks'\nimport { CHANGE_EVENT } from '@element-plus/constants'\nimport { affixEmits } from './affix'\n\nimport type { CSSProperties } from 'vue'\nimport type { AffixProps } from './affix'\n\nconst COMPONENT_NAME = 'ElAffix'\ndefineOptions({\n  name: COMPONENT_NAME,\n})\nconst props = withDefaults(defineProps<AffixProps>(), {\n  zIndex: 100,\n  target: '',\n  offset: 0,\n  position: 'top',\n  appendTo: 'body',\n})\nconst emit = defineEmits(affixEmits)\n\nconst ns = useNamespace('affix')\n\nconst target = shallowRef<HTMLElement>()\nconst root = shallowRef<HTMLDivElement>()\nconst scrollContainer = shallowRef<HTMLElement | Window>()\nconst { height: windowHeight } = useWindowSize()\nconst {\n  height: rootHeight,\n  width: rootWidth,\n  top: rootTop,\n  bottom: rootBottom,\n  left: rootLeft,\n  update: updateRoot,\n} = useElementBounding(root, { windowScroll: false })\nconst targetRect = useElementBounding(target)\n\nconst fixed = ref(false)\nconst scrollTop = ref(0)\nconst transform = ref(0)\n\nconst teleportDisabled = computed(() => {\n  return !props.teleported || !fixed.value\n})\n\nconst rootStyle = computed<CSSProperties>(() => {\n  return {\n    display: 'flow-root', // https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Display/Formatting_contexts#explicitly_creating_a_bfc_using_display_flow-root\n    height: fixed.value ? `${rootHeight.value}px` : '',\n    width: fixed.value ? `${rootWidth.value}px` : '',\n  }\n})\n\nconst affixStyle = computed<CSSProperties>(() => {\n  if (!fixed.value) return {}\n\n  const offset = addUnit(props.offset)\n  return {\n    height: `${rootHeight.value}px`,\n    width: `${rootWidth.value}px`,\n    top: props.position === 'top' ? offset : '',\n    bottom: props.position === 'bottom' ? offset : '',\n    left: props.teleported ? `${rootLeft.value}px` : '',\n    transform: transform.value ? `translateY(${transform.value}px)` : '',\n    zIndex: props.zIndex,\n  }\n})\n\nconst update = () => {\n  if (!scrollContainer.value) return\n\n  scrollTop.value =\n    scrollContainer.value instanceof Window\n      ? document.documentElement.scrollTop\n      : scrollContainer.value.scrollTop || 0\n\n  const { position, target, offset } = props\n  const rootHeightOffset = offset + rootHeight.value\n\n  if (position === 'top') {\n    if (target) {\n      const difference = targetRect.bottom.value - rootHeightOffset\n      fixed.value = offset > rootTop.value && targetRect.bottom.value > 0\n      transform.value = difference < 0 ? difference : 0\n    } else {\n      fixed.value = offset > rootTop.value\n    }\n  } else if (target) {\n    const difference =\n      windowHeight.value - targetRect.top.value - rootHeightOffset\n    fixed.value =\n      windowHeight.value - offset < rootBottom.value &&\n      windowHeight.value > targetRect.top.value\n    transform.value = difference < 0 ? -difference : 0\n  } else {\n    fixed.value = windowHeight.value - offset < rootBottom.value\n  }\n}\n\nconst updateRootRect = async () => {\n  if (!fixed.value) {\n    updateRoot()\n    return\n  }\n\n  fixed.value = false\n  await nextTick()\n  updateRoot()\n  fixed.value = true\n}\n\nconst handleScroll = async () => {\n  updateRoot()\n  await nextTick()\n  emit('scroll', {\n    scrollTop: scrollTop.value,\n    fixed: fixed.value,\n  })\n}\n\nwatch(fixed, (val) => emit(CHANGE_EVENT, val))\n\nonMounted(() => {\n  if (props.target) {\n    target.value =\n      document.querySelector<HTMLElement>(props.target) ?? undefined\n    if (!target.value)\n      throwError(COMPONENT_NAME, `Target does not exist: ${props.target}`)\n  } else {\n    target.value = document.documentElement\n  }\n  scrollContainer.value = getScrollContainer(root.value!, true)\n  updateRoot()\n})\n\nonActivated(() => {\n  nextTick(updateRootRect)\n})\n\nonDeactivated(() => {\n  fixed.value = false\n})\n\nuseEventListener(scrollContainer, 'scroll', handleScroll)\nwatchEffect(update)\n\ndefineExpose({\n  /** @description update affix status */\n  update,\n  /** @description update rootRect info */\n  updateRoot: updateRootRect,\n})\n</script>\n"],"mappings":""}