Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add React 18 bindings #756

Merged
merged 25 commits into from
Oct 9, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add bindings
  • Loading branch information
davesnx authored and anmonteiro committed Sep 20, 2023
commit 4828ec6c25d4c1a2ce40716245d258f25da97483
2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
@@ -67,7 +67,7 @@
default = pkgs.mkShell {
dontDetectOcamlConflicts = true;
inputsFrom = pkgs.lib.attrValues packages;
nativeBuildInputs = with pkgs.ocamlPackages; [ ocamlformat ];
nativeBuildInputs = with pkgs.ocamlPackages; [ ocamlformat pkgs.nodejs_latest ];
propagatedBuildInputs = with pkgs.ocamlPackages; [ merlin ];
};
};
7,114 changes: 1,195 additions & 5,919 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -26,9 +26,9 @@
"homepage": "https://reasonml.github.io/reason-react/",
"devDependencies": {
"jest": "^26.0.1",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-test-renderer": "^18.0.0"
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-test-renderer": "^18.2.0"
},
"jest": {
"moduleDirectories": [
34 changes: 4 additions & 30 deletions src/React.re
Original file line number Diff line number Diff line change
@@ -141,40 +141,14 @@ module Suspense = {
"Suspense";
};

/* Experimental React.SuspenseList */
module SuspenseList = {
type revealOrder;
type tail;
[@mel.obj]
external makeProps:
(
~children: element=?,
~revealOrder: [ | `forwards | `backwards | `together]=?,
~tail: [ | `collapsed | `hidden]=?,
unit
) =>
{
.
"children": option(element),
"revealOrder": option(revealOrder),
"tail": option(tail),
};

[@mel.module "react"]
external make:
component({
.
"children": option(element),
"revealOrder": option(revealOrder),
"tail": option(tail),
}) =
"SuspenseList";
};

include Hooks;

[@mel.set]
external setDisplayName: (component('props), string) => unit = "displayName";

[@mel.get] [@mel.return nullable]
external displayName: component('props) => option(string) = "displayName";

[@mel.module "react"]
external useDebugValue: ('value, ~format: 'value => string=?, unit) => unit =
"useDebugValue";
177 changes: 134 additions & 43 deletions src/React.rei
Original file line number Diff line number Diff line change
@@ -156,35 +156,6 @@ module Suspense: {
"Suspense";
};

/* Experimental React.SuspenseList */
module SuspenseList: {
type revealOrder;
type tail;
[@mel.obj]
external makeProps:
(
~children: element=?,
~revealOrder: [ | `forwards | `backwards | `together]=?,
~tail: [ | `collapsed | `hidden]=?,
unit
) =>
{
.
"children": option(element),
"revealOrder": option(revealOrder),
"tail": option(tail),
};

[@mel.module "react"]
external make:
component({
.
"children": option(element),
"revealOrder": option(revealOrder),
"tail": option(tail),
}) =
"SuspenseList";
};
/* HOOKS */

/*
@@ -214,6 +185,16 @@ external useReducerWithMapState:
('state, 'action => unit) =
"useReducer";

[@mel.module "react"]
external useSyncExternalStore:
(
~subscribe: [@mel.uncurry] (unit => unit),
~getSnapshot: [@mel.uncurry] (unit => 'snapshot),
~getServerSnapshot: [@mel.uncurry] (unit => 'snapshot)=?
) =>
'snapshot =
"useSyncExternalStore";

[@mel.module "react"]
external useEffect: ([@mel.uncurry] (unit => option(unit => unit))) => unit =
"useEffect";
@@ -263,6 +244,56 @@ external useEffect7:
unit =
"useEffect";

[@mel.module "react"]
external useInsertionEffect:
([@mel.uncurry] (unit => option(unit => unit))) => unit =
"useInsertionEffect";
[@mel.module "react"]
external useInsertionEffect0:
(
[@mel.uncurry] (unit => option(unit => unit)),
[@mel.as {json|[]|json}] _
) =>
unit =
"useInsertionEffect";
[@mel.module "react"]
external useInsertionEffect1:
([@mel.uncurry] (unit => option(unit => unit)), array('a)) => unit =
"useInsertionEffect";
[@mel.module "react"]
external useInsertionEffect2:
([@mel.uncurry] (unit => option(unit => unit)), ('a, 'b)) => unit =
"useInsertionEffect";
[@mel.module "react"]
external useInsertionEffect3:
([@mel.uncurry] (unit => option(unit => unit)), ('a, 'b, 'c)) => unit =
"useInsertionEffect";
[@mel.module "react"]
external useInsertionEffect4:
([@mel.uncurry] (unit => option(unit => unit)), ('a, 'b, 'c, 'd)) => unit =
"useInsertionEffect";
[@mel.module "react"]
external useInsertionEffect5:
([@mel.uncurry] (unit => option(unit => unit)), ('a, 'b, 'c, 'd, 'e)) =>
unit =
"useInsertionEffect";
[@mel.module "react"]
external useInsertionEffect6:
(
[@mel.uncurry] (unit => option(unit => unit)),
('a, 'b, 'c, 'd, 'e, 'f)
) =>
unit =
"useInsertionEffect";
[@mel.module "react"]
external useInsertionEffect7:
(
[@mel.uncurry] (unit => option(unit => unit)),
('a, 'b, 'c, 'd, 'e, 'f, 'g)
) =>
unit =
"useInsertionEffect";

[@mel.module "react"]
external useLayoutEffect:
([@mel.uncurry] (unit => option(unit => unit))) => unit =
@@ -371,6 +402,9 @@ external useCallback7: ('fn, ('a, 'b, 'c, 'd, 'e, 'f, 'g)) => 'fn =
external useContext: Context.t('any) => 'any = "useContext";

[@mel.module "react"] external useRef: 'value => ref('value) = "useRef";
[@mel.module "react"] external useId: unit => string = "useId";

[@mel.module "react"] external useDeferredValue: 'a => 'a = "useDeferredValue";

[@mel.module "react"]
external useImperativeHandle0:
@@ -519,20 +553,22 @@ module Uncurried: {
"useCallback";
};

type transitionConfig = {timeoutMs: int};

[@mel.module "react"]
external useTransition:
(~config: transitionConfig=?, unit) =>
(callback(callback(unit, unit), unit), bool) =
external useTransition: unit => (bool, callback(callback(unit, unit), unit)) =
"useTransition";

[@mel.module "react"] external use: Js.Promise.t('a) => 'a = "use";

[@mel.set]
external setDisplayName: (component('props), string) => unit = "displayName";

[@mel.get] [@mel.return nullable]
external displayName: component('props) => option(string) = "displayName";

[@mel.module "react"]
external useDebugValue: ('value, ~format: 'value => string=?, unit) => unit =
"useDebugValue";

module Event: {
/* This is the whole synthetic event system of ReactJS/ReasonReact. The first module `Synthetic` represents
the generic synthetic event. The rest are the specific ones.
@@ -1511,26 +1547,78 @@ module DOM: {

[@mel.module "react-dom/server"]
external renderToStaticMarkup: element => string = "renderToStaticMarkup";

type error = {.};

[@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(error => unit),
[@mel.optional]
onShellReady: option(unit => unit),
[@mel.optional]
onShellError: option(error => 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: {.} => unit,
abort: unit => unit,
};

let renderToPipeableStream:
(
~bootstrapScriptContent: string=?,
~bootstrapScripts: array(string)=?,
~bootstrapModules: array(string)=?,
~identifierPrefix: string=?,
~namespaceURI: string=?,
~nonce: string=?,
~onAllReady: unit => unit=?,
~onError: error => unit=?,
~onShellReady: unit => unit=?,
~onShellError: error => unit=?,
~progressiveChunkSize: int=?,
element
) =>
pipeableStream;
};

[@mel.return nullable]
external querySelector: string => option(Dom.element) =
"document.querySelector";

[@mel.module "react-dom"]
external render: (element, Dom.element) => unit = "render";

module Experimental: {
module Client: {
type root;

[@mel.module "react-dom"]
external createRoot: Dom.element => root = "createRoot";
[@mel.send] external render: (root, element) => unit = "render";

[@mel.module "react-dom"]
external createBlockingRoot: Dom.element => root = "createBlockingRoot";
[@mel.send] external unmount: (root, unit) => unit = "unmount";

[@mel.send] external render: (root, element) => unit = "render";
[@mel.module "react-dom/client"]
external createRoot: Dom.element => root = "createRoot";

[@mel.module "react-dom/client"]
external hydrateRoot: (Dom.element, element) => root = "hydrateRoot";
};
[@mel.module "react-dom"]
external render: (element, Dom.element) => unit = "render";

[@mel.module "react-dom"]
external hydrate: (element, Dom.element) => unit = "hydrate";
@@ -1542,6 +1630,9 @@ module DOM: {
external unmountComponentAtNode: Dom.element => unit =
"unmountComponentAtNode";

[@mel.module "react-dom"]
external flushSync: (unit => unit) => unit = "flushSync";

external domElementToObj: Dom.element => Js.t({..}) = "%identity";

type style = Style.t;
23 changes: 14 additions & 9 deletions src/dOM.re
Original file line number Diff line number Diff line change
@@ -10,21 +10,23 @@
external querySelector: string => option(Dom.element) =
"document.querySelector";

[@mel.module "react-dom"]
external render: (Types.element, Dom.element) => unit = "render";

module Experimental = {
module Client = {
type root;

[@mel.module "react-dom"]
external createRoot: Dom.element => root = "createRoot";
[@mel.send] external render: (root, Types.element) => unit = "render";

[@mel.module "react-dom"]
external createBlockingRoot: Dom.element => root = "createBlockingRoot";
[@mel.send] external unmount: (root, unit) => unit = "unmount";

[@mel.send] external render: (root, Types.element) => unit = "render";
[@mel.module "react-dom/client"]
external createRoot: Dom.element => root = "createRoot";

[@mel.module "react-dom/client"]
external hydrateRoot: (Dom.element, Types.element) => root = "hydrateRoot";
};

[@mel.module "react-dom"]
external render: (Types.element, Dom.element) => unit = "render";

[@mel.module "react-dom"]
external hydrate: (Types.element, Dom.element) => unit = "hydrate";

@@ -36,6 +38,9 @@ external createPortal: (Types.element, Dom.element) => Types.element =
external unmountComponentAtNode: Dom.element => unit =
"unmountComponentAtNode";

[@mel.module "react-dom"]
external flushSync: (unit => unit) => unit = "flushSync";

external domElementToObj: Dom.element => Js.t({..}) = "%identity";

type style = DOMStyle.t;
Loading