Skip to content

Commit 14f43f0

Browse files
authored
Allow select scheme to change color scheme manually (#1430)
* add select scheme method * add set scheme method * add getScheme
1 parent d5fc3e3 commit 14f43f0

File tree

6 files changed

+57
-22
lines changed

6 files changed

+57
-22
lines changed

generatedTypes/components/badge/index.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ declare class Badge extends PureComponent<BadgeProps> {
9292
styles: ReturnType<typeof createStyles>;
9393
static displayName: string;
9494
constructor(props: BadgeProps);
95-
get size(): number | "small" | "default" | "pimpleSmall" | "pimpleBig" | "pimpleHuge" | "large";
95+
get size(): number | "default" | "small" | "pimpleSmall" | "pimpleBig" | "pimpleHuge" | "large";
9696
getAccessibilityProps(): {
9797
accessible: boolean;
9898
accessibilityRole: string;
@@ -357,7 +357,7 @@ declare const _default: React.ComponentClass<ViewProps & TouchableOpacityProps &
357357
/**
358358
* the badge size (default, small)
359359
*/
360-
size?: number | "small" | "default" | "pimpleSmall" | "pimpleBig" | "pimpleHuge" | "large" | undefined;
360+
size?: number | "default" | "small" | "pimpleSmall" | "pimpleBig" | "pimpleHuge" | "large" | undefined;
361361
/**
362362
* Press handler
363363
*/

generatedTypes/incubator/TextField/usePreset.d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export default function usePreset({ preset, ...props }: InternalTextFieldProps):
119119
clearTextOnFocus?: boolean | undefined;
120120
dataDetectorTypes?: import("react-native").DataDetectorTypes | import("react-native").DataDetectorTypes[] | undefined;
121121
enablesReturnKeyAutomatically?: boolean | undefined;
122-
keyboardAppearance?: "light" | "dark" | "default" | undefined;
122+
keyboardAppearance?: "default" | "light" | "dark" | undefined;
123123
passwordRules?: string | null | undefined;
124124
rejectResponderTermination?: boolean | null | undefined;
125125
selectionState?: import("react-native").DocumentSelectionState | undefined;
@@ -450,7 +450,7 @@ export default function usePreset({ preset, ...props }: InternalTextFieldProps):
450450
clearTextOnFocus?: boolean | undefined;
451451
dataDetectorTypes?: import("react-native").DataDetectorTypes | import("react-native").DataDetectorTypes[] | undefined;
452452
enablesReturnKeyAutomatically?: boolean | undefined;
453-
keyboardAppearance?: "light" | "dark" | "default" | undefined;
453+
keyboardAppearance?: "default" | "light" | "dark" | undefined;
454454
passwordRules?: string | null | undefined;
455455
rejectResponderTermination?: boolean | null | undefined;
456456
selectionState?: import("react-native").DocumentSelectionState | undefined;
@@ -893,7 +893,7 @@ export default function usePreset({ preset, ...props }: InternalTextFieldProps):
893893
clearTextOnFocus?: boolean | undefined;
894894
dataDetectorTypes?: import("react-native").DataDetectorTypes | import("react-native").DataDetectorTypes[] | undefined;
895895
enablesReturnKeyAutomatically?: boolean | undefined;
896-
keyboardAppearance?: "light" | "dark" | "default" | undefined;
896+
keyboardAppearance?: "default" | "light" | "dark" | undefined;
897897
passwordRules?: string | null | undefined;
898898
rejectResponderTermination?: boolean | null | undefined;
899899
selectionState?: import("react-native").DocumentSelectionState | undefined;

generatedTypes/style/colors.d.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ declare type Schemes = {
88
[key: string]: string;
99
};
1010
};
11+
declare type SchemeType = 'default' | 'light' | 'dark';
1112
export declare class Colors {
1213
[key: string]: any;
1314
schemes: Schemes;
15+
currentScheme: SchemeType;
1416
constructor();
1517
/**
1618
* Load custom set of colors
@@ -26,6 +28,16 @@ export declare class Colors {
2628
* schemes - two sets of map of colors e.g {light: {screen: 'white'}, dark: {screen: 'black'}}
2729
*/
2830
loadSchemes(schemes: Schemes): void;
31+
/**
32+
* Get app's current color scheme
33+
*/
34+
getScheme(): 'light' | 'dark';
35+
/**
36+
* Set color scheme for app
37+
* arguments:
38+
* scheme - color scheme e.g light/dark/default
39+
*/
40+
setScheme(scheme: SchemeType): void;
2941
/**
3042
* Add alpha to hex or rgb color
3143
* arguments:
@@ -118,18 +130,13 @@ declare const colorObject: Colors & {
118130
purple20: string;
119131
purple30: string;
120132
purple40: string;
121-
/**
122-
* Add alpha to hex or rgb color
123-
* arguments:
124-
* p1 - hex color / R part of RGB
125-
* p2 - opacity / G part of RGB
126-
* p3 - B part of RGB
127-
* p4 - opacity
128-
*/
129133
purple50: string;
130134
purple60: string;
131135
purple70: string;
132136
purple80: string;
137+
/**
138+
* Get app's current color scheme
139+
*/
133140
violet10: string;
134141
violet20: string;
135142
violet30: string;

src/commons/asBaseComponent.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@ function asBaseComponent<PROPS, STATICS = {}>(WrappedComponent: React.ComponentT
3737
Appearance.removeChangeListener(this.appearanceListener);
3838
}
3939

40-
appearanceListener: Appearance.AppearanceListener = ({colorScheme}) => {
41-
this.setState({colorScheme});
40+
appearanceListener: Appearance.AppearanceListener = () => {
41+
// iOS 13 and above will trigger this call with the wrong colorScheme value. So just ignore returned colorScheme for now
42+
// https://github.com/facebook/react-native/issues/28525
43+
this.setState({colorScheme: Appearance.getColorScheme()});
4244
};
4345

4446
static getThemeProps = (props: any, context: any) => {

src/commons/modifiers.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import _ from 'lodash';
2-
import {Appearance, StyleSheet} from 'react-native';
2+
import {StyleSheet} from 'react-native';
33
import {Typography, Colors, BorderRadiuses, Spacings, ThemeManager} from '../style';
44
import {BorderRadiusesLiterals} from '../style/borderRadiuses';
55
import TypographyPresets from '../style/typographyPresets';
@@ -97,7 +97,7 @@ export type ContainerModifiers =
9797
BackgroundColorModifier;
9898

9999
export function extractColorValue(props: Dictionary<any>) {
100-
const scheme = Appearance.getColorScheme() || 'light';
100+
const scheme = Colors.getScheme();
101101
const schemeColors = Colors.schemes[scheme];
102102
const allColorsKeys: Array<keyof typeof Colors> = [..._.keys(Colors), ..._.keys(schemeColors)];
103103
const colorPropsKeys = _.chain(props)
@@ -110,7 +110,7 @@ export function extractColorValue(props: Dictionary<any>) {
110110

111111
export function extractBackgroundColorValue(props: Dictionary<any>) {
112112
let backgroundColor;
113-
const scheme = Appearance.getColorScheme() || 'light';
113+
const scheme = Colors.getScheme();
114114
const schemeColors = Colors.schemes[scheme];
115115

116116
const keys = Object.keys(props);

src/style/colors.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,21 @@ import {colorsPalette, themeColors} from './colorsPalette';
88
import ColorName from './colorName';
99

1010
type Schemes = {light: {[key: string]: string}; dark: {[key: string]: string}};
11+
type SchemeType = 'default' | 'light' | 'dark'
1112

1213
export class Colors {
1314
[key: string]: any;
1415
schemes: Schemes = {light: {}, dark: {}};
16+
currentScheme: SchemeType = 'default';
1517

1618
constructor() {
1719
const colors = Object.assign(colorsPalette, themeColors);
1820
Object.assign(this, colors);
1921

20-
Appearance.addChangeListener(({colorScheme}: Appearance.AppearancePreferences) => {
21-
Object.assign(this, this.schemes[colorScheme ?? 'light']);
22+
Appearance.addChangeListener(() => {
23+
if (this.currentScheme === 'default') {
24+
Object.assign(this, this.schemes[Appearance.getColorScheme() ?? 'light']);
25+
}
2226
});
2327
}
2428
/**
@@ -46,8 +50,30 @@ export class Colors {
4650
}
4751

4852
this.schemes = schemes;
49-
const colorScheme = Appearance.getColorScheme();
50-
Object.assign(this, this.schemes[colorScheme ?? 'light']);
53+
const colorScheme = this.getScheme();
54+
Object.assign(this, this.schemes[colorScheme]);
55+
}
56+
57+
/**
58+
* Get app's current color scheme
59+
*/
60+
getScheme(): 'light' | 'dark' {
61+
const scheme = this.currentScheme === 'default' ? Appearance.getColorScheme() : this.currentScheme;
62+
return scheme ?? 'light';
63+
}
64+
65+
/**
66+
* Set color scheme for app
67+
* arguments:
68+
* scheme - color scheme e.g light/dark/default
69+
*/
70+
setScheme(scheme: SchemeType) {
71+
if (!['light', 'dark', 'default'].includes(scheme)) {
72+
throw new Error(`${scheme} is invalid colorScheme, please use 'light' | 'dark' | 'default'`);
73+
}
74+
this.currentScheme = scheme;
75+
const colorScheme = this.getScheme();
76+
Object.assign(this, this.schemes[colorScheme]);
5177
}
5278

5379
/**

0 commit comments

Comments
 (0)