@hero-design/rn 8.96.0 → 8.97.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +3 -3
- package/CHANGELOG.md +6 -0
- package/es/index.js +436 -367
- package/lib/index.js +438 -369
- package/package.json +1 -1
- package/src/components/DatePicker/DatePickerAndroid.tsx +10 -36
- package/src/components/DatePicker/DatePickerIOS.tsx +13 -63
- package/src/components/DatePicker/Dialog/AndroidDialog.tsx +68 -0
- package/src/components/DatePicker/Dialog/IOSDialog.tsx +91 -0
- package/src/components/DatePicker/Dialog/__tests__/AndroidDialog.spec.tsx +70 -0
- package/src/components/DatePicker/Dialog/__tests__/IOSDialog.spec.tsx +114 -0
- package/src/components/DatePicker/Dialog/type.ts +50 -0
- package/src/components/DatePicker/__tests__/__snapshots__/DatePickerAndroid.spec.tsx.snap +18 -9
- package/src/components/DatePicker/index.tsx +12 -1
- package/stats/8.97.0/rn-stats.html +4842 -0
- package/types/components/DatePicker/Dialog/AndroidDialog.d.ts +5 -0
- package/types/components/DatePicker/Dialog/IOSDialog.d.ts +4 -0
- package/types/components/DatePicker/Dialog/type.d.ts +50 -0
- package/types/components/DatePicker/index.d.ts +5 -2
package/package.json
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import DateTimePicker from '@react-native-community/datetimepicker';
|
|
2
1
|
import React, { useState } from 'react';
|
|
3
2
|
import { TouchableOpacity, View } from 'react-native';
|
|
4
3
|
|
|
5
|
-
import { MonthYearPickerDialogueAndroid } from '@hero-design/react-native-month-year-picker';
|
|
6
|
-
import { useTheme } from '../../theme';
|
|
7
4
|
import TextInput from '../TextInput';
|
|
5
|
+
import AndroidDatePickerDialog from './Dialog/AndroidDialog';
|
|
8
6
|
import useCalculateDate from './hooks/useCalculateDate';
|
|
9
7
|
import useFormatDate from './hooks/useFormatDate';
|
|
10
8
|
import type { DatePickerProps } from './types';
|
|
@@ -43,9 +41,6 @@ const DatePickerAndroid = ({
|
|
|
43
41
|
|
|
44
42
|
useCalculateDate({ minDate, maxDate, onChange, value });
|
|
45
43
|
|
|
46
|
-
const pickerInitValue = value || new Date();
|
|
47
|
-
const theme = useTheme();
|
|
48
|
-
|
|
49
44
|
return (
|
|
50
45
|
<TouchableOpacity onPress={() => setOpen(true)} disabled={disabled}>
|
|
51
46
|
<View pointerEvents="none" testID="datePickerInputAndroid">
|
|
@@ -74,36 +69,15 @@ const DatePickerAndroid = ({
|
|
|
74
69
|
}
|
|
75
70
|
/>
|
|
76
71
|
</View>
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
onChange(date);
|
|
87
|
-
}
|
|
88
|
-
}}
|
|
89
|
-
/>
|
|
90
|
-
) : null}
|
|
91
|
-
{open && variant === 'default' ? (
|
|
92
|
-
<DateTimePicker
|
|
93
|
-
testID="datePickerAndroid"
|
|
94
|
-
mode="date"
|
|
95
|
-
value={pickerInitValue}
|
|
96
|
-
minimumDate={minDate}
|
|
97
|
-
maximumDate={maxDate}
|
|
98
|
-
display="default"
|
|
99
|
-
onChange={(_: any, date: Date | undefined) => {
|
|
100
|
-
setOpen(false);
|
|
101
|
-
if (date) {
|
|
102
|
-
onChange(date);
|
|
103
|
-
}
|
|
104
|
-
}}
|
|
105
|
-
/>
|
|
106
|
-
) : null}
|
|
72
|
+
<AndroidDatePickerDialog
|
|
73
|
+
open={open}
|
|
74
|
+
onClose={() => setOpen(false)}
|
|
75
|
+
value={value}
|
|
76
|
+
minDate={minDate}
|
|
77
|
+
maxDate={maxDate}
|
|
78
|
+
onChange={onChange}
|
|
79
|
+
variant={variant}
|
|
80
|
+
/>
|
|
107
81
|
</TouchableOpacity>
|
|
108
82
|
);
|
|
109
83
|
};
|
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
import DateTimePicker from '@react-native-community/datetimepicker';
|
|
2
1
|
import React, { useState } from 'react';
|
|
3
2
|
import { TouchableOpacity, View } from 'react-native';
|
|
4
3
|
|
|
5
|
-
import { MonthYearPickerViewIOS } from '@hero-design/react-native-month-year-picker';
|
|
6
|
-
import { useTheme } from '../../theme';
|
|
7
|
-
import BottomSheet from '../BottomSheet';
|
|
8
|
-
import Button from '../Button';
|
|
9
4
|
import { useLocale } from '../LocaleProvider/hooks';
|
|
10
5
|
import TextInput from '../TextInput';
|
|
11
|
-
import
|
|
6
|
+
import IOSDatePickerDialog from './Dialog/IOSDialog';
|
|
7
|
+
import useCalculateDate from './hooks/useCalculateDate';
|
|
12
8
|
import useFormatDate from './hooks/useFormatDate';
|
|
13
|
-
import { StyledPickerWrapper } from './StyledDatePicker';
|
|
14
9
|
import type { DatePickerProps } from './types';
|
|
15
10
|
|
|
16
11
|
type DatePickerIOSProps = Omit<
|
|
@@ -39,10 +34,6 @@ const DatePickerIOS = ({
|
|
|
39
34
|
locale,
|
|
40
35
|
renderSelectedValue,
|
|
41
36
|
}: DatePickerIOSProps) => {
|
|
42
|
-
const theme = useTheme();
|
|
43
|
-
const [selectingDate, setSelectingDate] = useState<Date>(
|
|
44
|
-
getDateValue(value || new Date(), minDate, maxDate)
|
|
45
|
-
);
|
|
46
37
|
const [open, setOpen] = useState(false);
|
|
47
38
|
const { lang: defaultLocale } = useLocale();
|
|
48
39
|
const { displayValue, format } = useFormatDate({
|
|
@@ -81,60 +72,19 @@ const DatePickerIOS = ({
|
|
|
81
72
|
}
|
|
82
73
|
/>
|
|
83
74
|
</View>
|
|
84
|
-
<
|
|
75
|
+
<IOSDatePickerDialog
|
|
76
|
+
value={value}
|
|
77
|
+
onChange={onChange}
|
|
85
78
|
open={open}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
<Button
|
|
90
|
-
variant="text"
|
|
91
|
-
text={confirmLabel}
|
|
92
|
-
onPress={() => {
|
|
93
|
-
if (selectingDate) {
|
|
94
|
-
onChange(selectingDate);
|
|
95
|
-
}
|
|
96
|
-
setOpen(false);
|
|
97
|
-
}}
|
|
98
|
-
/>
|
|
99
|
-
}
|
|
79
|
+
onClose={() => setOpen(false)}
|
|
80
|
+
confirmLabel={confirmLabel}
|
|
81
|
+
locale={locale || defaultLocale}
|
|
100
82
|
supportedOrientations={supportedOrientations}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
locale={locale || defaultLocale}
|
|
107
|
-
minimumDate={minDate}
|
|
108
|
-
textColor={theme.colors.onDefaultGlobalSurface}
|
|
109
|
-
maximumDate={maxDate}
|
|
110
|
-
onChange={(date: Date | undefined) => {
|
|
111
|
-
if (date) {
|
|
112
|
-
setSelectingDate(date);
|
|
113
|
-
}
|
|
114
|
-
}}
|
|
115
|
-
style={{ flex: 1 }}
|
|
116
|
-
/>
|
|
117
|
-
) : null}
|
|
118
|
-
{variant === 'default' ? (
|
|
119
|
-
<DateTimePicker
|
|
120
|
-
locale={locale || defaultLocale}
|
|
121
|
-
testID="datePickerIOS"
|
|
122
|
-
value={selectingDate}
|
|
123
|
-
minimumDate={minDate}
|
|
124
|
-
maximumDate={maxDate}
|
|
125
|
-
mode="date"
|
|
126
|
-
onChange={(_: any, date: Date | undefined) => {
|
|
127
|
-
if (date) {
|
|
128
|
-
setSelectingDate(date);
|
|
129
|
-
}
|
|
130
|
-
}}
|
|
131
|
-
display="spinner"
|
|
132
|
-
style={{ flex: 1 }}
|
|
133
|
-
textColor={theme.colors.onDefaultGlobalSurface}
|
|
134
|
-
/>
|
|
135
|
-
) : null}
|
|
136
|
-
</StyledPickerWrapper>
|
|
137
|
-
</BottomSheet>
|
|
83
|
+
variant={variant}
|
|
84
|
+
label={label}
|
|
85
|
+
minDate={minDate}
|
|
86
|
+
maxDate={maxDate}
|
|
87
|
+
/>
|
|
138
88
|
</TouchableOpacity>
|
|
139
89
|
);
|
|
140
90
|
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import DateTimePicker, {
|
|
3
|
+
DateTimePickerEvent,
|
|
4
|
+
} from '@react-native-community/datetimepicker';
|
|
5
|
+
import { MonthYearPickerDialogueAndroid } from '@hero-design/react-native-month-year-picker';
|
|
6
|
+
import { DatePickerDialogProps } from './type';
|
|
7
|
+
import { useTheme } from '../../../theme';
|
|
8
|
+
import Box from '../../Box';
|
|
9
|
+
|
|
10
|
+
export type AndroidDatePickerDialogProps = Omit<
|
|
11
|
+
DatePickerDialogProps,
|
|
12
|
+
'supportedOrientations' | 'confirmLabel' | 'label' | 'locale'
|
|
13
|
+
>;
|
|
14
|
+
|
|
15
|
+
const AndroidDatePickerDialog = ({
|
|
16
|
+
open,
|
|
17
|
+
onClose,
|
|
18
|
+
value,
|
|
19
|
+
minDate,
|
|
20
|
+
maxDate,
|
|
21
|
+
onChange,
|
|
22
|
+
testID,
|
|
23
|
+
variant = 'default',
|
|
24
|
+
}: AndroidDatePickerDialogProps) => {
|
|
25
|
+
const theme = useTheme();
|
|
26
|
+
if (!open) return null;
|
|
27
|
+
|
|
28
|
+
const pickerInitValue = value || new Date();
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<Box testID={testID}>
|
|
32
|
+
{open && variant === 'month-year' ? (
|
|
33
|
+
<Box testID={testID}>
|
|
34
|
+
<MonthYearPickerDialogueAndroid
|
|
35
|
+
themeVariant={theme.themeMode === 'dark' ? 'dark' : 'light'}
|
|
36
|
+
value={value}
|
|
37
|
+
minimumDate={minDate}
|
|
38
|
+
maximumDate={maxDate}
|
|
39
|
+
onChange={(action, date) => {
|
|
40
|
+
onClose();
|
|
41
|
+
if (action === 'dateSetAction' && !!date) {
|
|
42
|
+
onChange(date);
|
|
43
|
+
}
|
|
44
|
+
}}
|
|
45
|
+
/>
|
|
46
|
+
</Box>
|
|
47
|
+
) : null}
|
|
48
|
+
{open && variant === 'default' ? (
|
|
49
|
+
<DateTimePicker
|
|
50
|
+
testID="datePickerAndroid"
|
|
51
|
+
mode="date"
|
|
52
|
+
value={pickerInitValue}
|
|
53
|
+
minimumDate={minDate}
|
|
54
|
+
maximumDate={maxDate}
|
|
55
|
+
display="default"
|
|
56
|
+
onChange={(_: DateTimePickerEvent, date: Date | undefined) => {
|
|
57
|
+
onClose();
|
|
58
|
+
if (date) {
|
|
59
|
+
onChange(date);
|
|
60
|
+
}
|
|
61
|
+
}}
|
|
62
|
+
/>
|
|
63
|
+
) : null}
|
|
64
|
+
</Box>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export default AndroidDatePickerDialog;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { MonthYearPickerViewIOS } from '@hero-design/react-native-month-year-picker';
|
|
2
|
+
import DateTimePicker, {
|
|
3
|
+
DateTimePickerEvent,
|
|
4
|
+
} from '@react-native-community/datetimepicker';
|
|
5
|
+
import React, { useState } from 'react';
|
|
6
|
+
import BottomSheet from '../../BottomSheet';
|
|
7
|
+
import Button from '../../Button';
|
|
8
|
+
import { useTheme } from '../../../theme';
|
|
9
|
+
import { StyledPickerWrapper } from '../StyledDatePicker';
|
|
10
|
+
import { DatePickerDialogProps } from './type';
|
|
11
|
+
import { getDateValue } from '../hooks/useCalculateDate';
|
|
12
|
+
|
|
13
|
+
const IOSDatePickerDialog = ({
|
|
14
|
+
label,
|
|
15
|
+
open,
|
|
16
|
+
onClose,
|
|
17
|
+
confirmLabel,
|
|
18
|
+
locale,
|
|
19
|
+
value,
|
|
20
|
+
minDate,
|
|
21
|
+
maxDate,
|
|
22
|
+
onChange,
|
|
23
|
+
testID,
|
|
24
|
+
variant = 'default',
|
|
25
|
+
supportedOrientations = ['portrait'],
|
|
26
|
+
}: DatePickerDialogProps) => {
|
|
27
|
+
const theme = useTheme();
|
|
28
|
+
const [selectingDate, setSelectingDate] = useState<Date>(
|
|
29
|
+
getDateValue(value || new Date(), minDate, maxDate)
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<BottomSheet
|
|
34
|
+
testID={testID}
|
|
35
|
+
open={open}
|
|
36
|
+
onRequestClose={onClose}
|
|
37
|
+
header={label}
|
|
38
|
+
footer={
|
|
39
|
+
<Button
|
|
40
|
+
variant="text"
|
|
41
|
+
text={confirmLabel}
|
|
42
|
+
onPress={() => {
|
|
43
|
+
if (selectingDate) {
|
|
44
|
+
onChange(selectingDate);
|
|
45
|
+
}
|
|
46
|
+
onClose();
|
|
47
|
+
}}
|
|
48
|
+
/>
|
|
49
|
+
}
|
|
50
|
+
supportedOrientations={supportedOrientations}
|
|
51
|
+
>
|
|
52
|
+
<StyledPickerWrapper>
|
|
53
|
+
{variant === 'month-year' ? (
|
|
54
|
+
<MonthYearPickerViewIOS
|
|
55
|
+
value={selectingDate}
|
|
56
|
+
locale={locale}
|
|
57
|
+
minimumDate={minDate}
|
|
58
|
+
textColor={theme.colors.onDefaultGlobalSurface}
|
|
59
|
+
maximumDate={maxDate}
|
|
60
|
+
onChange={(date: Date | undefined) => {
|
|
61
|
+
if (date) {
|
|
62
|
+
setSelectingDate(date);
|
|
63
|
+
}
|
|
64
|
+
}}
|
|
65
|
+
style={{ flex: 1 }}
|
|
66
|
+
/>
|
|
67
|
+
) : null}
|
|
68
|
+
{variant === 'default' ? (
|
|
69
|
+
<DateTimePicker
|
|
70
|
+
locale={locale}
|
|
71
|
+
testID="datePickerIOS"
|
|
72
|
+
value={selectingDate}
|
|
73
|
+
minimumDate={minDate}
|
|
74
|
+
maximumDate={maxDate}
|
|
75
|
+
mode="date"
|
|
76
|
+
onChange={(_: DateTimePickerEvent, date: Date | undefined) => {
|
|
77
|
+
if (date) {
|
|
78
|
+
setSelectingDate(date);
|
|
79
|
+
}
|
|
80
|
+
}}
|
|
81
|
+
display="spinner"
|
|
82
|
+
style={{ flex: 1 }}
|
|
83
|
+
textColor={theme.colors.onDefaultGlobalSurface}
|
|
84
|
+
/>
|
|
85
|
+
) : null}
|
|
86
|
+
</StyledPickerWrapper>
|
|
87
|
+
</BottomSheet>
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export default IOSDatePickerDialog;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { fireEvent } from '@testing-library/react-native';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
import { Button } from '../../../..';
|
|
4
|
+
import renderWithTheme from '../../../../testHelpers/renderWithTheme';
|
|
5
|
+
import AndroidDialog, { AndroidDatePickerDialogProps } from '../AndroidDialog';
|
|
6
|
+
|
|
7
|
+
const AndroidDialogExample = (
|
|
8
|
+
props: Omit<AndroidDatePickerDialogProps, 'open' | 'onClose'>
|
|
9
|
+
) => {
|
|
10
|
+
const [open, setOpen] = useState(false);
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<>
|
|
14
|
+
<Button onPress={() => setOpen(true)} text="Open" />
|
|
15
|
+
<AndroidDialog open={open} onClose={() => setOpen(false)} {...props} />
|
|
16
|
+
</>
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
describe('AndroidDialog', () => {
|
|
21
|
+
it('renders correctly', () => {
|
|
22
|
+
const onChange = jest.fn();
|
|
23
|
+
|
|
24
|
+
const { getByText, queryByTestId } = renderWithTheme(
|
|
25
|
+
<AndroidDialogExample
|
|
26
|
+
value={new Date('December 21, 1995')}
|
|
27
|
+
minDate={new Date('December 17, 1994')}
|
|
28
|
+
maxDate={new Date('December 17, 1996')}
|
|
29
|
+
onChange={onChange}
|
|
30
|
+
testID="android-dialog"
|
|
31
|
+
/>
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
expect(queryByTestId('android-dialog')).toBeNull();
|
|
35
|
+
|
|
36
|
+
// Open date picker
|
|
37
|
+
fireEvent.press(getByText('Open'));
|
|
38
|
+
expect(queryByTestId('datePickerAndroid')).toBeVisible();
|
|
39
|
+
|
|
40
|
+
// Change date
|
|
41
|
+
fireEvent(
|
|
42
|
+
queryByTestId('datePickerAndroid'),
|
|
43
|
+
'onChange',
|
|
44
|
+
null,
|
|
45
|
+
new Date('December 17, 1995')
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
expect(onChange).toBeCalledWith(new Date('December 17, 1995'));
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('renders month-year picker', () => {
|
|
52
|
+
const onChangeSpy = jest.fn();
|
|
53
|
+
const { queryByText, getByText } = renderWithTheme(
|
|
54
|
+
<AndroidDialogExample
|
|
55
|
+
value={new Date('December 21, 1995')}
|
|
56
|
+
variant="month-year"
|
|
57
|
+
onChange={onChangeSpy}
|
|
58
|
+
testID="android-dialog"
|
|
59
|
+
/>
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
fireEvent.press(getByText('Open'));
|
|
63
|
+
expect(queryByText('Android month year picker')).toBeDefined();
|
|
64
|
+
|
|
65
|
+
// mock change date
|
|
66
|
+
fireEvent.press(getByText('Android month year picker'));
|
|
67
|
+
expect(queryByText('Android month year picker')).toBeNull();
|
|
68
|
+
expect(onChangeSpy).toBeCalledWith(new Date('2019-09-01'));
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { fireEvent } from '@testing-library/react-native';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
import type { ModalProps } from 'react-native';
|
|
4
|
+
import renderWithTheme from '../../../../testHelpers/renderWithTheme';
|
|
5
|
+
import IOSDialog from '../IOSDialog';
|
|
6
|
+
import { setOrientation } from '../../../../testHelpers/utils';
|
|
7
|
+
import { Button } from '../../../..';
|
|
8
|
+
import { DatePickerDialogProps } from '../type';
|
|
9
|
+
|
|
10
|
+
jest.mock('react-native/Libraries/Modal/Modal', () => {
|
|
11
|
+
const Modal = jest.requireActual('react-native/Libraries/Modal/Modal');
|
|
12
|
+
return (props: ModalProps) => <Modal {...props} />;
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const IOSDialogExample = (
|
|
16
|
+
props: Omit<DatePickerDialogProps, 'open' | 'onClose'>
|
|
17
|
+
) => {
|
|
18
|
+
const [open, setOpen] = useState(false);
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<>
|
|
22
|
+
<Button onPress={() => setOpen(true)} text="Open" />
|
|
23
|
+
<IOSDialog open={open} onClose={() => setOpen(false)} {...props} />
|
|
24
|
+
</>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
describe('IOSDialog', () => {
|
|
29
|
+
it('renders correctly', () => {
|
|
30
|
+
const onChange = jest.fn();
|
|
31
|
+
const { getByText, queryByTestId } = renderWithTheme(
|
|
32
|
+
<IOSDialogExample
|
|
33
|
+
value={new Date('December 21, 1995')}
|
|
34
|
+
label="Start date"
|
|
35
|
+
confirmLabel="Confirm"
|
|
36
|
+
onChange={onChange}
|
|
37
|
+
testID="ios-dialog"
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
expect(queryByTestId('ios-dialog')).toBeNull();
|
|
42
|
+
|
|
43
|
+
// Open date picker
|
|
44
|
+
fireEvent.press(getByText('Open'));
|
|
45
|
+
expect(queryByTestId('datePickerIOS')).toBeTruthy();
|
|
46
|
+
|
|
47
|
+
// Change date
|
|
48
|
+
fireEvent(
|
|
49
|
+
queryByTestId('datePickerIOS'),
|
|
50
|
+
'onChange',
|
|
51
|
+
null,
|
|
52
|
+
new Date('December 17, 1995')
|
|
53
|
+
);
|
|
54
|
+
fireEvent.press(getByText('Confirm'));
|
|
55
|
+
|
|
56
|
+
expect(onChange).toBeCalledWith(new Date('December 17, 1995'));
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('renders correctly in landscape mode', () => {
|
|
60
|
+
const onChange = jest.fn();
|
|
61
|
+
setOrientation('landscape');
|
|
62
|
+
const { getByText, queryByTestId } = renderWithTheme(
|
|
63
|
+
<IOSDialogExample
|
|
64
|
+
value={new Date('December 21, 1995')}
|
|
65
|
+
label="Start date"
|
|
66
|
+
confirmLabel="Confirm"
|
|
67
|
+
onChange={onChange}
|
|
68
|
+
supportedOrientations={['landscape']}
|
|
69
|
+
testID="ios-dialog"
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
expect(queryByTestId('ios-dialog')).toBeNull();
|
|
74
|
+
|
|
75
|
+
// Open date picker
|
|
76
|
+
fireEvent.press(getByText('Open'));
|
|
77
|
+
expect(queryByTestId('datePickerIOS')).toBeTruthy();
|
|
78
|
+
|
|
79
|
+
// Change date
|
|
80
|
+
fireEvent(
|
|
81
|
+
queryByTestId('datePickerIOS'),
|
|
82
|
+
'onChange',
|
|
83
|
+
null,
|
|
84
|
+
new Date('December 17, 1995')
|
|
85
|
+
);
|
|
86
|
+
fireEvent.press(getByText('Confirm'));
|
|
87
|
+
|
|
88
|
+
expect(onChange).toBeCalledWith(new Date('December 17, 1995'));
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('renders month-year picker', () => {
|
|
92
|
+
const onChangeSpy = jest.fn();
|
|
93
|
+
const { queryByText, getByText } = renderWithTheme(
|
|
94
|
+
<IOSDialogExample
|
|
95
|
+
value={new Date('December 21, 1995')}
|
|
96
|
+
variant="month-year"
|
|
97
|
+
label="Start date"
|
|
98
|
+
confirmLabel="Confirm"
|
|
99
|
+
onChange={onChangeSpy}
|
|
100
|
+
testID="ios-dialog"
|
|
101
|
+
/>
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
fireEvent.press(getByText('Open'));
|
|
105
|
+
expect(getByText('Confirm')).toBeDefined();
|
|
106
|
+
expect(getByText('IOS month year picker')).toBeDefined();
|
|
107
|
+
|
|
108
|
+
// mock change date
|
|
109
|
+
fireEvent.press(getByText('IOS month year picker'));
|
|
110
|
+
fireEvent.press(getByText('Confirm'));
|
|
111
|
+
expect(queryByText('iOS month year picker')).toBeNull();
|
|
112
|
+
expect(onChangeSpy).toBeCalledWith(new Date('2019-09-01'));
|
|
113
|
+
});
|
|
114
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface DatePickerDialogProps {
|
|
2
|
+
/**
|
|
3
|
+
* The value of the date picker.
|
|
4
|
+
*/
|
|
5
|
+
value?: Date;
|
|
6
|
+
/**
|
|
7
|
+
* The minimum date of the date picker.
|
|
8
|
+
*/
|
|
9
|
+
minDate?: Date;
|
|
10
|
+
/**
|
|
11
|
+
* The maximum date of the date picker.
|
|
12
|
+
*/
|
|
13
|
+
maxDate?: Date;
|
|
14
|
+
/**
|
|
15
|
+
* The function to call when the date is changed.
|
|
16
|
+
*/
|
|
17
|
+
onChange: (date: Date) => void;
|
|
18
|
+
/**
|
|
19
|
+
* The test ID of the date picker.
|
|
20
|
+
*/
|
|
21
|
+
testID?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Whether the dialog is open
|
|
24
|
+
*/
|
|
25
|
+
open: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* The function to call when the dialog is closed.
|
|
28
|
+
*/
|
|
29
|
+
onClose: () => void;
|
|
30
|
+
/**
|
|
31
|
+
* The variant of the date picker.
|
|
32
|
+
*/
|
|
33
|
+
variant?: 'default' | 'month-year';
|
|
34
|
+
/**
|
|
35
|
+
* [iOS only] The label of the DatePicker bottom sheet.
|
|
36
|
+
*/
|
|
37
|
+
label: string;
|
|
38
|
+
/**
|
|
39
|
+
* [iOS only] The confirm label of the date picker bottom sheet.
|
|
40
|
+
*/
|
|
41
|
+
confirmLabel: string;
|
|
42
|
+
/**
|
|
43
|
+
* [iOS only] The supported orientations of the date picker.
|
|
44
|
+
*/
|
|
45
|
+
supportedOrientations?: ('portrait' | 'landscape')[];
|
|
46
|
+
/**
|
|
47
|
+
* [iOS only] The locale of the date picker.
|
|
48
|
+
*/
|
|
49
|
+
locale?: string;
|
|
50
|
+
}
|
|
@@ -278,15 +278,24 @@ exports[`DatePickerAndroid renders correctly 1`] = `
|
|
|
278
278
|
</View>
|
|
279
279
|
</View>
|
|
280
280
|
</View>
|
|
281
|
-
<
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
281
|
+
<View
|
|
282
|
+
style={
|
|
283
|
+
[
|
|
284
|
+
{},
|
|
285
|
+
undefined,
|
|
286
|
+
]
|
|
287
|
+
}
|
|
288
|
+
>
|
|
289
|
+
<Picker
|
|
290
|
+
display="default"
|
|
291
|
+
maximumDate={1996-12-17T00:00:00.000Z}
|
|
292
|
+
minimumDate={1994-12-17T00:00:00.000Z}
|
|
293
|
+
mode="date"
|
|
294
|
+
onChange={[Function]}
|
|
295
|
+
testID="datePickerAndroid"
|
|
296
|
+
value={1995-12-21T00:00:00.000Z}
|
|
297
|
+
/>
|
|
298
|
+
</View>
|
|
290
299
|
</View>
|
|
291
300
|
<View
|
|
292
301
|
pointerEvents="box-none"
|
|
@@ -4,6 +4,9 @@ import DatePickerAndroid from './DatePickerAndroid';
|
|
|
4
4
|
import DatePickerCalendar from './DatePickerCalendar';
|
|
5
5
|
import DatePickerIOS from './DatePickerIOS';
|
|
6
6
|
import type { DatePickerProps } from './types';
|
|
7
|
+
import IOSDatePickerDialog from './Dialog/IOSDialog';
|
|
8
|
+
import AndroidDatePickerDialog from './Dialog/AndroidDialog';
|
|
9
|
+
import { DatePickerDialogProps } from './Dialog/type';
|
|
7
10
|
|
|
8
11
|
const DatePicker = ({ variant = 'default', ...props }: DatePickerProps) => {
|
|
9
12
|
if (variant === 'calendar') {
|
|
@@ -16,4 +19,12 @@ const DatePicker = ({ variant = 'default', ...props }: DatePickerProps) => {
|
|
|
16
19
|
return <DatePickerAndroid {...props} variant={variant} />;
|
|
17
20
|
};
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
const Dialog = ({ ...props }: DatePickerDialogProps) => {
|
|
23
|
+
if (Platform.OS === 'ios') {
|
|
24
|
+
return <IOSDatePickerDialog {...props} />;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return <AndroidDatePickerDialog {...props} />;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default Object.assign(DatePicker, { Dialog });
|