Skip to content

Commit 7ab10b8

Browse files
committed
Move copy-page button to footer, inline with 'Edit this page'
Per maintainer feedback (#4499): swizzle DocItem/Footer and render <CopyPageButton /> as a peer link next to EditThisPage in the edit-meta row (reads 'Edit this page | Copy page'), styled to match the edit link (no border, same font size/weight/color via customStyles). The row now renders on every doc page, not only ones with a TOC. Reverts the earlier TOC and DocItem/Layout additions and their CSS modules — the footer override replaces both. Follows house swizzle conventions (source-link doc comment + // CUSTOM CODE markers).
1 parent a6ac0f8 commit 7ab10b8

6 files changed

Lines changed: 144 additions & 62 deletions

File tree

src/theme/DocItem/Footer/index.tsx

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/**
2+
* DocItemFooter renders the footer of a doc page — the tags row and the
3+
* edit-meta row ("Edit this page" + last updated).
4+
*
5+
* Original source:
6+
* @link https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-theme-classic/src/theme/DocItem/Footer/index.tsx
7+
*
8+
* Reason for overriding:
9+
* - Render the "Copy page" button (docusaurus-plugin-copy-page-button) inline
10+
* with the "Edit this page" link, styled as a peer link rather than a
11+
* standalone button. Always show the edit-meta row so it appears on every
12+
* doc page, not only pages that have edit/last-updated metadata.
13+
*/
14+
15+
import React from 'react';
16+
import clsx from 'clsx';
17+
import {ThemeClassNames} from '@docusaurus/theme-common';
18+
import {useDoc} from '@docusaurus/plugin-content-docs/client';
19+
import TagsListInline from '@theme/TagsListInline';
20+
import EditThisPage from '@theme/EditThisPage';
21+
import LastUpdated from '@theme/LastUpdated';
22+
23+
// CUSTOM CODE
24+
import CopyPageButton from 'docusaurus-plugin-copy-page-button/react';
25+
import styles from './styles.module.css';
26+
// CUSTOM CODE END
27+
28+
export default function DocItemFooter(): JSX.Element | null {
29+
const {metadata} = useDoc();
30+
const {editUrl, lastUpdatedAt, lastUpdatedBy, tags} = metadata;
31+
32+
const canDisplayTagsRow = tags.length > 0;
33+
// CUSTOM CODE
34+
// Always render the edit-meta row so the "Copy page" button shows on every
35+
// doc page, even ones without an edit URL or last-updated metadata.
36+
const canDisplayEditMetaRow = true;
37+
// CUSTOM CODE END
38+
const canDisplayFooter = canDisplayTagsRow || canDisplayEditMetaRow;
39+
40+
if (!canDisplayFooter) {
41+
return null;
42+
}
43+
44+
return (
45+
<footer
46+
className={clsx(ThemeClassNames.docs.docFooter, 'docusaurus-mt-lg')}>
47+
{canDisplayTagsRow && (
48+
<div
49+
className={clsx(
50+
'row margin-top--sm',
51+
ThemeClassNames.docs.docFooterTagsRow,
52+
)}>
53+
<div className="col">
54+
<TagsListInline tags={tags} />
55+
</div>
56+
</div>
57+
)}
58+
{canDisplayEditMetaRow && (
59+
<div
60+
className={clsx(
61+
'row margin-top--sm',
62+
ThemeClassNames.docs.docFooterEditMetaRow,
63+
)}>
64+
<div className="col">
65+
{/* CUSTOM CODE — "Edit this page | Copy page" as peer links on one row */}
66+
<div className={styles.editMetaActions}>
67+
{editUrl && <EditThisPage editUrl={editUrl} />}
68+
<CopyPageButton
69+
customStyles={{
70+
container: {className: styles.copyPageContainer},
71+
button: {className: styles.copyPageButton},
72+
}}
73+
/>
74+
</div>
75+
{/* CUSTOM CODE END */}
76+
</div>
77+
<div className={clsx('col', styles.lastUpdatedCol)}>
78+
{(lastUpdatedAt || lastUpdatedBy) && (
79+
<LastUpdated
80+
lastUpdatedAt={lastUpdatedAt}
81+
lastUpdatedBy={lastUpdatedBy}
82+
/>
83+
)}
84+
</div>
85+
</div>
86+
)}
87+
</footer>
88+
);
89+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* Styles for the swizzled DocItem/Footer.
3+
* Renders the "Copy page" button as a peer link to "Edit this page".
4+
*/
5+
6+
.editMetaActions {
7+
display: inline-flex;
8+
align-items: center;
9+
flex-wrap: wrap;
10+
}
11+
12+
/* Divider between "Edit this page" and "Copy page" — only when both render */
13+
.editMetaActions > :not(:first-child) {
14+
margin-left: 0.85rem;
15+
padding-left: 0.85rem;
16+
border-left: 1px solid var(--ifm-color-emphasis-300);
17+
}
18+
19+
.copyPageContainer {
20+
display: inline-flex;
21+
align-items: center;
22+
}
23+
24+
/* Strip the default button chrome so it reads as a link, matching the
25+
* adjacent "Edit this page" link's size/weight. customStyles classes are
26+
* appended after the plugin defaults, so override with !important. */
27+
.copyPageButton {
28+
display: inline-flex !important;
29+
align-items: center;
30+
gap: 0.3rem;
31+
border: none !important;
32+
background: transparent !important;
33+
box-shadow: none !important;
34+
border-radius: 0 !important;
35+
padding: 0 !important;
36+
margin: 0 !important;
37+
min-height: 0 !important;
38+
/* Match the adjacent "Edit this page" anchor, which uses the Infima link color */
39+
color: var(--ifm-link-color) !important;
40+
font: inherit !important;
41+
line-height: inherit !important;
42+
cursor: pointer;
43+
}
44+
45+
.copyPageButton:hover {
46+
color: var(--ifm-link-hover-color, var(--ifm-link-color)) !important;
47+
text-decoration: underline;
48+
}
49+
50+
/* Match stock EditMetaRow: right-align last-updated on desktop */
51+
@media (min-width: 997px) {
52+
.lastUpdatedCol {
53+
text-align: right;
54+
}
55+
}

src/theme/DocItem/Layout/index.tsx

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import React from 'react';
1313
import clsx from 'clsx';
1414
import {useWindowSize} from '@docusaurus/theme-common';
1515
import {useDoc} from '@docusaurus/plugin-content-docs/client';
16-
import CopyPageButton from 'docusaurus-plugin-copy-page-button/react';
1716
import DocItemPaginator from '@theme/DocItem/Paginator';
1817
import DocVersionBanner from '@theme/DocVersionBanner';
1918
import DocVersionBadge from '@theme/DocVersionBadge';
@@ -24,7 +23,6 @@ import DocItemContent from '@theme/DocItem/Content';
2423
import ContentVisibility from '@theme/ContentVisibility';
2524
import type {Props} from '@theme/DocItem/Layout';
2625
import styles from '@docusaurus/theme-classic/lib/theme/DocItem/Layout/styles.module.css';
27-
import copyPageStyles from './styles.module.css';
2826

2927
// CUSTOM CODE
3028
import DocDemo from '@components/global/DocDemo';
@@ -88,15 +86,6 @@ export default function DocItemLayout({children, ...props}: Props): JSX.Element
8886
<article>
8987
<DocVersionBadge />
9088
{docTOC.mobile}
91-
<div className={copyPageStyles.copyPageArticleAction}>
92-
<CopyPageButton
93-
customStyles={{
94-
container: {className: copyPageStyles.copyPageContainer},
95-
button: {className: copyPageStyles.copyPageButton},
96-
dropdown: {className: copyPageStyles.copyPageDropdown},
97-
}}
98-
/>
99-
</div>
10089
<DocItemContent>{children}</DocItemContent>
10190
<DocItemFooter />
10291
</article>

src/theme/DocItem/Layout/styles.module.css

Lines changed: 0 additions & 21 deletions
This file was deleted.

src/theme/TOC/index.tsx

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,12 @@ import React, { useState, useEffect } from 'react';
1111
import TOC from '@theme-original/TOC';
1212
import type { Props } from '@theme/TOC';
1313

14-
import CopyPageButton from 'docusaurus-plugin-copy-page-button/react';
1514
import EditThisPage from '@theme-original/EditThisPage';
1615
import { useLocation } from '@docusaurus/router';
1716
import { usePluginData } from '@docusaurus/useGlobalData';
1817
import { PrismicRichText } from '@prismicio/react';
1918
import { useDoc } from '@docusaurus/plugin-content-docs/client';
2019

21-
import styles from './styles.module.css';
22-
2320
interface TOCProps extends Props {
2421
editUrl: string;
2522
}
@@ -40,15 +37,6 @@ export default function TOCWrapper(props: TOCProps): JSX.Element {
4037

4138
return (
4239
<div className="toc-wrapper">
43-
<div className={styles.copyPageAction}>
44-
<CopyPageButton
45-
customStyles={{
46-
container: { className: styles.copyPageContainer },
47-
button: { className: styles.copyPageButton },
48-
dropdown: { className: styles.copyPageDropdown },
49-
}}
50-
/>
51-
</div>
5240
<h2>Contents</h2>
5341
<TOC {...props} />
5442
<EditThisPage editUrl={metadata.editUrl} />

src/theme/TOC/styles.module.css

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)