Prevent "copy link" styling/behavior when a link is used inside a heading (#1020)

Fixes #868 - and also prevents the "Copy link" underline/prompt from
appearing when the link is hovered, for clarity about what action
clicking will perform


https://unicorn-utterances-git-fix-links-inside-headings-oceanbit.vercel.app/posts/example_noindex#Heading-with-a-link-inside-of-it
This commit is contained in:
James Fenn
2024-01-23 17:48:27 -05:00
committed by GitHub
3 changed files with 34 additions and 6 deletions

View File

@@ -154,3 +154,7 @@ This is regular text.
2. Padded sub-item 2 2. Padded sub-item 2
3. List item 3 3. List item 3
# Heading `with a code snippet` inside of it
# Heading [with a link](https://example.com) inside of it

View File

@@ -31,6 +31,10 @@ import style from "./heading-link.module.scss";
) as HTMLTemplateElement; ) as HTMLTemplateElement;
function handleClick(e: Event) { function handleClick(e: Event) {
if ((e.target as HTMLElement).tagName === "A") {
return;
}
const target = e.currentTarget as HTMLElement; const target = e.currentTarget as HTMLElement;
const headingAnchorEl = target.hasAttribute("data-heading-anchor") const headingAnchorEl = target.hasAttribute("data-heading-anchor")
? target ? target

View File

@@ -87,6 +87,17 @@
} }
} }
// If the heading contains an <a> which is hovered,
// click will follow the anchor href, so the "Copy link"
// button should not be displayed
@supports selector(:has(*)) {
:global(.heading-linked):has(a:hover, a:focus-visible) {
.headingLink {
opacity: 0 !important;
}
}
}
.headingLinkContainer:focus-visible .headingLink { .headingLinkContainer:focus-visible .headingLink {
outline: var(--heading-link_outline-width) solid var(--heading-link_outline-color); outline: var(--heading-link_outline-width) solid var(--heading-link_outline-color);
} }
@@ -116,13 +127,17 @@
--heading_background_outline-width: var(--border-width_focus); --heading_background_outline-width: var(--border-width_focus);
} }
:global(.heading-linked):hover,
:global(.heading-linked):focus-within,
:global(.heading-linked):has(.headingLinkContainer:hover) {
text-decoration: underline;
}
@supports selector(:has(*)) { @supports selector(:has(*)) {
:global(.heading-linked):hover,
:global(.heading-linked):focus-within,
:global(.heading-linked):has(.headingLinkContainer:hover) {
// The underline should not be applied if an inner <a> is focused
// as clicking will follow the link, not interact with the heading
&:not(:has(a:hover, a:focus-visible)) {
text-decoration: underline;
}
}
:global(.heading-linked):has(.headingLinkContainer:focus-visible) { :global(.heading-linked):has(.headingLinkContainer:focus-visible) {
&> span { &> span {
border-radius: calc(var(--heading_background_corner-radius) - var(--heading_background_padding)); border-radius: calc(var(--heading_background_corner-radius) - var(--heading_background_padding));
@@ -133,6 +148,11 @@
} }
@supports not selector(:has(*)) { @supports not selector(:has(*)) {
:global(.heading-linked):hover,
:global(.heading-linked):focus-within {
text-decoration: underline;
}
:global(.heading-linked):focus-within { :global(.heading-linked):focus-within {
&> span { &> span {
border-radius: calc(var(--heading_background_corner-radius) - var(--heading_background_padding)); border-radius: calc(var(--heading_background_corner-radius) - var(--heading_background_padding));