mirror of
https://github.com/saicaca/fuwari.git
synced 2026-01-12 23:32:53 +01:00
feat: added TOC (#198)
This commit is contained in:
@@ -2,15 +2,29 @@
|
||||
import Profile from './Profile.astro'
|
||||
import Tag from './Tags.astro'
|
||||
import Categories from './Categories.astro'
|
||||
import type { MarkdownHeading } from 'astro'
|
||||
import TOC from './TOC.astro'
|
||||
|
||||
interface Props {
|
||||
class? : string
|
||||
headings? : MarkdownHeading[]
|
||||
}
|
||||
|
||||
const className = Astro.props.class
|
||||
const headings = Astro.props.headings
|
||||
|
||||
---
|
||||
<div id="sidebar" class:list={[className, "w-full"]}>
|
||||
<div class="flex flex-col w-full gap-4 mb-4">
|
||||
<Profile></Profile>
|
||||
</div>
|
||||
<div id="sidebar-sticky" class="transition-all duration-700 flex flex-col w-full gap-4 top-4 sticky top-4">
|
||||
<Categories class="onload-animation" style="animation-delay: 150ms"></Categories>
|
||||
<Tag class="onload-animation" style="animation-delay: 200ms"></Tag>
|
||||
<div id="sidebar-sticky" class="sticky top-4">
|
||||
<div id="toc" class="transition-all duration-700 flex flex-col w-full gap-4">
|
||||
{headings && headings.length > 0 && <TOC class="mb-4 onload-animation" style="animation-delay: 150ms" headings={headings}/>}
|
||||
</div>
|
||||
<div class="transition-all duration-700 flex flex-col w-full gap-4">
|
||||
<Categories class="onload-animation" style="animation-delay: 150ms"></Categories>
|
||||
<Tag class="onload-animation" style="animation-delay: 200ms"></Tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
48
src/components/widget/TOC.astro
Normal file
48
src/components/widget/TOC.astro
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
import WidgetLayout from './WidgetLayout.astro'
|
||||
import type { MarkdownHeading } from 'astro';
|
||||
|
||||
import { i18n } from '../../i18n/translation'
|
||||
import I18nKey from '../../i18n/i18nKey'
|
||||
import ButtonLink from '../control/ButtonLink.astro'
|
||||
|
||||
interface Props {
|
||||
class?: string
|
||||
style?: string
|
||||
headings: MarkdownHeading[]
|
||||
}
|
||||
|
||||
const { headings } = Astro.props;
|
||||
|
||||
const className = Astro.props.class
|
||||
const style = Astro.props.style
|
||||
|
||||
const COLLAPSED_HEIGHT = '7.5rem'
|
||||
const COLLAPSE_THRESHOLD = 5
|
||||
|
||||
const isCollapsed = headings.length >= COLLAPSE_THRESHOLD
|
||||
|
||||
const getMarginStyleFromHeading = (heading: MarkdownHeading) => {
|
||||
return `margin-left: ${(heading.depth - 1) / 2}rem`;
|
||||
}
|
||||
|
||||
const removeTailingHash = (text: string) => {
|
||||
let lastIndexOfHash = text.lastIndexOf('#');
|
||||
if (lastIndexOfHash != text.length - 1) {
|
||||
return text;
|
||||
}
|
||||
|
||||
return text.substring(0, lastIndexOfHash);
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
<WidgetLayout name={i18n(I18nKey.toc)} id="toc" isCollapsed={isCollapsed} collapsedHeight={COLLAPSED_HEIGHT}
|
||||
class={className} style={style}
|
||||
>
|
||||
{headings.map((heading) =>
|
||||
<div style={getMarginStyleFromHeading(heading)}>
|
||||
<ButtonLink url={`#${heading.slug}`}>{removeTailingHash(heading.text)}</ButtonLink>
|
||||
</div>
|
||||
)}
|
||||
</WidgetLayout>
|
||||
Reference in New Issue
Block a user