@v-c/slider 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/Handles/Handle.cjs +1 -0
- package/dist/Handles/Handle.d.ts +107 -0
- package/dist/Handles/Handle.js +203 -0
- package/dist/Handles/index.cjs +1 -0
- package/dist/Handles/index.d.ts +98 -0
- package/dist/Handles/index.js +117 -0
- package/dist/Marks/Mark.cjs +1 -0
- package/dist/Marks/Mark.d.ts +9 -0
- package/dist/Marks/Mark.js +39 -0
- package/dist/Marks/index.cjs +1 -0
- package/dist/Marks/index.d.ts +15 -0
- package/dist/Marks/index.js +31 -0
- package/dist/Slider.cjs +1 -0
- package/dist/Slider.d.ts +253 -0
- package/dist/Slider.js +343 -0
- package/dist/Steps/Dot.cjs +1 -0
- package/dist/Steps/Dot.d.ts +9 -0
- package/dist/Steps/Dot.js +38 -0
- package/dist/Steps/index.cjs +1 -0
- package/dist/Steps/index.d.ts +11 -0
- package/dist/Steps/index.js +41 -0
- package/dist/Tracks/Track.cjs +1 -0
- package/dist/Tracks/Track.d.ts +61 -0
- package/dist/Tracks/Track.js +82 -0
- package/dist/Tracks/index.cjs +1 -0
- package/dist/Tracks/index.d.ts +47 -0
- package/dist/Tracks/index.js +83 -0
- package/dist/context.cjs +1 -0
- package/dist/context.d.ts +51 -0
- package/dist/context.js +27 -0
- package/dist/hooks/useDrag.cjs +1 -0
- package/dist/hooks/useDrag.d.ts +11 -0
- package/dist/hooks/useDrag.js +88 -0
- package/dist/hooks/useOffset.cjs +1 -0
- package/dist/hooks/useOffset.d.ts +10 -0
- package/dist/hooks/useOffset.js +98 -0
- package/dist/hooks/useRange.cjs +1 -0
- package/dist/hooks/useRange.d.ts +8 -0
- package/dist/hooks/useRange.js +10 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -0
- package/dist/interface.cjs +1 -0
- package/dist/interface.d.ts +7 -0
- package/dist/interface.js +1 -0
- package/dist/util.cjs +1 -0
- package/dist/util.d.ts +6 -0
- package/dist/util.js +29 -0
- package/docs/TooltipSlider.tsx +94 -0
- package/docs/assets/anim.less +63 -0
- package/docs/assets/bootstrap.less +163 -0
- package/docs/assets/index.less +337 -0
- package/docs/debug.vue +60 -0
- package/docs/editable.vue +59 -0
- package/docs/handle.vue +45 -0
- package/docs/marks.vue +85 -0
- package/docs/multiple.vue +54 -0
- package/docs/range.vue +211 -0
- package/docs/slider.stories.vue +45 -0
- package/docs/sliderDemo.vue +267 -0
- package/docs/vertical.vue +122 -0
- package/package.json +35 -0
- package/src/Handles/Handle.tsx +226 -0
- package/src/Handles/index.tsx +124 -0
- package/src/Marks/Mark.tsx +40 -0
- package/src/Marks/index.tsx +40 -0
- package/src/Slider.tsx +582 -0
- package/src/Steps/Dot.tsx +40 -0
- package/src/Steps/index.tsx +54 -0
- package/src/Tracks/Track.tsx +89 -0
- package/src/Tracks/index.tsx +92 -0
- package/src/context.ts +65 -0
- package/src/hooks/useDrag.ts +244 -0
- package/src/hooks/useOffset.ts +264 -0
- package/src/hooks/useRange.ts +24 -0
- package/src/index.ts +8 -0
- package/src/interface.ts +17 -0
- package/src/util.ts +41 -0
- package/vite.config.ts +18 -0
- package/vitest.config.ts +11 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { CSSProperties } from 'vue'
|
|
3
|
+
import Slider from '@v-c/slider'
|
|
4
|
+
import { ref } from 'vue'
|
|
5
|
+
import TooltipSlider from './TooltipSlider'
|
|
6
|
+
|
|
7
|
+
const style: CSSProperties = {
|
|
8
|
+
width: '600px',
|
|
9
|
+
margin: '50px',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function log(value: unknown) {
|
|
13
|
+
console.log(value) //eslint-disable-line
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function percentFormatter(v: unknown) {
|
|
17
|
+
return `${v} %`
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// NullableSlider组件
|
|
21
|
+
const nullableSliderValue = ref(null)
|
|
22
|
+
|
|
23
|
+
function onNullableSliderChange(newValue: any) {
|
|
24
|
+
log(newValue)
|
|
25
|
+
nullableSliderValue.value = newValue
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function onNullableSliderAfterChange(newValue: unknown) {
|
|
29
|
+
console.log(newValue) //eslint-disable-line
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function resetNullableSlider() {
|
|
33
|
+
console.log('reset value')
|
|
34
|
+
nullableSliderValue.value = null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// NullableRangeSlider组件
|
|
38
|
+
const nullableRangeValue = ref(null)
|
|
39
|
+
|
|
40
|
+
function setNullableRangeValue(newValue: any) {
|
|
41
|
+
nullableRangeValue.value = newValue
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function resetNullableRange() {
|
|
45
|
+
nullableRangeValue.value = null
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// CustomizedSlider组件
|
|
49
|
+
const customizedValue = ref(50)
|
|
50
|
+
|
|
51
|
+
function onCustomizedSliderChange(newValue: any) {
|
|
52
|
+
log(newValue)
|
|
53
|
+
customizedValue.value = newValue
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function onCustomizedSliderAfterChange(newValue: unknown) {
|
|
57
|
+
console.log(newValue) //eslint-disable-line
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// DynamicBounds组件
|
|
61
|
+
const dynamicMin = ref(1)
|
|
62
|
+
const dynamicMax = ref(100)
|
|
63
|
+
const dynamicStep = ref(10)
|
|
64
|
+
const dynamicValue = ref(1)
|
|
65
|
+
|
|
66
|
+
function onDynamicSliderChange(newValue: any) {
|
|
67
|
+
log(newValue)
|
|
68
|
+
dynamicValue.value = newValue
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function onDynamicMinChange(e: any) {
|
|
72
|
+
dynamicMin.value = +e.target.value || 0
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function onDynamicMaxChange(e: any) {
|
|
76
|
+
dynamicMax.value = +e.target.value || 100
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function onDynamicStepChange(e: any) {
|
|
80
|
+
dynamicStep.value = +e.target.value || 1
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const labelStyle = { minWidth: '60px', display: 'inline-block' }
|
|
84
|
+
const inputStyle = { marginBottom: '10px' }
|
|
85
|
+
</script>
|
|
86
|
+
|
|
87
|
+
<template>
|
|
88
|
+
<div>
|
|
89
|
+
<div :style="style">
|
|
90
|
+
<p>Basic Slider</p>
|
|
91
|
+
<Slider @change="log" />
|
|
92
|
+
</div>
|
|
93
|
+
<div :style="style">
|
|
94
|
+
<p>Basic Slider, `startPoint=50`</p>
|
|
95
|
+
<Slider :start-point="50" @change="log" />
|
|
96
|
+
</div>
|
|
97
|
+
<div :style="style">
|
|
98
|
+
<p>Slider reverse</p>
|
|
99
|
+
<Slider reverse :min="20" :max="60" @change="log" />
|
|
100
|
+
</div>
|
|
101
|
+
<div :style="style">
|
|
102
|
+
<p>Basic Slider,`step=20`</p>
|
|
103
|
+
<Slider :step="20" :default-value="50" @before-change="log" />
|
|
104
|
+
</div>
|
|
105
|
+
<div :style="style">
|
|
106
|
+
<p>Basic Slider,`step=20, dots`</p>
|
|
107
|
+
<Slider dots :step="20" :default-value="100" @change-complete="log" />
|
|
108
|
+
</div>
|
|
109
|
+
<div :style="style">
|
|
110
|
+
<p>
|
|
111
|
+
Basic Slider,`step=20, dots, dotStyle={"borderColor: 'orange'"}, activeDotStyle=
|
|
112
|
+
{"borderColor: 'yellow'"}`
|
|
113
|
+
</p>
|
|
114
|
+
<Slider
|
|
115
|
+
dots
|
|
116
|
+
:step="20"
|
|
117
|
+
:default-value="100"
|
|
118
|
+
:dot-style="{ borderColor: 'orange' }"
|
|
119
|
+
:active-dot-style="{ borderColor: 'yellow' }"
|
|
120
|
+
@change-complete="log"
|
|
121
|
+
/>
|
|
122
|
+
</div>
|
|
123
|
+
<div :style="style">
|
|
124
|
+
<p>Slider with tooltip, with custom `tipFormatter`</p>
|
|
125
|
+
<TooltipSlider
|
|
126
|
+
:tip-formatter="percentFormatter"
|
|
127
|
+
:tip-props="{ overlayClassName: 'foo' }"
|
|
128
|
+
@change="log"
|
|
129
|
+
/>
|
|
130
|
+
</div>
|
|
131
|
+
<div :style="style">
|
|
132
|
+
<p>
|
|
133
|
+
Slider with custom handle and track style.<strong>(old api, will be deprecated)</strong>
|
|
134
|
+
</p>
|
|
135
|
+
<Slider
|
|
136
|
+
:default-value="30"
|
|
137
|
+
:rail-style="{ backgroundColor: 'red', height: 10 }"
|
|
138
|
+
:track-style="{ backgroundColor: 'blue', height: 10 }"
|
|
139
|
+
:handle-style="{
|
|
140
|
+
borderColor: 'blue',
|
|
141
|
+
height: 28,
|
|
142
|
+
width: 28,
|
|
143
|
+
marginLeft: -14,
|
|
144
|
+
marginTop: -9,
|
|
145
|
+
backgroundColor: 'black',
|
|
146
|
+
}"
|
|
147
|
+
/>
|
|
148
|
+
</div>
|
|
149
|
+
<div :style="style">
|
|
150
|
+
<p>
|
|
151
|
+
Slider with custom handle and track style.<strong>(The recommended new api)</strong>
|
|
152
|
+
</p>
|
|
153
|
+
<Slider
|
|
154
|
+
:default-value="30"
|
|
155
|
+
:track-style="{ backgroundColor: 'blue', height: 10 }"
|
|
156
|
+
:handle-style="{
|
|
157
|
+
borderColor: 'blue',
|
|
158
|
+
height: 28,
|
|
159
|
+
width: 28,
|
|
160
|
+
marginLeft: -14,
|
|
161
|
+
marginTop: -9,
|
|
162
|
+
backgroundColor: 'black',
|
|
163
|
+
}"
|
|
164
|
+
:rail-style="{ backgroundColor: 'red', height: 10 }"
|
|
165
|
+
/>
|
|
166
|
+
</div>
|
|
167
|
+
<div :style="style">
|
|
168
|
+
<p>
|
|
169
|
+
Reversed Slider with custom handle and track style.
|
|
170
|
+
<strong>(The recommended new api)</strong>
|
|
171
|
+
</p>
|
|
172
|
+
<Slider
|
|
173
|
+
:default-value="30"
|
|
174
|
+
:track-style="{ backgroundColor: 'blue', height: 10 }"
|
|
175
|
+
reverse
|
|
176
|
+
:handle-style="{
|
|
177
|
+
borderColor: 'blue',
|
|
178
|
+
height: 28,
|
|
179
|
+
width: 28,
|
|
180
|
+
marginLeft: -14,
|
|
181
|
+
marginTop: -9,
|
|
182
|
+
backgroundColor: 'black',
|
|
183
|
+
}"
|
|
184
|
+
:rail-style="{ backgroundColor: 'red', height: 10 }"
|
|
185
|
+
/>
|
|
186
|
+
</div>
|
|
187
|
+
<div :style="style">
|
|
188
|
+
<p>Basic Slider, disabled</p>
|
|
189
|
+
<Slider disabled @change="log" />
|
|
190
|
+
</div>
|
|
191
|
+
<div :style="style">
|
|
192
|
+
<p>Controlled Slider</p>
|
|
193
|
+
<Slider :value="50" />
|
|
194
|
+
</div>
|
|
195
|
+
<div :style="style">
|
|
196
|
+
<p>Customized Slider</p>
|
|
197
|
+
<Slider
|
|
198
|
+
:value="customizedValue"
|
|
199
|
+
@change="onCustomizedSliderChange"
|
|
200
|
+
@change-complete="onCustomizedSliderAfterChange"
|
|
201
|
+
/>
|
|
202
|
+
</div>
|
|
203
|
+
<div :style="style">
|
|
204
|
+
<p>Slider with null value and reset button</p>
|
|
205
|
+
<div>
|
|
206
|
+
<Slider
|
|
207
|
+
:value="nullableSliderValue"
|
|
208
|
+
@change="onNullableSliderChange"
|
|
209
|
+
@change-complete="onNullableSliderAfterChange"
|
|
210
|
+
/>
|
|
211
|
+
<button type="button" @click="resetNullableSlider">
|
|
212
|
+
Reset
|
|
213
|
+
</button>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
<div :style="style">
|
|
217
|
+
<p>Range Slider with null value and reset button</p>
|
|
218
|
+
<div>
|
|
219
|
+
<Slider range :value="nullableRangeValue" @change="setNullableRangeValue" />
|
|
220
|
+
<button type="button" @click="resetNullableRange">
|
|
221
|
+
Reset
|
|
222
|
+
</button>
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
<div :style="style">
|
|
226
|
+
<p>Slider with dynamic `min` `max` `step`</p>
|
|
227
|
+
<div>
|
|
228
|
+
<label :style="labelStyle">Min: </label>
|
|
229
|
+
<input
|
|
230
|
+
type="number"
|
|
231
|
+
:value="dynamicMin"
|
|
232
|
+
:style="inputStyle"
|
|
233
|
+
@input="onDynamicMinChange"
|
|
234
|
+
>
|
|
235
|
+
<br>
|
|
236
|
+
<label :style="labelStyle">Max: </label>
|
|
237
|
+
<input
|
|
238
|
+
type="number"
|
|
239
|
+
:value="dynamicMax"
|
|
240
|
+
:style="inputStyle"
|
|
241
|
+
@input="onDynamicMaxChange"
|
|
242
|
+
>
|
|
243
|
+
<br>
|
|
244
|
+
<label :style="labelStyle">Step: </label>
|
|
245
|
+
<input
|
|
246
|
+
type="number"
|
|
247
|
+
:value="dynamicStep"
|
|
248
|
+
:style="inputStyle"
|
|
249
|
+
@input="onDynamicStepChange"
|
|
250
|
+
>
|
|
251
|
+
<br>
|
|
252
|
+
<br>
|
|
253
|
+
<label :style="labelStyle">Value: </label>
|
|
254
|
+
<span>{{ dynamicValue }}</span>
|
|
255
|
+
<br>
|
|
256
|
+
<br>
|
|
257
|
+
<Slider
|
|
258
|
+
:value="dynamicValue"
|
|
259
|
+
:min="dynamicMin"
|
|
260
|
+
:max="dynamicMax"
|
|
261
|
+
:step="dynamicStep"
|
|
262
|
+
@change="onDynamicSliderChange"
|
|
263
|
+
/>
|
|
264
|
+
</div>
|
|
265
|
+
</div>
|
|
266
|
+
</div>
|
|
267
|
+
</template>
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { CSSProperties } from 'vue'
|
|
3
|
+
import Slider from '@v-c/slider'
|
|
4
|
+
|
|
5
|
+
const style: CSSProperties = {
|
|
6
|
+
float: 'left',
|
|
7
|
+
width: '160px',
|
|
8
|
+
height: '400px',
|
|
9
|
+
marginBottom: '160px',
|
|
10
|
+
marginLeft: '50px',
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const parentStyle: CSSProperties = {
|
|
14
|
+
overflow: 'hidden',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const marks = {
|
|
18
|
+
'-10': '-10°C',
|
|
19
|
+
'0': '0°C',
|
|
20
|
+
'26': '26°C',
|
|
21
|
+
'37': '37°C',
|
|
22
|
+
'50': '50°C',
|
|
23
|
+
'100': {
|
|
24
|
+
style: {
|
|
25
|
+
color: 'red',
|
|
26
|
+
},
|
|
27
|
+
label: '100°C',
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function log(value) {
|
|
32
|
+
console.log(value); //eslint-disable-line
|
|
33
|
+
}
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<template>
|
|
37
|
+
<div :style="parentStyle">
|
|
38
|
+
<div :style="style">
|
|
39
|
+
<p>Slider with marks, `step=null`</p>
|
|
40
|
+
<Slider vertical :min="-10" :marks="marks" :step="null" :default-value="20" @change="log" />
|
|
41
|
+
</div>
|
|
42
|
+
<div :style="style">
|
|
43
|
+
<p>Slider with marks, `step=null` and `startPoint=0`</p>
|
|
44
|
+
<Slider
|
|
45
|
+
vertical
|
|
46
|
+
:min="-10"
|
|
47
|
+
:start-point="0"
|
|
48
|
+
:marks="marks"
|
|
49
|
+
:step="null"
|
|
50
|
+
:default-value="20"
|
|
51
|
+
@change="log"
|
|
52
|
+
/>
|
|
53
|
+
</div>
|
|
54
|
+
<div :style="style">
|
|
55
|
+
<p>Reverse Slider with marks, `step=null`</p>
|
|
56
|
+
<Slider
|
|
57
|
+
vertical
|
|
58
|
+
:min="-10"
|
|
59
|
+
:marks="marks"
|
|
60
|
+
:step="null"
|
|
61
|
+
:default-value="20"
|
|
62
|
+
reverse
|
|
63
|
+
@change="log"
|
|
64
|
+
/>
|
|
65
|
+
</div>
|
|
66
|
+
<div :style="style">
|
|
67
|
+
<p>Slider with marks and steps</p>
|
|
68
|
+
<Slider vertical dots :min="-10" :marks="marks" :step="10" :default-value="20" @change="log" />
|
|
69
|
+
</div>
|
|
70
|
+
<div :style="style">
|
|
71
|
+
<p>Slider with marks, `included=false`</p>
|
|
72
|
+
<Slider vertical :min="-10" :marks="marks" :included="false" :default-value="20" />
|
|
73
|
+
</div>
|
|
74
|
+
<div :style="style">
|
|
75
|
+
<p>Slider with marks and steps, `included=false`</p>
|
|
76
|
+
<Slider vertical :min="-10" :marks="marks" :step="10" :included="false" :default-value="20" />
|
|
77
|
+
</div>
|
|
78
|
+
<div :style="style">
|
|
79
|
+
<p>Range with marks</p>
|
|
80
|
+
<Slider range vertical :min="-10" :marks="marks" :default-value="[20, 40]" @change="log" />
|
|
81
|
+
</div>
|
|
82
|
+
<div :style="style">
|
|
83
|
+
<p>Range with marks and steps</p>
|
|
84
|
+
<Slider
|
|
85
|
+
range
|
|
86
|
+
vertical
|
|
87
|
+
:min="-10"
|
|
88
|
+
:marks="marks"
|
|
89
|
+
:step="10"
|
|
90
|
+
:default-value="[20, 40]"
|
|
91
|
+
@change="log"
|
|
92
|
+
/>
|
|
93
|
+
</div>
|
|
94
|
+
<div :style="style">
|
|
95
|
+
<p>Range with marks and draggableTrack</p>
|
|
96
|
+
<Slider
|
|
97
|
+
:range="{ draggableTrack: true }"
|
|
98
|
+
vertical
|
|
99
|
+
:min="-10"
|
|
100
|
+
:marks="marks"
|
|
101
|
+
:default-value="[20, 40]"
|
|
102
|
+
@change="log"
|
|
103
|
+
/>
|
|
104
|
+
</div>
|
|
105
|
+
<div :style="style">
|
|
106
|
+
<p>Range with marks and draggableTrack(reverse)</p>
|
|
107
|
+
<Slider
|
|
108
|
+
:range="{ draggableTrack: true }"
|
|
109
|
+
vertical
|
|
110
|
+
reverse
|
|
111
|
+
:min="-10"
|
|
112
|
+
:marks="marks"
|
|
113
|
+
:default-value="[20, 40]"
|
|
114
|
+
@change="log"
|
|
115
|
+
/>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</template>
|
|
119
|
+
|
|
120
|
+
<style scoped>
|
|
121
|
+
|
|
122
|
+
</style>
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@v-c/slider",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"require": "./dist/index.cjs"
|
|
11
|
+
},
|
|
12
|
+
"./dist/*": "./dist/*",
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"main": "index.js",
|
|
16
|
+
"peerDependencies": {
|
|
17
|
+
"vue": "^3.0.0"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"classnames": "^2.5.1",
|
|
21
|
+
"@v-c/util": "0.0.4"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@v-c/tooltip": "1.0.0"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"slider"
|
|
28
|
+
],
|
|
29
|
+
"author": "",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "vite build",
|
|
33
|
+
"test": "vitest"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import type { CSSProperties, PropType } from 'vue'
|
|
2
|
+
import type { OnStartMove, SliderClassNames, SliderStyles } from '../interface'
|
|
3
|
+
import KeyCode from '@v-c/util/dist/KeyCode'
|
|
4
|
+
import cls from 'classnames'
|
|
5
|
+
import { defineComponent, ref } from 'vue'
|
|
6
|
+
import { useInjectSlider } from '../context'
|
|
7
|
+
import { getDirectionStyle, getIndex } from '../util'
|
|
8
|
+
|
|
9
|
+
export default defineComponent({
|
|
10
|
+
name: 'Handle',
|
|
11
|
+
props: {
|
|
12
|
+
prefixCls: { type: String, required: true },
|
|
13
|
+
value: { type: Number, required: true },
|
|
14
|
+
valueIndex: { type: Number, required: true },
|
|
15
|
+
dragging: { type: Boolean, default: false },
|
|
16
|
+
draggingDelete: { type: Boolean, default: false },
|
|
17
|
+
onStartMove: { type: Function as PropType<OnStartMove>, required: true },
|
|
18
|
+
onDelete: { type: Function as PropType<(index: number) => void>, required: true },
|
|
19
|
+
onOffsetChange: { type: Function as PropType<(value: number | 'min' | 'max', valueIndex: number) => void>, required: true },
|
|
20
|
+
onFocus: { type: Function as PropType<(e: FocusEvent, index: number) => void>, required: true },
|
|
21
|
+
onMouseenter: { type: Function as PropType<(e: MouseEvent, index: number) => void>, required: true },
|
|
22
|
+
render: Function,
|
|
23
|
+
onChangeComplete: Function as PropType<() => void>,
|
|
24
|
+
mock: Boolean,
|
|
25
|
+
classNames: Object as PropType<SliderClassNames>,
|
|
26
|
+
styles: Object as PropType<SliderStyles>,
|
|
27
|
+
},
|
|
28
|
+
emits: ['focus', 'mouseenter', 'startMove', 'delete', 'offsetChange', 'changeComplete'],
|
|
29
|
+
setup(props, { attrs, emit, expose }) {
|
|
30
|
+
const {
|
|
31
|
+
min,
|
|
32
|
+
max,
|
|
33
|
+
direction,
|
|
34
|
+
disabled,
|
|
35
|
+
keyboard,
|
|
36
|
+
range,
|
|
37
|
+
tabIndex,
|
|
38
|
+
ariaLabelForHandle,
|
|
39
|
+
ariaLabelledByForHandle,
|
|
40
|
+
ariaRequired,
|
|
41
|
+
ariaValueTextFormatterForHandle,
|
|
42
|
+
} = useInjectSlider()
|
|
43
|
+
|
|
44
|
+
const divProps = ref({})
|
|
45
|
+
const handleClass = ref({})
|
|
46
|
+
const handleStyle = ref({})
|
|
47
|
+
|
|
48
|
+
// ============================ Events ============================
|
|
49
|
+
const onInternalStartMove = (e: MouseEvent | TouchEvent) => {
|
|
50
|
+
console.log('emit-start')
|
|
51
|
+
if (!disabled) {
|
|
52
|
+
emit('startMove', e, props.valueIndex)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const onInternalFocus = (e: FocusEvent) => {
|
|
57
|
+
console.log('emit-focus')
|
|
58
|
+
emit('focus', e, props.valueIndex)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const onInternalMouseEnter = (e: MouseEvent) => {
|
|
62
|
+
console.log('emit-enter')
|
|
63
|
+
emit('mouseenter', e, props.valueIndex)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// =========================== Keyboard ===========================
|
|
67
|
+
const onKeyDown = (e: KeyboardEvent) => {
|
|
68
|
+
if (!disabled && keyboard) {
|
|
69
|
+
let offset: number | 'min' | 'max' | null = null
|
|
70
|
+
|
|
71
|
+
// Change the value
|
|
72
|
+
switch (e.which || e.keyCode) {
|
|
73
|
+
case KeyCode.LEFT:
|
|
74
|
+
offset = direction.value === 'ltr' || direction.value === 'btt' ? -1 : 1
|
|
75
|
+
break
|
|
76
|
+
|
|
77
|
+
case KeyCode.RIGHT:
|
|
78
|
+
offset = direction.value === 'ltr' || direction.value === 'btt' ? 1 : -1
|
|
79
|
+
break
|
|
80
|
+
|
|
81
|
+
// Up is plus
|
|
82
|
+
case KeyCode.UP:
|
|
83
|
+
offset = direction.value !== 'ttb' ? 1 : -1
|
|
84
|
+
break
|
|
85
|
+
|
|
86
|
+
// Down is minus
|
|
87
|
+
case KeyCode.DOWN:
|
|
88
|
+
offset = direction.value !== 'ttb' ? -1 : 1
|
|
89
|
+
break
|
|
90
|
+
|
|
91
|
+
case KeyCode.HOME:
|
|
92
|
+
offset = 'min'
|
|
93
|
+
break
|
|
94
|
+
|
|
95
|
+
case KeyCode.END:
|
|
96
|
+
offset = 'max'
|
|
97
|
+
break
|
|
98
|
+
|
|
99
|
+
case KeyCode.PAGE_UP:
|
|
100
|
+
offset = 2
|
|
101
|
+
break
|
|
102
|
+
|
|
103
|
+
case KeyCode.PAGE_DOWN:
|
|
104
|
+
offset = -2
|
|
105
|
+
break
|
|
106
|
+
|
|
107
|
+
case KeyCode.BACKSPACE:
|
|
108
|
+
case KeyCode.DELETE:
|
|
109
|
+
emit('delete', e, props.valueIndex)
|
|
110
|
+
break
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (offset !== null) {
|
|
114
|
+
e.preventDefault()
|
|
115
|
+
emit('offsetChange', offset, props.valueIndex)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const handleKeyUp = (e: KeyboardEvent) => {
|
|
121
|
+
switch (e.which || e.keyCode) {
|
|
122
|
+
case KeyCode.LEFT:
|
|
123
|
+
case KeyCode.RIGHT:
|
|
124
|
+
case KeyCode.UP:
|
|
125
|
+
case KeyCode.DOWN:
|
|
126
|
+
case KeyCode.HOME:
|
|
127
|
+
case KeyCode.END:
|
|
128
|
+
case KeyCode.PAGE_UP:
|
|
129
|
+
case KeyCode.PAGE_DOWN:
|
|
130
|
+
emit('changeComplete')
|
|
131
|
+
break
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
expose({
|
|
135
|
+
focus: () => props.valueIndex,
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
return () => {
|
|
139
|
+
const {
|
|
140
|
+
prefixCls,
|
|
141
|
+
value,
|
|
142
|
+
valueIndex,
|
|
143
|
+
onStartMove,
|
|
144
|
+
onDelete,
|
|
145
|
+
render,
|
|
146
|
+
dragging,
|
|
147
|
+
draggingDelete,
|
|
148
|
+
onOffsetChange,
|
|
149
|
+
onChangeComplete,
|
|
150
|
+
onFocus,
|
|
151
|
+
onMouseenter,
|
|
152
|
+
styles,
|
|
153
|
+
classNames,
|
|
154
|
+
...restProps
|
|
155
|
+
} = props
|
|
156
|
+
// ============================ Offset ============================
|
|
157
|
+
const positionStyle = getDirectionStyle(direction.value, value, min.value, max.value)
|
|
158
|
+
// ============================ Render ============================
|
|
159
|
+
|
|
160
|
+
if (valueIndex !== null) {
|
|
161
|
+
divProps.value = {
|
|
162
|
+
'tabindex': disabled ? null : getIndex(tabIndex, valueIndex),
|
|
163
|
+
'role': 'slider',
|
|
164
|
+
'aria-valuemin': min.value,
|
|
165
|
+
'aria-valuemax': max.value,
|
|
166
|
+
'aria-valuenow': value,
|
|
167
|
+
'aria-disabled': disabled,
|
|
168
|
+
'aria-label': getIndex(ariaLabelForHandle, valueIndex),
|
|
169
|
+
'aria-labelledby': getIndex(ariaLabelledByForHandle, valueIndex),
|
|
170
|
+
'aria-required': getIndex(ariaRequired, valueIndex),
|
|
171
|
+
'aria-valuetext': getIndex(ariaValueTextFormatterForHandle, valueIndex)?.(value),
|
|
172
|
+
'aria-orientation': direction.value === 'ltr' || direction.value === 'rtl' ? 'horizontal' : 'vertical',
|
|
173
|
+
'onMousedown': onInternalStartMove,
|
|
174
|
+
'onTouchstart': onInternalStartMove,
|
|
175
|
+
'onFocus': onInternalFocus,
|
|
176
|
+
'onMouseenter': onInternalMouseEnter,
|
|
177
|
+
'onKeydown': onKeyDown,
|
|
178
|
+
'onKeyup': handleKeyUp,
|
|
179
|
+
...restProps,
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
divProps.value = {
|
|
184
|
+
...restProps,
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const handlePrefixCls = `${prefixCls}-handle`
|
|
188
|
+
handleClass.value = cls(
|
|
189
|
+
handlePrefixCls,
|
|
190
|
+
{
|
|
191
|
+
[`${handlePrefixCls}-${valueIndex + 1}`]: valueIndex !== null && range,
|
|
192
|
+
[`${handlePrefixCls}-dragging`]: dragging,
|
|
193
|
+
[`${handlePrefixCls}-dragging-delete`]: draggingDelete,
|
|
194
|
+
},
|
|
195
|
+
classNames?.handle,
|
|
196
|
+
)
|
|
197
|
+
handleStyle.value = {
|
|
198
|
+
...positionStyle,
|
|
199
|
+
...attrs.style as CSSProperties,
|
|
200
|
+
...styles?.handle,
|
|
201
|
+
}
|
|
202
|
+
const handleNode = (
|
|
203
|
+
<div
|
|
204
|
+
class={handleClass.value}
|
|
205
|
+
style={handleStyle.value}
|
|
206
|
+
{...divProps.value}
|
|
207
|
+
/>
|
|
208
|
+
)
|
|
209
|
+
// Customize
|
|
210
|
+
if (render) {
|
|
211
|
+
const renderProps = {
|
|
212
|
+
index: valueIndex,
|
|
213
|
+
prefixCls,
|
|
214
|
+
value,
|
|
215
|
+
dragging,
|
|
216
|
+
draggingDelete,
|
|
217
|
+
node: handleNode,
|
|
218
|
+
}
|
|
219
|
+
console.log('render', renderProps)
|
|
220
|
+
const RenderNode = () => render(renderProps)
|
|
221
|
+
return <RenderNode />
|
|
222
|
+
}
|
|
223
|
+
return handleNode
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
})
|