* Revert other base PR changes, switch date picker library rm expo-linear-gradient Revert "remove unused packages, switch to `expo-linear-gradient`" This reverts commit 20a0ffcf Revert "upgrade expo deps" This reverts commit a43dca92caa120d45fb771431752dd2db3b37ab5. Revert other library changes This reverts commit 5219f66e Revert "re-add normalize-url" This reverts commit 654019c4babe2e455f6069a6c725eb51140ab1ab. Revert "add `expo-haptics`" This reverts commit ff3a0399b1c7eae07b83946f13543eedf7cdfe82. Revert "add `expo-clipboard`" This reverts commit 440ae91632153e22ff79050d8ac803a7305e88a0. Revert "add `expo-file-system`" This reverts commit c0fe0c94534564982399c22299a8a19052bf3e54. fix android alf use modal on android migrate to `react-native-date-picker` rm `@reactnativecommunity/datetimepicker` add `react-native-date-picker` add `expo-file-system` add `expo-clipboard` add `expo-haptics` re-add normalize-url rm blur view upgrade expo deps remove unused packages, switch to `expo-linear-gradient` * rm old library * Use UTC for dates --------- Co-authored-by: Eric Bailey <git@esb.lol>
107 lines
2.9 KiB
TypeScript
107 lines
2.9 KiB
TypeScript
import React from 'react'
|
|
import {View, Pressable} from 'react-native'
|
|
|
|
import {useTheme, atoms} from '#/alf'
|
|
import {Text} from '#/components/Typography'
|
|
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
|
import * as TextField from '#/components/forms/TextField'
|
|
import {CalendarDays_Stroke2_Corner0_Rounded as CalendarDays} from '#/components/icons/CalendarDays'
|
|
|
|
import {DateFieldProps} from '#/components/forms/DateField/types'
|
|
import {
|
|
localizeDate,
|
|
toSimpleDateString,
|
|
} from '#/components/forms/DateField/utils'
|
|
import DatePicker from 'react-native-date-picker'
|
|
import {isAndroid} from 'platform/detection'
|
|
|
|
export * as utils from '#/components/forms/DateField/utils'
|
|
export const Label = TextField.Label
|
|
|
|
export function DateField({
|
|
value,
|
|
onChangeDate,
|
|
label,
|
|
isInvalid,
|
|
testID,
|
|
}: DateFieldProps) {
|
|
const t = useTheme()
|
|
const [open, setOpen] = React.useState(false)
|
|
const {
|
|
state: pressed,
|
|
onIn: onPressIn,
|
|
onOut: onPressOut,
|
|
} = useInteractionState()
|
|
const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState()
|
|
|
|
const {chromeFocus, chromeError, chromeErrorHover} =
|
|
TextField.useSharedInputStyles()
|
|
|
|
const onChangeInternal = React.useCallback(
|
|
(date: Date) => {
|
|
setOpen(false)
|
|
|
|
const formatted = toSimpleDateString(date)
|
|
onChangeDate(formatted)
|
|
},
|
|
[onChangeDate, setOpen],
|
|
)
|
|
|
|
const onCancel = React.useCallback(() => {
|
|
setOpen(false)
|
|
}, [])
|
|
|
|
return (
|
|
<View style={[atoms.relative, atoms.w_full]}>
|
|
<Pressable
|
|
aria-label={label}
|
|
accessibilityLabel={label}
|
|
accessibilityHint={undefined}
|
|
onPress={() => setOpen(true)}
|
|
onPressIn={onPressIn}
|
|
onPressOut={onPressOut}
|
|
onFocus={onFocus}
|
|
onBlur={onBlur}
|
|
style={[
|
|
{
|
|
paddingTop: 16,
|
|
paddingBottom: 16,
|
|
borderColor: 'transparent',
|
|
borderWidth: 2,
|
|
},
|
|
atoms.flex_row,
|
|
atoms.flex_1,
|
|
atoms.w_full,
|
|
atoms.px_lg,
|
|
atoms.rounded_sm,
|
|
t.atoms.bg_contrast_50,
|
|
focused || pressed ? chromeFocus : {},
|
|
isInvalid ? chromeError : {},
|
|
isInvalid && (focused || pressed) ? chromeErrorHover : {},
|
|
]}>
|
|
<TextField.Icon icon={CalendarDays} />
|
|
|
|
<Text
|
|
style={[atoms.text_md, atoms.pl_xs, t.atoms.text, {paddingTop: 3}]}>
|
|
{localizeDate(value)}
|
|
</Text>
|
|
</Pressable>
|
|
|
|
{open && (
|
|
<DatePicker
|
|
modal={isAndroid}
|
|
open={isAndroid}
|
|
theme={t.name === 'light' ? 'light' : 'dark'}
|
|
date={new Date(value)}
|
|
onConfirm={onChangeInternal}
|
|
onCancel={onCancel}
|
|
mode="date"
|
|
testID={`${testID}-datepicker`}
|
|
aria-label={label}
|
|
accessibilityLabel={label}
|
|
accessibilityHint={undefined}
|
|
/>
|
|
)}
|
|
</View>
|
|
)
|
|
}
|