-
Notifications
You must be signed in to change notification settings - Fork 2.8k
/
withEnvironment.tsx
72 lines (58 loc) · 2.7 KB
/
withEnvironment.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
import type {ComponentType, ForwardedRef, ReactElement, ReactNode, RefAttributes} from 'react';
import React, {createContext, forwardRef, useContext, useEffect, useMemo, useState} from 'react';
import type {ValueOf} from 'type-fest';
import * as Environment from '@libs/Environment/Environment';
import getComponentDisplayName from '@libs/getComponentDisplayName';
import CONST from '@src/CONST';
type EnvironmentProviderProps = {
/** Actual content wrapped by this component */
children: ReactNode;
};
type EnvironmentValue = ValueOf<typeof CONST.ENVIRONMENT>;
type EnvironmentContextValue = {
/** The string value representing the current environment */
environment: EnvironmentValue;
/** The string value representing the URL of the current environment */
environmentURL: string;
};
const EnvironmentContext = createContext<EnvironmentContextValue>({
environment: CONST.ENVIRONMENT.PRODUCTION,
environmentURL: CONST.NEW_EXPENSIFY_URL,
});
function EnvironmentProvider({children}: EnvironmentProviderProps): ReactElement {
const [environment, setEnvironment] = useState<EnvironmentValue>(CONST.ENVIRONMENT.PRODUCTION);
const [environmentURL, setEnvironmentURL] = useState(CONST.NEW_EXPENSIFY_URL);
useEffect(() => {
Environment.getEnvironment().then(setEnvironment);
Environment.getEnvironmentURL().then(setEnvironmentURL);
}, []);
const contextValue = useMemo(
(): EnvironmentContextValue => ({
environment,
environmentURL,
}),
[environment, environmentURL],
);
return <EnvironmentContext.Provider value={contextValue}>{children}</EnvironmentContext.Provider>;
}
EnvironmentProvider.displayName = 'EnvironmentProvider';
export default function withEnvironment<TProps extends EnvironmentContextValue, TRef>(
WrappedComponent: ComponentType<TProps & RefAttributes<TRef>>,
): (props: Omit<TProps, keyof EnvironmentContextValue> & React.RefAttributes<TRef>) => ReactElement | null {
function WithEnvironment(props: Omit<TProps, keyof EnvironmentContextValue>, ref: ForwardedRef<TRef>): ReactElement {
const {environment, environmentURL} = useContext(EnvironmentContext);
return (
<WrappedComponent
// eslint-disable-next-line react/jsx-props-no-spreading
{...(props as TProps)}
ref={ref}
environment={environment}
environmentURL={environmentURL}
/>
);
}
WithEnvironment.displayName = `withEnvironment(${getComponentDisplayName(WrappedComponent)})`;
return forwardRef(WithEnvironment);
}
export {EnvironmentContext, EnvironmentProvider};
export type {EnvironmentContextValue};