@@ -45,62 +45,50 @@ const current = computed({
4545const isReset = computed (() => props .resettable && current .value < 0 )
4646const clicksRange = computed (() => range (start .value , total .value + 1 ))
4747const sliderEl = ref <HTMLElement >()
48- let pointerDown: { id: number , x: number , y: number , dragging : boolean } | undefined
48+ let pointerDown: { id: number , x: number , y: number } | undefined
4949
5050function getPointerRatio(event : PointerEvent ) {
5151 const rect = sliderEl .value ! .getBoundingClientRect ()
5252 return (event .clientX - rect .left ) / Math .max (1 , rect .width )
5353}
5454
55- function syncCurrentFromPointer(event : PointerEvent ) {
56- if (props .readonly || ! (event .buttons & 1 ) || ! sliderEl .value )
55+ // Presses snap to a cell; drags switch only after crossing half a cell.
56+ function setCurrentFromPointer(event : PointerEvent , snap : boolean ) {
57+ if (props .readonly || ! sliderEl .value || (! snap && ! (event .buttons & 1 )))
5758 return
5859 const ratio = getPointerRatio (event )
60+ // In resettable mode, dragging left of the rail restores the inactive state.
5961 if (props .resettable && ratio < 0 ) {
6062 current .value = - 1
6163 return
6264 }
63- const position = clamp (0 , ratio , 1 ) * length .value
65+ // Keep press-at-right-edge inside the last cell.
66+ const position = clamp (0 , ratio , snap ? 0.999999 : 1 ) * length .value
6467 const currentOffset = clamp (0 , current .value - start .value , length .value - 1 )
65- let next = current .value
66- if (position >= currentOffset + 1.5 )
68+ let next = snap ? start . value + Math . floor ( position ) : current .value
69+ if (! snap && position >= currentOffset + 1.5 )
6770 next = start .value + Math .floor (position - 0.5 )
68- else if (position < currentOffset - 0.5 )
71+ else if (! snap && position < currentOffset - 0.5 )
6972 next = start .value + Math .ceil (position - 0.5 )
7073 current .value = clamp (start .value , next , total .value )
7174}
7275
73- function syncCurrentFromVisibleBlock(event : PointerEvent ) {
74- if (props .readonly || ! sliderEl .value )
75- return
76- const ratio = clamp (0 , getPointerRatio (event ), 0.999999 )
77- current .value = clamp (start .value , start .value + Math .floor (ratio * length .value ), total .value )
78- }
79-
8076function onPointerDown(event : PointerEvent ) {
8177 if (props .readonly )
8278 return
8379 sliderEl .value ?.setPointerCapture (event .pointerId )
84- pointerDown = { id: event .pointerId , x: event .clientX , y: event .clientY , dragging: false }
85- syncCurrentFromVisibleBlock (event )
80+ pointerDown = { id: event .pointerId , x: event .clientX , y: event .clientY }
81+ setCurrentFromPointer (event , true )
8682}
8783
8884function onPointerMove(event : PointerEvent ) {
8985 if (pointerDown ?.id === event .pointerId ) {
90- pointerDown . dragging || = Math . abs ( event . clientX - pointerDown . x ) > 3 || Math . abs ( event . clientY - pointerDown . y ) > 3
91- if (! pointerDown .dragging )
86+ // Treat tiny movement after pointerdown as part of the click.
87+ if (Math . abs ( event . clientX - pointerDown .x ) <= 3 && Math . abs ( event . clientY - pointerDown . y ) <= 3 )
9288 return
93- }
94- syncCurrentFromPointer (event )
95- }
96-
97- function onPointerUp(event : PointerEvent ) {
98- if (pointerDown ?.id === event .pointerId )
9989 pointerDown = undefined
100- }
101-
102- function onPointerCancel() {
103- pointerDown = undefined
90+ }
91+ setCurrentFromPointer (event , false )
10492}
10593 </script >
10694
@@ -141,8 +129,8 @@ function onPointerCancel() {
141129 :class =" [attached ? 'h-[22px]' : 'h5', isReset ? 'op80' : '']"
142130 @pointerdown.capture =" onPointerDown"
143131 @pointermove =" onPointerMove"
144- @pointerup =" onPointerUp "
145- @pointercancel =" onPointerCancel "
132+ @pointerup =" pointerDown = undefined "
133+ @pointercancel =" pointerDown = undefined "
146134 >
147135 <div
148136 v-for =" i of clicksRange" :key =" i"
@@ -167,8 +155,6 @@ function onPointerCancel() {
167155 <div
168156 :class =" [
169157 (+i === +current && active) ? 'text-primary font-bold op100' : 'op30',
170- i === 0 ? attached ? 'rounded-tl' : 'rounded-l' : '',
171- i === total && +i !== +current ? attached ? 'rounded-tr' : 'rounded-r' : '',
172158 i !== total ? 'border-r-2 border-main' : '',
173159 ]"
174160 w-full h-full text-xs flex items-center justify-center z-1
0 commit comments