@colisweb/rescript-toolkit 1.32.0 → 2.3.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colisweb/rescript-toolkit",
3
- "version": "1.32.0",
3
+ "version": "2.3.0",
4
4
  "scripts": {
5
5
  "clean": "rescript clean",
6
6
  "build": "rescript build",
@@ -1,4 +1,4 @@
1
- module Date = {
1
+ module Datetime = {
2
2
  type date = Js.Date.t
3
3
 
4
4
  let encoder: Decco.encoder<date> = value => value->Js.Date.toISOString->Decco.stringToJson
@@ -15,6 +15,24 @@ module Date = {
15
15
  type t = @decco.codec(codec) date
16
16
  }
17
17
 
18
+ module Date = {
19
+ type date = Js.Date.t
20
+
21
+ let encoder: Decco.encoder<date> = date =>
22
+ date->BsDateFns.formatWithPattern("yyyy-MM-dd")->Decco.stringToJson
23
+
24
+ let decoder: Decco.decoder<date> = json =>
25
+ switch Decco.stringFromJson(json) {
26
+ | Ok(v) => Js.Date.fromString(v)->Ok
27
+ | Error(_) as err => err
28
+ }
29
+
30
+ let codec: Decco.codec<date> = (encoder, decoder)
31
+
32
+ @decco
33
+ type t = @decco.codec(codec) date
34
+ }
35
+
18
36
  module Int = {
19
37
  let encoder = value => value->Decco.intToJson
20
38
 
@@ -5,16 +5,21 @@ module type RouterConfig = {
5
5
  }
6
6
 
7
7
  module Make = (Config: RouterConfig) => {
8
+ type contextState = {
9
+ currentRoute: Config.t,
10
+ previousRoute: option<Config.t>,
11
+ }
8
12
  let navigate = (route: Config.t) => RescriptReactRouter.push(route->Config.toString)
9
13
 
10
14
  let replace = (route: Config.t) => RescriptReactRouter.replace(route->Config.toString)
11
15
 
12
- let routerContext = React.createContext(
13
- RescriptReactRouter.dangerouslyGetInitialUrl()->Config.make,
14
- )
16
+ let routerContext = React.createContext({
17
+ currentRoute: RescriptReactRouter.dangerouslyGetInitialUrl()->Config.make,
18
+ previousRoute: None,
19
+ })
15
20
 
16
21
  module RouterContextProvider = {
17
- let makeProps = (~value: Config.t, ~children, ()) =>
22
+ let makeProps = (~value: contextState, ~children, ()) =>
18
23
  {
19
24
  "value": value,
20
25
  "children": children,
@@ -30,6 +35,8 @@ module Make = (Config: RouterConfig) => {
30
35
  RescriptReactRouter.dangerouslyGetInitialUrl()->Config.make
31
36
  )
32
37
 
38
+ let previousRoute = Toolkit__Hooks.usePrevious(currentRoute)
39
+
33
40
  React.useLayoutEffect1(() => {
34
41
  let watcherID = RescriptReactRouter.watchUrl(url =>
35
42
  setCurrentRoute(_ => url |> Config.make)
@@ -37,7 +44,14 @@ module Make = (Config: RouterConfig) => {
37
44
  Some(() => RescriptReactRouter.unwatchUrl(watcherID))
38
45
  }, [setCurrentRoute])
39
46
 
40
- <RouterContextProvider value=currentRoute> {children(~currentRoute)} </RouterContextProvider>
47
+ let contextValue: contextState = {
48
+ previousRoute: previousRoute,
49
+ currentRoute: currentRoute,
50
+ }
51
+
52
+ <RouterContextProvider value={contextValue}>
53
+ {children(~currentRoute)}
54
+ </RouterContextProvider>
41
55
  }
42
56
  }
43
57
 
@@ -47,7 +61,7 @@ module Make = (Config: RouterConfig) => {
47
61
  routeA->Config.toString === routeB->Config.toString
48
62
 
49
63
  let useIsCurrentRoute = (route: Config.t): bool => {
50
- let currentRoute = React.useContext(routerContext)
64
+ let {currentRoute} = React.useContext(routerContext)
51
65
  isRouteEqual(currentRoute, route)
52
66
  }
53
67
 
@@ -214,6 +228,7 @@ module Make = (Config: RouterConfig) => {
214
228
  ~links: array<link>,
215
229
  ~isNavOpen: bool,
216
230
  ~onLinkClick=() => (),
231
+ ~openMenu,
217
232
  ) => {
218
233
  let (isOpen, setIsOpen) = React.useState(() => false)
219
234
 
@@ -227,7 +242,12 @@ module Make = (Config: RouterConfig) => {
227
242
  }, [isNavOpen])
228
243
 
229
244
  <>
230
- <button onClick=toggle className={cx([commonClassName, "flex items-center w-full"])}>
245
+ <button
246
+ onClick={_ => {
247
+ openMenu()
248
+ toggle()
249
+ }}
250
+ className={cx([commonClassName, "flex items-center w-full"])}>
231
251
  <span className={cx(["mr-2 text-neutral-800", isNavOpen ? "pl-2" : "px-2"])}>
232
252
  groupInfo.icon
233
253
  </span>
@@ -247,6 +267,12 @@ module Make = (Config: RouterConfig) => {
247
267
  ])}
248
268
  />
249
269
  </span>
270
+ {isNavOpen
271
+ ? React.null
272
+ : <div
273
+ className="sidenav-link-tooltip absolute left-0 p-2 bg-neutral-700 text-white rounded transform top-1/2 -translate-y-1/2 transition-all duration-200 ease-in-out opacity-0 invisible ml-16 whitespace-nowrap">
274
+ groupInfo.label
275
+ </div>}
250
276
  </button>
251
277
  <div
252
278
  className={cx([
@@ -84,10 +84,17 @@ module App = {
84
84
  type sideNavRender = {
85
85
  onLinkClick: unit => unit,
86
86
  isNavOpen: bool,
87
+ openMenu: unit => unit,
87
88
  }
88
89
 
89
90
  @react.component
90
- let make = (~isNavOpen, ~bottom=?, ~hideMenu, ~children: sideNavRender => React.element) => {
91
+ let make = (
92
+ ~isNavOpen,
93
+ ~bottom=?,
94
+ ~hideMenu,
95
+ ~children: sideNavRender => React.element,
96
+ ~openMenu,
97
+ ) => {
91
98
  let {isLg} = Toolkit__Hooks.useMediaQuery()
92
99
 
93
100
  let onLinkClick = () => isLg ? () : hideMenu()
@@ -99,17 +106,13 @@ module App = {
99
106
  "lg:flex border-r px-2 py-3 fixed flex-col bg-white justify-between transition-all duration-300 ease-in-out z-40",
100
107
  isNavOpen ? "w-64 overflow-y-auto" : "w-16 hidden sidenav--closed",
101
108
  ])}>
102
- {children({onLinkClick: onLinkClick, isNavOpen: isNavOpen})}
109
+ {children({onLinkClick: onLinkClick, isNavOpen: isNavOpen, openMenu: openMenu})}
103
110
  {bottom->Option.mapWithDefault(React.null, content =>
104
111
  <div className={!isNavOpen ? "overflow-hidden" : ""}>
105
112
  <div
106
113
  className={cx([
107
- "flex flex-col justify-end transition-all duration-300 ease-in-out",
114
+ "flex flex-col justify-end transition-all duration-300 ease-in-out w-[14.75rem]",
108
115
  isNavOpen ? "opacity-100" : "opacity-0",
109
- {
110
- open Css
111
- style(list{width(14.75->rem)})
112
- },
113
116
  ])}>
114
117
  content
115
118
  </div>
@@ -161,12 +164,15 @@ module App = {
161
164
  )
162
165
 
163
166
  let hideMenu = React.useCallback(_ => setOpen(_ => false))
167
+ let openMenu = React.useCallback(_ => setOpen(_ => true))
164
168
 
165
169
  <NavOpenContext.Provider value={isNavOpen}>
166
170
  <div>
167
171
  <TopNavigationBar username logout logoutLabel toggleMenu onLogoClick />
168
172
  <div className="flex">
169
- <LeftNavigationBar isNavOpen ?bottom hideMenu> sideNavRender </LeftNavigationBar>
173
+ <LeftNavigationBar isNavOpen ?bottom hideMenu openMenu>
174
+ {sideNavRender}
175
+ </LeftNavigationBar>
170
176
  <main
171
177
  className={cx([
172
178
  className,
@@ -0,0 +1,13 @@
1
+ type fallbackProps = {
2
+ error: Js.Exn.t,
3
+ resetErrorBoundary: unit => unit,
4
+ }
5
+
6
+ @module("react-error-boundary") @react.component
7
+ external make: (
8
+ ~fallback: React.element=?,
9
+ ~fallbackComponent: fallbackProps => React.element=?,
10
+ ~fallbackRender: fallbackProps => React.element=?,
11
+ ~children: React.element,
12
+ ~resetKeys: array<'a>=?,
13
+ ) => React.element = "ErrorBoundary"