Skip to content

Commit

Permalink
feat(v2): Provide type definitions for remaining theme-classic compon…
Browse files Browse the repository at this point in the history
…ents (#3356)
  • Loading branch information
SamChou19815 authored Aug 28, 2020
1 parent 16ae3bf commit aa9212c
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 27 deletions.
1 change: 1 addition & 0 deletions packages/docusaurus-theme-classic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
Expand Down Expand Up @@ -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 dropDownMenuRef = React.useRef<HTMLUListElement>(null);
const [showDropDown, setShowDropDown] = useState(false);
Expand All @@ -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,
Expand Down Expand Up @@ -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',
{
Expand Down Expand Up @@ -172,8 +179,8 @@ function NavItemMobile({items, position: _position, className, ...props}) {
);
}

function DefaultNavbarItem({mobile = false, ...props}) {
const Comp: ComponentType<any> = mobile ? NavItemMobile : NavItemDesktop;
function DefaultNavbarItem({mobile = false, ...props}: Props): JSX.Element {
const Comp = mobile ? NavItemMobile : NavItemDesktop;
return <Comp {...props} />;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ 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);

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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,25 @@ 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}.`);
}
return NavbarItemComponent;
};

export default function NavbarItem({type, ...props}) {
export default function NavbarItem({type, ...props}: Props): JSX.Element {
const NavbarItemComponent = getNavbarItemComponent(type);
return <NavbarItemComponent {...props} />;
}
64 changes: 60 additions & 4 deletions packages/docusaurus-theme-classic/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down

0 comments on commit aa9212c

Please sign in to comment.