(undefined);
-
-// If in the future there can be more than two color modes we want to ensure that
-// our light/dark are always applied correctly.
-const getColorScheme = (c: ColorSchemeName): ColorScheme =>
- c === 'dark' ? 'dark' : 'light';
-
-export function ColorModeProvider({ children }: { children: ReactNode }) {
- const systemColorMode = useColorScheme();
- const [persistedColorMode, setPersistedColorMode] = useStorageString(
- STORAGE_KEYS.COLOR_MODE
- );
-
- const colorMode = (persistedColorMode || 'auto') as ColorMode;
-
- let colorScheme: ColorScheme;
-
- if (colorMode === 'auto') {
- colorScheme = getColorScheme(systemColorMode);
- } else if (colorMode === 'dark') {
- colorScheme = 'dark';
- } else {
- colorScheme = 'light';
- }
-
- const theme = colorScheme === 'light' ? lightTheme : darkTheme;
-
- return (
-
- {children}
-
- );
-}
-
-export const useColorMode = () => {
- const context = useContext(ColorModeContext);
- if (!context) throw new Error('Missing ColorModeProvider!');
- return context;
-};
diff --git a/src/styles/helpers.ts b/src/styles/helpers.ts
deleted file mode 100644
index 78ffe21b..00000000
--- a/src/styles/helpers.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-import * as typographyTokens from '../design-system/typography';
-import { theme, type Theme } from './styled';
-
-type Typography = keyof typeof typographyTokens;
-type ThemeKey = keyof Theme;
-
-/**
- * Generate all variants for a given theme key, eg:
- * ```
- * themeProp('color', 'colors', (color) => ({ color }))
- * ```
- * would generate a variant prop called `color` with all color values from theme:
- * {
- * color: {
- * primary: { color: '$primary' },
- * secondary: { color: '$secondary' },
- * text: { color: '$text' },
- * etc...
- * }
- * }
- */
-export function themeProp(
- prop: P,
- themeKey: T,
- getStyles: (token: string) => R
-) {
- const values: Record> = { [prop]: {} };
-
- Object.values(theme[themeKey]).forEach(({ token }) => {
- values[prop][token] = getStyles(`$${token}`);
- });
-
- return values as {
- [K in P]: { [TK in keyof Theme[T]]: R };
- };
-}
-
-/**
- * Automatically generate Text component typography variants from design tokens.
- * Also add `withLineHeight` prop to control when to apply line height.
- * {
- * variant: {
- * title1: { typography: '$title1' },
- * title2: { typography: '$title2' },
- * body: { typography: '$body' },
- * etc...
- * }
- * }
- */
-type TypographyVariant = {
- typography: Typography;
- lineHeight: number;
-};
-
-type CompoundVariant = {
- variant: Typography;
- withLineHeight: boolean;
- css: { lineHeight: string };
-};
-
-type DefaultVariants = {
- variant: Typography;
- withLineHeight: boolean;
-};
-
-export function getTextTypographyVariants() {
- const typographyVariants: Record =
- {} as Record;
-
- const compoundVariants: CompoundVariant[] = [];
-
- const defaultVariants: DefaultVariants = {
- variant: 'body',
- withLineHeight: false,
- };
-
- (Object.keys(typographyTokens) as Typography[]).forEach((variant) => {
- typographyVariants[variant] = {
- typography: variant,
- // Apply line height only for multiline text since by default app UI text
- // should not have a line height bigger than `1` (same as font size)
- lineHeight: typographyTokens[variant].fontSize,
- };
-
- compoundVariants.push({
- variant,
- withLineHeight: true,
- css: {
- lineHeight: `$${variant}`,
- },
- });
- });
-
- return {
- compoundVariants,
- defaultVariants,
- variants: {
- variant: typographyVariants,
- // NOTE: styles can be empty here since we use this value in compoundVariants
- // to set the correct line height from theme based on the `variant` prop
- withLineHeight: { true: {}, false: {} },
- },
- };
-}
diff --git a/src/styles/index.ts b/src/styles/index.ts
deleted file mode 100644
index eb0725fd..00000000
--- a/src/styles/index.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import * as stitches from './styled';
-
-const { styled, css, createTheme, useTheme, theme, ThemeProvider, darkTheme } =
- stitches;
-
-export type {
- Theme,
- Color,
- Space,
- Radii,
- LineHeight,
- Typography,
-} from './styled';
-
-export { themeProp, getTextTypographyVariants } from './helpers';
-export { styled, css, createTheme, useTheme, theme, ThemeProvider, darkTheme };
diff --git a/src/styles/styled.ts b/src/styles/styled.ts
index 7700562a..ae2825e5 100644
--- a/src/styles/styled.ts
+++ b/src/styles/styled.ts
@@ -1,43 +1,74 @@
-import { StyleSheet } from 'react-native';
-import type * as Stitches from 'stitches-native';
-import { createStitches } from 'stitches-native';
+import { StyleSheet } from 'react-native-unistyles';
import * as colors from '~design-system/colors';
import * as radii from '~design-system/radii';
+import * as shadows from '~design-system/shadows';
import space from '~design-system/spacing.json';
import * as typography from '~design-system/typography';
import * as designSystemUtils from '~design-system/utils';
-import * as utils from './utils';
-
-const { styled, css, createTheme, config, theme, useTheme, ThemeProvider } =
- createStitches({
- theme: {
- colors: designSystemUtils.transformColors(colors),
- radii: { ...radii, none: 0 },
- space: { ...space, none: 0 },
- sizes: { hairlineWidth: StyleSheet.hairlineWidth },
- fonts: designSystemUtils.getFonts(typography),
- fontSizes: designSystemUtils.getFontSizes(typography),
- fontWeights: designSystemUtils.getFontWeights(typography),
- letterSpacings: designSystemUtils.getLetterSpacings(typography), // prettier-ignore
- lineHeights: designSystemUtils.getLineHeights(typography),
- },
- utils,
- });
-
-export const darkTheme = createTheme({
- colors: designSystemUtils.transformColors(colors), // TODO: add dark theme support once we get dark mode colors from Figma
+import { absoluteFill, flexCenter } from './utils';
+
+const typographyTokens = typography as Typography;
+
+const lightTheme = {
+ typography: typographyTokens,
+ colors: designSystemUtils.transformColors(colors),
+ radii: { ...radii, none: 0 },
+ space: { ...space, none: 0 },
+ sizes: { hairlineWidth: StyleSheet.hairlineWidth },
+ fonts: designSystemUtils.getFonts(typographyTokens),
+ fontSizes: designSystemUtils.getFontSizes(typographyTokens),
+ fontWeights: designSystemUtils.getFontWeights(typographyTokens),
+ letterSpacings: designSystemUtils.getLetterSpacings(typographyTokens), // prettier-ignore
+ lineHeights: designSystemUtils.getLineHeights(typographyTokens),
+ shadows: designSystemUtils.getShadows(shadows),
+ utils: {
+ absoluteFill,
+ flexCenter,
+ },
+};
+
+const appThemes = {
+ light: lightTheme,
+ dark: lightTheme, // TODO: Add dark theme when available
+};
+
+const breakpoints = {
+ xs: 0,
+ sm: 300,
+ md: 500,
+ lg: 800,
+ xl: 1200,
+};
+
+type AppBreakpoints = typeof breakpoints;
+export type AppThemes = typeof appThemes;
+export type Theme = AppThemes[keyof AppThemes];
+
+export type Typography = Record<
+ T,
+ designSystemUtils.TypographyDefinition
+>;
+export type Color = keyof AppThemes['light']['colors'];
+export type Space = keyof AppThemes['light']['space'];
+export type Radii = keyof AppThemes['light']['radii'];
+export type Fonts = keyof AppThemes['light']['fonts'];
+export type FontSize = keyof AppThemes['light']['fontSizes'];
+export type FontWeight = keyof AppThemes['light']['fontWeights'];
+export type LetterSpace = keyof AppThemes['light']['letterSpacings'];
+export type LineHeight = keyof AppThemes['light']['lineHeights'];
+declare module 'react-native-unistyles' {
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
+ export interface UnistylesThemes extends AppThemes {}
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
+ export interface UnistylesBreakpoints extends AppBreakpoints {}
+}
+
+StyleSheet.configure({
+ themes: appThemes,
+ breakpoints,
+ settings: {
+ initialTheme: 'light',
+ },
});
-export { styled, css, createTheme, useTheme, config, theme, ThemeProvider };
-export type CSS = Stitches.CSS;
-export type Theme = typeof theme;
-export type Typography = keyof typeof typography;
-export type Color = keyof Theme['colors'];
-export type Space = keyof Theme['space'];
-export type Radii = keyof Theme['radii'];
-export type Fonts = keyof Theme['fonts'];
-export type FontSize = keyof Theme['fontSizes'];
-export type FontWeight = keyof Theme['fontWeights'];
-export type LetterSpace = keyof Theme['letterSpacings'];
-export type LineHeight = keyof Theme['lineHeights'];
diff --git a/src/styles/utils.ts b/src/styles/utils.ts
index 606e43b1..2c352eea 100644
--- a/src/styles/utils.ts
+++ b/src/styles/utils.ts
@@ -1,53 +1,44 @@
-import { StyleSheet } from 'react-native';
-import type * as Stitches from 'stitches-native';
+import { type ViewStyle } from 'react-native';
+import { StyleSheet } from 'react-native-unistyles';
-import * as shadows from '~design-system/shadows';
import * as typographyTokens from '~design-system/typography';
import * as designSystemUtils from '~design-system/utils';
-type Typography = keyof typeof typographyTokens;
+import { type AppThemes } from './styled';
-export const typography = (variant: Typography) => {
- const { fontWeight, textTransform } = typographyTokens[variant];
-
- return {
- fontFamily: `$${designSystemUtils.getFontFromWeight(fontWeight)}`,
- fontSize: `$${variant}`,
- fontWeight: `$${variant}`,
- letterSpacing: `$${variant}`,
- lineHeight: `$${variant}`,
- textTransform,
- };
+type FlexCenter = {
+ flexDirection: ViewStyle['flexDirection'];
+ justifyContent: ViewStyle['justifyContent'];
+ alignItems: ViewStyle['alignItems'];
};
-export const size = (value: Stitches.PropertyValue<'width'>) => ({
- width: value,
- height: value,
-});
-
-export const shadow = (
- level: 'none' | designSystemUtils.ShadowName
+export const typography = (
+ theme: AppThemes['light'],
+ variant: typographyTokens.TypographyToken
) => {
+ const { fontWeight, textTransform } = typographyTokens[variant];
+
return {
- none: {
- elevation: 0,
- shadowOffset: { width: 0, height: 0 },
- shadowRadius: 0,
- shadowOpacity: 0,
- shadowColor: '#000',
- },
- ...designSystemUtils.getShadows(shadows),
- }[level];
+ fontFamily: `${designSystemUtils.getFontFromWeight(fontWeight)}`,
+ fontSize: theme.fontSizes[variant],
+ fontWeight: theme.fontWeights[variant],
+ letterSpacing: theme.letterSpacings[variant],
+ lineHeight: theme.lineHeights[variant],
+ textTransform,
+ } as designSystemUtils.TypographyDefinition;
};
-export const flexCenter = (
- value?: Stitches.PropertyValue<'flexDirection'>
-) => ({
- flexDirection: value || 'column',
+export const flexCenter: FlexCenter = {
+ flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
-});
+};
-export const absoluteFill = () => ({
- ...StyleSheet.absoluteFillObject,
-});
+export const absoluteFill = StyleSheet.absoluteFillObject;
+
+export const getTypography = (
+ theme: AppThemes['light'],
+ variant: typographyTokens.TypographyToken
+): designSystemUtils.TypographyDefinition => {
+ return typography(theme, variant);
+};
diff --git a/src/types/declarations.d.ts b/src/types/declarations.d.ts
new file mode 100644
index 00000000..9530fc6f
--- /dev/null
+++ b/src/types/declarations.d.ts
@@ -0,0 +1,14 @@
+declare module '*.jpg' {
+ const value: ImageSourcePropType | undefined;
+ export default value;
+}
+
+declare module '*.png' {
+ const value: ImageSourcePropType | undefined;
+ export default value;
+}
+
+declare module '*.ttf' {
+ const src: FontSource;
+ export default src;
+}
diff --git a/src/utils/navigation.tsx b/src/utils/navigation.tsx
index e2935873..07e7ac4b 100644
--- a/src/utils/navigation.tsx
+++ b/src/utils/navigation.tsx
@@ -6,8 +6,7 @@ import {
import { type NativeStackNavigationOptions } from '@react-navigation/native-stack';
import { useNavigation } from 'expo-router';
import { useEffect } from 'react';
-
-import { useTheme } from '~styles';
+import { useUnistyles } from 'react-native-unistyles';
export function getActiveRouteName(
state: NavigationState | PartialState
@@ -20,7 +19,7 @@ export function getActiveRouteName(
export function useDefaultStackScreenOptions() {
const { t } = useLingui();
- const theme = useTheme();
+ const { theme } = useUnistyles();
const screenOptions: NativeStackNavigationOptions = {
headerStyle: {
diff --git a/tsconfig.json b/tsconfig.json
index f2682572..9eea95b7 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -8,6 +8,7 @@
"strictNullChecks": true,
"noImplicitAny": true,
"noFallthroughCasesInSwitch": true,
+ "resolveJsonModule": true,
"skipLibCheck": true
},
"include": ["**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", "expo-env.d.ts"]