diff --git a/src/README.md b/src/README.md index e6610c502..b21901515 100644 --- a/src/README.md +++ b/src/README.md @@ -1,6 +1,6 @@ ### Welcome to the source of ReasonReact -We want to expose as minimum modules to the toplevel as possible, and at the same time want to map closely to the npm packages. So each module maps to a npm package, and each sub-module maps to a sub-module. For example: `react-dom` -> `ReactDOM` and `react-dom/server` -> `ReactDOM.Server`. +We want to expose the minimum amount of top-level modules possible, and at the same time want to map closely to the npm packages. So each module maps to a npm package, and each sub-module maps to a sub-module. For example: `react-dom` -> `ReactDOM` and `react-dom/server` -> `ReactDOMServer`. Files overview: @@ -10,12 +10,12 @@ Files overview: - `React.Event`: bindings to React's custom events system - `React.Context`: bindings to React's Context - `ReactDOM`: bindings to ReactDOM - - `ReactDOM.Server`: bindings to ReactDOMServer - `ReactDOM.Style`: bindings to create `style` objects - - `ReactDOM.TestUtils`: helpers for testing your components +- `ReactDOMServer`: bindings to ReactDOMServer +- `ReactDOMTestUtils`: helpers for testing your components ## Extra (not part of react) -- `ErrorBoundary`: component to catch errors within your component tree +- `ReasonReactErrorBoundary`: component to catch errors within your component tree - `ReasonReactRouter`: a simple, yet fully featured router with minimal memory allocations -Eventually `React.ErrorBoundary` and `ReasonReactRouter` could live into their own packages, but for now they are part of ReasonReact (and we will keep them here for backwards compatibility). +Eventually `ReasonReactErrorBoundary` and `ReasonReactRouter` could live into their own packages, but for now they are part of ReasonReact (and we will keep them here for backwards compatibility). diff --git a/src/ReactDOM.re b/src/ReactDOM.re index 03f2a841c..15e06706f 100644 --- a/src/ReactDOM.re +++ b/src/ReactDOM.re @@ -1545,233 +1545,3 @@ external jsxs: (string, domProps) => React.element = "jsxs"; [@mel.module "react/jsx-runtime"] external jsxsKeyed: (string, domProps, ~key: string=?, unit) => React.element = "jsxs"; - -module Server = { - [@mel.module "react-dom/server"] - external renderToString: React.element => string = "renderToString"; - - [@mel.module "react-dom/server"] - external renderToStaticMarkup: React.element => string = - "renderToStaticMarkup"; - - [@deriving abstract] - type options = { - [@mel.optional] - bootstrapScriptContent: option(string), - [@mel.optional] - bootstrapScripts: option(array(string)), - [@mel.optional] - bootstrapModules: option(array(string)), - [@mel.optional] - identifierPrefix: option(string), - [@mel.optional] - namespaceURI: option(string), - [@mel.optional] - nonce: option(string), - [@mel.optional] - onAllReady: option(unit => unit), - [@mel.optional] - onError: option(Js.Exn.t => unit), - [@mel.optional] - onShellReady: option(unit => unit), - [@mel.optional] - onShellError: option(Js.Exn.t => unit), - [@mel.optional] - progressiveChunkSize: option(int), - }; - - type pipeableStream = { - /* Using empty object instead of Node.stream since Melange don't provide a binding to node's Stream (https://nodejs.org/api/stream.html) */ - pipe: Js.t({.}) => unit, - abort: unit => unit, - }; - - [@mel.module "react-dom/server"] - external renderToPipeableStream: (React.element, options) => pipeableStream = - "renderToPipeableStream"; - - let renderToPipeableStream = - ( - ~bootstrapScriptContent=?, - ~bootstrapScripts=?, - ~bootstrapModules=?, - ~identifierPrefix=?, - ~namespaceURI=?, - ~nonce=?, - ~onAllReady=?, - ~onError=?, - ~onShellReady=?, - ~onShellError=?, - ~progressiveChunkSize=?, - element, - ) => - renderToPipeableStream( - element, - options( - ~bootstrapScriptContent?, - ~bootstrapScripts?, - ~bootstrapModules?, - ~identifierPrefix?, - ~namespaceURI?, - ~nonce?, - ~onAllReady?, - ~onError?, - ~onShellReady?, - ~onShellError?, - ~progressiveChunkSize?, - (), - ), - ); -}; - -module TestUtils = { - type undefined = Js.undefined(unit); - - let undefined: undefined = Js.Undefined.empty; - - [@mel.module "react-dom/test-utils"] - external reactAct: ((. unit) => undefined) => unit = "act"; - - let act: (unit => unit) => unit = - func => { - let reactFunc = - (.) => { - func(); - undefined; - }; - reactAct(reactFunc); - }; - - [@mel.module "react-dom/test-utils"] - external reactActAsync: - ((. unit) => Js.Promise.t('a)) => Js.Promise.t(unit) = - "act"; - - let actAsync = func => { - let reactFunc = - (.) => { - func(); - }; - reactActAsync(reactFunc); - }; - - [@mel.module "react-dom/test-utils"] - external isElement: 'element => bool = "isElement"; - - [@mel.module "react-dom/test-utils"] - external isElementOfType: ('element, React.component('props)) => bool = - "isElementOfType"; - - [@mel.module "react-dom/test-utils"] - external isDOMComponent: 'element => bool = "isDOMComponent"; - - [@mel.module "react-dom/test-utils"] - external isCompositeComponent: 'element => bool = "isCompositeComponent"; - - [@mel.module "react-dom/test-utils"] - external isCompositeComponentWithType: - ('element, React.component('props)) => bool = - "isCompositeComponentWithType"; - - module Simulate = { - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external click: Dom.element => unit = "click"; - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external clickWithEvent: (Dom.element, 'event) => unit = "click"; - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external change: Dom.element => unit = "change"; - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external blur: Dom.element => unit = "blur"; - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external changeWithEvent: (Dom.element, 'event) => unit = "change"; - let changeWithValue = (element, value) => { - let event = { - "target": { - "value": value, - }, - }; - changeWithEvent(element, event); - }; - let changeWithChecked = (element, value) => { - let event = { - "target": { - "checked": value, - }, - }; - changeWithEvent(element, event); - }; - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external canPlay: Dom.element => unit = "canPlay"; - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external timeUpdate: Dom.element => unit = "timeUpdate"; - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external ended: Dom.element => unit = "ended"; - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external focus: Dom.element => unit = "focus"; - }; - - external document: Dom.document = "document"; - - [@mel.send] - external querySelector: (Dom.element, string) => option(Dom.element) = - "querySelector"; - - [@mel.send] - external querySelectorAll: - (Dom.element, string) => Js.Array.array_like(Dom.element) = - "querySelectorAll"; - - [@mel.get] external textContent: Dom.element => string = "textContent"; - [@mel.get] external body: Dom.document => option(Dom.element) = "body"; - [@mel.send] - external createElement: (Dom.document, string) => Dom.element = - "createElement"; - [@mel.send] external remove: Dom.element => unit = "remove"; - [@mel.send] - external appendChild: (Dom.element, Dom.element) => Dom.element = - "appendChild"; - - let querySelectorAll = (element, string) => { - Js.Array.from(querySelectorAll(element, string)); - }; - - module DOM = { - [@mel.return nullable] [@mel.get] - external value: Dom.element => option(string) = "value"; - - let findBySelector = (element, selector) => - querySelector(element, selector); - - let findByAllSelector = (element, selector) => - querySelectorAll(element, selector); - - let findBySelectorAndTextContent = (element, selector, content) => - querySelectorAll(element, selector) - |> Array.find_opt(node => node->textContent === content); - - let findBySelectorAndPartialTextContent = (element, selector, content) => - querySelectorAll(element, selector) - |> Array.find_opt(node => - node->textContent->Js.String2.includes(content) - ); - }; - - let prepareContainer = (container: ref(option(Dom.element)), ()) => { - let containerElement = document->createElement("div"); - let _: option(_) = - Option.map( - body => body->appendChild(containerElement), - document->body, - ); - container := Some(containerElement); - }; - - let cleanupContainer = (container: ref(option(Dom.element)), ()) => { - let _: option(_) = Option.map(remove, container^); - container := None; - }; - - let getContainer = container => { - container.contents->Option.get; - }; -}; diff --git a/src/ReactDOM.rei b/src/ReactDOM.rei index abc0a2f95..22e5585a8 100644 --- a/src/ReactDOM.rei +++ b/src/ReactDOM.rei @@ -433,64 +433,6 @@ module Style: { "Object.assign"; }; -module Server: { - [@mel.module "react-dom/server"] - external renderToString: React.element => string = "renderToString"; - - [@mel.module "react-dom/server"] - external renderToStaticMarkup: React.element => string = - "renderToStaticMarkup"; - - [@deriving abstract] - type options = { - [@mel.optional] - bootstrapScriptContent: option(string), - [@mel.optional] - bootstrapScripts: option(array(string)), - [@mel.optional] - bootstrapModules: option(array(string)), - [@mel.optional] - identifierPrefix: option(string), - [@mel.optional] - namespaceURI: option(string), - [@mel.optional] - nonce: option(string), - [@mel.optional] - onAllReady: option(unit => unit), - [@mel.optional] - onError: option(Js.Exn.t => unit), - [@mel.optional] - onShellReady: option(unit => unit), - [@mel.optional] - onShellError: option(Js.Exn.t => unit), - [@mel.optional] - progressiveChunkSize: option(int), - }; - - type pipeableStream = { - /* Using empty object instead of Node.stream since Melange don't provide a binding to node's Stream (https://nodejs.org/api/stream.html) */ - pipe: Js.t({.}) => unit, - abort: unit => unit, - }; - - let renderToPipeableStream: - ( - ~bootstrapScriptContent: string=?, - ~bootstrapScripts: array(string)=?, - ~bootstrapModules: array(string)=?, - ~identifierPrefix: string=?, - ~namespaceURI: string=?, - ~nonce: string=?, - ~onAllReady: unit => unit=?, - ~onError: Js.Exn.t => unit=?, - ~onShellReady: unit => unit=?, - ~onShellError: Js.Exn.t => unit=?, - ~progressiveChunkSize: int=?, - React.element - ) => - pipeableStream; -}; - [@mel.return nullable] external querySelector: string => option(Dom.element) = "document.querySelector"; @@ -1604,66 +1546,3 @@ external jsxs: (string, domProps) => React.element = "jsxs"; [@mel.module "react/jsx-runtime"] external jsxsKeyed: (string, domProps, ~key: string=?, unit) => React.element = "jsxs"; - -module TestUtils: { - let act: (unit => unit) => unit; - - let actAsync: (unit => Js.Promise.t('a)) => Js.Promise.t(unit); - - [@mel.module "react-dom/test-utils"] - external isElement: 'element => bool = "isElement"; - - [@mel.module "react-dom/test-utils"] - external isElementOfType: ('element, React.component('props)) => bool = - "isElementOfType"; - - [@mel.module "react-dom/test-utils"] - external isDOMComponent: 'element => bool = "isDOMComponent"; - - [@mel.module "react-dom/test-utils"] - external isCompositeComponent: 'element => bool = "isCompositeComponent"; - - [@mel.module "react-dom/test-utils"] - external isCompositeComponentWithType: - ('element, React.component('props)) => bool = - "isCompositeComponentWithType"; - - module Simulate: { - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external click: Dom.element => unit = "click"; - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external clickWithEvent: (Dom.element, 'event) => unit = "click"; - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external change: Dom.element => unit = "change"; - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external blur: Dom.element => unit = "blur"; - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external changeWithEvent: (Dom.element, 'event) => unit = "change"; - let changeWithValue: (Dom.element, string) => unit; - let changeWithChecked: (Dom.element, bool) => unit; - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external canPlay: Dom.element => unit = "canPlay"; - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external timeUpdate: Dom.element => unit = "timeUpdate"; - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external ended: Dom.element => unit = "ended"; - [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] - external focus: Dom.element => unit = "focus"; - }; - - module DOM: { - [@mel.return nullable] [@mel.get] - external value: Dom.element => option(string) = "value"; - - let findBySelector: (Dom.element, string) => option(Dom.element); - let findByAllSelector: (Dom.element, string) => array(Dom.element); - let findBySelectorAndTextContent: - (Dom.element, string, string) => option(Dom.element); - let findBySelectorAndPartialTextContent: - (Dom.element, string, string) => option(Dom.element); - }; - - let prepareContainer: (Stdlib.ref(option(Dom.element)), unit) => unit; - let cleanupContainer: (Stdlib.ref(option(Dom.element)), unit) => unit; - let getContainer: Stdlib.ref(option(Dom.element)) => Dom.element; -}; diff --git a/src/ReactDOMServer.re b/src/ReactDOMServer.re new file mode 100644 index 000000000..e53898ad9 --- /dev/null +++ b/src/ReactDOMServer.re @@ -0,0 +1,75 @@ +[@mel.module "react-dom/server"] +external renderToString: React.element => string = "renderToString"; + +[@mel.module "react-dom/server"] +external renderToStaticMarkup: React.element => string = + "renderToStaticMarkup"; + +[@deriving abstract] +type options = { + [@mel.optional] + bootstrapScriptContent: option(string), + [@mel.optional] + bootstrapScripts: option(array(string)), + [@mel.optional] + bootstrapModules: option(array(string)), + [@mel.optional] + identifierPrefix: option(string), + [@mel.optional] + namespaceURI: option(string), + [@mel.optional] + nonce: option(string), + [@mel.optional] + onAllReady: option(unit => unit), + [@mel.optional] + onError: option(Js.Exn.t => unit), + [@mel.optional] + onShellReady: option(unit => unit), + [@mel.optional] + onShellError: option(Js.Exn.t => unit), + [@mel.optional] + progressiveChunkSize: option(int), +}; + +type pipeableStream = { + /* Using empty object instead of Node.stream since Melange don't provide a binding to node's Stream (https://nodejs.org/api/stream.html) */ + pipe: Js.t({.}) => unit, + abort: unit => unit, +}; + +[@mel.module "react-dom/server"] +external renderToPipeableStream: (React.element, options) => pipeableStream = + "renderToPipeableStream"; + +let renderToPipeableStream = + ( + ~bootstrapScriptContent=?, + ~bootstrapScripts=?, + ~bootstrapModules=?, + ~identifierPrefix=?, + ~namespaceURI=?, + ~nonce=?, + ~onAllReady=?, + ~onError=?, + ~onShellReady=?, + ~onShellError=?, + ~progressiveChunkSize=?, + element, + ) => + renderToPipeableStream( + element, + options( + ~bootstrapScriptContent?, + ~bootstrapScripts?, + ~bootstrapModules?, + ~identifierPrefix?, + ~namespaceURI?, + ~nonce?, + ~onAllReady?, + ~onError?, + ~onShellReady?, + ~onShellError?, + ~progressiveChunkSize?, + (), + ), + ); diff --git a/src/ReactDOMServer.rei b/src/ReactDOMServer.rei new file mode 100644 index 000000000..49567a750 --- /dev/null +++ b/src/ReactDOMServer.rei @@ -0,0 +1,55 @@ +[@mel.module "react-dom/server"] +external renderToString: React.element => string = "renderToString"; + +[@mel.module "react-dom/server"] +external renderToStaticMarkup: React.element => string = + "renderToStaticMarkup"; + +[@deriving abstract] +type options = { + [@mel.optional] + bootstrapScriptContent: option(string), + [@mel.optional] + bootstrapScripts: option(array(string)), + [@mel.optional] + bootstrapModules: option(array(string)), + [@mel.optional] + identifierPrefix: option(string), + [@mel.optional] + namespaceURI: option(string), + [@mel.optional] + nonce: option(string), + [@mel.optional] + onAllReady: option(unit => unit), + [@mel.optional] + onError: option(Js.Exn.t => unit), + [@mel.optional] + onShellReady: option(unit => unit), + [@mel.optional] + onShellError: option(Js.Exn.t => unit), + [@mel.optional] + progressiveChunkSize: option(int), +}; + +type pipeableStream = { + /* Using empty object instead of Node.stream since Melange don't provide a binding to node's Stream (https://nodejs.org/api/stream.html) */ + pipe: Js.t({.}) => unit, + abort: unit => unit, +}; + +let renderToPipeableStream: + ( + ~bootstrapScriptContent: string=?, + ~bootstrapScripts: array(string)=?, + ~bootstrapModules: array(string)=?, + ~identifierPrefix: string=?, + ~namespaceURI: string=?, + ~nonce: string=?, + ~onAllReady: unit => unit=?, + ~onError: Js.Exn.t => unit=?, + ~onShellReady: unit => unit=?, + ~onShellError: Js.Exn.t => unit=?, + ~progressiveChunkSize: int=?, + React.element + ) => + pipeableStream; diff --git a/src/ReactDOMTestUtils.re b/src/ReactDOMTestUtils.re new file mode 100644 index 000000000..82c5d606d --- /dev/null +++ b/src/ReactDOMTestUtils.re @@ -0,0 +1,143 @@ +type undefined = Js.undefined(unit); + +let undefined: undefined = Js.Undefined.empty; + +[@mel.module "react-dom/test-utils"] +external reactAct: ((. unit) => undefined) => unit = "act"; + +let act: (unit => unit) => unit = + func => { + let reactFunc = + (.) => { + func(); + undefined; + }; + reactAct(reactFunc); + }; + +[@mel.module "react-dom/test-utils"] +external reactActAsync: ((. unit) => Js.Promise.t('a)) => Js.Promise.t(unit) = + "act"; + +let actAsync = func => { + let reactFunc = + (.) => { + func(); + }; + reactActAsync(reactFunc); +}; + +[@mel.module "react-dom/test-utils"] +external isElement: 'element => bool = "isElement"; + +[@mel.module "react-dom/test-utils"] +external isElementOfType: ('element, React.component('props)) => bool = + "isElementOfType"; + +[@mel.module "react-dom/test-utils"] +external isDOMComponent: 'element => bool = "isDOMComponent"; + +[@mel.module "react-dom/test-utils"] +external isCompositeComponent: 'element => bool = "isCompositeComponent"; + +[@mel.module "react-dom/test-utils"] +external isCompositeComponentWithType: + ('element, React.component('props)) => bool = + "isCompositeComponentWithType"; + +module Simulate = { + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external click: Dom.element => unit = "click"; + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external clickWithEvent: (Dom.element, 'event) => unit = "click"; + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external change: Dom.element => unit = "change"; + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external blur: Dom.element => unit = "blur"; + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external changeWithEvent: (Dom.element, 'event) => unit = "change"; + let changeWithValue = (element, value) => { + let event = { + "target": { + "value": value, + }, + }; + changeWithEvent(element, event); + }; + let changeWithChecked = (element, value) => { + let event = { + "target": { + "checked": value, + }, + }; + changeWithEvent(element, event); + }; + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external canPlay: Dom.element => unit = "canPlay"; + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external timeUpdate: Dom.element => unit = "timeUpdate"; + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external ended: Dom.element => unit = "ended"; + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external focus: Dom.element => unit = "focus"; +}; + +external document: Dom.document = "document"; + +[@mel.send] +external querySelector: (Dom.element, string) => option(Dom.element) = + "querySelector"; + +[@mel.send] +external querySelectorAll: + (Dom.element, string) => Js.Array.array_like(Dom.element) = + "querySelectorAll"; + +[@mel.get] external textContent: Dom.element => string = "textContent"; +[@mel.get] external body: Dom.document => option(Dom.element) = "body"; +[@mel.send] +external createElement: (Dom.document, string) => Dom.element = + "createElement"; +[@mel.send] external remove: Dom.element => unit = "remove"; +[@mel.send] +external appendChild: (Dom.element, Dom.element) => Dom.element = + "appendChild"; + +let querySelectorAll = (element, string) => { + Js.Array.from(querySelectorAll(element, string)); +}; + +module DOM = { + [@mel.return nullable] [@mel.get] + external value: Dom.element => option(string) = "value"; + + let findBySelector = (element, selector) => + querySelector(element, selector); + + let findByAllSelector = (element, selector) => + querySelectorAll(element, selector); + + let findBySelectorAndTextContent = (element, selector, content) => + querySelectorAll(element, selector) + |> Array.find_opt(node => node->textContent === content); + + let findBySelectorAndPartialTextContent = (element, selector, content) => + querySelectorAll(element, selector) + |> Array.find_opt(node => node->textContent->Js.String2.includes(content)); +}; + +let prepareContainer = (container: ref(option(Dom.element)), ()) => { + let containerElement = document->createElement("div"); + let _: option(_) = + Option.map(body => body->appendChild(containerElement), document->body); + container := Some(containerElement); +}; + +let cleanupContainer = (container: ref(option(Dom.element)), ()) => { + let _: option(_) = Option.map(remove, container^); + container := None; +}; + +let getContainer = container => { + container.contents->Option.get; +}; diff --git a/src/ReactDOMTestUtils.rei b/src/ReactDOMTestUtils.rei new file mode 100644 index 000000000..5f67f3345 --- /dev/null +++ b/src/ReactDOMTestUtils.rei @@ -0,0 +1,60 @@ +let act: (unit => unit) => unit; + +let actAsync: (unit => Js.Promise.t('a)) => Js.Promise.t(unit); + +[@mel.module "react-dom/test-utils"] +external isElement: 'element => bool = "isElement"; + +[@mel.module "react-dom/test-utils"] +external isElementOfType: ('element, React.component('props)) => bool = + "isElementOfType"; + +[@mel.module "react-dom/test-utils"] +external isDOMComponent: 'element => bool = "isDOMComponent"; + +[@mel.module "react-dom/test-utils"] +external isCompositeComponent: 'element => bool = "isCompositeComponent"; + +[@mel.module "react-dom/test-utils"] +external isCompositeComponentWithType: + ('element, React.component('props)) => bool = + "isCompositeComponentWithType"; + +module Simulate: { + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external click: Dom.element => unit = "click"; + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external clickWithEvent: (Dom.element, 'event) => unit = "click"; + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external change: Dom.element => unit = "change"; + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external blur: Dom.element => unit = "blur"; + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external changeWithEvent: (Dom.element, 'event) => unit = "change"; + let changeWithValue: (Dom.element, string) => unit; + let changeWithChecked: (Dom.element, bool) => unit; + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external canPlay: Dom.element => unit = "canPlay"; + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external timeUpdate: Dom.element => unit = "timeUpdate"; + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external ended: Dom.element => unit = "ended"; + [@mel.module "react-dom/test-utils"] [@mel.scope "Simulate"] + external focus: Dom.element => unit = "focus"; +}; + +module DOM: { + [@mel.return nullable] [@mel.get] + external value: Dom.element => option(string) = "value"; + + let findBySelector: (Dom.element, string) => option(Dom.element); + let findByAllSelector: (Dom.element, string) => array(Dom.element); + let findBySelectorAndTextContent: + (Dom.element, string, string) => option(Dom.element); + let findBySelectorAndPartialTextContent: + (Dom.element, string, string) => option(Dom.element); +}; + +let prepareContainer: (Stdlib.ref(option(Dom.element)), unit) => unit; +let cleanupContainer: (Stdlib.ref(option(Dom.element)), unit) => unit; +let getContainer: Stdlib.ref(option(Dom.element)) => Dom.element; diff --git a/src/dune b/src/dune index d1b80a874..2d1b62e29 100644 --- a/src/dune +++ b/src/dune @@ -7,6 +7,8 @@ (modules React ReactDOM + ReactDOMServer + ReactDOMTestUtils ReactTestRenderer ReasonReactRouter ReasonReactErrorBoundary) diff --git a/test/Hooks__test.re b/test/Hooks__test.re index 8c0869dbf..20b942a46 100644 --- a/test/Hooks__test.re +++ b/test/Hooks__test.re @@ -1,6 +1,6 @@ open Jest; open Jest.Expect; -open ReactDOM.TestUtils; +open ReactDOMTestUtils; open Belt; /* https://react.dev/blog/2022/03/08/react-18-upgrade-guide#configuring-your-testing-environment */ diff --git a/test/ReactDOM__test.re b/test/ReactDOM__test.re index be5554d2e..07d583612 100644 --- a/test/ReactDOM__test.re +++ b/test/ReactDOM__test.re @@ -16,14 +16,14 @@ describe("React.DOM", () => { describe("React.DOM.Server", () => { test("renderToString", () => { let string = - ReactDOM.Server.renderToString( + ReactDOMServer.renderToString(
"Hello world!"->React.string
, ); expect(string)->toBe("
Hello world!
"); }); test("renderToStaticMarkup", () => { let string = - ReactDOM.Server.renderToStaticMarkup( + ReactDOMServer.renderToStaticMarkup(
"Hello world!"->React.string
, ); expect(string)->toBe("
Hello world!
"); @@ -53,8 +53,8 @@ describe("React.DOM", () => { hasErrored := true; }, ); - let {pipe, abort: _}: ReactDOM.Server.pipeableStream = - ReactDOM.Server.renderToPipeableStream( + let {pipe, abort: _}: ReactDOMServer.pipeableStream = + ReactDOMServer.renderToPipeableStream(
"Hello world!"->React.string
, ); pipe(stream); diff --git a/test/React__test.re b/test/React__test.re index 9ec6ef7b4..8b26c8339 100644 --- a/test/React__test.re +++ b/test/React__test.re @@ -1,6 +1,6 @@ open Jest; open Jest.Expect; -open ReactDOM.TestUtils; +open ReactDOMTestUtils; open Belt; /* https://react.dev/blog/2022/03/08/react-18-upgrade-guide#configuring-your-testing-environment */