@colisweb/rescript-toolkit 2.63.0 → 2.64.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 +1 -1
- package/src/router/Toolkit__Router.res +89 -12
package/package.json
CHANGED
|
@@ -57,8 +57,23 @@ module Make = (Config: RouterConfig) => {
|
|
|
57
57
|
|
|
58
58
|
let useRoute = (): Config.t => RescriptReactRouter.useUrl()->Config.make
|
|
59
59
|
|
|
60
|
-
let isRouteEqual = (routeA: Config.t, routeB: Config.t): bool =>
|
|
61
|
-
routeA
|
|
60
|
+
let isRouteEqual = (routeA: Config.t, routeB: Config.t): bool => {
|
|
61
|
+
let routeA = {
|
|
62
|
+
let url = routeA->Config.toString
|
|
63
|
+
let queryParamsIndex = url->Js.String2.indexOf("?")
|
|
64
|
+
|
|
65
|
+
queryParamsIndex === -1 ? url : url->Js.String2.slice(~from=0, ~to_=queryParamsIndex)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let routeB = {
|
|
69
|
+
let url = routeB->Config.toString
|
|
70
|
+
let queryParamsIndex = url->Js.String2.indexOf("?")
|
|
71
|
+
|
|
72
|
+
queryParamsIndex === -1 ? url : url->Js.String2.slice(~from=0, ~to_=queryParamsIndex)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
routeA === routeB
|
|
76
|
+
}
|
|
62
77
|
|
|
63
78
|
let useIsCurrentRoute = (route: Config.t): bool => {
|
|
64
79
|
let {currentRoute} = React.useContext(routerContext)
|
|
@@ -71,6 +86,40 @@ module Make = (Config: RouterConfig) => {
|
|
|
71
86
|
|
|
72
87
|
let toString = Config.toString
|
|
73
88
|
|
|
89
|
+
module Breadcrumb = {
|
|
90
|
+
type link = {
|
|
91
|
+
route: Config.t,
|
|
92
|
+
text: React.element,
|
|
93
|
+
}
|
|
94
|
+
type state = {links: option<array<link>>}
|
|
95
|
+
|
|
96
|
+
type action =
|
|
97
|
+
| Reset
|
|
98
|
+
| Update(array<link>)
|
|
99
|
+
|
|
100
|
+
let store = Restorative.createStore({links: None}, (_state, action) =>
|
|
101
|
+
switch action {
|
|
102
|
+
| Reset => {links: None}
|
|
103
|
+
| Update(links) => {links: Some(links)}
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
let use = (routes: array<link>) => {
|
|
108
|
+
React.useLayoutEffect0(() => {
|
|
109
|
+
store.dispatch(Update(routes))
|
|
110
|
+
|
|
111
|
+
Some(() => store.dispatch(Reset))
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
let usePreviousLinkWithDefault = (defaultRoute, cb) => {
|
|
117
|
+
let {previousRoute} = React.useContext(routerContext)
|
|
118
|
+
previousRoute->Option.mapWithDefault(defaultRoute, route => {
|
|
119
|
+
cb(route) ? route : defaultRoute
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
|
|
74
123
|
module Link = {
|
|
75
124
|
@react.component
|
|
76
125
|
let make = (
|
|
@@ -170,7 +219,13 @@ module Make = (Config: RouterConfig) => {
|
|
|
170
219
|
|
|
171
220
|
module SingleLink = {
|
|
172
221
|
@react.component
|
|
173
|
-
let make = (
|
|
222
|
+
let make = (
|
|
223
|
+
~link: link,
|
|
224
|
+
~isNavOpen: bool,
|
|
225
|
+
~isSubLink=false,
|
|
226
|
+
~isActive=false,
|
|
227
|
+
~onLinkClick=() => (),
|
|
228
|
+
) =>
|
|
174
229
|
switch link {
|
|
175
230
|
| Legacy({icon, label, url}) =>
|
|
176
231
|
<a
|
|
@@ -198,7 +253,12 @@ module Make = (Config: RouterConfig) => {
|
|
|
198
253
|
| App({icon, label, route}) =>
|
|
199
254
|
<Link
|
|
200
255
|
route
|
|
201
|
-
className={cx([
|
|
256
|
+
className={cx([
|
|
257
|
+
commonClassName,
|
|
258
|
+
isSubLink ? "ml-3" : "",
|
|
259
|
+
"sidenav-link",
|
|
260
|
+
isActive ? "bg-primary-100/75 text-neutral-700" : "",
|
|
261
|
+
])}
|
|
202
262
|
activeClassName="bg-primary-100/75 text-neutral-700"
|
|
203
263
|
onClick={_ => onLinkClick()}>
|
|
204
264
|
<span className="overflow-hidden flex">
|
|
@@ -240,6 +300,17 @@ module Make = (Config: RouterConfig) => {
|
|
|
240
300
|
| App({route}) => isRouteEqual(currentRoute, route)
|
|
241
301
|
}
|
|
242
302
|
})
|
|
303
|
+
let breadcrumb = Breadcrumb.store.useStore()
|
|
304
|
+
|
|
305
|
+
let relativeRoute = breadcrumb.links->Option.mapWithDefault(None, breadcrumbLinks => {
|
|
306
|
+
links->Array.getBy(link => {
|
|
307
|
+
switch link {
|
|
308
|
+
| Legacy(_) => false
|
|
309
|
+
| App({route}) =>
|
|
310
|
+
breadcrumbLinks->Array.some(breadcrumbLink => breadcrumbLink.route->isRouteEqual(route))
|
|
311
|
+
}
|
|
312
|
+
})
|
|
313
|
+
})
|
|
243
314
|
|
|
244
315
|
React.useEffect1(() => {
|
|
245
316
|
if !isNavOpen {
|
|
@@ -257,11 +328,7 @@ module Make = (Config: RouterConfig) => {
|
|
|
257
328
|
className={cx([
|
|
258
329
|
commonClassName,
|
|
259
330
|
"flex items-center w-full sidenav-link",
|
|
260
|
-
|
|
261
|
-
| (true, true) => "bg-primary-100/50"
|
|
262
|
-
| (true, false) => "bg-primary-100/75"
|
|
263
|
-
| (false, _) => ""
|
|
264
|
-
},
|
|
331
|
+
hasActiveSubRoute || relativeRoute->Option.isSome ? "bg-primary-100/75" : "",
|
|
265
332
|
])}>
|
|
266
333
|
<span className={cx(["mr-2 text-neutral-800", isNavOpen ? "pl-2" : "px-2"])}>
|
|
267
334
|
groupInfo.icon
|
|
@@ -295,11 +362,21 @@ module Make = (Config: RouterConfig) => {
|
|
|
295
362
|
isOpen ? "h-auto" : "h-0 overflow-hidden",
|
|
296
363
|
])}>
|
|
297
364
|
{links
|
|
298
|
-
->Array.mapWithIndex((i, link) =>
|
|
365
|
+
->Array.mapWithIndex((i, link) => {
|
|
366
|
+
let isActive = switch (relativeRoute, link) {
|
|
367
|
+
| (Some(App({route: relativeRoute})), App({route})) =>
|
|
368
|
+
relativeRoute->isRouteEqual(route)
|
|
369
|
+
| _ => false
|
|
370
|
+
}
|
|
299
371
|
<SingleLink
|
|
300
|
-
key={"sidenav-grouped-" ++ i->Int.toString}
|
|
372
|
+
key={"sidenav-grouped-" ++ i->Int.toString}
|
|
373
|
+
link
|
|
374
|
+
isNavOpen
|
|
375
|
+
isSubLink=true
|
|
376
|
+
onLinkClick
|
|
377
|
+
isActive
|
|
301
378
|
/>
|
|
302
|
-
)
|
|
379
|
+
})
|
|
303
380
|
->React.array}
|
|
304
381
|
</div>
|
|
305
382
|
</>
|