完成时间线组件的开发

master
yutent 2023-04-19 16:03:06 +08:00
parent 125d825432
commit 771c78ac70
3 changed files with 150 additions and 3 deletions

View File

@ -13,7 +13,7 @@
- @bd/core 针对`web components`的核心封装库, 以数据驱动, 可以更方便的开发 wc 组件 - @bd/core 针对`web components`的核心封装库, 以数据驱动, 可以更方便的开发 wc 组件
### 开发进度 && 计划 (30/54) ### 开发进度 && 计划 (31/54)
- [x] `wc-card` 卡片组件 - [x] `wc-card` 卡片组件
- [x] `wc-space` 间隔组件 - [x] `wc-space` 间隔组件
@ -59,7 +59,7 @@
- [ ] `wc-loading` 加载组件 - [ ] `wc-loading` 加载组件
- [x] `wc-tabs` 选项卡组件 - [x] `wc-tabs` 选项卡组件
- [x] `wc-steps` 步骤条组件 - [x] `wc-steps` 步骤条组件
- [ ] `wc-timeline` 时间线组件 - [x] `wc-timeline` 时间线组件
- [ ] `wc-layout` 布局组件 - [ ] `wc-layout` 布局组件
- [ ] `wc-tag` 标签组件 - [ ] `wc-tag` 标签组件
- [ ] `wc-tooltip` 文字提示组件 - [ ] `wc-tooltip` 文字提示组件

View File

@ -61,7 +61,7 @@ class Card extends Component {
render() { render() {
return html` return html`
<div class="card-box"> <div class="card-box">
<div class="header"><slot>${this.header}</slot></div> <div class="header"><slot name="header">${this.header}</slot></div>
<div class="content"><slot></slot></div> <div class="content"><slot></slot></div>
</div> </div>
` `

147
src/timeline/index.js Normal file
View File

@ -0,0 +1,147 @@
/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2023/04/18 09:38:01
*/
import { css, html, Component, bind, styleMap, classMap } from '@bd/core'
import '../icon/index.js'
function pad(n) {
return n < 10 ? '0' + n : n
}
function getTimeStamp(t) {
let y = t.getFullYear()
let m = pad(t.getMonth() + 1)
let d = pad(t.getDate())
let h = pad(t.getHours())
let i = pad(t.getMinutes())
return `${y}/${m}/${d} ${h}:${i}`
}
const DEFAULT_TIME = getTimeStamp(new Date())
class Timeline extends Component {
static styles = [
css`
:host {
display: flex;
flex-direction: column;
justify-content: space-between;
}
`
]
created() {
bind(this.root, 'slotchange', ev => {
let children = ev.target.assignedNodes()
children.forEach((it, i) => {
it.removeAttribute('last')
})
children.at(-1).setAttribute('last', '')
})
}
}
class Item extends Component {
static props = {
time: {
type: String,
default: DEFAULT_TIME,
observer(v) {
if (isFinite(v)) {
this.time = getTimeStamp(new Date(+v))
}
}
},
content: '',
icon: { type: String, default: null },
color: ''
}
static styles = css`
:host {
flex: 1;
display: flex;
font-size: 14px;
}
.container {
display: flex;
width: 100%;
margin-bottom: 32px;
color: var(--color-dark-1);
}
.header {
position: relative;
display: flex;
justify-content: center;
width: 26px;
height: 100%;
min-height: 64px;
user-select: none;
&::after {
position: absolute;
left: 12px;
top: 20px;
width: 2px;
height: calc(100% + 12px); // -20 + 32
background: var(--color-grey-1);
content: '';
}
}
:host([last]) {
.header:after {
display: none;
}
}
.dot {
display: inline-flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--color-grey-1);
color: #fff;
--size: 14px;
}
.group {
flex: 1;
display: flex;
flex-direction: column;
margin-left: 12px;
}
.time {
margin-bottom: 4px;
line-height: 1.5;
font-size: 12px;
color: var(--color-grey-3);
user-select: none;
font-family: Raleway, Arial, Helvetica, sans-serif;
}
`
render() {
return html`
<label class="container" status=${this.status}>
<header class="header">
<span class="dot" style=${styleMap({ backgroundColor: this.color })}>
<wc-icon name=${this.icon || 'time'}></wc-icon>
</span>
</header>
<div class="group">
<span class="time">${this.time}</span>
<slot class="content">${this.content}</slot>
</div>
</label>
`
}
}
Timeline.reg('timeline')
Item.reg('timeline-item')