mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-22 04:28:10 +02:00
refactor(theme-classic): multiple re-arrangements (#7273)
* refactor(theme-classic): enforce collocated JSX and module CSS * refactor
This commit is contained in:
parent
355a22907d
commit
710f898703
9 changed files with 40 additions and 25 deletions
|
@ -10,7 +10,7 @@ import React from 'react';
|
||||||
import {useDocsSidebar} from '@docusaurus/theme-common';
|
import {useDocsSidebar} from '@docusaurus/theme-common';
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import styles from './Main.module.css';
|
import styles from './styles.module.css';
|
||||||
import type {Props} from '@theme/DocPage/Layout/Main';
|
import type {Props} from '@theme/DocPage/Layout/Main';
|
||||||
|
|
||||||
export default function DocPageLayoutMain({
|
export default function DocPageLayoutMain({
|
|
@ -10,7 +10,7 @@ import IconArrow from '@theme/IconArrow';
|
||||||
import {translate} from '@docusaurus/Translate';
|
import {translate} from '@docusaurus/Translate';
|
||||||
import type {Props} from '@theme/DocPage/Layout/Sidebar/ExpandButton';
|
import type {Props} from '@theme/DocPage/Layout/Sidebar/ExpandButton';
|
||||||
|
|
||||||
import styles from './ExpandButton.module.css';
|
import styles from './styles.module.css';
|
||||||
|
|
||||||
export default function DocPageLayoutSidebarExpandButton({
|
export default function DocPageLayoutSidebarExpandButton({
|
||||||
toggleSidebar,
|
toggleSidebar,
|
|
@ -9,7 +9,6 @@ import React from 'react';
|
||||||
import type {Props} from '@theme/TOCItems/Tree';
|
import type {Props} from '@theme/TOCItems/Tree';
|
||||||
|
|
||||||
// Recursive component rendering the toc tree
|
// Recursive component rendering the toc tree
|
||||||
/* eslint-disable jsx-a11y/control-has-associated-label */
|
|
||||||
function TOCItemTree({
|
function TOCItemTree({
|
||||||
toc,
|
toc,
|
||||||
className,
|
className,
|
||||||
|
@ -23,6 +22,7 @@ function TOCItemTree({
|
||||||
<ul className={isChild ? undefined : className}>
|
<ul className={isChild ? undefined : className}>
|
||||||
{toc.map((heading) => (
|
{toc.map((heading) => (
|
||||||
<li key={heading.id}>
|
<li key={heading.id}>
|
||||||
|
{/* eslint-disable-next-line jsx-a11y/control-has-associated-label */}
|
||||||
<a
|
<a
|
||||||
href={`#${heading.id}`}
|
href={`#${heading.id}`}
|
||||||
className={linkClassName ?? undefined}
|
className={linkClassName ?? undefined}
|
||||||
|
|
|
@ -32,13 +32,7 @@ export function DocsSidebarProvider({
|
||||||
items: PropSidebar | undefined;
|
items: PropSidebar | undefined;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const stableValue: ContextValue | null = useMemo(
|
const stableValue: ContextValue | null = useMemo(
|
||||||
() =>
|
() => (name && items ? {name, items} : null),
|
||||||
name && items
|
|
||||||
? {
|
|
||||||
name,
|
|
||||||
items,
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
[name, items],
|
[name, items],
|
||||||
);
|
);
|
||||||
return <Context.Provider value={stableValue}>{children}</Context.Provider>;
|
return <Context.Provider value={stableValue}>{children}</Context.Provider>;
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
import {useCallback, useRef} from 'react';
|
import {useCallback, useRef} from 'react';
|
||||||
import {useHistory} from '@docusaurus/router';
|
import {useHistory} from '@docusaurus/router';
|
||||||
import {useLocationChange} from './useLocationChange';
|
import {useLocationChange} from '../utils/useLocationChange';
|
||||||
import {ThemeClassNames} from './ThemeClassNames';
|
import {ThemeClassNames} from '../utils/ThemeClassNames';
|
||||||
|
|
||||||
function programmaticFocus(el: HTMLElement) {
|
function programmaticFocus(el: HTMLElement) {
|
||||||
el.setAttribute('tabindex', '-1');
|
el.setAttribute('tabindex', '-1');
|
||||||
|
@ -17,8 +17,21 @@ function programmaticFocus(el: HTMLElement) {
|
||||||
el.removeAttribute('tabindex');
|
el.removeAttribute('tabindex');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** This hook wires the logic for a skip-to-content link. */
|
||||||
export function useSkipToContent(): {
|
export function useSkipToContent(): {
|
||||||
|
/**
|
||||||
|
* The ref to the container. On page transition, the container will be focused
|
||||||
|
* so that keyboard navigators can instantly interact with the link and jump
|
||||||
|
* to content. **Note:** the type is `RefObject<HTMLDivElement>` only because
|
||||||
|
* the typing for refs don't reflect that the `ref` prop is contravariant, so
|
||||||
|
* using `HTMLElement` causes type-checking to fail. You can plug the ref into
|
||||||
|
* any HTML element, as long as it can be focused.
|
||||||
|
*/
|
||||||
containerRef: React.RefObject<HTMLDivElement>;
|
containerRef: React.RefObject<HTMLDivElement>;
|
||||||
|
/**
|
||||||
|
* Callback fired when the skip to content link has been interacted with. It
|
||||||
|
* will programmatically focus the main content.
|
||||||
|
*/
|
||||||
handleSkip: (e: React.MouseEvent<HTMLAnchorElement>) => void;
|
handleSkip: (e: React.MouseEvent<HTMLAnchorElement>) => void;
|
||||||
} {
|
} {
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
@ -58,8 +58,6 @@ export {
|
||||||
useDocRouteMetadata,
|
useDocRouteMetadata,
|
||||||
} from './utils/docsUtils';
|
} from './utils/docsUtils';
|
||||||
|
|
||||||
export {useSkipToContent} from './utils/a11yUtils';
|
|
||||||
|
|
||||||
export {useTitleFormatter} from './utils/generalUtils';
|
export {useTitleFormatter} from './utils/generalUtils';
|
||||||
|
|
||||||
export {usePluralForm} from './utils/usePluralForm';
|
export {usePluralForm} from './utils/usePluralForm';
|
||||||
|
@ -162,3 +160,4 @@ export {useLockBodyScroll} from './hooks/useLockBodyScroll';
|
||||||
export {useWindowSize} from './hooks/useWindowSize';
|
export {useWindowSize} from './hooks/useWindowSize';
|
||||||
export {useSearchPage} from './hooks/useSearchPage';
|
export {useSearchPage} from './hooks/useSearchPage';
|
||||||
export {useCodeWordWrap} from './hooks/useCodeWordWrap';
|
export {useCodeWordWrap} from './hooks/useCodeWordWrap';
|
||||||
|
export {useSkipToContent} from './hooks/useSkipToContent';
|
||||||
|
|
|
@ -20,9 +20,9 @@ import type {
|
||||||
PropSidebarItem,
|
PropSidebarItem,
|
||||||
PropSidebarItemCategory,
|
PropSidebarItemCategory,
|
||||||
PropVersionDoc,
|
PropVersionDoc,
|
||||||
PropVersionMetadata,
|
|
||||||
PropSidebarBreadcrumbsItem,
|
PropSidebarBreadcrumbsItem,
|
||||||
} from '@docusaurus/plugin-content-docs';
|
} from '@docusaurus/plugin-content-docs';
|
||||||
|
import type {Props as DocPageProps} from '@theme/DocPage';
|
||||||
import {useDocsPreferredVersion} from '../contexts/docsPreferredVersion';
|
import {useDocsPreferredVersion} from '../contexts/docsPreferredVersion';
|
||||||
import {useDocsVersion} from '../contexts/docsVersion';
|
import {useDocsVersion} from '../contexts/docsVersion';
|
||||||
import {useDocsSidebar} from '../contexts/docsSidebar';
|
import {useDocsSidebar} from '../contexts/docsSidebar';
|
||||||
|
@ -30,7 +30,6 @@ import {uniq} from './jsUtils';
|
||||||
import {isSamePath} from './routesUtils';
|
import {isSamePath} from './routesUtils';
|
||||||
import {matchPath, useLocation} from '@docusaurus/router';
|
import {matchPath, useLocation} from '@docusaurus/router';
|
||||||
import renderRoutes from '@docusaurus/renderRoutes';
|
import renderRoutes from '@docusaurus/renderRoutes';
|
||||||
import type {RouteConfig} from 'react-router-config';
|
|
||||||
|
|
||||||
// TODO not ideal, see also "useDocs"
|
// TODO not ideal, see also "useDocs"
|
||||||
export const isDocsPluginEnabled: boolean = !!useAllDocsData;
|
export const isDocsPluginEnabled: boolean = !!useAllDocsData;
|
||||||
|
@ -286,20 +285,32 @@ Available doc ids are:
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO later read version/route directly from context
|
// TODO later read version/route directly from context
|
||||||
|
/**
|
||||||
|
* The docs plugin creates nested routes, with the top-level route providing the
|
||||||
|
* version metadata, and the subroutes creating individual doc pages. This hook
|
||||||
|
* will match the current location against all known sub-routes.
|
||||||
|
*
|
||||||
|
* @param props The props received by `@theme/DocPage`
|
||||||
|
* @returns The data of the relevant document at the current location, or `null`
|
||||||
|
* if no document associated with the current location can be found.
|
||||||
|
*/
|
||||||
export function useDocRouteMetadata({
|
export function useDocRouteMetadata({
|
||||||
route,
|
route,
|
||||||
versionMetadata,
|
versionMetadata,
|
||||||
}: {
|
}: DocPageProps): null | {
|
||||||
route: RouteConfig;
|
/** The element that should be rendered at the current location. */
|
||||||
versionMetadata: PropVersionMetadata;
|
|
||||||
}): null | {
|
|
||||||
docElement: JSX.Element;
|
docElement: JSX.Element;
|
||||||
|
/**
|
||||||
|
* The name of the sidebar associated with the current doc. `sidebarName` and
|
||||||
|
* `sidebarItems` correspond to the value of {@link useDocsSidebar}.
|
||||||
|
*/
|
||||||
sidebarName: string | undefined;
|
sidebarName: string | undefined;
|
||||||
|
/** The items of the sidebar associated with the current doc. */
|
||||||
sidebarItems: PropSidebar | undefined;
|
sidebarItems: PropSidebar | undefined;
|
||||||
} {
|
} {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const docRoutes = route.routes;
|
const docRoutes = route.routes!;
|
||||||
const currentDocRoute = docRoutes!.find((docRoute) =>
|
const currentDocRoute = docRoutes.find((docRoute) =>
|
||||||
matchPath(location.pathname, docRoute),
|
matchPath(location.pathname, docRoute),
|
||||||
);
|
);
|
||||||
if (!currentDocRoute) {
|
if (!currentDocRoute) {
|
||||||
|
@ -313,9 +324,7 @@ export function useDocRouteMetadata({
|
||||||
? versionMetadata.docsSidebars[sidebarName]
|
? versionMetadata.docsSidebars[sidebarName]
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const docElement = renderRoutes(route.routes!, {
|
const docElement = renderRoutes(docRoutes, {versionMetadata});
|
||||||
versionMetadata,
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
docElement,
|
docElement,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue