forked from mantinedev/mantine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
MantineProvider.tsx
103 lines (89 loc) · 3.16 KB
/
MantineProvider.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import React, { createContext, useContext } from 'react';
import type { EmotionCache } from '@emotion/cache';
import { ThemeProvider, Global } from '@emotion/react';
import { DEFAULT_THEME } from './default-theme';
import { GlobalStyles } from './GlobalStyles';
import { MantineCssVariables } from './MantineCssVariables';
import type { MantineThemeOverride, MantineTheme } from './types';
import { mergeThemeWithFunctions } from './utils/merge-theme/merge-theme';
import { filterProps } from './utils/filter-props/filter-props';
import { NormalizeCSS } from './NormalizeCSS';
interface MantineProviderContextType {
theme: MantineTheme;
emotionCache?: EmotionCache;
}
const MantineProviderContext = createContext<MantineProviderContextType>({
theme: DEFAULT_THEME,
});
export function useMantineTheme() {
return useContext(MantineProviderContext)?.theme || DEFAULT_THEME;
}
export function useMantineProviderStyles(component: string | string[]) {
const theme = useMantineTheme();
const getStyles = (name: string) => ({
styles: theme.components[name]?.styles || {},
classNames: theme.components[name]?.classNames || {},
});
if (Array.isArray(component)) {
return component.map(getStyles);
}
return [getStyles(component)];
}
export function useMantineEmotionCache() {
return useContext(MantineProviderContext)?.emotionCache;
}
export function useComponentDefaultProps<T extends Record<string, any>, U extends Partial<T> = {}>(
component: string,
defaultProps: U,
props: T
): [keyof U] extends [keyof T]
? T
: {
[Key in Exclude<keyof T, keyof U>]: T[Key];
} & {
[Key in Extract<keyof T, keyof U>]-?: U[Key] & T[Key];
} {
const theme = useMantineTheme();
const contextPropsPayload = theme.components[component]?.defaultProps;
const contextProps =
typeof contextPropsPayload === 'function' ? contextPropsPayload(theme) : contextPropsPayload;
return { ...defaultProps, ...contextProps, ...filterProps(props) };
}
export interface MantineProviderProps {
theme?: MantineThemeOverride;
emotionCache?: EmotionCache;
withNormalizeCSS?: boolean;
withGlobalStyles?: boolean;
withCSSVariables?: boolean;
children: React.ReactNode;
inherit?: boolean;
}
export function MantineProvider({
theme,
emotionCache,
withNormalizeCSS = false,
withGlobalStyles = false,
withCSSVariables = false,
inherit = false,
children,
}: MantineProviderProps) {
const ctx = useContext(MantineProviderContext);
const mergedTheme = mergeThemeWithFunctions(
DEFAULT_THEME,
inherit ? { ...ctx.theme, ...theme } : theme
);
return (
<ThemeProvider theme={mergedTheme}>
<MantineProviderContext.Provider value={{ theme: mergedTheme, emotionCache }}>
{withNormalizeCSS && <NormalizeCSS />}
{withGlobalStyles && <GlobalStyles theme={mergedTheme} />}
{withCSSVariables && <MantineCssVariables theme={mergedTheme} />}
{typeof mergedTheme.globalStyles === 'function' && (
<Global styles={mergedTheme.globalStyles(mergedTheme) as any} />
)}
{children}
</MantineProviderContext.Provider>
</ThemeProvider>
);
}
MantineProvider.displayName = '@mantine/core/MantineProvider';