Skip to content

Commit 25fc0a8

Browse files
committed
Add version toggle for docs layout
1 parent 770cda9 commit 25fc0a8

File tree

3 files changed

+158
-53
lines changed

3 files changed

+158
-53
lines changed

layouts/DocsLayout.re

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,23 @@ module Toc = {
3333
};
3434
};
3535

36+
module VersionSelect = {
37+
[@react.component]
38+
let make = (~onChange, ~version: string, ~availableVersions: array(string)) => {
39+
let children =
40+
Belt.Array.map(availableVersions, ver => {
41+
<option className="py-4" key=ver value=ver> ver->s </option>
42+
});
43+
<select
44+
className="text-14 border border-fire inline-block rounded px-4 py-1 font-semibold "
45+
name="versionSelection"
46+
value=version
47+
onChange>
48+
children->ate
49+
</select>;
50+
};
51+
};
52+
3653
module Sidebar = {
3754
module Title = {
3855
[@react.component]
@@ -311,6 +328,7 @@ let make =
311328
~title: string,
312329
~frontmatter: option(Js.Json.t)=?,
313330
~version: option(string)=?,
331+
~availableVersions: option(array(string))=?,
314332
~activeToc: option(Toc.t)=?,
315333
~categories: array(Category.t),
316334
~components=Markdown.default,
@@ -351,7 +369,29 @@ let make =
351369
title->s
352370
{switch (version) {
353371
| Some(version) =>
354-
<span className="font-mono text-sm"> version->s </span>
372+
switch (availableVersions) {
373+
| Some(availableVersions) =>
374+
let onChange = evt => {
375+
open Url;
376+
ReactEvent.Form.preventDefault(evt);
377+
let version = evt->ReactEvent.Form.target##value;
378+
Js.log2("selected version", version);
379+
let url = Url.parse(route);
380+
381+
Js.log2("url", url);
382+
let targetUrl =
383+
"/"
384+
++ Js.Array2.joinWith(url.base, "/")
385+
++ "/"
386+
++ version
387+
++ "/"
388+
++ Js.Array2.joinWith(url.pagepath, "/");
389+
Js.log2("targetUrl", targetUrl);
390+
router->Next.Router.push(targetUrl);
391+
};
392+
<VersionSelect onChange version availableVersions />;
393+
| None => <span className="font-mono text-sm"> version->s </span>
394+
}
355395
| None => React.null
356396
}}
357397
</div>;

layouts/ManualDocsLayout.re

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
module Link = Next.Link;
22

3+
// This is used for the version dropdown in the manual layouts
4+
let allManualVersions = [|"latest", "v8.0.0"|];
5+
36
// Structure defined by `scripts/extract-tocs.js`
47
let tocData:
58
Js.Dict.t({
@@ -22,7 +25,10 @@ module Toc = DocsLayout.Toc;
2225

2326
let overviewNavs = [|
2427
NavItem.{name: "Introduction", href: "/docs/manual/latest/introduction"},
25-
{name: "Migrate from BuckleScript/Reason", href: "/docs/manual/latest/migrate-from-bucklescript-reason"},
28+
{
29+
name: "Migrate from BuckleScript/Reason",
30+
href: "/docs/manual/latest/migrate-from-bucklescript-reason",
31+
},
2632
{name: "Installation", href: "/docs/manual/latest/installation"},
2733
{name: "Try", href: "/docs/manual/latest/try"},
2834
{name: "Editor Plugins", href: "/docs/manual/latest/editor-plugins"},
@@ -45,7 +51,10 @@ let basicNavs = [|
4551
{name: "Function", href: "/docs/manual/latest/function"},
4652
{name: "Control Flow", href: "/docs/manual/latest/control-flow"},
4753
{name: "Pipe", href: "/docs/manual/latest/pipe"},
48-
{name: "Pattern Matching/Destructuring", href: "/docs/manual/latest/pattern-matching-destructuring"},
54+
{
55+
name: "Pattern Matching/Destructuring",
56+
href: "/docs/manual/latest/pattern-matching-destructuring",
57+
},
4958
{name: "Mutation", href: "/docs/manual/latest/mutation"},
5059
{name: "JSX", href: "/docs/manual/latest/jsx"},
5160
{name: "External", href: "/docs/manual/latest/external"},
@@ -58,22 +67,13 @@ let basicNavs = [|
5867
|];
5968

6069
let buildsystemNavs = [|
61-
NavItem.{
62-
name: "Overview",
63-
href: "/docs/manual/latest/build-overview",
64-
},
65-
{
66-
name: "Configuration",
67-
href: "/docs/manual/latest/build-configuration",
68-
},
70+
NavItem.{name: "Overview", href: "/docs/manual/latest/build-overview"},
71+
{name: "Configuration", href: "/docs/manual/latest/build-configuration"},
6972
{
7073
name: "Interop with JS Build System",
7174
href: "/docs/manual/latest/interop-with-js-build-systems",
7275
},
73-
{
74-
name: "Performance",
75-
href: "/docs/manual/latest/build-performance",
76-
},
76+
{name: "Performance", href: "/docs/manual/latest/build-performance"},
7777
|];
7878

7979
let jsInteropNavs = [|
@@ -83,13 +83,31 @@ let jsInteropNavs = [|
8383
},
8484
{name: "Shared Data Types", href: "/docs/manual/latest/shared-data-types"},
8585
{name: "Bind to JS Object", href: "/docs/manual/latest/bind-to-js-object"},
86-
{name: "Bind to JS Function", href: "/docs/manual/latest/bind-to-js-function"},
87-
{name: "Import from/Export to JS", href: "/docs/manual/latest/import-from-export-to-js"},
88-
{name: "Bind to Global JS Values", href: "/docs/manual/latest/bind-to-global-js-values"},
86+
{
87+
name: "Bind to JS Function",
88+
href: "/docs/manual/latest/bind-to-js-function",
89+
},
90+
{
91+
name: "Import from/Export to JS",
92+
href: "/docs/manual/latest/import-from-export-to-js",
93+
},
94+
{
95+
name: "Bind to Global JS Values",
96+
href: "/docs/manual/latest/bind-to-global-js-values",
97+
},
8998
{name: "JSON", href: "/docs/manual/latest/json"},
90-
{name: "Use Illegal Identifier Names", href: "/docs/manual/latest/use-illegal-identifier-names"},
91-
{name: "Browser Support & Polyfills", href: "/docs/manual/latest/browser-support-polyfills"},
92-
{name: "Interop Cheatsheet", href: "/docs/manual/latest/interop-cheatsheet"},
99+
{
100+
name: "Use Illegal Identifier Names",
101+
href: "/docs/manual/latest/use-illegal-identifier-names",
102+
},
103+
{
104+
name: "Browser Support & Polyfills",
105+
href: "/docs/manual/latest/browser-support-polyfills",
106+
},
107+
{
108+
name: "Interop Cheatsheet",
109+
href: "/docs/manual/latest/interop-cheatsheet",
110+
},
93111
|];
94112

95113
let guidesNavs = [|
@@ -101,7 +119,10 @@ let guidesNavs = [|
101119
|];
102120

103121
let extraNavs = [|
104-
NavItem.{name: "Newcomer Examples", href: "/docs/manual/latest/newcomer-examples"},
122+
NavItem.{
123+
name: "Newcomer Examples",
124+
href: "/docs/manual/latest/newcomer-examples",
125+
},
105126
{name: "Project Structure", href: "/docs/manual/latest/project-structure"},
106127
{name: "FAQ", href: "/docs/manual/latest/faq"},
107128
|];
@@ -154,14 +175,15 @@ module Docs = {
154175
);
155176

156177
let title = "Language Manual";
157-
let version = "v8.2.0";
178+
let version = "latest";
158179

159180
<DocsLayout
160181
theme=`Reason
161182
components
162183
categories
163184
version
164185
title
186+
availableVersions=allManualVersions
165187
?activeToc
166188
?breadcrumbs>
167189
children
@@ -172,8 +194,6 @@ module Docs = {
172194
module Prose = {
173195
[@react.component]
174196
let make = (~children) => {
175-
<Docs components=Markdown.default>
176-
children
177-
</Docs>;
197+
<Docs components=Markdown.default> children </Docs>;
178198
};
179199
};

layouts/ManualDocsLayout8_0_0.re

Lines changed: 72 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
let version = "v8.0.0";
2-
1+
open Util.ReactStuff;
32
module Link = Next.Link;
43

54
// Structure defined by `scripts/extract-tocs.js`
@@ -14,7 +13,7 @@ let tocData:
1413
"href": string,
1514
}),
1615
}) = [%raw
17-
"require('../index_data/manual_toc.json')"
16+
"require('../index_data/manual_v800_toc.json')"
1817
];
1918

2019
module UrlPath = DocsLayout.UrlPath;
@@ -24,7 +23,10 @@ module Toc = DocsLayout.Toc;
2423

2524
let overviewNavs = [|
2625
NavItem.{name: "Introduction", href: "/docs/manual/v8.0.0/introduction"},
27-
{name: "Migrate to New Syntax", href: "/docs/manual/v8.0.0/migrate-to-new-syntax"},
26+
{
27+
name: "Migrate to New Syntax",
28+
href: "/docs/manual/v8.0.0/migrate-to-new-syntax",
29+
},
2830
{name: "Installation", href: "/docs/manual/v8.0.0/installation"},
2931
{name: "Try", href: "/docs/manual/v8.0.0/try"},
3032
{name: "Editor Plugins", href: "/docs/manual/v8.0.0/editor-plugins"},
@@ -47,7 +49,10 @@ let basicNavs = [|
4749
{name: "Function", href: "/docs/manual/v8.0.0/function"},
4850
{name: "Control Flow", href: "/docs/manual/v8.0.0/control-flow"},
4951
{name: "Pipe", href: "/docs/manual/v8.0.0/pipe"},
50-
{name: "Pattern Matching/Destructuring", href: "/docs/manual/v8.0.0/pattern-matching-destructuring"},
52+
{
53+
name: "Pattern Matching/Destructuring",
54+
href: "/docs/manual/v8.0.0/pattern-matching-destructuring",
55+
},
5156
{name: "Mutation", href: "/docs/manual/v8.0.0/mutation"},
5257
{name: "JSX", href: "/docs/manual/v8.0.0/jsx"},
5358
{name: "External", href: "/docs/manual/v8.0.0/external"},
@@ -60,22 +65,13 @@ let basicNavs = [|
6065
|];
6166

6267
let buildsystemNavs = [|
63-
NavItem.{
64-
name: "Overview",
65-
href: "/docs/manual/v8.0.0/build-overview",
66-
},
67-
{
68-
name: "Configuration",
69-
href: "/docs/manual/v8.0.0/build-configuration",
70-
},
68+
NavItem.{name: "Overview", href: "/docs/manual/v8.0.0/build-overview"},
69+
{name: "Configuration", href: "/docs/manual/v8.0.0/build-configuration"},
7170
{
7271
name: "Interop with JS Build System",
7372
href: "/docs/manual/v8.0.0/interop-with-js-build-systems",
7473
},
75-
{
76-
name: "Performance",
77-
href: "/docs/manual/v8.0.0/build-performance",
78-
},
74+
{name: "Performance", href: "/docs/manual/v8.0.0/build-performance"},
7975
|];
8076

8177
let jsInteropNavs = [|
@@ -85,12 +81,27 @@ let jsInteropNavs = [|
8581
},
8682
{name: "Shared Data Types", href: "/docs/manual/v8.0.0/shared-data-types"},
8783
{name: "Bind to JS Object", href: "/docs/manual/v8.0.0/bind-to-js-object"},
88-
{name: "Bind to JS Function", href: "/docs/manual/v8.0.0/bind-to-js-function"},
89-
{name: "Import from/Export to JS", href: "/docs/manual/v8.0.0/import-from-export-to-js"},
90-
{name: "Bind to Global JS Values", href: "/docs/manual/v8.0.0/bind-to-global-js-values"},
84+
{
85+
name: "Bind to JS Function",
86+
href: "/docs/manual/v8.0.0/bind-to-js-function",
87+
},
88+
{
89+
name: "Import from/Export to JS",
90+
href: "/docs/manual/v8.0.0/import-from-export-to-js",
91+
},
92+
{
93+
name: "Bind to Global JS Values",
94+
href: "/docs/manual/v8.0.0/bind-to-global-js-values",
95+
},
9196
{name: "JSON", href: "/docs/manual/v8.0.0/json"},
92-
{name: "Browser Support & Polyfills", href: "/docs/manual/v8.0.0/browser-support-polyfills"},
93-
{name: "Interop Cheatsheet", href: "/docs/manual/v8.0.0/interop-cheatsheet"},
97+
{
98+
name: "Browser Support & Polyfills",
99+
href: "/docs/manual/v8.0.0/browser-support-polyfills",
100+
},
101+
{
102+
name: "Interop Cheatsheet",
103+
href: "/docs/manual/v8.0.0/interop-cheatsheet",
104+
},
94105
|];
95106

96107
let guidesNavs = [|
@@ -102,7 +113,10 @@ let guidesNavs = [|
102113
|];
103114

104115
let extraNavs = [|
105-
NavItem.{name: "Newcomer Examples", href: "/docs/manual/v8.0.0/newcomer-examples"},
116+
NavItem.{
117+
name: "Newcomer Examples",
118+
href: "/docs/manual/v8.0.0/newcomer-examples",
119+
},
106120
{name: "Project Structure", href: "/docs/manual/v8.0.0/project-structure"},
107121
{name: "FAQ", href: "/docs/manual/v8.0.0/faq"},
108122
|];
@@ -118,7 +132,12 @@ let categories = [|
118132

119133
module Docs = {
120134
[@react.component]
121-
let make = (~frontmatter: option(Js.Json.t)=?, ~components=Markdown.default, ~children) => {
135+
let make =
136+
(
137+
~frontmatter: option(Js.Json.t)=?,
138+
~components=Markdown.default,
139+
~children,
140+
) => {
122141
let router = Next.Router.useRouter();
123142
let route = router.route;
124143

@@ -155,16 +174,44 @@ module Docs = {
155174
);
156175

157176
let title = "Language Manual";
177+
let version = "v8.0.0";
178+
179+
let url = Url.parse(route);
180+
let latestUrl =
181+
"/"
182+
++ Js.Array2.joinWith(url.base, "/")
183+
++ "/latest/"
184+
++ Js.Array2.joinWith(url.pagepath, "/");
185+
186+
let warnBanner =
187+
Markdown.(
188+
<div className="mb-10">
189+
<Info>
190+
<P>
191+
{(
192+
"You are currently looking at the "
193+
++ version
194+
++ " docs. You can find the latest manual page "
195+
)
196+
->s}
197+
<A href=latestUrl> "here"->s </A>
198+
"."->s
199+
</P>
200+
</Info>
201+
</div>
202+
);
158203

159204
<DocsLayout
160205
theme=`Reason
161206
components
162207
categories
163208
version
209+
availableVersions=ManualDocsLayout.allManualVersions
164210
?frontmatter
165211
title
166212
?activeToc
167213
?breadcrumbs>
214+
warnBanner
168215
children
169216
</DocsLayout>;
170217
};
@@ -173,8 +220,6 @@ module Docs = {
173220
module Prose = {
174221
[@react.component]
175222
let make = (~frontmatter: option(Js.Json.t)=?, ~children) => {
176-
<Docs ?frontmatter components=Markdown.default>
177-
children
178-
</Docs>;
223+
<Docs ?frontmatter components=Markdown.default> children </Docs>;
179224
};
180225
};

0 commit comments

Comments
 (0)