Skip to content

Commit

Permalink
feat(comp:tabs): add onBeforeLeave prop (#965)
Browse files Browse the repository at this point in the history
  • Loading branch information
liuzaijiang committed Jun 21, 2022
1 parent 5db6616 commit 9a792e3
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 8 deletions.
34 changes: 33 additions & 1 deletion packages/components/tabs/__tests__/tabs.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { MountingOptions, mount } from '@vue/test-utils'
import { h } from 'vue'

import { renderWork } from '@tests'
import { renderWork, wait } from '@tests'

import Tab from '../src/Tab'
import Tabs from '../src/Tabs'
Expand Down Expand Up @@ -201,5 +201,37 @@ describe('Tabs', () => {

expect(wrapper.findAll('.ix-tabs-pane').length).toBe(2)
})

test('onBeforeLeave work', async () => {
const onUpdateSelectedKey = vi.fn()
const wrapper = TabsMount({
props: {
selectedKey: 'tab3',
'onUpdate:selectedKey': onUpdateSelectedKey,
onBeforeLeave: key => {
switch (key) {
case 'tab1':
return false
case 'tab2':
return new Promise(resolve => {
setTimeout(() => {
resolve(true)
}, 1000)
}) as Promise<boolean>
default:
return true
}
},
},
})

const tabs = wrapper.findAll('.ix-tabs-nav-tab')
await tabs[0].trigger('click')
expect(onUpdateSelectedKey).toBeCalledTimes(0)
await tabs[1].trigger('click')
expect(onUpdateSelectedKey).toBeCalledTimes(0)
await wait(1000)
expect(onUpdateSelectedKey).toBeCalledWith('tab2')
})
})
})
1 change: 1 addition & 0 deletions packages/components/tabs/docs/Index.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ order: 0
| `onTabClick` | 标签被点击的回调 | `(key: VKey, evt: Event) => void`| - | - | - |
| `onPreClick` | 滚动状态下,Pre按钮被点击的回调 | `(evt: Event) => void`| - | - | - |
| `onNextClick` | 滚动状态下,Next按钮被点击的回调 | `(evt: Event) => void`| - | - | - |
| `onBeforeLeave` | 切换标签之前的钩子函数,返回 `false` 或 promise resolve `false` 或 promise reject 会阻止切换 | `(key: VKey, oldKey?: VKey) => boolean \| Promise<boolean>`| - | - | - |

#### IxTabProps

Expand Down
16 changes: 10 additions & 6 deletions packages/components/tabs/src/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type { ComputedRef, Ref, VNode } from 'vue'

import { computed, defineComponent, nextTick, normalizeClass, provide, ref, vShow, watch, withDirectives } from 'vue'

import { curry, isNil, throttle } from 'lodash-es'
import { curry, isNil } from 'lodash-es'

import { useResizeObserver } from '@idux/cdk/resize'
import { addClass, callEmit, flattenNode, removeClass, useControlledProp } from '@idux/cdk/utils'
Expand Down Expand Up @@ -89,9 +89,13 @@ export default defineComponent({
const navPreClasses = curryNavPreNextClasses('pre', preReached)
const navNextClasses = curryNavPreNextClasses('next', nextReached)

const handleTabClick = (key: VKey, evt: Event) => {
callEmit(props.onTabClick, key, evt)
setSelectedKey(key)
const handleTabClick = async (key: VKey, evt: Event) => {
const leaveResult = callEmit(props.onBeforeLeave, key, selectedKey.value)
const result = await leaveResult
if (result !== false) {
callEmit(props.onTabClick, key, evt)
setSelectedKey(key)
}
}

const updateNavBarStyle = () => {
Expand Down Expand Up @@ -162,7 +166,7 @@ export default defineComponent({
updateNavBarStyle()
})

const onTabsResize = throttle(() => {
const onTabsResize = () => {
syncNavRelatedElSize()
if (hasScroll.value) {
//存在滚动状态时,因为会增加前进、后退两个按钮,所以需要重新获取navWrapper宽度
Expand All @@ -175,7 +179,7 @@ export default defineComponent({
} else {
updateNavBarStyle()
}
}, 10)
}

useResizeObserver(navWrapperElRef, onTabsResize)

Expand Down
2 changes: 1 addition & 1 deletion packages/components/tabs/src/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface TabsContext {
selectedKey: Ref<VKey | undefined>
selectedElRef: Ref<HTMLElement | null>
mergedPrefixCls: ComputedRef<string>
handleTabClick: (key: VKey, evt: Event) => void
handleTabClick: (key: VKey, evt: Event) => Promise<void>
}

export const tabsToken: InjectionKey<TabsContext> = Symbol('tabsToken')
1 change: 1 addition & 0 deletions packages/components/tabs/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const tabsProps = {
onTabClick: [Function, Array] as PropType<MaybeArray<(key: VKey, evt: Event) => void>>,
onPreClick: [Function, Array] as PropType<MaybeArray<(evt: Event) => void>>,
onNextClick: [Function, Array] as PropType<MaybeArray<(evt: Event) => void>>,
onBeforeLeave: [Function, Array] as PropType<MaybeArray<(key: VKey, oldKey?: VKey) => boolean | Promise<boolean>>>,
} as const

export const tabProps = {
Expand Down

0 comments on commit 9a792e3

Please sign in to comment.