merge: merge master

This commit is contained in:
jiangruowei
2017-03-22 17:08:28 +08:00
50 changed files with 871 additions and 255 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
<template>
<a class="zan-cell" :href="url" @click="handleClick">
<div :class="{ 'zan-cell__title': true, 'zan-cell__required': required }">
<div :class="{ 'zan-cell__title': true, 'zan-cell__required': required }" v-if="this.$slots.title || title || label">
<slot name="icon">
<i v-if="icon" class="zan-icon" :class="'zan-icon-' + icon"></i>
</slot>
+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 DateTimePicker from './src/datetime-picker';
export default DateTimePicker;
+10
View File
@@ -0,0 +1,10 @@
{
"name": "@youzan/zan-datetime-picker",
"version": "0.0.1",
"description": "datetime picker component",
"main": "./index.js",
"author": "niunai <niunai@youzan.com>",
"license": "MIT",
"devDependencies": {},
"dependencies": {}
}
@@ -0,0 +1,221 @@
<template>
<zan-picker
:columns="columns"
:visible-item-count="visibleItemCount"
@change="handlePickerChange"
@confirm="handlePickerConfirm"
showToolbar>
</zan-picker>
</template>
<script>
import Picker from 'packages/picker';
const allowedType = ['time', 'date', 'datetime'];
export default {
name: 'zan-datetime-picker',
components: {
Picker
},
props: {
type: {
type: String,
default: 'datetime',
validator(value) {
return allowedType.indexOf(value) > -1;
}
},
visibleItemCount: {
type: Number,
default: 5
},
minDate: {
type: Date,
default() {
return new Date(new Date().getFullYear() - 10, 0, 1);
}
},
maxDate: {
type: Date,
default() {
return new Date(new Date().getFullYear() + 10, 11, 31);
}
},
minHour: {
type: Number,
default: 0
},
maxHour: {
type: Number,
default: 23
},
value: null
},
data() {
return {
innerValue: this.val
};
},
watch: {
value(val) {
this.innerValue = val;
},
innerValue(val) {
console.log(val + '!!!');
this.$emit('input', val);
}
},
computed: {
ranges() {
console.log(this.innerValue + '!!');
// return this.innerValue + '!!';
if (this.type === 'time') {
return [
[this.minHour, this.maxHour],
[0, 59]
];
}
const { maxYear, maxDate, maxMonth, maxHour, maxMinute } = this.getBoundary('max', this.innerValue);
const { minYear, minDate, minMonth, minHour, minMinute } = this.getBoundary('min', this.innerValue);
const result = [
[minYear, maxYear],
[minMonth, maxMonth],
[minDate, maxDate],
[minHour, maxHour],
[minMinute, maxMinute]
];
if (this.type === 'date') result.splice(3, 2);
return result;
},
columns() {
return this.ranges.map(range => {
const values = this.times(range[1] - range[0] + 1, index => {
const value = range[0] + index;
return value < 10 ? `0${value}` : `${value}`;
});
return {
values
};
});
}
},
methods: {
times(n, iteratee) {
let index = -1;
const result = Array(n);
while (++index < n) {
result[index] = iteratee(index);
}
return result;
},
getBoundary(type, value) {
const boundary = this[`${type}Date`];
const year = boundary.getFullYear();
let month = 1;
let date = 1;
let hour = 0;
let minute = 0;
if (type === 'max') {
month = 12;
date = this.getMonthEndDay(value.getFullYear(), value.getMonth() + 1);
hour = 23;
minute = 59;
}
if (value.getFullYear() === year) {
month = boundary.getMonth() + 1;
if (value.getMonth() + 1 === month) {
date = value.getDate();
if (value.getDate() === date) {
hour = value.getHours();
if (value.getHours() === hour) {
minute = value.getMinutes();
}
}
}
}
return {
[`${type}Year`]: year,
[`${type}Month`]: month,
[`${type}Date`]: date,
[`${type}Hour`]: hour,
[`${type}Minute`]: minute
};
},
getTrueValue(formattedValue) {
if (!formattedValue) return;
while (isNaN(parseInt(formattedValue, 10))) {
formattedValue = formattedValue.slice(1);
}
return parseInt(formattedValue, 10);
},
getMonthEndDay(year, month) {
if (this.isShortMonth(month)) {
return 30;
} else if (month === 2) {
return this.isLeapYear(year) ? 29 : 28;
} else {
return 31;
}
},
isLeapYear(year) {
return (year % 400 === 0) || (year % 100 !== 0 && year % 4 === 0);
},
isShortMonth(month) {
return [4, 6, 9, 11].indexOf(month) > -1;
},
handlePickerConfirm(values) {
this.$emit('confirm', this.innerValue);
},
handlePickerChange(picker, values, index) {
console.log(this.innerValue);
let value;
if (this.type === 'time') {
value = values.join(':');
} else {
const year = this.getTrueValue(values[0]);
const month = this.getTrueValue(values[1]);
const maxDate = this.getMonthEndDay(year, month);
let date = this.getTrueValue(values[2]);
date = date > maxDate ? maxDate : date;
let hour = 0;
let minute = 0;
if (this.type === 'datetime') {
hour = this.getTrueValue(values[3]);
minute = this.getTrueValue(values[4]);
}
value = new Date(year, month - 1, date, hour, minute);
}
this.innerValue = value;
console.log(value, this.innerValue);
// this.$emit('input', value);
}
},
created() {
this.innerValue = this.value;
if (!this.innerValue) {
if (this.type.indexOf('date') > -1) {
this.innerValue = this.minDate;
} else {
const minHour = this.minHour;
this.innerValue = `${minHour > 10 ? minHour : '0' + minHour}:00`;
}
}
}
};
</script>
+37 -4
View File
@@ -8,22 +8,28 @@
'zan-field--nolabel': !label,
'zan-field--disabled': disabled,
'zan-field--error': error,
'zan-field--border': border
'zan-field--border': border,
'zan-field--autosize': autosize
}">
<textarea
v-if="type === 'textarea'"
ref="textareaElement"
class="zan-field__control"
v-model="currentValue"
@focus="handleInputFocus"
:placeholder="placeholder"
:maxlength="maxlength"
:disabled="disabled"
:readonly="readonly">
:readonly="readonly"
:rows="rows"
:cols="cols">
</textarea>
<input
v-else
class="zan-field__control"
:value="currentValue"
@input="handleInput"
@focus="handleInputFocus"
:type="type"
:placeholder="placeholder"
:maxlength="maxlength"
@@ -33,6 +39,7 @@
</template>
<script>
const VALID_TYPES = ['text', 'number', 'email', 'url', 'tel', 'date', 'datetime', 'password', 'textarea'];
import zanCell from 'packages/cell';
export default {
@@ -45,7 +52,10 @@ export default {
props: {
type: {
type: String,
default: 'text'
default: 'text',
validate(value) {
return VALID_TYPES.indexOf(value) > -1;
}
},
placeholder: String,
value: {},
@@ -55,7 +65,16 @@ export default {
readonly: Boolean,
required: Boolean,
maxlength: [String, Number],
border: Boolean
border: Boolean,
rows: [String, Number],
cols: [String, Number],
autosize: {
type: Boolean,
default: false,
validate(value) {
if (value && this.type !== 'textarea') return false;
}
}
},
data() {
@@ -70,6 +89,7 @@ export default {
},
currentValue(val) {
if (this.autosize && this.type === 'textarea') this.sizeAdjust();
this.$emit('input', val);
}
},
@@ -77,6 +97,19 @@ export default {
methods: {
handleInput(event) {
this.currentValue = event.target.value;
},
sizeAdjust() {
const textareaElement = this.$refs.textareaElement;
const textAreaDiff = (parseInt(textareaElement.style.paddingBottom, 10) +
parseInt(textareaElement.style.paddingTop, 10)) || 0;
// 需要先设为0 才可以让scrollHeight正确计算。
textareaElement.style.height = 0 + 'px';
textareaElement.style.height = (textareaElement.scrollHeight - textAreaDiff) + 'px';
},
handleInputFocus() {
this.$emit('focus');
}
}
};
+3
View File
@@ -65,6 +65,9 @@ export default {
},
watch: {
value(val) {
this.currentValue = val;
},
values(val) {
this.currentValues = val;
},
+7 -9
View File
@@ -15,6 +15,10 @@
<zan-icon class="zan-toast__icon" :name="type"></zan-icon>
<div class="zan-toast__text">{{message}}</div>
</template>
<!-- 传入html -->
<template v-if="displayStyle === 'html'">
<div class="zan-toast__text" v-html="message"></div>
</template>
</div>
<div class="zan-toast__overlay" v-if="forbidClick"></div>
</div>
@@ -25,7 +29,8 @@
import zanLoading from 'packages/loading';
import zanIcon from 'packages/icon';
const TOAST_TYPES = ['text', 'loading', 'success', 'fail'];
const TOAST_TYPES = ['text', 'html', 'loading', 'success', 'fail'];
const DEFAULT_STYLE_LIST = ['success', 'fail'];
/**
* zan-toast
* @module components/toast
@@ -70,14 +75,7 @@ export default {
},
computed: {
displayStyle() {
switch (this.type) {
case 'text':
return 'text';
case 'loading':
return 'loading';
default:
return 'default';
}
return DEFAULT_STYLE_LIST.indexOf(this.type) > -1 ? 'default' : this.type;
}
}
};
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@youzan/zanui-css",
"version": "0.0.38",
"version": "0.0.39",
"description": "zanui css.",
"main": "lib/index.css",
"style": "lib/index.css",
+1 -1
View File
@@ -65,7 +65,7 @@
}
@when alone {
float: left;
float: none;
}
}
+6
View File
@@ -50,6 +50,12 @@
}
}
@m autosize {
.zan-field__control {
min-height: 0px;
}
}
.zan-cell__title,
.zan-cell__value {
float: none;
+12
View File
@@ -48,6 +48,18 @@
width: 33.333%;
}
}
@m 4 {
.zan-picker-column {
width: 25%;
}
}
@m 5 {
.zan-picker-column {
width: 20%;
}
}
}
}
+1 -1
View File
@@ -29,7 +29,7 @@
padding: 45px;
}
@m text {
@m text, html {
padding: 12px;
min-width: 200px;
}