Skip to content

Commit ba17fc0

Browse files
authored
Infra/date time picker allow migration to new dialog (#2945)
* Fix NumberInput API * DateTimePicker - allow migration to new the Dialog via migrateDialog * Add type keyword and prettify
1 parent d143fb8 commit ba17fc0

File tree

5 files changed

+107
-104
lines changed

5 files changed

+107
-104
lines changed

demo/src/screens/componentScreens/DateTimePickerScreen.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,14 @@ export default class DateTimePickerScreen extends Component<{}, State> {
6262
<View padding-page>
6363
<Text text40>Date Time Picker</Text>
6464
<DateTimePicker
65+
migrateDialog
6566
containerStyle={{marginVertical: 20}}
6667
label={'Date'}
6768
placeholder={'Select a date'}
6869
// value={new Date('October 13, 2014')}
6970
/>
7071
<DateTimePicker
72+
migrateDialog
7173
mode={'time'}
7274
label={'Time'}
7375
placeholder={'Select time'}
@@ -78,12 +80,14 @@ export default class DateTimePickerScreen extends Component<{}, State> {
7880
Disabled
7981
</Text>
8082
<DateTimePicker
83+
migrateDialog
8184
containerStyle={{marginBottom: 20}}
8285
editable={false}
8386
label={'Date'}
8487
placeholder={'Select a date'}
8588
/>
8689
<DateTimePicker
90+
migrateDialog
8791
editable={false}
8892
mode={'time'}
8993
label={'Time'}
@@ -104,6 +108,7 @@ export default class DateTimePickerScreen extends Component<{}, State> {
104108
</View>
105109
</View>
106110
<DateTimePicker
111+
migrateDialog
107112
containerStyle={{marginVertical: 20}}
108113
renderInput={this.renderCustomInput}
109114
mode={mode}

src/components/dateTimePicker/index.tsx

Lines changed: 74 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {Colors} from '../../style';
1515
import Assets from '../../assets';
1616
import {Constants, asBaseComponent, BaseComponentInjectedProps} from '../../commons/new';
1717
import TextField, {TextFieldProps, TextFieldMethods} from '../textField';
18+
import type {DialogMigrationProps} from '../../incubator/Dialog';
1819
import {DialogProps} from '../dialog';
1920
import View from '../view';
2021
import Button from '../button';
@@ -23,78 +24,76 @@ import useOldApi, {OldApiProps} from './useOldApi';
2324

2425
export type DateTimePickerMode = 'date' | 'time';
2526

26-
export type DateTimePickerProps = OldApiProps & Omit<TextFieldProps, 'value' | 'onChange'> & {
27-
/**
28-
* The type of picker to display ('date' or 'time')
29-
*/
30-
mode?: DateTimePickerMode;
31-
/**
32-
* The initial value to set the picker to. Defaults to device's date / time
33-
*/
34-
value?: Date;
35-
/**
36-
* The onChange callback
37-
*/
38-
onChange?: (date: Date) => void;
39-
/**
40-
* Should this input be editable or disabled
41-
*/
42-
editable?: boolean;
43-
/**
44-
* The minimum date or time value to use
45-
*/
46-
minimumDate?: Date;
47-
/**
48-
* The maximum date or time value to use
49-
*/
50-
maximumDate?: Date;
51-
/**
52-
* A callback function to format the time or date
53-
* @param mode the type of the picker ('date' or 'time')
54-
* @returns the formatted string to display
55-
*/
56-
dateTimeFormatter?: (value: Date, mode: DateTimePickerMode) => string;
57-
/**
58-
* Allows changing of the locale of the component (iOS only)
59-
*/
60-
locale?: string;
61-
/**
62-
* Allows changing of the time picker to a 24 hour format (Android only)
63-
*/
64-
is24Hour?: boolean;
65-
/**
66-
* The interval at which minutes can be selected. Possible values are: 1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30 (iOS only)
67-
*/
68-
minuteInterval?: number;
69-
/**
70-
* Allows changing of the timeZone of the date picker. By default it uses the device's time zone (iOS only)
71-
*/
72-
timeZoneOffsetInMinutes?: number;
73-
/**
74-
* Props to pass the Dialog component
75-
*/
76-
dialogProps?: DialogProps;
77-
/**
78-
* style to apply to the iOS dialog header
79-
*/
80-
headerStyle?: StyleProp<ViewStyle>;
81-
/**
82-
* Render custom input
83-
*/
84-
renderInput?: (props: Omit<DateTimePickerProps, 'value'> & {value?: string}) => React.ReactElement;
85-
/**
86-
* Override system theme variant (dark or light mode) used by the date picker.
87-
*/
88-
themeVariant?: 'light' | 'dark';
89-
/**
90-
* The component testID
91-
*/
92-
testID?: string;
93-
/**
94-
* Allows changing the visual display of the picker
95-
*/
96-
display?: string;
97-
};
27+
export type DateTimePickerProps = OldApiProps &
28+
Omit<TextFieldProps, 'value' | 'onChange'> &
29+
DialogMigrationProps & {
30+
/**
31+
* The type of picker to display ('date' or 'time')
32+
*/
33+
mode?: DateTimePickerMode;
34+
/**
35+
* The initial value to set the picker to. Defaults to device's date / time
36+
*/
37+
value?: Date;
38+
/**
39+
* The onChange callback
40+
*/
41+
onChange?: (date: Date) => void;
42+
/**
43+
* Should this input be editable or disabled
44+
*/
45+
editable?: boolean;
46+
/**
47+
* The minimum date or time value to use
48+
*/
49+
minimumDate?: Date;
50+
/**
51+
* The maximum date or time value to use
52+
*/
53+
maximumDate?: Date;
54+
/**
55+
* A callback function to format the time or date
56+
* @param mode the type of the picker ('date' or 'time')
57+
* @returns the formatted string to display
58+
*/
59+
dateTimeFormatter?: (value: Date, mode: DateTimePickerMode) => string;
60+
/**
61+
* Allows changing of the locale of the component (iOS only)
62+
*/
63+
locale?: string;
64+
/**
65+
* Allows changing of the time picker to a 24 hour format (Android only)
66+
*/
67+
is24Hour?: boolean;
68+
/**
69+
* The interval at which minutes can be selected. Possible values are: 1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30 (iOS only)
70+
*/
71+
minuteInterval?: number;
72+
/**
73+
* Allows changing of the timeZone of the date picker. By default it uses the device's time zone (iOS only)
74+
*/
75+
timeZoneOffsetInMinutes?: number;
76+
/**
77+
* style to apply to the iOS dialog header
78+
*/
79+
headerStyle?: StyleProp<ViewStyle>;
80+
/**
81+
* Render custom input
82+
*/
83+
renderInput?: (props: Omit<DateTimePickerProps, 'value'> & {value?: string}) => React.ReactElement;
84+
/**
85+
* Override system theme variant (dark or light mode) used by the date picker.
86+
*/
87+
themeVariant?: 'light' | 'dark';
88+
/**
89+
* The component testID
90+
*/
91+
testID?: string;
92+
/**
93+
* Allows changing the visual display of the picker
94+
*/
95+
display?: string;
96+
};
9897

9998
type DateTimePickerPropsInternal = DateTimePickerProps & BaseComponentInjectedProps;
10099

@@ -128,6 +127,7 @@ const DateTimePicker = forwardRef((props: DateTimePickerPropsInternal, ref: Forw
128127
themeVariant = Colors.getScheme(),
129128
onChange,
130129
dialogProps,
130+
migrateDialog,
131131
headerStyle,
132132
testID,
133133
display = Constants.isIOS ? 'spinner' : undefined,
@@ -234,12 +234,7 @@ const DateTimePicker = forwardRef((props: DateTimePickerPropsInternal, ref: Forw
234234
onPress={toggleExpandableOverlay}
235235
testID={`${testID}.cancel`}
236236
/>
237-
<Button
238-
link
239-
iconSource={Assets.icons.check}
240-
onPress={onDonePressed}
241-
testID={`${testID}.done`}
242-
/>
237+
<Button link iconSource={Assets.icons.check} onPress={onDonePressed} testID={`${testID}.done`}/>
243238
</View>
244239
);
245240
};
@@ -302,6 +297,7 @@ const DateTimePicker = forwardRef((props: DateTimePickerPropsInternal, ref: Forw
302297
expandableContent={Constants.isIOS ? renderIOSExpandableOverlay() : undefined}
303298
useDialog
304299
dialogProps={_dialogProps}
300+
migrateDialog={migrateDialog}
305301
disabled={editable === false}
306302
// NOTE: Android picker comes with its own overlay built-in therefor we're not using ExpandableOverlay for it
307303
renderCustomOverlay={Constants.isAndroid ? renderAndroidDateTimePicker : undefined}

src/incubator/Dialog/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ import Modal from '../../components/modal';
2424
import {extractAlignmentsValues} from '../../commons/modifiers';
2525
import useHiddenLocation from '../hooks/useHiddenLocation';
2626
import DialogHeader from './DialogHeader';
27-
import {DialogProps, DialogDirections, DialogDirectionsEnum, DialogHeaderProps} from './types';
28-
export {DialogProps, DialogDirections, DialogDirectionsEnum, DialogHeaderProps};
27+
import {DialogProps, DialogDirections, DialogDirectionsEnum, DialogHeaderProps, DialogMigrationProps} from './types';
28+
export {DialogProps, DialogDirections, DialogDirectionsEnum, DialogHeaderProps, DialogMigrationProps};
2929

3030
const THRESHOLD_VELOCITY = 750;
3131

src/incubator/Dialog/types.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {PropsWithChildren, ReactElement} from 'react';
22
import {StyleProp, TextStyle, ViewStyle} from 'react-native';
33
import {AlignmentModifiers} from '../../commons/modifiers';
4+
import {DialogProps as DialogPropsOld} from '../../components/dialog';
45
import {ModalProps} from '../../components/modal';
56
import {ViewProps} from '../../components/view';
67
import {TextProps} from '../../components/text';
@@ -122,3 +123,25 @@ export interface _DialogProps extends AlignmentModifiers, Pick<ViewProps, 'useSa
122123
}
123124

124125
export type DialogProps = PropsWithChildren<_DialogProps>;
126+
127+
// For migration purposes
128+
export interface _DialogPropsOld {
129+
/**
130+
* The props to pass to the dialog expandable container
131+
*/
132+
dialogProps?: DialogPropsOld;
133+
migrateDialog?: false;
134+
}
135+
136+
export interface _DialogPropsNew {
137+
/**
138+
* The props to pass to the dialog expandable container
139+
*/
140+
dialogProps?: DialogProps;
141+
/**
142+
* Migrate the Dialog to DialogNew (make sure you use only new props in dialogProps)
143+
*/
144+
migrateDialog: true;
145+
}
146+
147+
export type DialogMigrationProps = _DialogPropsOld | _DialogPropsNew;

src/incubator/expandableOverlay/index.tsx

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import React, {useCallback, useState, forwardRef, PropsWithChildren, useImperati
33
import TouchableOpacity, {TouchableOpacityProps} from '../../components/touchableOpacity';
44
import View from '../../components/view';
55
import Modal, {ModalProps, ModalTopBarProps} from '../../components/modal';
6-
import DialogOld, {DialogProps as DialogPropsOld} from '../../components/dialog';
7-
import DialogNew, {DialogProps as DialogPropsNew} from '../Dialog';
6+
import DialogOld from '../../components/dialog';
7+
import DialogNew, {DialogMigrationProps} from '../Dialog';
88
import {Colors} from 'style';
99

1010
export interface ExpandableOverlayMethods {
@@ -17,29 +17,8 @@ export interface RenderCustomOverlayProps extends ExpandableOverlayMethods {
1717
visible: boolean;
1818
}
1919

20-
export interface _DialogPropsOld {
21-
/**
22-
* The props to pass to the dialog expandable container
23-
*/
24-
dialogProps?: DialogPropsOld;
25-
migrateDialog?: false;
26-
}
27-
28-
export interface _DialogPropsNew {
29-
/**
30-
* The props to pass to the dialog expandable container
31-
*/
32-
dialogProps?: DialogPropsNew;
33-
/**
34-
* Migrate the Dialog to DialogNew (make sure you use only new props in dialogProps)
35-
*/
36-
migrateDialog: true;
37-
}
38-
39-
export type DialogProps = _DialogPropsOld | _DialogPropsNew;
40-
4120
export type ExpandableOverlayProps = TouchableOpacityProps &
42-
DialogProps &
21+
DialogMigrationProps &
4322
PropsWithChildren<{
4423
/**
4524
* The content to render inside the expandable modal/dialog

0 commit comments

Comments
 (0)