feat(v2): Provide type definitions for remaining theme-classic components (#3356)

This commit is contained in:
Sam Zhou 2020-08-28 11:45:51 -04:00 committed by GitHub
parent 16ae3bf462
commit aa9212cb45
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 94 additions and 27 deletions

View file

@ -41,6 +41,7 @@
"@docusaurus/core": "^2.0.0", "@docusaurus/core": "^2.0.0",
"@docusaurus/plugin-content-blog": "^2.0.0-alpha.61", "@docusaurus/plugin-content-blog": "^2.0.0-alpha.61",
"@docusaurus/plugin-content-docs": "^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": "^16.8.4",
"react-dom": "^16.8.4" "react-dom": "^16.8.4"
}, },

View file

@ -5,11 +5,16 @@
* LICENSE file in the root directory of this source tree. * 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 clsx from 'clsx';
import Link from '@docusaurus/Link'; import Link from '@docusaurus/Link';
import useBaseUrl from '@docusaurus/useBaseUrl'; import useBaseUrl from '@docusaurus/useBaseUrl';
import useOnClickOutside from 'use-onclickoutside'; import useOnClickOutside from 'use-onclickoutside';
import type {
NavLinkProps,
DesktopOrMobileNavBarItemProps,
Props,
} from '@theme/NavbarItem/DefaultNavbarItem';
function NavLink({ function NavLink({
activeBasePath, activeBasePath,
@ -20,15 +25,7 @@ function NavLink({
activeClassName = 'navbar__link--active', activeClassName = 'navbar__link--active',
prependBaseUrlToHref, prependBaseUrlToHref,
...props ...props
}: { }: NavLinkProps) {
activeBasePath?: string;
activeBaseRegex?: string;
to?: string;
href?: string;
label?: string;
activeClassName?: string;
prependBaseUrlToHref?: string;
} & ComponentProps<'a'>) {
// TODO all this seems hacky // TODO all this seems hacky
// {to: 'version'} should probably be forbidden, in favor of {to: '/version'} // {to: 'version'} should probably be forbidden, in favor of {to: '/version'}
const toUrl = useBaseUrl(to); 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<HTMLDivElement>(null); const dropDownRef = React.useRef<HTMLDivElement>(null);
const dropDownMenuRef = React.useRef<HTMLUListElement>(null); const dropDownMenuRef = React.useRef<HTMLUListElement>(null);
const [showDropDown, setShowDropDown] = useState(false); const [showDropDown, setShowDropDown] = useState(false);
@ -78,7 +80,7 @@ function NavItemDesktop({items, position, className, ...props}) {
} }
setShowDropDown(state); setShowDropDown(state);
} }
const navLinkClassNames = (extraClassName, isDropdownItem = false) => const navLinkClassNames = (extraClassName?: string, isDropdownItem = false) =>
clsx( clsx(
{ {
'navbar__item navbar__link': !isDropdownItem, '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. // 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( clsx(
'menu__link', 'menu__link',
{ {
@ -172,8 +179,8 @@ function NavItemMobile({items, position: _position, className, ...props}) {
); );
} }
function DefaultNavbarItem({mobile = false, ...props}) { function DefaultNavbarItem({mobile = false, ...props}: Props): JSX.Element {
const Comp: ComponentType<any> = mobile ? NavItemMobile : NavItemDesktop; const Comp = mobile ? NavItemMobile : NavItemDesktop;
return <Comp {...props} />; return <Comp {...props} />;
} }

View file

@ -12,6 +12,7 @@ import {
useLatestVersion, useLatestVersion,
useActiveDocContext, useActiveDocContext,
} from '@theme/hooks/useDocs'; } from '@theme/hooks/useDocs';
import type {Props} from '@theme/NavbarItem/DocsVersionDropdownNavbarItem';
const getVersionMainDoc = (version) => const getVersionMainDoc = (version) =>
version.docs.find((doc) => doc.id === version.mainDocId); version.docs.find((doc) => doc.id === version.mainDocId);
@ -19,9 +20,8 @@ const getVersionMainDoc = (version) =>
export default function DocsVersionDropdownNavbarItem({ export default function DocsVersionDropdownNavbarItem({
mobile, mobile,
docsPluginId, docsPluginId,
nextVersionLabel: _unused, // TODO legacy, remove asap
...props ...props
}) { }: Props): JSX.Element {
const activeDocContext = useActiveDocContext(docsPluginId); const activeDocContext = useActiveDocContext(docsPluginId);
const versions = useVersions(docsPluginId); const versions = useVersions(docsPluginId);
const latestVersion = useLatestVersion(docsPluginId); const latestVersion = useLatestVersion(docsPluginId);

View file

@ -8,6 +8,7 @@
import React from 'react'; import React from 'react';
import DefaultNavbarItem from './DefaultNavbarItem'; import DefaultNavbarItem from './DefaultNavbarItem';
import {useActiveVersion, useLatestVersion} from '@theme/hooks/useDocs'; import {useActiveVersion, useLatestVersion} from '@theme/hooks/useDocs';
import type {Props} from '@theme/NavbarItem/DocsVersionNavbarItem';
const getVersionMainDoc = (version) => const getVersionMainDoc = (version) =>
version.docs.find((doc) => doc.id === version.mainDocId); version.docs.find((doc) => doc.id === version.mainDocId);
@ -16,9 +17,8 @@ export default function DocsVersionNavbarItem({
label: staticLabel, label: staticLabel,
to: staticTo, to: staticTo,
docsPluginId, docsPluginId,
nextVersionLabel: _unused, // TODO legacy, remove asap
...props ...props
}) { }: Props): JSX.Element {
const activeVersion = useActiveVersion(docsPluginId); const activeVersion = useActiveVersion(docsPluginId);
const latestVersion = useLatestVersion(docsPluginId); const latestVersion = useLatestVersion(docsPluginId);
const version = activeVersion ?? latestVersion; const version = activeVersion ?? latestVersion;

View file

@ -9,14 +9,17 @@ import React from 'react';
import DocsVersionNavbarItem from '@theme/NavbarItem/DocsVersionNavbarItem'; import DocsVersionNavbarItem from '@theme/NavbarItem/DocsVersionNavbarItem';
import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem';
import DocsVersionDropdownNavbarItem from '@theme/NavbarItem/DocsVersionDropdownNavbarItem'; import DocsVersionDropdownNavbarItem from '@theme/NavbarItem/DocsVersionDropdownNavbarItem';
import type {Props} from '@theme/NavbarItem';
const NavbarItemComponents = { const NavbarItemComponents = {
default: DefaultNavbarItem, default: DefaultNavbarItem,
docsVersion: DocsVersionNavbarItem, docsVersion: DocsVersionNavbarItem,
docsVersionDropdown: DocsVersionDropdownNavbarItem, docsVersionDropdown: DocsVersionDropdownNavbarItem,
}; } as const;
const getNavbarItemComponent = (type: string = 'default') => { const getNavbarItemComponent = (
type: keyof typeof NavbarItemComponents = 'default',
) => {
const NavbarItemComponent = NavbarItemComponents[type]; const NavbarItemComponent = NavbarItemComponents[type];
if (!NavbarItemComponent) { if (!NavbarItemComponent) {
throw new Error(`No NavbarItem component found for type=${type}.`); throw new Error(`No NavbarItem component found for type=${type}.`);
@ -24,7 +27,7 @@ const getNavbarItemComponent = (type: string = 'default') => {
return NavbarItemComponent; return NavbarItemComponent;
}; };
export default function NavbarItem({type, ...props}) { export default function NavbarItem({type, ...props}: Props): JSX.Element {
const NavbarItemComponent = getNavbarItemComponent(type); const NavbarItemComponent = getNavbarItemComponent(type);
return <NavbarItemComponent {...props} />; return <NavbarItemComponent {...props} />;
} }

View file

@ -277,10 +277,66 @@ declare module '@theme/Navbar' {
export default Navbar; export default Navbar;
} }
// TODO @theme/NavbarItem/DefaultNavbarItem declare module '@theme/NavbarItem/DefaultNavbarItem' {
// TODO @theme/NavbarItem/DocsVersionDropdownNavbarItem import type {ComponentProps} from 'react';
// TODO @theme/NavbarItem/DocsVersionNavbarItem
// TODO @theme/NavbarItem 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' { declare module '@theme/TabItem' {
import type {ReactNode} from 'react'; import type {ReactNode} from 'react';