-
Notifications
You must be signed in to change notification settings - Fork 45
/
Theme.tsx
88 lines (75 loc) · 2.58 KB
/
Theme.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import React, { useContext } from "react"
import { GridThemeProvider as StyledGridThemeProvider } from "styled-bootstrap-grid"
// FIXME: Upgrading styled-components types to get `ThemeContext` breaks many other typings.
// Notably: `Icon` and `Sans|Serif`
// @ts-expect-error MIGRATE_STRICT_MODE
import { ThemeContext, ThemeProvider } from "styled-components"
import { Theme as TTheme, THEME_V2, THEME_V3, ThemeV2, ThemeV3 } from "./themes"
export { THEME_V2, THEME_V3 } from "./themes"
export * from "@artsy/palette-tokens/dist/themes/v2"
export { TextVariant } from "@artsy/palette-tokens/dist/typography/types"
/**
* Creates a new Grid context for web. This glues the v2 grid theme into any other theme.
*/
const GridThemeProvider = ({ children }) => {
return (
<StyledGridThemeProvider gridTheme={THEME_V2.grid}>
{children}
</StyledGridThemeProvider>
)
}
const THEMES = {
v2: THEME_V2,
v3: THEME_V3,
}
/**
* A wrapper component for passing down the Artsy theme context
*/
export const Theme: React.FC<{ theme?: TTheme | keyof typeof THEMES }> = ({
children,
theme: themeOrThemeKey = THEME_V2,
}) => {
const theme =
themeOrThemeKey === "v2" || themeOrThemeKey === "v3"
? THEMES[themeOrThemeKey]
: themeOrThemeKey
return (
<ThemeProvider theme={theme}>
<GridThemeProvider>{children}</GridThemeProvider>
</ThemeProvider>
)
}
/** Utilize only the v2 theme */
export const ThemeProviderV2: React.FC = ({ children }) => {
return <ThemeProvider theme={THEME_V2}>{children}</ThemeProvider>
}
/** Utilize only the v3 theme */
export const ThemeProviderV3: React.FC = ({ children }) => {
return <ThemeProvider theme={THEME_V3}>{children}</ThemeProvider>
}
/** Returns the current theme */
export const useTheme = <T extends TTheme>() => {
const theme: T = useContext(ThemeContext)
return { theme }
}
/** Returns a config specific to the current theme. For use in React components */
export const useThemeConfig = <T, U>({ v2, v3 }: { v2: T; v3: U }): U | T => {
const { theme = { id: "v2" } } = useTheme()
return theme.id === "v2" ? v2 : v3
}
/** Returns a config specific to the current theme. For use in styled-components */
export const getThemeConfig = <T, U>(
props: Record<string, any>,
{ v2, v3 }: { v2: T; v3: U }
): U | T => {
const { theme = { id: "v2" } } = props
return theme.id === "v2" ? v2 : v3
}
/** Typeguard for v2 */
export const isThemeV2 = (theme: TTheme): theme is ThemeV2 => {
return theme.id === "v2"
}
/** Typeguard for v3 */
export const isThemeV3 = (theme: TTheme): theme is ThemeV3 => {
return theme.id === "v3"
}