add custom headings with deep link
This commit is contained in:
@@ -3,9 +3,10 @@ export interface Props {
|
|||||||
name: string,
|
name: string,
|
||||||
width?: string,
|
width?: string,
|
||||||
height?: string,
|
height?: string,
|
||||||
|
display?: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
const { name, width, height } = Astro.props;
|
const { name, width, height, display } = Astro.props;
|
||||||
|
|
||||||
const icons = import.meta.glob<{string: string}>('@components/icons/*.svg', { query: '?raw', import: 'default' });
|
const icons = import.meta.glob<{string: string}>('@components/icons/*.svg', { query: '?raw', import: 'default' });
|
||||||
const path = `/src/components/icons/${name}.svg`;
|
const path = `/src/components/icons/${name}.svg`;
|
||||||
@@ -17,8 +18,9 @@ const icon = await icons[path]();
|
|||||||
|
|
||||||
<span class="icon" set:html={icon} />
|
<span class="icon" set:html={icon} />
|
||||||
|
|
||||||
<style define:vars={{ width, height }}>
|
<style define:vars={{ width, height, display }}>
|
||||||
.icon :global(svg) {
|
.icon :global(svg) {
|
||||||
|
display: var(--display, block);
|
||||||
width: var(--width, 100%);
|
width: var(--width, 100%);
|
||||||
height: var(--height, 100%);
|
height: var(--height, 100%);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import Toc from '@components/Toc.vue';
|
|||||||
import { formatDate } from '@lib/datefmt';
|
import { formatDate } from '@lib/datefmt';
|
||||||
|
|
||||||
import Icon from '@components/Icon.astro';
|
import Icon from '@components/Icon.astro';
|
||||||
|
import { headingElements } from '@components/headings';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
entry: CollectionEntry<'posts'>,
|
entry: CollectionEntry<'posts'>,
|
||||||
@@ -20,6 +21,41 @@ const { entry, prevSlug, nextSlug } = Astro.props;
|
|||||||
const { Content, headings } = await render(entry);
|
const { Content, headings } = await render(entry);
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<article class="prose" data-dropcap-style={entry.data.dropcap}>
|
||||||
|
<header class="title">
|
||||||
|
<h1>
|
||||||
|
<!-- <SmallCaps text={entry.data.title} upperWeight={500} lowerWeight={800} /> -->
|
||||||
|
{ entry.data.title }
|
||||||
|
</h1>
|
||||||
|
<p class="subtitle">{ formatDate(entry.data.date) }</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div id="left-gutter">
|
||||||
|
<Toc client:load {headings} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section class="post">
|
||||||
|
<Content components={headingElements} />
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div id="right-gutter" />
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
{prevSlug && (
|
||||||
|
<div class="footer-link left">
|
||||||
|
<Icon name="arrow-left" height="1em" />
|
||||||
|
<a href={`/${prevSlug}`} data-astro-prefetch>Older</a>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{nextSlug && (
|
||||||
|
<div class="footer-link right">
|
||||||
|
<a href={`/${nextSlug}`} data-astro-prefetch>Newer</a>
|
||||||
|
<Icon name="arrow-right" height="1em" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</footer>
|
||||||
|
</article>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
/* 3-column grid: left gutter, center content, and right gutter */
|
/* 3-column grid: left gutter, center content, and right gutter */
|
||||||
article {
|
article {
|
||||||
@@ -126,38 +162,3 @@ article {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<article class="prose" data-dropcap-style={entry.data.dropcap}>
|
|
||||||
<header class="title">
|
|
||||||
<h1>
|
|
||||||
<!-- <SmallCaps text={entry.data.title} upperWeight={500} lowerWeight={800} /> -->
|
|
||||||
{ entry.data.title }
|
|
||||||
</h1>
|
|
||||||
<p class="subtitle">{ formatDate(entry.data.date) }</p>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div id="left-gutter">
|
|
||||||
<Toc client:load {headings} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<section class="post">
|
|
||||||
<Content />
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<div id="right-gutter" />
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
{prevSlug && (
|
|
||||||
<div class="footer-link left">
|
|
||||||
<Icon name="arrow-left" height="1em" />
|
|
||||||
<a href={`/${prevSlug}`} data-astro-prefetch>Older</a>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{nextSlug && (
|
|
||||||
<div class="footer-link right">
|
|
||||||
<a href={`/${nextSlug}`} data-astro-prefetch>Newer</a>
|
|
||||||
<Icon name="arrow-right" height="1em" />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</footer>
|
|
||||||
</article>
|
|
||||||
|
|||||||
7
src/components/headings/H1.astro
Normal file
7
src/components/headings/H1.astro
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
import Heading from './Heading.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Heading tag="h1" {...Astro.props}>
|
||||||
|
<slot />
|
||||||
|
</Heading>
|
||||||
7
src/components/headings/H2.astro
Normal file
7
src/components/headings/H2.astro
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
import Heading from './Heading.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Heading tag="h2" {...Astro.props}>
|
||||||
|
<slot />
|
||||||
|
</Heading>
|
||||||
7
src/components/headings/H3.astro
Normal file
7
src/components/headings/H3.astro
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
import Heading from './Heading.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Heading tag="h3" {...Astro.props}>
|
||||||
|
<slot />
|
||||||
|
</Heading>
|
||||||
7
src/components/headings/H4.astro
Normal file
7
src/components/headings/H4.astro
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
import Heading from './Heading.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Heading tag="h4" {...Astro.props}>
|
||||||
|
<slot />
|
||||||
|
</Heading>
|
||||||
7
src/components/headings/H5.astro
Normal file
7
src/components/headings/H5.astro
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
import Heading from './Heading.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Heading tag="h5" {...Astro.props}>
|
||||||
|
<slot />
|
||||||
|
</Heading>
|
||||||
7
src/components/headings/H6.astro
Normal file
7
src/components/headings/H6.astro
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
import Heading from './Heading.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<Heading tag="h6" {...Astro.props}>
|
||||||
|
<slot />
|
||||||
|
</Heading>
|
||||||
45
src/components/headings/Heading.astro
Normal file
45
src/components/headings/Heading.astro
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
import Icon from '@components/Icon.astro';
|
||||||
|
|
||||||
|
export interface Props extends astroHTML.JSX.HTMLAttributes {
|
||||||
|
tag: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
const { tag: Tag, ...rest } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<Tag {...rest}>
|
||||||
|
<slot />
|
||||||
|
|
||||||
|
<a href={`#${Astro.props.id}`} class="deep-link" >
|
||||||
|
<Icon name="link" height="0.9em" width="0.9em" display="inline" />
|
||||||
|
</a>
|
||||||
|
</Tag>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:hover :global(svg) {
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
& :global(svg) {
|
||||||
|
color: var(--content-color-faded);
|
||||||
|
padding-bottom: 0.15em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover :global(svg), &:active :global(svg) {
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(min-width: 60rem) {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.1em;
|
||||||
|
left: -1.25em;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
15
src/components/headings/index.ts
Normal file
15
src/components/headings/index.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import H1 from './H1.astro';
|
||||||
|
import H2 from './H2.astro';
|
||||||
|
import H3 from './H3.astro';
|
||||||
|
import H4 from './H4.astro';
|
||||||
|
import H5 from './H5.astro';
|
||||||
|
import H6 from './H6.astro';
|
||||||
|
|
||||||
|
export const headingElements = {
|
||||||
|
h1: H1,
|
||||||
|
h2: H2,
|
||||||
|
h3: H3,
|
||||||
|
h4: H4,
|
||||||
|
h5: H5,
|
||||||
|
h6: H6,
|
||||||
|
};
|
||||||
3
src/components/icons/link.svg
Normal file
3
src/components/icons/link.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 353 B |
Reference in New Issue
Block a user