react-native-datetimepicker / datetimepicker

React Native date & time picker component for iOS, Android and Windows
MIT License
2.5k stars 405 forks source link

How to customize the area size of the click? #796

Open emirdeliz opened 1 year ago

emirdeliz commented 1 year ago

How to customize the area size of the click? I tried to use it like the image below but the click only works if the user clicks inside the red rectangle.

Simulator Screenshot - iPhone 14 Pro - 2023-07-27 at 11 44 43

ThatGuySam commented 8 months ago

It's a bit hacky but I ended up just scaling it up with transform and putting what I wanted in front of it with pointerEvents='none'

Nasseratic commented 8 months ago

Did you try hitSlop prop?

ThatGuySam commented 5 months ago

@Nasseratic Actually, no. Is that a React Native primitive prop? I can't find documentation on that.

What I really need is a way to trigger opening the picker from a custom hit area or elements, not based on the stock input element.

Nasseratic commented 5 months ago

Yes it's a React Native primitive prop that you can pass to Views, Pressables, ..etc

Nasseratic commented 5 months ago

@ThatGuySam @emirdeliz Could you please give a code snippet as it will be much easier to help :)

ThatGuySam commented 5 months ago

I'll try my best, but my example of what I'm working with might be a bit too confusing without all the project context.

Here's the work around I'm using to get a custom Pressable area for


export function BirthDateField ( props: TextFieldProps ) {
    const {
        value,
        onChange,
    } = props
    const defaultYearMonthDay = thirtyYearsAgo()
    const shownDate = new Date( value || defaultYearMonthDay )
    const humanFriendlyDate = format( shownDate, 'MMMM do, yyyy' )

    return (
        {/* The parent container of all this is set to overflow: hidden so that everything inside get clipped to the right shape */}    
        <>
            {/* Actual Date Picker is absolute positioned, scaled up, and centered so that it fills it's container */}
            <View className='absolute inset-0 w-full h-full justify-center items-center'>
                <DateTimePicker
                    value={ shownDate }
                    mode='date'
                    onChange={ ( pickEvent, newDate ) => {
                        if ( !onChange || pickEvent.type !== 'set' || !newDate || toYearMonthDay( newDate ) === defaultYearMonthDay ) {
                            return
                        }

                        const [
                            yearMonthDay,
                        ] = newDate.toISOString().split( 'T' )

                        onChange( yearMonthDay )
                    } }
                    style={ {
                        backfaceVisibility: 'hidden',
                        transform: [ { scaleX: 2.5 }, { scaleY: 1.2 } ],
                    } }
                />
            </View>

            {/* Visible field gets rendered in front of DateTimePicker */}
            <View
                className='bg-white rounded-lg'
                // Pointer events are disabled so that taps pass through to the DateTimePicker
                // behind this component
                pointerEvents='none'
            >
                <GroupField.TextField
                    { ...remainingProps }
                    value={ humanFriendlyDate }
                    onChange={ undefined }
                    endIcon='chevron'
                />
            </View>
        </>
    )
}

One easier solution would be to have a custom method on the ref like so:

export function BirthDateField () {
    const datePickerRef = React.useRef< DateTimePicker >( null )

    return (
        <>
            <DateTimePicker
                ref={ datePickerRef }
            />

            {/* Visible field gets rendered in front of DateTimePicker */}
            <Pressable
                onPress={ () => datePickerRef.current?.toggle() }
                // Or
                // onPress={ () => datePickerRef.current?.open() }
            >
                <Text>Toggle/Open DateTimePicker</Text>
            </Pressable>
        </>
    )
}