11import * as React from 'react' ;
22
3+ import { useDebouncedCallback } from '../../hooks/useDebouncedCallback' ;
34import { WheelPicker } from './WheelPicker' ;
45import { ITEM_HEIGHT } from './WheelPicker.constants' ;
56import { WheelPickerOption } from './WheelPickerItem' ;
67
8+ const DEBOUNCE_TIME = 300 ;
9+
710export const makePaddedOptions = ( options : WheelPickerOption [ ] ) => {
811 return [
912 { value : 'emptyStart' , label : '' } ,
@@ -64,18 +67,15 @@ export const useWheelPicker = (props: UseWheelPickerProps) => {
6467 onValueChange = ( ) => {
6568 return ;
6669 } ,
67- value : initialValue ,
70+ value : initialValue = options [ 0 ] . value ,
6871 scrollContainer,
6972 ref,
7073 } = props ;
7174 const optionsWithClones = makePaddedOptions ( options ) ;
72- const [ currentValue , setCurrentValue ] = React . useState ( initialValue ) ;
75+ const [ value , setValue ] = React . useState < string > ( initialValue ) ;
7376 const getOption = React . useMemo ( ( ) => getOptionFromOptions ( options ) , [
7477 options ,
7578 ] ) ;
76- const initialScrollIndex = options . findIndex (
77- o => o . value === ( initialValue || options [ 0 ] . value ) ,
78- ) ;
7979
8080 const scrollToValue = React . useCallback (
8181 ( toValue : string , animated = true ) => {
@@ -87,30 +87,30 @@ export const useWheelPicker = (props: UseWheelPickerProps) => {
8787 animated,
8888 offset : index * ITEM_HEIGHT - ITEM_HEIGHT ,
8989 } ) ;
90-
91- setCurrentValue ( toValue ) ;
9290 } ,
9391 [ scrollContainer , options ] ,
9492 ) ;
9593
96- React . useLayoutEffect ( ( ) => {
97- if ( initialValue ) {
98- scrollToValue ( initialValue , false ) ;
99- } else {
100- scrollToValue ( options [ 0 ] . value , false ) ;
101- }
102- } , [ options ] ) ;
94+ const handleChange = React . useCallback (
95+ ( newValue : string ) => {
96+ if ( newValue !== value ) {
97+ onValueChange ( newValue ) ;
98+ setValue ( newValue ) ;
99+ }
100+ } ,
101+ [ onValueChange , value ] ,
102+ ) ;
103103
104- const handleScroll = React . useCallback (
104+ const handleScroll = useDebouncedCallback (
105105 ( offset : number ) => {
106106 if ( ! scrollContainer ) return ;
107107
108108 const selectedOption = getOption ( offset ) ;
109109
110- onValueChange ( selectedOption . value ) ;
111- setCurrentValue ( selectedOption . value ) ;
110+ handleChange ( selectedOption . value ) ;
112111 } ,
113- [ scrollContainer , options ] ,
112+ DEBOUNCE_TIME ,
113+ [ scrollContainer , options , handleChange ] ,
114114 ) ;
115115
116116 const handleEndDrag = React . useCallback (
@@ -125,43 +125,41 @@ export const useWheelPicker = (props: UseWheelPickerProps) => {
125125
126126 const selectedOption = getOption ( scrollPosition ) ;
127127
128- onValueChange ( selectedOption . value ) ;
129- setCurrentValue ( selectedOption . value ) ;
128+ handleChange ( selectedOption . value ) ;
130129 } ,
131- [ scrollContainer , options ] ,
130+ [ scrollContainer , options , handleChange ] ,
132131 ) ;
133132
134133 React . useImperativeHandle (
135134 ref ,
136135 ( ) => ( {
137- selectValue : ( value : string ) => scrollToValue ( value ) ,
136+ selectValue : ( newValue : string ) => scrollToValue ( newValue ) ,
138137 } ) ,
139138 [ scrollContainer , options ] ,
140139 ) ;
141140
142141 const handlePressUp = React . useCallback ( ( ) => {
143142 if ( ! scrollContainer ) return ;
144- const currentIndex = options . findIndex ( o => o . value === currentValue ) ;
143+ const currentIndex = options . findIndex ( o => o . value === value ) ;
145144
146145 if ( currentIndex <= 0 ) return ;
147146 scrollToValue ( options [ currentIndex - 1 ] . value ) ;
148- } , [ scrollContainer , currentValue ] ) ;
147+ } , [ scrollContainer , value ] ) ;
149148
150149 const handlePressDown = React . useCallback ( ( ) => {
151150 if ( ! scrollContainer ) return ;
152151
153- const currentIndex = options . findIndex ( o => o . value === currentValue ) ;
152+ const currentIndex = options . findIndex ( o => o . value === value ) ;
154153
155154 if ( currentIndex >= options . length - 1 ) return ;
156155 scrollToValue ( options [ currentIndex + 1 ] . value ) ;
157- } , [ scrollContainer , currentValue ] ) ;
156+ } , [ scrollContainer , value ] ) ;
158157
159158 return {
160159 handleEndDrag,
161160 handlePressDown,
162161 handlePressUp,
163162 handleScroll,
164- initialScrollIndex,
165163 optionsWithClones,
166164 scrollToValue,
167165 } ;
0 commit comments