@v-c/slider 1.0.2 → 1.0.4

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.
Files changed (76) hide show
  1. package/dist/Handles/Handle.cjs +195 -1
  2. package/dist/Handles/Handle.d.ts +17 -5
  3. package/dist/Handles/Handle.js +191 -202
  4. package/dist/Handles/index.cjs +108 -1
  5. package/dist/Handles/index.d.ts +20 -4
  6. package/dist/Handles/index.js +105 -116
  7. package/dist/Marks/Mark.cjs +51 -1
  8. package/dist/Marks/Mark.d.ts +2 -2
  9. package/dist/Marks/Mark.js +48 -39
  10. package/dist/Marks/index.cjs +39 -1
  11. package/dist/Marks/index.d.ts +2 -2
  12. package/dist/Marks/index.js +36 -32
  13. package/dist/Slider.cjs +569 -1
  14. package/dist/Slider.d.ts +60 -263
  15. package/dist/Slider.js +563 -352
  16. package/dist/Steps/Dot.cjs +52 -1
  17. package/dist/Steps/Dot.d.ts +2 -2
  18. package/dist/Steps/Dot.js +49 -38
  19. package/dist/Steps/index.cjs +64 -1
  20. package/dist/Steps/index.d.ts +2 -2
  21. package/dist/Steps/index.js +61 -41
  22. package/dist/Tracks/Track.cjs +74 -1
  23. package/dist/Tracks/Track.js +70 -81
  24. package/dist/Tracks/index.cjs +70 -1
  25. package/dist/Tracks/index.js +66 -82
  26. package/dist/_virtual/rolldown_runtime.cjs +21 -0
  27. package/dist/context.cjs +39 -1
  28. package/dist/context.d.ts +13 -7
  29. package/dist/context.js +29 -24
  30. package/dist/hooks/useDrag.cjs +160 -1
  31. package/dist/hooks/useDrag.d.ts +2 -2
  32. package/dist/hooks/useDrag.js +155 -86
  33. package/dist/hooks/useOffset.cjs +124 -1
  34. package/dist/hooks/useOffset.d.ts +2 -1
  35. package/dist/hooks/useOffset.js +122 -97
  36. package/dist/hooks/useRange.cjs +21 -1
  37. package/dist/hooks/useRange.js +18 -9
  38. package/dist/index.cjs +6 -1
  39. package/dist/index.d.ts +1 -0
  40. package/dist/index.js +4 -4
  41. package/dist/interface.cjs +0 -1
  42. package/dist/interface.js +0 -1
  43. package/dist/util.cjs +32 -1
  44. package/dist/util.js +27 -26
  45. package/package.json +18 -10
  46. package/docs/TooltipSlider.tsx +0 -94
  47. package/docs/assets/anim.less +0 -63
  48. package/docs/assets/bootstrap.less +0 -163
  49. package/docs/assets/index.less +0 -337
  50. package/docs/debug.vue +0 -60
  51. package/docs/editable.vue +0 -59
  52. package/docs/handle.vue +0 -45
  53. package/docs/marks.vue +0 -94
  54. package/docs/multiple.vue +0 -54
  55. package/docs/range.vue +0 -211
  56. package/docs/slider.stories.vue +0 -45
  57. package/docs/sliderDemo.vue +0 -267
  58. package/docs/vertical.vue +0 -122
  59. package/src/Handles/Handle.tsx +0 -223
  60. package/src/Handles/index.tsx +0 -124
  61. package/src/Marks/Mark.tsx +0 -40
  62. package/src/Marks/index.tsx +0 -40
  63. package/src/Slider.tsx +0 -593
  64. package/src/Steps/Dot.tsx +0 -40
  65. package/src/Steps/index.tsx +0 -54
  66. package/src/Tracks/Track.tsx +0 -89
  67. package/src/Tracks/index.tsx +0 -92
  68. package/src/context.ts +0 -65
  69. package/src/hooks/useDrag.ts +0 -243
  70. package/src/hooks/useOffset.ts +0 -264
  71. package/src/hooks/useRange.ts +0 -24
  72. package/src/index.ts +0 -8
  73. package/src/interface.ts +0 -17
  74. package/src/util.ts +0 -41
  75. package/vite.config.ts +0 -18
  76. package/vitest.config.ts +0 -11
@@ -1,89 +0,0 @@
1
- import type { CSSProperties, PropType } from 'vue'
2
- import type { OnStartMove } from '../interface'
3
- import cls from 'classnames'
4
- import { defineComponent } from 'vue'
5
- import { useInjectSlider } from '../context'
6
- import { getOffset } from '../util'
7
-
8
- export interface TrackProps {
9
- prefixCls: string
10
- /** Replace with origin prefix concat className */
11
- replaceCls?: string
12
- start: number
13
- end: number
14
- index: number
15
- onStartMove?: OnStartMove
16
- }
17
-
18
- const Track = defineComponent({
19
- name: 'Track',
20
- props: {
21
- prefixCls: { type: String, required: true },
22
- replaceCls: { type: String },
23
- start: { type: Number, required: true },
24
- end: { type: Number, required: true },
25
- index: { type: Number, default: () => null },
26
- onStartMove: { type: Function as PropType<OnStartMove> },
27
- },
28
- setup(props, { attrs }) {
29
- const { direction, min, max, disabled, range, classNames } = useInjectSlider()
30
-
31
- // ============================ Events ============================
32
- const onInternalStartMove = (e: MouseEvent | TouchEvent) => {
33
- if (!disabled && props.onStartMove) {
34
- props.onStartMove(e, -1)
35
- }
36
- }
37
-
38
- // ============================ Render ============================
39
- const positionStyle: CSSProperties = {}
40
-
41
- return () => {
42
- const { prefixCls, index, onStartMove, replaceCls, start, end } = props
43
-
44
- const offsetStart = getOffset(start, min.value, max.value)
45
- const offsetEnd = getOffset(end, min.value, max.value)
46
-
47
- const trackPrefixCls = `${prefixCls}-track`
48
- const className
49
- = replaceCls
50
- || cls(
51
- trackPrefixCls,
52
- {
53
- [`${trackPrefixCls}-${index + 1}`]: index !== null && range,
54
- [`${prefixCls}-track-draggable`]: onStartMove,
55
- },
56
- classNames.track,
57
- )
58
- switch (direction.value) {
59
- case 'rtl':
60
- positionStyle.right = `${offsetStart * 100}%`
61
- positionStyle.width = `${offsetEnd * 100 - offsetStart * 100}%`
62
- break
63
-
64
- case 'btt':
65
- positionStyle.bottom = `${offsetStart * 100}%`
66
- positionStyle.height = `${offsetEnd * 100 - offsetStart * 100}%`
67
- break
68
-
69
- case 'ttb':
70
- positionStyle.top = `${offsetStart * 100}%`
71
- positionStyle.height = `${offsetEnd * 100 - offsetStart * 100}%`
72
- break
73
-
74
- default:
75
- positionStyle.left = `${offsetStart * 100}%`
76
- positionStyle.width = `${offsetEnd * 100 - offsetStart * 100}%`
77
- }
78
- return (
79
- <div
80
- class={className}
81
- style={{ ...positionStyle, ...attrs.style as CSSProperties }}
82
- onMousedown={onStartMove ? onInternalStartMove : undefined}
83
- />
84
- )
85
- }
86
- },
87
- })
88
-
89
- export default Track
@@ -1,92 +0,0 @@
1
- import type { CSSProperties, PropType } from 'vue'
2
- import type { OnStartMove } from '../interface'
3
- import cls from 'classnames'
4
- import { computed, defineComponent } from 'vue'
5
- import { useInjectSlider } from '../context'
6
- import { getIndex } from '../util'
7
- import Track from './Track'
8
-
9
- export interface TrackProps {
10
- prefixCls: string
11
- style?: CSSProperties | CSSProperties[]
12
- values: number[]
13
- onStartMove?: OnStartMove
14
- startPoint?: number
15
- }
16
-
17
- const Tracks = defineComponent({
18
- name: 'Tracks',
19
- props: {
20
- prefixCls: { type: String, required: true },
21
- trackStyle: { type: [Object, Array] as PropType<CSSProperties | CSSProperties[]> },
22
- values: { type: Array as PropType<number[]>, required: true },
23
- onStartMove: { type: Function as PropType<OnStartMove> },
24
- startPoint: { type: Number },
25
- },
26
- setup(props) {
27
- const { included, range, min, styles, classNames } = useInjectSlider()
28
-
29
- // =========================== List ===========================
30
- const trackList = computed(() => {
31
- if (!range) {
32
- // null value do not have track
33
- if (props.values.length === 0) {
34
- return []
35
- }
36
-
37
- const startValue = props.startPoint ?? min.value
38
- const endValue = props.values[0]
39
-
40
- return [{ start: Math.min(startValue, endValue), end: Math.max(startValue, endValue) }]
41
- }
42
-
43
- // Multiple
44
- const list: { start: number, end: number }[] = []
45
-
46
- for (let i = 0; i < props.values.length - 1; i += 1) {
47
- list.push({ start: props.values[i], end: props.values[i + 1] })
48
- }
49
-
50
- return list
51
- })
52
-
53
- return () => {
54
- if (!included) {
55
- return null
56
- }
57
-
58
- // ========================== Render ==========================
59
- const tracksNode
60
- = trackList.value?.length && (classNames.tracks || styles.tracks)
61
- ? (
62
- <Track
63
- index={0}
64
- prefixCls={props.prefixCls}
65
- start={trackList.value[0].start}
66
- end={trackList.value[trackList.value.length - 1].end}
67
- replaceCls={cls(classNames.tracks, `${props.prefixCls}-tracks`)}
68
- style={styles.tracks}
69
- />
70
- )
71
- : null
72
- return (
73
- <>
74
- {tracksNode}
75
- {trackList.value.map(({ start, end }, index) => (
76
- <Track
77
- index={index}
78
- prefixCls={props.prefixCls}
79
- style={{ ...getIndex(props.trackStyle, index), ...styles?.track }}
80
- start={start}
81
- end={end}
82
- key={index}
83
- onStartMove={props.onStartMove}
84
- />
85
- ))}
86
- </>
87
- )
88
- }
89
- },
90
- })
91
-
92
- export default Tracks
package/src/context.ts DELETED
@@ -1,65 +0,0 @@
1
- import type { InjectionKey, ShallowRef } from 'vue'
2
- import type { AriaValueFormat, Direction, SliderClassNames, SliderStyles } from './interface'
3
- import { inject, provide } from 'vue'
4
-
5
- export interface SliderContextProps {
6
- min: ShallowRef<number>
7
- max: ShallowRef<number>
8
- includedStart: number
9
- includedEnd: number
10
- direction: ShallowRef<Direction>
11
- disabled?: boolean
12
- keyboard?: boolean
13
- included?: boolean
14
- step: ShallowRef<number | null>
15
- range?: boolean
16
- tabIndex: number | number[]
17
- ariaLabelForHandle?: string | string[]
18
- ariaLabelledByForHandle?: string | string[]
19
- ariaRequired?: boolean
20
- ariaValueTextFormatterForHandle?: AriaValueFormat | AriaValueFormat[]
21
- classNames: SliderClassNames
22
- styles: SliderStyles
23
- }
24
-
25
- const SliderContextKey: InjectionKey<SliderContextProps> = Symbol('SliderContext')
26
-
27
- export const defaultSliderContextValue = {
28
- min: 0,
29
- max: 0,
30
- direction: 'ltr',
31
- step: 1,
32
- includedStart: 0,
33
- includedEnd: 0,
34
- tabIndex: 0,
35
- keyboard: true,
36
- styles: {},
37
- classNames: {},
38
- }
39
-
40
- export function useProviderSliderContext(ctx: SliderContextProps) {
41
- provide(SliderContextKey, ctx)
42
- }
43
- export function useInjectSlider(): SliderContextProps {
44
- return inject(SliderContextKey)!
45
- }
46
-
47
- export interface UnstableContextProps {
48
- onDragStart?: (info: {
49
- rawValues: number[]
50
- draggingIndex: number
51
- draggingValue: number
52
- }) => void
53
- onDragChange?: (info: {
54
- rawValues: number[]
55
- deleteIndex: number
56
- draggingIndex: number
57
- draggingValue: number
58
- }) => void
59
- }
60
-
61
- /** @private NOT PROMISE AVAILABLE. DO NOT USE IN PRODUCTION. */
62
- export const UnstableContextKey: InjectionKey<UnstableContextProps> = Symbol('UnstableContext')
63
-
64
- // 默认值
65
- export const defaultUnstableContextValue: UnstableContextProps = {}
@@ -1,243 +0,0 @@
1
- import type { Ref, ShallowRef } from 'vue'
2
- import type { Direction, OnStartMove } from '../interface'
3
- import type { OffsetValues } from './useOffset'
4
- import useEvent from '@v-c/util/dist/hooks/useEvent'
5
- import { computed, inject, onUnmounted, ref } from 'vue'
6
- import { defaultUnstableContextValue, UnstableContextKey } from '../context'
7
-
8
- /** Drag to delete offset. It's a user experience number for dragging out */
9
- const REMOVE_DIST = 130
10
-
11
- function getPosition(e: MouseEvent | TouchEvent) {
12
- const obj = 'targetTouches' in e ? e.targetTouches[0] : e
13
-
14
- return { pageX: obj.pageX, pageY: obj.pageY }
15
- }
16
-
17
- function useDrag(
18
- containerRef: Ref<HTMLDivElement>,
19
- direction: ShallowRef<Direction>,
20
- rawValues: Ref<number[]>,
21
- min: ShallowRef<number>,
22
- max: ShallowRef<number>,
23
- formatValue: (value: number) => number,
24
- triggerChange: (values: number[]) => void,
25
- finishChange: (draggingDelete: boolean) => void,
26
- offsetValues: OffsetValues,
27
- editable: boolean,
28
- minCount: number,
29
- ): [
30
- draggingIndex: Ref<number>,
31
- draggingValue: Ref<number>,
32
- draggingDelete: Ref<boolean>,
33
- returnValues: Ref<number[]>,
34
- onStartMove: OnStartMove,
35
- ] {
36
- const draggingValue = ref<number | null>(null)
37
- const draggingIndex = ref<number>(-1)
38
- const draggingDelete = ref<boolean>(false)
39
- const cacheValues = ref<number[]>(rawValues.value)
40
- const originValues = ref<number[]>(rawValues.value)
41
-
42
- const mouseMoveEventRef = ref<((event: MouseEvent | TouchEvent) => void) | null>(null)
43
- const mouseUpEventRef = ref<((event: MouseEvent | TouchEvent) => void) | null>(null)
44
- const touchEventTargetRef = ref<EventTarget | null>(null)
45
-
46
- const unstableContext = inject(UnstableContextKey, defaultUnstableContextValue)
47
- const { onDragStart, onDragChange } = unstableContext
48
-
49
- if (draggingIndex.value === -1) {
50
- cacheValues.value = rawValues.value
51
- }
52
-
53
- // Clean up event
54
- onUnmounted(() => {
55
- document.removeEventListener('mousemove', mouseMoveEventRef.value)
56
- document.removeEventListener('mouseup', mouseUpEventRef.value)
57
- if (touchEventTargetRef.value) {
58
- touchEventTargetRef.value.removeEventListener('touchmove', mouseMoveEventRef.value)
59
- touchEventTargetRef.value.removeEventListener('touchend', mouseUpEventRef.value)
60
- }
61
- })
62
-
63
- const flushValues = (nextValues: number[], nextValue?: number, deleteMark?: boolean) => {
64
- // Perf: Only update state when value changed
65
- if (nextValue !== undefined) {
66
- draggingValue.value = nextValue
67
- }
68
- cacheValues.value = nextValues
69
-
70
- let changeValues = nextValues
71
- if (deleteMark) {
72
- changeValues = nextValues.filter((_, i) => i !== draggingIndex.value)
73
- }
74
- triggerChange(changeValues)
75
-
76
- if (onDragChange) {
77
- onDragChange({
78
- rawValues: nextValues,
79
- deleteIndex: deleteMark ? draggingIndex.value : -1,
80
- draggingIndex: draggingIndex.value,
81
- draggingValue: nextValue!,
82
- })
83
- }
84
- }
85
-
86
- const updateCacheValue = useEvent(
87
- (valueIndex: number, offsetPercent: number, deleteMark: boolean) => {
88
- if (valueIndex === -1) {
89
- // >>>> Dragging on the track
90
- const startValue = originValues.value[0]
91
- const endValue = originValues.value[originValues.value.length - 1]
92
- const maxStartOffset = min.value - startValue
93
- const maxEndOffset = max.value - endValue
94
-
95
- // Get valid offset
96
- let offset = offsetPercent * (max.value - min.value)
97
- offset = Math.max(offset, maxStartOffset)
98
- offset = Math.min(offset, maxEndOffset)
99
-
100
- // Use first value to revert back of valid offset (like steps marks)
101
- const formatStartValue = formatValue(startValue + offset)
102
- offset = formatStartValue - startValue
103
- const cloneCacheValues = originValues.value.map<number>(val => val + offset)
104
- flushValues(cloneCacheValues)
105
- }
106
- else {
107
- // >>>> Dragging on the handle
108
- const offsetDist = (max.value - min.value) * offsetPercent
109
-
110
- // Always start with the valueIndex origin value
111
- const cloneValues = [...cacheValues.value]
112
- cloneValues[valueIndex] = originValues.value[valueIndex]
113
-
114
- const next = offsetValues(cloneValues, offsetDist, valueIndex, 'dist')
115
-
116
- flushValues(next.values, next.value, deleteMark)
117
- }
118
- },
119
- )
120
-
121
- const onStartMove: OnStartMove = (e, valueIndex, startValues?: number[]) => {
122
- e.stopPropagation()
123
- // 如果是点击 track 触发的,需要传入变化后的初始值,而不能直接用 rawValues
124
- const initialValues = startValues || rawValues.value
125
- const originValue = initialValues[valueIndex]
126
-
127
- draggingIndex.value = valueIndex
128
- draggingValue.value = originValue
129
- originValues.value = initialValues
130
- cacheValues.value = initialValues
131
- draggingDelete.value = false
132
-
133
- const { pageX: startX, pageY: startY } = getPosition(e)
134
-
135
- // We declare it here since closure can't get outer latest value
136
- let deleteMark = false
137
-
138
- // Internal trigger event
139
- if (onDragStart) {
140
- onDragStart({
141
- rawValues: initialValues,
142
- draggingIndex: valueIndex,
143
- draggingValue: originValue,
144
- })
145
- }
146
-
147
- // Moving
148
- const onMouseMove = (event: MouseEvent | TouchEvent) => {
149
- event.preventDefault()
150
- const { pageX: moveX, pageY: moveY } = getPosition(event)
151
- const offsetX = moveX - startX
152
- const offsetY = moveY - startY
153
-
154
- const { width, height } = containerRef.value.getBoundingClientRect()
155
-
156
- let offSetPercent: number
157
- let removeDist: number
158
-
159
- switch (direction.value) {
160
- case 'btt':
161
- offSetPercent = -offsetY / height
162
- removeDist = offsetX
163
- break
164
-
165
- case 'ttb':
166
- offSetPercent = offsetY / height
167
- removeDist = offsetX
168
- break
169
-
170
- case 'rtl':
171
- offSetPercent = -offsetX / width
172
- removeDist = offsetY
173
- break
174
-
175
- default:
176
- offSetPercent = offsetX / width
177
- removeDist = offsetY
178
- }
179
-
180
- // Check if need mark remove
181
- deleteMark = editable
182
- ? Math.abs(removeDist) > REMOVE_DIST && minCount < cacheValues.value.length
183
- : false
184
- draggingDelete.value = deleteMark
185
-
186
- updateCacheValue(valueIndex, offSetPercent, deleteMark)
187
- }
188
-
189
- // End
190
- const onMouseUp = (event: MouseEvent | TouchEvent) => {
191
- event.preventDefault()
192
-
193
- document.removeEventListener('mouseup', onMouseUp)
194
- document.removeEventListener('mousemove', onMouseMove)
195
- if (touchEventTargetRef.value) {
196
- touchEventTargetRef.value.removeEventListener('touchmove', mouseMoveEventRef.value)
197
- touchEventTargetRef.value.removeEventListener('touchend', mouseUpEventRef.value)
198
- }
199
- mouseMoveEventRef.value = null
200
- mouseUpEventRef.value = null
201
- touchEventTargetRef.value = null
202
-
203
- finishChange(deleteMark)
204
-
205
- draggingIndex.value = -1
206
- draggingDelete.value = false
207
- }
208
-
209
- document.addEventListener('mouseup', onMouseUp)
210
- document.addEventListener('mousemove', onMouseMove)
211
- e.currentTarget.addEventListener('touchend', onMouseUp)
212
- e.currentTarget.addEventListener('touchmove', onMouseMove)
213
- mouseMoveEventRef.value = onMouseMove
214
- mouseUpEventRef.value = onMouseUp
215
- touchEventTargetRef.value = e.currentTarget
216
- }
217
-
218
- // Only return cache value when it mapping with rawValues
219
- const returnValues = computed(() => {
220
- const sourceValues = [...rawValues.value].sort((a, b) => a - b)
221
- const targetValues = [...cacheValues.value].sort((a, b) => a - b)
222
-
223
- const counts: Record<number, number> = {}
224
- targetValues.forEach((val) => {
225
- counts[val] = (counts[val] || 0) + 1
226
- })
227
- sourceValues.forEach((val) => {
228
- counts[val] = (counts[val] || 0) - 1
229
- })
230
-
231
- const maxDiffCount = editable ? 1 : 0
232
- const diffCount: number = Object.values(counts).reduce(
233
- (prev, next) => prev + Math.abs(next),
234
- 0,
235
- )
236
-
237
- return diffCount <= maxDiffCount ? cacheValues.value : rawValues.value
238
- })
239
-
240
- return [draggingIndex, draggingValue, draggingDelete, returnValues, onStartMove]
241
- }
242
-
243
- export default useDrag