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,20 +8,44 @@ | ||
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 | + @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 | </Tooltip> | 49 | </Tooltip> |
26 | </div> | 50 | </div> |
27 | <div v-if="range" | 51 | <div v-if="range" |
@@ -29,9 +53,22 @@ | @@ -29,9 +53,22 @@ | ||
29 | :style="{left: maxPosition + '%'}" | 53 | :style="{left: maxPosition + '%'}" |
30 | @touchstart="onPointerDown($event, 'max')" | 54 | @touchstart="onPointerDown($event, 'max')" |
31 | @mousedown="onPointerDown($event, 'max')"> | 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 | </Tooltip> | 72 | </Tooltip> |
36 | </div> | 73 | </div> |
37 | </div> | 74 | </div> |
@@ -110,7 +147,11 @@ | @@ -110,7 +147,11 @@ | ||
110 | startX: 0, | 147 | startX: 0, |
111 | currentX: 0, | 148 | currentX: 0, |
112 | startPos: 0, | 149 | startPos: 0, |
113 | - oldValue: val | 150 | + oldValue: val, |
151 | + valueIndex: { | ||
152 | + min: 0, | ||
153 | + max: 1, | ||
154 | + }, | ||
114 | }; | 155 | }; |
115 | }, | 156 | }, |
116 | watch: { | 157 | watch: { |
@@ -173,7 +214,6 @@ | @@ -173,7 +214,6 @@ | ||
173 | return (val[1] - this.min) / this.valueRange * 100; | 214 | return (val[1] - this.min) / this.valueRange * 100; |
174 | }, | 215 | }, |
175 | barStyle () { | 216 | barStyle () { |
176 | - | ||
177 | const style = { | 217 | const style = { |
178 | width: (this.currentValue[0] - this.min) / this.valueRange * 100 + '%' | 218 | width: (this.currentValue[0] - this.min) / this.valueRange * 100 + '%' |
179 | }; | 219 | }; |
@@ -216,6 +256,30 @@ | @@ -216,6 +256,30 @@ | ||
216 | max = Math.min(this.max, max); | 256 | max = Math.min(this.max, max); |
217 | return [min, max]; | 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 | onPointerDown (event, type) { | 283 | onPointerDown (event, type) { |
220 | if (this.disabled) return; | 284 | if (this.disabled) return; |
221 | event.preventDefault(); | 285 | event.preventDefault(); |
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 | { |