Commit 791d254e64d71f0251156c5ccb3a9df659d7161b
1 parent
f0c2af9d
Slider: Keyboard control like native
Showing
2 changed files
with
77 additions
and
11 deletions
Show diff stats
src/components/slider/slider.vue
| ... | ... | @@ -8,20 +8,44 @@ |
| 8 | 8 | :value="exportValue[0]" |
| 9 | 9 | :disabled="disabled" |
| 10 | 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 | 15 | <input type="hidden" :name="name" :value="exportValue"> |
| 13 | 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 | 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 | 28 | <div |
| 18 | 29 | :class="[prefixCls + '-button-wrap']" |
| 19 | 30 | :style="{left: minPosition + '%'}" |
| 20 | 31 | @touchstart="onPointerDown($event, 'min')" |
| 21 | 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 | + @keydown.left="onKeyLeft($event, 'min')" | |
| 45 | + @keydown.down="onKeyLeft($event, 'min')" | |
| 46 | + @keydown.right="onKeyRight($event, 'min')" | |
| 47 | + @keydown.up="onKeyRight($event, 'min')" | |
| 48 | + ></div> | |
| 25 | 49 | </Tooltip> |
| 26 | 50 | </div> |
| 27 | 51 | <div v-if="range" |
| ... | ... | @@ -29,9 +53,22 @@ |
| 29 | 53 | :style="{left: maxPosition + '%'}" |
| 30 | 54 | @touchstart="onPointerDown($event, 'max')" |
| 31 | 55 | @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> | |
| 56 | + <Tooltip | |
| 57 | + :controlled="pointerDown === 'max'" | |
| 58 | + placement="top" | |
| 59 | + :content="tipFormat(exportValue[1])" | |
| 60 | + :disabled="tipDisabled" | |
| 61 | + :always="showTip === 'always'" | |
| 62 | + ref="maxTooltip" | |
| 63 | + > | |
| 64 | + <div | |
| 65 | + :class="maxButtonClasses" | |
| 66 | + tabindex="0" | |
| 67 | + @keydown.left="onKeyLeft($event, 'max')" | |
| 68 | + @keydown.down="onKeyLeft($event, 'max')" | |
| 69 | + @keydown.right="onKeyRight($event, 'max')" | |
| 70 | + @keydown.up="onKeyRight($event, 'max')" | |
| 71 | + ></div> | |
| 35 | 72 | </Tooltip> |
| 36 | 73 | </div> |
| 37 | 74 | </div> |
| ... | ... | @@ -110,7 +147,11 @@ |
| 110 | 147 | startX: 0, |
| 111 | 148 | currentX: 0, |
| 112 | 149 | startPos: 0, |
| 113 | - oldValue: val | |
| 150 | + oldValue: val, | |
| 151 | + valueIndex: { | |
| 152 | + min: 0, | |
| 153 | + max: 1, | |
| 154 | + }, | |
| 114 | 155 | }; |
| 115 | 156 | }, |
| 116 | 157 | watch: { |
| ... | ... | @@ -173,7 +214,6 @@ |
| 173 | 214 | return (val[1] - this.min) / this.valueRange * 100; |
| 174 | 215 | }, |
| 175 | 216 | barStyle () { |
| 176 | - | |
| 177 | 217 | const style = { |
| 178 | 218 | width: (this.currentValue[0] - this.min) / this.valueRange * 100 + '%' |
| 179 | 219 | }; |
| ... | ... | @@ -216,6 +256,30 @@ |
| 216 | 256 | max = Math.min(this.max, max); |
| 217 | 257 | return [min, max]; |
| 218 | 258 | }, |
| 259 | + getCurrentValue (event, type) { | |
| 260 | + if (this.disabled) { | |
| 261 | + return; | |
| 262 | + } | |
| 263 | + | |
| 264 | + const index = this.valueIndex[type]; | |
| 265 | + if (typeof index === 'undefined') { | |
| 266 | + return; | |
| 267 | + } | |
| 268 | + | |
| 269 | + return this.currentValue[index]; | |
| 270 | + }, | |
| 271 | + onKeyLeft (event, type) { | |
| 272 | + const value = this.getCurrentValue(event, type); | |
| 273 | + if (Number.isFinite(value)) { | |
| 274 | + this.changeButtonPosition(value - this.step, type); | |
| 275 | + } | |
| 276 | + }, | |
| 277 | + onKeyRight (event, type) { | |
| 278 | + const value = this.getCurrentValue(event, type); | |
| 279 | + if (Number.isFinite(value)) { | |
| 280 | + this.changeButtonPosition(value + this.step, type); | |
| 281 | + } | |
| 282 | + }, | |
| 219 | 283 | onPointerDown (event, type) { |
| 220 | 284 | if (this.disabled) return; |
| 221 | 285 | event.preventDefault(); | ... | ... |