提交 29ff3666 编写于 作者: A Amy 提交者: doly mood

Dev toolbar (#193)

* [init] toolbar

* update(demo): toolbar

* update(doc): toolbar

* test: toolbar unit
上级 9e5709ab
......@@ -96,7 +96,8 @@
"subList": {
"button": "Button",
"loading": "Loading",
"tip": "Tip"
"tip": "Tip",
"toolbar": "Toolbar"
}
},
"form": {
......
## Toolbar
> New in 1.9.0+
Toolbar, with actions & more-actions.
### Example
- Basic
You can use `actions` to define the toolbar actions.
```html
<cube-toolbar :actions="actions" @click="clickHandler"></cube-toolbar>
```
```js
export default {
data() {
return {
money: 10,
actions: [
{
text: '完成订单',
action: 'showText'
},
{
text: '打车来接',
checked: false,
type: 'checkbox'
},
{
text: '一口价<span class="orange">10元</span>',
action: 'moreMoney'
}
]
}
},
methods: {
showText(item) {
this.$createToast({
type: 'correct',
txt: 'clicked ' + item.text,
time: 1000
}).show()
},
moreMoney(item) {
this.money += 10
item.text = '一口价<span class="orange">' + this.money + '元</span>'
},
clickHandler(item) {
if (item.action) {
this[item.action](item)
}
}
}
}
```
You can use handle the action in `click` event handler.
- More actions
You can use `moreActions` to define more actions.
```html
<cube-toolbar
:actions="actions"
:more-actions="moreActions"
@click="clickHandler"></cube-toolbar>
```
```js
export default {
data() {
let money = 10
return {
actions: [
{
text: '完成订单',
action: 'showText'
},
{
text: '打车来接',
checked: false,
type: 'checkbox'
},
{
text: '一口价<span class="orange">10元</span>',
action: 'moreMoney'
}
],
moreActions: [
{
text: '操作a',
action: 'showText'
},
{
text: '操作b',
action: 'showText'
},
{
text: '操作c',
icon: 'cubeic-right',
action: 'showText'
}
]
}
},
methods: {
showText(item) {
this.$createToast({
type: 'correct',
txt: 'clicked ' + item.text,
time: 1000
}).show()
},
moreMoney(item) {
this.money += 10
item.text = '一口价<span class="orange">' + this.money + '元</span>'
},
clickHandler(item) {
if (item.action) {
this[item.action](item)
}
}
}
}
```
### Props
| Attribute | Description | Type | Accepted Values | Demo |
| - | - | - | - | - |
| actions | actions description | Array | [] | [ {text: '完成订单' } ] |
| moreActions | more actions | Array | [] | [ {text: '完成订单' } ] |
* `actions` sub configuration
| Attribute | Description | Type | Accepted Values | Default |
| - | - | - | - | - |
| type | type, button or checkbox | String | button/checkbox | button |
| text | text, support html string | String | - | '' |
| checked | if type is checkbox, then this value will be the Checkbox's model alue | Boolean | true/false | false |
### Events
| Event Name | Description | Parameters |
| - | - | - |
| click | clicked one item | item value |
| more-click | clicked more item | whether more actions is visible |
## Toolbar
> 1.9.0 新增
工具栏,可以组合多个按钮,复选框操作为一个工具栏。
### 示例
- 基础使用
将每个操作的类型和文本传入 `actions` 属性。
```html
<cube-toolbar :actions="actions" @click="clickHandler"></cube-toolbar>
```
```js
export default {
data() {
return {
money: 10,
actions: [
{
text: '完成订单',
action: 'showText'
},
{
text: '打车来接',
checked: false,
type: 'checkbox'
},
{
text: '一口价<span class="orange">10元</span>',
action: 'moreMoney'
}
]
}
},
methods: {
showText(item) {
this.$createToast({
type: 'correct',
txt: 'clicked ' + item.text,
time: 1000
}).show()
},
moreMoney(item) {
this.money += 10
item.text = '一口价<span class="orange">' + this.money + '元</span>'
},
clickHandler(item) {
if (item.action) {
this[item.action](item)
}
}
}
}
```
- 更多操作
你还可以通过 `moreActions` 属性传入更多操作,就会把工具栏扩展成可展开收起的双层工具栏。
```html
<cube-toolbar
:actions="actions"
:more-actions="moreActions"
@click="clickHandler"></cube-toolbar>
```
```js
export default {
data() {
let money = 10
return {
actions: [
{
text: '完成订单',
action: 'showText'
},
{
text: '打车来接',
checked: false,
type: 'checkbox'
},
{
text: '一口价<span class="orange">10元</span>',
action: 'moreMoney'
}
],
moreActions: [
{
text: '操作a',
action: 'showText'
},
{
text: '操作b',
action: 'showText'
},
{
text: '操作c',
icon: 'cubeic-right',
action: 'showText'
}
]
}
},
methods: {
showText(item) {
this.$createToast({
type: 'correct',
txt: 'clicked ' + item.text,
time: 1000
}).show()
},
moreMoney(item) {
this.money += 10
item.text = '一口价<span class="orange">' + this.money + '元</span>'
},
clickHandler(item) {
if (item.action) {
this[item.action](item)
}
}
}
}
```
### Props 配置
| 参数 | 说明 | 类型 | 默认值 | 示例 |
| - | - | - | - | - |
| actions | 定义一组操作 | Array | [] | [ {text: '完成订单' } ] |
| moreActions | 定义更多的一组操作 | Array | [] | [ {text: '完成订单' } ] |
* `actions` 子配置项
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| - | - | - | - | - |
| type | 类型,包括 button 和 checkbox | String | button/checkbox | button |
| text | 文案,支持写入 html | String | - | '' |
| checked | 当为 checkbox 类型时,checkbox的初始状态 | Boolean | true/false | false |
### 事件
| 事件名 | 说明 | 参数 |
| - | - | - |
| click | 点击某一项触发 | 该项 item 的值 |
| more-click | 当有更多操作时,点击更多按钮时触发 | 更多操作是否是显示状态 |
......@@ -43,6 +43,10 @@
{
path: '/tip',
text: 'Tip'
},
{
path: '/toolbar',
text: 'Toolbar'
}
]
},
......
<template>
<cube-page type="toolbar" title="Toolbar" class="option-demo">
<div slot="content">
<div class="options">
<div class="option-list">
<div class="group">
<switch-option class="item" name="More Actions" :value="more"
@update:value="updateMore"></switch-option>
</div>
</div>
</div>
<cube-toolbar
:actions="actions"
:more-actions="more ? moreActions : undefined"
@click="clickHandler">
</cube-toolbar>
</div>
</cube-page>
</template>
<script type="text/ecmascript-6">
import CubePage from 'example/components/cube-page.vue'
import SwitchOption from 'example/components/switch-option.vue'
export default {
components: {
CubePage,
SwitchOption
},
data() {
return {
more: true,
money: 10,
actions: [
{
text: '完成订单',
action: 'showText'
},
{
text: '打车来接',
checked: false,
type: 'checkbox'
},
{
text: '一口价<span class="orange">10元</span>',
action: 'moreMoney'
}
],
moreActions: [
{
text: '操作a',
action: 'showText'
},
{
text: '操作b',
action: 'showText'
},
{
text: '操作c',
icon: 'cubeic-right',
action: 'showText'
}
]
}
},
methods: {
updateMore(val) {
this.more = val
},
showText(item) {
this.$createToast({
type: 'correct',
txt: 'clicked ' + item.text,
time: 1000
}).show()
},
moreMoney(item) {
this.money += 10
item.text = '一口价<span class="orange">' + this.money + '元</span>'
},
clickHandler(item) {
if (item.action) {
this[item.action](item)
}
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
</style>
......@@ -43,6 +43,7 @@ import DrawerCustom from '../pages/drawer/custom.vue'
import Slide from '../pages/slide/index.vue'
import SlideVertical from '../pages/slide/vertical.vue'
import SlideHorizontal from '../pages/slide/horizontal.vue'
import Toolbar from '../pages/toolbar.vue'
const routes = [
{
......@@ -236,6 +237,10 @@ const routes = [
component: SlideHorizontal
}
]
},
{
path: '/toolbar',
component: Toolbar
}
]
......
......@@ -48,3 +48,7 @@
content: "\e624"
.cubeic-eye-visible::before
content: "\e625"
.cubeic-more::before
content: "\e607"
.cubeic-pulldown::before
content: "\e603"
......@@ -47,6 +47,10 @@ $btn-outline-primary-bdc := $color-orange
$btn-outline-primary-active-bgc := $color-orange-opacity
$btn-outline-primary-active-bdc := $color-dark-orange
// toolbar
$toolbar-bgc := $color-light-grey-sss
$toolbar-active-bgc := $color-active-grey
// checkbox
$checkbox-color := $color-grey
$checkbox-icon-color := $color-light-grey-s
......
<template>
<li class="cube-toolbar-item border-right-1px">
<cube-button :icon="action.icon" @click="clickHandler">
<cube-checkbox
class="cube-toolbar-chb"
v-model="action.checked"
v-if="action.type == 'checkbox'"
:label="action.text">
</cube-checkbox>
<span v-else v-html="action.text"></span>
</cube-button>
<i class="cube-toolbar-down"></i>
</li>
</template>
<script>
import CubeButton from '../button/button'
import CubeCheckbox from '../checkbox/checkbox'
const COMPONENT_NAME = 'cube-toolbar-item'
const EVENT_CLICK = 'click'
export default {
name: COMPONENT_NAME,
components: {
CubeButton,
CubeCheckbox
},
props: {
action: {
type: Object,
default() {
/* istanbul ignore next */
return {}
}
}
},
methods: {
clickHandler() {
this.$emit(EVENT_CLICK)
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@require "../../common/stylus/variable.styl"
@require "../../common/stylus/mixin.styl"
.cube-toolbar-item
display: flex
flex-fix()
align-items: center
background-color: $toolbar-bgc
&:last-child
position: static
&::after
display: none
&:active
background-color: $toolbar-active-bgc
&:active
&::after
border-color: transparent
/* reset cube-checkbox style */
.cube-toolbar-chb
height: 44px
padding: 0
font-size: $fontsize-small
background-color: transparent
.cube-checkbox-wrap
padding: 0
justify-content: center
.cube-checkbox-ui
position: relative
left: auto
margin-right: .42em
/* reset cube-btn style */
.cube-btn
position: relative
padding: 0 5px
background-color: transparent
border: 0 none
color: $color-grey
font-size: $fontsize-small
&:active
background-color: transparent
&:active::after
display: none
i
margin-right: 0
&.cubeic-more
color: $color-light-grey
font-size: $fontsize-large
</style>
<template>
<div class="cube-toolbar">
<ul
class="cube-toolbar-group cube-toolbar-group-more"
v-if="moreActions"
v-show="showMore">
<cube-toolbar-item
v-for="(action, index) in moreActions"
:key="index"
:action="action"
@click="itemClick(action)"></cube-toolbar-item>
</ul>
<ul class="cube-toolbar-group">
<cube-toolbar-item
v-for="(action, index) in basicActions"
:key="index"
:action="action"
@click="itemClick(action)"></cube-toolbar-item>
</ul>
</div>
</template>
<script>
import CubeToolbarItem from './toolbar-item.vue'
const COMPONENT_NAME = 'cube-toolbar'
const EVENT_CLICK = 'click'
const EVENT_MORE_CLICK = 'more-click'
export default {
name: COMPONENT_NAME,
components: {
CubeToolbarItem
},
props: {
actions: {
type: Array,
default() {
/* istanbul ignore next */
return []
}
},
moreActions: {
type: Array
}
},
data() {
return {
showMore: false
}
},
computed: {
basicActions() {
const basicActions = this.actions.slice()
this.moreActions && basicActions.push({
icon: 'cubeic-more',
$cubeMore: true
})
return basicActions
}
},
methods: {
itemClick(action) {
if (action.$cubeMore) {
this.showMore = !this.showMore
this.$emit(EVENT_MORE_CLICK, this.showMore)
} else {
this.$emit(EVENT_CLICK, action)
}
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@require "../../common/stylus/variable.styl"
@require "../../common/stylus/mixin.styl"
$toolbar-spacing = 10px
.cube-toolbar
position: fixed
left: $toolbar-spacing
right: $toolbar-spacing
bottom: $toolbar-spacing
z-index: 2
safe-area-mixin(padding-bottom, bottom)
.cube-toolbar-group
display: flex
height: 44px
overflow: hidden
box-sizing: border-box
border-radius: 2px
box-shadow: 0 1px 6px rgba(0, 0, 0, .24)
background-color: $toolbar-bgc
.cube-toolbar-group-more
margin-bottom: $toolbar-spacing
.cube-toolbar-item
&:last-child
.cube-toolbar-down
position: absolute
top: 44px
right: 9%
height: $toolbar-spacing
color: $toolbar-bgc
font-size: $fontsize-large-xxx
font-family: cube-icon
font-style: normal
text-shadow: 0 1px 3px $toolbar-active-bgc
transform: scale(1.3)
&::before
content: "\E603"
position: relative
top: -10px
&::after
content: ""
display: block
position: absolute
left: 30%
top: 50%
margin-top: -6px
width: 40%
height: 2px
background-color: $toolbar-bgc
&:active
.cube-toolbar-down
color: $toolbar-active-bgc
&::after
background-color: $toolbar-active-bgc
</style>
......@@ -5,6 +5,7 @@ import {
Button,
Loading,
Tip,
Toolbar,
// form
Checkbox,
CheckboxGroup,
......@@ -45,6 +46,7 @@ const components = [
Button,
Loading,
Tip,
Toolbar,
// form
Checkbox,
CheckboxGroup,
......
......@@ -4,6 +4,7 @@ import Style from './modules/style'
import Button from './modules/button'
import Loading from './modules/loading'
import Tip from './modules/tip'
import Toolbar from './modules/toolbar'
// Form
import Checkbox from './modules/checkbox'
......@@ -55,6 +56,7 @@ export {
Button,
Loading,
Tip,
Toolbar,
// form
Checkbox,
CheckboxGroup,
......
import Button from '../../components/button/button.vue'
import Checkbox from '../../components/checkbox/checkbox.vue'
import Toolbar from '../../components/toolbar/toolbar.vue'
Toolbar.install = function (Vue) {
Vue.component(Button.name, Button)
Vue.component(Checkbox.name, Checkbox)
Vue.component(Toolbar.name, Toolbar)
}
Toolbar.Button = Button
Toolbar.Checkbox = Checkbox
export default Toolbar
import Vue from 'vue2'
import Toolbar from '@/modules/toolbar'
import instantiateComponent from '@/common/helpers/instantiate-component'
describe('Toolbar.vue', () => {
let vm
afterEach(() => {
if (vm) {
vm.$parent.destroy()
vm = null
}
})
it('use', () => {
Vue.use(Toolbar)
expect(Vue.component(Toolbar.name))
.to.be.a('function')
})
it('should render correct contents', () => {
vm = instantiateComponent(Vue, Toolbar, {
props: {
actions: [
{
text: '完成订单',
action: 'showText'
},
{
text: '打车来接',
checked: false,
type: 'checkbox'
}
]
}
})
expect(vm.$el.querySelectorAll('.cube-toolbar-group').length)
.to.equal(1)
const items = vm.$el.querySelectorAll('.cube-toolbar-item')
expect(items.length)
.to.equal(2)
expect(items[0].querySelector('.cube-btn').textContent.trim())
.to.equal('完成订单')
expect(items[1].querySelector('.cube-checkbox-label').textContent.trim())
.to.equal('打车来接')
})
it('should render correct contents - more actions', () => {
vm = instantiateComponent(Vue, Toolbar, {
props: {
actions: [
{
text: '完成订单',
action: 'showText'
},
{
text: '打车来接',
checked: false,
type: 'checkbox'
}
],
moreActions: [
{
text: '操作a',
action: 'showText'
}
]
}
})
const groups = vm.$el.querySelectorAll('.cube-toolbar-group')
expect(groups.length)
.to.equal(2)
const items = groups[0].querySelectorAll('.cube-toolbar-item')
expect(items.length)
.to.equal(1)
expect(items[0].querySelector('.cube-btn').textContent.trim())
.to.equal('操作a')
// 2 + 1 more action
expect(groups[1].querySelectorAll('.cube-toolbar-item').length)
.to.equal(3)
})
it('should trigger events', () => {
const itemHandler = sinon.spy()
const moreHandler = sinon.spy()
const actions = [
{
text: '完成订单',
action: 'showText'
},
{
text: '打车来接',
checked: false,
type: 'checkbox'
}
]
vm = instantiateComponent(Vue, Toolbar, {
props: {
actions,
moreActions: [
{
text: '操作a',
action: 'showText'
}
]
},
on: {
click: itemHandler,
'more-click': moreHandler
}
})
const groups = vm.$el.querySelectorAll('.cube-toolbar-group')
groups[1].querySelector('.cube-btn').click()
expect(itemHandler)
.to.be.calledOnce
expect(itemHandler)
.to.be.calledWith(actions[0])
groups[1].querySelector('.cube-toolbar-item:last-child .cube-btn').click()
expect(moreHandler)
.to.be.calledOnce
expect(moreHandler)
.to.be.calledWith(true)
})
})
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册