You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On the Sphinx lecture sites that run book theme 0.22.0, hovering over an entry in the right-hand "On this page" panel shows a small clipboard icon. Clicking it copies that section's full URL (the page URL plus #anchor) and briefly marks the icon as copied. This theme's outline has nothing like it. Each entry is a plain link, and the theme's own code contains no clipboard or copy-link code. A reader who wants to share or cite a section has to click the # beside the heading and copy the address bar, or copy the entry's link address from the browser's context menu.
Readers of those sites get the icon without changing any setting. The book theme adds it only to the pinned panel that sticky_contents turns on. That option defaults to true in v0.22.0, although it defaulted to sticky_contents = False when the icon first shipped in v0.17.0. The study counts 13 of the 21 published lecture sites on theme 0.22.0. The other 8 run 0.7.x or 0.8.0, which are older than the icon. A code search of the QuantEcon organisation on 2026-09-11 found sticky_contents in only five lecture configs, all set to true (table below). The same day, python-programming.quantecon.org/matplotlib.html rendered <div class="inner sticky" data-autoexpand="true">, and its quantecon-book-theme.js bundle contained the toc-copy-link code and a clipboard.writeText call. Moving one of those sites to this theme removes the icon.
Evidence
Where
The book theme adds a span.toc-copy-link inside every in-page link of the pinned panel. The span has role="button", aria-label and title "Copy link to section", and a 12px clipboard SVG. A click copies location.origin + location.pathname + href, then sets a copied class and a "Copied!" title for 1.5s
The icon is invisible until the entry is hovered. It then shows at 0.6 opacity, and at full opacity when the icon itself is hovered or has been clicked. Dark mode has its own colours
The theme has no clipboard or copy-link code of its own
A case-insensitive search of every tracked file at d504555 for clipboard, copy-link, copy link and toc-copy finds nothing
Upstream's # beside each heading scrolls to the heading and replaces the URL fragment. It never writes to the clipboard
myst-to-react 1.3.0, dist/heading.js line 9 and dist/hashLink.js lines 12-22 and 37-47. The theme combines upstream's default renderers with its own list and stderr renderers, and none of them replaces heading: root.tsx L32-L38
Lecture repos that set sticky_contents: true explicitly, on their default branch as of 2026-09-11:
Two things about the Sphinx version should not be copied. The span has no tabindex or key handler and appears only on hover, so keyboard users cannot reach it. The clipboard call has no error handler, so a failed copy shows nothing (scrollspy.js L218-L248, _page.scss L200-L207).
Neither the docs nor the plan record the gap. The "On this page" section of docs/layout.md L21-L32 describes the pinned outline and compares it with the Sphinx panel, but does not say the copy-link is missing. PLAN.md L58 marks the sticky_contents row ✅ / ✅ with no caveat. docs/index.md L42-L45 promises a note on the relevant page wherever "a Sphinx option has no counterpart". sticky_contents does have a counterpart, so that promise does not cover a missing part of the option.
Proposed change
Add a copy-link control to each entry in the "On this page" outline. The code goes in Entry in app/components/Outline.tsx, and the styles go with the existing .qe-outline rules in styles/quantecon.css L519-L602.
Behave like the Sphinx control: appear when the entry is hovered, copy the page URL plus the entry's #anchor, and confirm briefly.
Make it a real <button> next to the link, not inside it, because HTML does not allow a button inside an <a>. Keyboard users can then reach it, and it can appear on :focus-visible. The entry link is currently display: block, with space reserved for the active-entry rule on its inline-start side (styles/quantecon.css L552-L564). The entry row needs a new layout so the link and button fit side by side without moving that rule.
Announce the confirmation to screen readers, for example through a polite live region, and show visible feedback when the copy fails.
Use logical CSS properties, as the outline rules already do, so the control mirrors correctly in the RTL editions.
This issue proposes the outline entry because that is where Sphinx readers find the control. The alternative is the # permalink beside each heading. That placement would also reach narrower screens, because the outline column is hidden below 1280px (styles/app.css L32-L34, with the outline placed in that column at PageContent.tsx L75). docs/layout.md L53 says 1024px, which study row F001 records as wrong. But the heading is not where Sphinx readers look, and that option would mean replacing upstream's heading renderer, which the theme currently uses unchanged. If the maintainers decide not to port the control at all, the study's alternative is to record that decision in the "On this page" section of docs/layout.md.
Acceptance criteria
Every h2 and h3 entry in the "On this page" outline has a copy-link control. It copies the page URL plus that entry's #anchor, and opening the copied URL goes to that section.
The control is a focusable <button> whose accessible name is "Copy link to section". It is hidden by default and appears when the entry is hovered or the button has keyboard focus.
A successful copy shows a visible confirmation that screen readers also announce. A failed copy, for example when clipboard permission is denied, shows visible feedback.
Using the control does not scroll the page, change the URL, or change which entry is marked current (aria-current).
Whenever the icon is shown, it has at least 3:1 contrast against the panel background in both light and dark mode.
In the RTL edition (fixture-rtl) the control's position mirrors its LTR position, and the existing outline-within-viewport test still passes.
The "On this page" section of docs/layout.md describes the control, and the Unreleased section of CHANGELOG.md has an entry for it (CONTRIBUTING.md L167-L169).
Context
Source: the 2026-09-11 book-theme parity study, row F012. The study lists it in section 3.3 ("Other gaps, by area", Layout and navigation), outside its recommended gate additions. The study's recheck moved the row from dropped_by_decision to missing_untracked, at medium confidence. If the maintainers treat the PR feat(outline): pin the "On this page" panel, track scrolling, list subsections #196 sentence below as final, dropped_by_decision applies instead.
Problem
On the Sphinx lecture sites that run book theme 0.22.0, hovering over an entry in the right-hand "On this page" panel shows a small clipboard icon. Clicking it copies that section's full URL (the page URL plus
#anchor) and briefly marks the icon as copied. This theme's outline has nothing like it. Each entry is a plain link, and the theme's own code contains no clipboard or copy-link code. A reader who wants to share or cite a section has to click the#beside the heading and copy the address bar, or copy the entry's link address from the browser's context menu.Readers of those sites get the icon without changing any setting. The book theme adds it only to the pinned panel that
sticky_contentsturns on. That option defaults to true in v0.22.0, although it defaulted tosticky_contents = Falsewhen the icon first shipped in v0.17.0. The study counts 13 of the 21 published lecture sites on theme 0.22.0. The other 8 run 0.7.x or 0.8.0, which are older than the icon. A code search of the QuantEcon organisation on 2026-09-11 foundsticky_contentsin only five lecture configs, all set to true (table below). The same day, python-programming.quantecon.org/matplotlib.html rendered<div class="inner sticky" data-autoexpand="true">, and itsquantecon-book-theme.jsbundle contained thetoc-copy-linkcode and aclipboard.writeTextcall. Moving one of those sites to this theme removes the icon.span.toc-copy-linkinside every in-page link of the pinned panel. The span hasrole="button",aria-labelandtitle"Copy link to section", and a 12px clipboard SVG. A click copieslocation.origin + location.pathname + href, then sets acopiedclass and a "Copied!" title for 1.5sinitScrollSpystops when.inner.stickyis missing, and callsinitCopyLinksat its endLink#beside each heading scrolls to the heading and replaces the URL fragment. It never writes to the clipboardheading: root.tsx L32-L38Lecture repos that set
sticky_contents: trueexplicitly, on their default branch as of 2026-09-11:Two things about the Sphinx version should not be copied. The span has no
tabindexor key handler and appears only on hover, so keyboard users cannot reach it. The clipboard call has no error handler, so a failed copy shows nothing (scrollspy.js L218-L248, _page.scss L200-L207).Neither the docs nor the plan record the gap. The "On this page" section of docs/layout.md L21-L32 describes the pinned outline and compares it with the Sphinx panel, but does not say the copy-link is missing. PLAN.md L58 marks the
sticky_contentsrow ✅ / ✅ with no caveat. docs/index.md L42-L45 promises a note on the relevant page wherever "a Sphinx option has no counterpart".sticky_contentsdoes have a counterpart, so that promise does not cover a missing part of the option.Proposed change
Add a copy-link control to each entry in the "On this page" outline. The code goes in
Entryinapp/components/Outline.tsx, and the styles go with the existing.qe-outlinerules in styles/quantecon.css L519-L602.#anchor, and confirm briefly.<button>next to the link, not inside it, because HTML does not allow a button inside an<a>. Keyboard users can then reach it, and it can appear on:focus-visible. The entry link is currentlydisplay: block, with space reserved for the active-entry rule on its inline-start side (styles/quantecon.css L552-L564). The entry row needs a new layout so the link and button fit side by side without moving that rule.This issue proposes the outline entry because that is where Sphinx readers find the control. The alternative is the
#permalink beside each heading. That placement would also reach narrower screens, because the outline column is hidden below 1280px (styles/app.css L32-L34, with the outline placed in that column at PageContent.tsx L75). docs/layout.md L53 says 1024px, which study row F001 records as wrong. But the heading is not where Sphinx readers look, and that option would mean replacing upstream's heading renderer, which the theme currently uses unchanged. If the maintainers decide not to port the control at all, the study's alternative is to record that decision in the "On this page" section ofdocs/layout.md.Acceptance criteria
#anchor, and opening the copied URL goes to that section.<button>whose accessible name is "Copy link to section". It is hidden by default and appears when the entry is hovered or the button has keyboard focus.aria-current).fixture-rtl) the control's position mirrors its LTR position, and the existingoutline-within-viewporttest still passes.docs/layout.mddescribes the control, and the Unreleased section ofCHANGELOG.mdhas an entry for it (CONTRIBUTING.md L167-L169).Context
.toc-copy-link, an SVG that copies the section URL). Proposed out of scope here — it is a separate affordance, not part of the scroll behaviour — but say so explicitly rather than losing it." PR feat(outline): pin the "On this page" panel, track scrolling, list subsections #196, merged 2026-09-10, says: "Decision 4 (per-entry copy-link) is out of scope and stays so." No later comment on The "On this page" outline scrolls off the page and never marks the current section #182, no comment or review on feat(outline): pin the "On this page" panel, track scrolling, list subsections #196, and nothing in Book-theme parity cutover — tracking #147's body or comments returns to it. A search of this repo's issues on 2026-09-11 for copy link, copy-link, clipboard and toc-copy-link found no follow-up issue.docs/layout.md(tracked in PLAN.md and the user docs claim book-theme parity and behaviour that the code does not deliver #210).