mirror of
https://github.com/facebook/docusaurus.git
synced 2025-12-25 17:22:50 +00:00
fix(theme): Fix CSS `scroll-margin-top` when clicking footnote items, factorize code (#11466)
This commit is contained in:
parent
598af3b8e8
commit
ac630f8279
|
|
@ -8,18 +8,16 @@
|
|||
import React, {type ReactNode} from 'react';
|
||||
import clsx from 'clsx';
|
||||
import {translate} from '@docusaurus/Translate';
|
||||
import {useThemeConfig} from '@docusaurus/theme-common';
|
||||
import {useAnchorTargetClassName} from '@docusaurus/theme-common';
|
||||
import Link from '@docusaurus/Link';
|
||||
import useBrokenLinks from '@docusaurus/useBrokenLinks';
|
||||
import type {Props} from '@theme/Heading';
|
||||
|
||||
import styles from './styles.module.css';
|
||||
import './styles.module.css';
|
||||
|
||||
export default function Heading({as: As, id, ...props}: Props): ReactNode {
|
||||
const brokenLinks = useBrokenLinks();
|
||||
const {
|
||||
navbar: {hideOnScroll},
|
||||
} = useThemeConfig();
|
||||
const anchorTargetClassName = useAnchorTargetClassName(id);
|
||||
|
||||
// H1 headings do not need an id because they don't appear in the TOC.
|
||||
if (As === 'h1' || !id) {
|
||||
return <As {...props} id={undefined} />;
|
||||
|
|
@ -41,13 +39,7 @@ export default function Heading({as: As, id, ...props}: Props): ReactNode {
|
|||
return (
|
||||
<As
|
||||
{...props}
|
||||
className={clsx(
|
||||
'anchor',
|
||||
hideOnScroll
|
||||
? styles.anchorWithHideOnScrollNavbar
|
||||
: styles.anchorWithStickyNavbar,
|
||||
props.className,
|
||||
)}
|
||||
className={clsx('anchor', anchorTargetClassName, props.className)}
|
||||
id={id}>
|
||||
{props.children}
|
||||
<Link
|
||||
|
|
|
|||
|
|
@ -5,19 +5,6 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/*
|
||||
When the navbar is sticky, ensure that on anchor click,
|
||||
the browser does not scroll that anchor behind the navbar
|
||||
See https://x.com/JoshWComeau/status/1332015868725891076
|
||||
*/
|
||||
.anchorWithStickyNavbar {
|
||||
scroll-margin-top: calc(var(--ifm-navbar-height) + 0.5rem);
|
||||
}
|
||||
|
||||
.anchorWithHideOnScrollNavbar {
|
||||
scroll-margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
:global(.hash-link) {
|
||||
opacity: 0;
|
||||
padding-left: 0.5rem;
|
||||
|
|
|
|||
|
|
@ -8,35 +8,14 @@
|
|||
import React, {type ReactNode} from 'react';
|
||||
import clsx from 'clsx';
|
||||
import Link from '@docusaurus/Link';
|
||||
import {useThemeConfig} from '@docusaurus/theme-common';
|
||||
import {useAnchorTargetClassName} from '@docusaurus/theme-common';
|
||||
import type {Props} from '@theme/MDXComponents/A';
|
||||
import styles from './styles.module.css';
|
||||
|
||||
function isFootnoteRef(props: Props) {
|
||||
return props['data-footnote-ref'] === true;
|
||||
}
|
||||
|
||||
function FootnoteRefLink(props: Props) {
|
||||
const {
|
||||
navbar: {hideOnScroll},
|
||||
} = useThemeConfig();
|
||||
return (
|
||||
<Link
|
||||
{...props}
|
||||
className={clsx(
|
||||
hideOnScroll
|
||||
? styles.footnoteRefHideOnScrollNavbar
|
||||
: styles.footnoteRefStickyNavbar,
|
||||
|
||||
props.className,
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default function MDXA(props: Props): ReactNode {
|
||||
if (isFootnoteRef(props)) {
|
||||
return <FootnoteRefLink {...props} />;
|
||||
}
|
||||
return <Link {...props} />;
|
||||
// MDX Footnotes have ids such as <a id="user-content-fn-1-953011" ...>
|
||||
const anchorTargetClassName = useAnchorTargetClassName(props.id);
|
||||
|
||||
return (
|
||||
<Link {...props} className={clsx(anchorTargetClassName, props.className)} />
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
When the navbar is sticky, ensure that on footnote click,
|
||||
the browser does not scroll to the ref behind the navbar
|
||||
See https://github.com/facebook/docusaurus/issues/11232
|
||||
See also headings case https://x.com/JoshWComeau/status/1332015868725891076
|
||||
*/
|
||||
.footnoteRefStickyNavbar {
|
||||
scroll-margin-top: calc(var(--ifm-navbar-height) + 0.5rem);
|
||||
}
|
||||
|
||||
.footnoteRefHideOnScrollNavbar {
|
||||
scroll-margin-top: 0.5rem;
|
||||
}
|
||||
|
|
@ -6,12 +6,17 @@
|
|||
*/
|
||||
|
||||
import React, {type ReactNode} from 'react';
|
||||
import clsx from 'clsx';
|
||||
import useBrokenLinks from '@docusaurus/useBrokenLinks';
|
||||
import {useAnchorTargetClassName} from '@docusaurus/theme-common';
|
||||
import type {Props} from '@theme/MDXComponents/Li';
|
||||
|
||||
export default function MDXLi(props: Props): ReactNode | undefined {
|
||||
// MDX Footnotes have ids such as <li id="user-content-fn-1-953011">
|
||||
useBrokenLinks().collectAnchor(props.id);
|
||||
const anchorTargetClassName = useAnchorTargetClassName(props.id);
|
||||
|
||||
return <li {...props} />;
|
||||
return (
|
||||
<li className={clsx(anchorTargetClassName, props.className)} {...props} />
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,6 +109,8 @@ export {
|
|||
useSearchLinkCreator,
|
||||
} from './hooks/useSearchPage';
|
||||
|
||||
export {useAnchorTargetClassName} from './utils/anchorUtils';
|
||||
|
||||
export {isMultiColumnFooterLinks} from './utils/footerUtils';
|
||||
|
||||
export {isRegexpStringMatch} from './utils/regexpUtils';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.anchorTargetStickyNavbar {
|
||||
scroll-margin-top: calc(var(--ifm-navbar-height) + 0.5rem);
|
||||
}
|
||||
|
||||
.anchorTargetHideOnScrollNavbar {
|
||||
scroll-margin-top: 0.5rem;
|
||||
}
|
||||
|
|
@ -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 {useThemeConfig} from './useThemeConfig';
|
||||
import styles from './anchorUtils.module.css';
|
||||
|
||||
/**
|
||||
* When the navbar is sticky, this ensures that when clicking a hash link,
|
||||
* we do not navigate to an anchor that will appear below the navbar.
|
||||
* This happens in particular for MDX headings and footnotes.
|
||||
*
|
||||
* See https://github.com/facebook/docusaurus/issues/11232
|
||||
* See also headings case https://x.com/JoshWComeau/status/1332015868725891076
|
||||
*/
|
||||
export function useAnchorTargetClassName(
|
||||
id: string | undefined,
|
||||
): string | undefined {
|
||||
const {
|
||||
navbar: {hideOnScroll},
|
||||
} = useThemeConfig();
|
||||
if (typeof id === 'undefined') {
|
||||
return undefined;
|
||||
}
|
||||
return hideOnScroll
|
||||
? styles.anchorTargetHideOnScrollNavbar
|
||||
: styles.anchorTargetStickyNavbar;
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
# Footnotes
|
||||
|
||||
Lorem ipsum dolor sit amet [^1] [^2]
|
||||
|
||||
Lorem ipsum dolor sit amet [^3]
|
||||
|
||||
Lorem ipsum dolor sit amet [^4]
|
||||
|
||||
Lorem ipsum dolor sit amet [^5]
|
||||
|
||||
Lorem ipsum dolor sit amet [^6]
|
||||
|
||||
Lorem ipsum dolor sit amet [^7]
|
||||
|
||||
Lorem ipsum dolor sit amet [^8]
|
||||
|
||||
Lorem ipsum dolor sit amet [^9]
|
||||
|
||||
Lorem ipsum dolor sit amet [^10]
|
||||
|
||||
Lorem ipsum dolor sit amet [^11]
|
||||
|
||||
Lorem ipsum dolor sit amet [^12]
|
||||
|
||||
Lorem ipsum dolor sit amet [^13]
|
||||
|
||||
Lorem ipsum dolor sit amet [^14]
|
||||
|
||||
Lorem ipsum dolor sit amet [^15]
|
||||
|
||||
Lorem ipsum dolor sit amet [^16]
|
||||
|
||||
Lorem ipsum dolor sit amet [^17]
|
||||
|
||||
Lorem ipsum dolor sit amet [^18]
|
||||
|
||||
Lorem ipsum dolor sit amet [^19]
|
||||
|
||||
Lorem ipsum dolor sit amet [^20]
|
||||
|
||||
Lorem ipsum dolor sit amet [^21] [^22]
|
||||
|
||||
Lorem ipsum dolor sit amet [^23]
|
||||
|
||||
Lorem ipsum dolor sit amet [^24]
|
||||
|
||||
Lorem ipsum dolor sit amet [^25]
|
||||
|
||||
Lorem ipsum dolor sit amet [^26]
|
||||
|
||||
Lorem ipsum dolor sit amet [^27]
|
||||
|
||||
Lorem ipsum dolor sit amet [^28]
|
||||
|
||||
Lorem ipsum dolor sit amet [^29]
|
||||
|
||||
Lorem ipsum dolor sit amet [^30]
|
||||
|
||||
Lorem ipsum dolor sit amet [^31]
|
||||
|
||||
Lorem ipsum dolor sit amet [^32]
|
||||
|
||||
Lorem ipsum dolor sit amet [^33]
|
||||
|
||||
Lorem ipsum dolor sit amet [^34]
|
||||
|
||||
Lorem ipsum dolor sit amet [^35]
|
||||
|
||||
Lorem ipsum dolor sit amet [^36]
|
||||
|
||||
Lorem ipsum dolor sit amet [^37]
|
||||
|
||||
Lorem ipsum dolor sit amet [^38]
|
||||
|
||||
Lorem ipsum dolor sit amet [^39]
|
||||
|
||||
Lorem ipsum dolor sit amet [^40]
|
||||
|
||||
Lorem ipsum dolor sit amet [^41]
|
||||
|
||||
Lorem ipsum dolor sit amet [^42]
|
||||
|
||||
Lorem ipsum dolor sit amet [^43]
|
||||
|
||||
Lorem ipsum dolor sit amet [^44]
|
||||
|
||||
Lorem ipsum dolor sit amet [^45]
|
||||
|
||||
Lorem ipsum dolor sit amet [^46]
|
||||
|
||||
Lorem ipsum dolor sit amet [^47]
|
||||
|
||||
Lorem ipsum dolor sit amet [^48]
|
||||
|
||||
Lorem ipsum dolor sit amet [^49] [^50]
|
||||
|
||||
[^1]: footnote 1
|
||||
[^2]: footnote 2
|
||||
[^3]: footnote 3
|
||||
[^4]: footnote 4
|
||||
[^5]: footnote 5
|
||||
[^6]: footnote 6
|
||||
[^7]: footnote 7
|
||||
[^8]: footnote 8
|
||||
[^9]: footnote 9
|
||||
[^10]: footnote 10
|
||||
[^11]: footnote 11
|
||||
[^12]: footnote 12
|
||||
[^13]: footnote 13
|
||||
[^14]: footnote 14
|
||||
[^15]: footnote 15
|
||||
[^16]: footnote 16
|
||||
[^17]: footnote 17
|
||||
[^18]: footnote 18
|
||||
[^19]: footnote 19
|
||||
[^20]: footnote 20
|
||||
[^21]: footnote 21
|
||||
[^22]: footnote 22
|
||||
[^23]: footnote 23
|
||||
[^24]: footnote 24
|
||||
[^25]: footnote 25
|
||||
[^26]: footnote 26
|
||||
[^27]: footnote 27
|
||||
[^28]: footnote 28
|
||||
[^29]: footnote 29
|
||||
[^30]: footnote 30
|
||||
[^31]: footnote 31
|
||||
[^32]: footnote 32
|
||||
[^33]: footnote 33
|
||||
[^34]: footnote 34
|
||||
[^35]: footnote 35
|
||||
[^36]: footnote 36
|
||||
[^37]: footnote 37
|
||||
[^38]: footnote 38
|
||||
[^39]: footnote 39
|
||||
[^40]: footnote 40
|
||||
[^41]: footnote 41
|
||||
[^42]: footnote 42
|
||||
[^43]: footnote 43
|
||||
[^44]: footnote 44
|
||||
[^45]: footnote 45
|
||||
[^46]: footnote 46
|
||||
[^47]: footnote 47
|
||||
[^48]: footnote 48
|
||||
[^49]: footnote 49
|
||||
[^50]: footnote 50
|
||||
Loading…
Reference in New Issue