From 1fb244abedbe3dbfc11e31d3e9436be9062a8cbe Mon Sep 17 00:00:00 2001 From: Josh Rutherford Date: Thu, 19 Oct 2017 05:40:47 -0500 Subject: [PATCH] react-dom: add createPortal API (#20245). (#20336) * react-dom: add createPortal API. * React, React-DOM: move portal interface to types/react, update render for class components to include ReactPortal. * react-dom: add second portal test case with jsx, allow jsx in react-dom-tests. * react, react-dom createPortal api: remove undocumented arguments, properties. --- types/react-dom/index.d.ts | 5 ++++- .../{react-dom-tests.ts => react-dom-tests.tsx} | 14 ++++++++++++++ types/react-dom/tsconfig.json | 5 +++-- types/react/index.d.ts | 12 +++++++++--- 4 files changed, 30 insertions(+), 6 deletions(-) rename types/react-dom/{react-dom-tests.ts => react-dom-tests.tsx} (93%) diff --git a/types/react-dom/index.d.ts b/types/react-dom/index.d.ts index aeac0c8081..20b870a8b8 100644 --- a/types/react-dom/index.d.ts +++ b/types/react-dom/index.d.ts @@ -4,6 +4,7 @@ // AssureSign // Microsoft // MartynasZilinskas +// Josh Rutherford // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.3 @@ -12,12 +13,14 @@ export as namespace ReactDOM; import { ReactInstance, Component, ComponentState, ReactElement, SFCElement, CElement, - DOMAttributes, DOMElement + DOMAttributes, DOMElement, ReactNode, ReactPortal } from 'react'; export function findDOMNode(instance: ReactInstance): Element; export function unmountComponentAtNode(container: Element): boolean; +export function createPortal(children: ReactNode, container: Element): ReactPortal; + export const version: string; export const render: Renderer; export const hydrate: Renderer; diff --git a/types/react-dom/react-dom-tests.ts b/types/react-dom/react-dom-tests.tsx similarity index 93% rename from types/react-dom/react-dom-tests.ts rename to types/react-dom/react-dom-tests.tsx index 08eac7afdb..3f153b0a75 100644 --- a/types/react-dom/react-dom-tests.ts +++ b/types/react-dom/react-dom-tests.tsx @@ -31,6 +31,20 @@ describe('ReactDOM', () => { ReactDOM.render(React.createElement('div'), rootElement); ReactDOM.findDOMNode(rootElement); }); + + it('createPortal', () => { + const rootElement = document.createElement('div'); + const portalTarget = document.createElement('div'); + + class ClassComponent extends React.Component { + render() { + return ReactDOM.createPortal(
, portalTarget); + } + } + + ReactDOM.createPortal(React.createElement('div'), portalTarget); + ReactDOM.render(, rootElement); + }); }); describe('ReactDOMServer', () => { diff --git a/types/react-dom/tsconfig.json b/types/react-dom/tsconfig.json index 010744a826..0d21b07029 100644 --- a/types/react-dom/tsconfig.json +++ b/types/react-dom/tsconfig.json @@ -1,7 +1,7 @@ { "files": [ "index.d.ts", - "react-dom-tests.ts", + "react-dom-tests.tsx", "server/index.d.ts", "node-stream/index.d.ts", "test-utils/index.d.ts" @@ -22,6 +22,7 @@ ], "types": [], "noEmit": true, - "forceConsistentCasingInFileNames": true + "forceConsistentCasingInFileNames": true, + "jsx": "preserve" } } \ No newline at end of file diff --git a/types/react/index.d.ts b/types/react/index.d.ts index 35feb8d0ab..93cb62fbfa 100644 --- a/types/react/index.d.ts +++ b/types/react/index.d.ts @@ -13,6 +13,7 @@ // Dovydas Navickas // Stéphane Goetz // Rich Seviora +// Josh Rutherford // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.3 @@ -123,6 +124,11 @@ declare namespace React { type: keyof ReactSVG; } + interface ReactPortal { + key: Key | null; + children: ReactNode; + } + // // Factories // ---------------------------------------------------------------------- @@ -161,7 +167,7 @@ declare namespace React { // Should be Array but type aliases cannot be recursive type ReactFragment = {} | Array; - type ReactNode = ReactChild | ReactFragment | boolean | null | undefined; + type ReactNode = ReactChild | ReactFragment | ReactPortal | string | number | boolean | null | undefined; // // Top Level API @@ -280,7 +286,7 @@ declare namespace React { // tslint:enable:unified-signatures forceUpdate(callBack?: () => any): void; - render(): JSX.Element | JSX.Element[] | string | number | null | false; + render(): JSX.Element | JSX.Element[] | ReactPortal | string | number | null | false; // React.Props is now deprecated, which means that the `children` // property is not available on `P` by default, even though you can @@ -3505,7 +3511,7 @@ declare global { // tslint:disable:no-empty-interface interface Element extends React.ReactElement { } interface ElementClass extends React.Component { - render(): Element | Element[] | string | number | null | false; + render(): Element | Element[] | React.ReactPortal | string | number | null | false; } interface ElementAttributesProperty { props: {}; } interface ElementChildrenAttribute { children: {}; }