diff --git a/Readme.md b/Readme.md index 3c630d6..47a2d52 100644 --- a/Readme.md +++ b/Readme.md @@ -38,7 +38,7 @@ - [ ] `wc-cascadar`表单组件-多级联动 - [x] `wc-switch`表单组件-开关 - [x] `wc-icon`图标组件 -- [ ] `wc-layer` 弹层组件 +- [x] `wc-layer` 弹层组件 - [x] `wc-markd`markdown 组件 - [ ] `wc-meditor`md 文本编辑器 - [ ] `wc-neditor`富文本编辑器 @@ -48,10 +48,12 @@ - [ ] `wc-timepicker`时间选择器 - [x] `wc-code`代码高亮插件 - [x] `wc-scroll`滚动组件 -- [x] `wc-silder`滑块组件 +- [x] `wc-silder`面包屑组件 +- [x] `wc-breadcrumb`滑块组件 - [ ] `wc-progress`进度条组件 - [ ] `wc-tree`树形菜单组件 - [ ] `wc-uploader`上传组件 +- [ ] `wc-notify`通知组件 ### 测试预览 diff --git a/src/breadcrumb/index.js b/src/breadcrumb/index.js new file mode 100644 index 0000000..535f256 --- /dev/null +++ b/src/breadcrumb/index.js @@ -0,0 +1,89 @@ +/** + * {} + * @author yutent + * @date 2023/04/10 16:12:33 + */ + +import { css, html, Component, bind, styleMap } from '@bd/core' + +const last = Symbol('last') + +class Breadcrumb extends Component { + static styles = [ + css` + :host { + display: flex; + align-items: center; + width: 100%; + height: 32px; + font-size: 14px; + } + ` + ] + + #updateChildrenStat(checkAll) { + let list = Array.from(this.children) + list.forEach((it, i) => { + if (it.tagName === 'WC-BREADCRUMB-ITEM') { + if (list.length === i + 1) { + it.last = true + } + } else { + it.remove() + } + }) + } + + mounted() { + this.#updateChildrenStat() + } +} + +class Item extends Component { + static props = { + path: '', + separator: '/' + } + + static styles = [ + css` + :host, + .breadcrumb-item { + display: inline-flex; + align-items: center; + height: 32px; + font-size: 14px; + } + .separator { + margin: 0 8px; + user-select: none; + } + ` + ] + + get last() { + return this[last] || false + } + + set last(val) { + this[last] = !!val + this.$requestUpdate() + } + + render() { + return html` + + ` + } +} + +Breadcrumb.reg('breadcrumb') +Item.reg('breadcrumb-item') diff --git a/src/notify/index.js b/src/notify/index.js new file mode 100644 index 0000000..71f296e --- /dev/null +++ b/src/notify/index.js @@ -0,0 +1,213 @@ +/** + * {通知组件} + * @author yutent + * @date 2023/04/10 17:17:10 + */ + +import { css, html, Component, bind, styleMap } from '@bd/core' +import '../icon/index.js' + +const ANIMATION = [ + { transform: 'translateX(60%)', opacity: 0 }, + { transform: 'translateX(0)', opacity: 1 } +] + +const DEFAULT_OPT = { icon: '', image: '', body: '', progress: 0 } + +let notifyIns = null + +function merge(opt = {}) { + let output = Object.assign({}, DEFAULT_OPT) + + for (let k in opt) { + if (opt[k] !== void 0) { + output[k] = opt[k] + } + } + return output +} + +class NotifyGroup extends Component { + static styles = [ + css` + :host { + position: fixed; + z-index: 65535; + top: 0; + right: 0; + } + ` + ] +} + +class Notify extends Component { + static props = { + title: '', + opt: { icon: '', image: '', body: '', progress: 0 } + } + + static styles = [ + css` + :host { + display: block; + margin-top: 16px !important; + } + .noselect { + user-select: none; + + img, + a { + -webkit-user-drag: none; + } + } + cite { + font-style: normal; + } + .notification { + width: 300px; + padding: 12px; + border-radius: 3px; + font-size: 14px; + background: rgba(255, 255, 255, 0.9); + box-shadow: 0 5px 20px rgba(0, 0, 0, 0.15); + } + + .icon { + flex-shrink: 0; + width: 48px; + height: 48px; + margin-right: 8px; + } + .main, + .content { + display: flex; + } + .content { + flex: 1; + flex-direction: column; + } + .title { + display: flex; + align-items: center; + justify-content: space-between; + line-height: 2; + + wc-icon { + --size: 14px; + cursor: pointer; + } + } + `, + // 额外功能 + css` + .image { + width: 284px; + height: 86px; + margin-top: 8px; + object-fit: cover; + } + .progress { + width: 100%; + margin-top: 8px; + + .bar { + display: flex; + width: 100%; + height: 8px; + border-radius: 4px; + background: var(--color-plain-1); + } + + .thumb { + width: 10%; + height: 8px; + border-radius: 4px; + background: var(--color-teal-1); + } + } + ` + ] + + close() { + clearTimeout(this.timer) + this.$refs.box.$animate(true).then(_ => { + this.remove() + }) + } + + setProgress(val) { + let n = +val || 0 + if (n < 0) { + n = 0 + } else if (n > 100) { + n = 100 + } + this.opt.progress = n + } + + mounted() { + this.$refs.box.$animate() + + this.timer = setTimeout(() => { + this.close() + }, 3000) + } + + render() { + let progress = styleMap({ width: this.opt.progress + '%' }) + let iconShow = styleMap({ display: this.opt.icon ? '' : 'none' }) + let imageShow = styleMap({ display: this.opt.image ? '' : 'none' }) + let progressShow = styleMap({ + display: this.opt.progress > 0 ? '' : 'none' + }) + + return html`
+
+ +
+ + ${this.title} + + + ${this.opt.body} +
+
+ + +
+
+
+
` + } +} + +NotifyGroup.reg('notify-group') +Notify.reg('notify') + +export default function notify( + title = '通知', + { icon, body, image, progress } +) { + // + let container = notifyIns || document.createElement('wc-notify-group') + let elem = document.createElement('wc-notify') + + elem.title = title + + elem.opt = merge({ icon, body, image, progress }) + + container.append(elem) + + if (!notifyIns) { + notifyIns = container + document.body.append(notifyIns) + } + + return elem +} + +window.notify = notify