Skip to content

Commit e2df73e

Browse files
authored
Merge pull request rescript-lang#31 from reason-association/800
Version switching between v8.0.0 / latest manual
2 parents a1befaa + 13f18e9 commit e2df73e

File tree

103 files changed

+8340
-37
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+8340
-37
lines changed

bindings/Next.re

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ module Router = {
104104
events: Events.t,
105105
};
106106

107+
[@bs.send] external push: (router, string ) => unit = "push";
108+
107109
[@bs.module "next/router"] external useRouter: unit => router = "useRouter";
108110
};
109111

common/App.re

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ type props = {
4242
"pageProps": pageProps,
4343
};
4444

45+
[@bs.get]
46+
external frontmatter: React.component(Js.t({.})) => Js.Json.t =
47+
"frontmatter";
48+
4549
let default = (props: props): React.element => {
4650
let component = props##"Component";
4751
let pageProps = props##pageProps;
@@ -54,8 +58,18 @@ let default = (props: props): React.element => {
5458

5559
switch (url) {
5660
// docs routes
57-
| {base: [|"docs", "manual"|], version: Latest} =>
58-
<ManualDocsLayout.Prose> content </ManualDocsLayout.Prose>
61+
| {base: [|"docs", "manual"|], version} =>
62+
switch (version) {
63+
| Latest =>
64+
<ManualDocsLayout.Prose frontmatter={component->frontmatter}>
65+
content
66+
</ManualDocsLayout.Prose>
67+
| Version("v8.0.0") =>
68+
<ManualDocsLayout8_0_0.Prose frontmatter={component->frontmatter}>
69+
content
70+
</ManualDocsLayout8_0_0.Prose>
71+
| _ => React.null
72+
}
5973
| {base: [|"docs", "reason-compiler"|], version: Latest} =>
6074
<ReasonCompilerDocsLayout> content </ReasonCompilerDocsLayout>
6175
| {base: [|"docs", "reason-react"|], version: Latest} =>

common/DocFrontmatter.re

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
type t = {
2+
title: string,
3+
description: Js.null(string),
4+
canonical: Js.null(string),
5+
};
6+
7+
let decode = (json): result(t, string) => {
8+
open! Json.Decode;
9+
try(
10+
Ok({
11+
title: field("title", string, json),
12+
description:
13+
optional(field("description", string), json)->Js.Null.fromOption,
14+
canonical:
15+
optional(field("canonical", string), json)->Js.Null.fromOption,
16+
})
17+
) {
18+
| DecodeError(errMsg) => Error(errMsg)
19+
};
20+
};

layouts/DocsLayout.re

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

36+
module VersionSelect = {
37+
[@react.component]
38+
let make =
39+
(
40+
~onChange,
41+
~version: string,
42+
~latestVersionLabel: string,
43+
~availableVersions: array(string),
44+
) => {
45+
let children =
46+
Belt.Array.map(
47+
availableVersions,
48+
ver => {
49+
let label = ver === "latest" ? latestVersionLabel : ver;
50+
<option className="py-4" key=ver value=ver> label->s </option>;
51+
},
52+
);
53+
<select
54+
className="text-14 border border-fire inline-block rounded px-4 py-1 font-semibold "
55+
name="versionSelection"
56+
value=version
57+
onChange>
58+
children->ate
59+
</select>;
60+
};
61+
};
62+
3663
module Sidebar = {
3764
module Title = {
3865
[@react.component]
@@ -309,7 +336,10 @@ let make =
309336
(
310337
~breadcrumbs: option(list(UrlPath.breadcrumb))=?,
311338
~title: string,
339+
~frontmatter: option(Js.Json.t)=?,
312340
~version: option(string)=?,
341+
~availableVersions: option(array(string))=?,
342+
~latestVersionLabel: string="latest",
313343
~activeToc: option(Toc.t)=?,
314344
~categories: array(Category.t),
315345
~components=Markdown.default,
@@ -350,7 +380,31 @@ let make =
350380
title->s
351381
{switch (version) {
352382
| Some(version) =>
353-
<span className="font-mono text-sm"> version->s </span>
383+
switch (availableVersions) {
384+
| Some(availableVersions) =>
385+
let onChange = evt => {
386+
open Url;
387+
ReactEvent.Form.preventDefault(evt);
388+
let version = evt->ReactEvent.Form.target##value;
389+
let url = Url.parse(route);
390+
391+
let targetUrl =
392+
"/"
393+
++ Js.Array2.joinWith(url.base, "/")
394+
++ "/"
395+
++ version
396+
++ "/"
397+
++ Js.Array2.joinWith(url.pagepath, "/");
398+
router->Next.Router.push(targetUrl);
399+
};
400+
<VersionSelect
401+
latestVersionLabel
402+
onChange
403+
version
404+
availableVersions
405+
/>;
406+
| None => <span className="font-mono text-sm"> version->s </span>
407+
}
354408
| None => React.null
355409
}}
356410
</div>;
@@ -368,13 +422,28 @@ let make =
368422

369423
let metaTitle = title ++ " | ReScript Documentation";
370424

425+
let metaElement =
426+
switch (frontmatter) {
427+
| Some(frontmatter) =>
428+
switch (DocFrontmatter.decode(frontmatter)) {
429+
| Ok(fm) =>
430+
let canonical = Js.Null.toOption(fm.canonical);
431+
let description = Js.Null.toOption(fm.description);
432+
let title = fm.title ++ " | ReScript Language Manual";
433+
<Meta title ?description ?canonical />;
434+
| Error(_) => React.null
435+
}
436+
| None => React.null
437+
};
438+
371439
<SidebarLayout
372440
metaTitle
373441
theme
374442
components
375443
sidebarState=(isSidebarOpen, setSidebarOpen)
376444
sidebar
377445
?breadcrumbs>
446+
metaElement
378447
children
379448
</SidebarLayout>;
380449
};

layouts/ManualDocsLayout.re

Lines changed: 57 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
let version = "v8.2.0";
2-
31
module Link = Next.Link;
42

3+
// This is used for the version dropdown in the manual layouts
4+
let allManualVersions = [|"latest", "v8.0.0"|];
5+
6+
// Used for replacing "latest" with "vX.X.X" in the version dropdown
7+
let latestVersionLabel = "v8.2.0";
8+
59
// Structure defined by `scripts/extract-tocs.js`
610
let tocData:
711
Js.Dict.t({
@@ -24,7 +28,10 @@ module Toc = DocsLayout.Toc;
2428

2529
let overviewNavs = [|
2630
NavItem.{name: "Introduction", href: "/docs/manual/latest/introduction"},
27-
{name: "Migrate from BuckleScript/Reason", href: "/docs/manual/latest/migrate-from-bucklescript-reason"},
31+
{
32+
name: "Migrate from BuckleScript/Reason",
33+
href: "/docs/manual/latest/migrate-from-bucklescript-reason",
34+
},
2835
{name: "Installation", href: "/docs/manual/latest/installation"},
2936
{name: "Try", href: "/docs/manual/latest/try"},
3037
{name: "Editor Plugins", href: "/docs/manual/latest/editor-plugins"},
@@ -47,7 +54,10 @@ let basicNavs = [|
4754
{name: "Function", href: "/docs/manual/latest/function"},
4855
{name: "Control Flow", href: "/docs/manual/latest/control-flow"},
4956
{name: "Pipe", href: "/docs/manual/latest/pipe"},
50-
{name: "Pattern Matching/Destructuring", href: "/docs/manual/latest/pattern-matching-destructuring"},
57+
{
58+
name: "Pattern Matching/Destructuring",
59+
href: "/docs/manual/latest/pattern-matching-destructuring",
60+
},
5161
{name: "Mutation", href: "/docs/manual/latest/mutation"},
5262
{name: "JSX", href: "/docs/manual/latest/jsx"},
5363
{name: "External", href: "/docs/manual/latest/external"},
@@ -60,22 +70,13 @@ let basicNavs = [|
6070
|];
6171

6272
let buildsystemNavs = [|
63-
NavItem.{
64-
name: "Overview",
65-
href: "/docs/manual/latest/build-overview",
66-
},
67-
{
68-
name: "Configuration",
69-
href: "/docs/manual/latest/build-configuration",
70-
},
73+
NavItem.{name: "Overview", href: "/docs/manual/latest/build-overview"},
74+
{name: "Configuration", href: "/docs/manual/latest/build-configuration"},
7175
{
7276
name: "Interop with JS Build System",
7377
href: "/docs/manual/latest/interop-with-js-build-systems",
7478
},
75-
{
76-
name: "Performance",
77-
href: "/docs/manual/latest/build-performance",
78-
},
79+
{name: "Performance", href: "/docs/manual/latest/build-performance"},
7980
|];
8081

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

97116
let guidesNavs = [|
@@ -103,7 +122,10 @@ let guidesNavs = [|
103122
|];
104123

105124
let extraNavs = [|
106-
NavItem.{name: "Newcomer Examples", href: "/docs/manual/latest/newcomer-examples"},
125+
NavItem.{
126+
name: "Newcomer Examples",
127+
href: "/docs/manual/latest/newcomer-examples",
128+
},
107129
{name: "Project Structure", href: "/docs/manual/latest/project-structure"},
108130
{name: "FAQ", href: "/docs/manual/latest/faq"},
109131
|];
@@ -119,7 +141,12 @@ let categories = [|
119141

120142
module Docs = {
121143
[@react.component]
122-
let make = (~components=Markdown.default, ~children) => {
144+
let make =
145+
(
146+
~frontmatter: option(Js.Json.t)=?,
147+
~components=Markdown.default,
148+
~children,
149+
) => {
123150
let router = Next.Router.useRouter();
124151
let route = router.route;
125152

@@ -156,13 +183,17 @@ module Docs = {
156183
);
157184

158185
let title = "Language Manual";
186+
let version = "latest";
159187

160188
<DocsLayout
161189
theme=`Reason
162190
components
163191
categories
164192
version
165193
title
194+
availableVersions=allManualVersions
195+
latestVersionLabel
196+
?frontmatter
166197
?activeToc
167198
?breadcrumbs>
168199
children
@@ -172,9 +203,7 @@ module Docs = {
172203

173204
module Prose = {
174205
[@react.component]
175-
let make = (~children) => {
176-
<Docs components=Markdown.default>
177-
children
178-
</Docs>;
206+
let make = (~frontmatter: option(Js.Json.t)=?, ~children) => {
207+
<Docs ?frontmatter components=Markdown.default> children </Docs>;
179208
};
180209
};

0 commit comments

Comments
 (0)