36febc3c
梁灏
add Slider
|
1
2
|
<template>
<div :class="classes">
|
69576f47
梁灏
add Slider component
|
3
4
5
6
7
|
<Input-number
v-if="!range && showInput"
:min="min"
:max="max"
:step="step"
|
e3549149
Sergio Crisostomo
normalise public ...
|
8
|
:value="exportValue[0]"
|
69576f47
梁灏
add Slider component
|
9
10
|
:disabled="disabled"
@on-change="handleInputChange"></Input-number>
|
791d254e
Graham Fairweather
Slider: Keyboard ...
|
11
12
13
14
|
<div
:class="[prefixCls + '-wrap']"
ref="slider" @click.self="sliderClick"
>
|
e3549149
Sergio Crisostomo
normalise public ...
|
15
|
<input type="hidden" :name="name" :value="exportValue">
|
36febc3c
梁灏
add Slider
|
16
|
<template v-if="showStops">
|
791d254e
Graham Fairweather
Slider: Keyboard ...
|
17
18
19
20
21
22
|
<div
:class="[prefixCls + '-stop']"
v-for="item in stops"
:style="{ 'left': item + '%' }"
@click.self="sliderClick"
></div>
|
36febc3c
梁灏
add Slider
|
23
|
</template>
|
791d254e
Graham Fairweather
Slider: Keyboard ...
|
24
25
26
27
|
<div
:class="[prefixCls + '-bar']"
:style="barStyle"
@click.self="sliderClick"></div>
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
28
29
30
31
32
|
<div
:class="[prefixCls + '-button-wrap']"
:style="{left: minPosition + '%'}"
@touchstart="onPointerDown($event, 'min')"
@mousedown="onPointerDown($event, 'min')">
|
791d254e
Graham Fairweather
Slider: Keyboard ...
|
33
34
35
36
37
38
39
40
41
42
43
|
<Tooltip
:controlled="pointerDown === 'min'"
placement="top"
:content="tipFormat(exportValue[0])"
:disabled="tipDisabled"
:always="showTip === 'always'"
ref="minTooltip"
>
<div
:class="minButtonClasses"
tabindex="0"
|
5cb6ce9e
梁灏
Slider add Toolti...
|
44
45
|
@focus="handleFocus('min')"
@blur="handleBlur('min')"
|
791d254e
Graham Fairweather
Slider: Keyboard ...
|
46
47
48
49
50
|
@keydown.left="onKeyLeft($event, 'min')"
@keydown.down="onKeyLeft($event, 'min')"
@keydown.right="onKeyRight($event, 'min')"
@keydown.up="onKeyRight($event, 'min')"
></div>
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
51
52
53
54
55
56
57
|
</Tooltip>
</div>
<div v-if="range"
:class="[prefixCls + '-button-wrap']"
:style="{left: maxPosition + '%'}"
@touchstart="onPointerDown($event, 'max')"
@mousedown="onPointerDown($event, 'max')">
|
791d254e
Graham Fairweather
Slider: Keyboard ...
|
58
59
60
61
62
63
64
65
66
67
68
|
<Tooltip
:controlled="pointerDown === 'max'"
placement="top"
:content="tipFormat(exportValue[1])"
:disabled="tipDisabled"
:always="showTip === 'always'"
ref="maxTooltip"
>
<div
:class="maxButtonClasses"
tabindex="0"
|
5cb6ce9e
梁灏
Slider add Toolti...
|
69
70
|
@focus="handleFocus('max')"
@blur="handleBlur('max')"
|
791d254e
Graham Fairweather
Slider: Keyboard ...
|
71
72
73
74
75
|
@keydown.left="onKeyLeft($event, 'max')"
@keydown.down="onKeyLeft($event, 'max')"
@keydown.right="onKeyRight($event, 'max')"
@keydown.up="onKeyRight($event, 'max')"
></div>
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
76
77
|
</Tooltip>
</div>
|
36febc3c
梁灏
add Slider
|
78
79
80
81
82
83
|
</div>
</div>
</template>
<script>
import InputNumber from '../../components/input-number/input-number.vue';
import Tooltip from '../../components/tooltip/tooltip.vue';
|
59872199
Rijn
added show-tip to...
|
84
|
import { getStyle, oneOf } from '../../utils/assist';
|
825ed580
梁灏
fixed bug
|
85
|
import { on, off } from '../../utils/dom';
|
cd78c9c4
梁灏
some comps suppor...
|
86
|
import Emitter from '../../mixins/emitter';
|
36febc3c
梁灏
add Slider
|
87
88
89
90
|
const prefixCls = 'ivu-slider';
export default {
|
b1c118d8
梁灏
support Dropdown
|
91
|
name: 'Slider',
|
cd78c9c4
梁灏
some comps suppor...
|
92
|
mixins: [ Emitter ],
|
36febc3c
梁灏
add Slider
|
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
components: { InputNumber, Tooltip },
props: {
min: {
type: Number,
default: 0
},
max: {
type: Number,
default: 100
},
step: {
type: Number,
default: 1
},
range: {
type: Boolean,
default: false
},
value: {
type: [Number, Array],
default: 0
},
disabled: {
type: Boolean,
default: false
},
showInput: {
type: Boolean,
default: false
},
showStops: {
type: Boolean,
default: false
},
tipFormat: {
type: Function,
default (val) {
return val;
}
|
59872199
Rijn
added show-tip to...
|
132
133
134
135
136
137
138
|
},
showTip: {
type: String,
default: 'hover',
validator (value) {
return oneOf(value, ['hover', 'always', 'never']);
}
|
0460a1e8
梁灏
fixed #812
|
139
140
141
|
},
name: {
type: String
|
36febc3c
梁灏
add Slider
|
142
143
144
|
}
},
data () {
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
145
|
const val = this.checkLimits(Array.isArray(this.value) ? this.value : [this.value]);
|
36febc3c
梁灏
add Slider
|
146
|
return {
|
69576f47
梁灏
add Slider component
|
147
|
prefixCls: prefixCls,
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
148
|
currentValue: val,
|
69576f47
梁灏
add Slider component
|
149
|
dragging: false,
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
150
|
pointerDown: '',
|
69576f47
梁灏
add Slider component
|
151
152
153
|
startX: 0,
currentX: 0,
startPos: 0,
|
791d254e
Graham Fairweather
Slider: Keyboard ...
|
154
155
156
157
158
|
oldValue: val,
valueIndex: {
min: 0,
max: 1,
},
|
b0893113
jingsam
add eslint
|
159
|
};
|
36febc3c
梁灏
add Slider
|
160
|
},
|
1c803cdf
梁灏
support Slider
|
161
162
|
watch: {
value (val) {
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
163
164
165
166
|
val = this.checkLimits(Array.isArray(val) ? val : [val]);
if (val[0] !== this.currentValue[0] || val[1] !== this.currentValue[1]) {
this.currentValue = val;
}
|
1c803cdf
梁灏
support Slider
|
167
|
},
|
e3549149
Sergio Crisostomo
normalise public ...
|
168
|
exportValue (values) {
|
1c803cdf
梁灏
support Slider
|
169
|
this.$nextTick(() => {
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
170
|
this.$refs.minTooltip.updatePopper();
|
1c803cdf
梁灏
support Slider
|
171
|
if (this.range) {
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
172
|
this.$refs.maxTooltip.updatePopper();
|
1c803cdf
梁灏
support Slider
|
173
174
|
}
});
|
e3549149
Sergio Crisostomo
normalise public ...
|
175
176
177
|
const value = this.range ? values : values[0];
this.$emit('input', value);
this.$emit('on-input', value);
|
1c803cdf
梁灏
support Slider
|
178
179
|
}
},
|
36febc3c
梁灏
add Slider
|
180
181
182
183
184
|
computed: {
classes () {
return [
`${prefixCls}`,
{
|
69576f47
梁灏
add Slider component
|
185
|
[`${prefixCls}-input`]: this.showInput && !this.range,
|
36febc3c
梁灏
add Slider
|
186
187
188
|
[`${prefixCls}-range`]: this.range,
[`${prefixCls}-disabled`]: this.disabled
}
|
b0893113
jingsam
add eslint
|
189
|
];
|
36febc3c
梁灏
add Slider
|
190
|
},
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
191
|
minButtonClasses () {
|
69576f47
梁灏
add Slider component
|
192
193
194
|
return [
`${prefixCls}-button`,
{
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
195
|
[`${prefixCls}-button-dragging`]: this.pointerDown === 'min'
|
69576f47
梁灏
add Slider component
|
196
197
198
|
}
];
},
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
199
|
maxButtonClasses () {
|
69576f47
梁灏
add Slider component
|
200
201
202
|
return [
`${prefixCls}-button`,
{
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
203
|
[`${prefixCls}-button-dragging`]: this.pointerDown === 'max'
|
69576f47
梁灏
add Slider component
|
204
205
206
|
}
];
},
|
e3549149
Sergio Crisostomo
normalise public ...
|
207
208
209
210
|
exportValue(){
const decimalCases = (String(this.step).split('.')[1] || '').length;
return this.currentValue.map(nr => Number(nr.toFixed(decimalCases)));
},
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
211
212
|
minPosition () {
const val = this.currentValue;
|
965b6d8e
Sergio Crisostomo
Fix slider for m...
|
213
|
return (val[0] - this.min) / this.valueRange * 100;
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
214
215
216
217
|
},
maxPosition: function () {
const val = this.currentValue;
|
965b6d8e
Sergio Crisostomo
Fix slider for m...
|
218
|
return (val[1] - this.min) / this.valueRange * 100;
|
69576f47
梁灏
add Slider component
|
219
|
},
|
36febc3c
梁灏
add Slider
|
220
|
barStyle () {
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
221
|
const style = {
|
965b6d8e
Sergio Crisostomo
Fix slider for m...
|
222
|
width: (this.currentValue[0] - this.min) / this.valueRange * 100 + '%'
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
223
|
};
|
36febc3c
梁灏
add Slider
|
224
225
|
if (this.range) {
|
965b6d8e
Sergio Crisostomo
Fix slider for m...
|
226
227
|
style.left = (this.currentValue[0] - this.min) / this.valueRange * 100 + '%';
style.width = (this.currentValue[1] - this.currentValue[0]) / this.valueRange * 100 + '%';
|
36febc3c
梁灏
add Slider
|
228
229
230
231
|
}
return style;
},
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
232
|
stops () {
|
965b6d8e
Sergio Crisostomo
Fix slider for m...
|
233
|
let stopCount = this.valueRange / this.step;
|
41d90ccf
梁灏
Slider can show s...
|
234
|
let result = [];
|
965b6d8e
Sergio Crisostomo
Fix slider for m...
|
235
|
let stepWidth = 100 * this.step / this.valueRange;
|
41d90ccf
梁灏
Slider can show s...
|
236
237
238
239
|
for (let i = 1; i < stopCount; i++) {
result.push(i * stepWidth);
}
return result;
|
69576f47
梁灏
add Slider component
|
240
241
|
},
sliderWidth () {
|
1c803cdf
梁灏
support Slider
|
242
|
return parseInt(getStyle(this.$refs.slider, 'width'), 10);
|
59872199
Rijn
added show-tip to...
|
243
244
|
},
tipDisabled () {
|
1c803cdf
梁灏
support Slider
|
245
|
return this.tipFormat(this.currentValue[0]) === null || this.showTip === 'never';
|
965b6d8e
Sergio Crisostomo
Fix slider for m...
|
246
247
248
|
},
valueRange(){
return this.max - this.min;
|
36febc3c
梁灏
add Slider
|
249
250
251
|
}
},
methods: {
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
252
253
|
getPointerX (e) {
return e.type.indexOf('touch') !== -1 ? e.touches[0].clientX : e.clientX;
|
69576f47
梁灏
add Slider component
|
254
|
},
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
255
|
checkLimits ([min, max]) {
|
965b6d8e
Sergio Crisostomo
Fix slider for m...
|
256
257
|
min = Math.max(this.min, min);
min = Math.min(this.max, min);
|
36febc3c
梁灏
add Slider
|
258
|
|
965b6d8e
Sergio Crisostomo
Fix slider for m...
|
259
260
|
max = Math.max(this.min, min, max);
max = Math.min(this.max, max);
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
261
|
return [min, max];
|
69576f47
梁灏
add Slider component
|
262
|
},
|
791d254e
Graham Fairweather
Slider: Keyboard ...
|
263
|
getCurrentValue (event, type) {
|
5cb6ce9e
梁灏
Slider add Toolti...
|
264
265
266
|
if (this.disabled) {
return;
}
|
791d254e
Graham Fairweather
Slider: Keyboard ...
|
267
|
|
5cb6ce9e
梁灏
Slider add Toolti...
|
268
269
270
271
|
const index = this.valueIndex[type];
if (typeof index === 'undefined') {
return;
}
|
791d254e
Graham Fairweather
Slider: Keyboard ...
|
272
|
|
5cb6ce9e
梁灏
Slider add Toolti...
|
273
|
return this.currentValue[index];
|
791d254e
Graham Fairweather
Slider: Keyboard ...
|
274
275
|
},
onKeyLeft (event, type) {
|
5cb6ce9e
梁灏
Slider add Toolti...
|
276
277
278
279
|
const value = this.getCurrentValue(event, type);
if (Number.isFinite(value)) {
this.changeButtonPosition(value - this.step, type);
}
|
791d254e
Graham Fairweather
Slider: Keyboard ...
|
280
281
|
},
onKeyRight (event, type) {
|
5cb6ce9e
梁灏
Slider add Toolti...
|
282
283
284
285
|
const value = this.getCurrentValue(event, type);
if (Number.isFinite(value)) {
this.changeButtonPosition(value + this.step, type);
}
|
791d254e
Graham Fairweather
Slider: Keyboard ...
|
286
|
},
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
287
|
onPointerDown (event, type) {
|
69576f47
梁灏
add Slider component
|
288
|
if (this.disabled) return;
|
f2be585e
梁灏
optimize Slider w...
|
289
|
event.preventDefault();
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
290
291
292
293
294
295
296
|
this.pointerDown = type;
this.onPointerDragStart(event);
on(window, 'mousemove', this.onPointerDrag);
on(window, 'touchmove', this.onPointerDrag);
on(window, 'mouseup', this.onPointerDragEnd);
on(window, 'touchend', this.onPointerDragEnd);
|
69576f47
梁灏
add Slider component
|
297
|
},
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
298
|
onPointerDragStart (event) {
|
ce4c0faa
oustn
修复 Slider 滑动按钮单击时...
|
299
|
this.dragging = false;
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
300
|
this.startX = this.getPointerX(event);
|
965b6d8e
Sergio Crisostomo
Fix slider for m...
|
301
|
this.startPos = (this[`${this.pointerDown}Position`] * this.valueRange / 100) + this.min;
|
69576f47
梁灏
add Slider component
|
302
|
},
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
303
|
onPointerDrag (event) {
|
ce4c0faa
oustn
修复 Slider 滑动按钮单击时...
|
304
|
this.dragging = true;
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
305
306
|
this.$refs[`${this.pointerDown}Tooltip`].visible = true;
this.currentX = this.getPointerX(event);
|
965b6d8e
Sergio Crisostomo
Fix slider for m...
|
307
|
const diff = (this.currentX - this.startX) / this.sliderWidth * this.valueRange;
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
308
|
|
965b6d8e
Sergio Crisostomo
Fix slider for m...
|
309
|
this.changeButtonPosition(this.startPos + diff);
|
69576f47
梁灏
add Slider component
|
310
|
},
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
311
|
onPointerDragEnd () {
|
69576f47
梁灏
add Slider component
|
312
313
|
if (this.dragging) {
this.dragging = false;
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
314
|
this.$refs[`${this.pointerDown}Tooltip`].visible = false;
|
b964efae
Sergio Crisostomo
Emit change on po...
|
315
|
this.emitChange();
|
69576f47
梁灏
add Slider component
|
316
|
}
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
317
318
319
320
321
322
|
this.pointerDown = '';
off(window, 'mousemove', this.onPointerDrag);
off(window, 'touchmove', this.onPointerDrag);
off(window, 'mouseup', this.onPointerDragEnd);
off(window, 'touchend', this.onPointerDragEnd);
|
69576f47
梁灏
add Slider component
|
323
|
},
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
324
|
changeButtonPosition (newPos, forceType) {
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
325
326
327
328
329
|
const type = forceType || this.pointerDown;
const index = type === 'min' ? 0 : 1;
if (type === 'min') newPos = this.checkLimits([newPos, this.maxPosition])[0];
else newPos = this.checkLimits([this.minPosition, newPos])[1];
|
eb8c6cd9
Sergio Crisostomo
Correct steps cal...
|
330
|
const modulus = newPos % this.step;
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
331
|
const value = this.currentValue;
|
eb8c6cd9
Sergio Crisostomo
Correct steps cal...
|
332
|
value[index] = newPos - modulus;
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
333
334
|
this.currentValue = [...value];
|
a6fc9438
梁灏
fixed #461
|
335
|
if (!this.dragging) {
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
336
|
if (this.currentValue[index] !== this.oldValue[index]) {
|
b964efae
Sergio Crisostomo
Emit change on po...
|
337
|
this.emitChange();
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
338
|
this.oldValue[index] = this.currentValue[index];
|
69576f47
梁灏
add Slider component
|
339
340
341
|
}
}
},
|
69576f47
梁灏
add Slider component
|
342
|
|
b964efae
Sergio Crisostomo
Emit change on po...
|
343
|
emitChange(){
|
e3549149
Sergio Crisostomo
normalise public ...
|
344
345
346
|
const value = this.range ? this.exportValue : this.exportValue[0];
this.$emit('on-change', value);
this.dispatch('FormItem', 'on-form-change', value);
|
b964efae
Sergio Crisostomo
Emit change on po...
|
347
348
|
},
|
2eccfc99
梁灏
fixed #2852
|
349
|
sliderClick (event) {
|
69576f47
梁灏
add Slider component
|
350
|
if (this.disabled) return;
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
351
352
|
const currentX = this.getPointerX(event);
const sliderOffsetLeft = this.$refs.slider.getBoundingClientRect().left;
|
965b6d8e
Sergio Crisostomo
Fix slider for m...
|
353
|
let newPos = ((currentX - sliderOffsetLeft) / this.sliderWidth * this.valueRange) + this.min;
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
354
355
356
357
|
if (!this.range || newPos <= this.minPosition) this.changeButtonPosition(newPos, 'min');
else if (newPos >= this.maxPosition) this.changeButtonPosition(newPos, 'max');
else this.changeButtonPosition(newPos, ((newPos - this.firstPosition) <= (this.secondPosition - newPos)) ? 'min' : 'max');
|
69576f47
梁灏
add Slider component
|
358
|
},
|
69576f47
梁灏
add Slider component
|
359
|
|
2b87ffa9
Sergio Crisostomo
refactor and DRY ...
|
360
361
|
handleInputChange (val) {
this.currentValue = [val, this.currentValue[1]];
|
e3549149
Sergio Crisostomo
normalise public ...
|
362
|
this.emitChange();
|
69576f47
梁灏
add Slider component
|
363
|
},
|
5cb6ce9e
梁灏
Slider add Toolti...
|
364
365
366
367
368
369
370
371
|
handleFocus (type) {
this.$refs[`${type}Tooltip`].handleShowPopper();
},
handleBlur (type) {
this.$refs[`${type}Tooltip`].handleClosePopper();
}
|
2eccfc99
梁灏
fixed #2852
|
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
|
},
mounted () {
// #2852
this.$on('on-visible-change', (val) => {
if (val && this.showTip === 'always') {
this.$refs.minTooltip.doDestroy();
if (this.range) {
this.$refs.maxTooltip.doDestroy();
}
this.$nextTick(() => {
this.$refs.minTooltip.updatePopper();
if (this.range) {
this.$refs.maxTooltip.updatePopper();
}
});
}
});
|
36febc3c
梁灏
add Slider
|
389
|
}
|
b0893113
jingsam
add eslint
|
390
391
|
};
</script>
|