Commit 899ad697b046e29a00d661c6b81f94c3adf93b77
Committed by
GitHub
Merge pull request #3043 from iview/pr/3027
Pr/3027
Showing
3 changed files
with
179 additions
and
66 deletions
Show diff stats
examples/routers/slider.vue
| 1 | -<!--<template>--> | ||
| 2 | - <!--<div style="margin: 0 400px;">--> | ||
| 3 | - <!--<Slider v-model="valueSingle" @on-change="updateSingleDisplayValue"></Slider>--> | ||
| 4 | - <!--<Button @click="randomSingle">change</Button> {{singleDisplayValue}}--> | 1 | +<template> |
| 2 | + <Form :model="formItem" :label-width="80"> | ||
| 3 | + <FormItem label="Input"> | ||
| 4 | + <Input v-model="formItem.input" placeholder="Enter something..."></Input> | ||
| 5 | + </FormItem> | ||
| 6 | + <FormItem label="Select"> | ||
| 7 | + <Select v-model="formItem.select"> | ||
| 8 | + <Option value="beijing">New York</Option> | ||
| 9 | + <Option value="shanghai">London</Option> | ||
| 10 | + <Option value="shenzhen">Sydney</Option> | ||
| 11 | + </Select> | ||
| 12 | + </FormItem> | ||
| 13 | + <FormItem label="DatePicker"> | ||
| 14 | + <Row> | ||
| 15 | + <Col span="11"> | ||
| 16 | + <DatePicker type="date" placeholder="Select date" v-model="formItem.date"></DatePicker> | ||
| 17 | + </Col> | ||
| 18 | + <Col span="2" style="text-align: center">-</Col> | ||
| 19 | + <Col span="11"> | ||
| 20 | + <TimePicker type="time" placeholder="Select time" v-model="formItem.time"></TimePicker> | ||
| 21 | + </Col> | ||
| 22 | + </Row> | ||
| 23 | + </FormItem> | ||
| 24 | + <FormItem label="Radio"> | ||
| 25 | + <RadioGroup v-model="formItem.radio"> | ||
| 26 | + <Radio label="male">Male</Radio> | ||
| 27 | + <Radio label="female">Female</Radio> | ||
| 28 | + </RadioGroup> | ||
| 29 | + </FormItem> | ||
| 30 | + <FormItem label="Checkbox"> | ||
| 31 | + <CheckboxGroup v-model="formItem.checkbox"> | ||
| 32 | + <Checkbox label="Eat"></Checkbox> | ||
| 33 | + <Checkbox label="Sleep"></Checkbox> | ||
| 34 | + <Checkbox label="Run"></Checkbox> | ||
| 35 | + <Checkbox label="Movie"></Checkbox> | ||
| 36 | + </CheckboxGroup> | ||
| 37 | + </FormItem> | ||
| 38 | + <FormItem label="Switch"> | ||
| 39 | + <i-switch v-model="formItem.switch" size="large"> | ||
| 40 | + <span slot="open">On</span> | ||
| 41 | + <span slot="close">Off</span> | ||
| 42 | + </i-switch> | ||
| 43 | + </FormItem> | ||
| 44 | + <FormItem label="Slider"> | ||
| 45 | + <Slider v-model="formItem.slider" range></Slider> | ||
| 46 | + </FormItem> | ||
| 47 | + <FormItem label="Text"> | ||
| 48 | + <Input v-model="formItem.textarea" type="textarea" :autosize="{minRows: 2,maxRows: 5}" placeholder="Enter something..."></Input> | ||
| 49 | + </FormItem> | ||
| 50 | + <FormItem> | ||
| 51 | + <Button type="primary">Submit</Button> | ||
| 52 | + <Button type="ghost" style="margin-left: 8px">Cancel</Button> | ||
| 53 | + </FormItem> | ||
| 54 | + </Form> | ||
| 55 | +</template> | ||
| 56 | +<script> | ||
| 57 | + export default { | ||
| 58 | + data () { | ||
| 59 | + return { | ||
| 60 | + formItem: { | ||
| 61 | + input: '', | ||
| 62 | + select: '', | ||
| 63 | + radio: 'male', | ||
| 64 | + checkbox: [], | ||
| 65 | + switch: true, | ||
| 66 | + date: '', | ||
| 67 | + time: '', | ||
| 68 | + slider: [20, 50], | ||
| 69 | + textarea: '' | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + } | ||
| 73 | + } | ||
| 74 | +</script> | ||
| 75 | + | ||
| 5 | 76 | ||
| 6 | - <!--<Slider v-model="valueRange" range @on-change="updateRangeDisplayValue"></Slider>--> | ||
| 7 | - <!--<Button @click="randomRange">change</Button> {{rangeDisplayValue}}--> | 77 | + |
| 78 | +<!--<template>--> | ||
| 79 | + <!--<div>--> | ||
| 80 | + <!--<Button type="primary" @click="modal1 = true">Display dialog box</Button>--> | ||
| 81 | + <!--<Modal v-model="modal1">--> | ||
| 82 | + <!--<Slider v-model="value2" range show-tip="always"></Slider>--> | ||
| 83 | + <!--</Modal>--> | ||
| 8 | <!--</div>--> | 84 | <!--</div>--> |
| 9 | <!--</template>--> | 85 | <!--</template>--> |
| 10 | <!--<script>--> | 86 | <!--<script>--> |
| 11 | <!--export default {--> | 87 | <!--export default {--> |
| 12 | <!--data () {--> | 88 | <!--data () {--> |
| 13 | <!--return {--> | 89 | <!--return {--> |
| 14 | - <!--valueSingle: 10,--> | ||
| 15 | - <!--valueRange: [20, 50],--> | ||
| 16 | - <!--singleDisplayValue: 10,--> | ||
| 17 | - <!--rangeDisplayValue: [20, 50]--> | ||
| 18 | - <!--};--> | 90 | + <!--modal1: false,--> |
| 91 | + <!--value2: [20, 50],--> | ||
| 92 | + <!--}--> | ||
| 19 | <!--},--> | 93 | <!--},--> |
| 20 | <!--methods: {--> | 94 | <!--methods: {--> |
| 21 | - <!--updateSingleDisplayValue (val){--> | ||
| 22 | - <!--console.log('updateSingleDisplayValue', val);--> | ||
| 23 | - <!--this.singleDisplayValue = val;--> | ||
| 24 | - <!--},--> | ||
| 25 | - <!--updateRangeDisplayValue (val){--> | ||
| 26 | - <!--console.log('updateRangeDisplayValue', val);--> | ||
| 27 | - <!--this.rangeDisplayValue = val.join(' - ');--> | 95 | + <!--ok () {--> |
| 96 | + <!--this.$Message.info('Clicked ok');--> | ||
| 28 | <!--},--> | 97 | <!--},--> |
| 29 | - <!--randomSingle () {--> | ||
| 30 | - <!--this.valueSingle = this.random(0, 100);--> | ||
| 31 | - <!--},--> | ||
| 32 | - <!--randomRange () {--> | ||
| 33 | - <!--this.valueRange = [this.random(0, 50), this.random(50, 100)];--> | ||
| 34 | - <!--},--> | ||
| 35 | - <!--random (min, max){--> | ||
| 36 | - <!--return Math.round(Math.random() * (max - min)) + min;--> | 98 | + <!--cancel () {--> |
| 99 | + <!--this.$Message.info('Clicked cancel');--> | ||
| 37 | <!--}--> | 100 | <!--}--> |
| 38 | <!--}--> | 101 | <!--}--> |
| 39 | - <!--};--> | 102 | + <!--}--> |
| 40 | <!--</script>--> | 103 | <!--</script>--> |
| 41 | - | ||
| 42 | - | ||
| 43 | -<template> | ||
| 44 | - <div> | ||
| 45 | - <Button type="primary" @click="modal1 = true">Display dialog box</Button> | ||
| 46 | - <Modal v-model="modal1"> | ||
| 47 | - <Slider v-model="value2" range show-tip="always"></Slider> | ||
| 48 | - </Modal> | ||
| 49 | - </div> | ||
| 50 | -</template> | ||
| 51 | -<script> | ||
| 52 | - export default { | ||
| 53 | - data () { | ||
| 54 | - return { | ||
| 55 | - modal1: false, | ||
| 56 | - value2: [20, 50], | ||
| 57 | - } | ||
| 58 | - }, | ||
| 59 | - methods: { | ||
| 60 | - ok () { | ||
| 61 | - this.$Message.info('Clicked ok'); | ||
| 62 | - }, | ||
| 63 | - cancel () { | ||
| 64 | - this.$Message.info('Clicked cancel'); | ||
| 65 | - } | ||
| 66 | - } | ||
| 67 | - } | ||
| 68 | -</script> |
src/components/slider/slider.vue
| @@ -8,20 +8,46 @@ | @@ -8,20 +8,46 @@ | ||
| 8 | :value="exportValue[0]" | 8 | :value="exportValue[0]" |
| 9 | :disabled="disabled" | 9 | :disabled="disabled" |
| 10 | @on-change="handleInputChange"></Input-number> | 10 | @on-change="handleInputChange"></Input-number> |
| 11 | - <div :class="[prefixCls + '-wrap']" ref="slider" @click.self="sliderClick"> | 11 | + <div |
| 12 | + :class="[prefixCls + '-wrap']" | ||
| 13 | + ref="slider" @click.self="sliderClick" | ||
| 14 | + > | ||
| 12 | <input type="hidden" :name="name" :value="exportValue"> | 15 | <input type="hidden" :name="name" :value="exportValue"> |
| 13 | <template v-if="showStops"> | 16 | <template v-if="showStops"> |
| 14 | - <div :class="[prefixCls + '-stop']" v-for="item in stops" :style="{ 'left': item + '%' }" @click.self="sliderClick"></div> | 17 | + <div |
| 18 | + :class="[prefixCls + '-stop']" | ||
| 19 | + v-for="item in stops" | ||
| 20 | + :style="{ 'left': item + '%' }" | ||
| 21 | + @click.self="sliderClick" | ||
| 22 | + ></div> | ||
| 15 | </template> | 23 | </template> |
| 16 | - <div :class="[prefixCls + '-bar']" :style="barStyle" @click.self="sliderClick"></div> | 24 | + <div |
| 25 | + :class="[prefixCls + '-bar']" | ||
| 26 | + :style="barStyle" | ||
| 27 | + @click.self="sliderClick"></div> | ||
| 17 | <div | 28 | <div |
| 18 | :class="[prefixCls + '-button-wrap']" | 29 | :class="[prefixCls + '-button-wrap']" |
| 19 | :style="{left: minPosition + '%'}" | 30 | :style="{left: minPosition + '%'}" |
| 20 | @touchstart="onPointerDown($event, 'min')" | 31 | @touchstart="onPointerDown($event, 'min')" |
| 21 | @mousedown="onPointerDown($event, 'min')"> | 32 | @mousedown="onPointerDown($event, 'min')"> |
| 22 | - <Tooltip :controlled="pointerDown === 'min'" placement="top" :content="tipFormat(exportValue[0])" | ||
| 23 | - :disabled="tipDisabled" :always="showTip === 'always'" ref="minTooltip"> | ||
| 24 | - <div :class="minButtonClasses"></div> | 33 | + <Tooltip |
| 34 | + :controlled="pointerDown === 'min'" | ||
| 35 | + placement="top" | ||
| 36 | + :content="tipFormat(exportValue[0])" | ||
| 37 | + :disabled="tipDisabled" | ||
| 38 | + :always="showTip === 'always'" | ||
| 39 | + ref="minTooltip" | ||
| 40 | + > | ||
| 41 | + <div | ||
| 42 | + :class="minButtonClasses" | ||
| 43 | + tabindex="0" | ||
| 44 | + @focus="handleFocus('min')" | ||
| 45 | + @blur="handleBlur('min')" | ||
| 46 | + @keydown.left="onKeyLeft($event, 'min')" | ||
| 47 | + @keydown.down="onKeyLeft($event, 'min')" | ||
| 48 | + @keydown.right="onKeyRight($event, 'min')" | ||
| 49 | + @keydown.up="onKeyRight($event, 'min')" | ||
| 50 | + ></div> | ||
| 25 | </Tooltip> | 51 | </Tooltip> |
| 26 | </div> | 52 | </div> |
| 27 | <div v-if="range" | 53 | <div v-if="range" |
| @@ -29,9 +55,24 @@ | @@ -29,9 +55,24 @@ | ||
| 29 | :style="{left: maxPosition + '%'}" | 55 | :style="{left: maxPosition + '%'}" |
| 30 | @touchstart="onPointerDown($event, 'max')" | 56 | @touchstart="onPointerDown($event, 'max')" |
| 31 | @mousedown="onPointerDown($event, 'max')"> | 57 | @mousedown="onPointerDown($event, 'max')"> |
| 32 | - <Tooltip :controlled="pointerDown === 'max'" placement="top" :content="tipFormat(exportValue[1])" | ||
| 33 | - :disabled="tipDisabled" :always="showTip === 'always'" ref="maxTooltip"> | ||
| 34 | - <div :class="maxButtonClasses"></div> | 58 | + <Tooltip |
| 59 | + :controlled="pointerDown === 'max'" | ||
| 60 | + placement="top" | ||
| 61 | + :content="tipFormat(exportValue[1])" | ||
| 62 | + :disabled="tipDisabled" | ||
| 63 | + :always="showTip === 'always'" | ||
| 64 | + ref="maxTooltip" | ||
| 65 | + > | ||
| 66 | + <div | ||
| 67 | + :class="maxButtonClasses" | ||
| 68 | + tabindex="0" | ||
| 69 | + @focus="handleFocus('max')" | ||
| 70 | + @blur="handleBlur('max')" | ||
| 71 | + @keydown.left="onKeyLeft($event, 'max')" | ||
| 72 | + @keydown.down="onKeyLeft($event, 'max')" | ||
| 73 | + @keydown.right="onKeyRight($event, 'max')" | ||
| 74 | + @keydown.up="onKeyRight($event, 'max')" | ||
| 75 | + ></div> | ||
| 35 | </Tooltip> | 76 | </Tooltip> |
| 36 | </div> | 77 | </div> |
| 37 | </div> | 78 | </div> |
| @@ -110,7 +151,11 @@ | @@ -110,7 +151,11 @@ | ||
| 110 | startX: 0, | 151 | startX: 0, |
| 111 | currentX: 0, | 152 | currentX: 0, |
| 112 | startPos: 0, | 153 | startPos: 0, |
| 113 | - oldValue: val | 154 | + oldValue: val, |
| 155 | + valueIndex: { | ||
| 156 | + min: 0, | ||
| 157 | + max: 1, | ||
| 158 | + }, | ||
| 114 | }; | 159 | }; |
| 115 | }, | 160 | }, |
| 116 | watch: { | 161 | watch: { |
| @@ -173,7 +218,6 @@ | @@ -173,7 +218,6 @@ | ||
| 173 | return (val[1] - this.min) / this.valueRange * 100; | 218 | return (val[1] - this.min) / this.valueRange * 100; |
| 174 | }, | 219 | }, |
| 175 | barStyle () { | 220 | barStyle () { |
| 176 | - | ||
| 177 | const style = { | 221 | const style = { |
| 178 | width: (this.currentValue[0] - this.min) / this.valueRange * 100 + '%' | 222 | width: (this.currentValue[0] - this.min) / this.valueRange * 100 + '%' |
| 179 | }; | 223 | }; |
| @@ -216,6 +260,30 @@ | @@ -216,6 +260,30 @@ | ||
| 216 | max = Math.min(this.max, max); | 260 | max = Math.min(this.max, max); |
| 217 | return [min, max]; | 261 | return [min, max]; |
| 218 | }, | 262 | }, |
| 263 | + getCurrentValue (event, type) { | ||
| 264 | + if (this.disabled) { | ||
| 265 | + return; | ||
| 266 | + } | ||
| 267 | + | ||
| 268 | + const index = this.valueIndex[type]; | ||
| 269 | + if (typeof index === 'undefined') { | ||
| 270 | + return; | ||
| 271 | + } | ||
| 272 | + | ||
| 273 | + return this.currentValue[index]; | ||
| 274 | + }, | ||
| 275 | + onKeyLeft (event, type) { | ||
| 276 | + const value = this.getCurrentValue(event, type); | ||
| 277 | + if (Number.isFinite(value)) { | ||
| 278 | + this.changeButtonPosition(value - this.step, type); | ||
| 279 | + } | ||
| 280 | + }, | ||
| 281 | + onKeyRight (event, type) { | ||
| 282 | + const value = this.getCurrentValue(event, type); | ||
| 283 | + if (Number.isFinite(value)) { | ||
| 284 | + this.changeButtonPosition(value + this.step, type); | ||
| 285 | + } | ||
| 286 | + }, | ||
| 219 | onPointerDown (event, type) { | 287 | onPointerDown (event, type) { |
| 220 | if (this.disabled) return; | 288 | if (this.disabled) return; |
| 221 | event.preventDefault(); | 289 | event.preventDefault(); |
| @@ -293,6 +361,14 @@ | @@ -293,6 +361,14 @@ | ||
| 293 | this.currentValue = [val, this.currentValue[1]]; | 361 | this.currentValue = [val, this.currentValue[1]]; |
| 294 | this.emitChange(); | 362 | this.emitChange(); |
| 295 | }, | 363 | }, |
| 364 | + | ||
| 365 | + handleFocus (type) { | ||
| 366 | + this.$refs[`${type}Tooltip`].handleShowPopper(); | ||
| 367 | + }, | ||
| 368 | + | ||
| 369 | + handleBlur (type) { | ||
| 370 | + this.$refs[`${type}Tooltip`].handleClosePopper(); | ||
| 371 | + } | ||
| 296 | }, | 372 | }, |
| 297 | mounted () { | 373 | mounted () { |
| 298 | // #2852 | 374 | // #2852 |
src/styles/components/slider.less
| @@ -34,7 +34,9 @@ | @@ -34,7 +34,9 @@ | ||
| 34 | border-radius: 50%; | 34 | border-radius: 50%; |
| 35 | background-color: #fff; | 35 | background-color: #fff; |
| 36 | transition: all @transition-time linear; | 36 | transition: all @transition-time linear; |
| 37 | + outline: 0; | ||
| 37 | 38 | ||
| 39 | + &:focus, | ||
| 38 | &:hover, | 40 | &:hover, |
| 39 | &-dragging | 41 | &-dragging |
| 40 | { | 42 | { |