diff --git a/packages/notice-bar/index.js b/packages/notice-bar/index.js new file mode 100644 index 000000000..d33e20e76 --- /dev/null +++ b/packages/notice-bar/index.js @@ -0,0 +1,116 @@ +import { use } from '../utils'; +import Icon from '../icon'; + +const [sfc, bem] = use('notice-bar'); + +export default sfc({ + props: { + text: String, + mode: String, + color: String, + leftIcon: String, + background: String, + delay: { + type: [String, Number], + default: 1 + }, + scrollable: { + type: Boolean, + default: true + }, + speed: { + type: Number, + default: 50 + } + }, + + data() { + return { + wrapWidth: 0, + firstRound: true, + duration: 0, + offsetWidth: 0, + showNoticeBar: true, + animationClass: '' + }; + }, + + watch: { + text: { + handler() { + this.$nextTick(() => { + const { wrap, content } = this.$refs; + if (!wrap || !content) { + return; + } + + const wrapWidth = wrap.getBoundingClientRect().width; + const offsetWidth = content.getBoundingClientRect().width; + if (this.scrollable && offsetWidth > wrapWidth) { + this.wrapWidth = wrapWidth; + this.offsetWidth = offsetWidth; + this.duration = offsetWidth / this.speed; + this.animationClass = bem('play'); + } + }); + }, + immediate: true + } + }, + + methods: { + onClickIcon() { + this.showNoticeBar = this.mode !== 'closeable'; + }, + + onAnimationEnd() { + this.firstRound = false; + this.$nextTick(() => { + this.duration = (this.offsetWidth + this.wrapWidth) / this.speed; + this.animationClass = bem('play--infinite'); + }); + } + }, + + render(h) { + const { mode } = this; + + const iconName = mode === 'closeable' ? 'cross' : mode === 'link' ? 'arrow' : ''; + + const barStyle = { + color: this.color, + background: this.background + }; + + const contentStyle = { + paddingLeft: this.firstRound ? 0 : this.wrapWidth + 'px', + animationDelay: (this.firstRound ? this.delay : 0) + 's', + animationDuration: this.duration + 's' + }; + + return ( +