Merge pull request #3259 from Asana/react-simplification

Refactor react.d.ts, merging with react-addons.d.ts
This commit is contained in:
Masahiro Wakame
2014-12-05 03:50:31 +09:00
7 changed files with 999 additions and 878 deletions
-139
View File
@@ -1,139 +0,0 @@
/// <reference path="react-addons.d.ts" />
import React = require("react/addons");
var PropTypesSpecification: React.Specification<any, any> = {
propTypes: {
// You can declare that a prop is a specific JS primitive. By default, these
// are all optional.
optionalArray: React.PropTypes.array,
optionalBool: React.PropTypes.bool,
optionalFunc: React.PropTypes.func,
optionalNumber: React.PropTypes.number,
optionalObject: React.PropTypes.object,
optionalString: React.PropTypes.string,
// Anything that can be rendered: numbers, strings, components or an array
// containing these types.
optionalRenderable: React.PropTypes.node,
// A React component.
optionalComponent: React.PropTypes.component,
// You can also declare that a prop is an instance of a class. This uses
// JS's instanceof operator.
optionalMessage: React.PropTypes.instanceOf(Date),
// You can ensure that your prop is limited to specific values by treating
// it as an enum.
optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),
// An object that could be one of many types
optionalUnion: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number,
React.PropTypes.instanceOf(Date)
]),
// An array of a certain type
optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
// An object with property values of a certain type
optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),
// An object taking on a particular shape
optionalObjectWithShape: React.PropTypes.shape({
color: React.PropTypes.string,
fontSize: React.PropTypes.number
}),
// You can chain any of the above with `isRequired` to make sure a warning
// is shown if the prop isn't provided.
requiredFunc: React.PropTypes.func.isRequired,
// A value of any data type
requiredAny: React.PropTypes.any.isRequired,
// You can also specify a custom validator. It should return an Error
// object if the validation fails. Don't `console.warn` or throw, as this
// won't work inside `oneOfType`.
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error('Validation failed!');
}
return null;
}
},
render: (): React.ReactHTMLElement => {
return null;
}
};
React.createClass(PropTypesSpecification);
var mountNode: Element;
var HelloMessage = React.createClass({displayName: 'HelloMessage',
render: function() {
return React.DOM.div(null, "Hello ", (<React.Component<{name: string}, any>>this).props.name);
}
});
React.render(HelloMessage({name: "John"}), mountNode);
var Timer = React.createClass({displayName: 'Timer',
getInitialState: function() {
return {secondsElapsed: 0};
},
tick: function() {
(<React.Component<any, {secondsElapsed: number}>>this).setState({
secondsElapsed: (<React.Component<any, {secondsElapsed: number}>>this).state.secondsElapsed + 1
});
},
componentDidMount: function() {
this.interval = setInterval(this.tick, 1000);
},
componentWillUnmount: function() {
clearInterval(this.interval);
},
render: function() {
return React.DOM.div(
null,
"Seconds Elapsed: ",
(<React.Component<any, {secondsElapsed: number}>>this).state.secondsElapsed
);
}
});
React.render(Timer(null), mountNode);
// TestUtils
var that: React.Component<any, any>;
var node = that.refs['input'].getDOMNode();
React.addons.TestUtils.Simulate.click(node);
React.addons.TestUtils.Simulate.change(node);
React.addons.TestUtils.Simulate.keyDown(node, {key: "Enter"});
var Greeting = React.createClass({displayName: 'Greeting',
getInitialState: function() {
return {morning: true};
},
render: function() {
var me = <React.Component<{name: string}, {morning: boolean}>>this;
return React.DOM.div(null, (me.state.morning ? "Hello" : "Goodbye "), me.props.name);
}
});
var root = React.addons.TestUtils.renderIntoDocument(Greeting({name: "John"}));
var greeting = React.addons.TestUtils.findRenderedComponentWithType(root, Greeting);
greeting.setState({
morning: false
});
var isImportant: boolean;
var isRead: boolean;
var cx = React.addons.classSet;
var classes: string = cx({
'message': true,
'message-important': isImportant,
'message-read': isRead
});
-175
View File
@@ -1,175 +0,0 @@
// Type definitions for React with Addons 0.12.RC
// Project: http://facebook.github.io/react/
// Definitions by: Asana <https://asana.com>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
/// <reference path="../react/react.d.ts" />
declare module "react/addons" {
export = React;
}
declare module React {
export var addons: {
classSet: (classes: {[key: string]: boolean}) => string;
cloneWithProps: CloneWithProps<any>;
CSSTransitionGroup: ReactComponentFactory<CSSTransitionGroupProps>;
LinkedStateMixin: LinkedStateMixin<any, any>;
Perf: Perf;
PureRenderMixin: Mixin<any, any>;
TestUtils: TestUtils;
TransitionGroup: ReactComponentFactory<any>;
update(object: Object, changes: Object): Object;
};
export interface CloneWithProps<P> {
(instance: ReactComponentElement<P>, extraProps?: P): ReactComponentElement<P>;
}
export interface ReactLink<T> {
value: T;
requestChange(newValue: T): void;
}
export interface LinkedStateMixin<P, S> extends Mixin<P, S> {
linkState<T>(key: string): ReactLink<T>;
}
export interface ComponentPerfContext {
current: string;
owner: string;
}
export interface CSSTransitionGroupProps {
transitionName: string;
}
export interface TransitionsSpecification<P, S> extends Specification<P, S> {
componentWillEnter?(callback: () => void): void;
componentDidEnter?(): void;
componentWillLeave?(callback: () => void): void;
componentDidLeave?(): void;
}
export interface NumericPerfContext {
[key: string]: number;
}
export interface Measurements {
exclusive: NumericPerfContext;
inclusive: NumericPerfContext;
render: NumericPerfContext;
counts: NumericPerfContext;
writes: NumericPerfContext;
displayNames: {
[key: string]: ComponentPerfContext;
};
totalTime: number;
}
export interface Perf {
start(): void;
stop(): void;
printInclusive(measurements: Measurements[]): void;
printExclusive(measurements: Measurements[]): void;
printWasted(measurements: Measurements[]): void;
printDOM(measurements: Measurements[]): void;
getLastMeasurements(): Measurements[];
}
export interface TestUtils {
Simulate: Simulate;
renderIntoDocument<P>(instance: ReactComponentElement<P>): ReactComponentElement<P>;
renderIntoDocument(instance: ReactHTMLElement): ReactHTMLElement;
renderIntoDocument(instance: ReactSVGElement): ReactSVGElement;
mockComponent(componentClass: ReactComponentFactory<any>, mockTagName?: string): TestUtils;
isDescriptorOfType(descriptor: ReactElement<any, any>, componentClass: ReactComponentFactory<any>): boolean;
isDOMComponent(instance: ReactElement<any, any>): boolean;
isCompositeComponent(instance: ReactElement<any, any>): boolean;
isCompositeComponentWithType(instance: ReactElement<any, any>, componentClass: ReactComponentFactory<any>): boolean;
isTextComponent(instance: ReactElement<any, any>): boolean;
findAllInRenderedTree(tree: ReactElement<any, any>, test: (component: ReactElement<any, any>) => boolean): ReactElement<any, any>[];
scryRenderedDOMComponentsWithClass(tree: ReactElement<any, any>, className: string): ReactElement<any, any>[];
findRenderedDOMComponentWithClass(tree: ReactElement<any, any>, className: string): ReactElement<any, any>;
scryRenderedDOMComponentsWithTag(tree: ReactElement<any, any>, tagName: string): ReactElement<any, any>[];
findRenderedDOMComponentWithTag(tree: ReactElement<any, any>, tagName: string): ReactElement<any, any>;
scryRenderedComponentsWithTag(tree: ReactElement<any, any>, componentClass: Function): ReactElement<any, any>[];
findRenderedComponentWithType<P>(tree: ReactElement<any, any>, componentClass: ReactComponentFactory<P>): Component<P, any>;
scryRenderedComponentsWithType<P>(tree: ReactElement<any, any>, componentClass: ReactComponentFactory<P>): Component<P, any>[];
}
export interface SyntheticEventData {
altKey?: boolean;
button?: number;
buttons?: number;
clientX?: number;
clientY?: number;
changedTouches?: TouchList;
charCode?: boolean;
clipboardData?: DataTransfer;
ctrlKey?: boolean;
deltaMode?: number;
deltaX?: number;
deltaY?: number;
deltaZ?: number;
detail?: number;
getModifierState?(key: string): boolean;
key?: string;
keyCode?: number;
locale?: string;
location?: number;
metaKey?: boolean;
pageX?: number;
pageY?: number;
relatedTarget?: EventTarget;
repeat?: boolean;
screenX?: number;
screenY?: number;
shiftKey?: boolean;
targetTouches?: TouchList;
touches?: TouchList;
view?: AbstractView;
which?: number;
}
export interface EventSimulator {
(element: Element, eventData?: SyntheticEventData): void;
(descriptor: ReactElement<any, any>, eventData?: SyntheticEventData): void;
}
export interface Simulate {
blur: EventSimulator;
change: EventSimulator;
click: EventSimulator;
cut: EventSimulator;
doubleClick: EventSimulator;
drag: EventSimulator;
dragEnd: EventSimulator;
dragEnter: EventSimulator;
dragExit: EventSimulator;
dragLeave: EventSimulator;
dragOver: EventSimulator;
dragStart: EventSimulator;
drop: EventSimulator;
focus: EventSimulator;
input: EventSimulator;
keyDown: EventSimulator;
keyPress: EventSimulator;
keyUp: EventSimulator;
mouseDown: EventSimulator;
mouseEnter: EventSimulator;
mouseLeave: EventSimulator;
mouseMove: EventSimulator;
mouseOut: EventSimulator;
mouseOver: EventSimulator;
mouseUp: EventSimulator;
paste: EventSimulator;
scroll: EventSimulator;
submit: EventSimulator;
touchCancel: EventSimulator;
touchEnd: EventSimulator;
touchMove: EventSimulator;
touchStart: EventSimulator;
wheel: EventSimulator;
}
}
@@ -3,7 +3,7 @@
// Definitions by: Asana <https://asana.com>
// Definitions: https://github.com/borisyankov/DefinitelyTyped
/// <reference path="../../react/legacy/react-0.11.d.ts" />
/// <reference path="react-0.11.d.ts" />
declare module "react/addons-0.11" {
export = React;
+42
View File
@@ -0,0 +1,42 @@
/// <reference path="react.d.ts" />
import React = require("react/addons");
// TestUtils
var that: React.CompositeComponent<any, any>;
var node = that.refs["input"].getDOMNode();
React.addons.TestUtils.Simulate.click(node);
React.addons.TestUtils.Simulate.change(node);
React.addons.TestUtils.Simulate.keyDown(node, {key: "Enter"});
interface GreetingProps {
name: string;
}
interface GreetingState {
morning: boolean;
}
interface Greeting extends React.CompositeComponent<GreetingProps, GreetingState> {
}
var Greeting = React.createClass({displayName: "Greeting",
getInitialState: function() {
return {morning: true};
},
render: function() {
var me = <Greeting>this;
return React.DOM.div(null, (me.state.morning ? "Hello" : "Goodbye "), me.props.name);
}
});
var root = React.addons.TestUtils.renderIntoDocument(React.createElement(Greeting, {name: "John"}));
var greeting = <Greeting>React.addons.TestUtils.findRenderedComponentWithType(root, Greeting);
greeting.setState({
morning: false
});
var isImportant: boolean;
var isRead: boolean;
var cx = React.addons.classSet;
var classes: string = cx({
"message": true,
"message-important": isImportant,
"message-read": isRead
});
+146 -67
View File
@@ -1,64 +1,152 @@
/// <reference path="react.d.ts" />
import React = require("react");
var PropTypesSpecification: React.Specification<any, any> = {
interface Props {
hello: string;
world?: string;
foo: number;
bar: boolean;
}
interface State {
inputValue?: string;
seconds?: number;
}
interface MyComponent extends React.CompositeComponent<Props, State> {
reset(): void;
}
var props: Props = {
hello: "world",
foo: 42,
bar: true
};
var container: Element;
var INPUT_REF: string = "input";
//
// Top-Level API
// --------------------------------------------------------------------------
var reactClass: React.ComponentClass<Props> = React.createClass<Props>({
getDefaultProps: () => {
return <Props>{
hello: undefined,
world: "peace",
foo: undefined,
bar: undefined
};
},
getInitialState: () => {
return {
inputValue: "React.js",
seconds: 0
};
},
reset: () => {
this.replaceState(this.getInitialState());
},
render: () => {
return React.DOM.div(null,
React.DOM.input({
ref: INPUT_REF,
value: this.state.inputValue
}));
}
});
var reactElement: React.ReactElement<Props> =
React.createElement<Props>(reactClass, props);
var reactFactory: React.Factory<Props> =
React.createFactory<Props>(reactClass);
var component: React.Component<Props> =
React.render<Props>(reactElement, container);
var unmounted: boolean = React.unmountComponentAtNode(container);
var str: string = React.renderToString(reactElement);
var markup: string = React.renderToStaticMarkup(reactElement);
var notValid: boolean = React.isValidElement(props); // false
var isValid = React.isValidElement(reactElement); // true
React.initializeTouchEvents(true);
//
// React Elements
// --------------------------------------------------------------------------
var type = reactElement.type;
var elementProps: Props = reactElement.props;
var key = reactElement.key;
var ref: string = reactElement.ref;
var factoryElement: React.ReactElement<Props> = reactFactory(elementProps);
//
// React Components
// --------------------------------------------------------------------------
var displayName: string = reactClass.displayName;
var defaultProps: Props = reactClass.getDefaultProps();
var propTypes: React.ValidationMap<Props> = reactClass.propTypes;
//
// Component API
// --------------------------------------------------------------------------
var htmlElement: Element = component.getDOMNode();
var divElement: HTMLDivElement = component.getDOMNode<HTMLDivElement>();
var isMounted: boolean = component.isMounted();
component.setProps(elementProps);
component.replaceProps(props);
var compComponent: React.CompositeComponent<Props, State> =
<React.CompositeComponent<Props, State>>component;
var initialState: State = compComponent.state;
compComponent.setState({ inputValue: "!!!" });
compComponent.replaceState({ inputValue: "???", seconds: 60 });
compComponent.forceUpdate();
var inputRef: React.HTMLComponent =
<React.HTMLComponent>compComponent.refs[INPUT_REF];
var value: string = inputRef.getDOMNode<HTMLInputElement>().value;
var myComponent = <MyComponent>compComponent;
myComponent.reset();
//
// PropTypes
// --------------------------------------------------------------------------
var PropTypesSpecification: React.ComponentSpec<any, any> = {
propTypes: {
// You can declare that a prop is a specific JS primitive. By default, these
// are all optional.
optionalArray: React.PropTypes.array,
optionalBool: React.PropTypes.bool,
optionalFunc: React.PropTypes.func,
optionalNumber: React.PropTypes.number,
optionalObject: React.PropTypes.object,
optionalString: React.PropTypes.string,
// Anything that can be rendered: numbers, strings, components or an array
// containing these types.
optionalRenderable: React.PropTypes.node,
// A React component.
optionalComponent: React.PropTypes.component,
// You can also declare that a prop is an instance of a class. This uses
// JS's instanceof operator.
optionalNode: React.PropTypes.node,
optionalElement: React.PropTypes.element,
optionalMessage: React.PropTypes.instanceOf(Date),
// You can ensure that your prop is limited to specific values by treating
// it as an enum.
optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),
// An object that could be one of many types
optionalEnum: React.PropTypes.oneOf(["News", "Photos"]),
optionalUnion: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number,
React.PropTypes.instanceOf(Date)
]),
// An array of a certain type
optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
// An object with property values of a certain type
optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),
// An object taking on a particular shape
optionalObjectWithShape: React.PropTypes.shape({
color: React.PropTypes.string,
fontSize: React.PropTypes.number
}),
// You can chain any of the above with `isRequired` to make sure a warning
// is shown if the prop isn't provided.
requiredFunc: React.PropTypes.func.isRequired,
// A value of any data type
requiredAny: React.PropTypes.any.isRequired,
// You can also specify a custom validator. It should return an Error
// object if the validation fails. Don't `console.warn` or throw, as this
// won't work inside `oneOfType`.
customProp: function(props, propName, componentName) {
customProp: function(props: any, propName: string, componentName: string) {
if (!/matchme/.test(props[propName])) {
return new Error('Validation failed!');
return new Error("Validation failed!");
}
return null;
}
@@ -68,50 +156,41 @@ var PropTypesSpecification: React.Specification<any, any> = {
}
};
React.createClass(PropTypesSpecification);
//
// Example from http://facebook.github.io/react/
// --------------------------------------------------------------------------
var mountNode: Element;
interface HelloMessageProps {
name: string;
interface TimerState {
secondsElapsed: number;
}
var HelloMessage = React.createClass<HelloMessageProps, any>({displayName: 'HelloMessage',
render: function() {
return React.DOM.div(null, "Hello ", (<React.Component<HelloMessageProps, any>>this).props.name);
}
});
// This code - calling a component directly - is deprecated in v0.12
// See http://fb.me/react-legacyfactory
React.render(HelloMessage({ name: "John" }), mountNode);
// Create a factory instead
var HelloMessageFactory = React.createFactory(HelloMessage)
React.render(HelloMessageFactory({ name: "John" }), mountNode)
var Timer = React.createClass({displayName: 'Timer',
getInitialState: function() {
return {secondsElapsed: 0};
interface Timer extends React.CompositeComponent<{}, TimerState> {
}
var Timer = React.createClass({
displayName: "Timer",
getInitialState: () => {
return { secondsElapsed: 0 };
},
tick: function() {
(<React.Component<any, {secondsElapsed: number}>>this).setState({
secondsElapsed: (<React.Component<any, {secondsElapsed: number}>>this).state.secondsElapsed + 1
tick: () => {
var me = <Timer>this;
me.setState({
secondsElapsed: me.state.secondsElapsed + 1
});
},
componentDidMount: function() {
componentDidMount: () => {
this.interval = setInterval(this.tick, 1000);
},
componentWillUnmount: function() {
componentWillUnmount: () => {
clearInterval(this.interval);
},
render: function() {
render: () => {
var me = <Timer>this;
return React.DOM.div(
null,
"Seconds Elapsed: ",
(<React.Component<any, {secondsElapsed: number}>>this).state.secondsElapsed
me.state.secondsElapsed
);
}
});
var mountNode: Element;
React.render(React.createElement(Timer, null), mountNode);
React.render(Timer(), mountNode);
+810 -496
View File
File diff suppressed because it is too large Load Diff