Merge branch 'master' of gitlab.qima-inc.com:fe/oxygen

This commit is contained in:
niunai
2017-02-22 19:26:22 +08:00
24 changed files with 624 additions and 62 deletions
+3 -3
View File
@@ -1,15 +1,15 @@
<template>
<a class="z-cell" :href="url" @click="handleClick">
<div class="z-cell-title">
<div class="z-cell__title">
<slot name="icon">
<i v-if="icon" class="zui-icon" :class="'zui-icon-' + icon"></i>
</slot>
<slot name="title">
<span class="z-cell-text" v-text="title"></span>
<span class="z-cell-label" v-if="label" v-text="label"></span>
<span class="z-cell__abel" v-if="label" v-text="label"></span>
</slot>
</div>
<div class="z-cell-value" :class="{ 'is-link' : isLink }">
<div class="z-cell__value" :class="{ 'is-link' : isLink }">
<slot>
<span v-text="value"></span>
</slot>
+2 -2
View File
@@ -8,7 +8,7 @@
}">
<textarea
v-if="type === 'textarea'"
class="z-field-control"
class="z-field__control"
v-model="currentValue"
@change="$emit('change', currentValue)"
:placeholder="placeholder"
@@ -18,7 +18,7 @@
</textarea>
<input
v-else
class="z-field-control"
class="z-field__control"
:value="currentValue"
@change="$emit('change', currentValue)"
@input="handleInput"
+51
View File
@@ -0,0 +1,51 @@
import Vue from 'vue';
let isDragging = false;
const supportTouch = !Vue.prototype.$isServer && 'ontouchstart' in window;
export default function(element, options) {
const moveFn = function(event) {
if (options.drag) {
options.drag(supportTouch ? event.changedTouches[0] || event.touches[0] : event);
}
};
const endFn = function(event) {
if (!supportTouch) {
document.removeEventListener('mousemove', moveFn);
document.removeEventListener('mouseup', endFn);
}
document.onselectstart = null;
document.ondragstart = null;
isDragging = false;
if (options.end) {
options.end(supportTouch ? event.changedTouches[0] || event.touches[0] : event);
}
};
element.addEventListener(supportTouch ? 'touchstart' : 'mousedown', function(event) {
if (isDragging) return;
document.onselectstart = function() { return false; };
document.ondragstart = function() { return false; };
if (!supportTouch) {
document.addEventListener('mousemove', moveFn);
document.addEventListener('mouseup', endFn);
}
isDragging = true;
if (options.start) {
event.preventDefault();
options.start(supportTouch ? event.changedTouches[0] || event.touches[0] : event);
}
});
if (supportTouch) {
element.addEventListener('touchmove', moveFn);
element.addEventListener('touchend', endFn);
element.addEventListener('touchcancel', endFn);
}
};
+174 -9
View File
@@ -1,14 +1,21 @@
<template>
<div class="z-picker-column">
<div class="z-picker-column-wrapper">
<div class="z-picker-item">
<div class="z-picker-column" :class="classNames">
<div class="z-picker-column-wrapper" :class="{ dragging: isDragging }" ref="wrapper" :style="{ height: visibleContentHeight + 'px' }">
<div
v-for="item in currentValues"
class="z-picker-column__item"
:class="{ 'z-picker-column__item--selected': item === currentValue }"
:style="{ height: itemHeight + 'px', lineHeight: itemHeight + 'px' }">
{{item}}
</div>
</div>
</div>
</template>
<script>
import translateUtil from 'src/utils/transition';
import draggable from './draggable';
const DEFAULT_ITEM_HEIGHT = 44;
export default {
@@ -22,13 +29,25 @@ export default {
type: Number,
default: 5
},
/**
* 该列所有的可选值
*/
values: {
type: Array,
default() {
return [];
}
},
className: {},
/**
* 每列添加额外的`className`
*/
className: {
type: String,
default: ''
},
/**
* 行高
*/
itemHeight: {
type: Number,
default: DEFAULT_ITEM_HEIGHT
@@ -40,20 +59,24 @@ export default {
return {
currentValue: this.value,
currentValues: this.values,
dragging: false
isDragging: false
};
},
watch: {
values(val) {
this.currentValue = val;
this.currentValues = val;
},
currentValues(val) {
if (this.valueIndex === -1) {
this.currentValue = (val || [])[0];
}
},
currentValue(val) {
this.doOnValueChange();
this.$emit('change', this);
}
},
@@ -64,11 +87,153 @@ export default {
*/
visibleContentHeight() {
return this.itemHeight * this.visibileColumnCount;
},
/**
* 当前选中值在`values`中的索引
*/
valueIndex() {
return this.currentValues.indexOf(this.currentValue);
},
/**
* 计算picker的拖动范围
*/
dragRange() {
var values = this.currentValues;
var visibileColumnCount = this.visibileColumnCount;
var itemHeight = this.itemHeight;
return [ -itemHeight * (values.length - Math.ceil(visibileColumnCount / 2)), itemHeight * Math.floor(visibileColumnCount / 2) ];
},
/**
* 计算`classNames`
*/
classNames() {
return this.className.split(' ');
}
},
methods: {
mounted() {
this.initEvents();
this.doOnValueChange();
},
methods: {
/**
* 将当前`value`值转换成需要垂直方向需要`translate`的值
*/
value2Translate(value) {
let values = this.currentValues;
let valueIndex = values.indexOf(value);
let offset = Math.floor(this.visibileColumnCount / 2);
let itemHeight = this.itemHeight;
if (valueIndex !== -1) {
return (valueIndex - offset) * (-itemHeight);
}
},
/**
* 根据当前`translate`的值转换成当前选中的`value`
*/
translate2Value(translate) {
let itemHeight = this.itemHeight;
translate = Math.round(translate / itemHeight) * itemHeight;
let index = -(translate - Math.floor(this.visibileColumnCount / 2) * itemHeight) / itemHeight;
return this.currentValues[index];
},
/**
* 初始化拖动事件
*/
initEvents() {
var el = this.$refs.wrapper;
var dragState = {};
var velocityTranslate, prevTranslate, pickerItems;
draggable(el, {
start: (event) => {
// 存储当前状态
dragState = {
range: this.dragRange,
start: new Date(),
startLeft: event.pageX,
startTop: event.pageY,
startTranslateTop: translateUtil.getElementTranslate(el).top
};
pickerItems = el.querySelectorAll('.z-picker-item');
},
drag: (event) => {
this.isDragging = true;
dragState.left = event.pageX;
dragState.top = event.pageY;
let deltaY = dragState.top - dragState.startTop;
let translate = dragState.startTranslateTop + deltaY;
translateUtil.translateElement(el, null, translate);
velocityTranslate = translate - prevTranslate || translate;
prevTranslate = translate;
},
end: () => {
if (this.isDragging) {
this.isDragging = false;
var momentumRatio = 7;
var currentTranslate = translateUtil.getElementTranslate(el).top;
var duration = new Date() - dragState.start;
var momentumTranslate;
if (duration < 300) {
momentumTranslate = currentTranslate + velocityTranslate * momentumRatio;
}
var dragRange = dragState.range;
this.$nextTick(() => {
var translate;
var itemHeight = this.itemHeight;
if (momentumTranslate) {
translate = Math.round(momentumTranslate / itemHeight) * itemHeight;
} else {
translate = Math.round(currentTranslate / itemHeight) * itemHeight;
}
translate = Math.max(Math.min(translate, dragRange[1]), dragRange[0]);
translateUtil.translateElement(el, null, translate);
this.currentValue = this.translate2Value(translate);
});
}
dragState = {};
}
});
},
/**
* `value`改变时调用
*/
doOnValueChange() {
let value = this.currentValue;
let wrapper = this.$refs.wrapper;
this.$emit('input', this.currentValue);
translateUtil.translateElement(wrapper, null, this.value2Translate(value));
}
}
};
</script>
+6 -4
View File
@@ -1,10 +1,10 @@
<template>
<div class="z-picker">
<div class="z-picker-toolbar">
<div class="z-picker__toolbar">
<slot>
</slot>
</div>
<div class="z-picker-columns">
<div class="z-picker__columns" :class="['z-picker__columns--' + columns.length]">
<picker-column
v-for="(item, index) in columns"
v-model="values[index]"
@@ -14,6 +14,7 @@
:visible-item-count="visibleItemCount"
@change="columnValueChange">
</picker-column>
<div class="z-picker-center-highlight" :style="{ height: itemHeight + 'px', marginTop: -itemHeight / 2 + 'px' }"></div>
</div>
</div>
</template>
@@ -69,7 +70,7 @@ export default {
let values = [];
columns.forEach(column => {
values.push(column.value || column[column.defaultIndex || 0]);
values.push(column.value || column.values[column.defaultIndex || 0]);
});
return values;
@@ -97,7 +98,8 @@ export default {
*/
getColumnValue(index) {
let column = this.getColumn(index);
return column && column.value;
console.log(column)
return column && column.values[column.valueIndex];
},
/**
+8
View File
@@ -0,0 +1,8 @@
## 0.0.2 (2017-01-20)
* 改了bug A
* 加了功能B
## 0.0.1 (2017-01-10)
* 第一版
+26
View File
@@ -0,0 +1,26 @@
# @youzan/<%= name %>
!!! 请在此处填写你的文档最简单描述 !!!
[![version][version-image]][download-url]
[![download][download-image]][download-url]
[version-image]: http://npm.qima-inc.com/badge/v/@youzan/<%= name %>.svg?style=flat-square
[download-image]: http://npm.qima-inc.com/badge/d/@youzan/<%= name %>.svg?style=flat-square
[download-url]: http://npm.qima-inc.com/package/@youzan/<%= name %>
## Demo
## Usage
## API
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|-----------|-----------|-----------|-------------|-------------|
| className | 自定义额外类名 | string | '' | '' |
## License
[MIT](https://opensource.org/licenses/MIT)
+3
View File
@@ -0,0 +1,3 @@
import RadioGroup from 'packages/radio/src/radio-group';
export default RadioGroup;
+10
View File
@@ -0,0 +1,10 @@
{
"name": "<%= name %>",
"version": "<%= version %>",
"description": "<%= description %>",
"main": "./lib/index.js",
"author": "<%= author %>",
"license": "<%= license %>",
"devDependencies": {},
"dependencies": {}
}
+4
View File
@@ -6,6 +6,10 @@
<script>
export default {
name: 'z-radio-group',
props: {
value: [String, Number]
}
};
</script>
+36 -2
View File
@@ -4,6 +4,13 @@
:class="{
'is-disabled': disabled
}">
<span class="z-radio__input">
<input type="radio" class="z-radio__control">
<span class="z-radio__circle"></span>
</span>
<span class="z-radio__label">
<slot></slot>
</span>
</z-cell>
</template>
@@ -19,10 +26,37 @@ export default {
props: {
disabled: Boolean,
value: {}
value: {},
parentGroup: null
},
created() {
computed: {
isGroup() {
let parent = this.$parent;
while (parent) {
if (parent.$options.name === 'z-radio-group') {
this.parentGroup = parent;
return true;
} else {
parent = parent.$parent;
}
}
return false;
},
model: {
get() {
return this.isGroup ? this.parentGroup.value : this.value;
},
set(val) {
if (this.isGroup) {
} else {
this.$emit('input', val);
}
}
}
}
};
</script>
+8 -11
View File
@@ -1,6 +1,6 @@
<template>
<div class="o2-switch" :class="['is-' + switchState]" @click="toggleState">
<div class="o2-switch-node" :class="['is-' + switchState]"></div>
<div class="z-switch" :class="switchState" @click="toggleState">
<div class="z-switch__node" :class="switchState"></div>
</div>
</template>
@@ -39,15 +39,12 @@ export default {
},
computed: {
switchState: function() {
if (this.disabled) {
return 'disabled';
} else if (this.loading) {
return 'loading';
} else if (this.checked) {
return 'on';
} else {
return 'off';
}
let switchState = this.checked ? ['is-on'] : ['is-off'];
if (this.disabled) switchState.push('is-disabled');
if (this.loading) switchState.push('is-loading');
return switchState;
}
},
methods: {
+5 -5
View File
@@ -2,7 +2,7 @@
@import "./mixins/border_retina.pcss";
@component-namespace z {
@component cell-group {
@b cell-group {
padding-left: 10px;
position: relative;
@@ -11,7 +11,7 @@
}
}
@component cell {
@b cell {
display: block;
overflow: hidden;
position: relative;
@@ -33,19 +33,19 @@
}
}
@descendent title {
@empty-cells: show title {
float: left;
overflow: hidden;
}
@descendent label {
@e label {
display: block;
font-size: 12px;
line-height: 1.2;
color: #666;
}
@descendent value {
@e value {
float: right;
overflow: hidden;
+9 -9
View File
@@ -2,46 +2,46 @@
@import "./mixins/border_retina.pcss";
@component-namespace z {
@component field {
@b field {
width: 100%;
overflow: hidden;
@when textarea {
.z-field-control {
.z-field__control {
min-height: 60px;
}
}
@when nolabel {
.z-cell-title {
.z-cell__title {
display: none;
}
.z-cell-value {
.z-cell__value {
width: 100%;
padding-left: 0;
}
}
.z-cell-title,
.z-cell-value {
.z-cell__title,
.z-cell__value {
float: none;
box-sizing: border-box;
}
.z-cell-title {
.z-cell__title {
width: 90px;
position: absolute;
top: 10px;
left: 0;
}
.z-cell-value {
.z-cell__value {
width: 100%;
padding-left: 90px;
}
@descendent control {
@e control {
border: 0;
font-size: 14px;
line-height: 22px;
+1
View File
@@ -8,4 +8,5 @@
@import './field.pcss';
@import './icon.pcss';
@import './popup.pcss';
@import './picker.pcss';
@import './switch.pcss';
+110
View File
@@ -0,0 +1,110 @@
@component-namespace z {
@b picker {
overflow: hidden;
@e toolbar {
height: 40px;
}
@e columns {
position: relative;
overflow: hidden;
@m 1 {
.z-picker-column {
width: 100%;
}
}
@m 2 {
.z-picker-column {
width: 50%;
}
}
@m 3 {
.z-picker-column {
width: 33.333%;
}
}
}
}
.z-picker-center-highlight {
box-sizing: border-box;
position: absolute;
left: 0;
width: 100%;
top: 50%;
margin-top: -18px;
pointer-events: none;
}
.z-picker-center-highlight:before,
.z-picker-center-highlight:after {
content: '';
position: absolute;
height: 1px;
width: 100%;
background-color: #eaeaea;
display: block;
z-index: 15;
transform: scaleY(0.5);
}
.z-picker-center-highlight:before {
left: 0;
top: 0;
bottom: auto;
right: auto;
}
.z-picker-center-highlight:after {
left: 0;
bottom: 0;
right: auto;
top: auto;
}
@b picker-column {
font-size: 18px;
overflow: hidden;
position: relative;
max-height: 100%;
float: left;
text-align: center;
@e item {
height: 44px;
line-height: 44px;
padding: 0 10px;
white-space: nowrap;
position: relative;
overflow: hidden;
text-overflow: ellipsis;
color: #707274;
left: 0;
top: 0;
width: 100%;
box-sizing: border-box;
transition-duration: .3s;
backface-visibility: hidden;
@m selected {
color: #000;
transform: translate3d(0, 0, 0) rotateX(0);
}
}
}
.picker-column-wrapper {
transition-duration: 0.3s;
transition-timing-function: ease-out;
backface-visibility: hidden;
}
.picker-column-wrapper.dragging,
.picker-column-wrapper.dragging .picker-item {
transition-duration: 0s;
}
}
+5
View File
@@ -0,0 +1,5 @@
@component-namespace z {
@b radio {
}
}
+10 -10
View File
@@ -17,28 +17,23 @@
box-shadow: 0 3px 1px 0 rgba(0, 0, 0, .05), 0 2px 2px 0 rgba(0, 0, 0, .1), 0 3px 3px 0 rgba(0, 0, 0, .05);
@when on {
left: 0;
transition: all .5s ease-in-out;
}
@when off {
right: 0;
left: 20px;
transition: all .5s ease-in-out;
}
}
@when on {
background-color: #44db5e;
border-color: #44db5e;
@descendent node {
left: 0;
}
}
@when off {
background-color: #fff;
border-color: rgba(0, 0, 0, .1);
@descendent node {
right: 0;
}
}
@when loading {
@@ -46,8 +41,13 @@
}
@when disabled {
background-color: #f2f2f2;
border-color: rgba(0, 0, 0, .1);
@when off {
background-color: #f2f2f2;
border-color: rgba(0, 0, 0, .1);
}
@when on {
background-color: #a6e7b1;
}
}
}
}