-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
49 lines (43 loc) · 1.64 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 Id from '../IdContext/Id';
import State from './State';
import IdContext, { createIdContext, useIdContext } from '../IdContext';
import StateContextConsumer, { createStateContextConsumer } from './Consumer';
import StateContextProvider, { createStateContextProvider } from './Provider';
/**
* A privately scoped unique symbol for accessing {@link StateContext} internal {@link State}
* @internal
*/
const kState = Symbol('kState');
/**
* A State Context with support for multiple keyed values
*/
export default interface StateContext<T> {
Consumer: StateContextConsumer<T>;
Provider: StateContextProvider<T>;
/** @internal */
[kState]: IdContext<State<T>>;
}
const defaultDispatch = () => undefined;
/**
* Creates a State Context for providing a stateful value and a function to update it.
* @param defaultValue the value consumed if no {@link StateContextProvider} is in scope and the
* {@link StateContextConsumerProps.id | consumer `id`} is `null`
*/
export function createStateContext<T>(defaultValue: T): StateContext<T> {
const StateContext = createIdContext<State<T>>(
[defaultValue, defaultDispatch],
);
return {
Consumer: createStateContextConsumer(StateContext),
Provider: createStateContextProvider(StateContext),
[kState]: StateContext,
};
}
/**
* Consumes a stateful value from a {@link StateContextProvider}, and a function to update it
* @param context the {@link StateContext} to use
* @param id the {@link StateContextProviderProps.id | StateContextProvider id} to use
*/
export function useStateContext<T>(context: StateContext<T>, id?: Id): State<T> {
return useIdContext(context[kState], id);
}