refactor(components): [descriptions] switch to script-setup syntax (#8349)

This commit is contained in:
류한경
2022-07-19 20:21:30 +09:00
committed by GitHub
parent 3d311c003c
commit fbe5990f1c
9 changed files with 174 additions and 178 deletions

View File

@@ -3,7 +3,7 @@ import { nextTick, ref } from 'vue'
import { mount } from '@vue/test-utils'
import { describe, expect, test } from 'vitest'
import ElTag from '@element-plus/components/tag'
import ElDescriptions from '../src/index.vue'
import ElDescriptions from '../src/description.vue'
import ElDescriptionsItem from '../src/description-item'
describe('Descriptions.vue', () => {

View File

@@ -1,11 +1,14 @@
import { withInstall, withNoopInstall } from '@element-plus/utils'
import Descriptions from './src/index.vue'
import Descriptions from './src/description.vue'
import DescriptionsItem from './src/description-item'
export const ElDescriptions = withInstall(Descriptions, {
DescriptionsItem,
})
export default ElDescriptions
export const ElDescriptionsItem = withNoopInstall(DescriptionsItem)
export default ElDescriptions
export * from './src/description'

View File

@@ -0,0 +1,31 @@
import { buildProps } from '@element-plus/utils'
import { useSizeProp } from '@element-plus/hooks'
import type Description from './description.vue'
export const descriptionProps = buildProps({
border: {
type: Boolean,
default: false,
},
column: {
type: Number,
default: 3,
},
direction: {
type: String,
values: ['horizontal', 'vertical'],
default: 'horizontal',
},
size: useSizeProp,
title: {
type: String,
default: '',
},
extra: {
type: String,
default: '',
},
} as const)
export type DescriptionInstance = InstanceType<typeof Description>

View File

@@ -0,0 +1,115 @@
<template>
<div :class="descriptionKls">
<div
v-if="title || extra || $slots.title || $slots.extra"
:class="ns.e('header')"
>
<div :class="ns.e('title')">
<slot name="title">{{ title }}</slot>
</div>
<div :class="ns.e('extra')">
<slot name="extra">{{ extra }}</slot>
</div>
</div>
<div :class="ns.e('body')">
<table :class="[ns.e('table'), ns.is('bordered', border)]">
<tbody>
<template v-for="(row, index) in getRows()" :key="index">
<el-descriptions-row :row="row" />
</template>
</tbody>
</table>
</div>
</div>
</template>
<script lang="ts" setup>
// @ts-nocheck
import { computed, provide, useSlots } from 'vue'
import { useNamespace, useSize } from '@element-plus/hooks'
import ElDescriptionsRow from './descriptions-row.vue'
import { descriptionsKey } from './token'
import { descriptionProps } from './description'
defineOptions({
name: 'ElDescriptions',
})
const props = defineProps(descriptionProps)
const ns = useNamespace('descriptions')
const descriptionsSize = useSize()
const slots = useSlots()
provide(descriptionsKey, props)
const descriptionKls = computed(() => [ns.b(), ns.m(descriptionsSize.value)])
const flattedChildren = (children) => {
const temp = Array.isArray(children) ? children : [children]
const res = []
temp.forEach((child) => {
if (Array.isArray(child.children)) {
res.push(...flattedChildren(child.children))
} else {
res.push(child)
}
})
return res
}
const filledNode = (node, span, count, isLast = false) => {
if (!node.props) {
node.props = {}
}
if (span > count) {
node.props.span = count
}
if (isLast) {
// set the last span
node.props.span = span
}
return node
}
const getRows = () => {
const children = flattedChildren(slots.default?.()).filter(
(node) => node?.type?.name === 'ElDescriptionsItem'
)
const rows = []
let temp = []
let count = props.column
let totalSpan = 0 // all spans number of item
children.forEach((node, index) => {
const span = node.props?.span || 1
if (index < children.length - 1) {
totalSpan += span > count ? count : span
}
if (index === children.length - 1) {
// calculate the last item span
const lastSpan = props.column - (totalSpan % props.column)
temp.push(filledNode(node, lastSpan, count, true))
rows.push(temp)
return
}
if (span < count) {
count -= span
temp.push(node)
} else {
temp.push(filledNode(node, span, count))
rows.push(temp)
count = props.column
temp = []
}
})
return rows
}
</script>

View File

@@ -2,7 +2,7 @@
import { defineComponent, h, inject } from 'vue'
import { addUnit, getNormalizedProps } from '@element-plus/utils'
import { useNamespace } from '@element-plus/hooks'
import { elDescriptionsKey } from './token'
import { descriptionsKey } from './token'
import type { VNode } from 'vue'
import type {
@@ -24,7 +24,7 @@ export default defineComponent({
},
},
setup() {
const descriptions = inject(elDescriptionsKey, {} as IDescriptionsInject)
const descriptions = inject(descriptionsKey, {} as IDescriptionsInject)
return {
descriptions,

View File

@@ -0,0 +1,8 @@
import { buildProps } from '@element-plus/utils'
export const descriptionsRowProps = buildProps({
row: {
type: Array,
default: () => [],
},
} as const)

View File

@@ -22,30 +22,21 @@
</tr>
</template>
<script lang="ts">
<script lang="ts" setup>
// @ts-nocheck
import { defineComponent, inject } from 'vue'
import DescriptionsCell from './descriptions-cell'
import { elDescriptionsKey } from './token'
import { inject } from 'vue'
import ElDescriptionsCell from './descriptions-cell'
import { descriptionsKey } from './token'
import { descriptionsRowProps } from './descriptions-row'
import type { IDescriptionsInject } from './descriptions.type'
export default defineComponent({
defineOptions({
name: 'ElDescriptionsRow',
components: {
[DescriptionsCell.name]: DescriptionsCell,
},
props: {
row: {
type: Array,
},
},
setup() {
const descriptions = inject(elDescriptionsKey, {} as IDescriptionsInject)
return {
descriptions,
}
},
})
defineProps(descriptionsRowProps)
const descriptions = inject(descriptionsKey, {} as IDescriptionsInject)
</script>

View File

@@ -1,152 +0,0 @@
<template>
<div :class="descriptionKls">
<div
v-if="title || extra || $slots.title || $slots.extra"
:class="ns.e('header')"
>
<div :class="ns.e('title')">
<slot name="title">{{ title }}</slot>
</div>
<div :class="ns.e('extra')">
<slot name="extra">{{ extra }}</slot>
</div>
</div>
<div :class="ns.e('body')">
<table :class="[ns.e('table'), ns.is('bordered', border)]">
<tbody>
<template v-for="(row, index) in getRows()" :key="index">
<el-descriptions-row :row="row" />
</template>
</tbody>
</table>
</div>
</div>
</template>
<script lang="ts">
// @ts-nocheck
import { computed, defineComponent, provide } from 'vue'
import { isValidComponentSize } from '@element-plus/utils'
import { useNamespace, useSize } from '@element-plus/hooks'
import DescriptionsRow from './descriptions-row.vue'
import { elDescriptionsKey } from './token'
import type { PropType } from 'vue'
import type { ComponentSize } from '@element-plus/constants'
export default defineComponent({
name: 'ElDescriptions',
components: {
[DescriptionsRow.name]: DescriptionsRow,
},
props: {
border: {
type: Boolean,
default: false,
},
column: {
type: Number,
default: 3,
},
direction: {
type: String as PropType<'horizontal' | 'vertical'>,
default: 'horizontal',
},
size: {
type: String as PropType<ComponentSize>,
validator: isValidComponentSize,
},
title: {
type: String,
default: '',
},
extra: {
type: String,
default: '',
},
},
setup(props, { slots }) {
provide(elDescriptionsKey, props)
const descriptionsSize = useSize()
const ns = useNamespace('descriptions')
const descriptionKls = computed(() => [
ns.b(),
ns.m(descriptionsSize.value),
])
const flattedChildren = (children) => {
const temp = Array.isArray(children) ? children : [children]
const res = []
temp.forEach((child) => {
if (Array.isArray(child.children)) {
res.push(...flattedChildren(child.children))
} else {
res.push(child)
}
})
return res
}
const filledNode = (node, span, count, isLast = false) => {
if (!node.props) {
node.props = {}
}
if (span > count) {
node.props.span = count
}
if (isLast) {
// set the last span
node.props.span = span
}
return node
}
const getRows = () => {
const children = flattedChildren(slots.default?.()).filter(
(node) => node?.type?.name === 'ElDescriptionsItem'
)
const rows = []
let temp = []
let count = props.column
let totalSpan = 0 // all spans number of item
children.forEach((node, index) => {
const span = node.props?.span || 1
if (index < children.length - 1) {
totalSpan += span > count ? count : span
}
if (index === children.length - 1) {
// calculate the last item span
const lastSpan = props.column - (totalSpan % props.column)
temp.push(filledNode(node, lastSpan, count, true))
rows.push(temp)
return
}
if (span < count) {
count -= span
temp.push(node)
} else {
temp.push(filledNode(node, span, count))
rows.push(temp)
count = props.column
temp = []
}
})
return rows
}
return {
descriptionKls,
getRows,
ns,
}
},
})
</script>

View File

@@ -1,5 +1,5 @@
import type { InjectionKey } from 'vue'
import type { IDescriptionsInject } from './descriptions.type'
export const elDescriptionsKey =
export const descriptionsKey =
'elDescriptions' as any as InjectionKey<IDescriptionsInject>