diff --git a/react/README.md b/react/README.md
index c17ccaebe0..b7ff4b55e6 100644
--- a/react/README.md
+++ b/react/README.md
@@ -2,4 +2,4 @@
This folder contains the following `.d.ts` files:
* `react.d.ts` declares the module `"react"` and `"react/addons"`
-* `react-namespace.d.ts` declares the global namespace `React` (only include this if you are actually using the global `React`)
+* `react-global.d.ts` declares the global namespace `React` (only include this if you are actually using the global `React`)
diff --git a/react/react-global-tests.ts b/react/react-global-tests.ts
new file mode 100644
index 0000000000..a3f4a14849
--- /dev/null
+++ b/react/react-global-tests.ts
@@ -0,0 +1,367 @@
+///
+
+interface Props extends React.Props {
+ hello: string;
+ world?: string;
+ foo: number;
+ bar: boolean;
+}
+
+interface State {
+ inputValue?: string;
+ seconds?: number;
+}
+
+interface Context {
+ someValue?: string;
+}
+
+interface ChildContext {
+ someOtherValue: string;
+}
+
+interface MyComponent extends React.Component {
+ reset(): void;
+}
+
+var props: Props = {
+ key: 42,
+ ref: "myComponent42",
+ hello: "world",
+ foo: 42,
+ bar: true
+};
+
+var container: Element;
+
+//
+// Top-Level API
+// --------------------------------------------------------------------------
+
+var ClassicComponent: React.ClassicComponentClass =
+ React.createClass({
+ getDefaultProps() {
+ return {
+ hello: undefined,
+ world: "peace",
+ foo: undefined,
+ bar: undefined,
+ };
+ },
+ getInitialState() {
+ return {
+ inputValue: this.context.someValue,
+ seconds: this.props.foo
+ };
+ },
+ reset() {
+ this.replaceState(this.getInitialState());
+ },
+ render() {
+ return React.DOM.div(null,
+ React.DOM.input({
+ ref: input => this._input = input,
+ value: this.state.inputValue
+ }));
+ }
+ });
+
+class ModernComponent extends React.Component
+ implements React.ChildContextProvider {
+
+ static propTypes: React.ValidationMap = {
+ foo: React.PropTypes.number
+ }
+
+ static contextTypes: React.ValidationMap = {
+ someValue: React.PropTypes.string
+ }
+
+ static childContextTypes: React.ValidationMap = {
+ someOtherValue: React.PropTypes.string
+ }
+
+ context: Context;
+
+ getChildContext() {
+ return {
+ someOtherValue: 'foo'
+ }
+ }
+
+ state = {
+ inputValue: this.context.someValue,
+ seconds: this.props.foo
+ }
+
+ reset() {
+ this.setState({
+ inputValue: this.context.someValue,
+ seconds: this.props.foo
+ });
+ }
+
+ private _input: React.HTMLComponent;
+
+ render() {
+ return React.DOM.div(null,
+ React.DOM.input({
+ ref: input => this._input = input,
+ value: this.state.inputValue
+ }));
+ }
+}
+
+// React.createFactory
+var factory: React.Factory =
+ React.createFactory(ModernComponent);
+var factoryElement: React.ReactElement =
+ factory(props);
+
+var classicFactory: React.ClassicFactory =
+ React.createFactory(ClassicComponent);
+var classicFactoryElement: React.ClassicElement =
+ classicFactory(props);
+
+var domFactory: React.DOMFactory =
+ React.createFactory("foo");
+var domFactoryElement: React.DOMElement =
+ domFactory();
+
+// React.createElement
+var element: React.ReactElement =
+ React.createElement(ModernComponent, props);
+var classicElement: React.ClassicElement =
+ React.createElement(ClassicComponent, props);
+var domElement: React.HTMLElement =
+ React.createElement("div");
+
+// React.cloneElement
+var clonedElement: React.ReactElement =
+ React.cloneElement(element, props);
+var clonedClassicElement: React.ClassicElement =
+ React.cloneElement(classicElement, props);
+var clonedDOMElement: React.HTMLElement =
+ React.cloneElement(domElement);
+
+// React.render
+var component: React.Component =
+ React.render(element, container);
+var classicComponent: React.ClassicComponent =
+ React.render(classicElement, container);
+var domComponent: React.DOMComponent =
+ React.render(domElement, container);
+
+// Other Top-Level API
+var unmounted: boolean = React.unmountComponentAtNode(container);
+var str: string = React.renderToString(element);
+var markup: string = React.renderToStaticMarkup(element);
+var notValid: boolean = React.isValidElement(props); // false
+var isValid = React.isValidElement(element); // true
+React.initializeTouchEvents(true);
+var domNode: Element = React.findDOMNode(component);
+domNode = React.findDOMNode(domNode);
+
+//
+// React Elements
+// --------------------------------------------------------------------------
+
+var type = element.type;
+var elementProps: Props = element.props;
+var key = element.key;
+
+//
+// React Components
+// --------------------------------------------------------------------------
+
+var displayName: string = ClassicComponent.displayName;
+var defaultProps: Props = ClassicComponent.getDefaultProps();
+var propTypes: React.ValidationMap = ClassicComponent.propTypes;
+
+//
+// Component API
+// --------------------------------------------------------------------------
+
+// modern
+var componentState: State = component.state;
+component.setState({ inputValue: "!!!" });
+component.forceUpdate();
+
+// classic
+var htmlElement: Element = classicComponent.getDOMNode();
+var divElement: HTMLDivElement = classicComponent.getDOMNode();
+var isMounted: boolean = classicComponent.isMounted();
+classicComponent.setProps(elementProps);
+classicComponent.replaceProps(props);
+classicComponent.replaceState({ inputValue: "???", seconds: 60 });
+
+var myComponent = component;
+myComponent.reset();
+
+//
+// Attributes
+// --------------------------------------------------------------------------
+
+var children: any[] = ["Hello world", [null], React.DOM.span(null)];
+var divStyle: React.CSSProperties = { // CSSProperties
+ flex: "1 1 main-size",
+ backgroundImage: "url('hello.png')"
+};
+var htmlAttr: React.HTMLAttributes = {
+ key: 36,
+ ref: "htmlComponent",
+ children: children,
+ className: "test-attr",
+ style: divStyle,
+ onClick: (event: React.MouseEvent) => {
+ event.preventDefault();
+ event.stopPropagation();
+ },
+ dangerouslySetInnerHTML: {
+ __html: "STRONG"
+ }
+};
+React.DOM.div(htmlAttr);
+React.DOM.span(htmlAttr);
+React.DOM.input(htmlAttr);
+
+React.DOM.svg({ viewBox: "0 0 48 48" },
+ React.DOM.rect({
+ x: 22,
+ y: 10,
+ width: 4,
+ height: 28
+ }),
+ React.DOM.rect({
+ x: 10,
+ y: 22,
+ width: 28,
+ height: 4
+ }));
+
+
+//
+// React.PropTypes
+// --------------------------------------------------------------------------
+
+var PropTypesSpecification: React.ComponentSpec = {
+ propTypes: {
+ optionalArray: React.PropTypes.array,
+ optionalBool: React.PropTypes.bool,
+ optionalFunc: React.PropTypes.func,
+ optionalNumber: React.PropTypes.number,
+ optionalObject: React.PropTypes.object,
+ optionalString: React.PropTypes.string,
+ optionalNode: React.PropTypes.node,
+ optionalElement: React.PropTypes.element,
+ optionalMessage: React.PropTypes.instanceOf(Date),
+ optionalEnum: React.PropTypes.oneOf(["News", "Photos"]),
+ optionalUnion: React.PropTypes.oneOfType([
+ React.PropTypes.string,
+ React.PropTypes.number,
+ React.PropTypes.instanceOf(Date)
+ ]),
+ optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
+ optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),
+ optionalObjectWithShape: React.PropTypes.shape({
+ color: React.PropTypes.string,
+ fontSize: React.PropTypes.number
+ }),
+ requiredFunc: React.PropTypes.func.isRequired,
+ requiredAny: React.PropTypes.any.isRequired,
+ customProp: function(props: any, propName: string, componentName: string) {
+ if (!/matchme/.test(props[propName])) {
+ return new Error("Validation failed!");
+ }
+ return null;
+ }
+ },
+ render: (): React.ReactElement => {
+ return null;
+ }
+};
+
+//
+// ContextTypes
+// --------------------------------------------------------------------------
+
+var ContextTypesSpecification: React.ComponentSpec = {
+ contextTypes: {
+ optionalArray: React.PropTypes.array,
+ optionalBool: React.PropTypes.bool,
+ optionalFunc: React.PropTypes.func,
+ optionalNumber: React.PropTypes.number,
+ optionalObject: React.PropTypes.object,
+ optionalString: React.PropTypes.string,
+ optionalNode: React.PropTypes.node,
+ optionalElement: React.PropTypes.element,
+ optionalMessage: React.PropTypes.instanceOf(Date),
+ optionalEnum: React.PropTypes.oneOf(["News", "Photos"]),
+ optionalUnion: React.PropTypes.oneOfType([
+ React.PropTypes.string,
+ React.PropTypes.number,
+ React.PropTypes.instanceOf(Date)
+ ]),
+ optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
+ optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),
+ optionalObjectWithShape: React.PropTypes.shape({
+ color: React.PropTypes.string,
+ fontSize: React.PropTypes.number
+ }),
+ requiredFunc: React.PropTypes.func.isRequired,
+ requiredAny: React.PropTypes.any.isRequired,
+ customProp: function(props: any, propName: string, componentName: string) {
+ if (!/matchme/.test(props[propName])) {
+ return new Error("Validation failed!");
+ }
+ return null;
+ }
+ },
+ render: (): React.ReactElement => {
+ return null;
+ }
+};
+
+//
+// React.Children
+// --------------------------------------------------------------------------
+
+var childMap: { [key: string]: number } =
+ React.Children.map(children, (child) => { return 42; });
+React.Children.forEach(children, (child) => {});
+var nChildren: number = React.Children.count(children);
+var onlyChild = React.Children.only([null, [[["Hallo"], true]], false]);
+
+//
+// Example from http://facebook.github.io/react/
+// --------------------------------------------------------------------------
+
+interface TimerState {
+ secondsElapsed: number;
+}
+class Timer extends React.Component<{}, TimerState> {
+ state = {
+ secondsElapsed: 0
+ }
+ private _interval: number;
+ tick() {
+ this.setState((prevState, props) => ({
+ secondsElapsed: prevState.secondsElapsed + 1
+ }));
+ }
+ componentDidMount() {
+ this._interval = setInterval(() => this.tick(), 1000);
+ }
+ componentWillUnmount() {
+ clearInterval(this._interval);
+ }
+ render() {
+ return React.DOM.div(
+ null,
+ "Seconds Elapsed: ",
+ this.state.secondsElapsed
+ );
+ }
+}
+React.render(React.createElement(Timer), container);
+
diff --git a/react/react-namespace.ts b/react/react-global.d.ts
similarity index 100%
rename from react/react-namespace.ts
rename to react/react-global.d.ts