1- import { useCallback , useRef , useState } from 'react' ;
1+ import { useCallback , useEffect , useRef , useState } from 'react' ;
22import { clamp , useMergedRef , useMove , useUncontrolled } from '@mantine/hooks' ;
33import {
44 BoxProps ,
@@ -211,6 +211,12 @@ export const Slider = factory<SliderFactory>((_props, ref) => {
211211 } ) ;
212212
213213 const valueRef = useRef ( _value ) ;
214+ const onChangeEndRef = useRef ( onChangeEnd ) ;
215+
216+ useEffect ( ( ) => {
217+ onChangeEndRef . current = onChangeEnd ;
218+ } , [ onChangeEnd ] ) ;
219+
214220 const root = useRef < HTMLDivElement > ( null ) ;
215221 const thumb = useRef < HTMLDivElement > ( null ) ;
216222 const position = getPosition ( { value : _value , min : min ! , max : max ! } ) ;
@@ -242,21 +248,28 @@ export const Slider = factory<SliderFactory>((_props, ref) => {
242248 [ disabled , min , max , step , precision , setValue , marks , restrictToMarks ]
243249 ) ;
244250
245- const { ref : container , active } = useMove (
246- handleChange ,
247- {
248- onScrubEnd : ( ) =>
249- ! disabled &&
250- onChangeEnd ?.(
251- restrictToMarks && marks ?. length
252- ? findClosestNumber (
253- valueRef . current ,
254- marks . map ( ( mark ) => mark . value )
255- )
256- : valueRef . current
257- ) ,
251+ const handleScrubEnd = useCallback ( ( ) => {
252+ if ( ! disabled && onChangeEndRef . current ) {
253+ const finalValue =
254+ restrictToMarks && marks ?. length
255+ ? findClosestNumber (
256+ valueRef . current ,
257+ marks . map ( ( mark ) => mark . value )
258+ )
259+ : valueRef . current ;
260+ onChangeEndRef . current ( finalValue ) ;
261+ }
262+ } , [ disabled , marks , restrictToMarks ] ) ;
263+
264+ const { ref : container , active } = useMove ( handleChange , { onScrubEnd : handleScrubEnd } , dir ) ;
265+
266+ const callOnChangeEnd = useCallback (
267+ ( value : number ) => {
268+ if ( ! disabled && onChangeEndRef . current ) {
269+ onChangeEndRef . current ( value ) ;
270+ }
258271 } ,
259- dir
272+ [ disabled ]
260273 ) ;
261274
262275 const handleTrackKeydownCapture = ( event : React . KeyboardEvent < HTMLDivElement > ) => {
@@ -269,7 +282,7 @@ export const Slider = factory<SliderFactory>((_props, ref) => {
269282 if ( restrictToMarks && marks ) {
270283 const nextValue = getNextMarkValue ( _value , marks ) ;
271284 setValue ( nextValue ) ;
272- onChangeEnd ?. ( nextValue ) ;
285+ callOnChangeEnd ( nextValue ) ;
273286 break ;
274287 }
275288
@@ -278,7 +291,7 @@ export const Slider = factory<SliderFactory>((_props, ref) => {
278291 precision
279292 ) ;
280293 setValue ( nextValue ) ;
281- onChangeEnd ?. ( nextValue ) ;
294+ callOnChangeEnd ( nextValue ) ;
282295 break ;
283296 }
284297
@@ -290,7 +303,7 @@ export const Slider = factory<SliderFactory>((_props, ref) => {
290303 const nextValue =
291304 dir === 'rtl' ? getPreviousMarkValue ( _value , marks ) : getNextMarkValue ( _value , marks ) ;
292305 setValue ( nextValue ) ;
293- onChangeEnd ?. ( nextValue ) ;
306+ callOnChangeEnd ( nextValue ) ;
294307 break ;
295308 }
296309
@@ -299,7 +312,7 @@ export const Slider = factory<SliderFactory>((_props, ref) => {
299312 precision
300313 ) ;
301314 setValue ( nextValue ) ;
302- onChangeEnd ?. ( nextValue ) ;
315+ callOnChangeEnd ( nextValue ) ;
303316 break ;
304317 }
305318
@@ -310,7 +323,7 @@ export const Slider = factory<SliderFactory>((_props, ref) => {
310323 if ( restrictToMarks && marks ) {
311324 const nextValue = getPreviousMarkValue ( _value , marks ) ;
312325 setValue ( nextValue ) ;
313- onChangeEnd ?. ( nextValue ) ;
326+ callOnChangeEnd ( nextValue ) ;
314327 break ;
315328 }
316329
@@ -319,7 +332,7 @@ export const Slider = factory<SliderFactory>((_props, ref) => {
319332 precision
320333 ) ;
321334 setValue ( nextValue ) ;
322- onChangeEnd ?. ( nextValue ) ;
335+ callOnChangeEnd ( nextValue ) ;
323336 break ;
324337 }
325338
@@ -331,7 +344,7 @@ export const Slider = factory<SliderFactory>((_props, ref) => {
331344 const nextValue =
332345 dir === 'rtl' ? getNextMarkValue ( _value , marks ) : getPreviousMarkValue ( _value , marks ) ;
333346 setValue ( nextValue ) ;
334- onChangeEnd ?. ( nextValue ) ;
347+ callOnChangeEnd ( nextValue ) ;
335348 break ;
336349 }
337350
@@ -340,7 +353,7 @@ export const Slider = factory<SliderFactory>((_props, ref) => {
340353 precision
341354 ) ;
342355 setValue ( nextValue ) ;
343- onChangeEnd ?. ( nextValue ) ;
356+ callOnChangeEnd ( nextValue ) ;
344357 break ;
345358 }
346359
@@ -350,12 +363,12 @@ export const Slider = factory<SliderFactory>((_props, ref) => {
350363
351364 if ( restrictToMarks && marks ) {
352365 setValue ( getFirstMarkValue ( marks ) ) ;
353- onChangeEnd ?. ( getFirstMarkValue ( marks ) ) ;
366+ callOnChangeEnd ( getFirstMarkValue ( marks ) ) ;
354367 break ;
355368 }
356369
357370 setValue ( min ! ) ;
358- onChangeEnd ?. ( min ! ) ;
371+ callOnChangeEnd ( min ! ) ;
359372 break ;
360373 }
361374
@@ -365,12 +378,12 @@ export const Slider = factory<SliderFactory>((_props, ref) => {
365378
366379 if ( restrictToMarks && marks ) {
367380 setValue ( getLastMarkValue ( marks ) ) ;
368- onChangeEnd ?. ( getLastMarkValue ( marks ) ) ;
381+ callOnChangeEnd ( getLastMarkValue ( marks ) ) ;
369382 break ;
370383 }
371384
372385 setValue ( max ! ) ;
373- onChangeEnd ?. ( max ! ) ;
386+ callOnChangeEnd ( max ! ) ;
374387 break ;
375388 }
376389
@@ -401,7 +414,7 @@ export const Slider = factory<SliderFactory>((_props, ref) => {
401414 value = { scaledValue }
402415 disabled = { disabled }
403416 containerProps = { {
404- ref : container as any ,
417+ ref : container ,
405418 onMouseEnter : showLabelOnHover ? ( ) => setHovered ( true ) : undefined ,
406419 onMouseLeave : showLabelOnHover ? ( ) => setHovered ( false ) : undefined ,
407420 } }
0 commit comments