my fork of the bluesky client
1import React, {createContext, ReactNode, useContext} from 'react'
2import {TextStyle, ViewStyle} from 'react-native'
3
4import {ThemeName} from '#/alf/types'
5import {darkTheme, defaultTheme, dimTheme} from './themes'
6
7export type ColorScheme = 'light' | 'dark'
8
9export type PaletteColorName =
10 | 'default'
11 | 'primary'
12 | 'secondary'
13 | 'inverted'
14 | 'error'
15export type PaletteColor = {
16 background: string
17 backgroundLight: string
18 text: string
19 textLight: string
20 textInverted: string
21 link: string
22 border: string
23 borderDark: string
24 icon: string
25 [k: string]: string
26}
27export type Palette = Record<PaletteColorName, PaletteColor>
28
29export type ShapeName = 'button' | 'bigButton' | 'smallButton'
30export type Shapes = Record<ShapeName, ViewStyle>
31
32export type TypographyVariant =
33 | '2xl-thin'
34 | '2xl'
35 | '2xl-medium'
36 | '2xl-bold'
37 | '2xl-heavy'
38 | 'xl-thin'
39 | 'xl'
40 | 'xl-medium'
41 | 'xl-bold'
42 | 'xl-heavy'
43 | 'lg-thin'
44 | 'lg'
45 | 'lg-medium'
46 | 'lg-bold'
47 | 'lg-heavy'
48 | 'md-thin'
49 | 'md'
50 | 'md-medium'
51 | 'md-bold'
52 | 'md-heavy'
53 | 'sm-thin'
54 | 'sm'
55 | 'sm-medium'
56 | 'sm-bold'
57 | 'sm-heavy'
58 | 'xs-thin'
59 | 'xs'
60 | 'xs-medium'
61 | 'xs-bold'
62 | 'xs-heavy'
63 | 'title-2xl'
64 | 'title-xl'
65 | 'title-lg'
66 | 'title'
67 | 'title-sm'
68 | 'post-text-lg'
69 | 'post-text'
70 | 'button'
71 | 'button-lg'
72 | 'mono'
73export type Typography = Record<TypographyVariant, TextStyle>
74
75export interface Theme {
76 colorScheme: ColorScheme
77 palette: Palette
78 shapes: Shapes
79 typography: Typography
80}
81
82export interface ThemeProviderProps {
83 children?: ReactNode
84 theme: ThemeName
85}
86
87export const ThemeContext = createContext<Theme>(defaultTheme)
88
89export const useTheme = () => useContext(ThemeContext)
90
91function getTheme(theme: ThemeName) {
92 switch (theme) {
93 case 'light':
94 return defaultTheme
95 case 'dim':
96 return dimTheme
97 case 'dark':
98 return darkTheme
99 default:
100 return defaultTheme
101 }
102}
103
104export const ThemeProvider: React.FC<ThemeProviderProps> = ({
105 theme,
106 children,
107}) => {
108 const themeValue = getTheme(theme)
109
110 return (
111 <ThemeContext.Provider value={themeValue}>{children}</ThemeContext.Provider>
112 )
113}