Swap to use zachleat/heading-anchors for heading anchor links.
This commit is contained in:
parent
2df6143099
commit
d791163e12
@ -33,7 +33,7 @@
|
|||||||
{#- Renders the CSS bundle using a separate file, if you can't set CSP directive style-src: 'unsafe-inline' #}
|
{#- Renders the CSS bundle using a separate file, if you can't set CSP directive style-src: 'unsafe-inline' #}
|
||||||
{#- <link rel="stylesheet" href="{% getBundleFileUrl "css" %}"> #}
|
{#- <link rel="stylesheet" href="{% getBundleFileUrl "css" %}"> #}
|
||||||
|
|
||||||
{%- js %}{% include "public/js/heading-anchors.js" %}{% endjs %}
|
{%- js %}{% include "node_modules/@zachleat/heading-anchors/heading-anchors.js" %}{% endjs %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<a href="#skip" class="visually-hidden">Skip to main content</a>
|
<a href="#skip" class="visually-hidden">Skip to main content</a>
|
||||||
|
@ -10,7 +10,7 @@ Leverage agile frameworks to provide a robust synopsis for high level overviews.
|
|||||||
|
|
||||||
## Code
|
## Code
|
||||||
|
|
||||||
### Styled (with Syntax)
|
### This is a very long heading that I want to wrap This is a very long heading that I want to wrap This is a very long heading that I want to wrap This is a very long heading that I want to wrap
|
||||||
|
|
||||||
Bring to the table win-win survival strategies to ensure proactive domination. At the end of the day, going forward, a new normal that has evolved from generation X is on the runway heading towards a streamlined cloud solution. User generated content in real-time will have multiple touchpoints for offshoring.
|
Bring to the table win-win survival strategies to ensure proactive domination. At the end of the day, going forward, a new normal that has evolved from generation X is on the runway heading towards a streamlined cloud solution. User generated content in real-time will have multiple touchpoints for offshoring.
|
||||||
|
|
||||||
|
@ -44,5 +44,8 @@
|
|||||||
"luxon": "^3.4.4",
|
"luxon": "^3.4.4",
|
||||||
"zod": "^3.23.8",
|
"zod": "^3.23.8",
|
||||||
"zod-validation-error": "^3.3.0"
|
"zod-validation-error": "^3.3.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@zachleat/heading-anchors": "^1.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,7 +256,3 @@ header {
|
|||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Anchor links color */
|
|
||||||
a[href]:is(:link, :visited).ha {
|
|
||||||
color: #aaa;
|
|
||||||
}
|
|
||||||
|
@ -1,133 +0,0 @@
|
|||||||
// Thank you to https://github.com/daviddarnes/heading-anchors
|
|
||||||
// Thank you to https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
|
|
||||||
|
|
||||||
class HeadingAnchors extends HTMLElement {
|
|
||||||
static register(tagName) {
|
|
||||||
if ("customElements" in window) {
|
|
||||||
customElements.define(tagName || "heading-anchors", HeadingAnchors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static attributes = {
|
|
||||||
exclude: "data-ha-exclude",
|
|
||||||
content: "data-ha-text"
|
|
||||||
}
|
|
||||||
|
|
||||||
static classes = {
|
|
||||||
anchor: "ha",
|
|
||||||
heading: "ha-h", // only used for nested method
|
|
||||||
}
|
|
||||||
|
|
||||||
static defaultSelector = "h2,h3,h4,h5,h6";
|
|
||||||
|
|
||||||
static featureTest() {
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
static css = `
|
|
||||||
.${HeadingAnchors.classes.anchor} {
|
|
||||||
position: absolute;
|
|
||||||
text-decoration: none;
|
|
||||||
font-weight: 400;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity .15s;
|
|
||||||
padding-left: .25em;
|
|
||||||
padding-right: .25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* nested */
|
|
||||||
:is(h1,h2,h3,h4,h5,h6):is(:focus-within, :hover) .${HeadingAnchors.classes.anchor},
|
|
||||||
/* sibling */
|
|
||||||
:is(h1,h2,h3,h4,h5,h6) + .${HeadingAnchors.classes.anchor}:is(:focus-within, :hover),
|
|
||||||
:is(h1,h2,h3,h4,h5,h6):is(:focus-within, :hover) + .${HeadingAnchors.classes.anchor} {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
@supports (anchor-name: none) {
|
|
||||||
/* purely for anchoring */
|
|
||||||
.${HeadingAnchors.classes.heading}:after {
|
|
||||||
content: "";
|
|
||||||
anchor-name: var(--ha_anchor);
|
|
||||||
}
|
|
||||||
.${HeadingAnchors.classes.anchor} {
|
|
||||||
left: anchor(right);
|
|
||||||
top: anchor(top);
|
|
||||||
}
|
|
||||||
}`;
|
|
||||||
|
|
||||||
get supportsTest() {
|
|
||||||
return "replaceSync" in CSSStyleSheet.prototype;
|
|
||||||
}
|
|
||||||
|
|
||||||
get supportsAnchorPosition() {
|
|
||||||
return CSS.supports("anchor-name: none");
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
if(!this.supportsTest) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let sheet = new CSSStyleSheet();
|
|
||||||
sheet.replaceSync(HeadingAnchors.css);
|
|
||||||
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
if (!this.supportsTest) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.headings.forEach((heading, index) => {
|
|
||||||
if(!heading.hasAttribute(HeadingAnchors.attributes.exclude)) {
|
|
||||||
let anchor = this.getAnchorElement(heading);
|
|
||||||
|
|
||||||
// Prefers anchor position approach for better accessibility
|
|
||||||
// https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/
|
|
||||||
if(this.supportsAnchorPosition) {
|
|
||||||
let anchorName = `--ha_${index}`;
|
|
||||||
heading.style.setProperty("--ha_anchor", anchorName);
|
|
||||||
anchor.style.positionAnchor = anchorName;
|
|
||||||
|
|
||||||
let fontSize = parseInt(getComputedStyle(heading).getPropertyValue("font-size"), 10);
|
|
||||||
anchor.style.fontSize = `${fontSize / 16}em`;
|
|
||||||
|
|
||||||
heading.classList.add(HeadingAnchors.classes.heading);
|
|
||||||
heading.after(anchor);
|
|
||||||
} else {
|
|
||||||
heading.appendChild(anchor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getText(heading) {
|
|
||||||
return heading.getAttribute(HeadingAnchors.attributes.content) || "#";
|
|
||||||
}
|
|
||||||
|
|
||||||
getAnchorElement(heading) {
|
|
||||||
let anchor = document.createElement("a");
|
|
||||||
anchor.href = `#${heading.id}`;
|
|
||||||
anchor.classList.add(HeadingAnchors.classes.anchor);
|
|
||||||
|
|
||||||
let text = this.getText(heading);
|
|
||||||
if(this.supportsAnchorPosition) {
|
|
||||||
anchor.innerHTML = `<span class="visually-hidden">Jump to section titled: ${heading.textContent}</span><span aria-hidden="true">${text}</span>`;
|
|
||||||
} else {
|
|
||||||
anchor.innerHTML = `<span aria-hidden="true">${text}</span>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return anchor;
|
|
||||||
}
|
|
||||||
|
|
||||||
get headings() {
|
|
||||||
return this.querySelectorAll(this.selector.split(",").map(entry => `${entry.trim()}[id]`));
|
|
||||||
}
|
|
||||||
|
|
||||||
get selector() {
|
|
||||||
return this.getAttribute("selector") || HeadingAnchors.defaultSelector;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HeadingAnchors.register();
|
|
Loading…
Reference in New Issue
Block a user