Skip to content

Commit

Permalink
refactor(components): [tabs] switch to script-setup syntax (element-p…
Browse files Browse the repository at this point in the history
…lus#6468)

Co-authored-by: 三咲智子 <[email protected]>
  • Loading branch information
freedomlang and sxzz authored Mar 29, 2022
1 parent 65149ab commit cd0f5ac
Show file tree
Hide file tree
Showing 9 changed files with 310 additions and 302 deletions.
1 change: 1 addition & 0 deletions internal/build/src/type-safe.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"packages/components/rate/",
"packages/components/row/",
"packages/components/slot/",
"packages/components/tabs/",
"packages/components/tag/",
"packages/components/teleport/",
"packages/components/upload/",
Expand Down
2 changes: 1 addition & 1 deletion packages/components/tabs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import TabPane from './src/tab-pane.vue'
export const ElTabs = withInstall(Tabs, {
TabPane,
})
export default ElTabs
export const ElTabPane = withNoopInstall(TabPane)
export default ElTabs

export * from './src/tabs'
export * from './src/tab-bar'
Expand Down
8 changes: 5 additions & 3 deletions packages/components/tabs/src/tab-bar.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { buildProps, definePropType, mutable } from '@element-plus/utils'
import type { TabsPaneContext } from '@element-plus/tokens'
import type { ExtractPropTypes } from 'vue'
import type { TabsPaneContext } from '@element-plus/tokens'
import type TabBar from './tab-bar.vue'

export const tabBar = buildProps({
export const tabBarProps = buildProps({
tabs: {
type: definePropType<TabsPaneContext[]>(Array),
default: () => mutable([] as const),
},
} as const)

export type TabBar = ExtractPropTypes<typeof tabBar>
export type TabBarProps = ExtractPropTypes<typeof tabBarProps>
export type TabBarInstance = InstanceType<typeof TabBar>
137 changes: 64 additions & 73 deletions packages/components/tabs/src/tab-bar.vue
Original file line number Diff line number Diff line change
@@ -1,101 +1,92 @@
<template>
<div
ref="bar$"
:class="['el-tabs__active-bar', `is-${rootTabs.props.tabPosition}`]"
ref="barRef"
:class="[ns.e('active-bar'), ns.is(rootTabs.props.tabPosition)]"
:style="barStyle"
/>
</template>
<script lang="ts">
import {
defineComponent,
getCurrentInstance,
inject,
nextTick,
ref,
watch,
} from 'vue'
import { capitalize } from '@vue/shared'
<script lang="ts" setup>
import { getCurrentInstance, inject, nextTick, ref, watch } from 'vue'
import { useResizeObserver } from '@vueuse/core'
import { capitalize, throwError } from '@element-plus/utils'
import { tabsRootContextKey } from '@element-plus/tokens'
import { throwError } from '@element-plus/utils'
import { tabBar } from './tab-bar'
import { useNamespace } from '@element-plus/hooks'
import { tabBarProps } from './tab-bar'
import type { CSSProperties } from 'vue'
const COMPONENT_NAME = 'ElTabBar'
export default defineComponent({
name: COMPONENT_NAME,
props: tabBar,
defineOptions({
name: 'ElTabBar',
})
const props = defineProps(tabBarProps)
setup(props) {
const instance = getCurrentInstance()!
const rootTabs = inject(tabsRootContextKey)
if (!rootTabs) throwError(COMPONENT_NAME, 'must use with ElTabs')
const instance = getCurrentInstance()!
const rootTabs = inject(tabsRootContextKey)
if (!rootTabs) throwError(COMPONENT_NAME, '<el-tabs><el-tab-bar /></el-tabs>')
const bar$ = ref<HTMLDivElement>()
const barStyle = ref()
const ns = useNamespace('tabs')
const getBarStyle = (): CSSProperties => {
let offset = 0
let tabSize = 0
const barRef = ref<HTMLDivElement>()
const barStyle = ref<CSSProperties>()
const sizeName = ['top', 'bottom'].includes(rootTabs.props.tabPosition)
? 'width'
: 'height'
const sizeDir = sizeName === 'width' ? 'x' : 'y'
const getBarStyle = (): CSSProperties => {
let offset = 0
let tabSize = 0
props.tabs.every((tab) => {
const $el = instance.parent?.refs?.[
`tab-${tab.paneName}`
] as HTMLElement
if (!$el) return false
const sizeName = ['top', 'bottom'].includes(rootTabs.props.tabPosition)
? 'width'
: 'height'
const sizeDir = sizeName === 'width' ? 'x' : 'y'
if (!tab.active) {
return true
}
props.tabs.every((tab) => {
const $el = instance.parent?.refs?.[`tab-${tab.paneName}`] as HTMLElement
if (!$el) return false
tabSize = $el[`client${capitalize(sizeName)}`]
const position = sizeDir === 'x' ? 'left' : 'top'
offset =
$el.getBoundingClientRect()[position] -
($el.parentElement?.getBoundingClientRect()[position] ?? 0)
const tabStyles = window.getComputedStyle($el)
if (!tab.active) {
return true
}
if (sizeName === 'width') {
if (props.tabs.length > 1) {
tabSize -=
Number.parseFloat(tabStyles.paddingLeft) +
Number.parseFloat(tabStyles.paddingRight)
}
offset += Number.parseFloat(tabStyles.paddingLeft)
}
return false
})
tabSize = $el[`client${capitalize(sizeName)}`]
const position = sizeDir === 'x' ? 'left' : 'top'
offset =
$el.getBoundingClientRect()[position] -
($el.parentElement?.getBoundingClientRect()[position] ?? 0)
const tabStyles = window.getComputedStyle($el)
return {
[sizeName]: `${tabSize}px`,
transform: `translate${capitalize(sizeDir)}(${offset}px)`,
if (sizeName === 'width') {
if (props.tabs.length > 1) {
tabSize -=
Number.parseFloat(tabStyles.paddingLeft) +
Number.parseFloat(tabStyles.paddingRight)
}
offset += Number.parseFloat(tabStyles.paddingLeft)
}
return false
})
const update = () => (barStyle.value = getBarStyle())
return {
[sizeName]: `${tabSize}px`,
transform: `translate${capitalize(sizeDir)}(${offset}px)`,
}
}
watch(
() => props.tabs,
async () => {
await nextTick()
update()
},
{ immediate: true }
)
useResizeObserver(bar$, () => update())
const update = () => (barStyle.value = getBarStyle())
return {
bar$,
rootTabs,
barStyle,
update,
}
watch(
() => props.tabs,
async () => {
await nextTick()
update()
},
{ immediate: true }
)
useResizeObserver(barRef, () => update())
defineExpose({
/** @description tab root html element */
ref: barRef,
/** @description method to manually update tab bar style */
update,
})
</script>
Loading

0 comments on commit cd0f5ac

Please sign in to comment.