Skip to content

Commit f71fa6a

Browse files
fix: require cycle
1 parent 0528d7c commit f71fa6a

File tree

4 files changed

+161
-114
lines changed

4 files changed

+161
-114
lines changed

src/Date/CalendarEdit.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
import type { ModeType, ValidRangeType } from './Calendar'
1010
import type { LocalState } from './DatePickerModalContent'
1111

12-
import DatePickerInput from './DatePickerInput'
12+
import DatePickerInputWithoutModal from './DatePickerInputWithoutModal'
1313

1414
function CalendarEdit({
1515
mode,
@@ -77,7 +77,7 @@ function CalendarEdit({
7777
return (
7878
<View style={styles.root}>
7979
{mode === 'single' ? (
80-
<DatePickerInput
80+
<DatePickerInputWithoutModal
8181
inputMode="start"
8282
ref={dateInput}
8383
label={label}
@@ -92,7 +92,7 @@ function CalendarEdit({
9292
) : null}
9393
{mode === 'range' ? (
9494
<View style={styles.inner}>
95-
<DatePickerInput
95+
<DatePickerInputWithoutModal
9696
inputMode="start"
9797
ref={startInput}
9898
label={startLabel}
@@ -106,7 +106,7 @@ function CalendarEdit({
106106
autoComplete={'off'}
107107
/>
108108
<View style={styles.separator} />
109-
<DatePickerInput
109+
<DatePickerInputWithoutModal
110110
inputMode="end"
111111
ref={endInput}
112112
label={endLabel}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type { ValidRangeType } from './Calendar'
2+
import type * as React from 'react'
3+
import type { TextInput } from 'react-native-paper'
4+
5+
export type DatePickerInputProps = {
6+
inputMode: 'start' | 'end'
7+
locale: string
8+
onChange: (date: Date | undefined) => void
9+
value: Date | undefined
10+
validRange?: ValidRangeType | undefined
11+
withModal?: boolean
12+
withDateFormatInLabel?: boolean
13+
calendarIcon?: string
14+
} & Omit<
15+
React.ComponentProps<typeof TextInput>,
16+
'value' | 'onChange' | 'onChangeText'
17+
>

src/Date/DatePickerInput.tsx

Lines changed: 30 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,147 +1,67 @@
11
import * as React from 'react'
22

3-
import TextInputWithMask from '../TextInputMask'
4-
import { HelperText, IconButton, TextInput, useTheme } from 'react-native-paper'
5-
import { View, StyleSheet } from 'react-native'
3+
import { IconButton } from 'react-native-paper'
4+
import { StyleSheet } from 'react-native'
65
import DatePickerModal from './DatePickerModal'
7-
import useDateInput from './inputUtils'
8-
import type { ValidRangeType } from './Calendar'
96
import { useLatest } from '../utils'
7+
import type { DatePickerInputProps } from './DatePickerInput.shared'
8+
import DatePickerInputWithoutModal from './DatePickerInputWithoutModal'
109

1110
function DatePickerInput(
1211
{
13-
label,
14-
value,
15-
onChange,
16-
style,
17-
locale,
18-
validRange,
19-
inputMode,
2012
withModal = true,
21-
withDateFormatInLabel = true,
2213
calendarIcon = 'calendar',
2314
...rest
24-
}: {
25-
inputMode: 'start' | 'end'
26-
locale: string
27-
onChange: (date: Date | undefined) => void
28-
value: Date | undefined
29-
validRange?: ValidRangeType | undefined
30-
withModal?: boolean
31-
withDateFormatInLabel?: boolean
32-
calendarIcon?: string
33-
} & Omit<
34-
React.ComponentProps<typeof TextInput>,
35-
'value' | 'onChange' | 'onChangeText'
36-
>,
15+
}: DatePickerInputProps,
3716
ref: any
3817
) {
39-
const theme = useTheme()
40-
const { formattedValue, inputFormat, onChangeText, error } = useDateInput({
41-
locale,
42-
value,
43-
validRange,
44-
inputMode,
45-
onChange,
46-
})
47-
4818
const [visible, setVisible] = React.useState<boolean>(false)
4919
const onDismiss = React.useCallback(() => {
5020
setVisible(false)
5121
}, [setVisible])
52-
const onChangeRef = useLatest(onChange)
22+
const onChangeRef = useLatest(rest.onChange)
5323
const onInnerConfirm = React.useCallback(
54-
({ date }) => {
24+
({ date }: any) => {
5525
setVisible(false)
5626
onChangeRef.current(date)
5727
},
5828
[setVisible, onChangeRef]
5929
)
6030

6131
return (
62-
<>
63-
<View style={styles.root}>
64-
<TextInputWithMask
65-
{...rest}
66-
ref={ref}
67-
label={getLabel({
68-
// TODO: support label components?
69-
label: label as any,
70-
inputFormat,
71-
withDateFormatInLabel,
72-
})}
73-
value={formattedValue}
74-
keyboardType={'number-pad'}
75-
placeholder={inputFormat}
76-
mask={inputFormat}
77-
onChangeText={onChangeText}
78-
keyboardAppearance={theme.dark ? 'dark' : 'default'}
79-
error={!!error}
80-
style={[styles.input, style]}
81-
/>
82-
{withModal ? (
32+
<DatePickerInputWithoutModal
33+
ref={ref}
34+
{...rest}
35+
inputButtons={
36+
withModal ? (
8337
<IconButton
8438
size={24}
8539
style={styles.calendarButton}
8640
icon={calendarIcon}
8741
onPress={() => setVisible(true)}
8842
/>
89-
) : null}
90-
{!!error ? (
91-
<View style={styles.helperText}>
92-
<HelperText
93-
style={styles.helperText}
94-
type="error"
95-
visible={!!error}
96-
>
97-
{error}
98-
</HelperText>
99-
</View>
100-
) : null}
101-
</View>
102-
{withModal ? (
103-
<DatePickerModal
104-
date={value}
105-
mode="single"
106-
visible={visible}
107-
onDismiss={onDismiss}
108-
onConfirm={onInnerConfirm}
109-
locale={locale}
110-
dateMode={inputMode}
111-
validRange={validRange}
112-
/>
113-
) : null}
114-
</>
43+
) : null
44+
}
45+
modal={({ value, locale, inputMode, validRange }) =>
46+
withModal ? (
47+
<DatePickerModal
48+
date={value}
49+
mode="single"
50+
visible={visible}
51+
onDismiss={onDismiss}
52+
onConfirm={onInnerConfirm}
53+
locale={locale}
54+
dateMode={inputMode}
55+
validRange={validRange}
56+
/>
57+
) : null
58+
}
59+
/>
11560
)
11661
}
11762

118-
function getLabel({
119-
withDateFormatInLabel,
120-
inputFormat,
121-
label,
122-
}: {
123-
withDateFormatInLabel: boolean
124-
inputFormat: string
125-
label: string | undefined
126-
}) {
127-
if (withDateFormatInLabel) {
128-
return label ? `${label} (${inputFormat})` : inputFormat
129-
}
130-
return label || ''
131-
}
132-
13363
const styles = StyleSheet.create({
134-
root: {
135-
minWidth: 150,
136-
flexGrow: 1,
137-
},
138-
helperTextContainer: {
139-
flexDirection: 'row',
140-
},
141-
helperText: {
142-
flex: 1,
143-
},
144-
input: {},
14564
calendarButton: { position: 'absolute', right: 0, zIndex: 10 },
14665
})
66+
14767
export default React.forwardRef(DatePickerInput)
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import * as React from 'react'
2+
3+
import TextInputWithMask from '../TextInputMask'
4+
import { HelperText, useTheme } from 'react-native-paper'
5+
import { View, StyleSheet } from 'react-native'
6+
import useDateInput from './inputUtils'
7+
import type { DatePickerInputProps } from './DatePickerInput.shared'
8+
9+
function DatePickerInputWithoutModal(
10+
{
11+
label,
12+
value,
13+
onChange,
14+
style,
15+
locale,
16+
validRange,
17+
inputMode,
18+
withDateFormatInLabel = true,
19+
modal,
20+
inputButtons,
21+
...rest
22+
}: DatePickerInputProps & {
23+
modal: (params: {
24+
value: DatePickerInputProps['value']
25+
locale: DatePickerInputProps['locale']
26+
inputMode: DatePickerInputProps['inputMode']
27+
validRange: DatePickerInputProps['validRange']
28+
}) => any
29+
inputButtons: any
30+
},
31+
ref: any
32+
) {
33+
const theme = useTheme()
34+
const { formattedValue, inputFormat, onChangeText, error } = useDateInput({
35+
locale,
36+
value,
37+
validRange,
38+
inputMode,
39+
onChange,
40+
})
41+
42+
return (
43+
<>
44+
<View style={styles.root}>
45+
<TextInputWithMask
46+
{...rest}
47+
ref={ref}
48+
label={getLabel({
49+
// TODO: support label components?
50+
label: label as any,
51+
inputFormat,
52+
withDateFormatInLabel,
53+
})}
54+
value={formattedValue}
55+
keyboardType={'number-pad'}
56+
placeholder={inputFormat}
57+
mask={inputFormat}
58+
onChangeText={onChangeText}
59+
keyboardAppearance={theme.dark ? 'dark' : 'default'}
60+
error={!!error}
61+
style={[styles.input, style]}
62+
/>
63+
{inputButtons}
64+
{!!error ? (
65+
<View style={styles.helperText}>
66+
<HelperText
67+
style={styles.helperText}
68+
type="error"
69+
visible={!!error}
70+
>
71+
{error}
72+
</HelperText>
73+
</View>
74+
) : null}
75+
</View>
76+
{modal?.({ value, locale, inputMode, validRange })}
77+
</>
78+
)
79+
}
80+
81+
function getLabel({
82+
withDateFormatInLabel,
83+
inputFormat,
84+
label,
85+
}: {
86+
withDateFormatInLabel: boolean
87+
inputFormat: string
88+
label: string | undefined
89+
}) {
90+
if (withDateFormatInLabel) {
91+
return label ? `${label} (${inputFormat})` : inputFormat
92+
}
93+
return label || ''
94+
}
95+
96+
const styles = StyleSheet.create({
97+
root: {
98+
minWidth: 150,
99+
flexGrow: 1,
100+
justifyContent: 'center',
101+
},
102+
helperTextContainer: {
103+
flexDirection: 'row',
104+
},
105+
helperText: {
106+
flex: 1,
107+
},
108+
input: {},
109+
})
110+
export default React.forwardRef(DatePickerInputWithoutModal)

0 commit comments

Comments
 (0)