mirror of
https://github.com/facebook/docusaurus.git
synced 2025-08-04 09:19:16 +02:00
refactor: fix more type-aware linting errors (#7479)
This commit is contained in:
parent
bf1513a3e3
commit
624735bd92
51 changed files with 192 additions and 189 deletions
|
@ -19,8 +19,9 @@ import type webpack from 'webpack';
|
|||
const requireFromDocusaurusCore = createRequire(
|
||||
require.resolve('@docusaurus/core/package.json'),
|
||||
);
|
||||
const ContextReplacementPlugin: typeof webpack.ContextReplacementPlugin =
|
||||
requireFromDocusaurusCore('webpack/lib/ContextReplacementPlugin');
|
||||
const ContextReplacementPlugin = requireFromDocusaurusCore(
|
||||
'webpack/lib/ContextReplacementPlugin',
|
||||
) as typeof webpack.ContextReplacementPlugin;
|
||||
|
||||
// Need to be inlined to prevent dark mode FOUC
|
||||
// Make sure the key is the same as the one in `/theme/hooks/useTheme.js`
|
||||
|
|
|
@ -816,7 +816,6 @@ declare module '@theme/NavbarItem/NavbarNavLink' {
|
|||
|
||||
declare module '@theme/NavbarItem/DropdownNavbarItem' {
|
||||
import type {Props as NavbarNavLinkProps} from '@theme/NavbarItem/NavbarNavLink';
|
||||
|
||||
import type {LinkLikeNavbarItemProps} from '@theme/NavbarItem';
|
||||
|
||||
export type DesktopOrMobileNavBarItemProps = NavbarNavLinkProps & {
|
||||
|
@ -976,7 +975,7 @@ declare module '@theme/NavbarItem' {
|
|||
} & SearchNavbarItemProps)
|
||||
);
|
||||
|
||||
export type Types = Props['type'];
|
||||
export type NavbarItemType = Props['type'];
|
||||
|
||||
export default function NavbarItem(props: Props): JSX.Element;
|
||||
}
|
||||
|
|
|
@ -10,11 +10,13 @@ import Details from '@theme/Details';
|
|||
import type {Props} from '@theme/MDXComponents/Details';
|
||||
|
||||
export default function MDXDetails(props: Props): JSX.Element {
|
||||
const items = React.Children.toArray(props.children) as ReactElement[];
|
||||
const items = React.Children.toArray(props.children);
|
||||
// Split summary item from the rest to pass it as a separate prop to the
|
||||
// Details theme component
|
||||
const summary: ReactElement<ComponentProps<'summary'>> | undefined =
|
||||
items.find((item) => item?.props?.mdxType === 'summary');
|
||||
const summary = items.find(
|
||||
(item): item is ReactElement<ComponentProps<'summary'>> =>
|
||||
React.isValidElement(item) && item.props?.mdxType === 'summary',
|
||||
);
|
||||
const children = <>{items.filter((item) => item !== summary)}</>;
|
||||
|
||||
return (
|
||||
|
|
|
@ -11,8 +11,10 @@ import type {Props} from '@theme/MDXComponents/Head';
|
|||
|
||||
// MDX elements are wrapped through the MDX pragma. In some cases (notably usage
|
||||
// with Head/Helmet) we need to unwrap those elements.
|
||||
function unwrapMDXElement(element: ReactElement) {
|
||||
if (element?.props?.mdxType && element?.props?.originalType) {
|
||||
function unwrapMDXElement(
|
||||
element: ReactElement<{mdxType?: string; originalType?: string} | undefined>,
|
||||
) {
|
||||
if (element.props?.mdxType && element.props.originalType) {
|
||||
const {mdxType, originalType, ...newProps} = element.props;
|
||||
return React.createElement(element.props.originalType, newProps);
|
||||
}
|
||||
|
@ -21,7 +23,7 @@ function unwrapMDXElement(element: ReactElement) {
|
|||
|
||||
export default function MDXHead(props: Props): JSX.Element {
|
||||
const unwrappedChildren = React.Children.map(props.children, (child) =>
|
||||
unwrapMDXElement(child as ReactElement),
|
||||
React.isValidElement(child) ? unwrapMDXElement(child) : child,
|
||||
);
|
||||
return (
|
||||
<Head {...(props as ComponentProps<typeof Head>)}>{unwrappedChildren}</Head>
|
||||
|
|
|
@ -14,8 +14,8 @@ export default function MDXPre(props: Props): JSX.Element {
|
|||
<CodeBlock
|
||||
// If this pre is created by a ``` fenced codeblock, unwrap the children
|
||||
{...(isValidElement(props.children) &&
|
||||
props.children.props.originalType === 'code'
|
||||
? props.children?.props
|
||||
props.children.props?.originalType === 'code'
|
||||
? props.children.props
|
||||
: {...props})}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -11,13 +11,12 @@ import {
|
|||
useNavbarMobileSidebar,
|
||||
useThemeConfig,
|
||||
} from '@docusaurus/theme-common';
|
||||
import NavbarItem from '@theme/NavbarItem';
|
||||
import NavbarItem, {type Props as NavbarItemConfig} from '@theme/NavbarItem';
|
||||
import NavbarColorModeToggle from '@theme/Navbar/ColorModeToggle';
|
||||
import SearchBar from '@theme/SearchBar';
|
||||
import NavbarMobileSidebarToggle from '@theme/Navbar/MobileSidebar/Toggle';
|
||||
import NavbarLogo from '@theme/Navbar/Logo';
|
||||
import NavbarSearch from '@theme/Navbar/Search';
|
||||
import type {Props as NavbarItemConfig} from '@theme/NavbarItem';
|
||||
|
||||
import styles from './styles.module.css';
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import {useNavbarMobileSidebar, useThemeConfig} from '@docusaurus/theme-common';
|
||||
import NavbarItem from '@theme/NavbarItem';
|
||||
import type {Props as NavbarItemConfig} from '@theme/NavbarItem';
|
||||
import NavbarItem, {type Props as NavbarItemConfig} from '@theme/NavbarItem';
|
||||
|
||||
function useNavbarItems() {
|
||||
// TODO temporary casting until ThemeConfig type is improved
|
||||
|
|
|
@ -38,13 +38,13 @@ export default function DocsVersionDropdownNavbarItem({
|
|||
// We try to link to the same doc, in another version
|
||||
// When not possible, fallback to the "main doc" of the version
|
||||
const versionDoc =
|
||||
activeDocContext?.alternateDocVersions[version.name] ??
|
||||
activeDocContext.alternateDocVersions[version.name] ??
|
||||
getVersionMainDoc(version);
|
||||
return {
|
||||
isNavLink: true,
|
||||
label: version.label,
|
||||
to: versionDoc.path,
|
||||
isActive: () => version === activeDocContext?.activeVersion,
|
||||
isActive: () => version === activeDocContext.activeVersion,
|
||||
onClick: () => savePreferredVersionName(version.name),
|
||||
};
|
||||
});
|
||||
|
|
|
@ -15,12 +15,11 @@ import {
|
|||
useLocalPathname,
|
||||
} from '@docusaurus/theme-common';
|
||||
import NavbarNavLink from '@theme/NavbarItem/NavbarNavLink';
|
||||
import NavbarItem from '@theme/NavbarItem';
|
||||
import NavbarItem, {type LinkLikeNavbarItemProps} from '@theme/NavbarItem';
|
||||
import type {
|
||||
DesktopOrMobileNavBarItemProps,
|
||||
Props,
|
||||
} from '@theme/NavbarItem/DropdownNavbarItem';
|
||||
import type {LinkLikeNavbarItemProps} from '@theme/NavbarItem';
|
||||
|
||||
const dropdownLinkActiveClass = 'dropdown__link--active';
|
||||
|
||||
|
|
|
@ -7,31 +7,22 @@
|
|||
|
||||
import React from 'react';
|
||||
import ComponentTypes from '@theme/NavbarItem/ComponentTypes';
|
||||
import {type Props as DropdownNavbarItemProps} from '@theme/NavbarItem/DropdownNavbarItem';
|
||||
import type {Types, Props} from '@theme/NavbarItem';
|
||||
import type {NavbarItemType, Props} from '@theme/NavbarItem';
|
||||
|
||||
const getNavbarItemComponent = (type: NonNullable<Types>) => {
|
||||
const component = ComponentTypes[type];
|
||||
if (!component) {
|
||||
throw new Error(`No NavbarItem component found for type "${type}".`);
|
||||
}
|
||||
return component;
|
||||
};
|
||||
|
||||
function getComponentType(type: Types, isDropdown: boolean) {
|
||||
function normalizeComponentType(type: NavbarItemType, props: object) {
|
||||
// Backward compatibility: navbar item with no type set
|
||||
// but containing dropdown items should use the type "dropdown"
|
||||
if (!type || type === 'default') {
|
||||
return isDropdown ? 'dropdown' : 'default';
|
||||
return 'items' in props ? 'dropdown' : 'default';
|
||||
}
|
||||
return type as NonNullable<Types>;
|
||||
return type;
|
||||
}
|
||||
|
||||
export default function NavbarItem({type, ...props}: Props): JSX.Element {
|
||||
const componentType = getComponentType(
|
||||
type,
|
||||
(props as DropdownNavbarItemProps).items !== undefined,
|
||||
);
|
||||
const NavbarItemComponent = getNavbarItemComponent(componentType);
|
||||
const componentType = normalizeComponentType(type, props);
|
||||
const NavbarItemComponent = ComponentTypes[componentType];
|
||||
if (!NavbarItemComponent) {
|
||||
throw new Error(`No NavbarItem component found for type "${type}".`);
|
||||
}
|
||||
return <NavbarItemComponent {...(props as never)} />;
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ function TabsComponent(props: Props): JSX.Element {
|
|||
? defaultValueProp
|
||||
: defaultValueProp ??
|
||||
children.find((child) => child.props.default)?.props.value ??
|
||||
children[0]?.props.value;
|
||||
children[0]!.props.value;
|
||||
if (defaultValue !== null && !values.some((a) => a.value === defaultValue)) {
|
||||
throw new Error(
|
||||
`Docusaurus error: The <Tabs> has a defaultValue "${defaultValue}" but none of its children has the corresponding value. Available values are: ${values
|
||||
|
@ -126,12 +126,12 @@ function TabsComponent(props: Props): JSX.Element {
|
|||
switch (event.key) {
|
||||
case 'ArrowRight': {
|
||||
const nextTab = tabRefs.indexOf(event.currentTarget) + 1;
|
||||
focusElement = tabRefs[nextTab] || tabRefs[0]!;
|
||||
focusElement = tabRefs[nextTab] ?? tabRefs[0]!;
|
||||
break;
|
||||
}
|
||||
case 'ArrowLeft': {
|
||||
const prevTab = tabRefs.indexOf(event.currentTarget) - 1;
|
||||
focusElement = tabRefs[prevTab] || tabRefs[tabRefs.length - 1]!;
|
||||
focusElement = tabRefs[prevTab] ?? tabRefs[tabRefs.length - 1]!;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue