Skip to content

Commit d625a6e

Browse files
authored
Proper typography support in themes (#964)
* Update default theme typography to match defaults in platform codegen * Don't limit to node 18 * Proper theme typography types + revamped theme validation with zod * Fix bugs, simplify proxy, and add tests * Use named object paramters for `createThemeValuesProxy` * Unset persistent selected theme when it does not exist
1 parent 2e54b2b commit d625a6e

File tree

13 files changed

+588
-346
lines changed

13 files changed

+588
-346
lines changed

example/src/App.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,11 @@ const DarkTheme = createTheme({
188188
strong: "white",
189189
},
190190
},
191-
typography: {},
191+
typography: {
192+
body1: {
193+
fontWeight: "bold",
194+
},
195+
},
192196
},
193197
baseTheme: BaseTheme,
194198
});
@@ -225,7 +229,11 @@ const OtherTheme = createTheme({
225229
brand: "#FDAF7B",
226230
},
227231
},
228-
typography: {},
232+
typography: {
233+
body1: {
234+
fontStyle: "italic",
235+
},
236+
},
229237
},
230238
baseTheme: BaseTheme,
231239
});

example/src/ThemeExample.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react";
22
import Section, { Container } from "./Section";
3-
import { View } from "react-native";
3+
import { View, Text } from "react-native";
44
import {
55
AudioPlayer,
66
Button,
@@ -58,6 +58,13 @@ const VideoPlayerExample: React.FC = () => {
5858
}}
5959
/>
6060
</Section>
61+
<Section style={{}} title="Typography">
62+
<Text
63+
style={[theme.typography.body1, { color: theme.colors.text.strong }]}
64+
>
65+
This is a test of the typography system.
66+
</Text>
67+
</Section>
6168
<Section style={{}} title="Light/Dark Color">
6269
<View
6370
style={{

package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,5 @@
134134
"not samsung <= 4"
135135
],
136136
"node": "16"
137-
},
138-
"engines": {
139-
"node": "18.x"
140137
}
141138
}

packages/theme/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@
4141
"dependencies": {
4242
"@react-native-async-storage/async-storage": "1.21.0",
4343
"color": "^4.2.3",
44-
"deepmerge": "^4.3.1",
45-
"lodash.isobject": "^3.0.2",
46-
"react-native-typography": "^1.4.1"
44+
"deepmerge-ts": "^7.1.3",
45+
"react-native-typography": "^1.4.1",
46+
"zod": "^3.23.8"
4747
},
4848
"eslintIgnore": [
4949
"node_modules/",

packages/theme/src/DefaultTheme.ts

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -64,84 +64,84 @@ const DraftbitTheme = createTheme({
6464
},
6565
},
6666
typography: {
67-
headline1: {
67+
body1: {
6868
...systemWeights.regular,
69+
fontSize: 16,
70+
letterSpacing: 0,
71+
lineHeight: 26,
72+
},
73+
body2: {
74+
...systemWeights.regular,
75+
fontSize: 14,
76+
letterSpacing: 0,
77+
lineHeight: 22,
78+
},
79+
button: {
80+
...systemWeights.bold,
81+
fontSize: 14,
82+
letterSpacing: 0,
83+
lineHeight: 16,
84+
},
85+
caption: {
86+
...systemWeights.regular,
87+
fontSize: 12,
88+
letterSpacing: 0,
89+
lineHeight: 16,
90+
},
91+
headline1: {
92+
...systemWeights.bold,
6993
fontSize: 60,
7094
letterSpacing: 0,
7195
lineHeight: 71,
7296
},
7397
headline2: {
74-
...systemWeights.regular,
98+
...systemWeights.bold,
7599
fontSize: 48,
76100
letterSpacing: 0,
77101
lineHeight: 58,
78102
},
79103
headline3: {
80-
...systemWeights.regular,
104+
...systemWeights.bold,
81105
fontSize: 34,
82106
letterSpacing: 0,
83107
lineHeight: 40,
84108
},
85109
headline4: {
86-
...systemWeights.regular,
110+
...systemWeights.bold,
87111
fontSize: 24,
88112
letterSpacing: 0,
89113
lineHeight: 34,
90114
},
91115
headline5: {
92-
...systemWeights.regular,
116+
...systemWeights.bold,
93117
fontSize: 20,
94118
letterSpacing: 0,
95119
lineHeight: 26,
96120
},
97-
subtitle1: {
98-
...systemWeights.regular,
121+
headline6: {
122+
...systemWeights.bold,
99123
fontSize: 16,
100124
letterSpacing: 0,
101-
lineHeight: 26,
125+
lineHeight: 24,
102126
},
103-
subtitle2: {
127+
overline: {
104128
...systemWeights.regular,
105-
fontSize: 14,
106-
letterSpacing: 0,
107-
lineHeight: 22,
129+
fontSize: 12,
130+
letterSpacing: 2,
131+
lineHeight: 16,
108132
},
109-
body1: {
133+
subtitle1: {
110134
...systemWeights.regular,
111135
fontSize: 16,
112136
letterSpacing: 0,
113137
lineHeight: 26,
114138
},
115-
body2: {
139+
subtitle2: {
116140
...systemWeights.regular,
117141
fontSize: 14,
118142
letterSpacing: 0,
119143
lineHeight: 22,
120144
},
121-
button: {
122-
...systemWeights.regular,
123-
fontSize: 14,
124-
letterSpacing: 0,
125-
lineHeight: 16,
126-
},
127-
caption: {
128-
...systemWeights.regular,
129-
fontSize: 12,
130-
letterSpacing: 0,
131-
lineHeight: 16,
132-
},
133-
overline: {
134-
...systemWeights.regular,
135-
fontSize: 12,
136-
letterSpacing: 2,
137-
lineHeight: 16,
138-
},
139-
headline6: {
140-
...systemWeights.regular,
141-
fontSize: 16,
142-
letterSpacing: 0,
143-
lineHeight: 24,
144-
},
145145
},
146146
},
147147
});

packages/theme/src/Provider.tsx

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
Breakpoints,
88
ChangeThemeOptions,
99
ReadTheme,
10+
ThemeValues,
1011
ValidatedTheme,
1112
} from "./types";
1213

@@ -66,49 +67,28 @@ const Provider: React.FC<React.PropsWithChildren<ProviderProps>> = ({
6667
[themes, setCurrentTheme]
6768
);
6869

69-
const proxiedTheme: ReadTheme = React.useMemo(
70-
() => ({
70+
const proxiedTheme: ReadTheme = React.useMemo(() => {
71+
const createProxiedThemeValue = (value: ThemeValues | undefined) =>
72+
createThemeValuesProxy({
73+
value,
74+
breakpoints,
75+
deviceWidth,
76+
devicePlatform: Platform.OS,
77+
currentLightDarkSelection: lightDarkSelection,
78+
});
79+
80+
return {
7181
...currentTheme,
7282
colors: {
73-
branding: createThemeValuesProxy(
74-
currentTheme.colors.branding,
75-
breakpoints,
76-
deviceWidth,
77-
Platform.OS,
78-
lightDarkSelection
79-
),
80-
text: createThemeValuesProxy(
81-
currentTheme.colors.text,
82-
breakpoints,
83-
deviceWidth,
84-
Platform.OS,
85-
lightDarkSelection
86-
),
87-
background: createThemeValuesProxy(
88-
currentTheme.colors.background,
89-
breakpoints,
90-
deviceWidth,
91-
Platform.OS,
92-
lightDarkSelection
93-
),
94-
foreground: createThemeValuesProxy(
95-
currentTheme.colors.foreground,
96-
breakpoints,
97-
deviceWidth,
98-
Platform.OS,
99-
lightDarkSelection
100-
),
101-
border: createThemeValuesProxy(
102-
currentTheme.colors.border,
103-
breakpoints,
104-
deviceWidth,
105-
Platform.OS,
106-
lightDarkSelection
107-
),
83+
branding: createProxiedThemeValue(currentTheme.colors.branding),
84+
text: createProxiedThemeValue(currentTheme.colors.text),
85+
background: createProxiedThemeValue(currentTheme.colors.background),
86+
foreground: createProxiedThemeValue(currentTheme.colors.foreground),
87+
border: createProxiedThemeValue(currentTheme.colors.border),
10888
},
109-
}),
110-
[currentTheme, deviceWidth, breakpoints, lightDarkSelection]
111-
);
89+
typography: createProxiedThemeValue(currentTheme.typography),
90+
};
91+
}, [currentTheme, deviceWidth, breakpoints, lightDarkSelection]);
11292

11393
React.useEffect(() => {
11494
const listener = Dimensions.addEventListener("change", ({ window }) =>
@@ -124,8 +104,16 @@ const Provider: React.FC<React.PropsWithChildren<ProviderProps>> = ({
124104
const savedSelectedThemeName = await AsyncStorage.getItem(
125105
SAVED_SELECTED_THEME_KEY
126106
);
107+
const themeExists = themes.some((t) => t.name === savedSelectedThemeName);
108+
127109
if (savedSelectedThemeName) {
128-
changeTheme(savedSelectedThemeName);
110+
if (themeExists) {
111+
changeTheme(savedSelectedThemeName);
112+
} else {
113+
AsyncStorage.removeItem(SAVED_SELECTED_THEME_KEY).catch((e) => {
114+
console.warn("Failed to reset persisted selected theme", e);
115+
});
116+
}
129117
}
130118
};
131119
run();

0 commit comments

Comments
 (0)