Skip to content

Commit

Permalink
Create custom-styled DateTimePickerModal
Browse files Browse the repository at this point in the history
- Needed to set the styles.xml colorAccent in order to affecting the picker theme accent color on Android
  - Initial advice from: mmazzarolo/react-native-modal-datetime-picker#106 (comment)
  - Actual solution inspired by: xamarin/Xamarin.Forms#9033 (comment)
  • Loading branch information
High5Apps committed Nov 8, 2023
1 parent 1e8c646 commit f81d3ea
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
1 change: 1 addition & 0 deletions android/app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<!-- Customize your theme here. -->
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
<item name="android:windowBackground">@drawable/window_background</item>
<item name="colorAccent">@color/primary</item>
</style>

</resources>
82 changes: 82 additions & 0 deletions app/components/controls/DateTimePickerModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React, { Dispatch, SetStateAction, useCallback } from 'react';
import { StyleSheet, View } from 'react-native';
import BaseDateTimePickerModal, {
CancelButton, ConfirmButton, CustomCancelButtonPropTypes,
CustomConfirmButtonPropTypes, cancelButtonStyles,
} from 'react-native-modal-datetime-picker';
import useTheme from '../../Theme';

const useStyles = () => {
const { colors, isDarkMode, sizes } = useTheme();

const styles = StyleSheet.create({
customCancelButtonContainerIOS: {
borderColor: colors.separator,
borderWidth: sizes.border,

// Optional chaining is used because cancelButtonStyles only exists on iOS
borderRadius: cancelButtonStyles?.button.borderRadius,
},
customConfirmButtonContainerIOS: {
borderTopColor: colors.separator,
borderTopWidth: sizes.separator,
},
pickerContainerStyleIOS: {
borderColor: colors.separator,
borderWidth: sizes.border,
},
});

return { colors, isDarkMode, styles };
};

type Props = {
dateTime: Date;
setDateTime: Dispatch<SetStateAction<Date>>
setVisible: Dispatch<SetStateAction<boolean>>;
visible: boolean;
};

export default function DateTimePickerModal({
dateTime, setDateTime, setVisible, visible,
}: Props) {
const { colors, isDarkMode, styles } = useStyles();

const CustomCancelButtonIOS = useCallback((
props: CustomCancelButtonPropTypes,
) => (
<View style={styles.customCancelButtonContainerIOS}>
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
<CancelButton {...props} />
</View>
), [styles]);

const CustomConfirmButtonIOS = useCallback((
props: CustomConfirmButtonPropTypes,
) => (
<View style={styles.customConfirmButtonContainerIOS}>
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
<ConfirmButton {...props} />
</View>
), [styles]);

return (
<BaseDateTimePickerModal
buttonTextColorIOS={colors.primary}
accentColor={colors.primary}
customCancelButtonIOS={CustomCancelButtonIOS}
customConfirmButtonIOS={CustomConfirmButtonIOS}
date={dateTime}
display="inline"
isDarkModeEnabled={isDarkMode}
isVisible={visible}
mode="datetime"
onConfirm={(chosenDate) => {
setDateTime(chosenDate);
setVisible(false);
}}
onCancel={() => setVisible(false)}
pickerContainerStyleIOS={styles.pickerContainerStyleIOS}
/>
);
}

0 comments on commit f81d3ea

Please sign in to comment.