|
3 | 3 | * |
4 | 4 | * Dark and light themes with consistent styling. |
5 | 5 | * Optimized for readability and streaming performance. |
| 6 | + * |
| 7 | + * Font-agnostic: Uses platform defaults for text, allowing host apps |
| 8 | + * to set their own fonts. Only monospace is specified for code blocks. |
6 | 9 | */ |
7 | 10 |
|
8 | 11 | import { Platform } from 'react-native'; |
@@ -56,17 +59,12 @@ const lightColors: ThemeColors = { |
56 | 59 | // Font Configuration |
57 | 60 | // ============================================================================ |
58 | 61 |
|
| 62 | +// Font-agnostic: undefined lets React Native use platform defaults |
| 63 | +// This allows host apps to set fonts at the root level and have them inherited |
| 64 | +// Only monospace is specified for code blocks |
59 | 65 | const fonts = { |
60 | | - regular: Platform.select({ |
61 | | - ios: 'System', |
62 | | - android: 'System', |
63 | | - default: 'System', |
64 | | - }) as string, |
65 | | - bold: Platform.select({ |
66 | | - ios: 'System', |
67 | | - android: 'System', |
68 | | - default: 'System', |
69 | | - }) as string, |
| 66 | + regular: undefined as string | undefined, |
| 67 | + bold: undefined as string | undefined, |
70 | 68 | mono: Platform.select({ |
71 | 69 | ios: 'Menlo', |
72 | 70 | android: 'monospace', |
@@ -114,79 +112,87 @@ export function getTheme(theme: 'dark' | 'light' | ThemeConfig): ThemeConfig { |
114 | 112 |
|
115 | 113 | /** |
116 | 114 | * Generate text styles for a theme |
| 115 | + * |
| 116 | + * Font-agnostic: Only applies fontFamily when explicitly set in theme. |
| 117 | + * This allows host apps to set fonts at the root level and have them inherited. |
117 | 118 | */ |
118 | 119 | export function getTextStyles(theme: ThemeConfig) { |
| 120 | + // Helper to conditionally include fontFamily |
| 121 | + const withFont = (fontKey: 'regular' | 'bold' | 'mono') => |
| 122 | + theme.fonts[fontKey] ? { fontFamily: theme.fonts[fontKey] } : {}; |
| 123 | + |
119 | 124 | return { |
120 | 125 | body: { |
121 | 126 | color: theme.colors.foreground, |
122 | | - fontFamily: theme.fonts.regular, |
| 127 | + ...withFont('regular'), |
123 | 128 | fontSize: 16, |
124 | 129 | lineHeight: 24, |
125 | 130 | }, |
126 | 131 | heading1: { |
127 | 132 | color: theme.colors.foreground, |
128 | | - fontFamily: theme.fonts.bold, |
| 133 | + ...withFont('bold'), |
129 | 134 | fontSize: 28, |
130 | 135 | lineHeight: 36, |
131 | 136 | fontWeight: 'bold' as const, |
132 | 137 | marginBottom: theme.spacing.block, |
133 | 138 | }, |
134 | 139 | heading2: { |
135 | 140 | color: theme.colors.foreground, |
136 | | - fontFamily: theme.fonts.bold, |
| 141 | + ...withFont('bold'), |
137 | 142 | fontSize: 24, |
138 | 143 | lineHeight: 32, |
139 | 144 | fontWeight: 'bold' as const, |
140 | 145 | marginBottom: theme.spacing.block, |
141 | 146 | }, |
142 | 147 | heading3: { |
143 | 148 | color: theme.colors.foreground, |
144 | | - fontFamily: theme.fonts.bold, |
| 149 | + ...withFont('bold'), |
145 | 150 | fontSize: 20, |
146 | 151 | lineHeight: 28, |
147 | 152 | fontWeight: 'bold' as const, |
148 | 153 | marginBottom: theme.spacing.block, |
149 | 154 | }, |
150 | 155 | heading4: { |
151 | 156 | color: theme.colors.foreground, |
152 | | - fontFamily: theme.fonts.bold, |
| 157 | + ...withFont('bold'), |
153 | 158 | fontSize: 18, |
154 | 159 | lineHeight: 26, |
155 | 160 | fontWeight: 'bold' as const, |
156 | 161 | marginBottom: theme.spacing.block, |
157 | 162 | }, |
158 | 163 | heading5: { |
159 | 164 | color: theme.colors.foreground, |
160 | | - fontFamily: theme.fonts.bold, |
| 165 | + ...withFont('bold'), |
161 | 166 | fontSize: 16, |
162 | 167 | lineHeight: 24, |
163 | 168 | fontWeight: 'bold' as const, |
164 | 169 | marginBottom: theme.spacing.block, |
165 | 170 | }, |
166 | 171 | heading6: { |
167 | 172 | color: theme.colors.foreground, |
168 | | - fontFamily: theme.fonts.bold, |
| 173 | + ...withFont('bold'), |
169 | 174 | fontSize: 14, |
170 | 175 | lineHeight: 22, |
171 | 176 | fontWeight: 'bold' as const, |
172 | 177 | marginBottom: theme.spacing.block, |
173 | 178 | }, |
174 | 179 | paragraph: { |
175 | 180 | color: theme.colors.foreground, |
176 | | - fontFamily: theme.fonts.regular, |
| 181 | + ...withFont('regular'), |
177 | 182 | fontSize: 16, |
178 | 183 | lineHeight: 24, |
179 | 184 | marginBottom: theme.spacing.block, |
180 | 185 | }, |
181 | 186 | bold: { |
182 | | - fontFamily: theme.fonts.bold, |
| 187 | + ...withFont('bold'), |
183 | 188 | fontWeight: 'bold' as const, |
184 | 189 | }, |
185 | 190 | italic: { |
186 | 191 | fontStyle: 'italic' as const, |
| 192 | + // No fontFamily - inherits from parent, allowing platform italic to work |
187 | 193 | }, |
188 | 194 | code: { |
189 | | - fontFamily: theme.fonts.mono, |
| 195 | + ...withFont('mono'), |
190 | 196 | fontSize: 14, |
191 | 197 | color: theme.colors.codeForeground, |
192 | 198 | backgroundColor: theme.colors.codeBackground, |
|
0 commit comments