69 lines
2.0 KiB
Svelte
69 lines
2.0 KiB
Svelte
<script>
|
|
export let level;
|
|
export let id = '';
|
|
|
|
const tag = `h${level}`;
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.h {
|
|
position: relative;
|
|
}
|
|
|
|
// shift the anchor link to hang off the left side of the content when there's room
|
|
.anchor-wrapper {
|
|
// slightly overlap the span with the heading so that it doesn't
|
|
// lose its hover state as the cursor moves between them
|
|
position: absolute;
|
|
padding-right: 0.5em;
|
|
left: -1.25em;
|
|
|
|
@media(max-width: 58rem) {
|
|
position: revert;
|
|
}
|
|
}
|
|
|
|
a {
|
|
// works better to set the size here for line-height reasons
|
|
font-size: 0.9em;
|
|
|
|
// give the anchor link a faded appearance by default
|
|
color: hsl(0deg, 0%, 29%);
|
|
opacity: 40%;
|
|
transition: opacity 150ms, color 150ms;
|
|
|
|
&:hover {
|
|
border-bottom: 0.05em solid currentcolor;
|
|
}
|
|
}
|
|
|
|
// emphasize anchor link when heading is hovered or when clicked (the latter for mobile)
|
|
.h:hover a, .anchor-wrapper:hover a, .h a:active {
|
|
color: var(--accent-color);
|
|
opacity: 100%;
|
|
}
|
|
|
|
svg {
|
|
// undo the reset that makes images block
|
|
display: inline;
|
|
width: 1em;
|
|
// tiny tweak for optical alignment
|
|
transform: translateY(2px);
|
|
}
|
|
</style>
|
|
|
|
<svelte:element this={tag} {id} class="h">
|
|
<span>
|
|
<slot></slot>
|
|
</span>
|
|
|
|
<!-- Icon from https://heroicons.com/ -->
|
|
<span class="anchor-wrapper">
|
|
<a href="#{id}" >
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244" />
|
|
</svg>
|
|
</a>
|
|
</span>
|
|
</svelte:element>
|