@@ -3,32 +3,36 @@ import Animated, {
33 Extrapolation ,
44 interpolate ,
55 useAnimatedStyle ,
6+ useSharedValue ,
67 type SharedValue ,
78} from 'react-native-reanimated' ;
89import { GestureDetector , Gesture } from 'react-native-gesture-handler' ;
910import { HIT_SLOP } from './config' ;
10- import { useRef } from 'react' ;
1111
1212interface SliderProps {
1313 onValueChange : ( value : number ) => void ;
1414 maxValue : number ;
1515 value : SharedValue < number > ;
1616 thumbWidth : number ;
17+ thumbShadowColor ?: string ;
18+ trackHeight : number ;
1719 backgroundColor : string ;
1820 color : string ;
21+ gestureActiveRef ?: React . RefObject < boolean > ;
1922}
2023
2124export default function Slider ( {
2225 onValueChange,
2326 value,
2427 thumbWidth,
28+ trackHeight,
2529 backgroundColor,
2630 color,
31+ thumbShadowColor,
2732 maxValue,
33+ gestureActiveRef,
2834} : SliderProps ) {
29- const isInteractingRef = useRef ( false ) ;
30- const sliderWidthRef = useRef ( 0 ) ;
31- const sliderThumbWidthRef = useRef ( 0 ) ;
35+ const sliderWidth = useSharedValue ( 0 ) ;
3236
3337 const handleValueChange = async ( position : number ) => {
3438 const clampedValue = Math . max ( 0 , Math . min ( position , maxValue ) ) ;
@@ -39,7 +43,9 @@ export default function Slider({
3943 console . error ( 'Error updating Reanimated Slider value:' , error ) ;
4044 } finally {
4145 setTimeout ( ( ) => {
42- isInteractingRef . current = false ;
46+ if ( gestureActiveRef ) {
47+ gestureActiveRef . current = false ;
48+ }
4349 } , 100 ) ;
4450 }
4551 } ;
@@ -48,34 +54,34 @@ export default function Slider({
4854 . runOnJS ( true )
4955 . hitSlop ( HIT_SLOP )
5056 . onStart ( ( event ) => {
51- isInteractingRef . current = true ;
57+ if ( gestureActiveRef ) {
58+ gestureActiveRef . current = true ;
59+ }
5260
53- const clampedX = Math . max ( 0 , Math . min ( event . x , sliderWidthRef . current ) ) ;
61+ const clampedX = Math . max ( 0 , Math . min ( event . x , sliderWidth . value ) ) ;
5462 const position = interpolate (
5563 clampedX ,
56- [ 0 , sliderWidthRef . current ] ,
64+ [ 0 , sliderWidth . value ] ,
5765 [ 0 , maxValue ] ,
5866 Extrapolation . CLAMP
5967 ) ;
6068 value . set ( position ) ;
6169 } )
6270 . onUpdate ( ( event ) => {
63- if ( isInteractingRef . current ) {
64- const clampedX = Math . max ( 0 , Math . min ( event . x , sliderWidthRef . current ) ) ;
65- const position = interpolate (
66- clampedX ,
67- [ 0 , sliderWidthRef . current ] ,
68- [ 0 , maxValue ] ,
69- Extrapolation . CLAMP
70- ) ;
71- value . set ( position ) ;
72- }
71+ const clampedX = Math . max ( 0 , Math . min ( event . x , sliderWidth . value ) ) ;
72+ const position = interpolate (
73+ clampedX ,
74+ [ 0 , sliderWidth . value ] ,
75+ [ 0 , maxValue ] ,
76+ Extrapolation . CLAMP
77+ ) ;
78+ value . set ( position ) ;
7379 } )
7480 . onEnd ( async ( event ) => {
75- const clampedX = Math . max ( 0 , Math . min ( event . x , sliderWidthRef . current ) ) ;
81+ const clampedX = Math . max ( 0 , Math . min ( event . x , sliderWidth . value ) ) ;
7682 const position = interpolate (
7783 clampedX ,
78- [ 0 , sliderWidthRef . current ] ,
84+ [ 0 , sliderWidth . value ] ,
7985 [ 0 , maxValue ] ,
8086 Extrapolation . CLAMP
8187 ) ;
@@ -89,13 +95,15 @@ export default function Slider({
8995 . runOnJS ( true )
9096 . hitSlop ( HIT_SLOP )
9197 . onBegin ( ( event ) => {
92- isInteractingRef . current = true ;
98+ if ( gestureActiveRef ) {
99+ gestureActiveRef . current = true ;
100+ }
93101
94- const clampedX = Math . max ( 0 , Math . min ( event . x , sliderWidthRef . current ) ) ;
102+ const clampedX = Math . max ( 0 , Math . min ( event . x , sliderWidth . value ) ) ;
95103
96104 const position = interpolate (
97105 clampedX ,
98- [ 0 , sliderWidthRef . current ] ,
106+ [ 0 , sliderWidth . value ] ,
99107 [ 0 , maxValue ] ,
100108 Extrapolation . CLAMP
101109 ) ;
@@ -105,10 +113,10 @@ export default function Slider({
105113 . onFinalize ( async ( event , success ) => {
106114 if ( ! success ) return ;
107115
108- const clampedX = Math . max ( 0 , Math . min ( event . x , sliderWidthRef . current ) ) ;
116+ const clampedX = Math . max ( 0 , Math . min ( event . x , sliderWidth . value ) ) ;
109117 const position = interpolate (
110118 clampedX ,
111- [ 0 , sliderWidthRef . current ] ,
119+ [ 0 , sliderWidth . value ] ,
112120 [ 0 , maxValue ] ,
113121 Extrapolation . CLAMP
114122 ) ;
@@ -130,7 +138,7 @@ export default function Slider({
130138 translateX : interpolate (
131139 value . value ,
132140 [ 0 , maxValue ] ,
133- [ 0 , sliderWidthRef . current - sliderThumbWidthRef . current ] ,
141+ [ 0 , sliderWidth . value - thumbWidth ] ,
134142 Extrapolation . CLAMP
135143 ) ,
136144 } ,
@@ -141,15 +149,14 @@ export default function Slider({
141149 width : interpolate (
142150 value . value ,
143151 [ 0 , maxValue ] ,
144- [ 0 , sliderWidthRef . current ] ,
152+ [ 0 , sliderWidth . value ] ,
145153 Extrapolation . CLAMP
146154 ) ,
147155 } ) ) ;
148156
149- const measureLayout = ( event : LayoutChangeEvent ) => {
150- const { width } = event . nativeEvent . layout ;
151- sliderWidthRef . current = width ;
152- sliderThumbWidthRef . current = thumbWidth ;
157+ const measure = ( event : LayoutChangeEvent ) => {
158+ sliderWidth . value = event . nativeEvent . layout . width ;
159+ console . debug ( 'Slider width:' , sliderWidth . value ) ;
153160 } ;
154161
155162 return (
@@ -158,20 +165,20 @@ export default function Slider({
158165 style = { [
159166 styles . container ,
160167 {
161- height : thumbWidth ,
168+ height : trackHeight ,
162169 } ,
163170 ] }
164- onLayout = { measureLayout }
171+ onLayout = { measure }
165172 >
166173 { /* Background Track */ }
167174 < View
168175 style = { [
169176 styles . track ,
170177 {
171- height : thumbWidth ,
178+ height : trackHeight ,
172179 width : '100%' ,
173180 backgroundColor,
174- borderRadius : thumbWidth / 2 ,
181+ borderRadius : trackHeight / 2 ,
175182 } ,
176183 ] }
177184 />
@@ -181,9 +188,9 @@ export default function Slider({
181188 style = { [
182189 styles . track ,
183190 {
184- height : thumbWidth ,
191+ height : trackHeight ,
185192 backgroundColor : color ,
186- borderRadius : thumbWidth / 2 ,
193+ borderRadius : trackHeight / 2 ,
187194 } ,
188195 progressAnimatedStyle ,
189196 ] }
@@ -198,6 +205,7 @@ export default function Slider({
198205 height : thumbWidth ,
199206 borderRadius : thumbWidth / 2 ,
200207 backgroundColor : color ,
208+ shadowColor : thumbShadowColor ,
201209 } ,
202210 thumbAnimatedStyle ,
203211 ] }
@@ -220,7 +228,7 @@ const styles = StyleSheet.create({
220228 } ,
221229 thumb : {
222230 position : 'absolute' ,
223- shadowOpacity : 0.25 ,
231+ shadowOpacity : 0.75 ,
224232 shadowRadius : 3 ,
225233 shadowOffset : {
226234 width : 0 ,
0 commit comments