diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 9a087a7aa..3a5e904f4 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -317,6 +317,7 @@ All definitions files include a header with the author and editors, so at some p * [Rickshaw](http://code.shutterstock.com/rickshaw/) (by [Blake Niemyjski](https://github.com/niemyjski)) * [Riot.js](https://github.com/moot/riotjs) (by [vvakame](https://github.com/vvakame)) * [Restify](https://github.com/mcavage/node-restify) (by [Bret Little](https://github.com/blittle)) +* [React](http://facebook.github.io/react/) (by [Phips Peter](https://github.com/pspeter3) * [Redis](https://github.com/mranney/node_redis) (by [Carlos Ballesteros Velasco](https://github.com/soywiz)) * [Request](https://github.com/mikeal/request) (by [Carlos Ballesteros Velasco](https://github.com/soywiz)) * [Royalslider](http://dimsemenov.com/plugins/royal-slider/) (by [Christiaan Rakowski](https://github.com/csrakowski)) diff --git a/react/react-tests.ts b/react/react-tests.ts new file mode 100644 index 000000000..1267713c2 --- /dev/null +++ b/react/react-tests.ts @@ -0,0 +1,107 @@ +/// +import React = require("react"); + +var PropTypesSpecification: React.Specification = { + 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.renderable, + + // 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.Descriptor => { + return null; + } +}; + +React.createClass(PropTypesSpecification); + +var mountNode: Element; + +var HelloMessage = React.createClass({displayName: 'HelloMessage', + render: function() { + return React.DOM.div(null, "Hello ", (>this).props.name); + } +}); + +React.renderComponent(HelloMessage({name: "John"}), mountNode); + +var Timer = React.createClass({displayName: 'Timer', + getInitialState: function() { + return {secondsElapsed: 0}; + }, + tick: function() { + (>this).setState({ + secondsElapsed: (>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: ", + (>this).state.secondsElapsed + ); + } +}); + +React.renderComponent(Timer(null), mountNode); \ No newline at end of file diff --git a/react/react.d.ts b/react/react.d.ts new file mode 100644 index 000000000..c97810448 --- /dev/null +++ b/react/react.d.ts @@ -0,0 +1,534 @@ +// Type definitions for React 0.11.2 +// Project: http://facebook.github.io/react/ +// Definitions by: Asana +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +declare module "react" { + export function createClass(specification: Specification): Factory

; + + export function renderComponent(component: Descriptor, container: Element, callback?: () => void): void; + + export function unmountComponentAtNode(container: Element): boolean; + + export function renderComponentToString(component: Descriptor): string; + + export function renderComponentToStaticMarkup(component: Descriptor): string; + + export function isValidClass(factory: Factory): boolean; + + export function isValidComponent(component: Descriptor): boolean; + + export function initializeTouchEvents(shouldUseTouch: boolean): void; + + export interface Descriptor

{ + props: P; + } + + export interface Factory

{ + (properties?: P, ...children: any[]): Descriptor

; + } + + export interface Mixin { + componentWillMount?(): void; + componentDidMount?(): void; + componentWillReceiveProps?(nextProps: P): void; + shouldComponentUpdate?(nextProps: P, nextState: S): boolean; + componentWillUpdate?(nextProps: P, nextState: S): void; + componentDidUpdate?(prevProps: P, prevState: S): void; + componentWillUnmount?(): void; + } + + export interface Specification extends Mixin { + displayName?: string; + mixins?: Mixin[]; + statics?: { + [key: string]: Function; + }; + propTypes?: ValidationMap

; + getDefaultProps?(): P; + getInitialState?(): S; + render(): Descriptor; + } + + interface DomReferencer { + getDomNode(): Element; + } + + export interface Component extends DomReferencer { + refs: { + [key: string]: DomReferencer + }; + props: P; + state: S; + setState(nextState: S, callback?: () => void): void; + replaceState(nextState: S, callback?: () => void): void; + forceUpdate(callback?: () => void): void; + isMounted(): boolean; + transferPropsTo(target: Factory

): Descriptor

; + setProps(nextProps: P, callback?: () => void): void; + replaceProps(nextProps: P, callback?: () => void): void; + } + + interface Constructable { + new(): any; + } + + interface Validator

{ + (props: P, propName: string, componentName: string): Error; + } + + interface Requireable

extends Validator

{ + isRequired: Validator

; + } + + interface ValidationMap

{ + [key: string]: Validator

; + } + + export var PropTypes: { + any: Requireable; + array: Requireable; + bool: Requireable; + func: Requireable; + number: Requireable; + object: Requireable; + string: Requireable; + renderable: Requireable; + component: Requireable; + instanceOf: (clazz: Constructable) => Requireable; + oneOf: (types: any[]) => Requireable + oneOfType: (types: Validator[]) => Requireable; + arrayOf: (type: Validator) => Requireable; + objectOf: (type: Validator) => Requireable; + shape: (type: ValidationMap) => Requireable; + }; + + export var Children: { + map(children: any[], fn: (child: any) => any): any[]; + forEach(children: any[], fn: (child: any) => any): void; + count(children: any[]): number; + only(children: any[]): any; + }; + + // Browser Interfaces + // Taken from https://github.com/nikeee/2048-typescript/blob/master/2048/js/touch.d.ts + interface AbstractView { + styleMedia: StyleMedia; + document: Document; + } + + interface Touch { + identifier: number; + target: EventTarget; + screenX: number; + screenY: number; + clientX: number; + clientY: number; + pageX: number; + pageY: number; + } + + interface TouchList { + [index: number]: Touch; + length: number; + item(index: number): Touch; + identifiedTouch(identifier: number): Touch; + } + + // Events + export interface SyntheticEvent { + bubbles: boolean; + cancelable: boolean; + currentTarget: EventTarget; + defaultPrevented: boolean; + eventPhase: number; + nativeEvent: Event; + preventDefault(): void; + stopPropagation(): void; + target: EventTarget; + timeStamp: Date; + type: string; + } + + export interface ClipboardEvent extends SyntheticEvent { + clipboardData: DataTransfer; + } + + export interface KeyboardEvent extends SyntheticEvent { + altKey: boolean; + charCode: number; + ctrlKey: boolean; + getModifierState(key: string): boolean; + key: string; + keyCode: number; + locale: string; + location: number; + metaKey: boolean; + repeat: boolean; + shiftKey: boolean; + which: number; + } + + export interface FocusEvent extends SyntheticEvent { + relatedTarget: EventTarget; + } + + export interface MouseEvent extends SyntheticEvent { + altKey: boolean; + button: number; + buttons: number; + clientX: number; + clientY: number; + ctrlKey: boolean; + getModifierState(key: string): boolean; + metaKey: boolean; + pageX: number; + pageY: number; + relatedTarget: EventTarget; + screenX: number; + screenY: number; + shiftKey: boolean; + } + + export interface TouchEvent extends SyntheticEvent { + altKey: boolean; + changedTouches: TouchList; + ctrlKey: boolean; + getModifierState(key: string): boolean; + metaKey: boolean; + shiftKey: boolean; + targetTouches: TouchList; + touches: TouchList; + } + + export interface UiEvent extends SyntheticEvent { + detail: number; + view: AbstractView; + } + + export interface WheelEvent extends SyntheticEvent { + deltaMode: number; + deltaX: number; + deltaY: number; + deltaZ: number; + } + + // Attributes + interface EventAttributes { + onCopy?: (event: ClipboardEvent) => void; + onCut?: (event: ClipboardEvent) => void; + onPaste?: (event: ClipboardEvent) => void; + onKeyDown?: (event: KeyboardEvent) => void; + onKeyPress?: (event: KeyboardEvent) => void; + onKeyUp?: (event: KeyboardEvent) => void; + onFocus?: (event: FocusEvent) => void; + onBlur?: (event: FocusEvent) => void; + onChange?: (event: SyntheticEvent) => void; + onInput?: (event: SyntheticEvent) => void; + onSubmit?: (event: SyntheticEvent) => void; + onClick?: (event: MouseEvent) => void; + onDoubleClick?: (event: MouseEvent) => void; + onDrag?: (event: MouseEvent) => void; + onDragEnd?: (event: MouseEvent) => void; + onDragEnter?: (event: MouseEvent) => void; + onDragExit?: (event: MouseEvent) => void; + onDragLeave?: (event: MouseEvent) => void; + onDragOver?: (event: MouseEvent) => void; + onDragStart?: (event: MouseEvent) => void; + onDrop?: (event: MouseEvent) => void; + onMouseDown?: (event: MouseEvent) => void; + onMouseEnter?: (event: MouseEvent) => void; + onMouseLeave?: (event: MouseEvent) => void; + onMouseMove?: (event: MouseEvent) => void; + onMouseOut?: (event: MouseEvent) => void; + onMouseOver?: (event: MouseEvent) => void; + onMouseUp?: (event: MouseEvent) => void; + onTouchCancel?: (event: TouchEvent) => void; + onTouchEnd?: (event: TouchEvent) => void; + onTouchMove?: (event: TouchEvent) => void; + onTouchStart?: (event: TouchEvent) => void; + onScroll?: (event: UiEvent) => void; + onWheel?: (event: WheelEvent) => void; + } + + interface DomAttributes extends EventAttributes { + // HTML Attributes + accept?: any; + accessKey?: any; + action?: any; + allowFullScreen?: any; + allowTransparency?: any; + alt?: any; + async?: any; + autoComplete?: any; + autoFocus?: any; + autoPlay?: any; + cellPadding?: any; + cellSpacing?: any; + charSet?: any; + checked?: any; + className?: any; + cols?: any; + colSpan?: any; + content?: any; + contentEditable?: any; + contextMenu?: any; + controls?: any; + coords?: any; + crossOrigin?: any; + data?: any; + dateTime?: any; + defer?: any; + dir?: any; + disabled?: any; + download?: any; + draggable?: any; + encType?: any; + form?: any; + formNoValidate?: any; + frameBorder?: any; + height?: any; + hidden?: any; + href?: any; + hrefLang?: any; + htmlFor?: any; + httpEquiv?: any; + icon?: any; + id?: any; + label?: any; + lang?: any; + list?: any; + loop?: any; + max?: any; + maxLength?: any; + mediaGroup?: any; + method?: any; + min?: any; + multiple?: any; + muted?: any; + name?: any; + noValidate?: any; + open?: any; + pattern?: any; + placeholder?: any; + poster?: any; + preload?: any; + radioGroup?: any; + readOnly?: any; + rel?: any; + required?: any; + role?: any; + rows?: any; + rowSpan?: any; + sandbox?: any; + scope?: any; + scrollLeft?: any; + scrolling?: any; + scrollTop?: any; + seamless?: any; + selected?: any; + shape?: any; + size?: any; + span?: any; + spellCheck?: any; + src?: any; + srcDoc?: any; + srcSet?: any; + start?: any; + step?: any; + style?: any; + tabIndex?: any; + target?: any; + title?: any; + type?: any; + useMap?: any; + value?: any; + width?: any; + wmode?: any; + } + + interface SvgAttributes extends EventAttributes { + cx?: any; + cy?: any; + d?: any; + dx?: any; + dy?: any; + fill?: any; + fillOpacity?: any; + fontFamily?: any; + fontSize?: any; + fx?: any; + fy?: any; + gradientTransform?: any; + gradientUnits?: any; + markerEnd?: any; + markerMid?: any; + markerStart?: any; + offset?: any; + opacity?: any; + patternContentUnits?: any; + patternUnits?: any; + points?: any; + preserveAspectRatio?: any; + r?: any; + rx?: any; + ry?: any; + spreadMethod?: any; + stopColor?: any; + stopOpacity?: any; + stroke?: any; + strokeDasharray?: any; + strokeLinecap?: any; + strokeOpacity?: any; + strokeWidth?: any; + textAnchor?: any; + transform?: any; + version?: any; + viewBox?: any; + x1?: any; + x2?: any; + x?: any; + y1?: any; + y2?: any; + y?: any; + } + + interface DomElement extends Factory { + } + + interface SvgElement extends Factory { + } + + export var DOM: { + // HTML + a: DomElement; + abbr: DomElement; + address: DomElement; + area: DomElement; + article: DomElement; + aside: DomElement; + audio: DomElement; + b: DomElement; + base: DomElement; + bdi: DomElement; + bdo: DomElement; + big: DomElement; + blockquote: DomElement; + body: DomElement; + br: DomElement; + button: DomElement; + canvas: DomElement; + caption: DomElement; + cite: DomElement; + code: DomElement; + col: DomElement; + colgroup: DomElement; + data: DomElement; + datalist: DomElement; + dd: DomElement; + del: DomElement; + details: DomElement; + dfn: DomElement; + dialog: DomElement; + div: DomElement; + dl: DomElement; + dt: DomElement; + em: DomElement; + embed: DomElement; + fieldset: DomElement; + figcaption: DomElement; + figure: DomElement; + footer: DomElement; + form: DomElement; + h1: DomElement; + h2: DomElement; + h3: DomElement; + h4: DomElement; + h5: DomElement; + h6: DomElement; + head: DomElement; + header: DomElement; + hr: DomElement; + html: DomElement; + i: DomElement; + iframe: DomElement; + img: DomElement; + input: DomElement; + ins: DomElement; + kbd: DomElement; + keygen: DomElement; + label: DomElement; + legend: DomElement; + li: DomElement; + link: DomElement; + main: DomElement; + map: DomElement; + mark: DomElement; + menu: DomElement; + menuitem: DomElement; + meta: DomElement; + meter: DomElement; + nav: DomElement; + noscript: DomElement; + object: DomElement; + ol: DomElement; + optgroup: DomElement; + option: DomElement; + output: DomElement; + p: DomElement; + param: DomElement; + pre: DomElement; + progress: DomElement; + q: DomElement; + rp: DomElement; + rt: DomElement; + ruby: DomElement; + s: DomElement; + samp: DomElement; + script: DomElement; + section: DomElement; + select: DomElement; + small: DomElement; + source: DomElement; + span: DomElement; + strong: DomElement; + style: DomElement; + sub: DomElement; + summary: DomElement; + sup: DomElement; + table: DomElement; + tbody: DomElement; + td: DomElement; + textarea: DomElement; + tfoot: DomElement; + th: DomElement; + thead: DomElement; + time: DomElement; + title: DomElement; + tr: DomElement; + track: DomElement; + u: DomElement; + ul: DomElement; + "var": DomElement; + video: DomElement; + wbr: DomElement; + // SVG + circle: SvgElement; + defs: SvgElement; + ellipse: SvgElement; + g: SvgElement; + line: SvgElement; + linearGradient: SvgElement; + mask: SvgElement; + path: SvgElement; + pattern: SvgElement; + polygon: SvgElement; + polyline: SvgElement; + radialGradient: SvgElement; + rect: SvgElement; + stop: SvgElement; + svg: SvgElement; + text: SvgElement; + tspan: SvgElement; + }; +} \ No newline at end of file