[improvement] rename packages dir to src (#3659)
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<demo-section>
|
||||
<demo-block :title="$t('basicUsage')">
|
||||
<van-notice-bar
|
||||
:text="$t('text')"
|
||||
left-icon="volume-o"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('unscrollable')">
|
||||
<van-notice-bar
|
||||
:scrollable="false"
|
||||
:text="$t('text')"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('wrapable')">
|
||||
<van-notice-bar
|
||||
wrapable
|
||||
:scrollable="false"
|
||||
:text="$t('text')"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('mode')">
|
||||
<van-notice-bar
|
||||
mode="closeable"
|
||||
:text="$t('text')"
|
||||
/>
|
||||
<van-notice-bar
|
||||
mode="link"
|
||||
:text="$t('text')"
|
||||
/>
|
||||
</demo-block>
|
||||
|
||||
<demo-block :title="$t('customStyle')">
|
||||
<van-notice-bar
|
||||
:text="$t('text')"
|
||||
color="#1989fa"
|
||||
background="#ecf9ff"
|
||||
left-icon="info-o"
|
||||
/>
|
||||
</demo-block>
|
||||
</demo-section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
i18n: {
|
||||
'zh-CN': {
|
||||
unscrollable: '禁用滚动',
|
||||
mode: '通知栏模式',
|
||||
wrapable: '多行展示',
|
||||
text: '足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。',
|
||||
customStyle: '自定义样式'
|
||||
},
|
||||
'en-US': {
|
||||
mode: 'Mode',
|
||||
wrapable: 'Wrapable',
|
||||
unscrollable: 'Disable scroll',
|
||||
text: 'Only those who have the patience to do simple things perfectly ever acquire the skill to do difficult things easily.',
|
||||
customStyle: 'Custom Style'
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.demo-notice-bar {
|
||||
.van-notice-bar:not(:first-of-type) {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.van-doc-demo-block__title {
|
||||
padding-top: 25px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,91 @@
|
||||
# NoticeBar
|
||||
|
||||
### Install
|
||||
|
||||
``` javascript
|
||||
import { NoticeBar } from 'vant';
|
||||
|
||||
Vue.use(NoticeBar);
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```html
|
||||
<van-notice-bar
|
||||
text="Notice Content"
|
||||
left-icon="volume-o"
|
||||
/>
|
||||
```
|
||||
|
||||
### Disable scroll
|
||||
|
||||
```html
|
||||
<van-notice-bar :scrollable="false">
|
||||
Notice Content
|
||||
</van-notice-bar>
|
||||
```
|
||||
|
||||
### Wrapable
|
||||
|
||||
```html
|
||||
<van-notice-bar wrapable :scrollable="false">
|
||||
Notice Content
|
||||
</van-notice-bar>
|
||||
```
|
||||
|
||||
### Mode
|
||||
|
||||
```html
|
||||
<van-notice-bar mode="closeable">
|
||||
Notice Content
|
||||
</van-notice-bar>
|
||||
|
||||
<van-notice-bar mode="link">
|
||||
Notice Content
|
||||
</van-notice-bar>
|
||||
```
|
||||
|
||||
### Custom Style
|
||||
|
||||
```html
|
||||
<van-notice-bar
|
||||
color="#1989fa"
|
||||
background="#ecf9ff"
|
||||
left-icon="info-o"
|
||||
>
|
||||
Notice Content
|
||||
</van-notice-bar>
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
||||
| Attribute | Description | Type | Default |
|
||||
|------|------|------|------|
|
||||
| mode | Mode, can be set to `closeable` `link` | `String` | `''` |
|
||||
| text | Notice text content | `String` | `''` | - |
|
||||
| delay | Animation delay (s) | `Number` | `1` |
|
||||
| speed | Scroll speed (px/s) | `Number` | `50` |
|
||||
| scrollable | Whether to scroll content | `Boolean` | `true` |
|
||||
| wrapable | Whether to enable text wrap | `Boolean` | `false` | - |
|
||||
| left-icon | Left Icon | `String` | - |
|
||||
| color | Text color | `String` | `#f60` |
|
||||
| background | Background color | `String` | `#fff7cc` |
|
||||
|
||||
### Events
|
||||
|
||||
| Event | Description | Arguments |
|
||||
|------|------|------|
|
||||
| click | Triggered when click NoticeBar | - |
|
||||
| close | Triggered when closed | - |
|
||||
|
||||
### Slots
|
||||
|
||||
| Name | Description |
|
||||
|------|------|
|
||||
| default | Notice text content |
|
||||
| left-icon | Custom left icon |
|
||||
| right-icon | Custom right icon |
|
||||
@@ -0,0 +1,148 @@
|
||||
import { createNamespace } from '../utils';
|
||||
import Icon from '../icon';
|
||||
|
||||
const [createComponent, bem] = createNamespace('notice-bar');
|
||||
|
||||
export default createComponent({
|
||||
props: {
|
||||
text: String,
|
||||
mode: String,
|
||||
color: String,
|
||||
leftIcon: String,
|
||||
wrapable: Boolean,
|
||||
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() {
|
||||
if (this.mode === 'closeable') {
|
||||
this.showNoticeBar = false;
|
||||
this.$emit('close');
|
||||
}
|
||||
},
|
||||
|
||||
onAnimationEnd() {
|
||||
this.firstRound = false;
|
||||
this.$nextTick(() => {
|
||||
this.duration = (this.offsetWidth + this.wrapWidth) / this.speed;
|
||||
this.animationClass = bem('play--infinite');
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
render(h) {
|
||||
const { slots, mode, leftIcon, onClickIcon } = this;
|
||||
|
||||
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'
|
||||
};
|
||||
|
||||
function LeftIcon() {
|
||||
const slot = slots('left-icon');
|
||||
|
||||
if (slot) {
|
||||
return slot;
|
||||
}
|
||||
|
||||
if (leftIcon) {
|
||||
return <Icon class={bem('left-icon')} name={leftIcon} />;
|
||||
}
|
||||
}
|
||||
|
||||
function RightIcon() {
|
||||
const slot = slots('right-icon');
|
||||
|
||||
if (slot) {
|
||||
return slot;
|
||||
}
|
||||
|
||||
const iconName = mode === 'closeable' ? 'cross' : mode === 'link' ? 'arrow' : '';
|
||||
if (iconName) {
|
||||
return <Icon class={bem('right-icon')} name={iconName} onClick={onClickIcon} />;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
role="alert"
|
||||
vShow={this.showNoticeBar}
|
||||
class={bem({ wrapable: this.wrapable })}
|
||||
style={barStyle}
|
||||
onClick={() => {
|
||||
this.$emit('click');
|
||||
}}
|
||||
>
|
||||
{LeftIcon()}
|
||||
<div ref="wrap" class={bem('wrap')} role="marquee">
|
||||
<div
|
||||
ref="content"
|
||||
class={[
|
||||
bem('content'),
|
||||
this.animationClass,
|
||||
{ 'van-ellipsis': !this.scrollable && !this.wrapable }
|
||||
]}
|
||||
style={contentStyle}
|
||||
onAnimationend={this.onAnimationEnd}
|
||||
onWebkitAnimationEnd={this.onAnimationEnd}
|
||||
>
|
||||
{this.slots() || this.text}
|
||||
</div>
|
||||
</div>
|
||||
{RightIcon()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,75 @@
|
||||
@import '../style/var';
|
||||
|
||||
.van-notice-bar {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: @notice-bar-height;
|
||||
padding: @notice-bar-padding;
|
||||
color: @notice-bar-text-color;
|
||||
font-size: @notice-bar-font-size;
|
||||
line-height: @notice-bar-line-height;
|
||||
background-color: @notice-bar-background-color;
|
||||
|
||||
&__left-icon,
|
||||
&__right-icon {
|
||||
min-width: @notice-bar-icon-min-width;
|
||||
font-size: @notice-bar-icon-size;
|
||||
}
|
||||
|
||||
&__right-icon {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&__wrap {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
height: @notice-bar-line-height;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&__content {
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
|
||||
&.van-ellipsis {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&__play {
|
||||
animation: van-notice-bar-play linear both;
|
||||
|
||||
&--infinite {
|
||||
animation: van-notice-bar-play-infinite linear infinite both;
|
||||
}
|
||||
}
|
||||
|
||||
&--wrapable {
|
||||
height: auto;
|
||||
padding: @notice-bar-wrapable-padding;
|
||||
|
||||
.van-notice-bar {
|
||||
&__wrap {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
&__content {
|
||||
position: relative;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare two same keyframes
|
||||
* In case that some mobile browsers can continue animation when className changed
|
||||
*/
|
||||
@keyframes van-notice-bar-play {
|
||||
to { transform: translate3d(-100%, 0, 0); }
|
||||
}
|
||||
|
||||
@keyframes van-notice-bar-play-infinite {
|
||||
to { transform: translate3d(-100%, 0, 0); }
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders demo correctly 1`] = `
|
||||
<div>
|
||||
<div>
|
||||
<div role="alert" class="van-notice-bar"><i class="van-icon van-icon-volume-o van-notice-bar__left-icon">
|
||||
<!----></i>
|
||||
<div role="marquee" class="van-notice-bar__wrap">
|
||||
<div class="van-notice-bar__content" style="padding-left: 0px; animation-delay: 1s; animation-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div role="alert" class="van-notice-bar">
|
||||
<div role="marquee" class="van-notice-bar__wrap">
|
||||
<div class="van-notice-bar__content van-ellipsis" style="padding-left: 0px; animation-delay: 1s; animation-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div role="alert" class="van-notice-bar van-notice-bar--wrapable">
|
||||
<div role="marquee" class="van-notice-bar__wrap">
|
||||
<div class="van-notice-bar__content" style="padding-left: 0px; animation-delay: 1s; animation-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div role="alert" class="van-notice-bar">
|
||||
<div role="marquee" class="van-notice-bar__wrap">
|
||||
<div class="van-notice-bar__content" style="padding-left: 0px; animation-delay: 1s; animation-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
||||
</div><i class="van-icon van-icon-cross van-notice-bar__right-icon">
|
||||
<!----></i>
|
||||
</div>
|
||||
<div role="alert" class="van-notice-bar">
|
||||
<div role="marquee" class="van-notice-bar__wrap">
|
||||
<div class="van-notice-bar__content" style="padding-left: 0px; animation-delay: 1s; animation-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
||||
</div><i class="van-icon van-icon-arrow van-notice-bar__right-icon">
|
||||
<!----></i>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div role="alert" class="van-notice-bar" style="color: rgb(25, 137, 250); background: rgb(236, 249, 255);"><i class="van-icon van-icon-info-o van-notice-bar__left-icon">
|
||||
<!----></i>
|
||||
<div role="marquee" class="van-notice-bar__wrap">
|
||||
<div class="van-notice-bar__content" style="padding-left: 0px; animation-delay: 1s; animation-duration: 0s;">足协杯战线连续第2年上演广州德比战,上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -0,0 +1,9 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`icon slot 1`] = `
|
||||
<div role="alert" class="van-notice-bar">Custom Left Icon<div role="marquee" class="van-notice-bar__wrap">
|
||||
<div class="van-notice-bar__content" style="padding-left: 0px; animation-delay: 1s; animation-duration: 0s;">
|
||||
Content
|
||||
</div>
|
||||
</div>Custom Right Icon</div>
|
||||
`;
|
||||
@@ -0,0 +1,4 @@
|
||||
import Demo from '../demo';
|
||||
import demoTest from '../../../test/demo-test';
|
||||
|
||||
demoTest(Demo);
|
||||
@@ -0,0 +1,31 @@
|
||||
import NoticeBar from '..';
|
||||
import { mount } from '../../../test/utils';
|
||||
|
||||
test('close event', () => {
|
||||
const wrapper = mount(NoticeBar, {
|
||||
propsData: {
|
||||
mode: 'closeable'
|
||||
}
|
||||
});
|
||||
const close = wrapper.find('.van-notice-bar__right-icon');
|
||||
|
||||
close.trigger('click');
|
||||
expect(wrapper.emitted('close')).toBeTruthy();
|
||||
});
|
||||
|
||||
test('icon slot', () => {
|
||||
const wrapper = mount({
|
||||
template: `
|
||||
<notice-bar>
|
||||
Content
|
||||
<template v-slot:left-icon>Custom Left Icon</template>
|
||||
<template v-slot:right-icon>Custom Right Icon</template>
|
||||
</notice-bar>
|
||||
`,
|
||||
components: {
|
||||
NoticeBar
|
||||
}
|
||||
});
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
@@ -0,0 +1,99 @@
|
||||
# NoticeBar 通知栏
|
||||
|
||||
### 引入
|
||||
|
||||
``` javascript
|
||||
import { NoticeBar } from 'vant';
|
||||
|
||||
Vue.use(NoticeBar);
|
||||
```
|
||||
|
||||
## 代码演示
|
||||
|
||||
### 基础用法
|
||||
|
||||
```html
|
||||
<van-notice-bar
|
||||
text="通知内容"
|
||||
left-icon="volume-o"
|
||||
/>
|
||||
```
|
||||
|
||||
### 禁用滚动
|
||||
|
||||
文字内容多于一行时,可通过`scrollable`参数控制是否开启滚动
|
||||
|
||||
```html
|
||||
<van-notice-bar :scrollable="false">
|
||||
通知内容
|
||||
</van-notice-bar>
|
||||
```
|
||||
|
||||
### 多行展示
|
||||
|
||||
禁用滚动时,可以设置`wrapable`来开启多行展示
|
||||
|
||||
```html
|
||||
<van-notice-bar wrapable :scrollable="false">
|
||||
通知内容
|
||||
</van-notice-bar>
|
||||
```
|
||||
|
||||
### 通知栏模式
|
||||
|
||||
默认模式为空,支持`closeable`和`link`两种模式
|
||||
|
||||
```html
|
||||
<!-- closeable 模式,在右侧显示关闭按钮 -->
|
||||
<van-notice-bar mode="closeable">
|
||||
通知内容
|
||||
</van-notice-bar>
|
||||
|
||||
<!-- link 模式,在右侧显示链接箭头 -->
|
||||
<van-notice-bar mode="link">
|
||||
通知内容
|
||||
</van-notice-bar>
|
||||
```
|
||||
|
||||
### 自定义样式
|
||||
|
||||
```html
|
||||
<van-notice-bar
|
||||
color="#1989fa"
|
||||
background="#ecf9ff"
|
||||
left-icon="info-o"
|
||||
>
|
||||
通知内容
|
||||
</van-notice-bar>
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Props
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
|------|------|------|------|------|
|
||||
| mode | 通知栏模式,可选值为 `closeable` `link` | `String` | `''` | - |
|
||||
| text | 通知文本内容 | `String` | `''` | - |
|
||||
| delay | 动画延迟时间 (s) | `Number` | `1` | - |
|
||||
| speed | 滚动速率 (px/s) | `Number` | `50` | - |
|
||||
| scrollable | 是否在长度溢出时滚动播放 | `Boolean` | `true` | - |
|
||||
| wrapable | 是否开启文本换行,只在禁用滚动时生效 | `Boolean` | `false` | 1.6.11 |
|
||||
| left-icon | 左侧图标名称或图片链接,可选值见 Icon 组件 | `String` | - | - |
|
||||
| color | 文本颜色 | `String` | `#f60` | - |
|
||||
| background | 滚动条背景 | `String` | `#fff7cc` | - |
|
||||
|
||||
### Events
|
||||
|
||||
| 事件名 | 说明 | 回调参数 |
|
||||
|------|------|------|
|
||||
| click | 点击通知栏时触发 | - |
|
||||
| close | 关闭通知栏时触发 | - |
|
||||
|
||||
### Slots
|
||||
|
||||
| 名称 | 内容 |
|
||||
|------|------|
|
||||
| default | 通知文本内容 |
|
||||
| left-icon | 自定义左侧图标 |
|
||||
| right-icon | 自定义右侧图标 |
|
||||
Reference in New Issue
Block a user