Skip to content

Commit 53d3fb8

Browse files
committed
share collapsible navbar to layouts (docs, api, blog)
1 parent 6cb18fb commit 53d3fb8

9 files changed

+61
-33
lines changed

src/ApiDocs.res

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ let default = (props: props) => {
374374
metaTitle={title ++ " | ReScript API"}
375375
theme=#Reason
376376
components=ApiMarkdown.default
377+
navbarCollapsible=true
377378
sidebarState=(isSidebarOpen, setSidebarOpen)
378379
sidebar
379380
rightSidebar>

src/BlogArticle.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ let default = (props: props) => {
199199
</Markdown.Warn>
200200
</div>
201201
}
202-
<MainLayout> content </MainLayout>
202+
<MainLayout navbarCollapsible=true> content </MainLayout>
203203
}
204204

205205
let getStaticProps: Next.GetStaticProps.t<props, Params.t> = async ctx => {

src/common/ScrollDirectionHook.res

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/** scrollDir is not memo-friendly.
2+
It must be used with pattern matching.
3+
Do not pass it directly to child components. */
4+
type scrollDir =
5+
| Up({scrollY: int})
6+
| Down({scrollY: int})
7+
8+
/**
9+
This will cause highly frequent events, so use it only once in a root as possible.
10+
And split the children components to prevent heavy ones from being re-rendered unnecessarily. */
11+
let useScrollDirection = () => {
12+
let (_, startScrollEventTransition) = React.useTransition()
13+
let (scrollDir, setScrollDir) = React.useState(() => Up({scrollY: %raw(`Infinity`)}))
14+
15+
React.useEffect(() => {
16+
let onScroll = _e => {
17+
startScrollEventTransition(() => {
18+
setScrollDir(
19+
prev => {
20+
let Up({scrollY}) | Down({scrollY}) = prev
21+
if scrollY === 0 || scrollY > Webapi.Window.scrollY {
22+
Up({scrollY: Webapi.Window.scrollY})
23+
} else {
24+
Down({scrollY: Webapi.Window.scrollY})
25+
}
26+
},
27+
)
28+
})
29+
}
30+
Webapi.Window.addEventListener("scroll", onScroll)
31+
Some(() => Webapi.Window.removeEventListener("scroll", onScroll))
32+
}, [])
33+
34+
scrollDir
35+
}

src/layouts/ApiLayout.res

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ let make = (
133133
metaTitle={pageTitle ++ " | ReScript API"}
134134
theme=#Reason
135135
components
136+
navbarCollapsible=true
136137
sidebarState=(isSidebarOpen, setSidebarOpen)
137138
sidebar>
138139
children

src/layouts/DocsLayout.res

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ let make = (
152152
metaTitle
153153
theme
154154
components
155+
navbarCollapsible=true
155156
sidebarState=(isSidebarOpen, setSidebarOpen)
156157
sidebar
157158
categories

src/layouts/MainLayout.res

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
@react.component
2-
let make = (~components=MarkdownComponents.default, ~children) => {
2+
let make = (~components=MarkdownComponents.default, ~navbarCollapsible=false, ~children) => {
33
let (isOverlayOpen, setOverlayOpen) = React.useState(() => false)
4+
let scrollDir = ScrollDirectionHook.useScrollDirection()
5+
6+
let navAppearanceCascading = switch (navbarCollapsible, scrollDir) {
7+
| (true, Up(_)) => " group nav-appear"
8+
| (true, Down(_)) => " group nav-disappear"
9+
| _ => ""
10+
}
411

512
<>
6-
<div className="mt-4 xs:mt-16">
13+
<div className={"mt-4 xs:mt-16" ++ navAppearanceCascading}>
714
<div className="text-gray-80">
815
<Navigation isOverlayOpen setOverlayOpen />
916
<div className="flex xs:justify-center overflow-hidden pb-48">

src/layouts/MainLayout.resi

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
@react.component
2-
let make: (~components: MarkdownComponents.t=?, ~children: React.element) => React.element
2+
let make: (
3+
~components: MarkdownComponents.t=?,
4+
~navbarCollapsible: bool=?,
5+
~children: React.element,
6+
) => React.element

src/layouts/SidebarLayout.res

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,6 @@ module MobileDrawerButton = {
206206
</button>
207207
}
208208

209-
type scrollDir =
210-
| Up({scrollY: int})
211-
| Down({scrollY: int})
212-
213209
@react.component
214210
let make = (
215211
~metaTitle: string,
@@ -222,11 +218,11 @@ let make = (
222218
~rightSidebar: option<React.element>=?,
223219
~categories: option<array<Sidebar.Category.t>>=?,
224220
~breadcrumbs: option<list<Url.breadcrumb>>=?,
221+
~navbarCollapsible=false,
225222
~children,
226223
) => {
227224
let (isNavOpen, setNavOpen) = React.useState(() => false)
228-
let (_, startScrollEventTransition) = React.useTransition()
229-
let (scrollDir, setScrollDir) = React.useState(() => Up({scrollY: %raw(`Infinity`)}))
225+
let scrollDir = ScrollDirectionHook.useScrollDirection()
230226
let router = Next.Router.useRouter()
231227
let version = Url.parse(router.route).version
232228

@@ -260,25 +256,6 @@ let make = (
260256
)
261257
}, [])
262258

263-
React.useEffect(() => {
264-
let onScroll = _e => {
265-
startScrollEventTransition(() => {
266-
setScrollDir(
267-
prev => {
268-
let Up({scrollY}) | Down({scrollY}) = prev
269-
if scrollY === 0 || scrollY > Webapi.Window.scrollY {
270-
Up({scrollY: Webapi.Window.scrollY})
271-
} else {
272-
Down({scrollY: Webapi.Window.scrollY})
273-
}
274-
},
275-
)
276-
})
277-
}
278-
Webapi.Window.addEventListener("scroll", onScroll)
279-
Some(() => Webapi.Window.removeEventListener("scroll", onScroll))
280-
}, [])
281-
282259
let handleDrawerButtonClick = React.useCallback(evt => {
283260
ReactEvent.Mouse.preventDefault(evt)
284261
toggleSidebar()
@@ -327,14 +304,15 @@ let make = (
327304
| None => React.null
328305
}
329306

330-
let navAppearanceCascading = switch scrollDir {
331-
| Up(_) => "nav-appear"
332-
| Down(_) => "nav-disappear"
307+
let navAppearanceCascading = switch (navbarCollapsible, scrollDir) {
308+
| (true, Up(_)) => " group nav-appear"
309+
| (true, Down(_)) => " group nav-disappear"
310+
| _ => ""
333311
}
334312

335313
<>
336314
<Meta title=metaTitle version />
337-
<div className={"mt-16 min-w-320 " ++ theme ++ " group " ++ navAppearanceCascading}>
315+
<div className={"mt-16 min-w-320 " ++ theme ++ navAppearanceCascading}>
338316
<div className="w-full">
339317
<Navigation isOverlayOpen=isNavOpen setOverlayOpen=setNavOpen />
340318
<div className="flex lg:justify-center">

src/layouts/SidebarLayout.resi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,5 +73,6 @@ let make: (
7373
~rightSidebar: React.element=?,
7474
~categories: array<Sidebar.Category.t>=?,
7575
~breadcrumbs: list<Url.breadcrumb>=?,
76+
~navbarCollapsible: bool=?,
7677
~children: React.element,
7778
) => React.element

0 commit comments

Comments
 (0)