hongluan-ui
Version:
Hongluan Component Library for Vue 3
1 lines • 5.61 kB
Source Map (JSON)
{"version":3,"file":"affix.mjs","sources":["../../../../../../packages/components/affix/src/affix.vue"],"sourcesContent":["<template>\n <div ref=\"root\" :class=\"namespace\" :style=\"rootStyle\">\n <div :class=\"{'fixed': fixed}\" :style=\"affixStyle\">\n <slot></slot>\n </div>\n </div>\n</template>\n<script lang=\"ts\" setup>\nimport { computed, onMounted, ref, shallowRef, watch, watchEffect } from 'vue'\nimport {\n useEventListener,\n useElementBounding,\n useWindowSize,\n} from '@vueuse/core'\nimport { addUnit, getScrollContainer, throwError } from '@hongluan-ui/utils'\nimport { useNamespace } from '@hongluan-ui/hooks'\nimport { affixEmits, affixProps } from './affix'\nimport type { CSSProperties } from 'vue'\n\nconst COMPONENT_NAME = 'Affix'\ndefineOptions({\n name: COMPONENT_NAME,\n})\n\nconst props = defineProps(affixProps)\nconst emit = defineEmits(affixEmits)\n\nconst { namespace } = 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 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 rootStyle = computed<CSSProperties>(() => {\n return {\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 = props.offset ? addUnit(props.offset) : 0\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 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 if (props.position === 'top') {\n if (props.target) {\n const difference =\n targetRect.bottom.value - props.offset - rootHeight.value\n fixed.value = props.offset > rootTop.value && targetRect.bottom.value > 0\n transform.value = difference < 0 ? difference : 0\n } else {\n fixed.value = props.offset > rootTop.value\n }\n } else if (props.target) {\n const difference =\n windowHeight.value -\n targetRect.top.value -\n props.offset -\n rootHeight.value\n fixed.value =\n windowHeight.value - props.offset < rootBottom.value &&\n windowHeight.value > targetRect.top.value\n transform.value = difference < 0 ? -difference : 0\n } else {\n fixed.value = windowHeight.value - props.offset < rootBottom.value\n }\n}\n\nconst handleScroll = () => {\n updateRoot()\n emit('scroll', {\n scrollTop: scrollTop.value,\n fixed: fixed.value,\n })\n}\n\nwatch(fixed, val => emit('change', 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 existed: ${props.target}`)\n } else {\n target.value = document.documentElement\n }\n scrollContainer.value = getScrollContainer(root.value, true)\n updateRoot()\n})\n\nuseEventListener(scrollContainer, 'scroll', handleScroll)\nwatchEffect(update)\n\ndefineExpose({\n /** @description update affix status */\n update,\n /** @description update rootRect info */\n updateRoot,\n})\n</script>\n"],"names":[],"mappings":";;;;;;;;;;;oCAoBc;AAAA,EACZ,MAAM;AACR;;;;;;;AAKA,UAAM,EAAE,cAAc,aAAa,OAAO;AAE1C,UAAM,SAAS;AACf,UAAM,OAAO;AACb,UAAM,kBAAkB;AACxB,UAAM,EAAE,QAAQ,iBAAiB;AACjC,UAAM;AAAA,MACJ,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,QACN,mBAAmB,MAAM,EAAE,cAAc,OAAO;AACpD,UAAM,aAAa,mBAAmB,MAAM;AAE5C,UAAM,QAAQ,IAAI,KAAK;AACvB,UAAM,YAAY,IAAI,CAAC;AACvB,UAAM,YAAY,IAAI,CAAC;AAEvB,UAAM,YAAY,SAAwB,MAAM;AAC9C,aAAO;AAAA,QACL,QAAQ,MAAM,QAAQ,GAAG,WAAW,YAAY;AAAA,QAChD,OAAO,MAAM,QAAQ,GAAG,UAAU,YAAY;AAAA;AAChD,KACD;AAED,UAAM,aAAa,SAAwB,MAAM;AAC/C,UAAI,CAAC,MAAM;AAAO,eAAO;AAEzB,YAAM,SAAS,MAAM,SAAS,QAAQ,MAAM,MAAM,IAAI;AACtD,aAAO;AAAA,QACL,QAAQ,GAAG,WAAW;AAAA,QACtB,OAAO,GAAG,UAAU;AAAA,QACpB,KAAK,MAAM,aAAa,QAAQ,SAAS;AAAA,QACzC,QAAQ,MAAM,aAAa,WAAW,SAAS;AAAA,QAC/C,WAAW,UAAU,QAAQ,cAAc,UAAU,aAAa;AAAA,QAClE,QAAQ,MAAM;AAAA;AAChB,KACD;AAED,UAAM,SAAS,MAAM;AACnB,UAAI,CAAC,gBAAgB;AAAO;AAE5B,gBAAU,QACR,gBAAgB,iBAAiB,SAC7B,SAAS,gBAAgB,YACzB,gBAAgB,MAAM,aAAa;AAEzC,UAAI,MAAM,aAAa,OAAO;AAC5B,YAAI,MAAM,QAAQ;AAChB,gBAAM,aACJ,WAAW,OAAO,QAAQ,MAAM,SAAS,WAAW;AACtD,gBAAM,QAAQ,MAAM,SAAS,QAAQ,SAAS,WAAW,OAAO,QAAQ;AACxE,oBAAU,QAAQ,aAAa,IAAI,aAAa;AAAA,eAC3C;AACL,gBAAM,QAAQ,MAAM,SAAS,QAAQ;AAAA;AACvC,iBACS,MAAM,QAAQ;AACvB,cAAM,aACJ,aAAa,QACb,WAAW,IAAI,QACf,MAAM,SACN,WAAW;AACb,cAAM,QACJ,aAAa,QAAQ,MAAM,SAAS,WAAW,SAC/C,aAAa,QAAQ,WAAW,IAAI;AACtC,kBAAU,QAAQ,aAAa,IAAI,CAAC,aAAa;AAAA,aAC5C;AACL,cAAM,QAAQ,aAAa,QAAQ,MAAM,SAAS,WAAW;AAAA;AAC/D;AAGF,UAAM,eAAe,MAAM;AACzB;AACA,WAAK,UAAU;AAAA,QACb,WAAW,UAAU;AAAA,QACrB,OAAO,MAAM;AAAA,OACd;AAAA;AAGH,UAAM,OAAO,SAAO,KAAK,UAAU,GAAG,CAAC;AAEvC,cAAU,MAAM;AACd,UAAI;AACF,eAAO;AAEP,oBAAY;AACV;AAAqE;AAEvE;AAAwB;AAE1B;AACA;AAAW;AAGb;AACA;AAEA;AAAa;AAEX,MAEA;AAAA;;;;;;;;;;;;;;;;;;;;;;"}