Skip to content

Commit

Permalink
feat: add accentColor prop for iOS (#584)
Browse files Browse the repository at this point in the history
* Add accentColor props for iOs datetimepicker (#20)

* Fix rename to accentColor

* Fix e2e tests.

Scroll to bottom when rendering a date picker.
Ensure the date picker is shown.

* Fix e2e test.

Label Time Picker is used two times in dependency Tree.
Find element by type.

* Remove code duplications in expample app.

* Remove not needed View Tag from example app.

* Shorten command with "cd -"

Co-authored-by: Vojtech Novak <vonovak@gmail.com>

* Use bigger device for android.

* Test: List aviable devices

* Use Pixel 4 XL for android e2e Tests

* Fix use pixel 4 xl

* Revert getInlineTimePickerIOS selection

* Revert rename of android.device.debug.binaryPath

Co-authored-by: Vojtech Novak <vonovak@gmail.com>

* Fix error in package.json

* Fix grammar

Co-authored-by: Vojtech Novak <vonovak@gmail.com>

* Fix spelling of iOS

Co-authored-by: Vojtech Novak <vonovak@gmail.com>

* Scroll to datepicker only on iOS

Co-authored-by: Simon Nagl <johndoe@example.com>
Co-authored-by: Vojtech Novak <vonovak@gmail.com>
  • Loading branch information
3 people committed Mar 22, 2022
1 parent ac4ce89 commit dcda13c
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 15 deletions.
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 @@ -389,6 +390,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 no 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
57 changes: 43 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,14 @@ export const App = () => {
return (
<SafeAreaView style={[backgroundStyle, {flex: 1}]}>
<StatusBar barStyle="dark-content" />
<ScrollView testID="DateTimePickerScrollView">
<ScrollView
testID="DateTimePickerScrollView"
ref={scrollRef}
onContentSizeChange={() => {
if (Platform.OS === 'ios') {
scrollRef.current?.scrollToEnd({animated: true});
}
}}>
{global.HermesInternal != null && (
<View style={styles.engine}>
<Text testID="hermesIndicator" style={styles.footer}>
Expand Down Expand Up @@ -183,38 +193,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 +326,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 +523,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

0 comments on commit dcda13c

Please sign in to comment.