-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c3956e4
commit 1d8f869
Showing
10 changed files
with
226 additions
and
31 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { Dispatch, ReactNode, SetStateAction } from 'react'; | ||
import Id from '../../IdContext/Id'; | ||
|
||
export default interface StateConsumerProps<T> { | ||
/** | ||
* The {@link StateProvider} to use | ||
* @default null | ||
*/ | ||
id?: Id; | ||
children: (value: T, setState: Dispatch<SetStateAction<T>>) => ReactNode; | ||
} | ||
|
||
/** @ignore */ | ||
export const defaultProps = { | ||
id: null, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import React, { ComponentType, memo, useCallback, useMemo } from 'react'; | ||
import IdContext from '../../IdContext'; | ||
import State from '../State'; | ||
import StateContextConsumerProps, { defaultProps } from './Props'; | ||
|
||
type StateContextConsumer<T> = ComponentType<StateContextConsumerProps<T>>; | ||
|
||
export default StateContextConsumer; | ||
export { StateContextConsumerProps }; | ||
|
||
/** @ignore */ | ||
export function createStateContextConsumer<T>( | ||
{ Consumer }: IdContext<State<T>>, | ||
): StateContextConsumer<T> { | ||
const StateConsumer: StateContextConsumer<T> = ({ id, children }) => { | ||
const render = useCallback( | ||
([state, setState]: State<T>) => children(state, setState), | ||
[children], | ||
); | ||
|
||
return useMemo(() => ( | ||
<Consumer id={id}>{render}</Consumer> | ||
), [id, render]); | ||
}; | ||
|
||
StateConsumer.defaultProps = defaultProps; | ||
|
||
return memo(StateConsumer, (prev, next) => ( | ||
Object.is(prev.id, next.id) | ||
&& Object.is(prev.children, next.children) | ||
)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { ReactNode } from 'react'; | ||
import Id from '../../IdContext/Id'; | ||
import Reset from '../../State/Reset'; | ||
|
||
export default interface StateContextProviderProps<T> { | ||
/** | ||
* The initial value to provide | ||
*/ | ||
value: T; | ||
/** | ||
* The key that identifies the {@link StateContextProvider} to be consumed | ||
* @default null | ||
*/ | ||
id?: Id; | ||
/** | ||
* @default null | ||
*/ | ||
children?: ReactNode; | ||
/** | ||
* The reset function when {@link StateProviderProps.value | value} updates | ||
*/ | ||
reset?: Reset<T>; | ||
} | ||
|
||
/** @ignore */ | ||
export const defaultProps = { | ||
id: null, | ||
children: null, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import React, { ComponentType, memo, useMemo } from 'react'; | ||
import IdContext from '../../IdContext'; | ||
import useResetState from '../../State/useResetState'; | ||
import State from '../State'; | ||
import StateContextProviderProps, { defaultProps } from './Props'; | ||
|
||
type StateContextProvider<T> = ComponentType<StateContextProviderProps<T>>; | ||
|
||
export default StateContextProvider; | ||
export { StateContextProviderProps }; | ||
|
||
/** @ignore */ | ||
export function createStateContextProvider<T>( | ||
StateContext: IdContext<State<T>>, | ||
): StateContextProvider<T> { | ||
const { Provider } = StateContext; | ||
const StateProvider: StateContextProvider<T> = ({ value, id, children, reset }) => { | ||
const state = useResetState(value, reset); | ||
|
||
return useMemo(() => ( | ||
<Provider value={state} id={id}>{children}</Provider> | ||
), [state, id, children]); | ||
}; | ||
|
||
StateProvider.defaultProps = defaultProps; | ||
|
||
return memo(StateProvider, (prev, next) => ( | ||
Object.is(prev.value, next.value) | ||
&& Object.is(prev.id, next.id) | ||
&& Object.is(prev.children, next.children) | ||
)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { Dispatch, SetStateAction } from 'react'; | ||
|
||
/** | ||
* A stateful value and a function to update it | ||
*/ | ||
type State<T> = [T, Dispatch<SetStateAction<T>>]; | ||
|
||
export default State; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
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>>; | ||
} | ||
|
||
/** | ||
* 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, () => undefined], | ||
); | ||
|
||
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 = null): State<T> { | ||
return useIdContext(context[kState], id); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters