Skip to content

Add accentColor props for iOS datetimepicker (#20) #584

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ jobs:
- android/create-avd:
avd-name: TestingAVD
system-image: system-images;android-29;default;x86
additional-args: --device "pixel_4_xl"
install: true
- android/start-emulator:
avd-name: TestingAVD
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ For cleaning all the detox builds just run `npm run detox:clean`.
```sh
# Debug requires to run Metro Bundler
yarn start
cd "example/ios" && npx pod-install && cd -
yarn detox:ios:build:debug
yarn detox:ios:test:debug
```
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ React Native date & time picker component for iOS, Android and Windows.
- [`dateFormat` (`optional`, `Windows only`)](#dateFormat-optional-windows-only)
- [`firstDayOfWeek` (`optional`, `Windows only`)](#firstDayOfWeek-optional-windows-only)
- [`textColor` (`optional`, `iOS only`)](#textColor-optional-ios-only)
- [`accentColor` (`optional`, `iOS only`)](#accentColor-optional-ios-only)
- [`themeVariant` (`optional`, `iOS only`)](#themevariant-optional-ios-only)
- [`locale` (`optional`, `iOS only`)](#locale-optional-ios-only)
- [`is24Hour` (`optional`, `Windows and Android only`)](#is24hour-optional-windows-and-android-only)
Expand Down Expand Up @@ -387,6 +388,11 @@ Allows changing of the textColor of the date picker. Has effect only when `displ
<RNDateTimePicker textColor="red" />
```

#### `accentColor` (`optional`, `iOs only`)

Allows changing the accentColor (tintColor) of the date picker.
Has not effect when `display` is `"spinner"`.

#### `themeVariant` (`optional`, `iOS only`)

Allows overriding system theme variant (dark or light mode) used by the date picker.
Expand Down
55 changes: 41 additions & 14 deletions example/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import DateTimePicker from '@react-native-community/datetimepicker';
import SegmentedControl from '@react-native-segmented-control/segmented-control';
import {Colors} from 'react-native/Libraries/NewAppScreen';
import React, {useState} from 'react';
import React, {useRef, useState} from 'react';
import {Picker} from 'react-native-windows';
import moment from 'moment';
import {
Expand Down Expand Up @@ -43,7 +43,7 @@ const ThemedTextInput = (props) => {

const TextElement = React.createElement(TextInput, props);
return React.cloneElement(TextElement, {
style: [props.style, textColorByMode],
style: [props.style, styles.textInput, textColorByMode],
placeholderTextColor: isDarkMode ? Colors.white : Colors.black,
});
};
Expand All @@ -68,7 +68,8 @@ export const App = () => {
const [tzOffsetInMinutes, setTzOffsetInMinutes] = useState(undefined);
const [mode, setMode] = useState(MODE_VALUES[0]);
const [show, setShow] = useState(false);
const [color, setColor] = useState();
const [textColor, setTextColor] = useState();
const [accentColor, setAccentColor] = useState();
const [display, setDisplay] = useState(DISPLAY_VALUES[0]);
const [interval, setMinInterval] = useState(1);
const [neutralButtonLabel, setNeutralButtonLabel] = useState(undefined);
Expand All @@ -87,6 +88,8 @@ export const App = () => {
'{dayofweek.abbreviated(2)}',
);

const scrollRef = useRef(null);

const handleResetPress = () => {
setDate(undefined);
};
Expand Down Expand Up @@ -131,7 +134,12 @@ export const App = () => {
return (
<SafeAreaView style={[backgroundStyle, {flex: 1}]}>
<StatusBar barStyle="dark-content" />
<ScrollView testID="DateTimePickerScrollView">
<ScrollView
testID="DateTimePickerScrollView"
ref={scrollRef}
onContentSizeChange={() =>
scrollRef.current?.scrollToEnd({animated: true})
}>
{global.HermesInternal != null && (
<View style={styles.engine}>
<Text testID="hermesIndicator" style={styles.footer}>
Expand Down Expand Up @@ -183,38 +191,48 @@ export const App = () => {
}}
/>
<View style={styles.header}>
<ThemedText style={{margin: 10, flex: 1}}>
<ThemedText style={styles.textLabel}>
text color (iOS only)
</ThemedText>
<ThemedTextInput
value={color}
style={{height: 60, flex: 1}}
value={textColor}
onChangeText={(text) => {
setColor(text.toLowerCase());
setTextColor(text.toLowerCase());
}}
placeholder="color"
placeholder="textColor"
/>
</View>
<View style={styles.header}>
<ThemedText style={{margin: 10, flex: 1}}>
<ThemedText style={styles.textLabel}>
accent color (iOS only)
</ThemedText>
<ThemedTextInput
value={accentColor}
onChangeText={(text) => {
setAccentColor(text.toLowerCase());
}}
placeholder="accentColor"
/>
</View>
<View style={styles.header}>
<ThemedText style={styles.textLabel}>
disabled (iOS only)
</ThemedText>
<Switch value={disabled} onValueChange={setDisabled} />
</View>
<View style={styles.header}>
<ThemedText style={{margin: 10, flex: 1}}>
<ThemedText style={styles.textLabel}>
neutralButtonLabel (android only)
</ThemedText>
<ThemedTextInput
value={neutralButtonLabel}
style={{height: 60, flex: 1}}
onChangeText={setNeutralButtonLabel}
placeholder="neutralButtonLabel"
testID="neutralButtonLabelTextInput"
/>
</View>
<View style={styles.header}>
<ThemedText style={{margin: 10, flex: 1}}>
<ThemedText style={styles.textLabel}>
[android] show and dismiss picker after 3 secs
</ThemedText>
</View>
Expand Down Expand Up @@ -306,7 +324,8 @@ export const App = () => {
display={display}
onChange={onChange}
style={styles.iOsPicker}
textColor={color || undefined}
textColor={textColor || undefined}
accentColor={accentColor || undefined}
neutralButtonLabel={neutralButtonLabel}
disabled={disabled}
/>
Expand Down Expand Up @@ -502,6 +521,14 @@ const styles = StyleSheet.create({
alignItems: 'center',
flexDirection: 'row',
},
textLabel: {
margin: 10,
flex: 1,
},
textInput: {
height: 60,
flex: 1,
},
button: {
alignItems: 'center',
marginBottom: 10,
Expand Down
13 changes: 13 additions & 0 deletions ios/RNDateTimePickerManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,19 @@ + (NSString*) datepickerStyleToString: (UIDatePickerStyle) style API_AVAILABLE(
}
}

RCT_CUSTOM_VIEW_PROPERTY(accentColor, UIColor, RNDateTimePicker)
{
if (json) {
[view setTintColor:[RCTConvert UIColor:json]];
} else {
if (@available(iOS 15.0, *)) {
[view setTintColor:[UIColor tintColor]];
} else {
[view setTintColor:[UIColor systemBlueColor]];
}
}
}

// TODO vonovak setting preferredDatePickerStyle invalidates minuteinterval
RCT_CUSTOM_VIEW_PROPERTY(displayIOS, RNCUIDatePickerStyle, RNDateTimePicker)
{
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
"build": "export RCT_NO_LAUNCH_PACKAGER=true && (cd example/android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug)",
"type": "android.emulator",
"device": {
"avdName": "Pixel_4_Android_12_api_31"
"avdName": "Pixel_5_Android_12_api_31"
}
},
"android.device.debug": {
Expand Down
2 changes: 2 additions & 0 deletions src/datetimepicker.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export default function Picker({
minuteInterval,
timeZoneOffsetInMinutes,
textColor,
accentColor,
themeVariant,
onChange,
mode = ANDROID_MODE.date,
Expand Down Expand Up @@ -126,6 +127,7 @@ export default function Picker({
timeZoneOffsetInMinutes={timeZoneOffsetInMinutes}
onChange={_onChange}
textColor={textColor}
accentColor={accentColor}
themeVariant={themeVariant}
onStartShouldSetResponder={() => true}
onResponderTerminationRequest={() => false}
Expand Down
8 changes: 8 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ export type IOSNativeProps = Readonly<
*/
textColor?: string;

/**
* The date picker accent color.
*
* Sets the color of the selected, date and navigation icons.
* Has no effect for display 'spinner'.
*/
accentColor?: string;

/**
* Override theme variant used by iOS native picker
*/
Expand Down
8 changes: 8 additions & 0 deletions src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ export type IOSNativeProps = $ReadOnly<{|
*/
textColor?: ?ColorValue,

/**
* The date picker accent color.
*
* Sets the color of the selected, date and navigation icons.
* Has no effect for display 'spinner'.
*/
accentColor?: ?ColorValue,

/**
* Override theme variant used by iOS native picker
*/
Expand Down