mirror of
https://gitee.com/element-plus/element-plus.git
synced 2024-12-02 03:08:21 +08:00
parent
619dedb73e
commit
55afacad18
@ -4,9 +4,10 @@ import ElBadge from '@element-plus/badge'
|
||||
import ElCard from '@element-plus/card'
|
||||
import ElTag from '@element-plus/tag'
|
||||
import ElDivider from '@element-plus/divider'
|
||||
import ElTimeLine from '@element-plus/time-line'
|
||||
|
||||
export {
|
||||
ElButton, ElBadge, ElCard, ElDivider, ElTag,
|
||||
ElButton, ElBadge, ElCard, ElDivider, ElTag, ElTimeLine,
|
||||
}
|
||||
|
||||
export default function install(app: App): void {
|
||||
@ -15,4 +16,5 @@ export default function install(app: App): void {
|
||||
ElCard(app)
|
||||
ElTag(app)
|
||||
ElDivider(app)
|
||||
ElTimeLine(app)
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
"@element-plus/badge": "^0.0.0",
|
||||
"@element-plus/button": "^0.0.0",
|
||||
"@element-plus/card": "^0.0.0",
|
||||
"@element-plus/tag": "^0.0.0"
|
||||
"@element-plus/tag": "^0.0.0",
|
||||
"@element-plus/time-line": "^0.0.0",
|
||||
"@element-plus/divider": "^0.0.0"
|
||||
}
|
||||
}
|
||||
|
211
packages/time-line/__tests__/time-line.spec.ts
Normal file
211
packages/time-line/__tests__/time-line.spec.ts
Normal file
@ -0,0 +1,211 @@
|
||||
import { mount } from '@vue/test-utils'
|
||||
import TimeLine from '../src/index.vue'
|
||||
import TimeLineItem from '../src/item.vue'
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
const Component = defineComponent({
|
||||
components: {
|
||||
'el-timeline': TimeLine,
|
||||
'el-timeline-item': TimeLineItem,
|
||||
},
|
||||
props: [],
|
||||
data() {
|
||||
return {
|
||||
activities: [{
|
||||
content: 'Step 1: xxxxxx',
|
||||
timestamp: '2018-04-11',
|
||||
}, {
|
||||
content: 'Step 2: xxxxxx',
|
||||
timestamp: '2018-04-13',
|
||||
}, {
|
||||
content: 'Step 3: xxxxxx',
|
||||
timestamp: '2018-04-15',
|
||||
}],
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
v-for="(activity, index) in activities"
|
||||
:key="index"
|
||||
:timestamp="activity.timestamp">
|
||||
{{activity.content}}
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
`,
|
||||
})
|
||||
|
||||
describe('TimeLine.vue', () => {
|
||||
test('create', () => {
|
||||
const wrapper = mount(Component)
|
||||
const vm = wrapper.vm
|
||||
|
||||
const contentWrappers = wrapper.findAll('.el-timeline-item__content')
|
||||
contentWrappers.forEach((content, index) => {
|
||||
expect(content.text()).toEqual(vm.activities[index].content)
|
||||
})
|
||||
|
||||
const timestampWrappers = wrapper.findAll('.el-timeline-item__timestamp')
|
||||
timestampWrappers.forEach((timestamp, index) => {
|
||||
expect(timestamp.text()).toEqual(vm.activities[index].timestamp)
|
||||
})
|
||||
})
|
||||
|
||||
test('placement', () => {
|
||||
const wrapper = mount({
|
||||
...Component,
|
||||
template: `
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
v-for="(activity, index) in activities"
|
||||
:key="index"
|
||||
:timestamp="activity.timestamp"
|
||||
:placement="activity.placement">
|
||||
{{activity.content}}
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
activities: [{
|
||||
content: 'Step 1: xxxxxx',
|
||||
timestamp: '2018-04-11',
|
||||
placement: 'top',
|
||||
}, {
|
||||
content: 'Step 2: xxxxxx',
|
||||
timestamp: '2018-04-13',
|
||||
}, {
|
||||
content: 'Step 3: xxxxxx',
|
||||
timestamp: '2018-04-15',
|
||||
}],
|
||||
}
|
||||
},
|
||||
})
|
||||
const timestampWrapper = wrapper.findAll('.el-timeline-item__timestamp')[0]
|
||||
expect(timestampWrapper.classes('is-top')).toBe(true)
|
||||
})
|
||||
|
||||
test('hide-timestamp', () => {
|
||||
const wrapper = mount({
|
||||
...Component,
|
||||
template: `
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
v-for="(activity, index) in activities"
|
||||
:key="index"
|
||||
:timestamp="activity.timestamp"
|
||||
:hide-timestamp="activity.hideTimestamp">
|
||||
{{activity.content}}
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
activities: [{
|
||||
content: 'Step 1: xxxxxx',
|
||||
timestamp: '2018-04-11',
|
||||
hideTimestamp: true,
|
||||
}, {
|
||||
content: 'Step 2: xxxxxx',
|
||||
timestamp: '2018-04-13',
|
||||
}, {
|
||||
content: 'Step 3: xxxxxx',
|
||||
timestamp: '2018-04-15',
|
||||
}],
|
||||
}
|
||||
},
|
||||
})
|
||||
const timestampWrappers = wrapper.findAll('.el-timeline-item__timestamp')
|
||||
expect(timestampWrappers.length).toEqual(2)
|
||||
})
|
||||
|
||||
test('color', () => {
|
||||
const wrapper = mount({
|
||||
...Component,
|
||||
template: `
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
timestamp="2018-04-11"
|
||||
color="#f00">
|
||||
Step 1: xxxxxx
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
`,
|
||||
})
|
||||
const vm = wrapper.vm
|
||||
const nodeElm = vm.$el.querySelector('.el-timeline-item__node')
|
||||
expect(nodeElm.style.backgroundColor).toEqual('rgb(255, 0, 0)')
|
||||
})
|
||||
|
||||
test('type', () => {
|
||||
const wrapper = mount({
|
||||
...Component,
|
||||
template: `
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
timestamp="2018-04-11"
|
||||
type="primary">
|
||||
Step 1: xxxxxx
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
`,
|
||||
})
|
||||
const nodeWrapper = wrapper.find('.el-timeline-item__node')
|
||||
expect(nodeWrapper.classes('el-timeline-item__node--primary')).toBe(true)
|
||||
})
|
||||
|
||||
test('size', () => {
|
||||
const wrapper = mount({
|
||||
...Component,
|
||||
template: `
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
timestamp="2018-04-11"
|
||||
type="large">
|
||||
Step 1: xxxxxx
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
`,
|
||||
})
|
||||
const nodeWrapper = wrapper.find('.el-timeline-item__node')
|
||||
expect(nodeWrapper.classes('el-timeline-item__node--large')).toBe(true)
|
||||
})
|
||||
|
||||
test('icon', () => {
|
||||
const wrapper = mount({
|
||||
...Component,
|
||||
template: `
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
timestamp="2018-04-11"
|
||||
icon="el-icon-more">
|
||||
Step 1: xxxxxx
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
`,
|
||||
})
|
||||
const nodeWrapper = wrapper.find('.el-timeline-item__icon')
|
||||
expect(nodeWrapper.classes('el-icon-more')).toBe(true)
|
||||
})
|
||||
|
||||
test('dot', () => {
|
||||
const wrapper = mount({
|
||||
...Component,
|
||||
template: `
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
timestamp="2018-04-11"
|
||||
>
|
||||
<template v-slot:dot>
|
||||
dot
|
||||
</template>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
`,
|
||||
})
|
||||
|
||||
const dotWrapper = wrapper.find('.el-timeline-item__dot')
|
||||
expect(dotWrapper.text()).toEqual('dot')
|
||||
expect(wrapper.find('.el-timeline-item__node').exists()).toBe(false)
|
||||
})
|
||||
})
|
46
packages/time-line/doc/basic.vue
Normal file
46
packages/time-line/doc/basic.vue
Normal file
@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<div class="block">
|
||||
<el-time-line>
|
||||
<el-time-line-item
|
||||
v-for="(activity, index) in activities"
|
||||
:key="index"
|
||||
:timestamp="activity.timestamp"
|
||||
:placement="activity.placement"
|
||||
:hide-timestamp="activity.hideTimestamp"
|
||||
:type="activity.type"
|
||||
:icon="activity.icon"
|
||||
>
|
||||
{{ activity.content }}
|
||||
</el-time-line-item>
|
||||
</el-time-line>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang='ts'>
|
||||
import { defineComponent, reactive } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
return reactive({
|
||||
activities: [{
|
||||
content: 'Step 1: xxxxxx',
|
||||
timestamp: '2018-04-15',
|
||||
placement: 'top',
|
||||
}, {
|
||||
content: 'Step 2: xxxxxx',
|
||||
timestamp: '2018-04-13',
|
||||
hideTimestamp: true,
|
||||
}, {
|
||||
content: 'Step 3: xxxxxx',
|
||||
timestamp: '2018-04-11',
|
||||
type: 'large',
|
||||
icon: 'el-icon-more',
|
||||
},{
|
||||
content: 'Step 4: xxxxxx',
|
||||
timestamp: '2018-07-11',
|
||||
type: 'primary',
|
||||
}],
|
||||
})
|
||||
},
|
||||
})
|
||||
</script>
|
6
packages/time-line/doc/index.stories.ts
Normal file
6
packages/time-line/doc/index.stories.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export { default as BasicUsage } from './basic.vue'
|
||||
|
||||
export default {
|
||||
title: 'TimeLine',
|
||||
}
|
||||
|
7
packages/time-line/index.ts
Normal file
7
packages/time-line/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { App } from 'vue'
|
||||
import TimeLine from './src/index.vue'
|
||||
import TimeLineItem from './src/item.vue'
|
||||
export default (app: App): void => {
|
||||
app.component(TimeLine.name, TimeLine)
|
||||
app.component(TimeLineItem.name, TimeLineItem)
|
||||
}
|
12
packages/time-line/package.json
Normal file
12
packages/time-line/package.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "@element-plus/time-line",
|
||||
"version": "0.0.0",
|
||||
"main": "dist/index.js",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"vue": "^3.0.0-rc.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/test-utils": "^2.0.0-beta.0"
|
||||
}
|
||||
}
|
40
packages/time-line/src/index.vue
Normal file
40
packages/time-line/src/index.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<script lang='ts'>
|
||||
import { h, provide, defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ElTimeLine',
|
||||
setup(props, ctx) {
|
||||
provide('timeline', ctx)
|
||||
|
||||
/**
|
||||
* Maybe ,this component will not support prop 'reverse', why ?
|
||||
*
|
||||
* Example 1:
|
||||
* <component-a>
|
||||
* <div>1</div>
|
||||
* <div>2</div>
|
||||
* </component-a>
|
||||
*
|
||||
* Example 2:
|
||||
* <component-a>
|
||||
* <div v-for="i in 2" :key="i">{{ i }}</div>
|
||||
* </component-a>
|
||||
*
|
||||
* 'slots.default()' value in example 1 just like [Vnode, Vnode]
|
||||
* 'slots.default()' value in example 2 just like [Vnode]
|
||||
*
|
||||
* so i can't reverse the slots, when i use 'v-for' directive.
|
||||
*/
|
||||
|
||||
return () => {
|
||||
return h(
|
||||
'ul',
|
||||
{
|
||||
class: { 'el-timeline': true },
|
||||
},
|
||||
ctx.slots.default?.(),
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
97
packages/time-line/src/item.vue
Normal file
97
packages/time-line/src/item.vue
Normal file
@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<li class="el-timeline-item">
|
||||
<div class="el-timeline-item__tail"></div>
|
||||
|
||||
<div
|
||||
v-if="!$slots.dot"
|
||||
class="el-timeline-item__node"
|
||||
:class="[
|
||||
`el-timeline-item__node--${size || ''}`,
|
||||
`el-timeline-item__node--${type || ''}`
|
||||
]"
|
||||
:style="{
|
||||
backgroundColor: color
|
||||
}"
|
||||
>
|
||||
<i
|
||||
v-if="icon"
|
||||
class="el-timeline-item__icon"
|
||||
:class="icon"
|
||||
></i>
|
||||
</div>
|
||||
<div v-if="$slots.dot" class="el-timeline-item__dot">
|
||||
<slot name="dot"></slot>
|
||||
</div>
|
||||
|
||||
<div class="el-timeline-item__wrapper">
|
||||
<div
|
||||
v-if="!hideTimestamp && placement === 'top'"
|
||||
class="el-timeline-item__timestamp is-top"
|
||||
>
|
||||
{{ timestamp }}
|
||||
</div>
|
||||
|
||||
<div class="el-timeline-item__content">
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="!hideTimestamp && placement === 'bottom'"
|
||||
class="el-timeline-item__timestamp is-bottom"
|
||||
>
|
||||
{{ timestamp }}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script lang='ts'>
|
||||
import { inject, defineComponent } from 'vue'
|
||||
|
||||
interface ITimeLineItemProps {
|
||||
timestamp: string,
|
||||
hideTimestamp: boolean,
|
||||
placement: string,
|
||||
type: string,
|
||||
color: string,
|
||||
size: string,
|
||||
icon: string,
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ElTimeLineItem',
|
||||
props: {
|
||||
timestamp: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
hideTimestamp: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
placement: {
|
||||
type: String,
|
||||
default: 'bottom',
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: 'normal',
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
inject('timeline')
|
||||
},
|
||||
})
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user