Skip to content

Commit 9ef6c0b

Browse files
committed
Migrate to TypeScript
1 parent 5bb5e78 commit 9ef6c0b

File tree

21 files changed

+305
-206
lines changed

21 files changed

+305
-206
lines changed
Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1+
import type * as Preset from '@docusaurus/preset-classic';
2+
import type { Config } from '@docusaurus/types';
3+
14
import rehypeCodeblockMeta from './src/plugins/rehype-codeblock-meta.mjs';
25
import rehypeStaticToDynamic from './src/plugins/rehype-static-to-dynamic.mjs';
36
import rehypeVideoAspectRatio from './src/plugins/rehype-video-aspect-ratio.mjs';
47
import remarkNpm2Yarn from './src/plugins/remark-npm2yarn.mjs';
8+
import darkTheme from './src/themes/react-navigation-dark';
9+
import lightTheme from './src/themes/react-navigation-light';
510

6-
export default {
11+
const config: Config = {
712
title: 'React Navigation',
813
tagline: 'Routing and navigation for your React Native apps',
914
url: 'https://reactnavigation.org/',
@@ -26,8 +31,8 @@ export default {
2631
respectPrefersColorScheme: true,
2732
},
2833
prism: {
29-
theme: require('./src/themes/react-navigation-light.js'),
30-
darkTheme: require('./src/themes/react-navigation-dark.js'),
34+
theme: lightTheme,
35+
darkTheme: darkTheme,
3136
additionalLanguages: [
3237
'bash',
3338
'json',
@@ -53,7 +58,6 @@ export default {
5358
appId: 'QCWXRU195A',
5459
apiKey: 'bad995329370d9a9ba50cc4b840a3884',
5560
indexName: 'react-navigation',
56-
algoliaOptions: {},
5761
},
5862
navbar: {
5963
title: 'React Navigation',
@@ -122,7 +126,7 @@ export default {
122126
},
123127
],
124128
},
125-
},
129+
} satisfies Preset.ThemeConfig,
126130
plugins: [
127131
'./src/plugins/disable-fully-specified.mjs',
128132
'./src/plugins/react-navigation-versions.mjs',
@@ -179,12 +183,12 @@ export default {
179183
remarkPlugins: [[remarkNpm2Yarn, { sync: true }]],
180184
},
181185
theme: {
182-
customCss: require.resolve('./src/css/custom.css'),
186+
customCss: './src/css/custom.css',
183187
},
184188
googleAnalytics: {
185189
trackingID: 'UA-10128745-16',
186190
},
187-
},
191+
} satisfies Preset.Options,
188192
],
189193
],
190194
headTags: [
@@ -217,3 +221,5 @@ export default {
217221
'/js/video-playback.js',
218222
],
219223
};
224+
225+
export default config;

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"clear": "docusaurus clear",
99
"serve": "docusaurus serve",
1010
"swizzle": "docusaurus swizzle",
11+
"typecheck": "tsc",
1112
"deploy": "DEPLOYMENT_BRANCH=gh-pages docusaurus deploy",
1213
"test": "node --test --test-reporter=@voxpelli/node-test-pretty-reporter",
1314
"crowdin-upload": "crowdin upload sources --auto-update -b main",
@@ -34,13 +35,17 @@
3435
},
3536
"devDependencies": {
3637
"@babel/types": "^7.28.5",
38+
"@docusaurus/tsconfig": "^3.9.2",
3739
"@ffprobe-installer/ffprobe": "^2.1.2",
40+
"@types/react": "^19.2.8",
41+
"@types/react-dom": "^19.2.3",
3842
"@voxpelli/node-test-pretty-reporter": "^1.1.2",
3943
"markdownlint": "^0.40.0",
4044
"markdownlint-cli2": "^0.19.1",
4145
"postcss-nesting": "^13.0.2",
4246
"prettier": "^3.7.4",
43-
"recast": "^0.23.11"
47+
"recast": "^0.23.11",
48+
"typescript": "^5.9.3"
4449
},
4550
"packageManager": "yarn@4.0.2",
4651
"browserslist": {
Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,23 @@ import * as React from 'react';
55
import Editor from 'react-simple-code-editor';
66
import RouteMap from './RouteMap';
77

8-
const parse = (value) => eval(`(function() { return ${value}; }())`);
8+
const parse = (value: string) => eval(`(function() { return ${value}; }())`);
99

10-
function Code({ code, theme, language }) {
10+
type Props = {
11+
code: string;
12+
theme: typeof themes.dracula;
13+
language: string;
14+
};
15+
16+
function Code({ code, theme, language }: Props) {
1117
return (
1218
<Highlight code={code} theme={theme} language={language}>
1319
{({ className, style, tokens, getLineProps, getTokenProps }) => (
1420
<pre className={className} style={{ ...style, ...styles.json }}>
1521
{tokens.map((line, i) => (
16-
<div {...getLineProps({ line, key: i })}>
22+
<div {...getLineProps({ line, key: i })} key={i}>
1723
{line.map((token, key) => (
18-
<span {...getTokenProps({ token, key })} />
24+
<span {...getTokenProps({ token, key })} key={key} />
1925
))}
2026
</div>
2127
))}
@@ -53,13 +59,15 @@ export default function LinkingTester() {
5359

5460
const [path, setPath] = React.useState('/user/@vergil/edit');
5561
const [config, setConfig] = React.useState(() => parse(rawConfig));
56-
const [pane, setPane] = React.useState('chart');
62+
const [pane, setPane] = React.useState<'chart' | 'state' | 'action'>('chart');
5763

5864
let state, action;
5965

6066
try {
6167
state = getStateFromPath(path.replace(/(^\w+:|^)\/\//, ''), config);
62-
action = getActionFromState(state, config);
68+
if (state) {
69+
action = getActionFromState(state, config);
70+
}
6371
} catch (e) {
6472
// Ignore
6573
}
@@ -89,15 +97,17 @@ export default function LinkingTester() {
8997
}}
9098
highlight={(code) => (
9199
<Highlight code={code} theme={theme} language="jsx">
92-
{({ tokens, getLineProps, getTokenProps }) =>
93-
tokens.map((line, i) => (
94-
<div {...getLineProps({ line, key: i })}>
95-
{line.map((token, key) => (
96-
<span {...getTokenProps({ token, key })} />
97-
))}
98-
</div>
99-
))
100-
}
100+
{({ tokens, getLineProps, getTokenProps }) => (
101+
<>
102+
{tokens.map((line, i) => (
103+
<div {...getLineProps({ line, key: i })} key={i}>
104+
{line.map((token, key) => (
105+
<span {...getTokenProps({ token, key })} key={key} />
106+
))}
107+
</div>
108+
))}
109+
</>
110+
)}
101111
</Highlight>
102112
)}
103113
padding={16}
@@ -154,7 +164,7 @@ export default function LinkingTester() {
154164
);
155165
}
156166

157-
const styles = {
167+
const styles: Record<string, React.CSSProperties> = {
158168
code: {
159169
display: 'block',
160170
fontFamily: 'var(--ifm-font-family-monospace)',
Lines changed: 74 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,32 @@ const COMMENTS = {
1212
FOCUS_END: '// codeblock-focus-end',
1313
};
1414

15+
type Props = {
16+
children: React.ReactElement<{ className?: string; children: string }>;
17+
'data-name'?: string;
18+
'data-snack'?: string | 'embed';
19+
'data-dependencies'?: string;
20+
'data-lang'?: string;
21+
};
22+
1523
export default function Pre({
1624
children,
1725
'data-name': name,
1826
'data-snack': snack,
1927
'data-dependencies': deps,
2028
'data-lang': lang,
2129
...rest
22-
}) {
30+
}: Props) {
2331
const [isExpanded, setIsExpanded] = React.useState(false);
2432

2533
const { colorMode } = useColorMode();
26-
const activeVersion = useActiveVersion();
27-
const { versions } = usePluginData('react-navigation-versions');
34+
const activeVersion = useActiveVersion(undefined);
35+
const { versions } = usePluginData('react-navigation-versions') as {
36+
versions: Record<
37+
string,
38+
Record<string, string | [string, Record<string, string>]>
39+
>;
40+
};
2841

2942
const child = React.Children.only(children);
3043

@@ -57,15 +70,17 @@ export default function Pre({
5770
})
5871
.join('\n');
5972

60-
children = React.cloneElement(child, {
61-
className: `language-${lang}`,
62-
children: content,
63-
});
64-
65-
return <MDXPre {...rest}>{children}</MDXPre>;
73+
return (
74+
<MDXPre {...rest}>
75+
{React.cloneElement(child, {
76+
className: `language-${lang}`,
77+
children: content,
78+
})}
79+
</MDXPre>
80+
);
6681
}
6782

68-
const buttons = [];
83+
const buttons: React.ReactNode[] = [];
6984

7085
if (child.props.children.includes?.(COMMENTS.FOCUS_START)) {
7186
buttons.push(
@@ -106,7 +121,7 @@ export default function Pre({
106121
const version = activeVersion?.name;
107122

108123
// Handle snack demos
109-
if (snack && versions[version] != null) {
124+
if (snack && version && versions[version] != null) {
110125
const code = child.props.children;
111126

112127
if (typeof code !== 'string') {
@@ -115,7 +130,7 @@ export default function Pre({
115130
);
116131
}
117132

118-
const dependencies = deps
133+
const dependencies: Record<string, string> = deps
119134
? Object.fromEntries(
120135
deps.split(',').map((entry) => {
121136
let prefix = '';
@@ -135,34 +150,37 @@ export default function Pre({
135150

136151
Object.assign(
137152
dependencies,
138-
Object.entries(versions[version]).reduce((acc, [key, value]) => {
139-
if (code.includes(`from '${key}'`)) {
140-
if (Array.isArray(value)) {
141-
const [v, peers] = value;
142-
143-
Object.assign(acc, {
144-
[key]: v,
145-
...Object.fromEntries(
146-
Object.entries(peers).map(([key, value]) => {
147-
const meta = versions[version][key];
148-
149-
if (value === '*' && meta) {
150-
const v = Array.isArray(meta) ? meta[0] : meta;
151-
152-
return [key, v];
153-
}
154-
155-
return [key, value];
156-
})
157-
),
158-
});
159-
} else {
160-
acc[key] = value;
153+
Object.entries(versions[version]).reduce(
154+
(acc, [key, value]) => {
155+
if (code.includes(`from '${key}'`)) {
156+
if (Array.isArray(value)) {
157+
const [v, peers] = value;
158+
159+
Object.assign(acc, {
160+
[key]: v,
161+
...Object.fromEntries(
162+
Object.entries(peers).map(([key, value]) => {
163+
const meta = versions[version][key];
164+
165+
if (value === '*' && meta) {
166+
const v = Array.isArray(meta) ? meta[0] : meta;
167+
168+
return [key, v];
169+
}
170+
171+
return [key, value];
172+
})
173+
),
174+
});
175+
} else {
176+
acc[key] = value;
177+
}
161178
}
162-
}
163179

164-
return acc;
165-
}, {})
180+
return acc;
181+
},
182+
{} as Record<string, string>
183+
)
166184
);
167185

168186
const url = new URL('https://snack.expo.dev');
@@ -209,7 +227,6 @@ export default function Pre({
209227
style={{
210228
width: '100%',
211229
height: 660,
212-
border: 'none',
213230
border: '1px solid var(--ifm-table-border-color)',
214231
borderRadius: 'var(--ifm-global-radius)',
215232
overflow: 'hidden',
@@ -263,7 +280,14 @@ export default function Pre({
263280
);
264281
}
265282

266-
function FocusedCodeBlock({ children, expanded, ...rest }) {
283+
function FocusedCodeBlock({
284+
children,
285+
expanded,
286+
...rest
287+
}: {
288+
children: React.ReactElement<{ children: string }>;
289+
expanded: boolean;
290+
}) {
267291
const child = React.Children.only(children);
268292
const code = child.props.children;
269293

@@ -274,7 +298,7 @@ function FocusedCodeBlock({ children, expanded, ...rest }) {
274298
if (expanded) {
275299
content = code
276300
.split('\n')
277-
.filter((line) =>
301+
.filter((line: string) =>
278302
[COMMENTS.FOCUS_START, COMMENTS.FOCUS_END].every(
279303
(comment) => line.trim() !== comment
280304
)
@@ -284,7 +308,7 @@ function FocusedCodeBlock({ children, expanded, ...rest }) {
284308
const lines = code.split('\n');
285309

286310
let focus = false;
287-
let indent;
311+
let indent: string | undefined;
288312

289313
for (const line of lines) {
290314
if (line.trim() === COMMENTS.FOCUS_START) {
@@ -293,10 +317,10 @@ function FocusedCodeBlock({ children, expanded, ...rest }) {
293317
focus = false;
294318
} else if (focus) {
295319
if (indent === undefined) {
296-
indent = line.match(/^\s*/)[0];
320+
indent = line.match(/^\s*/)?.[0];
297321
}
298322

299-
if (line.startsWith(indent)) {
323+
if (indent && line.startsWith(indent)) {
300324
content += line.slice(indent.length) + '\n';
301325
} else {
302326
content += line + '\n';
@@ -305,8 +329,12 @@ function FocusedCodeBlock({ children, expanded, ...rest }) {
305329
}
306330
}
307331

308-
children = React.Children.map(children, (c) =>
309-
React.cloneElement(c, { children: content })
332+
return (
333+
<MDXPre {...rest}>
334+
{React.Children.map(children, (c) =>
335+
React.cloneElement(c, { children: content })
336+
)}
337+
</MDXPre>
310338
);
311339
}
312340

0 commit comments

Comments
 (0)