first commit

This commit is contained in:
jefferyzhao
2025-07-31 17:44:12 +08:00
commit b9bdc8598b
42390 changed files with 4467935 additions and 0 deletions

View File

@ -0,0 +1,8 @@
import Descriptions from './src/index';
/* istanbul ignore next */
Descriptions.install = function install(Vue) {
Vue.component(Descriptions.name, Descriptions);
};
export default Descriptions;

View File

@ -0,0 +1,30 @@
export default {
name: 'ElDescriptionsItem',
props: {
label: {
type: String,
default: ''
},
span: {
type: Number,
default: 1
},
contentClassName: {
type: String,
default: ''
},
contentStyle: {
type: Object
},
labelClassName: {
type: String,
default: ''
},
labelStyle: {
type: Object
}
},
render() {
return null;
}
};

View File

@ -0,0 +1,116 @@
export default {
name: 'ElDescriptionsRow',
props: {
row: {
type: Array
}
},
inject: ['elDescriptions'],
render(h) {
const { elDescriptions } = this;
const row = (this.row || []).map(item => {
return {
...item,
label: item.slots.label || item.props.label,
...['labelClassName', 'contentClassName', 'labelStyle', 'contentStyle'].reduce((res, key) => {
res[key] = item.props[key] || elDescriptions[key];
return res;
}, {})
};
});
if (elDescriptions.direction === 'vertical') {
return (
<tbody>
<tr class="el-descriptions-row">
{
row.map(item => {
return (
<th
class={{
'el-descriptions-item__cell': true,
'el-descriptions-item__label': true,
'has-colon': elDescriptions.border ? false : elDescriptions.colon,
'is-bordered-label': elDescriptions.border,
[item.labelClassName]: true
}}
style={item.labelStyle}
colSpan={item.props.span}
>{item.label}</th>
);
})
}
</tr>
<tr class="el-descriptions-row">
{
row.map(item =>{
return (
<td
class={['el-descriptions-item__cell', 'el-descriptions-item__content', item.contentClassName]}
style={item.contentStyle}
colSpan={item.props.span}
>{item.slots.default}</td>
);
})
}
</tr>
</tbody>
);
}
if (elDescriptions.border) {
return (
<tbody>
<tr class="el-descriptions-row">
{
row.map(item=> {
return ([
<th
class={{
'el-descriptions-item__cell': true,
'el-descriptions-item__label': true,
'is-bordered-label': elDescriptions.border,
[item.labelClassName]: true
}}
style={item.labelStyle}
colSpan="1"
>{item.label}</th>,
<td
class={['el-descriptions-item__cell', 'el-descriptions-item__content', item.contentClassName]}
style={item.contentStyle}
colSpan={item.props.span * 2 - 1}
>{item.slots.default}</td>
]);
})
}
</tr>
</tbody>
);
}
return (
<tbody>
<tr class="el-descriptions-row">
{
row.map(item=> {
return (
<td class="el-descriptions-item el-descriptions-item__cell" colSpan={item.props.span}>
<div class="el-descriptions-item__container">
<span
class={{
'el-descriptions-item__label': true,
'has-colon': elDescriptions.colon,
[item.labelClassName]: true
}}
style={item.labelStyle}
>{item.label}</span>
<span
class={['el-descriptions-item__content', item.contentClassName]}
style={item.contentStyle}
>{item.slots.default}</span>
</div>
</td>);
})
}
</tr>
</tbody>
);
}
};

View File

@ -0,0 +1,180 @@
import DescriptionsRow from './descriptions-row';
import { isFunction } from 'element-ui/src/utils/types';
export default {
name: 'ElDescriptions',
components: {
[DescriptionsRow.name]: DescriptionsRow
},
props: {
border: {
type: Boolean,
default: false
},
column: {
type: Number,
default: 3
},
direction: {
type: String,
default: 'horizontal'
},
size: {
type: String
// validator: isValidComponentSize,
},
title: {
type: String,
default: ''
},
extra: {
type: String,
default: ''
},
labelStyle: {
type: Object
},
contentStyle: {
type: Object
},
labelClassName: {
type: String,
default: ''
},
contentClassName: {
type: String,
default: ''
},
colon: {
type: Boolean,
default: true
}
},
computed: {
descriptionsSize() {
return this.size || (this.$ELEMENT || {}).size;
}
},
provide() {
return {
elDescriptions: this
};
},
methods: {
getOptionProps(vnode) {
if (vnode.componentOptions) {
const componentOptions = vnode.componentOptions;
const { propsData = {}, Ctor = {} } = componentOptions;
const props = (Ctor.options || {}).props || {};
const res = {};
for (const k in props) {
const v = props[k];
const defaultValue = v.default;
if (defaultValue !== undefined) {
res[k] = isFunction(defaultValue) ? defaultValue.call(vnode) : defaultValue;
}
}
return { ...res, ...propsData };
}
return {};
},
getSlots(vnode) {
let componentOptions = vnode.componentOptions || {};
const children = vnode.children || componentOptions.children || [];
const slots = {};
children.forEach(child => {
if (!this.isEmptyElement(child)) {
const name = (child.data && child.data.slot) || 'default';
slots[name] = slots[name] || [];
if (child.tag === 'template') {
slots[name].push(child.children);
} else {
slots[name].push(child);
}
}
});
return { ...slots };
},
isEmptyElement(c) {
return !(c.tag || (c.text && c.text.trim() !== ''));
},
filledNode(node, span, count, isLast = false) {
if (!node.props) {
node.props = {};
}
if (span > count) {
node.props.span = count;
}
if (isLast) {
// set the max span, cause of the last td
node.props.span = count;
}
return node;
},
getRows() {
const children = ((this.$slots.default || []).filter(vnode => vnode.tag &&
vnode.componentOptions && vnode.componentOptions.Ctor.options.name === 'ElDescriptionsItem'));
const nodes = children.map(vnode => {
return {
props: this.getOptionProps(vnode),
slots: this.getSlots(vnode),
vnode
};
});
const rows = [];
let temp = [];
let count = this.column;
nodes.forEach((node, index) => {
const span = node.props.span || 1;
if (index === children.length - 1) {
temp.push(this.filledNode(node, span, count, true));
rows.push(temp);
return;
}
if (span < count) {
count -= span;
temp.push(node);
} else {
temp.push(this.filledNode(node, span, count));
rows.push(temp);
count = this.column;
temp = [];
}
});
return rows;
}
},
render() {
const { title, extra, border, descriptionsSize, $slots } = this;
const rows = this.getRows();
return (
<div class="el-descriptions">
{
(title || extra || $slots.title || $slots.extra)
? <div class="el-descriptions__header">
<div class="el-descriptions__title">
{ $slots.title ? $slots.title : title}
</div>
<div class="el-descriptions__extra">
{ $slots.extra ? $slots.extra : extra }
</div>
</div>
: null
}
<div class="el-descriptions__body">
<table class={['el-descriptions__table', {'is-bordered': border}, descriptionsSize ? `el-descriptions--${descriptionsSize}` : '']}>
{rows.map(row => (
<DescriptionsRow row={row}></DescriptionsRow>
))}
</table>
</div>
</div>
);
}
};