@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
|
@@ -1,63 +1,42 @@
|
|
|
1
1
|
module MakeString = () => {
|
|
2
|
-
module Id
|
|
3
|
-
@
|
|
4
|
-
type t
|
|
5
|
-
module Dict: {
|
|
6
|
-
type key = t
|
|
7
|
-
@decco
|
|
8
|
-
type t<'a>
|
|
9
|
-
let get: (t<'a>, key) => option<'a>
|
|
10
|
-
@set_index
|
|
11
|
-
external set: (t<'a>, key, 'a) => unit = ""
|
|
12
|
-
@val
|
|
13
|
-
external keys: t<'a> => array<string> = "Object.keys"
|
|
14
|
-
@obj /** Returns an empty dictionary. */
|
|
15
|
-
external empty: unit => t<'a> = ""
|
|
16
|
-
let unsafeDeleteKey: (. t<string>, string) => unit
|
|
17
|
-
let entries: t<'a> => array<(key, 'a)>
|
|
18
|
-
let values: t<'a> => array<'a>
|
|
19
|
-
let fromList: list<(key, 'a)> => t<'a>
|
|
20
|
-
let fromArray: array<(key, 'a)> => t<'a>
|
|
21
|
-
let map: ((. 'a) => 'b, t<'a>) => t<'b>
|
|
22
|
-
let deleteKey: (t<'a>, key) => t<'a>
|
|
23
|
-
}
|
|
24
|
-
} = {
|
|
25
|
-
@decco
|
|
2
|
+
module Id = {
|
|
3
|
+
@spice
|
|
26
4
|
type t = string
|
|
27
5
|
module Dict = {
|
|
28
6
|
include Js.Dict
|
|
29
7
|
|
|
30
8
|
let deleteKey: (t<'a>, string) => t<'a> = %raw("function (dict, key) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}")
|
|
35
|
-
|
|
9
|
+
const newDict = Object.assign({},dict);
|
|
10
|
+
delete newDict[key];
|
|
11
|
+
return newDict;
|
|
12
|
+
}")
|
|
13
|
+
|
|
14
|
+
let t_encode = (encoder, dict): Js.Json.t => Js.Json.Object(Js.Dict.map(encoder, dict))
|
|
36
15
|
|
|
37
16
|
let t_decode = (decoder, json) => {
|
|
38
|
-
open
|
|
39
|
-
switch Js.Json.
|
|
40
|
-
|
|
|
17
|
+
open Spice
|
|
18
|
+
switch (json: Js.Json.t) {
|
|
19
|
+
| Js.Json.Object(dict) =>
|
|
41
20
|
dict
|
|
42
21
|
->Js.Dict.entries
|
|
43
22
|
->Belt.Array.reduce(Ok(Js.Dict.empty()), (acc, (key, value)) =>
|
|
44
23
|
switch (acc, decoder(value)) {
|
|
45
24
|
| (Error(_), _) => acc
|
|
46
25
|
|
|
47
|
-
| (_, Error({path} as error)) => Error({...error, path: "." ++ key ++ path})
|
|
26
|
+
| (_, Error({path} as error)) => Error({...error, path: "." ++ (key ++ path)})
|
|
48
27
|
|
|
49
28
|
| (Ok(prev), Ok(newVal)) =>
|
|
50
29
|
let () = prev->Js.Dict.set(key, newVal)
|
|
51
30
|
Ok(prev)
|
|
52
31
|
}
|
|
53
32
|
)
|
|
54
|
-
|
|
|
33
|
+
| _ => Error({path: "", message: "Not a dict", value: json})
|
|
55
34
|
}
|
|
56
35
|
}
|
|
57
36
|
}
|
|
58
37
|
}
|
|
59
38
|
|
|
60
|
-
@
|
|
39
|
+
@spice
|
|
61
40
|
type t = Id.t
|
|
62
41
|
|
|
63
42
|
module Dict = Id.Dict
|
|
@@ -68,14 +47,14 @@ module MakeString = () => {
|
|
|
68
47
|
|
|
69
48
|
module MakeInt = () => {
|
|
70
49
|
module Id: {
|
|
71
|
-
@
|
|
50
|
+
@spice
|
|
72
51
|
type t
|
|
73
52
|
} = {
|
|
74
|
-
@
|
|
53
|
+
@spice
|
|
75
54
|
type t = int
|
|
76
55
|
}
|
|
77
56
|
|
|
78
|
-
@
|
|
57
|
+
@spice
|
|
79
58
|
type t = Id.t
|
|
80
59
|
external make: int => t = "%identity"
|
|
81
60
|
external toInt: t => int = "%identity"
|
|
@@ -86,42 +65,20 @@ module MakeInt = () => {
|
|
|
86
65
|
}
|
|
87
66
|
|
|
88
67
|
module MakeStringOrInt = () => {
|
|
89
|
-
module Id
|
|
90
|
-
|
|
91
|
-
type t
|
|
92
|
-
module Dict: {
|
|
93
|
-
type key = t
|
|
94
|
-
@decco
|
|
95
|
-
type t<'a>
|
|
96
|
-
let get: (t<'a>, key) => option<'a>
|
|
97
|
-
@set_index
|
|
98
|
-
external set: (t<'a>, key, 'a) => unit = ""
|
|
99
|
-
@val
|
|
100
|
-
external keys: t<'a> => array<string> = "Object.keys"
|
|
101
|
-
@obj /** Returns an empty dictionary. */
|
|
102
|
-
external empty: unit => t<'a> = ""
|
|
103
|
-
let unsafeDeleteKey: (. t<string>, string) => unit
|
|
104
|
-
let entries: t<'a> => array<(key, 'a)>
|
|
105
|
-
let values: t<'a> => array<'a>
|
|
106
|
-
let fromList: list<(key, 'a)> => t<'a>
|
|
107
|
-
let fromArray: array<(key, 'a)> => t<'a>
|
|
108
|
-
let map: ((. 'a) => 'b, t<'a>) => t<'b>
|
|
109
|
-
let deleteKey: (t<'a>, key) => t<'a>
|
|
110
|
-
}
|
|
111
|
-
} = {
|
|
112
|
-
let encoder: Decco.encoder<string> = id => id->Decco.stringToJson
|
|
68
|
+
module Id = {
|
|
69
|
+
let encoder: Spice.encoder<string> = id => id->Spice.stringToJson
|
|
113
70
|
|
|
114
|
-
let decoder:
|
|
115
|
-
switch (
|
|
71
|
+
let decoder: Spice.decoder<string> = json =>
|
|
72
|
+
switch (Spice.stringFromJson(json), Spice.intFromJson(json)) {
|
|
116
73
|
| (Ok(v), _) => Ok(v)
|
|
117
74
|
| (_, Ok(v)) => Ok(v->Int.toString)
|
|
118
75
|
| (Error(err), _) => Error(err)
|
|
119
76
|
}
|
|
120
77
|
|
|
121
|
-
let codec:
|
|
78
|
+
let codec: Spice.codec<string> = (encoder, decoder)
|
|
122
79
|
|
|
123
|
-
@
|
|
124
|
-
type t = @
|
|
80
|
+
@spice
|
|
81
|
+
type t = @spice.codec(codec) string
|
|
125
82
|
module Dict = {
|
|
126
83
|
include Js.Dict
|
|
127
84
|
|
|
@@ -131,10 +88,10 @@ module MakeStringOrInt = () => {
|
|
|
131
88
|
return newDict;
|
|
132
89
|
}")
|
|
133
90
|
|
|
134
|
-
let t_encode = (encoder, dict) => dict->Js.Dict.map(
|
|
91
|
+
let t_encode = (encoder, dict) => dict->Js.Dict.map(encoder, _)->Js.Json.object_
|
|
135
92
|
|
|
136
93
|
let t_decode = (decoder, json) => {
|
|
137
|
-
open
|
|
94
|
+
open Spice
|
|
138
95
|
switch Js.Json.decodeObject(json) {
|
|
139
96
|
| Some(dict) =>
|
|
140
97
|
dict
|
|
@@ -156,7 +113,7 @@ module MakeStringOrInt = () => {
|
|
|
156
113
|
}
|
|
157
114
|
}
|
|
158
115
|
|
|
159
|
-
@
|
|
116
|
+
@spice
|
|
160
117
|
type t = Id.t
|
|
161
118
|
|
|
162
119
|
module Dict = Id.Dict
|
package/src/identifier/index.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Identifier
|
|
2
2
|
|
|
3
|
-
Convert a string or an int in an opaque type with a
|
|
3
|
+
Convert a string or an int in an opaque type with a spice decoder.
|
|
4
4
|
Mostly used for identifiers.
|
|
5
5
|
|
|
6
6
|
## API
|
|
@@ -13,7 +13,7 @@ module DeliveryId = Toolkit.Identifier.MakeString({});
|
|
|
13
13
|
/**
|
|
14
14
|
somewhere
|
|
15
15
|
**/
|
|
16
|
-
[@
|
|
16
|
+
[@spice]
|
|
17
17
|
type response = {
|
|
18
18
|
deliveryId: DeliveryId.t
|
|
19
19
|
};
|
|
@@ -29,7 +29,7 @@ module DeliveryId = Toolkit.Identifier.MakeInt({});
|
|
|
29
29
|
/**
|
|
30
30
|
somewhere
|
|
31
31
|
**/
|
|
32
|
-
[@
|
|
32
|
+
[@spice]
|
|
33
33
|
type response = {
|
|
34
34
|
deliveryId: DeliveryId.t
|
|
35
35
|
};
|
|
@@ -97,7 +97,7 @@ module Make = (Config: IntlConfig) => {
|
|
|
97
97
|
let intl = useIntl()
|
|
98
98
|
let locale = useCurrentLocale()
|
|
99
99
|
|
|
100
|
-
React.
|
|
100
|
+
React.useLayoutEffect(() => {
|
|
101
101
|
DateFns.setDefaultOptions({locale: locale->getDateFnsLocale})
|
|
102
102
|
None
|
|
103
103
|
}, [locale])
|
package/src/mock/MockOverlay.res
CHANGED
|
@@ -10,7 +10,7 @@ let make = (~worker: Msw.worker, ~workerOptions: Msw.startOptions={}, ~className
|
|
|
10
10
|
)
|
|
11
11
|
let (workerStarted, setWorkerStarted) = React.useState(() => false)
|
|
12
12
|
|
|
13
|
-
React.
|
|
13
|
+
React.useLayoutEffect(() => {
|
|
14
14
|
if mockEnabled {
|
|
15
15
|
worker->Msw.start(workerOptions)
|
|
16
16
|
setWorkerStarted(_ => true)
|
package/src/request/index.md
CHANGED
|
@@ -8,9 +8,9 @@ module API = {
|
|
|
8
8
|
module Config = {
|
|
9
9
|
type argument = unit;
|
|
10
10
|
|
|
11
|
-
[@
|
|
11
|
+
[@spice]
|
|
12
12
|
type response = array(user)
|
|
13
|
-
[@
|
|
13
|
+
[@spice]
|
|
14
14
|
and user = {
|
|
15
15
|
name: string
|
|
16
16
|
};
|
|
@@ -41,12 +41,12 @@ module API = {
|
|
|
41
41
|
| `accessRefused
|
|
42
42
|
| `unknown
|
|
43
43
|
]
|
|
44
|
-
[@
|
|
44
|
+
[@spice]
|
|
45
45
|
and activation = {ruleTitle: string};
|
|
46
46
|
|
|
47
|
-
let encoder:
|
|
47
|
+
let encoder: Spice.encoder(errorType) = _v => ""->Spice.stringToJson;
|
|
48
48
|
|
|
49
|
-
let decoder:
|
|
49
|
+
let decoder: Spice.decoder(errorType) =
|
|
50
50
|
json => {
|
|
51
51
|
let error = json->Obj.magic;
|
|
52
52
|
let value =
|
|
@@ -66,23 +66,23 @@ module API = {
|
|
|
66
66
|
value->Ok;
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
-
let codec:
|
|
69
|
+
let codec: Spice.codec(errorType) = (encoder, decoder);
|
|
70
70
|
|
|
71
|
-
[@
|
|
72
|
-
type t = [@
|
|
71
|
+
[@spice]
|
|
72
|
+
type t = [@spice.codec codec] errorType;
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
module Config = {
|
|
76
76
|
type argument = unit;
|
|
77
77
|
|
|
78
|
-
[@
|
|
78
|
+
[@spice]
|
|
79
79
|
type response = array(user)
|
|
80
|
-
[@
|
|
80
|
+
[@spice]
|
|
81
81
|
and user = {
|
|
82
82
|
name: string
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
-
[@
|
|
85
|
+
[@spice]
|
|
86
86
|
type error = Error.t;
|
|
87
87
|
|
|
88
88
|
let exec = clientId => {
|
|
@@ -31,7 +31,7 @@ module Make = (Config: RouterConfig) => {
|
|
|
31
31
|
|
|
32
32
|
let previousRoute = Toolkit__Hooks.usePrevious(currentRoute)
|
|
33
33
|
|
|
34
|
-
React.
|
|
34
|
+
React.useLayoutEffect(() => {
|
|
35
35
|
let watcherID = RescriptReactRouter.watchUrl(url => setCurrentRoute(_ => url->Config.make))
|
|
36
36
|
Some(() => RescriptReactRouter.unwatchUrl(watcherID))
|
|
37
37
|
}, [setCurrentRoute])
|
|
@@ -128,13 +128,13 @@ module Make = (Config: RouterConfig) => {
|
|
|
128
128
|
|
|
129
129
|
@react.component
|
|
130
130
|
let make = (~to_: Config.t, ~behavior=Replace) => {
|
|
131
|
-
React.
|
|
131
|
+
React.useEffect(() => {
|
|
132
132
|
switch behavior {
|
|
133
133
|
| Push => navigate(to_)
|
|
134
134
|
| Replace => replace(to_)
|
|
135
135
|
}
|
|
136
136
|
None
|
|
137
|
-
})
|
|
137
|
+
}, [])
|
|
138
138
|
|
|
139
139
|
React.null
|
|
140
140
|
}
|
|
@@ -143,11 +143,11 @@ module Make = (Config: RouterConfig) => {
|
|
|
143
143
|
module RedirectExternal = {
|
|
144
144
|
@react.component
|
|
145
145
|
let make = (~url: string) => {
|
|
146
|
-
React.
|
|
146
|
+
React.useEffect(() => {
|
|
147
147
|
Browser.Location.replace(Browser.Location.location, url)
|
|
148
148
|
|
|
149
149
|
None
|
|
150
|
-
})
|
|
150
|
+
}, [])
|
|
151
151
|
|
|
152
152
|
React.null
|
|
153
153
|
}
|
|
@@ -172,11 +172,11 @@ module Make = (Config: RouterConfig) => {
|
|
|
172
172
|
)
|
|
173
173
|
|
|
174
174
|
let use = (routes: array<link>) => {
|
|
175
|
-
React.
|
|
175
|
+
React.useLayoutEffect(() => {
|
|
176
176
|
store.dispatch(Update(routes))
|
|
177
177
|
|
|
178
178
|
Some(() => store.dispatch(Reset))
|
|
179
|
-
})
|
|
179
|
+
}, [])
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
@react.component
|
|
@@ -340,7 +340,7 @@ module Make = (Config: RouterConfig) => {
|
|
|
340
340
|
) => {
|
|
341
341
|
let (isOpen, setIsOpen) = React.useState(() => false)
|
|
342
342
|
let currentRoute = useRoute()
|
|
343
|
-
let toggle = React.
|
|
343
|
+
let toggle = React.useCallback(_ => setIsOpen(v => !v), [])
|
|
344
344
|
let hasActiveSubRoute = links->Array.some(link => {
|
|
345
345
|
switch link {
|
|
346
346
|
| Legacy(_) => false
|
|
@@ -361,14 +361,14 @@ module Make = (Config: RouterConfig) => {
|
|
|
361
361
|
})
|
|
362
362
|
})
|
|
363
363
|
|
|
364
|
-
React.
|
|
364
|
+
React.useEffect(() => {
|
|
365
365
|
if !isNavOpen {
|
|
366
366
|
setIsOpen(_ => false)
|
|
367
367
|
}
|
|
368
368
|
None
|
|
369
369
|
}, [isNavOpen])
|
|
370
370
|
|
|
371
|
-
|
|
371
|
+
<React.Fragment>
|
|
372
372
|
<button
|
|
373
373
|
onClick={_ => {
|
|
374
374
|
openMenu()
|
|
@@ -416,7 +416,7 @@ module Make = (Config: RouterConfig) => {
|
|
|
416
416
|
| _ => <LinksList links relativeRoute onLinkClick isNavOpen />
|
|
417
417
|
}}
|
|
418
418
|
</div>
|
|
419
|
-
|
|
419
|
+
</React.Fragment>
|
|
420
420
|
}
|
|
421
421
|
}
|
|
422
422
|
}
|
|
@@ -144,7 +144,7 @@ let make = (
|
|
|
144
144
|
{additionnalOption->Option.getWithDefault(React.null)}
|
|
145
145
|
</div>
|
|
146
146
|
| Ok(suggestions) =>
|
|
147
|
-
|
|
147
|
+
<React.Fragment>
|
|
148
148
|
{suggestions
|
|
149
149
|
->Array.mapWithIndex((i, suggestion) => {
|
|
150
150
|
<HeadlessUi.Combobox.OptionRender
|
|
@@ -167,7 +167,7 @@ let make = (
|
|
|
167
167
|
})
|
|
168
168
|
->React.array}
|
|
169
169
|
{additionnalOption->Option.getWithDefault(React.null)}
|
|
170
|
-
|
|
170
|
+
</React.Fragment>
|
|
171
171
|
}}
|
|
172
172
|
</HeadlessUi.Combobox.Options>
|
|
173
173
|
</HeadlessUi.Transition>
|
|
@@ -25,7 +25,7 @@ let make = (
|
|
|
25
25
|
let (activeIndex, setActiveIndex) = React.useState(() => defaultActiveIndex)
|
|
26
26
|
let previousIndex = Toolkit__Hooks.usePrevious(activeIndex)
|
|
27
27
|
|
|
28
|
-
React.
|
|
28
|
+
React.useEffect(() => {
|
|
29
29
|
onIndexChange->Option.forEach(fn => {
|
|
30
30
|
switch previousIndex {
|
|
31
31
|
| Some(previousIndex) if previousIndex !== activeIndex =>
|
|
@@ -21,7 +21,7 @@ let make = (
|
|
|
21
21
|
let (isChecked, setChecked) = React.useState(() => checked->Option.getWithDefault(false))
|
|
22
22
|
let previousChecked = Toolkit__Hooks.usePrevious(isChecked)
|
|
23
23
|
|
|
24
|
-
React.
|
|
24
|
+
React.useEffect(() => {
|
|
25
25
|
switch (previousChecked, checked) {
|
|
26
26
|
| (Some(previous), Some(checked)) if previous != checked => setChecked(_ => checked)
|
|
27
27
|
| _ => ()
|
|
@@ -21,11 +21,11 @@ let make = (~coordinates: Toolkit__Decoders.Coordinates.t, ~copyWrapperClassName
|
|
|
21
21
|
| [{value}] => value->React.string
|
|
22
22
|
| [{value}, _] => value->React.string
|
|
23
23
|
| [val1, _, val2] =>
|
|
24
|
-
|
|
24
|
+
<React.Fragment>
|
|
25
25
|
{val1.value->React.string}
|
|
26
26
|
{"."->React.string}
|
|
27
27
|
{val2.value->React.string}
|
|
28
|
-
|
|
28
|
+
</React.Fragment>
|
|
29
29
|
| _ => React.null
|
|
30
30
|
}
|
|
31
31
|
}}
|
|
@@ -37,11 +37,11 @@ let make = (~coordinates: Toolkit__Decoders.Coordinates.t, ~copyWrapperClassName
|
|
|
37
37
|
| [{value}] => value->React.string
|
|
38
38
|
| [{value}, _] => value->React.string
|
|
39
39
|
| [val1, _, val2] =>
|
|
40
|
-
|
|
40
|
+
<React.Fragment>
|
|
41
41
|
{val1.value->React.string}
|
|
42
42
|
{"."->React.string}
|
|
43
43
|
{val2.value->React.string}
|
|
44
|
-
|
|
44
|
+
</React.Fragment>
|
|
45
45
|
| _ => React.null
|
|
46
46
|
}
|
|
47
47
|
}}
|
|
@@ -44,7 +44,7 @@ module DatePicker = {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
@react.component
|
|
47
|
-
let make =
|
|
47
|
+
let make = (
|
|
48
48
|
~id,
|
|
49
49
|
~name=?,
|
|
50
50
|
~value=?,
|
|
@@ -70,10 +70,10 @@ let make = React.forwardRef((
|
|
|
70
70
|
~timeFormat="p",
|
|
71
71
|
~timeIntervals=15,
|
|
72
72
|
~timeCaption="Heure",
|
|
73
|
-
|
|
73
|
+
~inputRef=?,
|
|
74
74
|
) =>
|
|
75
75
|
<DatePicker
|
|
76
|
-
ref=?{
|
|
76
|
+
ref=?{inputRef->Option.map(ReactDOM.Ref.domRef)}
|
|
77
77
|
selected=?value
|
|
78
78
|
?showTimeSelect
|
|
79
79
|
showPopperArrow=false
|
|
@@ -108,4 +108,3 @@ let make = React.forwardRef((
|
|
|
108
108
|
isInvalid->Option.getWithDefault(false) ? "border-danger-500 shadow-danger-500" : "",
|
|
109
109
|
])}
|
|
110
110
|
/>
|
|
111
|
-
)
|
|
@@ -91,7 +91,7 @@ let buttonStyle = (
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
@react.component
|
|
94
|
-
let make =
|
|
94
|
+
let make = (
|
|
95
95
|
~size=#md,
|
|
96
96
|
~color=#white,
|
|
97
97
|
~variant=#default,
|
|
@@ -105,10 +105,10 @@ let make = React.forwardRef((
|
|
|
105
105
|
~ariaLabel: option<string>=?,
|
|
106
106
|
~className="",
|
|
107
107
|
~icon: React.element,
|
|
108
|
-
|
|
109
|
-
) =>
|
|
108
|
+
~buttonRef=?,
|
|
109
|
+
) => {
|
|
110
110
|
<button
|
|
111
|
-
ref=?{
|
|
111
|
+
ref=?{buttonRef->Option.map(ReactDOM.Ref.domRef)}
|
|
112
112
|
disabled
|
|
113
113
|
type_
|
|
114
114
|
?id
|
|
@@ -120,4 +120,4 @@ let make = React.forwardRef((
|
|
|
120
120
|
className={cx([buttonStyle(~color, ~variant, ~size, ~disabled, ()), className])}>
|
|
121
121
|
icon
|
|
122
122
|
</button>
|
|
123
|
-
|
|
123
|
+
}
|
|
@@ -109,7 +109,7 @@ module App = {
|
|
|
109
109
|
|
|
110
110
|
let onLinkClick = () => isLg ? () : hideMenu()
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
<React.Fragment>
|
|
113
113
|
<nav
|
|
114
114
|
className={cx([
|
|
115
115
|
"sidenav",
|
|
@@ -137,7 +137,7 @@ module App = {
|
|
|
137
137
|
/>
|
|
138
138
|
| _ => React.null
|
|
139
139
|
}}
|
|
140
|
-
|
|
140
|
+
</React.Fragment>
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
@@ -162,7 +162,7 @@ module App = {
|
|
|
162
162
|
->Option.getWithDefault(false)
|
|
163
163
|
)
|
|
164
164
|
|
|
165
|
-
let toggleMenu = React.
|
|
165
|
+
let toggleMenu = React.useCallback(_ =>
|
|
166
166
|
setOpen(value => {
|
|
167
167
|
let newValue = !value
|
|
168
168
|
|
|
@@ -172,10 +172,10 @@ module App = {
|
|
|
172
172
|
)
|
|
173
173
|
newValue
|
|
174
174
|
})
|
|
175
|
-
)
|
|
175
|
+
, [])
|
|
176
176
|
|
|
177
|
-
let hideMenu = React.useCallback(_ => setOpen(_ => false))
|
|
178
|
-
let openMenu = React.useCallback(_ => setOpen(_ => true))
|
|
177
|
+
let hideMenu = React.useCallback(_ => setOpen(_ => false), [])
|
|
178
|
+
let openMenu = React.useCallback(_ => setOpen(_ => true), [])
|
|
179
179
|
|
|
180
180
|
<NavOpenContext.Provider value={isNavOpen}>
|
|
181
181
|
<div>
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
module Listbox = HeadlessUi.Listbox
|
|
2
|
-
|
|
3
1
|
type compare<'value> =
|
|
4
2
|
| Key(string)
|
|
5
3
|
| ValueEquality
|
|
@@ -10,22 +8,21 @@ type compare<'value> =
|
|
|
10
8
|
) => bool,
|
|
11
9
|
)
|
|
12
10
|
|
|
13
|
-
type
|
|
14
|
-
type options<'value> = array<selectOption<'value>>
|
|
11
|
+
type options<'value> = array<HeadlessUi.Listbox.selectOption<'value>>
|
|
15
12
|
|
|
16
13
|
@react.component
|
|
17
14
|
let make = (
|
|
18
15
|
~options: options<'value>,
|
|
19
16
|
~compare: compare<'value>,
|
|
20
|
-
~onChange: option<Listbox.selectOption<'value> => unit>=?,
|
|
17
|
+
~onChange: option<HeadlessUi.Listbox.selectOption<'value> => unit>=?,
|
|
21
18
|
~placeholder=?,
|
|
22
|
-
~defaultOption: option<Listbox.selectOption<'value>>=?,
|
|
19
|
+
~defaultOption: option<HeadlessUi.Listbox.selectOption<'value>>=?,
|
|
23
20
|
~isDisabled=?,
|
|
24
21
|
~value=?,
|
|
25
22
|
~name=?,
|
|
26
23
|
) => {
|
|
27
24
|
<div className="relative">
|
|
28
|
-
<Listbox
|
|
25
|
+
<HeadlessUi.Listbox
|
|
29
26
|
value
|
|
30
27
|
by={switch compare {
|
|
31
28
|
| Key(objectKey) => objectKey
|
|
@@ -37,7 +34,6 @@ let make = (
|
|
|
37
34
|
)
|
|
38
35
|
}
|
|
39
36
|
)->Obj.magic
|
|
40
|
-
|
|
41
37
|
| Function(fn) => fn->Obj.magic
|
|
42
38
|
}}
|
|
43
39
|
onChange={value => {
|
|
@@ -49,22 +45,22 @@ let make = (
|
|
|
49
45
|
?name
|
|
50
46
|
defaultValue=?{defaultOption->Obj.magic}>
|
|
51
47
|
{props => {
|
|
52
|
-
|
|
53
|
-
<Listbox.Button
|
|
48
|
+
<React.Fragment>
|
|
49
|
+
<HeadlessUi.Listbox.Button
|
|
54
50
|
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
|
-
{
|
|
56
|
-
|
|
51
|
+
{buttonProps => {
|
|
52
|
+
<React.Fragment>
|
|
57
53
|
<span className="table-cell truncate text-left">
|
|
58
|
-
{switch (
|
|
54
|
+
{switch (buttonProps.value, placeholder) {
|
|
59
55
|
| (None, Some(p)) => p->React.string
|
|
60
56
|
| (Some(selectedOption), _) => selectedOption.label->React.string
|
|
61
57
|
| _ => React.null
|
|
62
58
|
}}
|
|
63
59
|
</span>
|
|
64
60
|
<ReactIcons.FaAngleDown size={20} />
|
|
65
|
-
|
|
61
|
+
</React.Fragment>
|
|
66
62
|
}}
|
|
67
|
-
</Listbox.Button>
|
|
63
|
+
</HeadlessUi.Listbox.Button>
|
|
68
64
|
<HeadlessUi.Transition
|
|
69
65
|
show={props.isOpen}
|
|
70
66
|
className="relative z-20"
|
|
@@ -74,12 +70,12 @@ let make = (
|
|
|
74
70
|
leave="transition duration-75 ease-out"
|
|
75
71
|
leaveFrom="transform scale-100 opacity-100"
|
|
76
72
|
leaveTo="transform scale-95 opacity-0">
|
|
77
|
-
<Listbox.Options
|
|
73
|
+
<HeadlessUi.Listbox.Options
|
|
78
74
|
static={true}
|
|
79
75
|
className="absolute min-w-[250px] mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm z-20">
|
|
80
76
|
{options
|
|
81
77
|
->Array.mapWithIndex((i, option) => {
|
|
82
|
-
<Listbox.Option
|
|
78
|
+
<HeadlessUi.Listbox.Option
|
|
83
79
|
key={`listbox-${i->Int.toString}`} value={option} disabled=?{option.disabled}>
|
|
84
80
|
{props => {
|
|
85
81
|
<div
|
|
@@ -114,13 +110,13 @@ let make = (
|
|
|
114
110
|
{option.label->React.string}
|
|
115
111
|
</div>
|
|
116
112
|
}}
|
|
117
|
-
</Listbox.Option>
|
|
113
|
+
</HeadlessUi.Listbox.Option>
|
|
118
114
|
})
|
|
119
115
|
->React.array}
|
|
120
|
-
</Listbox.Options>
|
|
116
|
+
</HeadlessUi.Listbox.Options>
|
|
121
117
|
</HeadlessUi.Transition>
|
|
122
|
-
|
|
118
|
+
</React.Fragment>
|
|
123
119
|
}}
|
|
124
|
-
</Listbox>
|
|
120
|
+
</HeadlessUi.Listbox>
|
|
125
121
|
</div>
|
|
126
122
|
}
|
|
@@ -103,7 +103,7 @@ let make = (
|
|
|
103
103
|
let deferredSearch = React.useDeferredValue(search)
|
|
104
104
|
let allowFilter = options->Array.length > 5 && allowFilter
|
|
105
105
|
|
|
106
|
-
React.
|
|
106
|
+
React.useEffect(() => {
|
|
107
107
|
let prev =
|
|
108
108
|
previousDefaultValue
|
|
109
109
|
->Option.getWithDefault([])
|