Skip to content

Commit

Permalink
fix(ui/tabs): fix bug of tabs scrolling fail in the safari
Browse files Browse the repository at this point in the history
affects: @varlet/ui
  • Loading branch information
haoziqaq committed May 21, 2021
1 parent fbe50a6 commit 3e96046
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 12 deletions.
12 changes: 6 additions & 6 deletions packages/varlet-ui/src/tabs/Tabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ import {
import { props } from './props'
import { TabsProvider, useTabList } from './provide'
import { TabProvider } from '../tab/provide'
import { isNumber } from '../utils/shared'
import { toSizeUnit } from '../utils/elements'
import { easeInOutCubic, isNumber, linear } from '../utils/shared'
import { toSizeUnit, scrollTo } from '../utils/elements'
export default defineComponent({
name: 'VarTabs',
Expand Down Expand Up @@ -136,15 +136,15 @@ export default defineComponent({
if (props.layoutDirection === 'horizontal') {
const left: number = el.offsetLeft + el.offsetWidth / 2 - scroller.offsetWidth / 2
scroller.scrollTo({
scrollTo(scroller, {
left,
behavior: 'smooth',
animation: linear,
})
} else {
const top: number = el.offsetTop + el.offsetHeight / 2 - scroller.offsetHeight / 2
scroller.scrollTo({
scrollTo(scroller, {
top,
behavior: 'smooth',
animation: linear,
})
}
}
Expand Down
30 changes: 29 additions & 1 deletion packages/varlet-ui/src/utils/elements.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isNumber, isString, toNumber } from './shared'
import { easeInOutCubic, isNumber, isString, toNumber } from './shared'

export function getTop(element: HTMLElement): number {
const { top } = element.getBoundingClientRect()
Expand Down Expand Up @@ -128,3 +128,31 @@ export function nextTickFrame(fn: FrameRequestCallback) {
requestAnimationFrame(fn)
})
}

interface ScrollToOptions {
top?: number
left?: number
duration?: number
animation: (progress: number) => number
}

export function scrollTo(element: HTMLElement, { top = 0, left = 0, duration = 300, animation }: ScrollToOptions) {
const startTime = Date.now()
const { scrollTop, scrollLeft } = element

const frame = () => {
const progress = (Date.now() - startTime) / duration

if (progress < 1) {
const nextTop = scrollTop + (top - scrollTop) * animation(progress)
const nextLeft = scrollLeft + (left - scrollLeft) * animation(progress)

element.scrollTo(nextLeft, nextTop)
requestAnimationFrame(frame)
} else {
element.scrollTo(left, top)
}
}

requestAnimationFrame(frame)
}
5 changes: 0 additions & 5 deletions packages/varlet-ui/src/utils/jest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,6 @@ export function trigger(
return nextTick()
}

export function scrollTo(top: number) {
Object.defineProperty(window, 'scrollTop', { value: top, writable: true })
return trigger(window, 'scroll')
}

export function mockOffset() {
Object.defineProperties(HTMLElement.prototype, {
offsetWidth: {
Expand Down
2 changes: 2 additions & 0 deletions packages/varlet-ui/src/utils/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ export const createCache = <T>(max: number): CacheInstance<T> => {
}
}

export const linear = (value: number): number => value

export const cubic = (value: number): number => value ** 3

export const easeInOutCubic = (value: number): number =>
Expand Down

0 comments on commit 3e96046

Please sign in to comment.