Skip to content

Commit 69d5b33

Browse files
authored
feat: Allow overriding theme variant used by native ios picker (#354)
1 parent 64d0603 commit 69d5b33

File tree

6 files changed

+60
-13
lines changed

6 files changed

+60
-13
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ If set to false, the specific item will be disabled, i.e. the user will not be a
387387
- [`itemStyle`](#itemstyle)
388388
- [`onValueChange`](#onvaluechange)
389389
- [`selectedValue`](#selectedvalue)
390+
- [`themeVariant`](#themeVariant)
390391

391392
---
392393

@@ -416,4 +417,10 @@ If set to false, the specific item will be disabled, i.e. the user will not be a
416417
| ---- | -------- |
417418
| any | No |
418419

419-
420+
---
421+
422+
### `themeVariant`
423+
424+
| Type | Required |
425+
| ---- | -------- |
426+
| enum('light', 'dark') | No |

example/src/PickerExample.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,35 @@ function NoListenerPickerExample() {
165165
);
166166
}
167167

168+
function ThemeVariantOverridePickerExample() {
169+
const [themeVariantValue, setThemeVariantValue] = React.useState('dark');
170+
const isDarkMode = themeVariantValue === 'dark';
171+
172+
const handleSelect = ({nativeEvent: {newValue}}) =>
173+
setThemeVariantValue(newValue);
174+
175+
return (
176+
<View style={{backgroundColor: isDarkMode ? 'black' : 'transparent'}}>
177+
<Picker
178+
selectedValue={themeVariantValue}
179+
selectedColor={'white'}
180+
themeVariant={themeVariantValue}
181+
onChange={handleSelect}>
182+
<Item
183+
color={isDarkMode ? 'white' : 'black'}
184+
label="Dark mode"
185+
value="dark"
186+
/>
187+
<Item
188+
color={isDarkMode ? 'white' : 'black'}
189+
label="Light mode"
190+
value="light"
191+
/>
192+
</Picker>
193+
</View>
194+
);
195+
}
196+
168197
function ColorPickerExample() {
169198
const [value, setValue] = React.useState('red');
170199
const [isFocused, setIsFocused] = React.useState(false);
@@ -245,6 +274,10 @@ export const examples = [
245274
title: 'Styled Picker',
246275
render: StyledPickerExample,
247276
},
277+
{
278+
title: 'Picker with overrided theme variant',
279+
render: ThemeVariantOverridePickerExample,
280+
},
248281
{
249282
title: 'Disabled Picker',
250283
render: DisabledPickerExample,

ios/RNCPickerManager.m

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,18 @@ - (UIView *)view
4242
{
4343
view.font = [RCTFont updateFont:view.font withFamily:json ?: defaultView.font.familyName];
4444
}
45+
RCT_CUSTOM_VIEW_PROPERTY(themeVariant, NSString, RNCPicker)
46+
{
47+
if (@available(iOS 13.4, *)) {
48+
if (json) {
49+
if ([json isEqual:@"dark"])
50+
view.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
51+
else if ([json isEqual:@"light"])
52+
view.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
53+
else
54+
view.overrideUserInterfaceStyle = UIUserInterfaceStyleUnspecified;
55+
}
56+
}
57+
}
4558

4659
@end

js/PickerIOS.ios.js

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import * as React from 'react';
1717
import {processColor, StyleSheet, View} from 'react-native';
1818
import RNCPickerNativeComponent from './RNCPickerNativeComponent';
19+
import type {RNCPickerIOSType} from './RNCPickerNativeComponent';
1920

2021
import type {SyntheticEvent} from 'react-native/Libraries/Types/CoreEventTypes';
2122
import type {ColorValue} from 'react-native/Libraries/StyleSheet/StyleSheet';
@@ -38,17 +39,6 @@ type RNCPickerIOSItemType = $ReadOnly<{|
3839
testID: ?string,
3940
|}>;
4041

41-
type RNCPickerIOSType = HostComponent<
42-
$ReadOnly<{|
43-
items: $ReadOnlyArray<RNCPickerIOSItemType>,
44-
onChange: (event: PickerIOSChangeEvent) => void,
45-
selectedIndex: number,
46-
style?: ?TextStyleProp,
47-
testID?: ?string,
48-
numberOfLines?: ?number,
49-
|}>,
50-
>;
51-
5242
type Label = Stringish | number;
5343

5444
type Props = $ReadOnly<{|
@@ -59,6 +49,7 @@ type Props = $ReadOnly<{|
5949
onValueChange?: ?(itemValue: string | number, itemIndex: number) => mixed,
6050
selectedValue: ?(number | string),
6151
numberOfLines: ?number,
52+
themeVariant: ?string,
6253
|}>;
6354

6455
type State = {|
@@ -115,6 +106,7 @@ class PickerIOS extends React.Component<Props, State> {
115106
ref={(picker) => {
116107
this._picker = picker;
117108
}}
109+
themeVariant={this.props.themeVariant}
118110
testID={this.props.testID}
119111
style={[styles.pickerIOS, this.props.itemStyle]}
120112
items={this.state.items}

js/RNCPickerNativeComponent.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,15 @@ type RNCPickerIOSTypeItemType = $ReadOnly<{|
3131

3232
type Label = Stringish | number;
3333

34-
type RNCPickerIOSType = HostComponent<
34+
export type RNCPickerIOSType = HostComponent<
3535
$ReadOnly<{|
3636
items: $ReadOnlyArray<RNCPickerIOSTypeItemType>,
3737
onChange: (event: PickerIOSChangeEvent) => void,
3838
selectedIndex: number,
3939
style?: ?TextStyleProp,
4040
testID?: ?string,
4141
numberOfLines?: ?number,
42+
themeVariant?: ?string,
4243
|}>,
4344
>;
4445

typings/PickerIOS.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export interface PickerIOSProps extends ViewProps {
1919
selectedValue?: ItemValue;
2020
testID?: string;
2121
numberOfLines?: number;
22+
themeVariant ?: string;
2223
}
2324

2425
declare class PickerIOS extends React.Component<PickerIOSProps, {}> {

0 commit comments

Comments
 (0)