Skip to content

Commit

Permalink
feat(value): Use Js.Json.t consistently and provide some convenient (…
Browse files Browse the repository at this point in the history
…yet unsafe) helpers
  • Loading branch information
Kevin COMBRIAT committed Aug 17, 2021
1 parent 7e2255d commit 4021c48
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 15 deletions.
35 changes: 25 additions & 10 deletions example/Example.res
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,18 @@ module Form = {
rules={Rules.make(
~required=true,
~validate=Js.Dict.fromArray([
("validEmail", Validation.sync(value => value->String.contains('@'))),
("validLength", Validation.sync(value => value->String.length >= 8)),
(
"validEmail",
Validation.sync(value =>
value->ReCode.Decode.string->Belt.Result.getWithDefault("")->String.contains('@')
),
),
(
"validLength",
Validation.sync(value =>
value->ReCode.Decode.string->Belt.Result.getWithDefault("")->String.length >= 8
),
),
]),
(),
)}
Expand All @@ -62,7 +72,7 @@ module Form = {
onBlur={_event => onBlur()}
onChange={event => onChange(Controller.OnChangeArg.event(event))}
ref
value
value={value->ReCode.Decode.string->Belt.Result.getWithDefault("")}
/>
<span>
{errors
Expand Down Expand Up @@ -91,7 +101,7 @@ module Form = {
onBlur={_event => onBlur()}
onChange={event => onChange(Controller.OnChangeArg.event(event))}
ref
value
value={value->ReCode.Decode.string->Belt.Result.getWithDefault("")}
/>
<ErrorMessage errors name message={"Required"->React.string} />
</div>}
Expand All @@ -108,16 +118,20 @@ module Form = {
onBlur={_event => onBlur()}
onChange={event => onChange(Controller.OnChangeArg.event(event))}
ref
value
value={value->ReCode.Decode.string->Belt.Result.getWithDefault("")}
/>
<button
type_="button"
onClick={_event =>
onChange(
Controller.OnChangeArg.value(
Js.Json.string(
value->Js.String2.split("")->Js.Array2.reverseInPlace->Js.Array2.joinWith(""),
),
value
->ReCode.Decode.string
->Belt.Result.getWithDefault("")
->Js.String2.split("")
->Js.Array2.reverseInPlace
->Js.Array2.joinWith("")
->ReCode.Encode.string,
),
)}>
{"Reverse"->React.string}
Expand All @@ -136,7 +150,7 @@ module Form = {
onBlur={_event => onBlur()}
onChange={event => onChange(Controller.OnChangeArg.event(event))}
ref
value
value={value->ReCode.Decode.string->Belt.Result.getWithDefault("")}
type_="checkbox"
/>
</div>
Expand All @@ -159,7 +173,8 @@ module Form = {
onBlur={_event => onBlur()}
onChange={event => onChange(Controller.OnChangeArg.event(event))}
ref
value
// Let's be unsafe here!
value={Unsafe.valueToString(value)}
/>
<ErrorMessage errors name message={"Required"->React.string} />
<button
Expand Down
4 changes: 1 addition & 3 deletions src/Controller.res
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ type field = {
onBlur: unit => unit,
onChange: OnChangeArg.t => unit,
ref: ReactDOM.domRef,
// This is not correct, the value can be a bool or an int
// The value should be considered opaque and never access directly
value: string,
value: Js.Json.t,
}

@ocaml.doc(
Expand Down
23 changes: 23 additions & 0 deletions src/Unsafe.res
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,26 @@ to improve performances or quickly get the value out of a form.
Use it with care.")
external anyToJson: 'a => Js.Json.t = "%identity"

@ocaml.doc("Can be useful when you want to pass the `value` argument received
from a Controller's render function to a native input.
Notice that such values can actually be of any (serializable) type so use with care.
Example:
```
<Controller
render={({field: {value}}) =>
<input value={Unsafe.valueToString(value)} />
}
/>
```
")
external valueToString: Js.Json.t => string = "%identity"

@ocaml.doc("Can be useful when you want to pass the `value` argument received
from a Controller's render function to a native checkbox.
Notice that such values can actually be of any (serializable) type so use with care.")
external valueToBool: Js.Json.t => bool = "%identity"
4 changes: 2 additions & 2 deletions src/Validation.resi
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
type rec t

@ocaml.doc("Synchronous validation")
let sync: (string => bool) => t
let sync: (Js.Json.t => bool) => t

@ocaml.doc("Asynchronous validation")
let async: (string => Js.Promise.t<bool>) => t
let async: (Js.Json.t => Js.Promise.t<bool>) => t

0 comments on commit 4021c48

Please sign in to comment.