@colisweb/rescript-toolkit 4.29.2 → 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.
- package/package.json +25 -23
- package/{bsconfig.json → rescript.json} +10 -5
- package/src/decoders/Decoders__UnitMeasure.res +251 -0
- package/src/decoders/Toolkit__Decoders.res +118 -412
- package/src/decoders/index.md +5 -5
- package/src/form/Reform.res +18 -18
- package/src/form/Toolkit__Form.res +53 -50
- package/src/hooks/Toolkit__Hooks.res +40 -42
- package/src/hooks/index.md +2 -2
- package/src/identifier/Toolkit__Identifier.res +27 -70
- package/src/identifier/index.md +3 -3
- package/src/intl/Toolkit__Intl.res +1 -1
- package/src/mock/MockOverlay.res +1 -1
- package/src/request/index.md +11 -11
- package/src/router/Toolkit__Router.res +11 -11
- package/src/ui/Toolkit__Ui_Autocomplete.res +2 -2
- package/src/ui/Toolkit__Ui_Button.res +1 -1
- package/src/ui/Toolkit__Ui_ButtonGroup2.res +1 -1
- package/src/ui/Toolkit__Ui_Checkbox.res +1 -1
- package/src/ui/Toolkit__Ui_Coordinates.res +4 -4
- package/src/ui/Toolkit__Ui_DatetimeInput.res +3 -4
- package/src/ui/Toolkit__Ui_Dropdown.res +1 -1
- package/src/ui/Toolkit__Ui_DropdownList.res +1 -1
- package/src/ui/Toolkit__Ui_IconButton.res +5 -5
- package/src/ui/Toolkit__Ui_Layout.res +6 -6
- package/src/ui/Toolkit__Ui_Listbox.res +17 -21
- package/src/ui/Toolkit__Ui_MultiSelect.res +1 -1
- package/src/ui/Toolkit__Ui_MultiSelectWithValidation.res +1 -1
- package/src/ui/Toolkit__Ui_Notice.res +37 -26
- package/src/ui/Toolkit__Ui_Portal.res +1 -1
- package/src/ui/Toolkit__Ui_PortalDropdown.res +8 -6
- package/src/ui/Toolkit__Ui_RadioGroup.res +1 -1
- package/src/ui/Toolkit__Ui_SearchListbox.res +4 -5
- package/src/ui/Toolkit__Ui_SelectWithValidation.res +1 -1
- package/src/ui/Toolkit__Ui_Snackbar.res +2 -2
- package/src/ui/Toolkit__Ui_Switch.res +1 -1
- package/src/ui/Toolkit__Ui_TextInput.res +3 -4
- package/src/ui/Toolkit__Ui_TextareaInput.res +2 -23
- package/src/ui/Toolkit__Ui_Tooltip.res +1 -1
- package/src/ui/Toolkit__Ui_WeekDateFilter.res +1 -1
- package/src/unleash/Toolkit__Unleash.res +6 -6
- package/src/unleash/index.md +1 -1
- package/src/utils/Toolkit__Utils.res +20 -0
- package/src/utils/Toolkit__Utils_UnitMeasure.res +72 -110
- package/src/vendors/Axios.res +2 -2
- package/src/vendors/Browser.resi +1 -0
- package/src/vendors/DatadogRum.res +3 -3
- package/src/vendors/ReactDayPicker.res +4 -4
- package/src/vendors/ReactUse.res +1 -1
- 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.
|
|
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
|
-
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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.
|
|
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.
|
|
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(
|
|
66
|
-
style
|
|
67
|
-
|
|
68
|
-
style
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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.
|
|
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.
|
|
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={
|
|
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 =
|
|
80
|
-
|
|
81
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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 =
|
|
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
|
-
|
|
28
|
+
~inputRef=?,
|
|
29
29
|
) =>
|
|
30
30
|
<input
|
|
31
|
-
ref=?{
|
|
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 =
|
|
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
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
@
|
|
1
|
+
@spice
|
|
2
2
|
type strategy<'parameters> = {
|
|
3
3
|
name: string,
|
|
4
4
|
parameters: 'parameters,
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
@
|
|
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
|
-
@
|
|
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
|
-
@
|
|
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
|
|
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
|
}
|
package/src/unleash/index.md
CHANGED
|
@@ -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
|
+
}
|