import * as React from "react"; import { AppState } from "@client/state"; const StateContext = React.createContext(null); export interface ProvideStateProps { state: AppState; children: React.ReactNode; } export function ProvideState({ state, children }: ProvideStateProps) { return ( {children} ); } export interface ConsumeStateProps { children: (state: AppState) => React.ReactNode; } export function ConsumeState({ children }: ConsumeStateProps) { const consumeState = (state: AppState | null) => { if (state == null) { throw new Error( "Component with ConsumeState must be mounted inside ProvideState" ); } return children(state); }; return {consumeState}; } export function injectState

( Component: React.ComponentType

): React.FunctionComponent> { return function InjectState(props) { const state = React.useContext(StateContext); if (state == null) { throw new Error( "Component with injectState must be mounted inside ProvideState" ); } // tslint:disable-next-line: no-object-literal-type-assertion const allProps: Readonly

= {...props, appState: state} as Readonly

; return ; } }