From 771c78ac70b262c66bc4ab97e9a5a7b4708bcded Mon Sep 17 00:00:00 2001 From: yutent Date: Wed, 19 Apr 2023 16:03:06 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=97=B6=E9=97=B4=E7=BA=BF?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E7=9A=84=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 4 +- src/card/index.js | 2 +- src/timeline/index.js | 147 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 src/timeline/index.js diff --git a/Readme.md b/Readme.md index 47e6795..5511ccf 100644 --- a/Readme.md +++ b/Readme.md @@ -13,7 +13,7 @@ - @bd/core 针对`web components`的核心封装库, 以数据驱动, 可以更方便的开发 wc 组件 -### 开发进度 && 计划 (30/54) +### 开发进度 && 计划 (31/54) - [x] `wc-card` 卡片组件 - [x] `wc-space` 间隔组件 @@ -59,7 +59,7 @@ - [ ] `wc-loading` 加载组件 - [x] `wc-tabs` 选项卡组件 - [x] `wc-steps` 步骤条组件 -- [ ] `wc-timeline` 时间线组件 +- [x] `wc-timeline` 时间线组件 - [ ] `wc-layout` 布局组件 - [ ] `wc-tag` 标签组件 - [ ] `wc-tooltip` 文字提示组件 diff --git a/src/card/index.js b/src/card/index.js index 67afc03..725057f 100644 --- a/src/card/index.js +++ b/src/card/index.js @@ -61,7 +61,7 @@ class Card extends Component { render() { return html`
-
${this.header}
+
${this.header}
` diff --git a/src/timeline/index.js b/src/timeline/index.js new file mode 100644 index 0000000..75c1de7 --- /dev/null +++ b/src/timeline/index.js @@ -0,0 +1,147 @@ +/** + * {} + * @author yutent + * @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` + + ` + } +} + +Timeline.reg('timeline') +Item.reg('timeline-item')