mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-22 21:47:01 +02:00
refactor(theme-classic): apply import/no-named-export eslint rule (#6283)
This commit is contained in:
parent
1c7b0d1353
commit
3bc63b2b09
18 changed files with 257 additions and 176 deletions
10
.eslintrc.js
10
.eslintrc.js
|
@ -173,6 +173,16 @@ module.exports = {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
overrides: [
|
overrides: [
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
'packages/docusaurus-theme-*/src/theme/**/*.js',
|
||||||
|
'packages/docusaurus-theme-*/src/theme/**/*.ts',
|
||||||
|
'packages/docusaurus-theme-*/src/theme/**/*.tsx',
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
'import/no-named-export': ERROR,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
files: [
|
files: [
|
||||||
'packages/create-docusaurus/templates/**/*.js',
|
'packages/create-docusaurus/templates/**/*.js',
|
||||||
|
|
|
@ -149,23 +149,33 @@ declare module '@theme/DocSidebar' {
|
||||||
declare module '@theme/DocSidebarItem' {
|
declare module '@theme/DocSidebarItem' {
|
||||||
import type {PropSidebarItem} from '@docusaurus/plugin-content-docs';
|
import type {PropSidebarItem} from '@docusaurus/plugin-content-docs';
|
||||||
|
|
||||||
type DocSidebarPropsBase = {
|
export type DocSidebarPropsBase = {
|
||||||
readonly activePath: string;
|
readonly activePath: string;
|
||||||
readonly onItemClick?: (item: PropSidebarItem) => void;
|
readonly onItemClick?: (item: PropSidebarItem) => void;
|
||||||
readonly level: number;
|
readonly level: number;
|
||||||
readonly tabIndex?: number;
|
readonly tabIndex?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface Props extends DocSidebarPropsBase {
|
export interface Props {
|
||||||
|
readonly activePath: string;
|
||||||
|
readonly onItemClick?: (item: PropSidebarItem) => void;
|
||||||
|
readonly level: number;
|
||||||
|
readonly tabIndex?: number;
|
||||||
readonly item: PropSidebarItem;
|
readonly item: PropSidebarItem;
|
||||||
}
|
}
|
||||||
const DocSidebarItem: (props: Props) => JSX.Element;
|
|
||||||
export default DocSidebarItem;
|
|
||||||
|
|
||||||
export type DocSidebarItemsProps = DocSidebarPropsBase & {
|
export default function DocSidebarItem(props: Props): JSX.Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module '@theme/DocSidebarItems' {
|
||||||
|
import type {Props as DocSidebarItemProps} from '@theme/DocSidebarItem';
|
||||||
|
import type {PropSidebarItem} from '@docusaurus/plugin-content-docs';
|
||||||
|
|
||||||
|
export type Props = Omit<DocSidebarItemProps, 'item'> & {
|
||||||
readonly items: readonly PropSidebarItem[];
|
readonly items: readonly PropSidebarItem[];
|
||||||
};
|
};
|
||||||
export const DocSidebarItems: (props: DocSidebarItemsProps) => JSX.Element;
|
|
||||||
|
export default function DocSidebarItems(props: Props): JSX.Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module '@theme/DocVersionSuggestions' {
|
declare module '@theme/DocVersionSuggestions' {
|
||||||
|
@ -196,12 +206,13 @@ declare module '@theme/Footer' {
|
||||||
declare module '@theme/Heading' {
|
declare module '@theme/Heading' {
|
||||||
import type {ComponentProps} from 'react';
|
import type {ComponentProps} from 'react';
|
||||||
|
|
||||||
export type HeadingType = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
type HeadingType = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
||||||
export interface Props extends ComponentProps<HeadingType> {}
|
|
||||||
|
|
||||||
const Heading: (Tag: HeadingType) => (props: Props) => JSX.Element;
|
export interface Props extends ComponentProps<HeadingType> {
|
||||||
export default Heading;
|
as: HeadingType;
|
||||||
export const MainHeading: (props: Props) => JSX.Element;
|
}
|
||||||
|
|
||||||
|
export default function Heading(props: Props): JSX.Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module '@theme/hooks/useHideableNavbar' {
|
declare module '@theme/hooks/useHideableNavbar' {
|
||||||
|
@ -372,18 +383,9 @@ declare module '@theme/Navbar' {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module '@theme/NavbarItem/DefaultNavbarItem' {
|
declare module '@theme/NavbarItem/DefaultNavbarItem' {
|
||||||
import type {ReactNode} from 'react';
|
import type {Props as NavbarNavLinkProps} from '@theme/NavbarItem/NavbarNavLink';
|
||||||
import type {LinkProps} from '@docusaurus/Link';
|
|
||||||
|
|
||||||
export type NavLinkProps = LinkProps & {
|
export type DesktopOrMobileNavBarItemProps = NavbarNavLinkProps & {
|
||||||
readonly activeBasePath?: string;
|
|
||||||
readonly activeBaseRegex?: string;
|
|
||||||
readonly exact?: boolean;
|
|
||||||
readonly label?: ReactNode;
|
|
||||||
readonly prependBaseUrlToHref?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type DesktopOrMobileNavBarItemProps = NavLinkProps & {
|
|
||||||
readonly isDropdownItem?: boolean;
|
readonly isDropdownItem?: boolean;
|
||||||
readonly className?: string;
|
readonly className?: string;
|
||||||
readonly position?: 'left' | 'right';
|
readonly position?: 'left' | 'right';
|
||||||
|
@ -393,17 +395,30 @@ declare module '@theme/NavbarItem/DefaultNavbarItem' {
|
||||||
readonly mobile?: boolean;
|
readonly mobile?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const NavLink: (props: NavLinkProps) => JSX.Element;
|
export default function DefaultNavbarItem(props: Props): JSX.Element;
|
||||||
|
}
|
||||||
|
|
||||||
const DefaultNavbarItem: (props: Props) => JSX.Element;
|
declare module '@theme/NavbarItem/NavbarNavLink' {
|
||||||
export default DefaultNavbarItem;
|
import type {ReactNode} from 'react';
|
||||||
|
import type {LinkProps} from '@docusaurus/Link';
|
||||||
|
|
||||||
|
export type Props = LinkProps & {
|
||||||
|
readonly activeBasePath?: string;
|
||||||
|
readonly activeBaseRegex?: string;
|
||||||
|
readonly exact?: boolean;
|
||||||
|
readonly label?: ReactNode;
|
||||||
|
readonly prependBaseUrlToHref?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function NavbarNavLink(props: Props): JSX.Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module '@theme/NavbarItem/DropdownNavbarItem' {
|
declare module '@theme/NavbarItem/DropdownNavbarItem' {
|
||||||
import type {NavLinkProps} from '@theme/NavbarItem/DefaultNavbarItem';
|
import type {Props as NavbarNavLinkProps} from '@theme/NavbarItem/NavbarNavLink';
|
||||||
|
|
||||||
import type {LinkLikeNavbarItemProps} from '@theme/NavbarItem';
|
import type {LinkLikeNavbarItemProps} from '@theme/NavbarItem';
|
||||||
|
|
||||||
export type DesktopOrMobileNavBarItemProps = NavLinkProps & {
|
export type DesktopOrMobileNavBarItemProps = NavbarNavLinkProps & {
|
||||||
readonly position?: 'left' | 'right';
|
readonly position?: 'left' | 'right';
|
||||||
readonly items: readonly LinkLikeNavbarItemProps[];
|
readonly items: readonly LinkLikeNavbarItemProps[];
|
||||||
readonly className?: string;
|
readonly className?: string;
|
||||||
|
@ -526,6 +541,10 @@ declare module '@theme/NavbarItem' {
|
||||||
export default NavbarItem;
|
export default NavbarItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare module '@theme/NavbarItem/utils' {
|
||||||
|
export function getInfimaActiveClassName(mobile?: boolean): string;
|
||||||
|
}
|
||||||
|
|
||||||
declare module '@theme/PaginatorNavLink' {
|
declare module '@theme/PaginatorNavLink' {
|
||||||
import type {ReactNode} from 'react';
|
import type {ReactNode} from 'react';
|
||||||
import type {PropNavigationLink} from '@docusaurus/plugin-content-docs';
|
import type {PropNavigationLink} from '@docusaurus/plugin-content-docs';
|
||||||
|
|
|
@ -13,7 +13,7 @@ import DocPaginator from '@theme/DocPaginator';
|
||||||
import Seo from '@theme/Seo';
|
import Seo from '@theme/Seo';
|
||||||
import DocVersionBanner from '@theme/DocVersionBanner';
|
import DocVersionBanner from '@theme/DocVersionBanner';
|
||||||
import DocVersionBadge from '@theme/DocVersionBadge';
|
import DocVersionBadge from '@theme/DocVersionBadge';
|
||||||
import {MainHeading} from '@theme/Heading';
|
import Heading from '@theme/Heading';
|
||||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||||
|
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
|
@ -35,9 +35,9 @@ export default function DocCategoryGeneratedIndexPage({
|
||||||
<DocVersionBanner />
|
<DocVersionBanner />
|
||||||
<DocVersionBadge />
|
<DocVersionBadge />
|
||||||
<header>
|
<header>
|
||||||
<MainHeading className={styles.title}>
|
<Heading as="h1" className={styles.title}>
|
||||||
{categoryGeneratedIndex.title}
|
{categoryGeneratedIndex.title}
|
||||||
</MainHeading>
|
</Heading>
|
||||||
{categoryGeneratedIndex.description && (
|
{categoryGeneratedIndex.description && (
|
||||||
<p>{categoryGeneratedIndex.description}</p>
|
<p>{categoryGeneratedIndex.description}</p>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import type {Props} from '@theme/DocItem';
|
||||||
import DocItemFooter from '@theme/DocItemFooter';
|
import DocItemFooter from '@theme/DocItemFooter';
|
||||||
import TOC from '@theme/TOC';
|
import TOC from '@theme/TOC';
|
||||||
import TOCCollapsible from '@theme/TOCCollapsible';
|
import TOCCollapsible from '@theme/TOCCollapsible';
|
||||||
import {MainHeading} from '@theme/Heading';
|
import Heading from '@theme/Heading';
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
import {ThemeClassNames} from '@docusaurus/theme-common';
|
import {ThemeClassNames} from '@docusaurus/theme-common';
|
||||||
|
|
||||||
|
@ -80,7 +80,11 @@ export default function DocItem(props: Props): JSX.Element {
|
||||||
To make both cases consistent, the added title is added under the same div.markdown block
|
To make both cases consistent, the added title is added under the same div.markdown block
|
||||||
See https://github.com/facebook/docusaurus/pull/4882#issuecomment-853021120
|
See https://github.com/facebook/docusaurus/pull/4882#issuecomment-853021120
|
||||||
*/}
|
*/}
|
||||||
{shouldAddTitle && <MainHeading>{title}</MainHeading>}
|
{shouldAddTitle && (
|
||||||
|
<header>
|
||||||
|
<Heading as="h1">{title}</Heading>
|
||||||
|
</header>
|
||||||
|
)}
|
||||||
|
|
||||||
<DocContent />
|
<DocContent />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -19,7 +19,7 @@ import useWindowSize from '@theme/hooks/useWindowSize';
|
||||||
import Logo from '@theme/Logo';
|
import Logo from '@theme/Logo';
|
||||||
import IconArrow from '@theme/IconArrow';
|
import IconArrow from '@theme/IconArrow';
|
||||||
import {translate} from '@docusaurus/Translate';
|
import {translate} from '@docusaurus/Translate';
|
||||||
import {DocSidebarItems} from '@theme/DocSidebarItem';
|
import DocSidebarItems from '@theme/DocSidebarItems';
|
||||||
import type {Props} from '@theme/DocSidebar';
|
import type {Props} from '@theme/DocSidebar';
|
||||||
|
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {useEffect, memo, useMemo} from 'react';
|
import React, {useEffect, useMemo} from 'react';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import {
|
import {
|
||||||
isActiveSidebarItem,
|
isActiveSidebarItem,
|
||||||
|
@ -20,7 +20,8 @@ import isInternalUrl from '@docusaurus/isInternalUrl';
|
||||||
import {translate} from '@docusaurus/Translate';
|
import {translate} from '@docusaurus/Translate';
|
||||||
import IconExternalLink from '@theme/IconExternalLink';
|
import IconExternalLink from '@theme/IconExternalLink';
|
||||||
|
|
||||||
import type {Props, DocSidebarItemsProps} from '@theme/DocSidebarItem';
|
import DocSidebarItems from '@theme/DocSidebarItems';
|
||||||
|
import type {Props} from '@theme/DocSidebarItem';
|
||||||
import type {
|
import type {
|
||||||
PropSidebarItemCategory,
|
PropSidebarItemCategory,
|
||||||
PropSidebarItemLink,
|
PropSidebarItemLink,
|
||||||
|
@ -29,23 +30,6 @@ import type {
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
import useIsBrowser from '@docusaurus/useIsBrowser';
|
import useIsBrowser from '@docusaurus/useIsBrowser';
|
||||||
|
|
||||||
// Optimize sidebar at each "level"
|
|
||||||
// TODO this item should probably not receive the "activePath" props
|
|
||||||
// TODO this triggers whole sidebar re-renders on navigation
|
|
||||||
export const DocSidebarItems = memo(
|
|
||||||
({items, ...props}: DocSidebarItemsProps): JSX.Element => (
|
|
||||||
<>
|
|
||||||
{items.map((item, index) => (
|
|
||||||
<DocSidebarItem
|
|
||||||
key={index} // sidebar is static, the index does not change
|
|
||||||
item={item}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
export default function DocSidebarItem({
|
export default function DocSidebarItem({
|
||||||
item,
|
item,
|
||||||
...props
|
...props
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, {memo} from 'react';
|
||||||
|
|
||||||
|
import DocSidebarItem from '@theme/DocSidebarItem';
|
||||||
|
|
||||||
|
import type {Props} from '@theme/DocSidebarItems';
|
||||||
|
|
||||||
|
// TODO this item should probably not receive the "activePath" props
|
||||||
|
// TODO this triggers whole sidebar re-renders on navigation
|
||||||
|
function DocSidebarItems({items, ...props}: Props): JSX.Element {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{items.map((item, index) => (
|
||||||
|
<DocSidebarItem
|
||||||
|
key={index} // sidebar is static, the index does not change
|
||||||
|
item={item}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optimize sidebar at each "level"
|
||||||
|
export default memo(DocSidebarItems);
|
|
@ -0,0 +1,19 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@media (min-width: 997px) {
|
||||||
|
.menuLinkText {
|
||||||
|
cursor: initial;
|
||||||
|
}
|
||||||
|
.menuLinkText:hover {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menuLinkText.hasHref {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,40 +7,24 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import type {HeadingType, Props} from '@theme/Heading';
|
import type {Props} from '@theme/Heading';
|
||||||
import {translate} from '@docusaurus/Translate';
|
import {translate} from '@docusaurus/Translate';
|
||||||
import {useThemeConfig} from '@docusaurus/theme-common';
|
import {useThemeConfig} from '@docusaurus/theme-common';
|
||||||
|
|
||||||
import './styles.css';
|
import './styles.css';
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
|
|
||||||
type HeadingComponent = (props: Props) => JSX.Element;
|
function AnchorHeading({as: As, id, ...props}: Props) {
|
||||||
|
|
||||||
// eslint-disable-next-line react/function-component-definition
|
|
||||||
export const MainHeading: HeadingComponent = ({...props}) => (
|
|
||||||
<header>
|
|
||||||
<h1
|
|
||||||
{...props}
|
|
||||||
id={undefined} // h1 headings do not need an id because they don't appear in the TOC
|
|
||||||
>
|
|
||||||
{props.children}
|
|
||||||
</h1>
|
|
||||||
</header>
|
|
||||||
);
|
|
||||||
|
|
||||||
const createAnchorHeading =
|
|
||||||
(Tag: HeadingType) =>
|
|
||||||
({id, ...props}: Props) => {
|
|
||||||
const {
|
const {
|
||||||
navbar: {hideOnScroll},
|
navbar: {hideOnScroll},
|
||||||
} = useThemeConfig();
|
} = useThemeConfig();
|
||||||
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
return <Tag {...props} />;
|
return <As {...props} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tag
|
<As
|
||||||
{...props}
|
{...props}
|
||||||
className={clsx('anchor', {
|
className={clsx('anchor', {
|
||||||
[styles.anchorWithHideOnScrollNavbar]: hideOnScroll,
|
[styles.anchorWithHideOnScrollNavbar]: hideOnScroll,
|
||||||
|
@ -58,11 +42,20 @@ const createAnchorHeading =
|
||||||
})}>
|
})}>
|
||||||
​
|
​
|
||||||
</a>
|
</a>
|
||||||
</Tag>
|
</As>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
const Heading = (headingType: HeadingType): ((props: Props) => JSX.Element) =>
|
export default function Heading({as, ...props}: Props) {
|
||||||
headingType === 'h1' ? MainHeading : createAnchorHeading(headingType);
|
if (as === 'h1') {
|
||||||
|
return (
|
||||||
export default Heading;
|
<h1
|
||||||
|
{...props}
|
||||||
|
id={undefined} // h1 headings do not need an id because they don't appear in the TOC
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</h1>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return <AnchorHeading as={as} {...props} />;
|
||||||
|
}
|
||||||
|
|
|
@ -67,12 +67,12 @@ const MDXComponents: MDXComponentsObject = {
|
||||||
</Details>
|
</Details>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
h1: Heading('h1'),
|
h1: (props) => <Heading as="h1" {...props} />,
|
||||||
h2: Heading('h2'),
|
h2: (props) => <Heading as="h2" {...props} />,
|
||||||
h3: Heading('h3'),
|
h3: (props) => <Heading as="h3" {...props} />,
|
||||||
h4: Heading('h4'),
|
h4: (props) => <Heading as="h4" {...props} />,
|
||||||
h5: Heading('h5'),
|
h5: (props) => <Heading as="h5" {...props} />,
|
||||||
h6: Heading('h6'),
|
h6: (props) => <Heading as="h6" {...props} />,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MDXComponents;
|
export default MDXComponents;
|
||||||
|
|
|
@ -7,71 +7,15 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import Link from '@docusaurus/Link';
|
|
||||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
import NavbarNavLink from '@theme/NavbarItem/NavbarNavLink';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
NavLinkProps,
|
|
||||||
DesktopOrMobileNavBarItemProps,
|
DesktopOrMobileNavBarItemProps,
|
||||||
Props,
|
Props,
|
||||||
} from '@theme/NavbarItem/DefaultNavbarItem';
|
} from '@theme/NavbarItem/DefaultNavbarItem';
|
||||||
import IconExternalLink from '@theme/IconExternalLink';
|
|
||||||
import isInternalUrl from '@docusaurus/isInternalUrl';
|
|
||||||
import {isRegexpStringMatch} from '@docusaurus/theme-common';
|
|
||||||
import {getInfimaActiveClassName} from './index';
|
|
||||||
|
|
||||||
const dropdownLinkActiveClass = 'dropdown__link--active';
|
import {getInfimaActiveClassName} from '@theme/NavbarItem/utils';
|
||||||
|
|
||||||
export function NavLink({
|
|
||||||
activeBasePath,
|
|
||||||
activeBaseRegex,
|
|
||||||
to,
|
|
||||||
href,
|
|
||||||
label,
|
|
||||||
activeClassName = '',
|
|
||||||
prependBaseUrlToHref,
|
|
||||||
...props
|
|
||||||
}: NavLinkProps): JSX.Element {
|
|
||||||
// TODO all this seems hacky
|
|
||||||
// {to: 'version'} should probably be forbidden, in favor of {to: '/version'}
|
|
||||||
const toUrl = useBaseUrl(to);
|
|
||||||
const activeBaseUrl = useBaseUrl(activeBasePath);
|
|
||||||
const normalizedHref = useBaseUrl(href, {forcePrependBaseUrl: true});
|
|
||||||
const isExternalLink = label && href && !isInternalUrl(href);
|
|
||||||
const isDropdownLink = activeClassName === dropdownLinkActiveClass;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Link
|
|
||||||
{...(href
|
|
||||||
? {
|
|
||||||
href: prependBaseUrlToHref ? normalizedHref : href,
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
isNavLink: true,
|
|
||||||
activeClassName: !props.className?.includes(activeClassName)
|
|
||||||
? activeClassName
|
|
||||||
: '',
|
|
||||||
to: toUrl,
|
|
||||||
...(activeBasePath || activeBaseRegex
|
|
||||||
? {
|
|
||||||
isActive: (_match, location) =>
|
|
||||||
activeBaseRegex
|
|
||||||
? isRegexpStringMatch(activeBaseRegex, location.pathname)
|
|
||||||
: location.pathname.startsWith(activeBaseUrl),
|
|
||||||
}
|
|
||||||
: null),
|
|
||||||
})}
|
|
||||||
{...props}>
|
|
||||||
{isExternalLink ? (
|
|
||||||
<span>
|
|
||||||
{label}
|
|
||||||
<IconExternalLink {...(isDropdownLink && {width: 12, height: 12})} />
|
|
||||||
</span>
|
|
||||||
) : (
|
|
||||||
label
|
|
||||||
)}
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function DefaultNavbarItemDesktop({
|
function DefaultNavbarItemDesktop({
|
||||||
className,
|
className,
|
||||||
|
@ -79,7 +23,7 @@ function DefaultNavbarItemDesktop({
|
||||||
...props
|
...props
|
||||||
}: DesktopOrMobileNavBarItemProps) {
|
}: DesktopOrMobileNavBarItemProps) {
|
||||||
const element = (
|
const element = (
|
||||||
<NavLink
|
<NavbarNavLink
|
||||||
className={clsx(
|
className={clsx(
|
||||||
isDropdownItem ? 'dropdown__link' : 'navbar__item navbar__link',
|
isDropdownItem ? 'dropdown__link' : 'navbar__item navbar__link',
|
||||||
className,
|
className,
|
||||||
|
@ -102,7 +46,7 @@ function DefaultNavbarItemMobile({
|
||||||
}: DesktopOrMobileNavBarItemProps) {
|
}: DesktopOrMobileNavBarItemProps) {
|
||||||
return (
|
return (
|
||||||
<li className="menu__list-item">
|
<li className="menu__list-item">
|
||||||
<NavLink className={clsx('menu__link', className)} {...props} />
|
<NavbarNavLink className={clsx('menu__link', className)} {...props} />
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import React from 'react';
|
||||||
import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem';
|
import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem';
|
||||||
import {useLatestVersion, useActiveDocContext} from '@theme/hooks/useDocs';
|
import {useLatestVersion, useActiveDocContext} from '@theme/hooks/useDocs';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import {getInfimaActiveClassName} from './index';
|
import {getInfimaActiveClassName} from '@theme/NavbarItem/utils';
|
||||||
import type {Props} from '@theme/NavbarItem/DocNavbarItem';
|
import type {Props} from '@theme/NavbarItem/DocNavbarItem';
|
||||||
import {useDocsPreferredVersion, uniq} from '@docusaurus/theme-common';
|
import {useDocsPreferredVersion, uniq} from '@docusaurus/theme-common';
|
||||||
import type {GlobalDataVersion} from '@docusaurus/plugin-content-docs';
|
import type {GlobalDataVersion} from '@docusaurus/plugin-content-docs';
|
||||||
|
|
|
@ -9,9 +9,10 @@ import React from 'react';
|
||||||
import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem';
|
import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem';
|
||||||
import {useLatestVersion, useActiveDocContext} from '@theme/hooks/useDocs';
|
import {useLatestVersion, useActiveDocContext} from '@theme/hooks/useDocs';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import {getInfimaActiveClassName} from './index';
|
import {getInfimaActiveClassName} from '@theme/NavbarItem/utils';
|
||||||
import type {Props} from '@theme/NavbarItem/DocSidebarNavbarItem';
|
|
||||||
import {useDocsPreferredVersion, uniq} from '@docusaurus/theme-common';
|
import {useDocsPreferredVersion, uniq} from '@docusaurus/theme-common';
|
||||||
|
|
||||||
|
import type {Props} from '@theme/NavbarItem/DocSidebarNavbarItem';
|
||||||
import type {
|
import type {
|
||||||
GlobalDataVersion,
|
GlobalDataVersion,
|
||||||
GlobalDataSidebar,
|
GlobalDataSidebar,
|
||||||
|
|
|
@ -20,7 +20,7 @@ import type {
|
||||||
} from '@theme/NavbarItem/DropdownNavbarItem';
|
} from '@theme/NavbarItem/DropdownNavbarItem';
|
||||||
import type {LinkLikeNavbarItemProps} from '@theme/NavbarItem';
|
import type {LinkLikeNavbarItemProps} from '@theme/NavbarItem';
|
||||||
|
|
||||||
import {NavLink} from '@theme/NavbarItem/DefaultNavbarItem';
|
import NavbarNavLink from '@theme/NavbarItem/NavbarNavLink';
|
||||||
import NavbarItem from '@theme/NavbarItem';
|
import NavbarItem from '@theme/NavbarItem';
|
||||||
|
|
||||||
const dropdownLinkActiveClass = 'dropdown__link--active';
|
const dropdownLinkActiveClass = 'dropdown__link--active';
|
||||||
|
@ -84,7 +84,7 @@ function DropdownNavbarItemDesktop({
|
||||||
'dropdown--right': position === 'right',
|
'dropdown--right': position === 'right',
|
||||||
'dropdown--show': showDropdown,
|
'dropdown--show': showDropdown,
|
||||||
})}>
|
})}>
|
||||||
<NavLink
|
<NavbarNavLink
|
||||||
href={props.to ? undefined : '#'}
|
href={props.to ? undefined : '#'}
|
||||||
className={clsx('navbar__link', className)}
|
className={clsx('navbar__link', className)}
|
||||||
{...props}
|
{...props}
|
||||||
|
@ -96,7 +96,7 @@ function DropdownNavbarItemDesktop({
|
||||||
}
|
}
|
||||||
}}>
|
}}>
|
||||||
{props.children ?? props.label}
|
{props.children ?? props.label}
|
||||||
</NavLink>
|
</NavbarNavLink>
|
||||||
<ul className="dropdown__menu">
|
<ul className="dropdown__menu">
|
||||||
{items.map((childItemProps, i) => (
|
{items.map((childItemProps, i) => (
|
||||||
<NavbarItem
|
<NavbarItem
|
||||||
|
@ -146,7 +146,7 @@ function DropdownNavbarItemMobile({
|
||||||
className={clsx('menu__list-item', {
|
className={clsx('menu__list-item', {
|
||||||
'menu__list-item--collapsed': collapsed,
|
'menu__list-item--collapsed': collapsed,
|
||||||
})}>
|
})}>
|
||||||
<NavLink
|
<NavbarNavLink
|
||||||
role="button"
|
role="button"
|
||||||
className={clsx('menu__link menu__link--sublist', className)}
|
className={clsx('menu__link menu__link--sublist', className)}
|
||||||
{...props}
|
{...props}
|
||||||
|
@ -155,7 +155,7 @@ function DropdownNavbarItemMobile({
|
||||||
toggleCollapsed();
|
toggleCollapsed();
|
||||||
}}>
|
}}>
|
||||||
{props.children ?? props.label}
|
{props.children ?? props.label}
|
||||||
</NavLink>
|
</NavbarNavLink>
|
||||||
<Collapsible lazy as="ul" className="menu__list" collapsed={collapsed}>
|
<Collapsible lazy as="ul" className="menu__list" collapsed={collapsed}>
|
||||||
{items.map((childItemProps, i) => (
|
{items.map((childItemProps, i) => (
|
||||||
<NavbarItem
|
<NavbarItem
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import Link from '@docusaurus/Link';
|
||||||
|
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||||
|
import type {Props} from '@theme/NavbarItem/NavbarNavLink';
|
||||||
|
import IconExternalLink from '@theme/IconExternalLink';
|
||||||
|
import isInternalUrl from '@docusaurus/isInternalUrl';
|
||||||
|
import {isRegexpStringMatch} from '@docusaurus/theme-common';
|
||||||
|
|
||||||
|
const dropdownLinkActiveClass = 'dropdown__link--active';
|
||||||
|
|
||||||
|
export default function NavbarNavLink({
|
||||||
|
activeBasePath,
|
||||||
|
activeBaseRegex,
|
||||||
|
to,
|
||||||
|
href,
|
||||||
|
label,
|
||||||
|
activeClassName = '',
|
||||||
|
prependBaseUrlToHref,
|
||||||
|
...props
|
||||||
|
}: Props): JSX.Element {
|
||||||
|
// TODO all this seems hacky
|
||||||
|
// {to: 'version'} should probably be forbidden, in favor of {to: '/version'}
|
||||||
|
const toUrl = useBaseUrl(to);
|
||||||
|
const activeBaseUrl = useBaseUrl(activeBasePath);
|
||||||
|
const normalizedHref = useBaseUrl(href, {forcePrependBaseUrl: true});
|
||||||
|
const isExternalLink = label && href && !isInternalUrl(href);
|
||||||
|
const isDropdownLink = activeClassName === dropdownLinkActiveClass;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
{...(href
|
||||||
|
? {
|
||||||
|
href: prependBaseUrlToHref ? normalizedHref : href,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
isNavLink: true,
|
||||||
|
activeClassName: !props.className?.includes(activeClassName)
|
||||||
|
? activeClassName
|
||||||
|
: '',
|
||||||
|
to: toUrl,
|
||||||
|
...(activeBasePath || activeBaseRegex
|
||||||
|
? {
|
||||||
|
isActive: (_match, location) =>
|
||||||
|
activeBaseRegex
|
||||||
|
? isRegexpStringMatch(activeBaseRegex, location.pathname)
|
||||||
|
: location.pathname.startsWith(activeBaseUrl),
|
||||||
|
}
|
||||||
|
: null),
|
||||||
|
})}
|
||||||
|
{...props}>
|
||||||
|
{isExternalLink ? (
|
||||||
|
<span>
|
||||||
|
{label}
|
||||||
|
<IconExternalLink {...(isDropdownLink && {width: 12, height: 12})} />
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
label
|
||||||
|
)}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
|
@ -58,9 +58,6 @@ function getComponentType(
|
||||||
return type as NavbarItemComponentType;
|
return type as NavbarItemComponentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getInfimaActiveClassName = (mobile?: boolean): string =>
|
|
||||||
mobile ? 'menu__link--active' : 'navbar__link--active';
|
|
||||||
|
|
||||||
export default function NavbarItem({type, ...props}: Props): JSX.Element {
|
export default function NavbarItem({type, ...props}: Props): JSX.Element {
|
||||||
const componentType = getComponentType(
|
const componentType = getComponentType(
|
||||||
type,
|
type,
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// eslint-disable-next-line import/no-named-export
|
||||||
|
export const getInfimaActiveClassName = (mobile?: boolean): string =>
|
||||||
|
mobile ? 'menu__link--active' : 'navbar__link--active';
|
|
@ -8,4 +8,5 @@
|
||||||
// Re-expose useDocs
|
// Re-expose useDocs
|
||||||
// Ensure it's always statically available even if user is not using the docs plugin
|
// Ensure it's always statically available even if user is not using the docs plugin
|
||||||
// Problem reported for the blog-only mode: https://github.com/facebook/docusaurus/issues/3360
|
// Problem reported for the blog-only mode: https://github.com/facebook/docusaurus/issues/3360
|
||||||
|
// eslint-disable-next-line import/no-named-export
|
||||||
export * from '@docusaurus/plugin-content-docs/lib/theme/hooks/useDocs';
|
export * from '@docusaurus/plugin-content-docs/lib/theme/hooks/useDocs';
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue