Commit e355dd49d3434c503c21db078ee684a490e250fc
1 parent
c13471b5
add Select Component
add Select Component
Showing
21 changed files
with
1137 additions
and
99 deletions
Show diff stats
components/collapse/panel.vue
| @@ -4,7 +4,7 @@ | @@ -4,7 +4,7 @@ | ||
| 4 | <Icon type="arrow-right-b"></Icon> | 4 | <Icon type="arrow-right-b"></Icon> |
| 5 | <slot></slot> | 5 | <slot></slot> |
| 6 | </div> | 6 | </div> |
| 7 | - <div :class="concentClasses" v-show="isActive" transition="height"> | 7 | + <div :class="concentClasses" v-show="isActive"> |
| 8 | <div :class="boxClasses"><slot name="content"></slot></div> | 8 | <div :class="boxClasses"><slot name="content"></slot></div> |
| 9 | </div> | 9 | </div> |
| 10 | </div> | 10 | </div> |
components/page/options.vue
| 1 | <template> | 1 | <template> |
| 2 | <div v-if="showSizer || showElevator" :class="optsClasses"> | 2 | <div v-if="showSizer || showElevator" :class="optsClasses"> |
| 3 | <div v-if="showSizer" :class="sizerClasses"> | 3 | <div v-if="showSizer" :class="sizerClasses"> |
| 4 | - <select v-model="pageSize" @change="changeSize"> | ||
| 5 | - <option :value="item" v-for="item in pageSizeOpts">{{ item }} 条/页</option> | ||
| 6 | - </select> | 4 | + <i-select :model.sync="pageSize" @on-change="changeSize"> |
| 5 | + <i-option v-for="item in pageSizeOpts" :value="item" style="text-align:center;">{{ item }} 条/页</i-option> | ||
| 6 | + </i-select> | ||
| 7 | </div> | 7 | </div> |
| 8 | <div v-if="showElevator" :class="ElevatorClasses"> | 8 | <div v-if="showElevator" :class="ElevatorClasses"> |
| 9 | 跳至 | 9 | 跳至 |
| @@ -13,6 +13,9 @@ | @@ -13,6 +13,9 @@ | ||
| 13 | </div> | 13 | </div> |
| 14 | </template> | 14 | </template> |
| 15 | <script> | 15 | <script> |
| 16 | + import iSelect from '../../components/select/select.vue'; | ||
| 17 | + import iOption from '../../components/select/option.vue'; | ||
| 18 | + | ||
| 16 | const prefixCls = 'ivu-page'; | 19 | const prefixCls = 'ivu-page'; |
| 17 | 20 | ||
| 18 | function isValueNumber (value) { | 21 | function isValueNumber (value) { |
| @@ -20,6 +23,7 @@ | @@ -20,6 +23,7 @@ | ||
| 20 | } | 23 | } |
| 21 | 24 | ||
| 22 | export default { | 25 | export default { |
| 26 | + components: { iSelect, iOption }, | ||
| 23 | props: { | 27 | props: { |
| 24 | pageSizeOpts: Array, | 28 | pageSizeOpts: Array, |
| 25 | showSizer: Boolean, | 29 | showSizer: Boolean, |
| 1 | +<template> | ||
| 2 | + <div class="ivu-select-dropdown"><slot></slot></div> | ||
| 3 | +</template> | ||
| 4 | +<script> | ||
| 5 | + import Popper from 'popper.js'; | ||
| 6 | + | ||
| 7 | + export default { | ||
| 8 | + data () { | ||
| 9 | + return { | ||
| 10 | + popper: null | ||
| 11 | + } | ||
| 12 | + }, | ||
| 13 | + methods: { | ||
| 14 | + update () { | ||
| 15 | + if (this.popper) { | ||
| 16 | + this.$nextTick(() => { | ||
| 17 | + this.popper.update(); | ||
| 18 | + }); | ||
| 19 | + } else { | ||
| 20 | + this.$nextTick(() => { | ||
| 21 | + this.popper = new Popper(this.$parent.$els.reference, this.$el, { | ||
| 22 | + gpuAcceleration: false, | ||
| 23 | + placement: 'bottom-start', | ||
| 24 | + boundariesPadding: 0, | ||
| 25 | + forceAbsolute: true | ||
| 26 | + }); | ||
| 27 | + this.popper.onCreate(popper => { | ||
| 28 | + this.resetTransformOrigin(popper); | ||
| 29 | + }); | ||
| 30 | + }); | ||
| 31 | + } | ||
| 32 | + }, | ||
| 33 | + destroy () { | ||
| 34 | + if (this.popper) { | ||
| 35 | + this.resetTransformOrigin(this.popper); | ||
| 36 | + setTimeout(() => { | ||
| 37 | + this.popper.destroy(); | ||
| 38 | + this.popper = null; | ||
| 39 | + }, 300); | ||
| 40 | + } | ||
| 41 | + }, | ||
| 42 | + resetTransformOrigin(popper) { | ||
| 43 | + let placementMap = {top: 'bottom', bottom: 'top'}; | ||
| 44 | + let placement = popper._popper.getAttribute('x-placement').split('-')[0]; | ||
| 45 | + let origin = placementMap[placement]; | ||
| 46 | + popper._popper.style.transformOrigin = `center ${ origin }`; | ||
| 47 | + } | ||
| 48 | + }, | ||
| 49 | + ready () { | ||
| 50 | + this.$on('on-update-popper', this.update); | ||
| 51 | + this.$on('on-destroy-popper', this.destroy); | ||
| 52 | + }, | ||
| 53 | + beforeDestroy () { | ||
| 54 | + if (this.popper) { | ||
| 55 | + this.popper.destroy(); | ||
| 56 | + } | ||
| 57 | + } | ||
| 58 | + } | ||
| 59 | +</script> | ||
| 0 | \ No newline at end of file | 60 | \ No newline at end of file |
| 1 | +<template> | ||
| 2 | + <li :class="[`${prefixCls}-wrap`]"> | ||
| 3 | + <div :class="[`${prefixCls}-title`]">{{ label }}</div> | ||
| 4 | + <ul> | ||
| 5 | + <li :class="[`${prefixCls}`]"><slot></slot></li> | ||
| 6 | + </ul> | ||
| 7 | + </li> | ||
| 8 | +</template> | ||
| 9 | +<script> | ||
| 10 | + const prefixCls = 'ivu-select-group'; | ||
| 11 | + | ||
| 12 | + export default { | ||
| 13 | + props: { | ||
| 14 | + label: { | ||
| 15 | + type: String, | ||
| 16 | + default: '' | ||
| 17 | + } | ||
| 18 | + }, | ||
| 19 | + data () { | ||
| 20 | + return { | ||
| 21 | + prefixCls: prefixCls | ||
| 22 | + } | ||
| 23 | + } | ||
| 24 | + } | ||
| 25 | +</script> | ||
| 0 | \ No newline at end of file | 26 | \ No newline at end of file |
| 1 | +<template> | ||
| 2 | + <li :class="classes" @click.stop="select" @mouseout.stop="blur"><slot>{{ showLabel }}</slot></li> | ||
| 3 | +</template> | ||
| 4 | +<script> | ||
| 5 | + const prefixCls = 'ivu-select-item'; | ||
| 6 | + | ||
| 7 | + export default { | ||
| 8 | + props: { | ||
| 9 | + value: { | ||
| 10 | + type: [String, Number], | ||
| 11 | + required: true | ||
| 12 | + }, | ||
| 13 | + label: { | ||
| 14 | + type: [String, Number] | ||
| 15 | + }, | ||
| 16 | + disabled: { | ||
| 17 | + type: Boolean, | ||
| 18 | + default: false | ||
| 19 | + } | ||
| 20 | + }, | ||
| 21 | + componentName: 'select-item', | ||
| 22 | + data () { | ||
| 23 | + return { | ||
| 24 | + selected: false, | ||
| 25 | + index: 0, // for up and down to focus | ||
| 26 | + isFocus: false | ||
| 27 | + } | ||
| 28 | + }, | ||
| 29 | + computed: { | ||
| 30 | + classes () { | ||
| 31 | + return [ | ||
| 32 | + `${prefixCls}`, | ||
| 33 | + { | ||
| 34 | + [`${prefixCls}-disabled`]: this.disabled, | ||
| 35 | + [`${prefixCls}-selected`]: this.selected, | ||
| 36 | + [`${prefixCls}-focus`]: this.isFocus | ||
| 37 | + } | ||
| 38 | + ] | ||
| 39 | + }, | ||
| 40 | + showLabel () { | ||
| 41 | + return (!!this.label) ? this.label : this.value; | ||
| 42 | + } | ||
| 43 | + }, | ||
| 44 | + methods: { | ||
| 45 | + select () { | ||
| 46 | + if (this.disabled) { | ||
| 47 | + return false; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + this.$dispatch('on-select-selected', this.value); | ||
| 51 | + }, | ||
| 52 | + blur () { | ||
| 53 | + this.isFocus = false; | ||
| 54 | + } | ||
| 55 | + }, | ||
| 56 | + ready () { | ||
| 57 | + | ||
| 58 | + }, | ||
| 59 | + events: { | ||
| 60 | + 'on-select-close' () { | ||
| 61 | + this.isFocus = false; | ||
| 62 | + } | ||
| 63 | + } | ||
| 64 | + } | ||
| 65 | +</script> | ||
| 0 | \ No newline at end of file | 66 | \ No newline at end of file |
| 1 | +<template> | ||
| 2 | + <div :class="classes" v-clickoutside="handleClose"> | ||
| 3 | + <div | ||
| 4 | + :class="[`${prefixCls}-selection`]" | ||
| 5 | + v-el:reference | ||
| 6 | + @click="toggleMenu"> | ||
| 7 | + <div class="ivu-tag" v-if="multiple" v-for="item in selectedMultiple"> | ||
| 8 | + <span class="ivu-tag-text">{{ item.label }}</span> | ||
| 9 | + <Icon type="ios-close-empty" @click.stop="removeTag($index)"></Icon> | ||
| 10 | + </div> | ||
| 11 | + <span :class="[`${prefixCls}-placeholder`]" v-show="showPlaceholder && !filterable">{{ placeholder }}</span> | ||
| 12 | + <span :class="[`${prefixCls}-selected-value`]" v-show="!showPlaceholder && !multiple && !filterable">{{ selectedSingle }}</span> | ||
| 13 | + <input | ||
| 14 | + type="text" | ||
| 15 | + :class="[`${prefixCls}-input`]" | ||
| 16 | + v-if="filterable" | ||
| 17 | + v-model="query" | ||
| 18 | + :placeholder="placeholder" | ||
| 19 | + :style="inputStyle"> | ||
| 20 | + <Icon type="ios-close" :class="[`${prefixCls}-arrow`]" v-show="showCloseIcon" @click.stop="clearSingleSelect"></Icon> | ||
| 21 | + <Icon type="arrow-down-b" :class="[`${prefixCls}-arrow`]"></Icon> | ||
| 22 | + </div> | ||
| 23 | + <Dropdown v-show="visible" transition="slide-up" v-ref:dropdown> | ||
| 24 | + <ul :class="[`${prefixCls}-dropdown-list`]"><slot></slot></ul> | ||
| 25 | + </Dropdown> | ||
| 26 | + </div> | ||
| 27 | +</template> | ||
| 28 | +<script> | ||
| 29 | + import Icon from '../icon'; | ||
| 30 | + import Dropdown from './dropdown.vue'; | ||
| 31 | + import clickoutside from '../../directives/clickoutside'; | ||
| 32 | + import { oneOf } from '../../utils/assist'; | ||
| 33 | + | ||
| 34 | + const prefixCls = 'ivu-select'; | ||
| 35 | + | ||
| 36 | + export default { | ||
| 37 | + components: { Icon, Dropdown }, | ||
| 38 | + directives: { clickoutside }, | ||
| 39 | + props: { | ||
| 40 | + model: { | ||
| 41 | + type: [String, Number, Array], | ||
| 42 | + default: '' | ||
| 43 | + }, | ||
| 44 | + multiple: { | ||
| 45 | + type: Boolean, | ||
| 46 | + default: false | ||
| 47 | + }, | ||
| 48 | + disabled: { | ||
| 49 | + type: Boolean, | ||
| 50 | + default: false | ||
| 51 | + }, | ||
| 52 | + clearable: { | ||
| 53 | + type: Boolean, | ||
| 54 | + default: false | ||
| 55 | + }, | ||
| 56 | + placeholder: { | ||
| 57 | + type: String, | ||
| 58 | + default: '请选择' | ||
| 59 | + }, | ||
| 60 | + filterable: { | ||
| 61 | + type: Boolean, | ||
| 62 | + default: false | ||
| 63 | + }, | ||
| 64 | + filterMethod: { | ||
| 65 | + type: Function | ||
| 66 | + }, | ||
| 67 | + size: { | ||
| 68 | + validator (value) { | ||
| 69 | + return oneOf(value, ['small', 'large']); | ||
| 70 | + } | ||
| 71 | + }, | ||
| 72 | + labelInValue: { | ||
| 73 | + type: Boolean, | ||
| 74 | + default: false | ||
| 75 | + } | ||
| 76 | + }, | ||
| 77 | + data () { | ||
| 78 | + return { | ||
| 79 | + prefixCls: prefixCls, | ||
| 80 | + visible: false, | ||
| 81 | + options: [], | ||
| 82 | + optionInstances: [], | ||
| 83 | + selectedSingle: '', // label | ||
| 84 | + selectedMultiple: [], | ||
| 85 | + focusIndex: 0, | ||
| 86 | + query: '', | ||
| 87 | + inputLength: 20 | ||
| 88 | + } | ||
| 89 | + }, | ||
| 90 | + computed: { | ||
| 91 | + classes () { | ||
| 92 | + return [ | ||
| 93 | + `${prefixCls}`, | ||
| 94 | + { | ||
| 95 | + [`${prefixCls}-visible`]: this.visible, | ||
| 96 | + [`${prefixCls}-disabled`]: this.disabled, | ||
| 97 | + [`${prefixCls}-multiple`]: this.multiple, | ||
| 98 | + [`${prefixCls}-single`]: !this.multiple, | ||
| 99 | + [`${prefixCls}-show-clear`]: this.showCloseIcon, | ||
| 100 | + [`${prefixCls}-${this.size}`]: !!this.size | ||
| 101 | + } | ||
| 102 | + ] | ||
| 103 | + }, | ||
| 104 | + showPlaceholder () { | ||
| 105 | + let status = false; | ||
| 106 | + | ||
| 107 | + if ((typeof this.model) === 'string') { | ||
| 108 | + if (this.model === '') { | ||
| 109 | + status = true; | ||
| 110 | + } | ||
| 111 | + } else if (Array.isArray(this.model)) { | ||
| 112 | + if (!this.model.length) { | ||
| 113 | + status = true; | ||
| 114 | + } | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + return status; | ||
| 118 | + }, | ||
| 119 | + showCloseIcon () { | ||
| 120 | + return !this.multiple && this.clearable && !this.showPlaceholder; | ||
| 121 | + }, | ||
| 122 | + inputStyle () { | ||
| 123 | + let style = {}; | ||
| 124 | + | ||
| 125 | + if (this.multiple) { | ||
| 126 | + style.width = `${this.inputLength}px`; | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + return style; | ||
| 130 | + } | ||
| 131 | + }, | ||
| 132 | + methods: { | ||
| 133 | + toggleMenu () { | ||
| 134 | + if (this.disabled) { | ||
| 135 | + return false; | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + this.visible = !this.visible; | ||
| 139 | + }, | ||
| 140 | + hideMenu () { | ||
| 141 | + this.visible = false; | ||
| 142 | + this.focusIndex = 0; | ||
| 143 | + this.$broadcast('on-select-close'); | ||
| 144 | + }, | ||
| 145 | + // find option component | ||
| 146 | + findChild (cb) { | ||
| 147 | + const find = function (child) { | ||
| 148 | + const name = child.$options.componentName; | ||
| 149 | + | ||
| 150 | + if (name) { | ||
| 151 | + cb(child); | ||
| 152 | + } else if (child.$children.length) { | ||
| 153 | + child.$children.forEach((innerChild) => { | ||
| 154 | + find(innerChild, cb); | ||
| 155 | + }); | ||
| 156 | + } | ||
| 157 | + }; | ||
| 158 | + | ||
| 159 | + if (this.optionInstances.length) { | ||
| 160 | + this.optionInstances.forEach((child) => { | ||
| 161 | + find(child); | ||
| 162 | + }) | ||
| 163 | + } else { | ||
| 164 | + this.$children.forEach((child) => { | ||
| 165 | + find(child); | ||
| 166 | + }); | ||
| 167 | + } | ||
| 168 | + }, | ||
| 169 | + updateOptions (init) { | ||
| 170 | + let options = []; | ||
| 171 | + let index = 1; | ||
| 172 | + | ||
| 173 | + this.findChild((child) => { | ||
| 174 | + options.push({ | ||
| 175 | + value: child.value, | ||
| 176 | + label: (child.label === undefined) ? child.$el.innerHTML : child.label | ||
| 177 | + }); | ||
| 178 | + child.index = index++; | ||
| 179 | + | ||
| 180 | + if (init) { | ||
| 181 | + this.optionInstances.push(child); | ||
| 182 | + } | ||
| 183 | + }); | ||
| 184 | + | ||
| 185 | + this.options = options; | ||
| 186 | + | ||
| 187 | + if (init) { | ||
| 188 | + this.updateSingleSelected(true); | ||
| 189 | + this.updateMultipleSelected(true); | ||
| 190 | + } | ||
| 191 | + }, | ||
| 192 | + updateSingleSelected (init = false) { | ||
| 193 | + const type = typeof this.model; | ||
| 194 | + | ||
| 195 | + if (type === 'string' || type === 'number') { | ||
| 196 | + for (let i = 0; i < this.options.length; i++) { | ||
| 197 | + if (this.model === this.options[i].value) { | ||
| 198 | + this.selectedSingle = this.options[i].label; | ||
| 199 | + break; | ||
| 200 | + } | ||
| 201 | + } | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + this.toggleSingleSelected(this.model, init); | ||
| 205 | + }, | ||
| 206 | + clearSingleSelect () { | ||
| 207 | + if (this.showCloseIcon) { | ||
| 208 | + this.findChild((child) => { | ||
| 209 | + child.selected = false; | ||
| 210 | + }); | ||
| 211 | + this.model = ''; | ||
| 212 | + } | ||
| 213 | + }, | ||
| 214 | + updateMultipleSelected (init = false) { | ||
| 215 | + if (this.multiple && Array.isArray(this.model)) { | ||
| 216 | + let selected = []; | ||
| 217 | + | ||
| 218 | + for (let i = 0; i < this.model.length; i++) { | ||
| 219 | + const model = this.model[i]; | ||
| 220 | + | ||
| 221 | + for (let j = 0; j < this.options.length; j++) { | ||
| 222 | + const option = this.options[j]; | ||
| 223 | + | ||
| 224 | + if (model === option.value) { | ||
| 225 | + selected.push({ | ||
| 226 | + value: option.value, | ||
| 227 | + label: option.label | ||
| 228 | + }) | ||
| 229 | + } | ||
| 230 | + } | ||
| 231 | + } | ||
| 232 | + | ||
| 233 | + this.selectedMultiple = selected; | ||
| 234 | + } | ||
| 235 | + | ||
| 236 | + this.toggleMultipleSelected(this.model, init); | ||
| 237 | + }, | ||
| 238 | + removeTag (index) { | ||
| 239 | + if (this.disabled) { | ||
| 240 | + return false; | ||
| 241 | + } | ||
| 242 | + this.model.splice(index, 1); | ||
| 243 | + }, | ||
| 244 | + // to select option for single | ||
| 245 | + toggleSingleSelected (value, init = false) { | ||
| 246 | + if (!this.multiple) { | ||
| 247 | + let label = ''; | ||
| 248 | + | ||
| 249 | + this.findChild((child) => { | ||
| 250 | + if (child.value === value) { | ||
| 251 | + child.selected = true; | ||
| 252 | + label = (child.label === undefined) ? child.$el.innerHTML : child.label; | ||
| 253 | + } else { | ||
| 254 | + child.selected = false; | ||
| 255 | + } | ||
| 256 | + }); | ||
| 257 | + | ||
| 258 | + this.hideMenu(); | ||
| 259 | + | ||
| 260 | + if (!init) { | ||
| 261 | + if (this.labelInValue) { | ||
| 262 | + this.$emit('on-change', { | ||
| 263 | + value: value, | ||
| 264 | + label: label | ||
| 265 | + }); | ||
| 266 | + } else { | ||
| 267 | + this.$emit('on-change', value); | ||
| 268 | + } | ||
| 269 | + } | ||
| 270 | + } | ||
| 271 | + }, | ||
| 272 | + // to select option for multiple | ||
| 273 | + toggleMultipleSelected (value, init = false) { | ||
| 274 | + if (this.multiple) { | ||
| 275 | + let hybridValue = []; | ||
| 276 | + for (let i = 0; i < value.length; i++) { | ||
| 277 | + hybridValue.push({ | ||
| 278 | + value: value[i] | ||
| 279 | + }); | ||
| 280 | + } | ||
| 281 | + | ||
| 282 | + this.findChild((child) => { | ||
| 283 | + const index = value.indexOf(child.value); | ||
| 284 | + | ||
| 285 | + if (index >= 0) { | ||
| 286 | + child.selected = true; | ||
| 287 | + hybridValue[index].label = (child.label === undefined) ? child.$el.innerHTML : child.label; | ||
| 288 | + } else { | ||
| 289 | + child.selected = false; | ||
| 290 | + } | ||
| 291 | + }); | ||
| 292 | + | ||
| 293 | + if (!init) { | ||
| 294 | + if (this.labelInValue) { | ||
| 295 | + this.$emit('on-change', hybridValue); | ||
| 296 | + } else { | ||
| 297 | + this.$emit('on-change', value); | ||
| 298 | + } | ||
| 299 | + } | ||
| 300 | + } | ||
| 301 | + }, | ||
| 302 | + handleClose () { | ||
| 303 | + this.hideMenu(); | ||
| 304 | + }, | ||
| 305 | + handleKeydown (e) { | ||
| 306 | + if (this.visible) { | ||
| 307 | + const keyCode = e.keyCode; | ||
| 308 | + // Esc slide-up | ||
| 309 | + if (keyCode === 27) { | ||
| 310 | + e.preventDefault(); | ||
| 311 | + this.hideMenu(); | ||
| 312 | + } | ||
| 313 | + // next | ||
| 314 | + if (keyCode === 40) { | ||
| 315 | + e.preventDefault(); | ||
| 316 | + this.navigateOptions('next'); | ||
| 317 | + } | ||
| 318 | + // prev | ||
| 319 | + if (keyCode === 38) { | ||
| 320 | + e.preventDefault(); | ||
| 321 | + this.navigateOptions('prev'); | ||
| 322 | + } | ||
| 323 | + // enter | ||
| 324 | + if (keyCode === 13) { | ||
| 325 | + e.preventDefault(); | ||
| 326 | + | ||
| 327 | + this.findChild((child) => { | ||
| 328 | + if (child.isFocus) { | ||
| 329 | + child.select(); | ||
| 330 | + } | ||
| 331 | + }); | ||
| 332 | + } | ||
| 333 | + } | ||
| 334 | + }, | ||
| 335 | + navigateOptions (direction) { | ||
| 336 | + if (direction === 'next') { | ||
| 337 | + const next = this.focusIndex + 1; | ||
| 338 | + this.focusIndex = (this.focusIndex === this.options.length) ? 1 : next; | ||
| 339 | + } else if (direction === 'prev') { | ||
| 340 | + const prev = this.focusIndex - 1; | ||
| 341 | + this.focusIndex = (this.focusIndex <= 1) ? this.options.length : prev; | ||
| 342 | + } | ||
| 343 | + | ||
| 344 | + let child_status = { | ||
| 345 | + disabled: false | ||
| 346 | + }; | ||
| 347 | + | ||
| 348 | + this.findChild((child) => { | ||
| 349 | + if (child.index === this.focusIndex) { | ||
| 350 | + child_status.disabled = child.disabled; | ||
| 351 | + | ||
| 352 | + if (!child.disabled) { | ||
| 353 | + child.isFocus = true; | ||
| 354 | + } | ||
| 355 | + } else { | ||
| 356 | + child.isFocus = false; | ||
| 357 | + } | ||
| 358 | + }); | ||
| 359 | + | ||
| 360 | + this.resetScrollTop(); | ||
| 361 | + | ||
| 362 | + if (child_status.disabled) { | ||
| 363 | + this.navigateOptions(direction); | ||
| 364 | + } | ||
| 365 | + }, | ||
| 366 | + resetScrollTop () { | ||
| 367 | + const index = this.focusIndex - 1; | ||
| 368 | + let bottomOverflowDistance = this.optionInstances[index].$el.getBoundingClientRect().bottom - this.$refs.dropdown.$el.getBoundingClientRect().bottom; | ||
| 369 | + let topOverflowDistance = this.optionInstances[index].$el.getBoundingClientRect().top - this.$refs.dropdown.$el.getBoundingClientRect().top; | ||
| 370 | + | ||
| 371 | + if (bottomOverflowDistance > 0) { | ||
| 372 | + this.$refs.dropdown.$el.scrollTop += bottomOverflowDistance; | ||
| 373 | + } | ||
| 374 | + if (topOverflowDistance < 0) { | ||
| 375 | + this.$refs.dropdown.$el.scrollTop += topOverflowDistance; | ||
| 376 | + } | ||
| 377 | + } | ||
| 378 | + }, | ||
| 379 | + ready () { | ||
| 380 | + this.updateOptions(true); | ||
| 381 | + document.addEventListener('keydown', this.handleKeydown); | ||
| 382 | + }, | ||
| 383 | + beforeDestroy () { | ||
| 384 | + document.removeEventListener('keydown', this.handleKeydown); | ||
| 385 | + }, | ||
| 386 | + watch: { | ||
| 387 | + model () { | ||
| 388 | + if (this.multiple) { | ||
| 389 | + this.updateMultipleSelected(); | ||
| 390 | + } else { | ||
| 391 | + this.updateSingleSelected(); | ||
| 392 | + } | ||
| 393 | + }, | ||
| 394 | + visible (val) { | ||
| 395 | + if (val) { | ||
| 396 | + this.$broadcast('on-update-popper'); | ||
| 397 | + } else { | ||
| 398 | + | ||
| 399 | + } | ||
| 400 | + } | ||
| 401 | + }, | ||
| 402 | + events: { | ||
| 403 | + 'on-select-selected' (value) { | ||
| 404 | + if (this.model === value) { | ||
| 405 | + this.hideMenu(); | ||
| 406 | + } else { | ||
| 407 | + if (this.multiple) { | ||
| 408 | + const index = this.model.indexOf(value); | ||
| 409 | + if (index >= 0) { | ||
| 410 | + this.removeTag(index); | ||
| 411 | + } else { | ||
| 412 | + this.model.push(value); | ||
| 413 | + } | ||
| 414 | + } else { | ||
| 415 | + this.model = value; | ||
| 416 | + } | ||
| 417 | + } | ||
| 418 | + } | ||
| 419 | + } | ||
| 420 | + } | ||
| 421 | +</script> | ||
| 0 | \ No newline at end of file | 422 | \ No newline at end of file |
| 1 | +export default { | ||
| 2 | + bind () { | ||
| 3 | + this.documentHandler = (e) => { | ||
| 4 | + if (this.el.contains(e.target)) { | ||
| 5 | + return false; | ||
| 6 | + } | ||
| 7 | + if (this.expression) { | ||
| 8 | + this.vm[this.expression](); | ||
| 9 | + } | ||
| 10 | + }; | ||
| 11 | + document.addEventListener('click', this.documentHandler); | ||
| 12 | + }, | ||
| 13 | + update () { | ||
| 14 | + | ||
| 15 | + }, | ||
| 16 | + unbind () { | ||
| 17 | + document.removeEventListener('click', this.documentHandler); | ||
| 18 | + } | ||
| 19 | +} | ||
| 0 | \ No newline at end of file | 20 | \ No newline at end of file |
index.js
| @@ -24,6 +24,7 @@ import Message from './components/message'; | @@ -24,6 +24,7 @@ import Message from './components/message'; | ||
| 24 | import Notice from './components/notice'; | 24 | import Notice from './components/notice'; |
| 25 | import LoadingBar from './components/loading-bar'; | 25 | import LoadingBar from './components/loading-bar'; |
| 26 | import Modal from './components/modal'; | 26 | import Modal from './components/modal'; |
| 27 | +import { Select, Option, OptionGroup } from './components/select'; | ||
| 27 | 28 | ||
| 28 | const iview = { | 29 | const iview = { |
| 29 | Button, | 30 | Button, |
| @@ -52,7 +53,10 @@ const iview = { | @@ -52,7 +53,10 @@ const iview = { | ||
| 52 | Message, | 53 | Message, |
| 53 | Notice, | 54 | Notice, |
| 54 | LoadingBar, | 55 | LoadingBar, |
| 55 | - Modal | 56 | + Modal, |
| 57 | + iSelect: Select, | ||
| 58 | + iOption: Option, | ||
| 59 | + iOptionGroup: OptionGroup | ||
| 56 | }; | 60 | }; |
| 57 | 61 | ||
| 58 | module.exports = iview; | 62 | module.exports = iview; |
| 59 | \ No newline at end of file | 63 | \ No newline at end of file |
local/main.js
| @@ -60,6 +60,11 @@ router.map({ | @@ -60,6 +60,11 @@ router.map({ | ||
| 60 | component: function (resolve) { | 60 | component: function (resolve) { |
| 61 | require(['./routers/tag.vue'], resolve); | 61 | require(['./routers/tag.vue'], resolve); |
| 62 | } | 62 | } |
| 63 | + }, | ||
| 64 | + '/select': { | ||
| 65 | + component: function (resolve) { | ||
| 66 | + require(['./routers/select.vue'], resolve); | ||
| 67 | + } | ||
| 63 | } | 68 | } |
| 64 | }); | 69 | }); |
| 65 | 70 |
local/routers/index.vue
| @@ -2,14 +2,7 @@ | @@ -2,14 +2,7 @@ | ||
| 2 | 2 | ||
| 3 | </style> | 3 | </style> |
| 4 | <template> | 4 | <template> |
| 5 | - <Button @click="info">info</Button> | ||
| 6 | - <Button @click="success">success</Button> | ||
| 7 | - <Button @click="warning">warning</Button> | ||
| 8 | - <Button @click="error">error</Button> | ||
| 9 | - <Button @click="confirm">confirm</Button> | ||
| 10 | - <Page :total="11" :page-size="11"></Page> | ||
| 11 | - <Page :total="11" size="small"></Page> | ||
| 12 | - <Page :current="1" :total="0" simple></Page> | 5 | + <Page :total="100" show-sizer></Page> |
| 13 | </template> | 6 | </template> |
| 14 | <script> | 7 | <script> |
| 15 | import { Modal, Button, Message, Page } from 'iview'; | 8 | import { Modal, Button, Message, Page } from 'iview'; |
| 1 | +<template> | ||
| 2 | + <div> | ||
| 3 | + <!--<br><br><br><br><br><br><br><br><br><br><br>--> | ||
| 4 | + {{ city | json }}<br> | ||
| 5 | + <Button @click="city = 'hangzhou'">切换城市</Button> | ||
| 6 | + <br> | ||
| 7 | + <i-select :model.sync="city" style="width:200px" @on-change="change"> | ||
| 8 | + <i-option-group label="热门城市"> | ||
| 9 | + <i-option value="beijing">北京市</i-option> | ||
| 10 | + <i-option value="shanghai" disabled label="上海市">上海市2</i-option> | ||
| 11 | + <i-option value="shenzhen">深圳市</i-option> | ||
| 12 | + </i-option-group> | ||
| 13 | + <i-option-group label="二线城市"> | ||
| 14 | + <i-option value="nanjing">南京市</i-option> | ||
| 15 | + <i-option value="hangzhou">杭州市</i-option> | ||
| 16 | + </i-option-group> | ||
| 17 | + <i-option value="heilongjiang" disabled>黑龙江市</i-option> | ||
| 18 | + <i-option-group label="热门城市"> | ||
| 19 | + <i-option value="beijing">北京市</i-option> | ||
| 20 | + <i-option value="shanghai" disabled label="上海市">上海市2</i-option> | ||
| 21 | + <i-option value="shenzhen">深圳市</i-option> | ||
| 22 | + </i-option-group> | ||
| 23 | + <i-option-group label="二线城市"> | ||
| 24 | + <i-option value="nanjing">南京市</i-option> | ||
| 25 | + <i-option value="hangzhou">杭州市</i-option> | ||
| 26 | + </i-option-group> | ||
| 27 | + <i-option value="heilongjiang" disabled>黑龙江市</i-option> | ||
| 28 | + <i-option-group label="热门城市"> | ||
| 29 | + <i-option value="beijing">北京市</i-option> | ||
| 30 | + <i-option value="shanghai" disabled label="上海市">上海市2</i-option> | ||
| 31 | + <i-option value="shenzhen">深圳市</i-option> | ||
| 32 | + </i-option-group> | ||
| 33 | + <i-option-group label="二线城市"> | ||
| 34 | + <i-option value="nanjing">南京市</i-option> | ||
| 35 | + <i-option value="hangzhou">杭州市</i-option> | ||
| 36 | + </i-option-group> | ||
| 37 | + <i-option value="heilongjiang" disabled>黑龙江市</i-option> | ||
| 38 | + </i-select> | ||
| 39 | + | ||
| 40 | + <i-select :model.sync="focus" style="width:200px" @on-change="change" clearable filterable label-in-value> | ||
| 41 | + <i-option value="beijing">北京市</i-option> | ||
| 42 | + <i-option value="shanghai" label="上海市">上海市</i-option> | ||
| 43 | + <i-option value="shenzhen" disabled>深圳市</i-option> | ||
| 44 | + <i-option value="guangzhou" label="广州市">广州市2</i-option> | ||
| 45 | + <i-option value="shijiazhuang" disabled>石家庄市</i-option> | ||
| 46 | + <i-option value="a">a市</i-option> | ||
| 47 | + <i-option value="b">b市</i-option> | ||
| 48 | + <i-option value="c">c市</i-option> | ||
| 49 | + <i-option value="d">d市</i-option> | ||
| 50 | + <i-option value="e">e市</i-option> | ||
| 51 | + </i-select> | ||
| 52 | + | ||
| 53 | + <i-select :model.sync="focus2" style="width:300px" @on-change="change" clearable multiple> | ||
| 54 | + <i-option value="beijing">北京市</i-option> | ||
| 55 | + <i-option value="shanghai">上海市</i-option> | ||
| 56 | + <i-option value="shenzhen" disabled>深圳市</i-option> | ||
| 57 | + <i-option value="guangzhou">广州市</i-option> | ||
| 58 | + <i-option value="shijiazhuang">石家庄市</i-option> | ||
| 59 | + <i-option value="a">a市</i-option> | ||
| 60 | + <i-option value="b">b市</i-option> | ||
| 61 | + <i-option value="c">c市</i-option> | ||
| 62 | + <i-option value="d">d市</i-option> | ||
| 63 | + <i-option value="e">e市</i-option> | ||
| 64 | + </i-select> | ||
| 65 | + | ||
| 66 | + <br><br><br><br><br><br><br><br><br><br><br><br> | ||
| 67 | + </div> | ||
| 68 | +</template> | ||
| 69 | +<script> | ||
| 70 | + import { iSelect, iOption, iOptionGroup, Button } from 'iview'; | ||
| 71 | + | ||
| 72 | + export default { | ||
| 73 | + components: { | ||
| 74 | + iSelect, | ||
| 75 | + iOption, | ||
| 76 | + iOptionGroup, | ||
| 77 | + Button | ||
| 78 | + }, | ||
| 79 | + props: { | ||
| 80 | + | ||
| 81 | + }, | ||
| 82 | + data () { | ||
| 83 | + return { | ||
| 84 | + city: '', | ||
| 85 | + focus: '', | ||
| 86 | + focus2: ['beijing', 'guangzhou', 'b'] | ||
| 87 | +// focus2: [] | ||
| 88 | + } | ||
| 89 | + }, | ||
| 90 | + computed: { | ||
| 91 | + | ||
| 92 | + }, | ||
| 93 | + methods: { | ||
| 94 | + change (data) { | ||
| 95 | + console.log(data) | ||
| 96 | + } | ||
| 97 | + } | ||
| 98 | + } | ||
| 99 | +</script> | ||
| 0 | \ No newline at end of file | 100 | \ No newline at end of file |
local/routers/tag.vue
| 1 | <template> | 1 | <template> |
| 2 | - <div> | ||
| 3 | - <Button @click="start">start</Button> | ||
| 4 | - <Button @click="destroy">destroy</Button> | ||
| 5 | - <Button @click="finish">finish</Button> | ||
| 6 | - <Button @click="error">error</Button> | ||
| 7 | - <Button @click="update">update</Button> | ||
| 8 | - <br><br> | ||
| 9 | - <Page :total="100"></Page> | ||
| 10 | - <Page :total="100" show-sizer></Page> | ||
| 11 | - <Page :total="100" show-elevator></Page> | ||
| 12 | - <Page :total="100" show-total></Page> | ||
| 13 | - <br><br> | ||
| 14 | - <Page :current="2" :total="50" simple></Page> | ||
| 15 | - <br> | ||
| 16 | - <Page :total="400" size="small"></Page> | ||
| 17 | - <br> | ||
| 18 | - <Page :total="400" size="small" show-elevator show-sizer></Page> | ||
| 19 | - <br> | ||
| 20 | - <Page :total="400" size="small" show-total></Page> | ||
| 21 | - </div> | 2 | + <Collapse active-key="1"> |
| 3 | + <Panel key="1"> | ||
| 4 | + 史蒂夫·乔布斯 | ||
| 5 | + <p slot="content">史蒂夫·乔布斯(Steve Jobs),1955年2月24日生于美国加利福尼亚州旧金山,美国发明家、企业家、美国苹果公司联合创办人。</p> | ||
| 6 | + </Panel> | ||
| 7 | + <Panel key="2"> | ||
| 8 | + 斯蒂夫·盖瑞·沃兹尼亚克 | ||
| 9 | + <p slot="content">斯蒂夫·盖瑞·沃兹尼亚克(Stephen Gary Wozniak),美国电脑工程师,曾与史蒂夫·乔布斯合伙创立苹果电脑(今之苹果公司)。斯蒂夫·盖瑞·沃兹尼亚克曾就读于美国科罗拉多大学,后转学入美国著名高等学府加州大学伯克利分校(UC Berkeley)并获得电机工程及计算机(EECS)本科学位(1987年)。</p> | ||
| 10 | + </Panel> | ||
| 11 | + <Panel key="3"> | ||
| 12 | + 乔纳森·伊夫 | ||
| 13 | + <p slot="content">乔纳森·伊夫是一位工业设计师,现任Apple公司设计师兼资深副总裁,英国爵士。他曾参与设计了iPod,iMac,iPhone,iPad等众多苹果产品。除了乔布斯,他是对苹果那些著名的产品最有影响力的人。</p> | ||
| 14 | + </Panel> | ||
| 15 | + </Collapse> | ||
| 16 | + <Input-number :max="10" :min="1" :value="1" @on-change="change"></Input-number> | ||
| 17 | + <Input-number :max="10" :min="1" :step="1.2" :value="1"></Input-number> | ||
| 22 | </template> | 18 | </template> |
| 23 | <script> | 19 | <script> |
| 24 | - import { Tag, LoadingBar, Button, Progress, Icon, Timeline, Page } from 'iview'; | ||
| 25 | - const ButtonGroup = Button.Group; | ||
| 26 | - const TimelineItem = Timeline.Item; | 20 | + import { Collapse, InputNumber } from 'iview'; |
| 21 | + const Panel = Collapse.Panel; | ||
| 27 | export default { | 22 | export default { |
| 28 | - components: { | ||
| 29 | - Tag, | ||
| 30 | - Button, | ||
| 31 | - Progress, | ||
| 32 | - ButtonGroup, | ||
| 33 | - Timeline, | ||
| 34 | - TimelineItem, | ||
| 35 | - Icon, | ||
| 36 | - Page | ||
| 37 | - }, | ||
| 38 | - props: { | ||
| 39 | - | ||
| 40 | - }, | ||
| 41 | - data () { | ||
| 42 | - return { | ||
| 43 | - percent: 0 | ||
| 44 | - } | ||
| 45 | - }, | ||
| 46 | - computed: { | ||
| 47 | - | ||
| 48 | - }, | 23 | + components: { Collapse, Panel, InputNumber }, |
| 49 | methods: { | 24 | methods: { |
| 50 | - start () { | ||
| 51 | - LoadingBar.start(); | ||
| 52 | - }, | ||
| 53 | - destroy () { | ||
| 54 | - LoadingBar.destroy(); | ||
| 55 | - }, | ||
| 56 | - finish () { | ||
| 57 | - LoadingBar.finish(); | ||
| 58 | - }, | ||
| 59 | - error () { | ||
| 60 | - LoadingBar.error(); | ||
| 61 | - }, | ||
| 62 | - update () { | ||
| 63 | - LoadingBar.update(50); | ||
| 64 | - }, | ||
| 65 | - add () { | ||
| 66 | - if (this.percent >= 100) { | ||
| 67 | - return false; | ||
| 68 | - } | ||
| 69 | - this.percent += 10; | ||
| 70 | - }, | ||
| 71 | - minus () { | ||
| 72 | - if (this.percent <= 0) { | ||
| 73 | - return false; | ||
| 74 | - } | ||
| 75 | - this.percent -= 10; | 25 | + change (data) { |
| 26 | + console.log(data); | ||
| 76 | } | 27 | } |
| 77 | } | 28 | } |
| 78 | } | 29 | } |
| 79 | -</script> | ||
| 80 | \ No newline at end of file | 30 | \ No newline at end of file |
| 31 | +</script> |
package.json
| 1 | { | 1 | { |
| 2 | "name": "iview", | 2 | "name": "iview", |
| 3 | - "version": "0.9.3", | 3 | + "version": "0.9.4", |
| 4 | "title": "iView", | 4 | "title": "iView", |
| 5 | "description": "A high quality UI components Library with Vue.js", | 5 | "description": "A high quality UI components Library with Vue.js", |
| 6 | "homepage": "http://www.iviewui.com", | 6 | "homepage": "http://www.iviewui.com", |
| @@ -29,6 +29,7 @@ | @@ -29,6 +29,7 @@ | ||
| 29 | "url": "https://github.com/iview/iview/issues" | 29 | "url": "https://github.com/iview/iview/issues" |
| 30 | }, | 30 | }, |
| 31 | "dependencies": { | 31 | "dependencies": { |
| 32 | + "popper.js": "^0.6.4", | ||
| 32 | "vue": "^1.0.26" | 33 | "vue": "^1.0.26" |
| 33 | }, | 34 | }, |
| 34 | "devDependencies": { | 35 | "devDependencies": { |
styles/animation/index.less
| @@ -24,4 +24,5 @@ | @@ -24,4 +24,5 @@ | ||
| 24 | 24 | ||
| 25 | @import "fade"; | 25 | @import "fade"; |
| 26 | @import "move"; | 26 | @import "move"; |
| 27 | -@import "ease"; | ||
| 28 | \ No newline at end of file | 27 | \ No newline at end of file |
| 28 | +@import "ease"; | ||
| 29 | +@import "slide"; | ||
| 29 | \ No newline at end of file | 30 | \ No newline at end of file |
| 1 | +.slide-motion(@className, @keyframeName) { | ||
| 2 | + .make-motion(@className, @keyframeName); | ||
| 3 | + .@{className}-enter, .@{className}-appear { | ||
| 4 | + opacity: 0; | ||
| 5 | + animation-timing-function: @ease-in-out; | ||
| 6 | + } | ||
| 7 | + .@{className}-leave { | ||
| 8 | + animation-timing-function: @ease-in-out; | ||
| 9 | + } | ||
| 10 | +} | ||
| 11 | + | ||
| 12 | +.slide-motion(slide-up, ivuSlideUp); | ||
| 13 | +.slide-motion(slide-down, ivuSlideDown); | ||
| 14 | +.slide-motion(slide-left, ivuSlideLeft); | ||
| 15 | +.slide-motion(slide-right, ivuSlideRight); | ||
| 16 | + | ||
| 17 | +@keyframes ivuSlideUpIn { | ||
| 18 | + 0% { | ||
| 19 | + opacity: 0; | ||
| 20 | + transform-origin: 0% 0%; | ||
| 21 | + transform: scaleY(.8); | ||
| 22 | + } | ||
| 23 | + 100% { | ||
| 24 | + opacity: 1; | ||
| 25 | + transform-origin: 0% 0%; | ||
| 26 | + transform: scaleY(1); | ||
| 27 | + } | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +@keyframes ivuSlideUpOut { | ||
| 31 | + 0% { | ||
| 32 | + opacity: 1; | ||
| 33 | + transform-origin: 0% 0%; | ||
| 34 | + transform: scaleY(1); | ||
| 35 | + } | ||
| 36 | + 100% { | ||
| 37 | + opacity: 0; | ||
| 38 | + transform-origin: 0% 0%; | ||
| 39 | + transform: scaleY(.8); | ||
| 40 | + } | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +@keyframes ivuSlideDownIn { | ||
| 44 | + 0% { | ||
| 45 | + opacity: 0; | ||
| 46 | + transform-origin: 100% 100%; | ||
| 47 | + transform: scaleY(.8); | ||
| 48 | + } | ||
| 49 | + 100% { | ||
| 50 | + opacity: 1; | ||
| 51 | + transform-origin: 100% 100%; | ||
| 52 | + transform: scaleY(1); | ||
| 53 | + } | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +@keyframes ivuSlideDownOut { | ||
| 57 | + 0% { | ||
| 58 | + opacity: 1; | ||
| 59 | + transform-origin: 100% 100%; | ||
| 60 | + transform: scaleY(1); | ||
| 61 | + } | ||
| 62 | + 100% { | ||
| 63 | + opacity: 0; | ||
| 64 | + transform-origin: 100% 100%; | ||
| 65 | + transform: scaleY(.8); | ||
| 66 | + } | ||
| 67 | +} | ||
| 68 | + | ||
| 69 | +@keyframes ivuSlideLeftIn { | ||
| 70 | + 0% { | ||
| 71 | + opacity: 0; | ||
| 72 | + transform-origin: 0% 0%; | ||
| 73 | + transform: scaleX(.8); | ||
| 74 | + } | ||
| 75 | + 100% { | ||
| 76 | + opacity: 1; | ||
| 77 | + transform-origin: 0% 0%; | ||
| 78 | + transform: scaleX(1); | ||
| 79 | + } | ||
| 80 | +} | ||
| 81 | + | ||
| 82 | +@keyframes ivuSlideLeftOut { | ||
| 83 | + 0% { | ||
| 84 | + opacity: 1; | ||
| 85 | + transform-origin: 0% 0%; | ||
| 86 | + transform: scaleX(1); | ||
| 87 | + } | ||
| 88 | + 100% { | ||
| 89 | + opacity: 0; | ||
| 90 | + transform-origin: 0% 0%; | ||
| 91 | + transform: scaleX(.8); | ||
| 92 | + } | ||
| 93 | +} | ||
| 94 | + | ||
| 95 | +@keyframes ivuSlideRightIn { | ||
| 96 | + 0% { | ||
| 97 | + opacity: 0; | ||
| 98 | + transform-origin: 100% 0%; | ||
| 99 | + transform: scaleX(.8); | ||
| 100 | + } | ||
| 101 | + 100% { | ||
| 102 | + opacity: 1; | ||
| 103 | + transform-origin: 100% 0%; | ||
| 104 | + transform: scaleX(1); | ||
| 105 | + } | ||
| 106 | +} | ||
| 107 | + | ||
| 108 | +@keyframes ivuSlideRightOut { | ||
| 109 | + 0% { | ||
| 110 | + opacity: 1; | ||
| 111 | + transform-origin: 100% 0%; | ||
| 112 | + transform: scaleX(1); | ||
| 113 | + } | ||
| 114 | + 100% { | ||
| 115 | + opacity: 0; | ||
| 116 | + transform-origin: 100% 0%; | ||
| 117 | + transform: scaleX(.8); | ||
| 118 | + } | ||
| 119 | +} | ||
| 0 | \ No newline at end of file | 120 | \ No newline at end of file |
styles/common/iconfont/_ionicons-font.less
| @@ -12,16 +12,20 @@ | @@ -12,16 +12,20 @@ | ||
| 12 | font-style: normal; | 12 | font-style: normal; |
| 13 | } | 13 | } |
| 14 | 14 | ||
| 15 | +.ivu-icon() { | ||
| 16 | + display: inline-block; | ||
| 17 | + font-family: @ionicons-font-family; | ||
| 18 | + speak: none; | ||
| 19 | + font-style: normal; | ||
| 20 | + font-weight: normal; | ||
| 21 | + font-variant: normal; | ||
| 22 | + text-transform: none; | ||
| 23 | + text-rendering: auto; | ||
| 24 | + line-height: 1; | ||
| 25 | + -webkit-font-smoothing: antialiased; | ||
| 26 | + -moz-osx-font-smoothing: grayscale; | ||
| 27 | +} | ||
| 28 | + | ||
| 15 | .ivu-icon { | 29 | .ivu-icon { |
| 16 | - display: inline-block; | ||
| 17 | - font-family: @ionicons-font-family; | ||
| 18 | - speak: none; | ||
| 19 | - font-style: normal; | ||
| 20 | - font-weight: normal; | ||
| 21 | - font-variant: normal; | ||
| 22 | - text-transform: none; | ||
| 23 | - text-rendering: auto; | ||
| 24 | - line-height: 1; | ||
| 25 | - -webkit-font-smoothing: antialiased; | ||
| 26 | - -moz-osx-font-smoothing: grayscale; | 30 | + .ivu-icon(); |
| 27 | } | 31 | } |
| 28 | \ No newline at end of file | 32 | \ No newline at end of file |
styles/components/index.less
| @@ -19,4 +19,6 @@ | @@ -19,4 +19,6 @@ | ||
| 19 | @import "timeline"; | 19 | @import "timeline"; |
| 20 | @import "page"; | 20 | @import "page"; |
| 21 | @import "steps"; | 21 | @import "steps"; |
| 22 | -@import "modal"; | ||
| 23 | \ No newline at end of file | 22 | \ No newline at end of file |
| 23 | +@import "modal"; | ||
| 24 | +@import "select"; | ||
| 25 | +@import "select-dropdown"; | ||
| 24 | \ No newline at end of file | 26 | \ No newline at end of file |
| 1 | +@select-dropdown-prefix-cls: ~"@{css-prefix}select-dropdown"; | ||
| 2 | + | ||
| 3 | +.@{select-dropdown-prefix-cls} { | ||
| 4 | + width: 100%; | ||
| 5 | + max-height: 200px; | ||
| 6 | + overflow: auto; | ||
| 7 | + margin: 5px 0; | ||
| 8 | + padding: 7px 0; | ||
| 9 | + background-color: #fff; | ||
| 10 | + box-sizing: border-box; | ||
| 11 | + border: 1px solid @border-color-base; | ||
| 12 | + border-radius: @btn-border-radius; | ||
| 13 | + box-shadow: 0 1px 3px rgba(0,0,0,.2); | ||
| 14 | + position: absolute; | ||
| 15 | + z-index: @zindex-select; | ||
| 16 | +} | ||
| 0 | \ No newline at end of file | 17 | \ No newline at end of file |
| 1 | +@select-prefix-cls: ~"@{css-prefix}select"; | ||
| 2 | +@select-item-prefix-cls: ~"@{css-prefix}select-item"; | ||
| 3 | +@select-group-prefix-cls: ~"@{css-prefix}select-group"; | ||
| 4 | + | ||
| 5 | +.@{select-prefix-cls} { | ||
| 6 | + display: inline-block; | ||
| 7 | + width: 100%; | ||
| 8 | + box-sizing: border-box; | ||
| 9 | + vertical-align: middle; | ||
| 10 | + color: @text-color; | ||
| 11 | + font-size: @font-size-base; | ||
| 12 | + position: relative; | ||
| 13 | + | ||
| 14 | + &-selection { | ||
| 15 | + display: block; | ||
| 16 | + box-sizing: border-box; | ||
| 17 | + outline: none; | ||
| 18 | + user-select: none; | ||
| 19 | + cursor: pointer; | ||
| 20 | + | ||
| 21 | + background-color: #fff; | ||
| 22 | + border-radius: @btn-border-radius; | ||
| 23 | + border: 1px solid @border-color-base; | ||
| 24 | + .transition(all @transition-time @ease-in-out); | ||
| 25 | + | ||
| 26 | + .@{select-prefix-cls}-arrow:nth-of-type(1) { | ||
| 27 | + display: none; | ||
| 28 | + cursor: pointer; | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + &:hover { | ||
| 32 | + .hover(); | ||
| 33 | + .@{select-prefix-cls}-arrow:nth-of-type(1) { | ||
| 34 | + display: inline-block; | ||
| 35 | + } | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + &-show-clear &-selection:hover .@{select-prefix-cls}-arrow:nth-of-type(2){ | ||
| 40 | + display: none; | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + &-arrow { | ||
| 44 | + position: absolute; | ||
| 45 | + top: 50%; | ||
| 46 | + right: 8px; | ||
| 47 | + line-height: 1; | ||
| 48 | + margin-top: -6px; | ||
| 49 | + color: @border-color-base; | ||
| 50 | + .transition(all @transition-time @ease-in-out); | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + &-visible{ | ||
| 54 | + .@{select-prefix-cls}-selection{ | ||
| 55 | + .active(); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + .@{select-prefix-cls}-arrow:nth-of-type(2) { | ||
| 59 | + .transform(rotate(180deg)); | ||
| 60 | + } | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + &-disabled { | ||
| 64 | + .@{select-prefix-cls}-selection { | ||
| 65 | + .disabled(); | ||
| 66 | + | ||
| 67 | + .@{select-prefix-cls}-arrow:nth-of-type(1) { | ||
| 68 | + display: none; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + &:hover { | ||
| 72 | + border-color: @border-color-base; | ||
| 73 | + box-shadow: none; | ||
| 74 | + | ||
| 75 | + .@{select-prefix-cls}-arrow:nth-of-type(2) { | ||
| 76 | + display: inline-block; | ||
| 77 | + } | ||
| 78 | + } | ||
| 79 | + } | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + &-single &-selection{ | ||
| 83 | + height: 28px; | ||
| 84 | + position: relative; | ||
| 85 | + | ||
| 86 | + .@{select-prefix-cls}-placeholder{ | ||
| 87 | + color: @input-placeholder-color; | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + .@{select-prefix-cls}-placeholder, .@{select-prefix-cls}-selected-value{ | ||
| 91 | + display: block; | ||
| 92 | + height: 26px; | ||
| 93 | + line-height: 26px; | ||
| 94 | + overflow: hidden; | ||
| 95 | + text-overflow: ellipsis; | ||
| 96 | + white-space: nowrap; | ||
| 97 | + padding-left: 8px; | ||
| 98 | + padding-right: 24px; | ||
| 99 | + } | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + &-large&-single &-selection{ | ||
| 103 | + height: 32px; | ||
| 104 | + | ||
| 105 | + .@{select-prefix-cls}-placeholder, .@{select-prefix-cls}-selected-value{ | ||
| 106 | + height: 30px; | ||
| 107 | + line-height: 30px; | ||
| 108 | + } | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + &-small&-single &-selection{ | ||
| 112 | + height: 22px; | ||
| 113 | + border-radius: @btn-border-radius-small; | ||
| 114 | + | ||
| 115 | + .@{select-prefix-cls}-placeholder, .@{select-prefix-cls}-selected-value{ | ||
| 116 | + height: 20px; | ||
| 117 | + line-height: 20px; | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + &-multiple &-selection{ | ||
| 122 | + padding: 0 24px 0 2px; | ||
| 123 | + min-height: 28px; | ||
| 124 | + | ||
| 125 | + .@{select-prefix-cls}-placeholder{ | ||
| 126 | + display: block; | ||
| 127 | + height: 26px; | ||
| 128 | + line-height: 26px; | ||
| 129 | + color: @input-placeholder-color; | ||
| 130 | + overflow: hidden; | ||
| 131 | + text-overflow: ellipsis; | ||
| 132 | + white-space: nowrap; | ||
| 133 | + padding-left: 8px; | ||
| 134 | + padding-right: 22px; | ||
| 135 | + } | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + // input | ||
| 139 | + &-input{ | ||
| 140 | + display: inline-block; | ||
| 141 | + height: @input-height-base; | ||
| 142 | + line-height: @input-height-base; | ||
| 143 | + padding: 0 24px 0 8px; | ||
| 144 | + font-size: @font-size-base; | ||
| 145 | + outline: none; | ||
| 146 | + border: none; | ||
| 147 | + box-sizing: border-box; | ||
| 148 | + color: @input-color; | ||
| 149 | + background-color: transparent; | ||
| 150 | + position: relative; | ||
| 151 | + cursor: pointer; | ||
| 152 | + .placeholder(); | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + &-single &-input{ | ||
| 156 | + width: 100%; | ||
| 157 | + } | ||
| 158 | + | ||
| 159 | + &-large &-input{ | ||
| 160 | + height: @input-height-large; | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + &-small &-input{ | ||
| 164 | + height: @input-height-small; | ||
| 165 | + } | ||
| 166 | +} | ||
| 167 | + | ||
| 168 | +.@{select-item-prefix-cls} { | ||
| 169 | + margin: 0; | ||
| 170 | + padding: 7px 15px; | ||
| 171 | + clear: both; | ||
| 172 | + color: @text-color; | ||
| 173 | + //border-radius: @btn-border-radius-small; | ||
| 174 | + white-space: nowrap; | ||
| 175 | + cursor: pointer; | ||
| 176 | + .transition(background @transition-time @ease-in-out); | ||
| 177 | + | ||
| 178 | + &:hover{ | ||
| 179 | + background: @background-color-select-hover; | ||
| 180 | + } | ||
| 181 | + | ||
| 182 | + &-focus { | ||
| 183 | + background: @background-color-select-hover; | ||
| 184 | + } | ||
| 185 | + | ||
| 186 | + &-disabled { | ||
| 187 | + color: @btn-disable-color; | ||
| 188 | + cursor: @cursor-disabled; | ||
| 189 | + | ||
| 190 | + &:hover { | ||
| 191 | + color: @btn-disable-color; | ||
| 192 | + background-color: #fff; | ||
| 193 | + cursor: @cursor-disabled; | ||
| 194 | + } | ||
| 195 | + } | ||
| 196 | + | ||
| 197 | + &-selected ,&-selected:hover{ | ||
| 198 | + color: #fff; | ||
| 199 | + background: @selected-color; | ||
| 200 | + } | ||
| 201 | + | ||
| 202 | + &-selected&-focus { | ||
| 203 | + background: shade(@selected-color, 10%); | ||
| 204 | + } | ||
| 205 | +} | ||
| 206 | + | ||
| 207 | +.@{select-prefix-cls}-multiple .@{select-item-prefix-cls} { | ||
| 208 | + &-selected{ | ||
| 209 | + color: @selected-color; | ||
| 210 | + background: #fff; | ||
| 211 | + } | ||
| 212 | + &-focus,&-selected:hover{ | ||
| 213 | + background: @background-color-select-hover; | ||
| 214 | + } | ||
| 215 | + | ||
| 216 | + &-selected&-focus { | ||
| 217 | + color: shade(@selected-color, 10%); | ||
| 218 | + background: #fff; | ||
| 219 | + } | ||
| 220 | + | ||
| 221 | + &-selected:after{ | ||
| 222 | + .ivu-icon(); | ||
| 223 | + float: right; | ||
| 224 | + font-size: 24px; | ||
| 225 | + content: '\F3FD'; | ||
| 226 | + color: @selected-color; | ||
| 227 | + } | ||
| 228 | +} | ||
| 229 | + | ||
| 230 | +.@{select-group-prefix-cls} { | ||
| 231 | + list-style: none; | ||
| 232 | + margin: 0; | ||
| 233 | + padding: 0; | ||
| 234 | + | ||
| 235 | + &-title { | ||
| 236 | + padding-left: 10px; | ||
| 237 | + font-size: 12px; | ||
| 238 | + color: @legend-color; | ||
| 239 | + height: 30px; | ||
| 240 | + line-height: 30px; | ||
| 241 | + } | ||
| 242 | +} | ||
| 0 | \ No newline at end of file | 243 | \ No newline at end of file |
styles/themes/default/custom.less
| @@ -10,6 +10,7 @@ | @@ -10,6 +10,7 @@ | ||
| 10 | @link-color : #0099e5; | 10 | @link-color : #0099e5; |
| 11 | @link-hover-color : tint(@link-color, 20%); | 11 | @link-hover-color : tint(@link-color, 20%); |
| 12 | @link-active-color : shade(@link-color, 5%); | 12 | @link-active-color : shade(@link-color, 5%); |
| 13 | +@selected-color : fade(@primary-color, 90%); | ||
| 13 | 14 | ||
| 14 | // Base | 15 | // Base |
| 15 | @body-background : #fff; | 16 | @body-background : #fff; |
| @@ -28,7 +29,8 @@ | @@ -28,7 +29,8 @@ | ||
| 28 | @border-color-split : #e9e9e9; // inside | 29 | @border-color-split : #e9e9e9; // inside |
| 29 | 30 | ||
| 30 | // Background color | 31 | // Background color |
| 31 | -@background-color-base : #f7f7f7; // base | 32 | +@background-color-base : #f7f7f7; // base |
| 33 | +@background-color-select-hover: @input-disabled-bg; | ||
| 32 | 34 | ||
| 33 | // Shadow | 35 | // Shadow |
| 34 | @shadow-color : rgba(100, 100, 100, .2); | 36 | @shadow-color : rgba(100, 100, 100, .2); |
| @@ -102,6 +104,7 @@ | @@ -102,6 +104,7 @@ | ||
| 102 | @zindex-spin : 8; | 104 | @zindex-spin : 8; |
| 103 | @zindex-affix : 10; | 105 | @zindex-affix : 10; |
| 104 | @zindex-back-top : 10; | 106 | @zindex-back-top : 10; |
| 107 | +@zindex-select : 900; | ||
| 105 | @zindex-modal : 1000; | 108 | @zindex-modal : 1000; |
| 106 | @zindex-message : 1010; | 109 | @zindex-message : 1010; |
| 107 | @zindex-notification : 1010; | 110 | @zindex-notification : 1010; |