Merge remote-tracking branch 'upstream/master'

This commit is contained in:
jingsam 2016-11-14 18:02:36 +08:00
commit bdee066680
43 changed files with 11427 additions and 136 deletions

5
.babelrc Normal file
View file

@ -0,0 +1,5 @@
{
"presets": ["es2015"],
"plugins": ["transform-runtime"],
"comments": false
}

View file

@ -3,5 +3,5 @@
*.yml *.yml
build/ build/
node_modules/ node_modules/
local/ test/
gulpfile.js gulpfile.js

View file

@ -31,36 +31,32 @@
### Install vue-webpack project in the first place ### Install vue-webpack project in the first place
Use [vue-vueRouter-webpack](https://github.com/icarusion/vue-vueRouter-webpack)(Recommended) Or [vue-cli](https://github.com/vuejs/vue-cli) Use [iview-project](https://github.com/iview/iview-project)(Recommended) Or [vue-cli](https://github.com/vuejs/vue-cli)
### Install iView ### Install iView
```bash using npm
```
npm install iview --save npm install iview --save
``` ```
Or using script tag for global use
### Babel support for iView in webpack ```
```js <script type="text/javascript" src="iview.min.js"></script>
module: {
loaders: [
{ test: /iview.src.*?js$/, loader: 'babel' },
{ test: /\.js$/, loader: 'babel', exclude: /node_modules/ }
]
}
``` ```
## Usage ## Usage
Use component as required
```html ```html
<template> <template>
<Page :current="1" :total="100"></Page> <Slider :value.sync="value" range></Slider>
</template> </template>
<script> <script>
import { Page } from 'iview';
export default { export default {
components: { Page } data () {
return {
value: [20, 50]
}
}
} }
</script> </script>
``` ```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 159 KiB

View file

@ -1,3 +0,0 @@
/**
* todo 编译.vue组件为.js文件
*/

View file

@ -1,12 +0,0 @@
var compiler = require('vueify').compiler;
var fs = require('fs');
var data = fs.readFileSync('../components/button/button.vue', 'utf-8');
// console.log(data);
var fileContent = data;
var filePath = '../components/button';
compiler.compile(fileContent, filePath, function (err, result) {
// result is a common js module string
console.log(result);
});

View file

@ -47,11 +47,6 @@ module.exports = {
js: 'babel' js: 'babel'
} }
}, },
// 转es5
babel: {
presets: ['es2015'],
plugins: ['transform-runtime']
},
resolve: { resolve: {
// require时省略的扩展名require('module') 不需要module.js // require时省略的扩展名require('module') 不需要module.js
extensions: ['', '.js', '.vue'], extensions: ['', '.js', '.vue'],

View file

@ -0,0 +1,51 @@
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: {
main: './src/index.js'
},
output: {
path: path.resolve(__dirname, '../dist'),
publicPath: '/dist/',
filename: 'iview.js',
library: 'iview',
libraryTarget: 'umd',
umdNamedDefine: true
},
externals: {
'vue': 'Vue'
},
resolve: {
extensions: ['', '.js', '.vue']
},
module: {
loaders: [{
test: /\.vue$/,
loader: 'vue'
}, {
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
}, {
test: /\.css$/,
loader: 'style!css!autoprefixer'
}, {
test: /\.less$/,
loader: 'style!css!less'
}, {
test: /\.(gif|jpg|png|woff|svg|eot|ttf)\??.*$/,
loader: 'url?limit=8192'
}, {
test: /\.(html|tpl)$/,
loader: 'vue-html'
}]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"development"'
}
})
]
}

View file

@ -0,0 +1,57 @@
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: {
main: './src/index.js'
},
output: {
path: path.resolve(__dirname, '../dist'),
publicPath: '/dist/',
filename: 'iview.min.js',
library: 'iview',
libraryTarget: 'umd',
umdNamedDefine: true
},
externals: {
'vue': 'Vue'
},
resolve: {
extensions: ['', '.js', '.vue']
},
module: {
loaders: [{
test: /\.vue$/,
loader: 'vue'
}, {
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
}, {
test: /\.css$/,
loader: 'style!css!autoprefixer'
}, {
test: /\.less$/,
loader: 'style!css!less'
}, {
test: /\.(gif|jpg|png|woff|svg|eot|ttf)\??.*$/,
loader: 'url?limit=8192'
}, {
test: /\.(html|tpl)$/,
loader: 'vue-html'
}]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
new webpack.optimize.OccurenceOrderPlugin()
]
}

10688
dist/iview.js vendored Normal file

File diff suppressed because it is too large Load diff

5
dist/iview.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
.ivu-article h1{font-size:26px;font-weight:400}.ivu-article h2{font-size:20px;font-weight:400}.ivu-article h3{font-size:16px;font-weight:400}.ivu-article h4{font-size:14px;font-weight:400}.ivu-article h5,.ivu-article h6{font-size:12px;font-weight:400}.ivu-article blockquote{padding:5px 5px 3px 10px;line-height:1.5;border-left:4px solid #ddd;margin-bottom:20px;color:#666;font-size:14px}.ivu-article ul{padding-left:40px;list-style-type:disc}.ivu-article li{margin-bottom:5px;font-size:14px}.ivu-article ol ul,.ivu-article ul ul{list-style-type:circle}.ivu-article p{margin:5px;font-size:14px} .ivu-article h1{font-size:26px;font-weight:400}.ivu-article h2{font-size:20px;font-weight:400}.ivu-article h3{font-size:16px;font-weight:400}.ivu-article h4{font-size:14px;font-weight:400}.ivu-article h5,.ivu-article h6{font-size:12px;font-weight:400}.ivu-article blockquote{padding:5px 5px 3px 10px;line-height:1.5;border-left:4px solid #ddd;margin-bottom:20px;color:#666;font-size:14px}.ivu-article ul{padding-left:40px;list-style-type:disc}.ivu-article li{margin-bottom:5px;font-size:14px}.ivu-article ol ul,.ivu-article ul ul{list-style-type:circle}.ivu-article p{margin:5px;font-size:14px}.ivu-article a[target="_blank"]:after{content:"\F220";font-family:Ionicons;color:#aaa;margin-left:3px}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
{ {
"name": "iview", "name": "iview",
"version": "0.9.7", "version": "0.9.8-rc-1",
"title": "iView", "title": "iView",
"description": "A high quality UI components Library with Vue.js", "description": "A high quality UI components Library with Vue.js",
"homepage": "http://www.iviewui.com", "homepage": "http://www.iviewui.com",
@ -13,10 +13,13 @@
"ui", "ui",
"framework" "framework"
], ],
"main": "src/index.js", "main": "dist/iview.js",
"scripts": { "scripts": {
"dev": "webpack-dev-server --content-base test/ --open --inline --hot --compress --history-api-fallback --port 8081 --config build/webpack.config.js", "dev": "webpack-dev-server --content-base test/ --open --inline --hot --compress --history-api-fallback --port 8081 --config build/webpack.dev.config.js",
"build": "gulp --gulpfile build/build-style.js" "dist:style": "gulp --gulpfile build/build-style.js",
"dist:dev": "webpack --config build/webpack.dist.dev.config.js",
"dist:prod": "webpack --config build/webpack.dist.prod.config.js",
"build": "npm run dist:style && npm run dist:dev && npm run dist:prod"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -31,7 +34,7 @@
"popper.js": "^0.6.4" "popper.js": "^0.6.4"
}, },
"peerDependencies": { "peerDependencies": {
"vue": "^1.0.26" "vue": "^1.0.17"
}, },
"devDependencies": { "devDependencies": {
"autoprefixer-loader": "^2.0.0", "autoprefixer-loader": "^2.0.0",

View file

@ -7,20 +7,25 @@
export default { export default {
props: { props: {
type: String, type: String,
size: [Number, String] size: [Number, String],
color: String
}, },
computed: { computed: {
classes () { classes () {
return `${prefixCls} ${prefixCls}-${this.type}` return `${prefixCls} ${prefixCls}-${this.type}`
}, },
styles () { styles () {
let style = {};
if (!!this.size) { if (!!this.size) {
return { style['font-size'] = `${this.size}px`;
'font-size': `${this.size}px`
}
} else {
return {}
} }
if (!!this.color) {
style.color = this.color;
}
return style;
} }
} }
} }

View file

@ -4,7 +4,7 @@
<div :class="[prefixCls + '-group-prepend']" v-if="prepend" v-el:prepend><slot name="prepend"></slot></div> <div :class="[prefixCls + '-group-prepend']" v-if="prepend" v-el:prepend><slot name="prepend"></slot></div>
<i class="ivu-icon" :class="['ivu-icon-' + icon, prefixCls + '-icon']" v-if="icon" @click="handleIconClick"></i> <i class="ivu-icon" :class="['ivu-icon-' + icon, prefixCls + '-icon']" v-if="icon" @click="handleIconClick"></i>
<input <input
type="text" :type="type"
:class="inputClasses" :class="inputClasses"
:placeholder="placeholder" :placeholder="placeholder"
:disabled="disabled" :disabled="disabled"
@ -37,7 +37,7 @@
props: { props: {
type: { type: {
validator (value) { validator (value) {
return oneOf(value, ['text', 'textarea']); return oneOf(value, ['text', 'textarea', 'password']);
}, },
default: 'text' default: 'text'
}, },
@ -85,6 +85,7 @@
return [ return [
`${prefixCls}-wrapper`, `${prefixCls}-wrapper`,
{ {
[`${prefixCls}-wrapper-${this.size}`]: !!this.size,
[`${prefixCls}-type`]: this.type, [`${prefixCls}-type`]: this.type,
[`${prefixCls}-group`]: this.prepend || this.append, [`${prefixCls}-group`]: this.prepend || this.append,
[`${prefixCls}-group-${this.size}`]: (this.prepend || this.append) && !!this.size [`${prefixCls}-group-${this.size}`]: (this.prepend || this.append) && !!this.size

View file

@ -1,23 +1,53 @@
<template> <template>
<div :class="classes"> <div :class="classes">
<Input-number v-if="!range && showInput" :min="min" :max="max" :step="step" :value.sync="value" :disabled="disabled"></Input-number> <Input-number
<div :class="[prefixCls + '-wrap']" @click="sliderClick"> v-if="!range && showInput"
:min="min"
:max="max"
:step="step"
:value="value"
:disabled="disabled"
@on-change="handleInputChange"></Input-number>
<div :class="[prefixCls + '-wrap']" v-el:slider @click.self="sliderClick">
<template v-if="showStops"> <template v-if="showStops">
<div :class="[prefixCls + '-stop']" v-for="item in stops" :style="{ 'left': item + '%' }"></div> <div :class="[prefixCls + '-stop']" v-for="item in stops" :style="{ 'left': item + '%' }" @click.self="sliderClick"></div>
</template>
<div :class="[prefixCls + '-bar']" :style="barStyle" @click.self="sliderClick"></div>
<template v-if="range">
<div
:class="[prefixCls + '-button-wrap']"
:style="{left: firstPosition + '%'}"
@mousedown="onFirstButtonDown">
<Tooltip :controlled="firstDragging" placement="top" :content="tipFormat(value[0])" :disabled="tipFormat(value[0]) === null" v-ref:tooltip>
<div :class="button1Classes"></div>
</Tooltip>
</div>
<div
:class="[prefixCls + '-button-wrap']"
:style="{left: secondPosition + '%'}"
@mousedown="onSecondButtonDown">
<Tooltip :controlled="secondDragging" placement="top" :content="tipFormat(value[1])" :disabled="tipFormat(value[1]) === null" v-ref:tooltip2>
<div :class="button2Classes"></div>
</Tooltip>
</div>
</template>
<template v-else>
<div
:class="[prefixCls + '-button-wrap']"
:style="{left: singlePosition + '%'}"
@mousedown="onSingleButtonDown">
<Tooltip :controlled="dragging" placement="top" :content="tipFormat(value)" :disabled="tipFormat(value) === null" v-ref:tooltip>
<div :class="buttonClasses"></div>
</Tooltip>
</div>
</template> </template>
<div :class="[prefixCls + '-bar']" :style="barStyle"></div>
<div :class="[prefixCls + '-button-wrap']" v-if="!range">
<Tooltip placement="top" :content="tipFormat(value)">
<div :class="[prefixCls + '-button']"></div>
</Tooltip>
</div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import InputNumber from '../../components/input-number/input-number.vue'; import InputNumber from '../../components/input-number/input-number.vue';
import Tooltip from '../../components/tooltip/tooltip.vue'; import Tooltip from '../../components/tooltip/tooltip.vue';
import { getStyle } from '../../utils/assist';
const prefixCls = 'ivu-slider'; const prefixCls = 'ivu-slider';
@ -65,7 +95,20 @@
}, },
data () { data () {
return { return {
prefixCls: prefixCls prefixCls: prefixCls,
dragging: false,
firstDragging: false,
secondDragging: false,
startX: 0,
currentX: 0,
startPos: 0,
newPos: null,
oldSingleValue: this.value,
oldFirstValue: this.value[0],
oldSecondValue: this.value[1],
singlePosition: (this.value - this.min) / (this.max - this.min) * 100,
firstPosition: (this.value[0] - this.min) / (this.max - this.min) * 100,
secondPosition: (this.value[1] - this.min) / (this.max - this.min) * 100
} }
}, },
computed: { computed: {
@ -73,12 +116,36 @@
return [ return [
`${prefixCls}`, `${prefixCls}`,
{ {
[`${prefixCls}-input`]: this.showInput, [`${prefixCls}-input`]: this.showInput && !this.range,
[`${prefixCls}-range`]: this.range, [`${prefixCls}-range`]: this.range,
[`${prefixCls}-disabled`]: this.disabled [`${prefixCls}-disabled`]: this.disabled
} }
] ]
}, },
buttonClasses () {
return [
`${prefixCls}-button`,
{
[`${prefixCls}-button-dragging`]: this.dragging
}
];
},
button1Classes () {
return [
`${prefixCls}-button`,
{
[`${prefixCls}-button-dragging`]: this.firstDragging
}
];
},
button2Classes () {
return [
`${prefixCls}-button`,
{
[`${prefixCls}-button-dragging`]: this.secondDragging
}
];
},
barStyle () { barStyle () {
let style; let style;
@ -96,20 +163,259 @@
return style; return style;
}, },
stops() { stops() {
return this.max / this.step; let stopCount = (this.max - this.min) / this.step;
let result = [];
let stepWidth = 100 * this.step / (this.max - this.min);
for (let i = 1; i < stopCount; i++) {
result.push(i * stepWidth);
}
return result;
},
sliderWidth () {
return parseInt(getStyle(this.$els.slider, 'width'), 10);
}
},
watch: {
value (val) {
this.$nextTick(() => {
this.$refs.tooltip.updatePopper();
if (this.range) {
this.$refs.tooltip2.updatePopper();
}
});
this.updateValue(val);
} }
}, },
methods: { methods: {
sliderClick () { updateValue (val, init = false) {
if (this.range) {
let value = [...val];
if (init) {
if (value[0] > value[1]) {
value = [this.min, this.max];
}
} else {
if (value[0] > value[1]) {
value[0] = value[1];
}
}
if (value[0] < this.min) {
value[0] = this.min;
}
if (value[0] > this.max) {
value[0] = this.max;
}
if (value[1] < this.min) {
value[1] = this.min;
}
if (value[1] > this.max) {
value[1] = this.max;
}
if (this.value[0] === value[0] && this.value[1] === value[1]) return;
this.value = value;
this.setFirstPosition(this.value[0]);
this.setSecondPosition(this.value[1]);
} else {
if (val < this.min) {
this.value = this.min;
}
if (val > this.max) {
this.value = this.max;
}
this.setSinglePosition(this.value);
}
},
sliderClick (event) {
if (this.disabled) return;
const currentX = event.clientX;
const sliderOffsetLeft = this.$els.slider.getBoundingClientRect().left;
const newPos = (currentX - sliderOffsetLeft) / this.sliderWidth * 100;
if (this.range) {
let type = '';
if (newPos <= this.firstPosition) {
type = 'First';
} else if (newPos >= this.secondPosition) {
type = 'Second';
} else {
if ((newPos - this.firstPosition) <= (this.secondPosition - newPos)) {
type = 'First';
} else {
type = 'Second';
}
}
this[`change${type}Position`](newPos);
} else {
this.changeSinglePosition(newPos);
}
},
// for single use
onSingleButtonDown (event) {
if (this.disabled) return;
event.preventDefault();
this.onSingleDragStart(event);
window.addEventListener('mousemove', this.onSingleDragging);
window.addEventListener('mouseup', this.onSingleDragEnd);
},
onSingleDragStart (event) {
this.dragging = true;
this.startX = event.clientX;
this.startPos = parseInt(this.singlePosition, 10);
},
onSingleDragging (event) {
if (this.dragging) {
this.$refs.tooltip.visible = true;
this.currentX = event.clientX;
const diff = (this.currentX - this.startX) / this.sliderWidth * 100;
this.newPos = this.startPos + diff;
this.changeSinglePosition(this.newPos);
}
},
onSingleDragEnd () {
if (this.dragging) {
this.dragging = false;
this.$refs.tooltip.visible = false;
this.changeSinglePosition(this.newPos);
window.removeEventListener('mousemove', this.onSingleDragging);
window.removeEventListener('mouseup', this.onSingleDragEnd);
}
},
changeSinglePosition (newPos) {
if (newPos >= 0 && (newPos <= 100)) {
const lengthPerStep = 100 / ((this.max - this.min) / this.step);
const steps = Math.round(newPos / lengthPerStep);
this.value = Math.round(steps * lengthPerStep * (this.max - this.min) * 0.01 + this.min);
this.setSinglePosition(this.value);
if (!this.dragging) {
if (this.value !== this.oldSingleValue) {
this.$emit('on-change', this.value);
this.oldSingleValue = this.value;
}
}
}
},
setSinglePosition (val) {
this.singlePosition = (val - this.min) / (this.max - this.min) * 100;
},
handleInputChange (val) {
this.value = val;
this.setSinglePosition(val);
this.$emit('on-change', this.value);
},
// for range use first
onFirstButtonDown (event) {
if (this.disabled) return;
event.preventDefault();
this.onFirstDragStart(event);
window.addEventListener('mousemove', this.onFirstDragging);
window.addEventListener('mouseup', this.onFirstDragEnd);
},
onFirstDragStart (event) {
this.firstDragging = true;
this.startX = event.clientX;
this.startPos = parseInt(this.firstPosition, 10);
},
onFirstDragging (event) {
if (this.firstDragging) {
this.$refs.tooltip.visible = true;
this.currentX = event.clientX;
const diff = (this.currentX - this.startX) / this.sliderWidth * 100;
this.newPos = this.startPos + diff;
this.changeFirstPosition(this.newPos);
}
},
onFirstDragEnd () {
if (this.firstDragging) {
this.firstDragging = false;
this.$refs.tooltip.visible = false;
this.changeFirstPosition(this.newPos);
window.removeEventListener('mousemove', this.onFirstDragging);
window.removeEventListener('mouseup', this.onFirstDragEnd);
}
},
changeFirstPosition (newPos) {
if (newPos >= 0 && (newPos <= this.secondPosition)) {
const lengthPerStep = 100 / ((this.max - this.min) / this.step);
const steps = Math.round(newPos / lengthPerStep);
this.value = [Math.round(steps * lengthPerStep * (this.max - this.min) * 0.01 + this.min), this.value[1]];
this.setFirstPosition(this.value[0]);
if (!this.firstDragging) {
if (this.value[0] !== this.oldFirstValue) {
this.$emit('on-change', this.value);
this.oldFirstValue = this.value[0];
}
}
}
},
setFirstPosition (val) {
this.firstPosition = (val - this.min) / (this.max - this.min) * 100;
},
// for range use second
onSecondButtonDown (event) {
if (this.disabled) return;
event.preventDefault();
this.onSecondDragStart(event);
window.addEventListener('mousemove', this.onSecondDragging);
window.addEventListener('mouseup', this.onSecondDragEnd);
},
onSecondDragStart (event) {
this.secondDragging = true;
this.startX = event.clientX;
this.startPos = parseInt(this.secondPosition, 10);
},
onSecondDragging (event) {
if (this.secondDragging) {
this.$refs.tooltip2.visible = true;
this.currentX = event.clientX;
const diff = (this.currentX - this.startX) / this.sliderWidth * 100;
this.newPos = this.startPos + diff;
this.changeSecondPosition(this.newPos);
}
},
onSecondDragEnd () {
if (this.secondDragging) {
this.secondDragging = false;
this.$refs.tooltip2.visible = false;
this.changeSecondPosition(this.newPos);
window.removeEventListener('mousemove', this.onSecondDragging);
window.removeEventListener('mouseup', this.onSecondDragEnd);
}
},
changeSecondPosition (newPos) {
if (newPos >= this.firstPosition && (newPos <= 100)) {
const lengthPerStep = 100 / ((this.max - this.min) / this.step);
const steps = Math.round(newPos / lengthPerStep);
this.value = [this.value[0], Math.round(steps * lengthPerStep * (this.max - this.min) * 0.01 + this.min)];
this.setSecondPosition(this.value[1]);
if (!this.secondDragging) {
if (this.value[1] !== this.oldSecondValue) {
this.$emit('on-change', this.value);
this.oldSecondValue = this.value[1];
}
}
}
},
setSecondPosition (val) {
this.secondPosition = (val - this.min) / (this.max - this.min) * 100;
} }
}, },
ready () { ready () {
if (this.range) { if (this.range) {
const isArray = Array.isArray(this.value); const isArray = Array.isArray(this.value);
if (!isArray || (isArray && this.value.length != 2) || (isArray && (!isNaN(this.value[0]) || !isNaN(this.value[1])))) { if (!isArray || (isArray && this.value.length != 2) || (isArray && (isNaN(this.value[0]) || isNaN(this.value[1])))) {
this.value = [0, 0]; this.value = [this.min, this.max];
} else {
this.updateValue(this.value, true);
} }
} else {
if (typeof this.value !== 'number') {
this.value = this.min;
}
this.updateValue(this.value);
} }
} }
} }

View file

@ -37,6 +37,10 @@
disabled: { disabled: {
type: Boolean, type: Boolean,
default: false default: false
},
controlled: { // under this prop,Tooltip will not close when mouseleave
type: Boolean,
default: false
} }
}, },
data () { data () {
@ -52,7 +56,9 @@
}, },
handleClosePopper() { handleClosePopper() {
clearTimeout(this.timeout); clearTimeout(this.timeout);
this.visible = false; if (!this.controlled) {
this.visible = false;
}
} }
} }
} }

View file

@ -36,22 +36,23 @@ const iview = {
Badge, Badge,
Breadcrumb, Breadcrumb,
BreadcrumbItem: Breadcrumb.Item, BreadcrumbItem: Breadcrumb.Item,
Button, iButton: Button,
ButtonGroup: Button.Group, ButtonGroup: Button.Group,
Card, Card,
Checkbox, Checkbox,
CheckboxGroup: Checkbox.Group, CheckboxGroup: Checkbox.Group,
Circle, Circle,
Col, iCol: Col,
Collapse, Collapse,
Icon, Icon,
iInput: Input,
InputNumber, InputNumber,
LoadingBar, LoadingBar,
Message, Message,
Modal, Modal,
Notice, Notice,
Option, iOption: Option,
OptionGroup: OptionGroup, OptionGroup,
Page, Page,
Panel: Collapse.Panel, Panel: Collapse.Panel,
Poptip, Poptip,
@ -59,7 +60,7 @@ const iview = {
Radio, Radio,
RadioGroup: Radio.Group, RadioGroup: Radio.Group,
Row, Row,
Select, iSelect: Select,
Slider, Slider,
Spin, Spin,
Step: Steps.Step, Step: Steps.Step,
@ -68,15 +69,23 @@ const iview = {
Tag, Tag,
Timeline, Timeline,
TimelineItem: Timeline.Item, TimelineItem: Timeline.Item,
Tooltip, Tooltip
iButton: Button,
iButtonGroup: Button.Group,
iCol: Col,
iInput: Input,
iOption: Option,
iOptionGroup: OptionGroup,
iSelect: Select
}; };
module.exports = iview; const install = function (Vue) {
Object.keys(iview).forEach((key) => {
Vue.component(key, iview[key])
});
Vue.prototype.$Loading = LoadingBar;
Vue.prototype.$Message = Message;
Vue.prototype.$Modal = Modal;
Vue.prototype.$Notice = Notice;
};
// auto install
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue);
}
module.exports = Object.assign(iview, {install});

View file

@ -49,4 +49,11 @@
margin: 5px; margin: 5px;
font-size: 14px; font-size: 14px;
} }
a[target="_blank"]:after{
content: "\F220";
font-family: Ionicons;
color: #aaa;
margin-left: 3px;
}
} }

View file

@ -24,4 +24,5 @@
@import "select-dropdown"; @import "select-dropdown";
@import "tooltip"; @import "tooltip";
@import "poptip"; @import "poptip";
@import "input"; @import "input";
@import "slider";

View file

@ -73,7 +73,7 @@
line-height: 12px; line-height: 12px;
font-size: 14px; font-size: 14px;
color: #999; color: #999;
user-select: none; .user-select();
position: absolute; position: absolute;
right: 4px; right: 4px;
.transition(all @transition-time linear); .transition(all @transition-time linear);

View file

@ -9,20 +9,26 @@
} }
&-icon { &-icon {
width: 32px; width: 32px;
height: 100%; height: @input-height-base;
line-height: @input-height-base;
font-size: 16px; font-size: 16px;
text-align: center; text-align: center;
color: @subsidiary-color; color: @subsidiary-color;
position: absolute; position: absolute;
right: 0; right: 0;
z-index: 1; z-index: 1;
&:after{ }
content: '';
display: inline-block; &-wrapper-large &-icon{
width: 0; font-size: 18px;
height: 100%; height: @input-height-large;
vertical-align: middle; line-height: @input-height-large;
} }
&-wrapper-small &-icon{
width: 24px;
font-size: 14px;
height: @input-height-small;
line-height: @input-height-small;
} }
&-icon + &{ &-icon + &{

View file

@ -9,7 +9,7 @@
top: 100px; top: 100px;
&-hidden { &-hidden {
display: none; display: none !important;
} }
&-wrap { &-wrap {

View file

@ -19,7 +19,7 @@
text-align: center; text-align: center;
list-style: none; list-style: none;
background-color: #fff; background-color: #fff;
user-select: none; .user-select();
cursor: pointer; cursor: pointer;
font-family: Arial; font-family: Arial;
border: 1px solid @border-color-base; border: 1px solid @border-color-base;

View file

@ -15,7 +15,7 @@
display: block; display: block;
box-sizing: border-box; box-sizing: border-box;
outline: none; outline: none;
user-select: none; .user-select();
cursor: pointer; cursor: pointer;
background-color: #fff; background-color: #fff;

View file

@ -0,0 +1,110 @@
@slider-prefix-cls: ~"@{css-prefix}slider";
.@{slider-prefix-cls} {
&-wrap{
width: 100%;
height: @slider-height;
margin: @slider-margin;
background-color: @border-color-split;
border-radius: @btn-border-radius-small;
vertical-align: middle;
position: relative;
cursor: pointer;
}
&-button-wrap{
.square(@slider-button-wrap-size);
text-align: center;
background-color: transparent;
position: absolute;
top: @slider-button-wrap-offset;
.transform(translateX(-50%));
.@{tooltip-prefix-cls} {
display: block;
.user-select();
}
}
&-button{
width: 12px;
height: 12px;
border: 2px solid @slider-color;
border-radius: 50%;
background-color: #fff;
.transition(all @transition-time linear);
&:hover,
&-dragging
{
border-color: @primary-color;
.transform(scale(1.5));
}
&:hover{
cursor: grab;
}
&-dragging,
&-dragging:hover
{
cursor: grabbing;
}
}
&-bar{
height: @slider-height;
background: @slider-color;
border-radius: @btn-border-radius-small;
position: absolute;
}
&-stop{
position: absolute;
.square(@slider-height);
border-radius: 50%;
background-color: @slider-disabled-color;
.transform(translateX(-50%));
}
}
.@{slider-prefix-cls}-disabled{
cursor: @cursor-disabled;
.@{slider-prefix-cls}-wrap{
background-color: @slider-disabled-color;
cursor: @cursor-disabled;
}
.@{slider-prefix-cls}-bar{
background-color: @slider-disabled-color;
}
.@{slider-prefix-cls}-button{
border-color: @slider-disabled-color;
&:hover,
&-dragging
{
border-color: @slider-disabled-color;
}
&:hover{
cursor: @cursor-disabled;
}
&-dragging,
&-dragging:hover
{
cursor: @cursor-disabled;
}
}
}
.@{slider-prefix-cls}-input{
.@{slider-prefix-cls}-wrap{
width: auto;
margin-right: 100px;
}
.@{input-number-prefix-cls}{
float: right;
margin-top: -14px;
}
}

View file

@ -11,7 +11,7 @@
background-color: #ccc; background-color: #ccc;
position: relative; position: relative;
cursor: pointer; cursor: pointer;
user-select: none; .user-select();
.transition(all @transition-time @ease-in-out); .transition(all @transition-time @ease-in-out);
&-inner { &-inner {

View file

@ -120,7 +120,7 @@
border: 1px solid transparent; border: 1px solid transparent;
white-space: nowrap; white-space: nowrap;
line-height: @line-height-base; line-height: @line-height-base;
user-select: none; .user-select();
.button-size(@btn-padding-base; @btn-font-size; @btn-border-radius); .button-size(@btn-padding-base; @btn-font-size; @btn-border-radius);
.transform(translate3d(0, 0, 0)); .transform(translate3d(0, 0, 0));
//.transition(all @transition-time linear); //.transition(all @transition-time linear);

View file

@ -12,4 +12,10 @@
&::-webkit-input-placeholder { &::-webkit-input-placeholder {
color: @color; color: @color;
} }
}
.user-select(@type: none) {
-webkit-user-select: @type;
-moz-user-select: @type;
user-select: @type;
} }

View file

@ -1,6 +1,7 @@
// Prefix // Prefix
@css-prefix : ivu-; @css-prefix : ivu-;
@css-prefix-iconfont : ivu-icon; @css-prefix-iconfont : ivu-icon;
// Color // Color
@primary-color : #3399ff; @primary-color : #3399ff;
@info-color : #2db7f5; @info-color : #2db7f5;
@ -119,4 +120,12 @@
// Animation // Animation
@animation-time : .3s; @animation-time : .3s;
@transition-time : .2s; @transition-time : .2s;
@ease-in-out : ease-in-out; @ease-in-out : ease-in-out;
// Slider
@slider-color : tint(@primary-color, 20%);
@slider-height : 4px;
@slider-margin : 16px 0;
@slider-button-wrap-size : 18px;
@slider-button-wrap-offset : -5px;
@slider-disabled-color : #ccc;

View file

@ -52,4 +52,27 @@ export function getScrollBarSize (fresh) {
} }
// watch DOM change // watch DOM change
export const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver || false; export const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver || false;
const SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
const MOZ_HACK_REGEXP = /^moz([A-Z])/;
function camelCase(name) {
return name.replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
return offset ? letter.toUpperCase() : letter;
}).replace(MOZ_HACK_REGEXP, 'Moz$1');
}
// getStyle
export function getStyle (element, styleName) {
if (!element || !styleName) return null;
styleName = camelCase(styleName);
if (styleName === 'float') {
styleName = 'cssFloat';
}
try {
var computed = document.defaultView.getComputedStyle(element, '');
return element.style[styleName] || computed ? computed[styleName] : null;
} catch(e) {
return element.style[styleName];
}
}

View file

@ -1,6 +1,7 @@
<style lang="less"> <style lang="less">
@import "../src/styles/index.less"; @import "../src/styles/index.less";
@import "../src/styles/package.less"; @import "../src/styles/package.less";
@import "../src/styles/article/index.less";
</style> </style>
<style scoped> <style scoped>
nav { nav {

View file

@ -169,14 +169,14 @@
</Button-group> </Button-group>
</template> </template>
<script> <script>
import { Button, Icon, Input, Switch, Radio, Checkbox, InputNumber, Row, Col, Page } from 'iview'; import { iButton, Icon, Input, Switch, Radio, Checkbox, InputNumber, Row, Col, Page } from 'iview';
const ButtonGroup = Button.Group; const ButtonGroup = iButton.Group;
const RadioGroup = Radio.Group; const RadioGroup = Radio.Group;
const CheckboxGroup = Checkbox.Group; const CheckboxGroup = Checkbox.Group;
export default { export default {
components: { components: {
iButton: Button, iButton,
ButtonGroup, ButtonGroup,
Icon, Icon,
iInput: Input, iInput: Input,

View file

@ -74,6 +74,7 @@
<Input-number :value="2" size="small"></Input-number> <Input-number :value="2" size="small"></Input-number>
<Input-number :value="2"></Input-number> <Input-number :value="2"></Input-number>
<Input-number :value="2" size="large"></Input-number> <Input-number :value="2" size="large"></Input-number>
<i-input type="password"></i-input>
</div> </div>
</template> </template>
<script> <script>

View file

@ -21,7 +21,7 @@
export default { export default {
components: { components: {
Message, Message,
Button, iButton,
Alert, Alert,
Card, Card,
Notice, Notice,
@ -29,7 +29,7 @@
Modal Modal
}, },
props: { props: {
}, },
data () { data () {
return { return {
@ -121,4 +121,4 @@
// }); // });
} }
} }
</script> </script>

View file

@ -67,10 +67,10 @@
<Step title="待进行" content="这里是该步骤的描述信息"></Step> <Step title="待进行" content="这里是该步骤的描述信息"></Step>
<Step title="待进行" content="这里是该步骤的描述信息"></Step> <Step title="待进行" content="这里是该步骤的描述信息"></Step>
</Steps> </Steps>
<Button @click="testStatus = 'process'">change Status</Button> <i-button @click="testStatus = 'process'">change Status</i-button>
</template> </template>
<script> <script>
import { Badge, Tag, Progress, Circle, Timeline, Icon, Affix, Button, BackTop, Spin, Steps, Breadcrumb} from 'iview'; import { Badge, Tag, Progress, Circle, Timeline, Icon, Affix, iButton, BackTop, Spin, Steps, Breadcrumb} from 'iview';
const TimelineItem = Timeline.Item; const TimelineItem = Timeline.Item;
const Step = Steps.Step; const Step = Steps.Step;
const BreadcrumbItem = Breadcrumb.Item; const BreadcrumbItem = Breadcrumb.Item;
@ -85,7 +85,7 @@
TimelineItem, TimelineItem,
Icon, Icon,
Affix, Affix,
Button, iButton,
BackTop, BackTop,
Spin, Spin,
Steps, Steps,
@ -94,7 +94,7 @@
BreadcrumbItem BreadcrumbItem
}, },
props: { props: {
}, },
data () { data () {
return { return {
@ -108,7 +108,7 @@
} }
}, },
computed: { computed: {
}, },
methods: { methods: {
closed (e) { closed (e) {
@ -130,4 +130,4 @@
}, 1000) }, 1000)
} }
} }
</script> </script>

View file

@ -153,10 +153,10 @@
</div> </div>
</template> </template>
<script> <script>
import { Tooltip, Button, Row, iCol, Poptip, iSelect, iOption, Message, Icon } from 'iview'; import { Tooltip, iButton, Row, iCol, Poptip, iSelect, iOption, Message, Icon } from 'iview';
export default { export default {
components: { Tooltip, iButton: Button, Row, iCol, Poptip, iSelect, iOption, Message, Icon }, components: { Tooltip, iButton, Row, iCol, Poptip, iSelect, iOption, Message, Icon },
props: { props: {
}, },

View file

@ -20,10 +20,10 @@
<Radio value="印度黑羚"></Radio> <Radio value="印度黑羚"></Radio>
</Radio-group> </Radio-group>
<br><br> <br><br>
<Button @click="activeKey = '2'"></Button> <i-button @click="activeKey = '2'"></i-button>
</div> </div>
<Radio :checked.sync="radio">Radio</Radio> <Radio :checked.sync="radio">Radio</Radio>
<Button @click="radio = !radio">change radio</Button> <i-button @click="radio = !radio">change radio</i-button>
<br> <br>
<br> <br>
<Radio-group :model.sync="phone" type="button"> <Radio-group :model.sync="phone" type="button">
@ -145,7 +145,7 @@
<Checkbox :checked.sync="single"></Checkbox> <Checkbox :checked.sync="single"></Checkbox>
</template> </template>
<script> <script>
import { Radio, Alert, Icon, Collapse, Button, Checkbox, Switch, InputNumber, Breadcrumb, LoadingBar } from 'iview'; import { Radio, Alert, Icon, Collapse, iButton, Checkbox, Switch, InputNumber, Breadcrumb, LoadingBar } from 'iview';
const RadioGroup = Radio.Group; const RadioGroup = Radio.Group;
const Panel = Collapse.Panel; const Panel = Collapse.Panel;
@ -160,7 +160,7 @@
Icon, Icon,
Collapse, Collapse,
Panel, Panel,
Button, iButton,
Checkbox, Checkbox,
CheckboxGroup, CheckboxGroup,
Switch, Switch,
@ -203,4 +203,4 @@
LoadingBar.start(); LoadingBar.start();
} }
} }
</script> </script>

View file

@ -27,18 +27,18 @@
<i-option v-for="item in cityList" :value="item.value">{{ item.label }}</i-option> <i-option v-for="item in cityList" :value="item.value">{{ item.label }}</i-option>
</i-select> </i-select>
<i-select :model.sync="model7" style="width:200px"> <i-select :model.sync="model7" style="width:200px">
<i-option-group label="热门城市"> <Option-group label="热门城市">
<i-option v-for="item in cityList | limitBy 3" :value="item.value">{{ item.label }}</i-option> <i-option v-for="item in cityList | limitBy 3" :value="item.value">{{ item.label }}</i-option>
</i-option-group> </Option-group>
<i-option-group label="其它城市"> <Option-group label="其它城市">
<i-option v-for="item in cityList | limitBy 3 3" :value="item.value">{{ item.label }}</i-option> <i-option v-for="item in cityList | limitBy 3 3" :value="item.value">{{ item.label }}</i-option>
</i-option-group> </Option-group>
</i-select> </i-select>
</template> </template>
<script> <script>
import { iSelect, iOption, iButton, iOptionGroup } from 'iview'; import { iSelect, iOption, iButton, OptionGroup } from 'iview';
export default { export default {
components: { iSelect, iOption, iButton, iOptionGroup }, components: { iSelect, iOption, iButton, OptionGroup },
data () { data () {
return { return {
cityList: [ cityList: [

View file

@ -1,20 +1,35 @@
<template> <template>
<Slider :value="10" :tip-format="format"> <div style="width: 400px;margin:100px;">
{{ value }}
</Slider> <Slider @on-change="change" :step="15"></Slider>
<Slider :value="40" :tip-format="format"></Slider>
<Slider :value.sync="value" show-input show-stops range @on-change="change" :step="13"></Slider>
<!--<Slider :max="10"></Slider>-->
<!--<Slider :step="13"></Slider>-->
<!--<Slider :step="13" :max="60"></Slider>-->
<Icon type="checkmark-circled" size="40" color="#f60"></Icon>
<p>附近的首付款是东方红看就是</p>
<div class="ivu-article">
<a href="http://www.iviewui.com" target="_blank">iView</a>
</div>
</div>
</template> </template>
<script> <script>
import { Slider } from 'iview'; import { Slider, Icon } from 'iview';
export default { export default {
components: { Slider }, components: { Slider, Icon },
data () { data () {
return { return {
value: [20, 50]
} }
}, },
methods: { methods: {
format (val) { format (val) {
return null;
return `进度:${val}%` return `进度:${val}%`
},
change (data) {
// console.log(data)
} }
} }
} }

View file

@ -58,7 +58,7 @@
</Steps> </Steps>
</template> </template>
<script> <script>
import { Page, Steps, Button } from 'iview'; import { Page, Steps, iButton } from 'iview';
const Step = Steps.Step; const Step = Steps.Step;
@ -67,7 +67,7 @@
Page, Page,
Steps, Steps,
Step, Step,
iButton: Button iButton
}, },
props: { props: {