Skip to content

Commit

Permalink
feat: finish indexbar
Browse files Browse the repository at this point in the history
  • Loading branch information
BeADre committed Jan 19, 2021
1 parent d3c66bb commit 923aa37
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 18 deletions.
24 changes: 15 additions & 9 deletions packages/varlet-ui/src/index-anchor/IndexAnchor.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
<template>
<var-sticky v-if="active === name && sticky" :z-index="zIndex" :offset-top="stickyOffsetTop">
<div class="var-index-anchor" ref="anchorEl" v-bind="$attrs">
<var-sticky :z-index="zIndex" ref="anchorEl" :offset-top="stickyOffsetTop">
<div class="var-index-anchor" v-bind="$attrs">
<slot>{{ name }}</slot>
</div>
</var-sticky>
<div class="var-index-anchor" ref="anchorEl" v-bind="$attrs" v-else :style="{ zIndex: zIndex + 1 }">
<slot>{{ name }}</slot>
</div>
</template>

<script lang="ts">
import { computed, ComputedRef, defineComponent, ref, Ref } from 'vue'
import { computed, ComputedRef, defineComponent, ref, Ref, RendererNode } from 'vue'
import Sticky from '../sticky'
import { useParent, useAtParentIndex } from '../utils/components'
import { IndexAnchorProvider } from './provide'
Expand All @@ -29,21 +26,30 @@ export default defineComponent({
inheritAttrs: false,
props,
setup(props) {
const ownTop: Ref<number> = ref(0)
const name: ComputedRef<number | string | undefined> = computed(() => props.index)
const anchorEl: Ref<HTMLDivElement | null> = ref(null)
const anchorEl: Ref<RendererNode | null> = ref(null)
const { parentProvider: IndexBarProvider, bindParent } = useParent<IndexBarProvider, IndexAnchorProvider>(
INDEX_BAR_BIND_INDEX_ANCHOR_KEY
)
if (!IndexBarProvider || !bindParent) {
console.error('[Varlet] IndexAnchor: You should use this component in "IndexBar"')
return
}
const { active, sticky, stickyOffsetTop, zIndex } = IndexBarProvider
const { index } = useAtParentIndex(INDEX_BAR_COUNT_INDEX_ANCHOR_KEY)
const getTop = (): number => (anchorEl.value as HTMLDivElement).offsetTop
const setOwnTop = () => {
ownTop.value = (anchorEl.value as RendererNode).$el.offsetTop
}
const indexAnchorProvider: IndexAnchorProvider = {
index,
name,
getTop,
ownTop,
setOwnTop,
}
bindParent(indexAnchorProvider)
Expand Down
7 changes: 4 additions & 3 deletions packages/varlet-ui/src/index-anchor/provide.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { ComputedRef } from 'vue'
import { ComputedRef, Ref } from 'vue'

export interface IndexAnchorProvider {
index: ComputedRef<number>
index: ComputedRef<number> | null
name: ComputedRef<string | number | undefined>
getTop: () => number
ownTop: Ref<number>
setOwnTop: () => void
}
15 changes: 9 additions & 6 deletions packages/varlet-ui/src/index-bar/IndexBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</template>

<script lang="ts">
import { computed, ComputedRef, defineComponent, nextTick, ref, Ref, watch } from 'vue'
import { computed, ComputedRef, defineComponent, nextTick, ref, Ref, watch, onMounted } from 'vue'
import { useChildren, useAtChildrenCounter } from '../utils/components'
import { isBaseObject } from '../utils/shared'
import { IndexBarProvider, INDEX_BAR_BIND_INDEX_ANCHOR_KEY, INDEX_BAR_COUNT_INDEX_ANCHOR_KEY } from './provide'
Expand Down Expand Up @@ -50,9 +50,7 @@ export default defineComponent({
bindChildren(indexBarProvider)
const emitEvent = (anchor: IndexAnchorProvider | number | string) => {
// const anchorName = typeof anchor === 'object' ? anchor.name.value : anchor
const anchorName = isBaseObject(anchor) ? anchor.name.value : anchor
// console.log(typeof '233')
if (anchorName === props.active) return
props['onUpdate:active']?.(anchorName)
props.onChange?.(anchorName)
Expand All @@ -61,7 +59,7 @@ export default defineComponent({
const handleScroll = () => {
const { scrollTop } = barEl.value as HTMLDivElement
IndexAnchorProviders.forEach((anchor: IndexAnchorProvider, index: number) => {
const anchorTop = anchor.getTop()
const anchorTop = anchor.ownTop.value
const top = scrollTop - anchorTop + stickyOffsetTop.value
if (top >= 0 && top <= 10) {
Expand All @@ -72,11 +70,12 @@ export default defineComponent({
}
})
}
//
const anchorClick = (anchorName: string | number) => {
if (anchorName === active.value) return
const indexAnchor = IndexAnchorProviders.find(({ name }: IndexAnchorProvider) => anchorName === name.value)
if (!indexAnchor) return
const top = indexAnchor.getTop()
const top = indexAnchor.ownTop.value
const { scrollLeft } = barEl.value as HTMLDivElement
;(barEl.value as HTMLDivElement).scrollTo(scrollLeft, top)
emitEvent(anchorName)
Expand All @@ -92,6 +91,10 @@ export default defineComponent({
})
)
onMounted(() => {
IndexAnchorProviders.forEach(({ setOwnTop }) => setOwnTop())
})
return {
barEl,
anchorNameList,
Expand Down

0 comments on commit 923aa37

Please sign in to comment.