@colisweb/rescript-toolkit 4.29.3 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/package.json +25 -23
  2. package/{bsconfig.json → rescript.json} +10 -5
  3. package/src/decoders/Decoders__UnitMeasure.res +251 -0
  4. package/src/decoders/Toolkit__Decoders.res +118 -412
  5. package/src/decoders/index.md +5 -5
  6. package/src/form/Reform.res +18 -18
  7. package/src/form/Toolkit__Form.res +53 -50
  8. package/src/hooks/Toolkit__Hooks.res +40 -42
  9. package/src/hooks/index.md +2 -2
  10. package/src/identifier/Toolkit__Identifier.res +27 -70
  11. package/src/identifier/index.md +3 -3
  12. package/src/intl/Toolkit__Intl.res +1 -1
  13. package/src/mock/MockOverlay.res +1 -1
  14. package/src/request/index.md +11 -11
  15. package/src/router/Toolkit__Router.res +11 -11
  16. package/src/ui/Toolkit__Ui_Autocomplete.res +2 -2
  17. package/src/ui/Toolkit__Ui_Button.res +1 -1
  18. package/src/ui/Toolkit__Ui_ButtonGroup2.res +1 -1
  19. package/src/ui/Toolkit__Ui_Checkbox.res +1 -1
  20. package/src/ui/Toolkit__Ui_Coordinates.res +4 -4
  21. package/src/ui/Toolkit__Ui_DatetimeInput.res +3 -4
  22. package/src/ui/Toolkit__Ui_Dropdown.res +1 -1
  23. package/src/ui/Toolkit__Ui_DropdownList.res +1 -1
  24. package/src/ui/Toolkit__Ui_IconButton.res +5 -5
  25. package/src/ui/Toolkit__Ui_Layout.res +6 -6
  26. package/src/ui/Toolkit__Ui_Listbox.res +17 -21
  27. package/src/ui/Toolkit__Ui_MultiSelect.res +1 -1
  28. package/src/ui/Toolkit__Ui_MultiSelectWithValidation.res +1 -1
  29. package/src/ui/Toolkit__Ui_Notice.res +37 -26
  30. package/src/ui/Toolkit__Ui_Portal.res +1 -1
  31. package/src/ui/Toolkit__Ui_PortalDropdown.res +8 -6
  32. package/src/ui/Toolkit__Ui_RadioGroup.res +1 -1
  33. package/src/ui/Toolkit__Ui_SearchListbox.res +4 -5
  34. package/src/ui/Toolkit__Ui_SelectWithValidation.res +1 -1
  35. package/src/ui/Toolkit__Ui_Snackbar.res +2 -2
  36. package/src/ui/Toolkit__Ui_Switch.res +1 -1
  37. package/src/ui/Toolkit__Ui_TextInput.res +3 -4
  38. package/src/ui/Toolkit__Ui_TextareaInput.res +2 -23
  39. package/src/ui/Toolkit__Ui_Tooltip.res +1 -1
  40. package/src/ui/Toolkit__Ui_WeekDateFilter.res +1 -1
  41. package/src/unleash/Toolkit__Unleash.res +6 -6
  42. package/src/unleash/index.md +1 -1
  43. package/src/utils/Toolkit__Utils.res +20 -0
  44. package/src/utils/Toolkit__Utils_UnitMeasure.res +72 -110
  45. package/src/vendors/Axios.res +2 -2
  46. package/src/vendors/DatadogRum.res +3 -3
  47. package/src/vendors/ReactDayPicker.res +4 -4
  48. package/src/vendors/ReactUse.res +1 -1
  49. package/src/vendors/Zendesk.res +1 -1
@@ -11,7 +11,7 @@ let make = (
11
11
  let (style, setStyle) = React.useState(() => None)
12
12
  let noticeRef = React.useRef(Js.Nullable.null)
13
13
 
14
- React.useEffect2(() => {
14
+ React.useEffect(() => {
15
15
  let timeoutId = ref(None)
16
16
 
17
17
  baseElementRef.current
@@ -22,21 +22,29 @@ let make = (
22
22
  if visible {
23
23
  setVisibility(_ => true)
24
24
 
25
- setStyle(_ => {
26
- setElementReady(_ => true)
25
+ setStyle(
26
+ _ => {
27
+ setElementReady(_ => true)
28
+ Some(
29
+ ReactDOM.Style.make(
30
+ ~top=`${Js.Float.toString(y +. height)}px`,
31
+ ~left=`${(x +. width /. 2.)->Js.Float.toString}px`,
32
+ (),
33
+ ),
34
+ )
35
+ },
36
+ )
37
+ } else {
38
+ timeoutId :=
27
39
  Some(
28
- ReactDOM.Style.make(
29
- ~top=`${Js.Float.toString(y +. height)}px`,
30
- ~left=`${(x +. width /. 2.)->Js.Float.toString}px`,
31
- (),
40
+ Js.Global.setTimeout(
41
+ () => {
42
+ setElementReady(_ => false)
43
+ setVisibility(_ => visible)
44
+ },
45
+ 500,
32
46
  ),
33
47
  )
34
- })
35
- } else {
36
- timeoutId := Some(Js.Global.setTimeout(() => {
37
- setElementReady(_ => false)
38
- setVisibility(_ => visible)
39
- }, 500))
40
48
  setCustomClassName(_ => "opacity-0")
41
49
  }
42
50
  })
@@ -44,7 +52,7 @@ let make = (
44
52
  Some(() => timeoutId.contents->Option.forEach(Js.Global.clearTimeout))
45
53
  }, (baseElementRef, visible))
46
54
 
47
- React.useEffect1(() => {
55
+ React.useEffect(() => {
48
56
  let timeoutId = ref(None)
49
57
 
50
58
  if elementReady {
@@ -55,24 +63,27 @@ let make = (
55
63
  Some(() => timeoutId.contents->Option.forEach(Js.Global.clearTimeout))
56
64
  }, [elementReady])
57
65
 
58
- React.useEffect2(() => {
66
+ React.useEffect(() => {
59
67
  if visibility {
60
68
  noticeRef.current
61
69
  ->Js.Nullable.toOption
62
70
  ->Option.forEach(dom => {
63
71
  let {left, right} = dom->Browser.DomElement.getBoundingClientRect
64
72
 
65
- setStyle(style =>
66
- style->Option.map(style => {
67
- ReactDOM.Style.combine(
68
- style,
69
- ReactDOM.Style.make(
70
- ~marginLeft=left < 0. ? `${-.left->Js.Float.toString}px` : "",
71
- ~marginRight=right < 0. ? `${-.right->Js.Float.toString}px` : "",
72
- (),
73
- ),
74
- )
75
- })
73
+ setStyle(
74
+ style =>
75
+ style->Option.map(
76
+ style => {
77
+ ReactDOM.Style.combine(
78
+ style,
79
+ ReactDOM.Style.make(
80
+ ~marginLeft=left < 0. ? `${-.left->Js.Float.toString}px` : "",
81
+ ~marginRight=right < 0. ? `${-.right->Js.Float.toString}px` : "",
82
+ (),
83
+ ),
84
+ )
85
+ },
86
+ ),
76
87
  )
77
88
  })
78
89
  }
@@ -12,7 +12,7 @@ let make = (~children) => {
12
12
  let node = React.useRef(createElement("div")).current
13
13
  let (defaultNode, setDefaultNode) = React.useState(() => None)
14
14
 
15
- React.useEffect1(() => {
15
+ React.useEffect(() => {
16
16
  switch defaultNode {
17
17
  | None => {
18
18
  appendToBody(node)
@@ -36,7 +36,7 @@ let make = (
36
36
 
37
37
  let (adjustmentStyle, setAdjustmentStyle) = React.useState(() => None)
38
38
 
39
- React.useEffect1(() => {
39
+ React.useEffect(() => {
40
40
  if isOpen {
41
41
  ()
42
42
  } else {
@@ -52,7 +52,7 @@ let make = (
52
52
  type_="button"
53
53
  color=buttonColor
54
54
  buttonRef={ReactDOM.Ref.domRef(buttonRef)}
55
- onClick={event => {
55
+ onClick={_ => {
56
56
  onButtonClick->Option.forEach(fn => fn())
57
57
  isOpen ? hide() : toggle()
58
58
  }}
@@ -76,10 +76,12 @@ let make = (
76
76
  let dropdown = ref->Browser.DomElement.getBoundingClientRect
77
77
  let left = left +. width /. 2. -. dropdown.width /. 2.
78
78
 
79
- let adjustmentStyle = ReactDOM.Style.make(
80
- ~top=`${(top +. height)->Js.Float.toString}px`,
81
- ~opacity="1",
82
- )
79
+ let adjustmentStyle =
80
+ ReactDOM.Style.make(
81
+ ~top=`${(top +. height)->Js.Float.toString}px`,
82
+ ~opacity="1",
83
+ ...
84
+ )
83
85
  let adjustmentStyle = switch left {
84
86
  | left if left < 0. => adjustmentStyle(~left="8px", ())
85
87
  | left if left +. dropdown.width > Browser.innerWidth->Int.toFloat =>
@@ -11,7 +11,7 @@ let make = (~onChange, ~elements: array<element>, ~defaultValue=?, ~inline=false
11
11
  let name = "radio-" ++ ReachUi_AutoId.use("")
12
12
  let (value, setValue) = React.useState(() => defaultValue->Option.getWithDefault(""))
13
13
 
14
- React.useEffect1(() => {
14
+ React.useEffect(() => {
15
15
  onChange(value)
16
16
  None
17
17
  }, [value])
@@ -18,7 +18,6 @@ let make = (
18
18
  ~compare: compare<'value>,
19
19
  ~onChange: option<Listbox.selectOption<'value> => unit>=?,
20
20
  ~placeholder=?,
21
- ~searchPlaceholder as _=?,
22
21
  ~defaultOption: option<Listbox.selectOption<'value>>=?,
23
22
  ~isDisabled=?,
24
23
  ~value=?,
@@ -49,11 +48,11 @@ let make = (
49
48
  ?name
50
49
  defaultValue=?{defaultOption->Obj.magic}>
51
50
  {props => {
52
- <>
51
+ <React.Fragment>
53
52
  <Listbox.Button
54
53
  className="relative flex flex-row items-center justify-between w-full cursor-default rounded-md font-semibold bg-white py-2 pl-3 pr-4 text-left border border-gray-300">
55
54
  {props => {
56
- <>
55
+ <React.Fragment>
57
56
  <span className="table-cell truncate text-left">
58
57
  {switch (props.value, placeholder) {
59
58
  | (None, Some(p)) => p->React.string
@@ -62,7 +61,7 @@ let make = (
62
61
  }}
63
62
  </span>
64
63
  <ReactIcons.FaAngleDown size={20} />
65
- </>
64
+ </React.Fragment>
66
65
  }}
67
66
  </Listbox.Button>
68
67
  <HeadlessUi.Transition
@@ -119,7 +118,7 @@ let make = (
119
118
  ->React.array}
120
119
  </Listbox.Options>
121
120
  </HeadlessUi.Transition>
122
- </>
121
+ </React.Fragment>
123
122
  }}
124
123
  </Listbox>
125
124
  </div>
@@ -111,7 +111,7 @@ let make = (
111
111
  let deferredSearch = React.useDeferredValue(search)
112
112
  let allowFilter = options->Array.length > 5 && allowFilter
113
113
 
114
- React.useEffect2(() => {
114
+ React.useEffect(() => {
115
115
  switch (previousDefaultValue, defaultValue) {
116
116
  | (Some(Some(v)), Some(v2)) if v !== v2 => setSelectedOption(_ => defaultValue)
117
117
  | _ => ()
@@ -62,14 +62,14 @@ module Item = {
62
62
 
63
63
  let (mounted, setMounted) = React.useState(() => false)
64
64
 
65
- React.useEffect0(() => {
65
+ React.useEffect(() => {
66
66
  setMounted(_ => true)
67
67
 
68
68
  let timeoutId = Js.Global.setTimeout(() => {
69
69
  hide(id)
70
70
  }, timeout)
71
71
  Some(() => Js.Global.clearTimeout(timeoutId))
72
- })
72
+ }, [])
73
73
 
74
74
  <div
75
75
  style={ReactDOM.Style.make(~pointerEvents="all", ())}
@@ -20,7 +20,7 @@ let make = (
20
20
  let (isChecked, setIsChecked) = React.useState(() => checked->Option.getWithDefault(false))
21
21
  let previousChecked = Toolkit__Hooks.usePrevious(checked)
22
22
 
23
- React.useEffect2(() => {
23
+ React.useEffect(() => {
24
24
  checked->Option.forEach(checked => {
25
25
  switch (previousChecked, checked) {
26
26
  | (Some(Some(c1)), c2) if c1 != c2 => setIsChecked(_ => c2)
@@ -1,5 +1,5 @@
1
1
  @react.component
2
- let make = React.forwardRef((
2
+ let make = (
3
3
  ~id: string,
4
4
  ~accept: option<string>=?,
5
5
  ~name: option<string>=?,
@@ -25,10 +25,10 @@ let make = React.forwardRef((
25
25
  ~isInvalid: option<bool>=?,
26
26
  ~className: string="",
27
27
  ~style: option<ReactDOM.style>=?,
28
- ref,
28
+ ~inputRef=?,
29
29
  ) =>
30
30
  <input
31
- ref=?{ref->Js.Nullable.toOption->Option.map(ReactDOM.Ref.domRef)}
31
+ ref=?{inputRef->Option.map(ReactDOM.Ref.domRef)}
32
32
  className={cx([
33
33
  className,
34
34
  "appearance-none outline-none transition duration-150 ease-in-out block w-full bg-white text-gray-800 border rounded py-2 px-4 leading-tight focus:z30 relative disabled:bg-gray-200 disabled:text-gray-700",
@@ -67,4 +67,3 @@ let make = React.forwardRef((
67
67
  ?onBlur
68
68
  ?onKeyDown
69
69
  />
70
- )
@@ -16,7 +16,7 @@ let autoExpand: Dom.element => unit = %raw(`
16
16
  `)
17
17
 
18
18
  @react.component
19
- let make = React.forwardRef((
19
+ let make = (
20
20
  ~id,
21
21
  ~name=?,
22
22
  ~value=?,
@@ -31,33 +31,12 @@ let make = React.forwardRef((
31
31
  ~onChange: option<ReactEvent.Form.t => unit>=?,
32
32
  ~isInvalid=?,
33
33
  ~className="",
34
- ref_,
35
34
  ) => {
36
- let ownRef = React.useRef(Js.Nullable.null)
37
- let textareaRef = switch ref_->Js.Nullable.toOption {
38
- | Some(ref_) => ref_
39
- | _ => ownRef
40
- }
41
-
42
- React.useLayoutEffect1(() => {
43
- if textareaRef.current->Js.Nullable.toOption->Option.isSome {
44
- textareaRef.current->Js.Nullable.toOption->Option.map(autoExpand)->ignore
45
- }
46
- None
47
- }, [textareaRef])
48
-
49
35
  let onChange = event => {
50
- if textareaRef.current->Js.Nullable.toOption->Option.isSome {
51
- Js.Global.setTimeout(
52
- () => textareaRef.current->Js.Nullable.toOption->Option.map(autoExpand)->ignore,
53
- 0,
54
- )->ignore
55
- }
56
36
  onChange->Option.map(onChange => onChange(event))->ignore
57
37
  }
58
38
 
59
39
  <textarea
60
- ref={ReactDOM.Ref.callbackDomRef(ref_ => textareaRef.current = ref_)}
61
40
  style={ReactDOM.Style.make(
62
41
  ~height="auto",
63
42
  ~minHeight="38px",
@@ -86,4 +65,4 @@ let make = React.forwardRef((
86
65
  ?onBlur
87
66
  ?onKeyDown
88
67
  />
89
- })
68
+ }
@@ -20,7 +20,7 @@ let make = (
20
20
  let (children, isHover) = ReactUse.useHover(children)
21
21
  let (adjustmentStyle, setAdjustmentStyle) = React.useState(() => None)
22
22
 
23
- React.useEffect2(() => {
23
+ React.useEffect(() => {
24
24
  if isHover {
25
25
  ref.current
26
26
  ->Js.Nullable.toOption
@@ -11,7 +11,7 @@ type action =
11
11
  | NextTimeSlot
12
12
  | UpdateSelectedDay(option<Js.Date.t>)
13
13
 
14
- @decco
14
+ @spice
15
15
  type queryParams = {
16
16
  start: Toolkit__Decoders.Option.t<Toolkit__Decoders.Date.t>,
17
17
  selectedDay: Toolkit__Decoders.Option.t<Toolkit__Decoders.Date.t>,
@@ -1,10 +1,10 @@
1
- @decco
1
+ @spice
2
2
  type strategy<'parameters> = {
3
3
  name: string,
4
4
  parameters: 'parameters,
5
5
  }
6
6
 
7
- @decco
7
+ @spice
8
8
  type config<'strategy> = {
9
9
  name: string,
10
10
  description: string,
@@ -13,7 +13,7 @@ type config<'strategy> = {
13
13
  }
14
14
 
15
15
  module type Config = {
16
- @decco
16
+ @spice
17
17
  type argument
18
18
  type input
19
19
  type output
@@ -23,14 +23,14 @@ module type Config = {
23
23
  }
24
24
 
25
25
  module MakeFeature = (C: Config) => {
26
- @decco
26
+ @spice
27
27
  type t = config<C.argument>
28
28
 
29
29
  let exec = (var: C.input) =>
30
- Axios.get(C.envUrl ++ C.featureName,~config={Axios.makeConfig()}, ())
30
+ Axios.get(C.envUrl ++ C.featureName, ~config={Axios.makeConfig()}, ())
31
31
  ->Promise.Js.toResult
32
32
  ->Promise.flatMapOk(({data}) => {
33
33
  Promise.resolved(t_decode(data))
34
34
  })
35
- ->Promise.mapOk(C.exec(var))
35
+ ->Promise.mapOk(C.exec(var, ...))
36
36
  }
@@ -8,7 +8,7 @@
8
8
 
9
9
  ```rescript
10
10
  module OutdatedApplicationConfig = {
11
- [@decco]
11
+ [@spice]
12
12
  type parameters = {version: string};
13
13
  type input = unit;
14
14
  type output = bool;
@@ -25,3 +25,23 @@ let durationMinutesToHourMinutesString = (durationMinutes: float) => {
25
25
  `${h < 10. ? "0" : ""}${h->Js.Float.toFixed}:${min < 10. ? "0" : ""}${min->Js.Float.toFixed}`
26
26
  }
27
27
  }
28
+
29
+ module type Enum = {
30
+ type t
31
+ let t_decode: Js.Json.t => result<t, Spice.decodeError>
32
+ let t_encode: t => Js.Json.t
33
+ }
34
+
35
+ let encodeEnumToString = (type enum, enumValue: enum, enum: module(Enum with type t = enum)) => {
36
+ let module(Enum) = enum
37
+
38
+ (enumValue->Enum.t_encode->Obj.magic: string)
39
+ }
40
+
41
+ let decodeEnumFromString = (type enum, str: string, enum: module(Enum with type t = enum)) => {
42
+ let module(Enum) = enum
43
+ switch str->Obj.magic->Enum.t_decode {
44
+ | Ok(v) => Some(v)
45
+ | Error(_) => None
46
+ }
47
+ }