Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ help: ## Print this help message

.PHONY: build
build: ## Build the project, including non installable libraries and executables
@$(DUNE) build @@default
@$(DUNE) build @all

.PHONY: build-prod
build-prod: ## Build for production (--profile=prod)
Expand Down
2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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 ];
};
};
Expand Down
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
Expand Up @@ -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": [
Expand Down
4 changes: 3 additions & 1 deletion ppx/test/input.re
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,9 @@ module External = {
{|require("my-react-library").MyReactComponent|};
};

module type X_int = {let x: int;};
module type X_int = {
let x: int;
};

module Func = (M: X_int) => {
let x = M.x + 1;
Expand Down
34 changes: 1 addition & 33 deletions src/React.re
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@ module DOM = DOM;
module ErrorBoundary = ErrorBoundary;
module Event = Event;
module Router = Router;

type element = Types.element;

external null: element = "null";

external float: float => element = "%identity";
external int: int => element = "%identity";
external string: string => element = "%identity";

external array: array(element) => element = "%identity";

type componentLike('props, 'return) = Types.componentLike('props, 'return);

type component('props) = componentLike('props, element);

/* this function exists to prepare for making `component` abstract */
Expand Down Expand Up @@ -141,36 +139,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";
};

include Hooks;

[@mel.set]
Expand Down
196 changes: 151 additions & 45 deletions src/React.rei
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ type componentLike('props, 'return) = 'props => 'return;
type component('props) = componentLike('props, element);

external null: element = "null";

external float: float => element = "%identity";
external int: int => element = "%identity";
external string: string => element = "%identity";

external array: array(element) => element = "%identity";

/* this function exists to prepare for making `component` abstract */
Expand Down Expand Up @@ -156,35 +154,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 */

/*
Expand Down Expand Up @@ -214,6 +183,25 @@ external useReducerWithMapState:
('state, 'action => unit) =
"useReducer";

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

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

[@mel.module "react"]
external useEffect: ([@mel.uncurry] (unit => option(unit => unit))) => unit =
"useEffect";
Expand Down Expand Up @@ -263,6 +251,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 =
Expand Down Expand Up @@ -371,6 +409,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:
Expand Down Expand Up @@ -519,20 +560,25 @@ 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";

module Experimental: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we also include SuspenseList in this module?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SuspenseList got unstable by React in facebook/react#27061 and facebook/react#27056 (comment)

I'm fine keeping it but it's very useless

/* This module is used to bind to APIs for future versions of React. There is no guarantee of backwards compatibility or stability. */
[@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.
Expand Down Expand Up @@ -1511,27 +1557,84 @@ module DOM: {

[@mel.module "react-dom/server"]
external renderToStaticMarkup: 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: {.} => 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=?,
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";
};

[@deprecated
"This function will be removed in the next release. Use React.DOM.Client.render instead."
]
[@mel.module "react-dom"]
external render: (element, Dom.element) => unit = "render";

[@deprecated
"This function will be removed in the next release. Use React.DOM.Client.hydrateRoot instead."
]
[@mel.module "react-dom"]
external hydrate: (element, Dom.element) => unit = "hydrate";

Expand All @@ -1542,6 +1645,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;
Expand Down
Loading