Skip to content

Commit

Permalink
fix(api): fix typings for accept property
Browse files Browse the repository at this point in the history
BREAKING CHANGE: accept property uses polymorphic variants
instead of regular one
  • Loading branch information
erykpiast committed Sep 2, 2020
1 parent 497c937 commit 5b53bf6
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 22 deletions.
62 changes: 47 additions & 15 deletions __tests__/ReactDropzone_test.re
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,58 @@ open ExpectJs;

Enzyme.configureEnzyme(Enzyme.react_16_adapter());

let renderReason = () => (
/* react-dropzone uses `forwardRef` and hooks on the root element
* what causes issues when rendered directly through shallow renderer
* Using Fragment (</>) triggers another kind of error, so plain old div
* isn't as bad as you may think
*/
<div>
<ReactDropzone>
{(_) => ReasonReact.null}
</ReactDropzone>
</div>
) |> Enzyme.shallow |> Enzyme.Shallow.childAt(0);

let renderJs = [%bs.raw "() => React.createElement(require('react-dropzone').default, {}, () => null)"];
let renderReason = (~acceptProp=None, ()) =>
{
let children = _ => ReasonReact.null;

/* react-dropzone uses `forwardRef` and hooks on the root element
* what causes issues when rendered directly through shallow renderer
* Using Fragment (</>) triggers another kind of error, so plain old div
* isn't as bad as you may think
*/
<div>
{switch (acceptProp) {
| None => <ReactDropzone> children </ReactDropzone>
| Some(accept) => <ReactDropzone accept> children </ReactDropzone>
}}
</div>;
}
|> Enzyme.shallow
|> Enzyme.Shallow.childAt(0);

let renderJs = [%bs.raw
"(accept) => React.createElement(require('react-dropzone').default, { accept }, () => null)"
];

describe("jsx3", () => {
test("output equal to direct JS rendering", () => {
let reasonComponent = renderReason();
let jsComponent = [%bs.raw "renderJs()"];

expect(Enzyme.Shallow.equals(jsComponent, reasonComponent)) |> toBe(true)
expect(Enzyme.Shallow.equals(jsComponent, reasonComponent))
|> toBe(true);
});

describe("accept property", () => {
test("single", () => {
let reasonComponent =
renderReason(~acceptProp=Some(`single("application/json")), ());
let jsComponent = [%bs.raw "renderJs('application/json')"];

expect(Enzyme.Shallow.equals(jsComponent, reasonComponent))
|> toBe(true);
});

test("multi", () => {
let reasonComponent =
renderReason(
~acceptProp=Some(`many(["application/json", "text/json"])),
(),
);
let jsComponent = [%bs.raw "renderJs(['application/json', 'text/json'])"];

expect(Enzyme.Shallow.equals(jsComponent, reasonComponent))
|> toBe(true);
});
});
});
24 changes: 17 additions & 7 deletions src/ReactDropzone.re
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
open ReactDropzone__Utils;

type accept =
| Single(string)
| Multi(array(string));

[@bs.deriving abstract]
type file = {
lastModified: int,
Expand All @@ -22,6 +18,20 @@ type onDragOver = ReactEvent.Mouse.t => unit;
type onDragLeave = ReactEvent.Mouse.t => unit;
type ref = Js.nullable(Dom.element) => unit;

module Accept = {
type t = [ | `single(string) | `many(list(string))];

type js;

external makeString: string => js = "%identity";
external makeArray: array(string) => js = "%identity";

let make =
fun
| `single(s) => s |> makeString
| `many(m) => m |> Array.of_list |> makeArray;
};

module GetInputProps = {
type onChange = ReactEvent.Form.t => unit;

Expand Down Expand Up @@ -269,7 +279,7 @@ module Children = {
[@bs.module "react-dropzone"] [@react.component]
external make:
(
~accept: accept=?,
~accept: Accept.js=?,
~disabled: bool=?,
~maxSize: int=?,
~minSize: int=?,
Expand Down Expand Up @@ -313,8 +323,8 @@ let makeProps = (
~onKeyDown=?,
~preventDropOnDocument=?,
~children
) => makeProps(
~accept?,
) => makeProps(
~accept=?accept <$> Accept.make,
~disabled?,
~maxSize?,
~minSize?,
Expand Down
5 changes: 5 additions & 0 deletions src/ReactDropzone__Utils.ml
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
let unary (fn: 'a) : 'a = [%raw "(a) => fn(a)" ];;
let (||>) f g x = g(f(x));;
let (<$>) option mapper = (
match option with
| None -> None
| Some value -> Some (mapper value)
);;

0 comments on commit 5b53bf6

Please sign in to comment.