-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
49 lines (43 loc) · 1.61 KB
/
index.ts
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
import { Context, createContext, useContext } from 'react';
import Id from './Id';
import Environment, { unwrap } from './Environment';
import IdContextConsumer, { createIdContextConsumer } from './Consumer';
import IdContextProvider, { createIdContextProvider } from './Provider';
/**
* A privately scoped unique symbol for accessing {@link IdContext} internal {@link Environment}
* @internal
*/
const kEnvironment = Symbol('kEnvironment');
/**
* A Context with support for multiple keyed values
*/
export default interface IdContext<T> {
Consumer: IdContextConsumer<T>;
Provider: IdContextProvider<T>;
/** @internal */
[kEnvironment]: Context<Environment<T>>;
}
/**
* Creates a keyed Context allowing multiple nested Providers to be accessible in the same scope.
* @param defaultValue the value consumed if no {@link IdContextProvider} is in scope and the
* {@link IdContextConsumerProps.id | consumer `id`} is `null`
*/
export function createIdContext<T>(defaultValue: T): IdContext<T> {
const EnvironmentContext = createContext<Environment<T>>(
new Map([[null, defaultValue]]),
);
return {
Consumer: createIdContextConsumer(EnvironmentContext),
Provider: createIdContextProvider(EnvironmentContext),
[kEnvironment]: EnvironmentContext,
};
}
/**
* Consumes a value from an {@link IdContextProvider}
* @param context the {@link IdContext} to use
* @param id the {@link IdContextProviderProps.id | IdContextProvider id} to use
*/
export function useIdContext<T>(context: IdContext<T>, id?: Id): T {
const env = useContext(context[kEnvironment]);
return unwrap(env, id != null ? id : null);
}