diff --git a/packages/docusaurus-plugin-content-blog/index.d.ts b/packages/docusaurus-plugin-content-blog/index.d.ts index 23174ea608..a41db5f3af 100644 --- a/packages/docusaurus-plugin-content-blog/index.d.ts +++ b/packages/docusaurus-plugin-content-blog/index.d.ts @@ -44,7 +44,7 @@ declare module '@theme/BlogPostPage' { export type Content = { readonly frontMatter: FrontMatter; readonly metadata: Metadata; - readonly rightToc: MarkdownRightTableOfContents; + readonly rightToc: readonly MarkdownRightTableOfContents[]; (): JSX.Element; }; @@ -64,17 +64,19 @@ declare module '@theme/BlogListPage' { readonly content: () => JSX.Element; }; + export type Metadata = { + readonly blogDescription: string; + readonly nextPage?: string; + readonly page: number; + readonly permalink: string; + readonly postsPerPage: number; + readonly previousPage?: string; + readonly totalCount: number; + readonly totalPages: number; + }; + export type Props = { - readonly metadata: { - readonly blogDescription: string; - readonly nextPage?: string; - readonly page: number; - readonly permalink: string; - readonly postsPerPage: number; - readonly previousPage?: string; - readonly totalCount: number; - readonly totalPages: number; - }; + readonly metadata: Metadata; readonly items: readonly {readonly content: Content}[]; }; diff --git a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts index 90a801977a..9cfb7eb16d 100644 --- a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts +++ b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts @@ -66,6 +66,8 @@ declare module '@theme/DocItem' { readonly lastUpdatedAt?: number; readonly lastUpdatedBy?: string; readonly version?: string; + readonly previous?: {readonly permalink: string; readonly title: string}; + readonly next?: {readonly permalink: string; readonly title: string}; }; export type Props = { @@ -73,7 +75,7 @@ declare module '@theme/DocItem' { readonly content: { readonly frontMatter: FrontMatter; readonly metadata: Metadata; - readonly rightToc: MarkdownRightTableOfContents; + readonly rightToc: readonly MarkdownRightTableOfContents[]; (): JSX.Element; }; }; diff --git a/packages/docusaurus-theme-classic/package.json b/packages/docusaurus-theme-classic/package.json index 4cf5ecd08d..4a0f5fe168 100644 --- a/packages/docusaurus-theme-classic/package.json +++ b/packages/docusaurus-theme-classic/package.json @@ -3,6 +3,7 @@ "version": "2.0.0-alpha.61", "description": "Classic theme for Docusaurus", "main": "src/index.js", + "types": "src/types.d.ts", "publishConfig": { "access": "public" }, @@ -10,13 +11,14 @@ "scripts": { "build": "tsc --noEmit && yarn babel && yarn prettier", "watch": "yarn babel --watch", - "babel": "babel src -d lib --extensions \".tsx,.ts\" --copy-files", + "babel": "babel src -d lib --extensions \".tsx,.ts\" --ignore \"**/*.d.ts\" --copy-files", "prettier": "prettier --config ../../.prettierrc --write \"**/*.{js,ts}\"" }, "dependencies": { "@hapi/joi": "^17.1.1", "@mdx-js/mdx": "^1.5.8", "@mdx-js/react": "^1.5.8", + "@types/react-toggle": "^4.0.2", "clsx": "^1.1.1", "copy-text-to-clipboard": "^2.2.0", "infima": "0.2.0-alpha.12", diff --git a/packages/docusaurus-theme-classic/src/theme/BlogListPaginator/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogListPaginator/index.tsx index 8593728803..9ec1ca93f1 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogListPaginator/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogListPaginator/index.tsx @@ -7,8 +7,9 @@ import React from 'react'; import Link from '@docusaurus/Link'; +import type {Metadata} from '@theme/BlogListPage'; -function BlogListPaginator(props): JSX.Element { +function BlogListPaginator(props: {readonly metadata: Metadata}): JSX.Element { const {metadata} = props; const {previousPage, nextPage} = metadata; diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/index.tsx index a3efc4ee90..a0706b281a 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/index.tsx @@ -12,7 +12,7 @@ import {MDXProvider} from '@mdx-js/react'; import Head from '@docusaurus/Head'; import Link from '@docusaurus/Link'; import MDXComponents from '@theme/MDXComponents'; -import type {FrontMatter, Metadata} from '@theme/BlogPostPage'; +import type {Props} from '@theme/BlogPostItem'; import useBaseUrl from '@docusaurus/useBaseUrl'; import styles from './styles.module.css'; @@ -32,14 +32,6 @@ const MONTHS = [ 'December', ]; -type Props = { - readonly frontMatter: FrontMatter; - readonly metadata: Metadata; - readonly truncated?: boolean; - readonly isBlogPostPage?: boolean; - readonly children: JSX.Element; -}; - function BlogPostItem(props: Props): JSX.Element { const { children, diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostPaginator/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostPaginator/index.tsx index 0ad300348a..2d4741bd94 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostPaginator/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostPaginator/index.tsx @@ -7,8 +7,9 @@ import React from 'react'; import Link from '@docusaurus/Link'; +import type {Props} from '@theme/BlogPostPaginator'; -function BlogPostPaginator(props): JSX.Element { +function BlogPostPaginator(props: Props): JSX.Element { const {nextItem, prevItem} = props; return ( diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx b/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx index df897c5522..458dd2c1d0 100644 --- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx @@ -14,6 +14,7 @@ import copy from 'copy-text-to-clipboard'; import rangeParser from 'parse-numeric-range'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import usePrismTheme from '@theme/hooks/usePrismTheme'; +import type {Props} from '@theme/CodeBlock'; import styles from './styles.module.css'; @@ -91,11 +92,7 @@ export default ({ children, className: languageClassName, metastring, -}: { - children: string; - className: string; - metastring: string; -}): JSX.Element => { +}: Props): JSX.Element => { const { siteConfig: { themeConfig: {prism = {}}, diff --git a/packages/docusaurus-theme-classic/src/theme/DocPaginator/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocPaginator/index.tsx index 3d0f917f8f..a9d10027b5 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocPaginator/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/DocPaginator/index.tsx @@ -7,12 +7,7 @@ import React from 'react'; import Link from '@docusaurus/Link'; - -type PageInfo = {permalink: string; title: string}; - -type Props = { - metadata: {previous: PageInfo; next: PageInfo}; -}; +import type {Props} from '@theme/DocPaginator'; function DocPaginator(props: Props): JSX.Element { const {metadata} = props; diff --git a/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.tsx index 3ed8678b98..e1f4e42d07 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.tsx @@ -15,6 +15,7 @@ import useLogo from '@theme/hooks/useLogo'; import useScrollPosition from '@theme/hooks/useScrollPosition'; import Link from '@docusaurus/Link'; import isInternalUrl from '@docusaurus/isInternalUrl'; +import type {Props} from '@theme/DocSidebar'; import styles from './styles.module.css'; @@ -167,7 +168,7 @@ function DocSidebar({ path, sidebar, sidebarCollapsible = true, -}): JSX.Element | null { +}: Props): JSX.Element | null { const [showResponsiveSidebar, setShowResponsiveSidebar] = useState(false); const { siteConfig: { @@ -195,7 +196,7 @@ function DocSidebar({ })}> {hideOnScroll && ( diff --git a/packages/docusaurus-theme-classic/src/theme/Heading/index.tsx b/packages/docusaurus-theme-classic/src/theme/Heading/index.tsx index 1e114dfd90..8724028afa 100644 --- a/packages/docusaurus-theme-classic/src/theme/Heading/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Heading/index.tsx @@ -7,14 +7,15 @@ /* eslint-disable jsx-a11y/anchor-has-content, jsx-a11y/anchor-is-valid */ -import React, {ComponentType} from 'react'; +import React from 'react'; import clsx from 'clsx'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import type {HeadingType, Props} from '@theme/Heading'; import './styles.css'; import styles from './styles.module.css'; -const Heading = (Tag: ComponentType): ((props) => JSX.Element) => +const Heading = (Tag: HeadingType): ((props: Props) => JSX.Element) => function TargetComponent({id, ...props}) { const { siteConfig: { diff --git a/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx b/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx index d36de4c083..53e6cf4e72 100644 --- a/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Layout/index.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React, {ReactNode} from 'react'; +import React from 'react'; import Head from '@docusaurus/Head'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import useBaseUrl from '@docusaurus/useBaseUrl'; @@ -15,6 +15,7 @@ import UserPreferencesProvider from '@theme/UserPreferencesProvider'; import AnnouncementBar from '@theme/AnnouncementBar'; import Navbar from '@theme/Navbar'; import Footer from '@theme/Footer'; +import type {Props} from '@theme/Layout'; import './styles.css'; @@ -26,17 +27,6 @@ function Providers({children}) { ); } -type Props = { - children: ReactNode; - title?: string; - noFooter?: boolean; - description?: string; - image?: string; - keywords?: string[]; - permalink?: string; - version?: string; -}; - function Layout(props: Props): JSX.Element { const {siteConfig = {}} = useDocusaurusContext(); const { diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx index d643ad648f..0feff446fe 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/index.tsx @@ -5,15 +5,16 @@ * LICENSE file in the root directory of this source tree. */ -import React, {ComponentProps} from 'react'; +import React from 'react'; import Link from '@docusaurus/Link'; import CodeBlock from '@theme/CodeBlock'; import Heading from '@theme/Heading'; +import type {MDXComponentsObject} from '@theme/MDXComponents'; import styles from './styles.module.css'; -export default { - code: (props: ComponentProps): JSX.Element => { +const MDXComponents: MDXComponentsObject = { + code: (props) => { const {children} = props; if (typeof children === 'string') { if (!children.includes('\n')) { @@ -23,12 +24,8 @@ export default { } return children; }, - a: (props: ComponentProps<'a'>): JSX.Element => { - return ; - }, - pre: (props: ComponentProps<'div'>): JSX.Element => ( -
- ), + a: (props) => , + pre: (props) =>
, h1: Heading('h1'), h2: Heading('h2'), h3: Heading('h3'), @@ -36,3 +33,5 @@ export default { h5: Heading('h5'), h6: Heading('h6'), }; + +export default MDXComponents; diff --git a/packages/docusaurus-theme-classic/src/theme/TOC/index.tsx b/packages/docusaurus-theme-classic/src/theme/TOC/index.tsx index ce1483d1fd..d7b98d85b8 100644 --- a/packages/docusaurus-theme-classic/src/theme/TOC/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/TOC/index.tsx @@ -8,15 +8,13 @@ import React from 'react'; import useTOCHighlight from '@theme/hooks/useTOCHighlight'; -import type {MarkdownRightTableOfContents} from '@docusaurus/types'; +import type {TOCProps} from '@theme/TOC'; import styles from './styles.module.css'; const LINK_CLASS_NAME = 'table-of-contents__link'; const ACTIVE_LINK_CLASS_NAME = 'table-of-contents__link--active'; const TOP_OFFSET = 100; -type TOCProps = {readonly headings: MarkdownRightTableOfContents[]}; - /* eslint-disable jsx-a11y/control-has-associated-label */ function Headings({headings, isChild}: TOCProps & {isChild?: boolean}) { if (!headings.length) { diff --git a/packages/docusaurus-theme-classic/src/theme/TabItem/index.tsx b/packages/docusaurus-theme-classic/src/theme/TabItem/index.tsx index 6b1309d864..99559b36e6 100644 --- a/packages/docusaurus-theme-classic/src/theme/TabItem/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/TabItem/index.tsx @@ -5,9 +5,10 @@ * LICENSE file in the root directory of this source tree. */ -import React, {ReactNode} from 'react'; +import React from 'react'; +import type {Props} from '@theme/TabItem'; -function TabItem(props: {readonly children: ReactNode}): JSX.Element { +function TabItem(props: Props): JSX.Element { return
{props.children}
; } diff --git a/packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx b/packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx index 19933ce069..4c454b422a 100644 --- a/packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Tabs/index.tsx @@ -7,6 +7,7 @@ import React, {useState, Children, ReactElement, useEffect} from 'react'; import useUserPreferencesContext from '@theme/hooks/useUserPreferencesContext'; +import type {Props} from '@theme/Tabs'; import clsx from 'clsx'; @@ -18,14 +19,6 @@ const keys = { tab: 9, }; -type Props = { - block?: boolean; - children: ReactElement<{value: string}>[]; - defaultValue?: string; - values: {value: string; label: string}[]; - groupId?: string; -}; - function Tabs(props: Props): JSX.Element { const {block, children, defaultValue, values, groupId} = props; const {tabGroupChoices, setTabGroupChoices} = useUserPreferencesContext(); diff --git a/packages/docusaurus-theme-classic/src/theme/ThemeContext.ts b/packages/docusaurus-theme-classic/src/theme/ThemeContext.ts index ad265a49e4..f5e0f05bc1 100644 --- a/packages/docusaurus-theme-classic/src/theme/ThemeContext.ts +++ b/packages/docusaurus-theme-classic/src/theme/ThemeContext.ts @@ -6,7 +6,10 @@ */ import React from 'react'; +import type {ThemeContextProps} from '@theme/hooks/useThemeContext'; -const ThemeContext = React.createContext(undefined); +const ThemeContext = React.createContext( + undefined, +); export default ThemeContext; diff --git a/packages/docusaurus-theme-classic/src/theme/ThemeProvider/index.tsx b/packages/docusaurus-theme-classic/src/theme/ThemeProvider/index.tsx index be26e0d165..d586ae926a 100644 --- a/packages/docusaurus-theme-classic/src/theme/ThemeProvider/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/ThemeProvider/index.tsx @@ -5,12 +5,13 @@ * LICENSE file in the root directory of this source tree. */ -import React, {ReactNode} from 'react'; +import React from 'react'; import useTheme from '@theme/hooks/useTheme'; import ThemeContext from '@theme/ThemeContext'; +import type {Props} from '@theme/ThemeProvider'; -function ThemeProvider(props: {readonly children: ReactNode}): JSX.Element { +function ThemeProvider(props: Props): JSX.Element { const {isDarkTheme, setLightTheme, setDarkTheme} = useTheme(); return ( diff --git a/packages/docusaurus-theme-classic/src/theme/UserPreferencesProvider/index.tsx b/packages/docusaurus-theme-classic/src/theme/UserPreferencesProvider/index.tsx index 12b34b1a55..bccc11978f 100644 --- a/packages/docusaurus-theme-classic/src/theme/UserPreferencesProvider/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/UserPreferencesProvider/index.tsx @@ -5,13 +5,14 @@ * LICENSE file in the root directory of this source tree. */ -import React, {ReactNode} from 'react'; +import React from 'react'; import useTabGroupChoice from '@theme/hooks/useTabGroupChoice'; import useAnnouncementBar from '@theme/hooks/useAnnouncementBar'; import UserPreferencesContext from '@theme/UserPreferencesContext'; +import type {Props} from '@theme/UserPreferencesProvider'; -function UserPreferencesProvider(props: {children: ReactNode}): JSX.Element { +function UserPreferencesProvider(props: Props): JSX.Element { const {tabGroupChoices, setTabGroupChoices} = useTabGroupChoice(); const {isAnnouncementBarClosed, closeAnnouncementBar} = useAnnouncementBar(); diff --git a/packages/docusaurus-theme-classic/src/theme/hooks/useAnnouncementBar.ts b/packages/docusaurus-theme-classic/src/theme/hooks/useAnnouncementBar.ts index 8963b581e3..de96b1fc01 100644 --- a/packages/docusaurus-theme-classic/src/theme/hooks/useAnnouncementBar.ts +++ b/packages/docusaurus-theme-classic/src/theme/hooks/useAnnouncementBar.ts @@ -7,14 +7,12 @@ import {useState, useEffect, useCallback} from 'react'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import type {useAnnouncementBarReturns} from '@theme/hooks/useAnnoucementBar'; const STORAGE_DISMISS_KEY = 'docusaurus.announcement.dismiss'; const STORAGE_ID_KEY = 'docusaurus.announcement.id'; -const useAnnouncementBar = (): { - isAnnouncementBarClosed: boolean; - closeAnnouncementBar: () => void; -} => { +const useAnnouncementBar = (): useAnnouncementBarReturns => { const {announcementBar} = useDocusaurusContext().siteConfig.themeConfig; const [isClosed, setClosed] = useState(true); diff --git a/packages/docusaurus-theme-classic/src/theme/hooks/useHideableNavbar.ts b/packages/docusaurus-theme-classic/src/theme/hooks/useHideableNavbar.ts index b954aa1cf2..f250ce90a4 100644 --- a/packages/docusaurus-theme-classic/src/theme/hooks/useHideableNavbar.ts +++ b/packages/docusaurus-theme-classic/src/theme/hooks/useHideableNavbar.ts @@ -9,13 +9,14 @@ import {useState, useCallback, useEffect} from 'react'; import {useLocation} from '@docusaurus/router'; import useLocationHash from '@theme/hooks/useLocationHash'; import useScrollPosition from '@theme/hooks/useScrollPosition'; +import type {useHideableNavbarReturns} from '@theme/hooks/useHideableNavbar'; -const useHideableNavbar = (hideOnScroll: boolean) => { +const useHideableNavbar = (hideOnScroll: boolean): useHideableNavbarReturns => { const [isNavbarVisible, setIsNavbarVisible] = useState(true); const [isFocusedAnchor, setIsFocusedAnchor] = useState(false); const [lastScrollTop, setLastScrollTop] = useState(0); const [navbarHeight, setNavbarHeight] = useState(0); - const navbarRef = useCallback((node) => { + const navbarRef = useCallback((node: HTMLElement | null) => { if (node !== null) { setNavbarHeight(node.getBoundingClientRect().height); } diff --git a/packages/docusaurus-theme-classic/src/theme/hooks/useLocationHash.ts b/packages/docusaurus-theme-classic/src/theme/hooks/useLocationHash.ts index 0b4d75a342..eb2edff64f 100644 --- a/packages/docusaurus-theme-classic/src/theme/hooks/useLocationHash.ts +++ b/packages/docusaurus-theme-classic/src/theme/hooks/useLocationHash.ts @@ -5,11 +5,10 @@ * LICENSE file in the root directory of this source tree. */ -import {useState, useEffect, Dispatch, SetStateAction} from 'react'; +import {useState, useEffect} from 'react'; +import type {useLocationHashReturns} from '@theme/hooks/useLocationHash'; -function useLocationHash( - initialHash: string, -): [string, Dispatch>] { +function useLocationHash(initialHash: string): useLocationHashReturns { const [hash, setHash] = useState(initialHash); useEffect(() => { diff --git a/packages/docusaurus-theme-classic/src/theme/hooks/useLogo.ts b/packages/docusaurus-theme-classic/src/theme/hooks/useLogo.ts index 4631f8aec3..198a33a3f7 100644 --- a/packages/docusaurus-theme-classic/src/theme/hooks/useLogo.ts +++ b/packages/docusaurus-theme-classic/src/theme/hooks/useLogo.ts @@ -9,15 +9,9 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import useThemeContext from '@theme/hooks/useThemeContext'; import useBaseUrl from '@docusaurus/useBaseUrl'; import isInternalUrl from '@docusaurus/isInternalUrl'; +import type {LogoLinkProps, useLogoReturns} from '@theme/hooks/useLogo'; -type LogoLinkProps = {target?: string; rel?: string}; - -const useLogo = (): { - logoLink: string; - logoLinkProps: LogoLinkProps; - logoImageUrl: string; - logoAlt: string; -} => { +const useLogo = (): useLogoReturns => { const { siteConfig: {themeConfig: {navbar: {logo = {}} = {}} = {}} = {}, } = useDocusaurusContext(); diff --git a/packages/docusaurus-theme-classic/src/theme/hooks/useScrollPosition.ts b/packages/docusaurus-theme-classic/src/theme/hooks/useScrollPosition.ts index 81c352c149..e56fc85539 100644 --- a/packages/docusaurus-theme-classic/src/theme/hooks/useScrollPosition.ts +++ b/packages/docusaurus-theme-classic/src/theme/hooks/useScrollPosition.ts @@ -7,8 +7,7 @@ import {useState, useEffect} from 'react'; import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; - -type ScrollPosition = {scrollX: number; scrollY: number}; +import type {ScrollPosition} from '@theme/hooks/useScrollPosition'; const getScrollPosition = (): ScrollPosition => ({ scrollX: ExecutionEnvironment.canUseDOM ? window.pageXOffset : 0, @@ -16,7 +15,7 @@ const getScrollPosition = (): ScrollPosition => ({ }); const useScrollPosition = ( - effect: (position: ScrollPosition) => void, + effect?: (position: ScrollPosition) => void, deps = [], ): ScrollPosition => { const [scrollPosition, setScrollPosition] = useState(getScrollPosition()); diff --git a/packages/docusaurus-theme-classic/src/theme/hooks/useTabGroupChoice.ts b/packages/docusaurus-theme-classic/src/theme/hooks/useTabGroupChoice.ts index 3c7bac9f13..511f415419 100644 --- a/packages/docusaurus-theme-classic/src/theme/hooks/useTabGroupChoice.ts +++ b/packages/docusaurus-theme-classic/src/theme/hooks/useTabGroupChoice.ts @@ -6,13 +6,11 @@ */ import {useState, useCallback, useEffect} from 'react'; +import type {useTabGroupChoiceReturns} from '@theme/hooks/useTabGroupChoice'; const TAB_CHOICE_PREFIX = 'docusaurus.tab.'; -const useTabGroupChoice = (): { - tabGroupChoices: {readonly [groupId: string]: string}; - setTabGroupChoices: (groupId: string, newChoice: string) => void; -} => { +const useTabGroupChoice = (): useTabGroupChoiceReturns => { const [tabGroupChoices, setChoices] = useState<{ readonly [groupId: string]: string; }>({}); diff --git a/packages/docusaurus-theme-classic/src/theme/hooks/useTheme.ts b/packages/docusaurus-theme-classic/src/theme/hooks/useTheme.ts index bbb45bfe9a..24d3c770cd 100644 --- a/packages/docusaurus-theme-classic/src/theme/hooks/useTheme.ts +++ b/packages/docusaurus-theme-classic/src/theme/hooks/useTheme.ts @@ -9,6 +9,7 @@ import {useState, useCallback, useEffect} from 'react'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; +import type {useThemeReturns} from '@theme/hooks/useTheme'; const themes = { light: 'light', @@ -35,11 +36,7 @@ const storeTheme = (newTheme) => { } }; -const useTheme = (): { - isDarkTheme: boolean; - setLightTheme: () => void; - setDarkTheme: () => void; -} => { +const useTheme = (): useThemeReturns => { const { siteConfig: { themeConfig: {colorMode: {disableSwitch = false} = {}} = {}, diff --git a/packages/docusaurus-theme-classic/src/theme/hooks/useThemeContext.ts b/packages/docusaurus-theme-classic/src/theme/hooks/useThemeContext.ts index 889005be2d..f0e5a39169 100644 --- a/packages/docusaurus-theme-classic/src/theme/hooks/useThemeContext.ts +++ b/packages/docusaurus-theme-classic/src/theme/hooks/useThemeContext.ts @@ -8,15 +8,10 @@ import {useContext} from 'react'; import ThemeContext from '@theme/ThemeContext'; - -type ThemeContextProps = { - isDarkTheme: boolean; - setLightTheme: () => void; - setDarkTheme: () => void; -}; +import type {ThemeContextProps} from '@theme/hooks/useThemeContext'; function useThemeContext(): ThemeContextProps { - const context = useContext(ThemeContext); + const context = useContext(ThemeContext); if (context == null) { throw new Error( '`useThemeContext` is used outside of `Layout` Component. See https://v2.docusaurus.io/docs/theme-classic#usethemecontext.', diff --git a/packages/docusaurus-theme-classic/src/theme/hooks/useUserPreferencesContext.ts b/packages/docusaurus-theme-classic/src/theme/hooks/useUserPreferencesContext.ts index 6dd221c078..18ac644501 100644 --- a/packages/docusaurus-theme-classic/src/theme/hooks/useUserPreferencesContext.ts +++ b/packages/docusaurus-theme-classic/src/theme/hooks/useUserPreferencesContext.ts @@ -8,16 +8,10 @@ import {useContext} from 'react'; import UserPreferencesContext from '@theme/UserPreferencesContext'; - -type UserPreferencesContextProps = { - tabGroupChoices: {readonly [groupId: string]: string}; - setTabGroupChoices: (groupId: string, newChoice: string) => void; - isAnnouncementBarClosed: boolean; - closeAnnouncementBar: () => void; -}; +import type {UserPreferencesContextProps} from '@theme/hooks/useUserPreferencesContext'; function useUserPreferencesContext(): UserPreferencesContextProps { - const context = useContext( + const context = useContext( UserPreferencesContext, ); if (context == null) { diff --git a/packages/docusaurus-theme-classic/src/theme/hooks/useWindowSize.ts b/packages/docusaurus-theme-classic/src/theme/hooks/useWindowSize.ts index 7ec2e32818..a07eeea7c0 100644 --- a/packages/docusaurus-theme-classic/src/theme/hooks/useWindowSize.ts +++ b/packages/docusaurus-theme-classic/src/theme/hooks/useWindowSize.ts @@ -7,6 +7,8 @@ import {useEffect, useState} from 'react'; +import type {WindowSize} from '@theme/hooks/useWindowSize'; + const desktopThresholdWidth = 996; const windowSizes = { @@ -14,8 +16,6 @@ const windowSizes = { mobile: 'mobile', } as const; -type WindowSize = keyof typeof windowSizes; - function useWindowSize(): WindowSize | undefined { const isClient = typeof window !== 'undefined'; diff --git a/packages/docusaurus-theme-classic/src/types.d.ts b/packages/docusaurus-theme-classic/src/types.d.ts index b08a3df20e..9f57acf2f0 100644 --- a/packages/docusaurus-theme-classic/src/types.d.ts +++ b/packages/docusaurus-theme-classic/src/types.d.ts @@ -5,7 +5,359 @@ * LICENSE file in the root directory of this source tree. */ +/* eslint-disable import/no-duplicates */ /* eslint-disable spaced-comment */ /// /// /// + +declare module '@theme/AnnouncementBar' { + const AnnouncementBar: () => JSX.Element | null; + export default AnnouncementBar; +} + +declare module '@theme/BlogListPaginator' { + import type {Metadata} from '@theme/BlogListPage'; + + export type Props = {readonly metadata: Metadata}; + + const BlogListPaginator: (props: Props) => JSX.Element; + export default BlogListPaginator; +} + +declare module '@theme/BlogPostItem' { + import type {FrontMatter, Metadata} from '@theme/BlogPostPage'; + + export type Props = { + readonly frontMatter: FrontMatter; + readonly metadata: Metadata; + readonly truncated?: string | boolean; + readonly isBlogPostPage?: boolean; + readonly children: JSX.Element; + }; + + const BlogPostItem: (props: Props) => JSX.Element; + export default BlogPostItem; +} + +declare module '@theme/BlogPostPaginator' { + type Item = {readonly title: string; readonly permalink: string}; + + export type Props = {readonly nextItem?: Item; readonly prevItem?: Item}; + + const BlogPostPaginator: (props: Props) => JSX.Element; + export default BlogPostPaginator; +} + +declare module '@theme/CodeBlock' { + export type Props = { + readonly children: string; + readonly className?: string; + readonly metastring?: string; + }; + + const CodeBlock: (props: Props) => JSX.Element; + export default CodeBlock; +} + +declare module '@theme/DocPaginator' { + type PageInfo = {readonly permalink: string; readonly title: string}; + + export type Props = { + readonly metadata: {readonly previous?: PageInfo; readonly next?: PageInfo}; + }; + + const DocPaginator: (props: Props) => JSX.Element; + export default DocPaginator; +} + +declare module '@theme/DocSidebar' { + import type {PropSidebarItem} from '@docusaurus/plugin-content-docs-types'; + + export type Props = { + readonly path: string; + readonly sidebar: readonly PropSidebarItem[]; + readonly sidebarCollapsible?: boolean; + }; + + const DocSidebar: (props: Props) => JSX.Element; + export default DocSidebar; +} + +declare module '@theme/DocVersionSuggestions' { + const DocVersionSuggestions: () => JSX.Element; + export default DocVersionSuggestions; +} + +declare module '@theme/Footer' { + const Footer: () => JSX.Element | null; + export default Footer; +} + +declare module '@theme/Heading' { + import type {ComponentProps} from 'react'; + + export type HeadingType = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; + export type Props = ComponentProps; + + const Heading: (Tag: HeadingType) => (props: Props) => JSX.Element; + export default Heading; +} + +declare module '@theme/hooks/useAnnoucementBar' { + export type useAnnouncementBarReturns = { + readonly isAnnouncementBarClosed: boolean; + readonly closeAnnouncementBar: () => void; + }; + + const useAnnouncementBar: () => useAnnouncementBarReturns; + export default useAnnouncementBar; +} + +declare module '@theme/hooks/useHideableNavbar' { + export type useHideableNavbarReturns = { + readonly navbarRef: (node: HTMLElement | null) => void; + readonly isNavbarVisible: boolean; + }; + + const useHideableNavbar: (hideOnScroll: boolean) => useHideableNavbarReturns; + export default useHideableNavbar; +} + +declare module '@theme/hooks/useLocationHash' { + import type {Dispatch, SetStateAction} from 'react'; + + export type useLocationHashReturns = readonly [ + string, + Dispatch>, + ]; + + const useLocationHash: (initialHash: string) => useLocationHashReturns; + export default useLocationHash; +} + +declare module '@theme/hooks/useLockBodyScroll' { + const useLockBodyScroll: (lock?: boolean) => void; + export default useLockBodyScroll; +} + +declare module '@theme/hooks/useLogo' { + export type LogoLinkProps = {target?: string; rel?: string}; + + export type useLogoReturns = { + readonly logoLink: string; + readonly logoLinkProps: LogoLinkProps; + readonly logoImageUrl: string; + readonly logoAlt: string; + }; + + const useLogo: () => useLogoReturns; + export default useLogo; +} + +declare module '@theme/hooks/usePrismTheme' { + import defaultTheme from 'prism-react-renderer/themes/palenight'; + + const usePrismTheme: () => typeof defaultTheme; + export default usePrismTheme; +} + +declare module '@theme/hooks/useScrollPosition' { + export type ScrollPosition = {scrollX: number; scrollY: number}; + + const useScrollPosition: ( + effect?: (position: ScrollPosition) => void, + deps?: unknown[], + ) => ScrollPosition; + export default useScrollPosition; +} + +declare module '@theme/hooks/useTabGroupChoice' { + export type useTabGroupChoiceReturns = { + readonly tabGroupChoices: {readonly [groupId: string]: string}; + readonly setTabGroupChoices: (groupId: string, newChoice: string) => void; + }; + + const useTabGroupChoice: () => useTabGroupChoiceReturns; + export default useTabGroupChoice; +} + +declare module '@theme/hooks/useTheme' { + export type useThemeReturns = { + readonly isDarkTheme: boolean; + readonly setLightTheme: () => void; + readonly setDarkTheme: () => void; + }; + + const useTheme: () => useThemeReturns; + export default useTheme; +} + +declare module '@theme/hooks/useThemeContext' { + export type ThemeContextProps = { + isDarkTheme: boolean; + setLightTheme: () => void; + setDarkTheme: () => void; + }; + + export default function useThemeContext(): ThemeContextProps; +} + +declare module '@theme/hooks/useTOCHighlight' { + export default function useTOCHighlight( + linkClassName: string, + linkActiveClassName: string, + topOffset: number, + ): void; +} + +declare module '@theme/hooks/useUserPreferencesContext' { + export type UserPreferencesContextProps = { + tabGroupChoices: {readonly [groupId: string]: string}; + setTabGroupChoices: (groupId: string, newChoice: string) => void; + isAnnouncementBarClosed: boolean; + closeAnnouncementBar: () => void; + }; + + export default function useUserPreferencesContext(): UserPreferencesContextProps; +} + +declare module '@theme/hooks/useWindowSize' { + export const windowSizes: { + desktop: 'desktop'; + mobile: 'mobile'; + }; + + export type WindowSize = keyof typeof windowSizes; + + export default function useWindowSize(): WindowSize | undefined; +} + +declare module '@theme/Layout' { + import type {ReactNode} from 'react'; + + export type Props = { + children: ReactNode; + title?: string; + noFooter?: boolean; + description?: string; + image?: string; + keywords?: string[]; + permalink?: string; + version?: string; + }; + + const Layout: (props: Props) => JSX.Element; + export default Layout; +} + +declare module '@theme/MDXComponents' { + import {ComponentProps} from 'react'; + import CodeBlock from '@theme/CodeBlock'; + + export type MDXComponentsObject = { + readonly code: typeof CodeBlock; + readonly a: (props: ComponentProps<'a'>) => JSX.Element; + readonly pre: (props: ComponentProps<'div'>) => JSX.Element; + readonly h1: (props: ComponentProps<'h1'>) => JSX.Element; + readonly h2: (props: ComponentProps<'h2'>) => JSX.Element; + readonly h3: (props: ComponentProps<'h3'>) => JSX.Element; + readonly h4: (props: ComponentProps<'h4'>) => JSX.Element; + readonly h5: (props: ComponentProps<'h5'>) => JSX.Element; + readonly h6: (props: ComponentProps<'h6'>) => JSX.Element; + }; + + const MDXComponents: MDXComponentsObject; + export default MDXComponents; +} + +// TODO @theme/MDXPage + +declare module '@theme/Navbar' { + const Navbar: () => JSX.Element; + export default Navbar; +} + +// TODO @theme/NavbarItem/DefaultNavbarItem +// TODO @theme/NavbarItem/DocsVersionDropdownNavbarItem +// TODO @theme/NavbarItem/DocsVersionNavbarItem +// TODO @theme/NavbarItem + +declare module '@theme/TabItem' { + import type {ReactNode} from 'react'; + + export type Props = {readonly children: ReactNode}; + + const TabItem: () => JSX.Element; + export default TabItem; +} + +declare module '@theme/Tabs' { + import type {ReactElement} from 'react'; + + export type Props = { + readonly block?: boolean; + readonly children: readonly ReactElement<{value: string}>[]; + readonly defaultValue?: string; + readonly values: readonly {value: string; label: string}[]; + readonly groupId?: string; + }; + + const Tabs: () => JSX.Element; + export default Tabs; +} + +declare module '@theme/ThemeProvider' { + import type {ReactNode} from 'react'; + + export type Props = {readonly children: ReactNode}; + + const ThemeProvider: (props: Props) => JSX.Element; + export default ThemeProvider; +} + +declare module '@theme/TOC' { + import type {MarkdownRightTableOfContents} from '@docusaurus/types'; + + export type TOCProps = { + readonly headings: readonly MarkdownRightTableOfContents[]; + }; + + const TOC: (props: TOCProps) => JSX.Element; + export default TOC; +} + +declare module '@theme/Toggle' { + import {ComponentProps} from 'react'; + import ReactToggle from 'react-toggle'; + + const Toggle: (props: ComponentProps) => JSX.Element; + export default Toggle; +} + +declare module '@theme/UserPreferencesProvider' { + import type {ReactNode} from 'react'; + + export type Props = {readonly children: ReactNode}; + + const UserPreferencesProvider: (props: Props) => JSX.Element; + export default UserPreferencesProvider; +} + +declare module '@theme/ThemeContext' { + import type {Context} from 'react'; + import type {ThemeContextProps} from '@theme/hooks/useThemeContext'; + + const ThemeContext: Context; + export default ThemeContext; +} + +declare module '@theme/UserPreferencesContext' { + import type {Context} from 'react'; + import type {UserPreferencesContextProps} from '@theme/hooks/useUserPreferencesContext'; + + const UserPreferencesContext: Context< + UserPreferencesContextProps | undefined + >; + export default UserPreferencesContext; +} diff --git a/website/src/types.d.ts b/website/src/types.d.ts index 684e0064fb..be20e6399f 100644 --- a/website/src/types.d.ts +++ b/website/src/types.d.ts @@ -7,3 +7,4 @@ // eslint-disable-next-line spaced-comment /// +/// diff --git a/yarn.lock b/yarn.lock index 730193aa8a..f32848ee48 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4168,6 +4168,13 @@ "@types/history" "*" "@types/react" "*" +"@types/react-toggle@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/react-toggle/-/react-toggle-4.0.2.tgz#46ffa5af1a55de5f25d0aa78ef0b557b5c8bf276" + integrity sha512-sHqfoKFnL0YU2+OC4meNEC8Ptx9FE8/+nFeFvNcdBa6ANA8KpAzj3R9JN8GtrvlLgjKDoYgI7iILgXYcTPo2IA== + dependencies: + "@types/react" "*" + "@types/react@*", "@types/react@^16.9.38": version "16.9.38" resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.38.tgz#868405dace93a4095d3e054f4c4a1de7a1ac0680"