diff --git a/src/notify/index.js b/src/notify/index.js index fb0a875..71f296e 100644 --- a/src/notify/index.js +++ b/src/notify/index.js @@ -5,29 +5,209 @@ */ 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: '', - content: '' + 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() { - return html`
` + 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') -function notify(title = '通知', { icon, body }) { +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.icon = icon - elem.content = body - document.body.append(elem) + elem.opt = merge({ icon, body, image, progress }) + + container.append(elem) + + if (!notifyIns) { + notifyIns = container + document.body.append(notifyIns) + } + + return elem } window.notify = notify