mirror of
https://github.com/element-plus/element-plus.git
synced 2025-04-06 16:30:35 +08:00
refactor(components): [tabs] improve types (#9561)
Co-authored-by: 三咲智子 <sxzz@sxzz.moe>
This commit is contained in:
parent
e8817aae06
commit
c4d0c6f90a
@ -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>
|
||||
|
@ -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'
|
||||
|
@ -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)
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
@ -11,6 +11,7 @@
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
computed,
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
})
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user