diff --git a/website/.remarkrc.mjs b/website/.remarkrc.mjs index f019fea1116..d03910747d8 100644 --- a/website/.remarkrc.mjs +++ b/website/.remarkrc.mjs @@ -1,4 +1,4 @@ -import packageJson from "./package.json" assert { type: "json" }; +import packageJson from "./package.json" with { type: "json" }; export default { plugins: [ diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index 537bf29bc78..0faa296d589 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -21,7 +21,7 @@ export interface EditUrlButton { href: string; } -const commonDocsOptions = { +const commonDocsOptions: PluginContentDocs.Options = { breadcrumbs: false, showLastUpdateAuthor: false, showLastUpdateTime: true, diff --git a/website/src/pages/Home/Platforms/FoxFact.tsx b/website/src/pages/Home/Platforms/FoxFact.tsx index e62580a92d1..501c0607c31 100644 --- a/website/src/pages/Home/Platforms/FoxFact.tsx +++ b/website/src/pages/Home/Platforms/FoxFact.tsx @@ -7,7 +7,7 @@ import React from 'react'; -function FoxFact({className}) { +function FoxFact({className}: {className: string}) { return (
{children}
diff --git a/website/src/pages/Home/components/ThemeImage/index.tsx b/website/src/pages/Home/components/ThemeImage/index.tsx index 1b50f92d5af..e711b581cf9 100644 --- a/website/src/pages/Home/components/ThemeImage/index.tsx +++ b/website/src/pages/Home/components/ThemeImage/index.tsx @@ -7,7 +7,17 @@ import React, {useState, useEffect} from 'react'; -function ThemeImage({lightSrc, darkSrc, className, alt}) { +function ThemeImage({ + lightSrc, + darkSrc, + className, + alt, +}: { + lightSrc: string; + darkSrc: string; + className?: string; + alt: string; +}) { const [theme, setTheme] = useState('light'); useEffect(() => { diff --git a/website/src/pages/showcase.tsx b/website/src/pages/showcase.tsx index c7c102b5b25..f30b43f2894 100644 --- a/website/src/pages/showcase.tsx +++ b/website/src/pages/showcase.tsx @@ -13,7 +13,11 @@ import type users from '../../showcase.json'; import IconExternalLink from '../theme/Icon/ExternalLink'; import ThemedImage from '@theme/ThemedImage'; -const renderApp = (app, i) => ; +type UserAppType = (typeof users)[keyof typeof users][number]; + +const renderApp = (app: UserAppType, i: number) => ( + +); function Section({ children, @@ -24,7 +28,7 @@ function Section({ return
{children}
; } -const AppBox = ({app}) => { +const AppBox = ({app}: {app: UserAppType}) => { const imgSource = useBaseUrl( app.icon.startsWith('http') ? app.icon : 'img/showcase/' + app.icon ); @@ -40,7 +44,7 @@ const AppBox = ({app}) => {

{app.name}

{renderLinks(app)} - {app.infoLink && ( + {'infoTitle' in app && app.infoLink && ( { ); }; -const renderLinks = app => { +const renderLinks = (app: UserAppType) => { const links = [ app.linkAppStore ? ( @@ -67,12 +71,12 @@ const renderLinks = app => { Android ) : null, - app.linkDesktop ? ( + 'linkDesktop' in app && app.linkDesktop ? ( Desktop ) : null, - app.linkMetaQuest ? ( + 'linkMetaQuest' in app && app.linkMetaQuest ? ( Meta Quest diff --git a/website/src/theme/Badge/index.tsx b/website/src/theme/Badge/index.tsx index 6c88272a42e..7ac836d5414 100644 --- a/website/src/theme/Badge/index.tsx +++ b/website/src/theme/Badge/index.tsx @@ -8,7 +8,13 @@ import React from 'react'; import styles from './styles.module.css'; -export default function Badge({icon, title}) { +export default function Badge({ + icon, + title, +}: { + icon: React.ReactNode; + title: React.ReactNode; +}) { return (
{icon} diff --git a/website/src/theme/Blog/Components/Author/index.tsx b/website/src/theme/Blog/Components/Author/index.tsx index 8c550c24da2..7f64e9dcdea 100644 --- a/website/src/theme/Blog/Components/Author/index.tsx +++ b/website/src/theme/Blog/Components/Author/index.tsx @@ -1,24 +1,24 @@ -import React from 'react'; -import clsx from 'clsx'; -import Link from '@docusaurus/Link'; +import Link, {type Props as LinkProps} from '@docusaurus/Link'; +import type {Props} from '@theme/Blog/Components/Author'; import AuthorSocials from '@theme/Blog/Components/Author/Socials'; import Heading from '@theme/Heading'; +import clsx from 'clsx'; import styles from './styles.module.css'; -function MaybeLink(props) { +function MaybeLink(props: LinkProps) { if (props.href) { return ; } return <>{props.children}; } -function AuthorTitle({title}) { +function AuthorTitle({title}: {title: string}) { return ( {title} ); } -function AuthorName({name, as}) { +function AuthorName({name, as}: {name: string; as: Props['as']}) { if (!as) { return {name}; } else { @@ -29,17 +29,18 @@ function AuthorName({name, as}) { ); } } -function AuthorBlogPostCount({count}) { +function AuthorBlogPostCount({count}: {count: number}) { return {count}; } // Note: in the future we might want to have multiple "BlogAuthor" components // Creating different display modes with the "as" prop may not be the best idea // Explainer: https://kyleshevlin.com/prefer-multiple-compositions/ // For now, we almost use the same design for all cases, so it's good enough -export default function BlogAuthor({as, author, className, count}) { +export default function BlogAuthor({as, author, className, count}: Props) { const {name, title, url, imageURL, email, page} = author; const link = page?.permalink || url || (email && `mailto:${email}`) || undefined; + return (
)} - {count && } + {count !== undefined && }
{!!title && } {/* - We always render AuthorSocials even if there's none - This keeps other things aligned with flexbox layout - */} + We always render AuthorSocials even if there's none + This keeps other things aligned with flexbox layout + */}
)} diff --git a/website/src/theme/BlogSidebar/Mobile/index.tsx b/website/src/theme/BlogSidebar/Mobile/index.tsx index e14c9664e1f..d0e3986f036 100644 --- a/website/src/theme/BlogSidebar/Mobile/index.tsx +++ b/website/src/theme/BlogSidebar/Mobile/index.tsx @@ -39,7 +39,7 @@ function BlogSidebarMobileSecondaryMenu({sidebar}: Props) { ); } -export default function BlogSidebarMobile(props) { +export default function BlogSidebarMobile(props: Props) { return (
diff --git a/website/src/theme/DocItem/Footer/index.tsx b/website/src/theme/DocItem/Footer/index.tsx index c5a226154a4..4e00b381745 100644 --- a/website/src/theme/DocItem/Footer/index.tsx +++ b/website/src/theme/DocItem/Footer/index.tsx @@ -13,6 +13,7 @@ import TagsListInline, { import type {EditUrlButton} from '../../../../docusaurus.config'; import styles from './styles.module.css'; import DocsRating from '../../../../core/DocsRating'; +import type {Props} from '@theme/EditMetaRow'; function TagsRow(props: TagsListInlineProps) { return ( @@ -39,7 +40,7 @@ function EditPage({label, href}: {label: string; href: string}) { ); } -function EditMetaRow({editUrl, lastUpdatedAt, lastUpdatedBy}) { +function EditMetaRow({editUrl, lastUpdatedAt, lastUpdatedBy}: Props) { const buttons = React.useMemo((): EditUrlButton[] => { try { return JSON.parse(editUrl); @@ -87,6 +88,7 @@ export default function DocItemFooter() { editUrl={editUrl} lastUpdatedAt={lastUpdatedAt} lastUpdatedBy={lastUpdatedBy} + className="" /> )} diff --git a/website/src/theme/DocVersionBanner/index.tsx b/website/src/theme/DocVersionBanner/index.tsx index 3d649f195b7..d1a40f44480 100644 --- a/website/src/theme/DocVersionBanner/index.tsx +++ b/website/src/theme/DocVersionBanner/index.tsx @@ -1,9 +1,10 @@ -import React from 'react'; +import React, {ComponentType} from 'react'; import clsx from 'clsx'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import Link from '@docusaurus/Link'; import Translate from '@docusaurus/Translate'; import { + GlobalVersion, useActivePlugin, useDocVersionSuggestions, } from '@docusaurus/plugin-content-docs/client'; @@ -12,8 +13,21 @@ import { useDocsVersion, useDocsPreferredVersion, } from '@docusaurus/plugin-content-docs/client'; +import type {Props} from '@theme/DocVersionBanner'; +import type { + VersionBanner, + PropVersionMetadata, +} from '@docusaurus/plugin-content-docs'; -function UnreleasedVersionLabel({siteTitle, versionMetadata}) { +type BannerLabelComponentProps = { + siteTitle: string; + versionMetadata: PropVersionMetadata; +}; + +function UnreleasedVersionLabel({ + siteTitle, + versionMetadata, +}: BannerLabelComponentProps) { return ( {versionMetadata.label}, }}> { - 'This is documentation for {siteTitle} {versionLabel}, which is no longer in active development.' + 'This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.' } ); } -const BannerLabelComponents = { + +const BannerLabelComponents: { + [banner in VersionBanner]: ComponentType; +} = { unreleased: UnreleasedVersionLabel, unmaintained: UnmaintainedVersionLabel, }; -function BannerLabel(props) { +function BannerLabel(props: BannerLabelComponentProps) { const BannerLabelComponent = - BannerLabelComponents[props.versionMetadata.banner]; + BannerLabelComponents[props.versionMetadata.banner!]; return ; } -function LatestVersionSuggestionLabel({versionLabel, to, onClick}) { +function LatestVersionSuggestionLabel({ + versionLabel, + to, + onClick, +}: { + to: string; + onClick: () => void; + versionLabel: string; +}) { return ( - version.docs.find(doc => doc.id === version.mainDocId); + const {pluginId} = useActivePlugin({failfast: true})!; + + const getVersionMainDoc = (version: GlobalVersion) => + version.docs.find(doc => doc.id === version.mainDocId)!; + const {savePreferredVersionName} = useDocsPreferredVersion(pluginId); + const {latestDocSuggestion, latestVersionSuggestion} = useDocVersionSuggestions(pluginId); @@ -105,7 +141,9 @@ function DocVersionBannerEnabled({className, versionMetadata}) { 'alert alert--warning margin-bottom--md' )} role="alert"> - +
+ +
typeof el === 'string' && !el.includes('\n') ); diff --git a/website/src/theme/MDXComponents/InlineCode.tsx b/website/src/theme/MDXComponents/InlineCode.tsx index d2eec0bddab..ae137948231 100644 --- a/website/src/theme/MDXComponents/InlineCode.tsx +++ b/website/src/theme/MDXComponents/InlineCode.tsx @@ -1,11 +1,12 @@ import React from 'react'; import Link from '@docusaurus/Link'; +import type {Props} from '@theme/CodeInline'; // Note: this component is a custom React-Native-Website feature const MarkdownInlineCodePrefix = 'md '; -export default function InlineCode(props) { +export default function InlineCode(props: Props) { if ( typeof props.children === 'string' && props.children.startsWith(MarkdownInlineCodePrefix) @@ -25,23 +26,26 @@ export default function InlineCode(props) { // To enable Markdown support, use the "`md " prefix // Syntax example: `md ({nativeEvent: [PressEvent](pressevent)})` const MarkdownInlineCode = React.memo(function MarkdownInlineCodeInner( - props: React.PropsWithChildren + props: Props ) { - const children = linkify(props.children); + const children = + typeof props.children !== 'string' + ? props.children + : linkify(props.children); return ; }); // Gives the ability to use basic Markdown links inside inline code blocks // We use RegExp because a full Markdown parser would be quite heavy // See https://github.com/facebook/react-native-website/pull/3807 -function linkify(input) { +function linkify(input: string): React.ReactNode { // Inspired by https://github.com/gakimball/transform-markdown-links // Thank you: http://stackoverflow.com/a/32382702 (with some modifications) const linkRegExp = /(?\[(?[^\]]+)?\]\((?[^)]+)\))/g; const linkSplitRegExp = /\[[^\]]+?\]\([^)]+\)/g; const links = []; - let match; + let match: RegExpExecArray | null; while ((match = linkRegExp.exec(input)) !== null) { const link = match.groups.link; const text = match.groups.text; diff --git a/website/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx b/website/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx index 868b8bd7ef0..f00eed3f913 100644 --- a/website/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx +++ b/website/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx @@ -9,7 +9,9 @@ import React from 'react'; import DocsVersionDropdownNavbarItem from '@theme-original/NavbarItem/DocsVersionDropdownNavbarItem'; import {useActiveDocContext} from '@docusaurus/plugin-content-docs/client'; -export default function DocsVersionDropdownNavbarItemWrapper(props) { +export default function DocsVersionDropdownNavbarItemWrapper(props: { + docsPluginId: string; +}) { // (CUSTOM) Hide version dropdown on non-versioned pages const activeDocContext = useActiveDocContext(props.docsPluginId); if (!activeDocContext.activeDoc) { diff --git a/website/src/theme/PlatformSupport/index.tsx b/website/src/theme/PlatformSupport/index.tsx index 6dc398a0889..45e7648e07a 100644 --- a/website/src/theme/PlatformSupport/index.tsx +++ b/website/src/theme/PlatformSupport/index.tsx @@ -16,7 +16,11 @@ import Windows from '@site/src/theme/Icon/Windows'; import TV from '@site/src/theme/Icon/TV'; import Web from '@site/src/theme/Icon/Web'; -export default function PlatformSupport({platforms}) { +export default function PlatformSupport({ + platforms, +}: { + platforms: Array; +}) { return (
Platform support