You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
43 lines
1.3 KiB
43 lines
1.3 KiB
import * as PropTypes from "prop-types"; |
|
import * as React from "react"; |
|
|
|
import { StateBase } from "@app/state"; |
|
|
|
interface IProvidedStateContext { |
|
providedState: StateBase; |
|
} |
|
|
|
const providedStateContextTypes: PropTypes.ValidationMap<any> = { |
|
providedState: PropTypes.object, |
|
}; |
|
|
|
export class ProvideState extends React.Component<{ |
|
state: StateBase, |
|
}> implements React.ChildContextProvider<IProvidedStateContext> { |
|
static childContextTypes = providedStateContextTypes; |
|
|
|
getChildContext(): IProvidedStateContext { |
|
return { |
|
providedState: this.props.state, |
|
}; |
|
} |
|
|
|
render() { |
|
return React.Children.only(this.props.children); |
|
} |
|
} |
|
|
|
type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T]; |
|
type Omit<T, K extends keyof T> = {[P in Diff<keyof T, K>]: T[P]}; |
|
|
|
export function injectState<P extends { "state": StateBase }>(Component: React.ComponentType<P>) { |
|
return class extends React.Component<Omit<P, "state">> { |
|
static contextTypes = providedStateContextTypes; |
|
context: IProvidedStateContext; |
|
|
|
render() { |
|
const state = this.context.providedState; |
|
return <Component {...this.props} state={state} />; |
|
} |
|
}; |
|
}
|
|
|