UNPKG

element-plus

Version:

A Component Library for Vue 3

1 lines 12.6 kB
{"version":3,"file":"anchor.vue2.mjs","sources":["../../../../../../packages/components/anchor/src/anchor.vue"],"sourcesContent":["<template>\n <div ref=\"anchorRef\" :class=\"cls\">\n <div\n v-if=\"marker\"\n ref=\"markerRef\"\n :class=\"ns.e('marker')\"\n :style=\"markerStyle\"\n />\n <div :class=\"ns.e('list')\">\n <slot />\n </div>\n </div>\n</template>\n\n<script lang=\"ts\" setup>\nimport {\n computed,\n nextTick,\n onMounted,\n provide,\n ref,\n useSlots,\n watch,\n} from 'vue'\nimport { useEventListener } from '@vueuse/core'\nimport { useNamespace } from '@element-plus/hooks'\nimport {\n animateScrollTo,\n getElement,\n getOffsetTopDistance,\n getScrollElement,\n getScrollTop,\n isUndefined,\n isWindow,\n throttleByRaf,\n} from '@element-plus/utils'\nimport { CHANGE_EVENT } from '@element-plus/constants'\nimport { anchorEmits } from './anchor'\nimport { anchorKey } from './constants'\n\nimport type { CSSProperties } from 'vue'\nimport type { AnchorProps } from './anchor'\nimport type { AnchorLinkState } from './constants'\n\ndefineOptions({\n name: 'ElAnchor',\n})\n\nconst props = withDefaults(defineProps<AnchorProps>(), {\n offset: 0,\n bound: 15,\n duration: 300,\n marker: true,\n type: 'default',\n direction: 'vertical',\n})\nconst emit = defineEmits(anchorEmits)\nconst slots = useSlots()\n\nconst currentAnchor = ref('')\nconst markerStyle = ref<CSSProperties>({})\nconst anchorRef = ref<HTMLElement | null>(null)\nconst markerRef = ref<HTMLElement | null>(null)\nconst containerEl = ref<HTMLElement | Window>()\n\nconst links: Record<string, HTMLElement> = {}\nlet isScrolling = false\nlet currentScrollTop = 0\n\nconst ns = useNamespace('anchor')\n\nconst cls = computed(() => [\n ns.b(),\n props.type === 'underline' ? ns.m('underline') : '',\n ns.m(props.direction),\n])\n\nconst addLink = (state: AnchorLinkState) => {\n links[state.href] = state.el\n}\n\nconst removeLink = (href: string) => {\n delete links[href]\n}\n\nconst setCurrentAnchor = (href: string) => {\n const activeHref = currentAnchor.value\n if (activeHref !== href) {\n currentAnchor.value = href\n emit(CHANGE_EVENT, href)\n }\n}\n\nlet clearAnimate: (() => void) | null = null\nlet currentTargetHref = ''\n\nconst scrollToAnchor = (href: string) => {\n if (!containerEl.value) return\n const target = getElement(href)\n if (!target) return\n\n if (clearAnimate) {\n if (currentTargetHref === href) return\n clearAnimate()\n }\n\n currentTargetHref = href\n isScrolling = true\n const scrollEle = getScrollElement(target, containerEl.value)\n const distance = getOffsetTopDistance(target, scrollEle)\n const max = scrollEle.scrollHeight - scrollEle.clientHeight\n const to = Math.min(distance - props.offset, max)\n clearAnimate = animateScrollTo(\n containerEl.value,\n currentScrollTop,\n to,\n props.duration,\n () => {\n // make sure it is executed after throttleByRaf's handleScroll\n setTimeout(() => {\n isScrolling = false\n currentTargetHref = ''\n }, 20)\n }\n )\n}\n\nconst scrollTo = (href?: string) => {\n if (href) {\n setCurrentAnchor(href)\n scrollToAnchor(href)\n }\n}\n\nconst handleClick = (e: MouseEvent, href?: string) => {\n emit('click', e, href)\n scrollTo(href)\n}\n\nconst handleScroll = throttleByRaf(() => {\n if (containerEl.value) {\n currentScrollTop = getScrollTop(containerEl.value)\n }\n const currentHref = getCurrentHref()\n if (isScrolling || isUndefined(currentHref)) return\n setCurrentAnchor(currentHref)\n})\n\nconst getCurrentHref = () => {\n if (!containerEl.value) return\n const scrollTop = getScrollTop(containerEl.value)\n const anchorTopList: { top: number; href: string }[] = []\n\n for (const href of Object.keys(links)) {\n const target = getElement(href)\n if (!target) continue\n const scrollEle = getScrollElement(target, containerEl.value)\n const distance = getOffsetTopDistance(target, scrollEle)\n anchorTopList.push({\n top: distance - props.offset - props.bound,\n href,\n })\n }\n anchorTopList.sort((prev, next) => prev.top - next.top)\n for (let i = 0; i < anchorTopList.length; i++) {\n const item = anchorTopList[i]\n const next = anchorTopList[i + 1]\n\n if (i === 0 && scrollTop === 0) {\n return props.selectScrollTop ? item.href : ''\n }\n if (item.top <= scrollTop && (!next || next.top > scrollTop)) {\n return item.href\n }\n }\n}\n\nconst getContainer = () => {\n const el = getElement(props.container)\n if (!el || isWindow(el)) {\n containerEl.value = window\n } else {\n containerEl.value = el\n }\n}\n\nuseEventListener(containerEl, 'scroll', handleScroll)\n\nconst updateMarkerStyle = () => {\n nextTick(() => {\n if (!anchorRef.value || !markerRef.value || !currentAnchor.value) {\n markerStyle.value = {}\n return\n }\n const currentLinkEl = links[currentAnchor.value]\n if (!currentLinkEl) {\n markerStyle.value = {}\n return\n }\n const anchorRect = anchorRef.value.getBoundingClientRect()\n const markerRect = markerRef.value.getBoundingClientRect()\n const linkRect = currentLinkEl.getBoundingClientRect()\n\n if (props.direction === 'horizontal') {\n const left = linkRect.left - anchorRect.left\n markerStyle.value = {\n left: `${left}px`,\n width: `${linkRect.width}px`,\n opacity: 1,\n }\n } else {\n const top =\n linkRect.top -\n anchorRect.top +\n (linkRect.height - markerRect.height) / 2\n markerStyle.value = {\n top: `${top}px`,\n opacity: 1,\n }\n }\n })\n}\n\nwatch(currentAnchor, updateMarkerStyle)\nwatch(() => slots.default?.(), updateMarkerStyle)\n\nonMounted(() => {\n getContainer()\n const hash = decodeURIComponent(window.location.hash)\n const target = getElement(hash)\n if (target) {\n scrollTo(hash)\n } else {\n handleScroll()\n }\n})\n\nwatch(\n () => props.container,\n () => {\n getContainer()\n }\n)\n\nprovide(anchorKey, {\n ns,\n direction: props.direction,\n currentAnchor,\n addLink,\n removeLink,\n handleClick,\n})\n\ndefineExpose({\n scrollTo,\n})\n</script>\n"],"names":["_createElementBlock","_normalizeClass","_unref","_createElementVNode","_renderSlot"],"mappings":"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"}