bs-webapi-incubator
bs-webapi-incubator copied to clipboard
How to use HtmlInputElement (focus, select) ?
I want to do simple thing. Just focus and select input field after click button. I have code like this:
[@react.component]
let make = () => {
let inputRef = React.useRef(Js.Nullable.null);
let handleSelect = _event => {
let element =
inputRef.current->Js.toOption->Belt.Option.flatMap(Webapi.Dom.HtmlInputElement.ofElement);
switch (element) {
| Some(input) =>
Webapi.Dom.HtmlInputElement.focus(input);
Webapi.Dom.HtmlInputElement.select(input);
| None => ()
};
};
<>
<input
className="new-leon-input"
type_="text"
value="abcd"
onChange={_ => ()}
ref={ReactDOMRe.Ref.domRef(inputRef)}
/>
<button onClick=handleSelect> "select"->React.string </button>
</>;
};
Compiler return a bug:
We've found a bug for you!
src/components/TestComponent.re 11:41-45
9 ┆ switch (element) {
10 ┆ | Some(input) =>
11 ┆ Webapi.Dom.HtmlInputElement.focus(input);
12 ┆ Webapi.Dom.HtmlInputElement.select(input);
13 ┆ | None => ()
This has type:
Dom.htmlElement (defined as
Dom.eventTarget_like(Dom._node(Dom._element(Dom._htmlElement(Dom._baseClass)))))
But somewhere wanted:
Webapi.Dom.HtmlInputElement.t_htmlElement (defined as
Dom.eventTarget_like(Dom._node(Dom._element(Dom._htmlElement(Dom._htmlInputElement)))))
The incompatible parts:
Dom._baseClass
vs
Dom._htmlInputElement
What is wrong in this code ? This code was working with bs-webapi 0.15.9, with newest: 0.19.1 i have an error above. Maybe there is a bug in library ? I use bs-platform: 7.3.2
It looks like the type of ofElement
has changed to Webapi__Dom__Element.t => option(Dom.htmlElement)
instead of option(Dom.htmlInputElement)
.
And it's another bug from #182 : https://github.com/reasonml-community/bs-webapi-incubator/pull/182/files?file-filters%5B%5D=.re#diff-f6590c311eac02db4a8591dfe7b1a4c232207269ed2d71105f8407ad4c5ba34dL13-R4
The type annotation on let ofElement: Dom.element => option(t_htmlElement)
has been lost (I'm not even sure if it would be valid with the new implementation) so the function becomes effectively useless in scenarios where it's inherited by other modules.
cc @yawaramin
Hello, any progress of this one? We've run into the same issue trying to access input's value in tests.
Downgrade your version? It has been nearly a month and the maintainer hasn't responded 🤷♂️
With 0.18, 0.17, 0.16 i have the same problem. With 0.15.9 works - but no with bs-platform 8.3.1. With bs-platform 8 and bs-webapi 0.15.9 i have an error:
We've found a bug for you!
/home/leon/public_html/client/react/node_modules/bs-webapi/src/Webapi/Webapi__Dom/Webapi__Dom__DomStringMap.re:11:5-7
9 │ let set = (key, value, map) => set(map, key, value);
10 │ let unsafeDeleteKey: (key, t) => unit =
11 │ [%raw (key, map) => "delete map[key];"];
12 │
bs.raw can only be applied to a string
I made workaround to have working with bs-platform 8 and newest bs-webapi, i just created my own functions using %raw
(maybe it will be useful for someone):
let focus: Dom.element => unit = [%raw {| domElement => domElement.focus() |}];
let select: Dom.element => unit = [%raw {| domElement => domElement.select() |}];
[@react.component]
let make = () => {
let inputRef = React.useRef(Js.Nullable.null);
let handleSelect = _event => {
let element = inputRef.current->Js.toOption;
switch (element) {
| Some(input) =>
focus(input);
select(input);
| None => ()
};
};
<>
<input
className="new-leon-input"
type_="text"
value="abcd"
onChange={_ => ()}
ref={ReactDOMRe.Ref.domRef(inputRef)}
/>
<button onClick=handleSelect> "select"->React.string </button>
</>;
};
But of course it would be much better to fix this library.
Oh right, because the library had to be updated to work with some ReScript incompatibilities and this bug was introduced around the same time.
You could use external
instead of raw
, if you prefer, similar to how webapi does it
[@send] external focus: Dom.element => unit = "focus";
[@send] external select: Dom.element => unit = "select";
and then focus(input)
will compile to input.focus()
.