From a19ca3863571e55b9327b9490ed7ec91491828bb Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 28 Aug 2020 09:58:27 -0400 Subject: [PATCH] feat(v2): Provide type definitions for remaining theme-classic components --- .../docusaurus-theme-classic/package.json | 1 + .../theme/NavbarItem/DefaultNavbarItem.tsx | 39 ++++++----- .../DocsVersionDropdownNavbarItem.tsx | 4 +- .../NavbarItem/DocsVersionNavbarItem.tsx | 4 +- .../src/theme/NavbarItem/index.tsx | 9 ++- .../docusaurus-theme-classic/src/types.d.ts | 64 +++++++++++++++++-- 6 files changed, 94 insertions(+), 27 deletions(-) diff --git a/packages/docusaurus-theme-classic/package.json b/packages/docusaurus-theme-classic/package.json index 4a0f5fe168aa..540db5c6351e 100644 --- a/packages/docusaurus-theme-classic/package.json +++ b/packages/docusaurus-theme-classic/package.json @@ -41,6 +41,7 @@ "@docusaurus/core": "^2.0.0", "@docusaurus/plugin-content-blog": "^2.0.0-alpha.61", "@docusaurus/plugin-content-docs": "^2.0.0-alpha.61", + "@docusaurus/plugin-content-pages": "^2.0.0-alpha.61", "react": "^16.8.4", "react-dom": "^16.8.4" }, diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DefaultNavbarItem.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DefaultNavbarItem.tsx index e1bbe0e822a1..7e149fcff547 100644 --- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DefaultNavbarItem.tsx +++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DefaultNavbarItem.tsx @@ -5,11 +5,16 @@ * LICENSE file in the root directory of this source tree. */ -import React, {ComponentProps, ComponentType, useState} from 'react'; +import React, {useState} from 'react'; import clsx from 'clsx'; import Link from '@docusaurus/Link'; import useBaseUrl from '@docusaurus/useBaseUrl'; import useOnClickOutside from 'use-onclickoutside'; +import type { + NavLinkProps, + DesktopOrMobileNavBarItemProps, + Props, +} from '@theme/NavbarItem/DefaultNavbarItem'; function NavLink({ activeBasePath, @@ -20,15 +25,7 @@ function NavLink({ activeClassName = 'navbar__link--active', prependBaseUrlToHref, ...props -}: { - activeBasePath?: string; - activeBaseRegex?: string; - to?: string; - href?: string; - label?: string; - activeClassName?: string; - prependBaseUrlToHref?: string; -} & ComponentProps<'a'>) { +}: NavLinkProps) { // TODO all this seems hacky // {to: 'version'} should probably be forbidden, in favor of {to: '/version'} const toUrl = useBaseUrl(to); @@ -62,7 +59,12 @@ function NavLink({ ); } -function NavItemDesktop({items, position, className, ...props}) { +function NavItemDesktop({ + items, + position, + className, + ...props +}: DesktopOrMobileNavBarItemProps) { const dropDownRef = React.useRef(null); const dropDownMenuRef = React.useRef(null); const [showDropDown, setShowDropDown] = useState(false); @@ -78,7 +80,7 @@ function NavItemDesktop({items, position, className, ...props}) { } setShowDropDown(state); } - const navLinkClassNames = (extraClassName, isDropdownItem = false) => + const navLinkClassNames = (extraClassName?: string, isDropdownItem = false) => clsx( { 'navbar__item navbar__link': !isDropdownItem, @@ -132,9 +134,14 @@ function NavItemDesktop({items, position, className, ...props}) { ); } -function NavItemMobile({items, position: _position, className, ...props}) { +function NavItemMobile({ + items, + position: _position, + className, + ...props +}: DesktopOrMobileNavBarItemProps) { // Need to destructure position from props so that it doesn't get passed on. - const navLinkClassNames = (extraClassName, isSubList = false) => + const navLinkClassNames = (extraClassName?: string, isSubList = false) => clsx( 'menu__link', { @@ -172,8 +179,8 @@ function NavItemMobile({items, position: _position, className, ...props}) { ); } -function DefaultNavbarItem({mobile = false, ...props}) { - const Comp: ComponentType = mobile ? NavItemMobile : NavItemDesktop; +function DefaultNavbarItem({mobile = false, ...props}: Props): JSX.Element { + const Comp = mobile ? NavItemMobile : NavItemDesktop; return ; } diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx index a9a6efd56e00..7701f9d83516 100644 --- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx +++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx @@ -12,6 +12,7 @@ import { useLatestVersion, useActiveDocContext, } from '@theme/hooks/useDocs'; +import type {Props} from '@theme/NavbarItem/DocsVersionDropdownNavbarItem'; const getVersionMainDoc = (version) => version.docs.find((doc) => doc.id === version.mainDocId); @@ -19,9 +20,8 @@ const getVersionMainDoc = (version) => export default function DocsVersionDropdownNavbarItem({ mobile, docsPluginId, - nextVersionLabel: _unused, // TODO legacy, remove asap ...props -}) { +}: Props): JSX.Element { const activeDocContext = useActiveDocContext(docsPluginId); const versions = useVersions(docsPluginId); const latestVersion = useLatestVersion(docsPluginId); diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionNavbarItem.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionNavbarItem.tsx index 5d6a0f33bf95..9a82a31ffba8 100644 --- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionNavbarItem.tsx +++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/DocsVersionNavbarItem.tsx @@ -8,6 +8,7 @@ import React from 'react'; import DefaultNavbarItem from './DefaultNavbarItem'; import {useActiveVersion, useLatestVersion} from '@theme/hooks/useDocs'; +import type {Props} from '@theme/NavbarItem/DocsVersionNavbarItem'; const getVersionMainDoc = (version) => version.docs.find((doc) => doc.id === version.mainDocId); @@ -16,9 +17,8 @@ export default function DocsVersionNavbarItem({ label: staticLabel, to: staticTo, docsPluginId, - nextVersionLabel: _unused, // TODO legacy, remove asap ...props -}) { +}: Props): JSX.Element { const activeVersion = useActiveVersion(docsPluginId); const latestVersion = useLatestVersion(docsPluginId); const version = activeVersion ?? latestVersion; diff --git a/packages/docusaurus-theme-classic/src/theme/NavbarItem/index.tsx b/packages/docusaurus-theme-classic/src/theme/NavbarItem/index.tsx index 9ef55cdf7f72..04e7f3afad67 100644 --- a/packages/docusaurus-theme-classic/src/theme/NavbarItem/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/NavbarItem/index.tsx @@ -9,14 +9,17 @@ import React from 'react'; import DocsVersionNavbarItem from '@theme/NavbarItem/DocsVersionNavbarItem'; import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; import DocsVersionDropdownNavbarItem from '@theme/NavbarItem/DocsVersionDropdownNavbarItem'; +import type {Props} from '@theme/NavbarItem'; const NavbarItemComponents = { default: DefaultNavbarItem, docsVersion: DocsVersionNavbarItem, docsVersionDropdown: DocsVersionDropdownNavbarItem, -}; +} as const; -const getNavbarItemComponent = (type: string = 'default') => { +const getNavbarItemComponent = ( + type: keyof typeof NavbarItemComponents = 'default', +) => { const NavbarItemComponent = NavbarItemComponents[type]; if (!NavbarItemComponent) { throw new Error(`No NavbarItem component found for type=${type}.`); @@ -24,7 +27,7 @@ const getNavbarItemComponent = (type: string = 'default') => { return NavbarItemComponent; }; -export default function NavbarItem({type, ...props}) { +export default function NavbarItem({type, ...props}: Props): JSX.Element { const NavbarItemComponent = getNavbarItemComponent(type); return ; } diff --git a/packages/docusaurus-theme-classic/src/types.d.ts b/packages/docusaurus-theme-classic/src/types.d.ts index e9506464413f..456e8a6fe072 100644 --- a/packages/docusaurus-theme-classic/src/types.d.ts +++ b/packages/docusaurus-theme-classic/src/types.d.ts @@ -277,10 +277,66 @@ declare module '@theme/Navbar' { export default Navbar; } -// TODO @theme/NavbarItem/DefaultNavbarItem -// TODO @theme/NavbarItem/DocsVersionDropdownNavbarItem -// TODO @theme/NavbarItem/DocsVersionNavbarItem -// TODO @theme/NavbarItem +declare module '@theme/NavbarItem/DefaultNavbarItem' { + import type {ComponentProps} from 'react'; + + export type NavLinkProps = { + activeBasePath?: string; + activeBaseRegex?: string; + to?: string; + href?: string; + label?: string; + activeClassName?: string; + prependBaseUrlToHref?: string; + } & ComponentProps<'a'>; + + export type DesktopOrMobileNavBarItemProps = NavLinkProps & { + readonly items?: readonly NavLinkProps[]; + readonly position?: 'left' | 'right'; + readonly className?: string; + }; + + export type Props = DesktopOrMobileNavBarItemProps & { + readonly mobile?: boolean; + }; + + const DefaultNavbarItem: (props: Props) => JSX.Element; + export default DefaultNavbarItem; +} + +declare module '@theme/NavbarItem/DocsVersionDropdownNavbarItem' { + import type {Props as DefaultNavbarItemProps} from '@theme/NavbarItem/DefaultNavbarItem'; + + export type Props = DefaultNavbarItemProps & {readonly docsPluginId?: string}; + + const DocsVersionDropdownNavbarItem: (props: Props) => JSX.Element; + export default DocsVersionDropdownNavbarItem; +} + +declare module '@theme/NavbarItem/DocsVersionNavbarItem' { + import type {Props as DefaultNavbarItemProps} from '@theme/NavbarItem/DefaultNavbarItem'; + + export type Props = DefaultNavbarItemProps & {readonly docsPluginId?: string}; + + const DocsVersionNavbarItem: (props: Props) => JSX.Element; + export default DocsVersionNavbarItem; +} + +declare module '@theme/NavbarItem' { + import type {Props as DefaultNavbarItemProps} from '@theme/NavbarItem/DefaultNavbarItem'; + import type {Props as DocsVersionDropdownNavbarItemProps} from '@theme/NavbarItem/DocsVersionDropdownNavbarItem'; + import type {Props as DocsVersionNavbarItemProps} from '@theme/NavbarItem/DocsVersionNavbarItem'; + + export type Props = + | ({readonly type: 'default'} & DefaultNavbarItemProps) + | ({ + readonly type: 'docsVersionDropdown'; + } & DocsVersionDropdownNavbarItemProps) + | ({readonly type: 'docsVersion'} & DocsVersionNavbarItemProps); + + const NavbarItem: (props: Props) => JSX.Element; + export default NavbarItem; +} declare module '@theme/TabItem' { import type {ReactNode} from 'react';