Skip to content

Instantly share code, notes, and snippets.

@Dremora
Last active April 13, 2018 18:12
Show Gist options
  • Save Dremora/e02fbbfb1eb5009abac92ccf71c4eb5f to your computer and use it in GitHub Desktop.
Save Dremora/e02fbbfb1eb5009abac92ccf71c4eb5f to your computer and use it in GitHub Desktop.
// @flow
import React, { Component, type Node } from 'react';
import PropTypes from 'prop-types';
type RenderFn<T> = (value: T) => Node;
export type ProviderProps<T> = {
value: T,
children?: Node
};
export type ConsumerProps<T> = {
children: RenderFn<T> | [RenderFn<T>]
};
export type ConsumerState<T> = {
value: T
};
export type Provider<T> = Component<ProviderProps<T>>;
export type Consumer<T> = Component<ConsumerProps<T>, ConsumerState<T>>;
export type Context<T> = {
Provider: Class<Provider<T>>,
Consumer: Class<Consumer<T>>
};
function onlyChild(children): any {
return Array.isArray(children) ? children[0] : children;
}
function createReactContext<T>(
defaultValue: T,
calculateChangedBits: ?(a: T, b: T) => number,
contextProp: string
): Context<T> {
class Provider extends Component<ProviderProps<T>> {
static childContextTypes = {
[contextProp]: PropTypes.object.isRequired
};
getChildContext() {
return {
[contextProp]: this.props.value
};
}
render() {
return this.props.children;
}
}
class Consumer extends Component<ConsumerProps<T>, ConsumerState<T>> {
static contextTypes = {
[contextProp]: PropTypes.object
};
state: ConsumerState<T> = {
value: this.getValue()
};
getValue(): T {
if (this.context[contextProp]) {
return this.context[contextProp];
} else {
return defaultValue;
}
}
render() {
return onlyChild(this.props.children)(this.state.value);
}
}
return {
Provider,
Consumer
};
}
// $FlowFixMe
React.createContext = createReactContext;
declare module 'react' {
declare export var DOM: any;
declare export var PropTypes: ReactPropTypes;
declare export var version: string;
declare export function checkPropTypes<V>(
propTypes: $Subtype<{ [_: $Keys<V>]: ReactPropsCheckType }>,
values: V,
location: string,
componentName: string,
getStack: ?() => ?string
): void;
declare export var createClass: React$CreateClass;
declare export function createContext<T>(
defaultValue: T,
calculateChangedBits: ?(a: T, b: T) => number,
contextProp: string
): {
Provider: React$ComponentType<{ value: T }>,
Consumer: React$ComponentType<{ children: (value: T) => React$Node }>
};
declare export type Context<T> = {
Provider: React$ComponentType<{ value: T }>,
Consumer: React$ComponentType<{ children: (value: T) => React$Node }>
};
declare export var createElement: React$CreateElement;
declare export var cloneElement: React$CloneElement;
declare export function createFactory<ElementType: React$ElementType>(
type: ElementType
): React$ElementFactory<ElementType>;
declare export function isValidElement(element: any): boolean;
declare export var Component: typeof React$Component;
declare export var PureComponent: typeof React$PureComponent;
declare export type StatelessFunctionalComponent<P> = React$StatelessFunctionalComponent<P>;
declare export type ComponentType<P> = React$ComponentType<P>;
declare export type ElementType = React$ElementType;
declare export type Element<+C> = React$Element<C>;
declare export var Fragment: ({ children: React$Node }) => React$Node;
declare export type Key = React$Key;
declare export type Ref<C> = React$Ref<C>;
declare export type Node = React$Node;
declare export type Portal = React$Portal;
declare export type ElementProps<C> = React$ElementProps<C>;
declare export type ElementConfig<C> = React$ElementConfig<C>;
declare export type ElementRef<C> = React$ElementRef<C>;
declare export type ChildrenArray<+T> = $ReadOnlyArray<ChildrenArray<T>> | T;
declare export var Children: {
map<T, U>(
children: ChildrenArray<T>,
fn: (child: $NonMaybeType<T>, index: number) => U,
thisArg?: mixed
): Array<$NonMaybeType<U>>,
forEach<T>(children: ChildrenArray<T>, fn: (child: T, index: number) => mixed, thisArg?: mixed): void,
count(children: ChildrenArray<any>): number,
only<T>(children: ChildrenArray<T>): $NonMaybeType<T>,
toArray<T>(children: ChildrenArray<T>): Array<$NonMaybeType<T>>
};
declare export default {|
+DOM: typeof DOM,
+PropTypes: typeof PropTypes,
+version: typeof version,
+checkPropTypes: typeof checkPropTypes,
+createClass: typeof createClass,
+createContext: typeof createContext,
+createElement: typeof createElement,
+cloneElement: typeof cloneElement,
+createFactory: typeof createFactory,
+isValidElement: typeof isValidElement,
+Component: typeof Component,
+PureComponent: typeof PureComponent,
+Children: typeof Children
|};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment