-
Notifications
You must be signed in to change notification settings - Fork 842
/
Copy pathhooks.tsx
118 lines (103 loc) · 3.27 KB
/
hooks.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React, { forwardRef, useContext, useMemo } from 'react';
import {
EuiThemeContext,
EuiModificationsContext,
EuiColorModeContext,
defaultComputedTheme,
EuiNestedThemeContext,
} from './context';
import { emitEuiProviderWarning } from './warning';
import {
EuiThemeColorModeStandard,
EuiThemeModifications,
EuiThemeComputed,
} from './types';
const providerMessage = `\`EuiProvider\` is missing which can result in negative effects.
Wrap your component in \`EuiProvider\`: https://ela.st/euiprovider.`;
/**
* Hook for function components
*/
export interface UseEuiTheme<T extends {} = {}> {
euiTheme: EuiThemeComputed<T>;
colorMode: EuiThemeColorModeStandard;
modifications: EuiThemeModifications<T>;
}
export const useEuiTheme = <T extends {} = {}>(): UseEuiTheme<T> => {
const theme = useContext(EuiThemeContext);
const colorMode = useContext(EuiColorModeContext);
const modifications = useContext(EuiModificationsContext);
const isFallback = theme === defaultComputedTheme;
if (isFallback) {
emitEuiProviderWarning(providerMessage);
}
const assembledTheme = useMemo(
() => ({
euiTheme: theme as EuiThemeComputed<T>,
colorMode,
modifications: modifications as EuiThemeModifications<T>,
}),
[theme, colorMode, modifications]
);
return assembledTheme;
};
/**
* HOC for class components
*/
export interface WithEuiThemeProps<P extends {} = {}> {
theme: UseEuiTheme<P>;
}
// Provide the component props interface as the generic to allow the docs props table to populate.
// e.g., `const EuiComponent = withEuiTheme<EuiComponentProps>(_EuiComponent)`
export const withEuiTheme = <T extends {} = {}, U extends {} = {}>(
Component: React.ComponentType<T & WithEuiThemeProps<U>>
) => {
const componentName =
Component.displayName || Component.name || 'ComponentWithTheme';
const Render = (
props: Omit<T, keyof WithEuiThemeProps<U>>,
ref: React.Ref<Omit<T, keyof WithEuiThemeProps<U>>>
) => {
const theme = useEuiTheme<U>();
return <Component theme={theme} ref={ref} {...(props as T)} />;
};
const WithEuiTheme = forwardRef(Render);
WithEuiTheme.displayName = componentName;
return WithEuiTheme;
};
/**
* Render prop alternative for complex class components
* Most useful for scenarios where a HOC may interfere with typing
*/
export const RenderWithEuiTheme = <T extends {} = {}>({
children,
}: {
children: (theme: UseEuiTheme) => React.ReactElement;
}) => {
const theme = useEuiTheme<T>();
return children(theme);
};
/**
* Minor syntactical sugar hook for theme CSS variables.
* Primarily meant for internal EUI usage.
*/
export const useEuiThemeCSSVariables = () => {
const {
setGlobalCSSVariables,
globalCSSVariables,
setNearestThemeCSSVariables,
themeCSSVariables,
} = useContext(EuiNestedThemeContext);
return {
setGlobalCSSVariables,
globalCSSVariables,
setNearestThemeCSSVariables,
themeCSSVariables,
};
};