Created
July 10, 2025 15:36
-
-
Save cferdinandi/712a89a687ff2e255d700bc87e8ab252 to your computer and use it in GitHub Desktop.
Watch the tutorial: https://youtu.be/AwAcchY28yA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Kelp</title> | |
<meta name="description" content="A UI library for people who love HTML, powered by modern CSS and Web Components."> | |
<!-- Mobile Screen Resizing --> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<!-- Kelp CSS --> | |
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/kelpui@0/css/kelp.css"> | |
</head> | |
<body> | |
<main class="container"> | |
<h1>kelp-toc - debug</h1> | |
<kelp-toc></kelp-toc> | |
</main> | |
<script> | |
document.addEventListener('kelp-debug', function (event) { | |
console.log(event.target, event.detail); | |
}); | |
</script> | |
<script src="./toc.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Kelp</title> | |
<meta name="description" content="A UI library for people who love HTML, powered by modern CSS and Web Components."> | |
<!-- Mobile Screen Resizing --> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<!-- Kelp CSS --> | |
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/kelpui@0/css/kelp.css"> | |
</head> | |
<body> | |
<main class="container"> | |
<h1>kelp-toc</h1> | |
<kelp-toc></kelp-toc> | |
<h2>Cat O'Nine Tails</h2> | |
<h3 id="the-brig">The Brig</h3> | |
<h4>Privateer</h4> | |
<h2>Ahoy</h2> | |
<h3 id="man-of-war">Man-of-War</h3> | |
<h2 id="corsair">Corsair</h2> | |
<h3 id="shiver-me-timbers">Shiver Me Timbers</h3> | |
<h2 id="scurvy-dog">Scurvy Dog</h2> | |
<h4>Sea Legs</h4> | |
<h2 id="quarterdeck">On the Quarterdeck</h2> | |
<h3 id="jolly-roger">Jolly Roger</h3> | |
<h3 id="sloop">Sloop</h3> | |
<h4 id="swab">Swab</h4> | |
<h5>Grog</h5> | |
<div id="empty"></div> | |
</main> | |
<!-- Component JS --> | |
<script src="./toc.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Kelp</title> | |
<meta name="description" content="A UI library for people who love HTML, powered by modern CSS and Web Components."> | |
<!-- Mobile Screen Resizing --> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<!-- Kelp CSS --> | |
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/kelpui@0/css/kelp.css"> | |
<!-- Component JS --> | |
<script> | |
document.addEventListener('kelp-debug', function (event) { | |
console.log(event.target, event.detail); | |
}); | |
</script> | |
<script src="./toc.js"></script> | |
</head> | |
<body> | |
<main class="container"> | |
<h1>kelp-toc - load in header</h1> | |
<kelp-toc></kelp-toc> | |
<h2>Cat O'Nine Tails</h2> | |
<h3 id="the-brig">The Brig</h3> | |
<h4>Privateer</h4> | |
<h2>Ahoy</h2> | |
<h3 id="man-of-war">Man-of-War</h3> | |
<h2 id="corsair">Corsair</h2> | |
<h3 id="shiver-me-timbers">Shiver Me Timbers</h3> | |
<h2 id="scurvy-dog">Scurvy Dog</h2> | |
<h4>Sea Legs</h4> | |
<h2 id="quarterdeck">On the Quarterdeck</h2> | |
<h3 id="jolly-roger">Jolly Roger</h3> | |
<h3 id="sloop">Sloop</h3> | |
<h4 id="swab">Swab</h4> | |
<h5>Grog</h5> | |
<div id="empty"></div> | |
</main> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
customElements.define('kelp-toc', class extends HTMLElement { | |
// Initialize on connect | |
connectedCallback () { | |
if (document.readyState !== 'loading') { | |
this.init(); | |
return; | |
} | |
document.addEventListener('DOMContentLoaded', () => this.init(), {once: true}); | |
} | |
// Initialize the component | |
init () { | |
// Don't run if already initialized | |
if (this.hasAttribute('is-ready')) return; | |
// Get settings | |
this.level = this.getAttribute('level') || 'h2'; | |
this.heading = this.getAttribute('heading'); | |
this.target = this.getAttribute('target') || ''; | |
this.listClass = this.getAttribute('list-class') || 'list-inline'; | |
// Render | |
if (!this.render()) { | |
this.debug('No matching headings were found'); | |
return; | |
} | |
// Ready | |
this.emit(); | |
this.setAttribute('is-ready', ''); | |
} | |
// Render the TOC | |
render () { | |
// Generate list items | |
const navList = Array.from(document.querySelectorAll(`${this.target} ${this.level}`)).map((heading) => { | |
if (!heading.id) { | |
heading.id = `h_${crypto.randomUUID()}`; | |
} | |
return `<li><a class="link-subtle" href="#${heading.id}">${heading.textContent}</a></li>`; | |
}).join(''); | |
// Make sure a navList exists | |
if (navList.length < 1) return; | |
// Render the HTML | |
this.innerHTML = `<ul class="${this.listClass}">${this.heading ? `<li><strong>${this.heading}</strong></li>` : ''}${navList}</ul>`; | |
return true; | |
} | |
// Emit a custom event | |
emit () { | |
// Create a new event | |
const event = new CustomEvent('kelp:toc-ready', { | |
bubbles: true | |
}); | |
// Dispatch the event | |
return this.dispatchEvent(event); | |
} | |
// Emit a debug event | |
debug (detail = '') { | |
// Create a new event | |
const event = new CustomEvent('kelp-debug', { | |
bubbles: true, | |
detail | |
}); | |
// Dispatch the event | |
return this.dispatchEvent(event); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment