refactor(components): [tabs] improve types (#9561)

Co-authored-by: 三咲智子 <sxzz@sxzz.moe>
This commit is contained in:
qiang 2022-09-07 00:26:17 +08:00 committed by GitHub
parent e8817aae06
commit c4d0c6f90a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 38 additions and 33 deletions

View File

@ -48,7 +48,7 @@ describe('Tabs.vue', () => {
activeName.value = tab.paneName
}
const wrapper = mount(() => (
<Tabs v-model={activeName.value} onTab-click={handleClick}>
<Tabs v-model={activeName.value} onTabClick={handleClick}>
<TabPane name="a" label="label-1">
A
</TabPane>
@ -308,8 +308,8 @@ describe('Tabs.vue', () => {
type="card"
addable
closable
onTab-add={addTab}
onTab-remove={removeTab}
onTabAdd={addTab}
onTabRemove={removeTab}
>
{editableTabs.value.map((item) => (
<TabPane
@ -646,7 +646,7 @@ describe('Tabs.vue', () => {
activeName.value = tab.paneName
}
const wrapper = mount(() => (
<Tabs v-model={activeName.value} onTab-click={handleClick}>
<Tabs v-model={activeName.value} onTabClick={handleClick}>
<TabPane name={0} label="label-1">
A
</TabPane>
@ -678,7 +678,7 @@ describe('Tabs.vue', () => {
activeName.value = tab.paneName
}
const wrapper = mount(() => (
<Tabs v-model={activeName.value} onTab-click={handleClick}>
<Tabs v-model={activeName.value} onTabClick={handleClick}>
<TabPane name={0} label="n-0">
number-0
</TabPane>

View File

@ -5,8 +5,8 @@
:style="barStyle"
/>
</template>
<script lang="ts" setup>
// @ts-nocheck
import { getCurrentInstance, inject, nextTick, ref, watch } from 'vue'
import { useResizeObserver } from '@vueuse/core'
import { capitalize, throwError } from '@element-plus/utils'

View File

@ -1,4 +1,3 @@
// @ts-nocheck
import {
computed,
defineComponent,
@ -10,7 +9,6 @@ import {
ref,
watch,
} from 'vue'
import { NOOP } from '@vue/shared'
import {
useDocumentVisibility,
useResizeObserver,
@ -48,16 +46,6 @@ export const tabNavProps = buildProps({
default: '',
},
editable: Boolean,
onTabClick: {
type: definePropType<
(tab: TabsPaneContext, tabName: TabPanelName, ev: Event) => void
>(Function),
default: NOOP,
},
onTabRemove: {
type: definePropType<(tab: TabsPaneContext, ev: Event) => void>(Function),
default: NOOP,
},
type: {
type: String,
values: ['card', 'border-card', ''],
@ -66,14 +54,21 @@ export const tabNavProps = buildProps({
stretch: Boolean,
} as const)
export const tabNavEmits = {
tabClick: (tab: TabsPaneContext, tabName: TabPanelName, ev: Event) =>
ev instanceof Event,
tabRemove: (tab: TabsPaneContext, ev: Event) => ev instanceof Event,
}
export type TabNavProps = ExtractPropTypes<typeof tabNavProps>
export type TabNavEmits = typeof tabNavEmits
const COMPONENT_NAME = 'ElTabNav'
const TabNav = defineComponent({
name: COMPONENT_NAME,
props: tabNavProps,
setup(props, { expose }) {
emits: tabNavEmits,
setup(props, { expose, emit }) {
const vm = getCurrentInstance()!
const rootTabs = inject(tabsRootContextKey)
@ -320,7 +315,7 @@ const TabNav = defineComponent({
// `onClick` not exist when generate dts
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
onClick={(ev: MouseEvent) => props.onTabRemove(pane, ev)}
onClick={(ev: MouseEvent) => emit('tabRemove', pane, ev)}
>
<Close />
</ElIcon>
@ -350,7 +345,7 @@ const TabNav = defineComponent({
onBlur={() => removeFocus()}
onClick={(ev: MouseEvent) => {
removeFocus()
props.onTabClick(pane, tabName, ev)
emit('tabClick', pane, tabName, ev)
}}
onKeydown={(ev: KeyboardEvent) => {
if (
@ -358,7 +353,7 @@ const TabNav = defineComponent({
(ev.code === EVENT_CODE.delete ||
ev.code === EVENT_CODE.backspace)
) {
props.onTabRemove(pane, ev)
emit('tabRemove', pane, ev)
}
}}
>

View File

@ -11,6 +11,7 @@
<slot />
</div>
</template>
<script lang="ts" setup>
import {
computed,

View File

@ -67,12 +67,12 @@ const isPanelName = (value: unknown): value is string | number =>
export const tabsEmits = {
[UPDATE_MODEL_EVENT]: (name: TabPanelName) => isPanelName(name),
'tab-click': (pane: TabsPaneContext, ev: Event) => ev instanceof Event,
'tab-change': (name: TabPanelName) => isPanelName(name),
tabClick: (pane: TabsPaneContext, ev: Event) => ev instanceof Event,
tabChange: (name: TabPanelName) => isPanelName(name),
edit: (paneName: TabPanelName | undefined, action: 'remove' | 'add') =>
['remove', 'add'].includes(action),
'tab-remove': (name: TabPanelName) => isPanelName(name),
'tab-add': () => true,
tabRemove: (name: TabPanelName) => isPanelName(name),
tabAdd: () => true,
}
export type TabsEmits = typeof tabsEmits
@ -94,7 +94,7 @@ export default defineComponent({
const changeCurrentName = (value: TabPanelName) => {
currentName.value = value
emit(UPDATE_MODEL_EVENT, value)
emit('tab-change', value)
emit('tabChange', value)
}
const setCurrentName = async (value?: TabPanelName) => {
@ -121,19 +121,19 @@ export default defineComponent({
) => {
if (tab.props.disabled) return
setCurrentName(tabName)
emit('tab-click', tab, event)
emit('tabClick', tab, event)
}
const handleTabRemove = (pane: TabsPaneContext, ev: Event) => {
if (pane.props.disabled || isUndefined(pane.props.name)) return
ev.stopPropagation()
emit('edit', pane.props.name, 'remove')
emit('tab-remove', pane.props.name)
emit('tabRemove', pane.props.name)
}
const handleTabAdd = () => {
emit('edit', undefined, 'add')
emit('tab-add')
emit('tabAdd')
}
useDeprecated(

View File

@ -16,9 +16,14 @@ describe('strings', () => {
)
})
it('capitalize', () => {
;['capitalize', 'camelize', 'hyphenate'].forEach((item) => {
expect(capitalize(item)).toBe(vueShared.capitalize(item))
})
})
it('re-export from @vue/shared', () => {
expect(camelize).toBe(vueShared.camelize)
expect(capitalize).toBe(vueShared.capitalize)
expect(hyphenate).toBe(vueShared.hyphenate)
expect(kebabCase).toBe(vueShared.hyphenate)
})

View File

@ -1,6 +1,6 @@
import { capitalize as toCapitalize } from '@vue/shared'
export {
camelize,
capitalize,
hyphenate,
hyphenate as kebabCase, // alias
} from '@vue/shared'
@ -10,3 +10,7 @@ export {
*/
export const escapeStringRegexp = (string = '') =>
string.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d')
// NOTE: improve capitalize types. Restore previous code after the [PR](https://github.com/vuejs/core/pull/6212) merge
export const capitalize = <T extends string>(str: T) =>
toCapitalize(str) as Capitalize<T>