IndexAnchor.mjs 2.5 KB

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