IndexAnchor.mjs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import { ref, reactive, computed, defineComponent, createVNode as _createVNode } from "vue";
  2. import { extend, numericProp, BORDER_BOTTOM, getZIndexStyle, createNamespace } from "../utils/index.mjs";
  3. import { INDEX_BAR_KEY } from "../index-bar/IndexBar.mjs";
  4. import { getScrollTop, getRootScrollTop } from "../utils/dom.mjs";
  5. import { useRect, useParent } from "@vant/use";
  6. import { useExpose } from "../composables/use-expose.mjs";
  7. const [name, bem] = createNamespace("index-anchor");
  8. const indexAnchorProps = {
  9. index: numericProp
  10. };
  11. var stdin_default = defineComponent({
  12. name,
  13. props: indexAnchorProps,
  14. setup(props, {
  15. slots
  16. }) {
  17. const state = reactive({
  18. top: 0,
  19. left: null,
  20. rect: {
  21. top: 0,
  22. height: 0
  23. },
  24. width: null,
  25. active: false
  26. });
  27. const root = ref();
  28. const {
  29. parent
  30. } = useParent(INDEX_BAR_KEY);
  31. if (!parent) {
  32. if (process.env.NODE_ENV !== "production") {
  33. console.error("[Vant] <IndexAnchor> must be a child component of <IndexBar>.");
  34. }
  35. return;
  36. }
  37. const isSticky = () => state.active && parent.props.sticky;
  38. const anchorStyle = computed(() => {
  39. const {
  40. zIndex,
  41. highlightColor
  42. } = parent.props;
  43. if (isSticky()) {
  44. return extend(getZIndexStyle(zIndex), {
  45. left: state.left ? `${state.left}px` : void 0,
  46. width: state.width ? `${state.width}px` : void 0,
  47. transform: state.top ? `translate3d(0, ${state.top}px, 0)` : void 0,
  48. color: highlightColor
  49. });
  50. }
  51. });
  52. const getRect = (scrollParent, scrollParentRect) => {
  53. const rootRect = useRect(root);
  54. state.rect.height = rootRect.height;
  55. if (scrollParent === window || scrollParent === document.body) {
  56. state.rect.top = rootRect.top + getRootScrollTop();
  57. } else {
  58. state.rect.top = rootRect.top + getScrollTop(scrollParent) - scrollParentRect.top;
  59. }
  60. return state.rect;
  61. };
  62. useExpose({
  63. state,
  64. getRect
  65. });
  66. return () => {
  67. const sticky = isSticky();
  68. return _createVNode("div", {
  69. "ref": root,
  70. "style": {
  71. height: sticky ? `${state.rect.height}px` : void 0
  72. }
  73. }, [_createVNode("div", {
  74. "style": anchorStyle.value,
  75. "class": [bem({
  76. sticky
  77. }), {
  78. [BORDER_BOTTOM]: sticky
  79. }]
  80. }, [slots.default ? slots.default() : props.index])]);
  81. };
  82. }
  83. });
  84. export {
  85. stdin_default as default,
  86. indexAnchorProps
  87. };