This commit is contained in:
1 parent
2a04f9a226
commit
37b8ffc7fe
1 file changed
+57
-27
@@ -20,6 +20,40 @@
|
|||||||
: null
|
: null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let isSeriesOpen = $state(true);
|
||||||
|
let seriesContentEl: HTMLElement | null = $state(null);
|
||||||
|
|
||||||
|
function toggleSeries(e: MouseEvent) {
|
||||||
|
const target = e.target as HTMLElement;
|
||||||
|
if (target.closest('a')) return;
|
||||||
|
|
||||||
|
const contentEl = seriesContentEl;
|
||||||
|
if (!contentEl) {
|
||||||
|
isSeriesOpen = !isSeriesOpen;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSeriesOpen) {
|
||||||
|
if (contentEl.style.maxHeight === 'none' || contentEl.style.maxHeight === '') {
|
||||||
|
contentEl.style.maxHeight = contentEl.scrollHeight + 'px';
|
||||||
|
void contentEl.offsetHeight;
|
||||||
|
}
|
||||||
|
contentEl.style.maxHeight = '0px';
|
||||||
|
isSeriesOpen = false;
|
||||||
|
} else {
|
||||||
|
isSeriesOpen = true;
|
||||||
|
contentEl.style.maxHeight = contentEl.scrollHeight + 'px';
|
||||||
|
|
||||||
|
const transitionEndHandler = (ev: Event) => {
|
||||||
|
if (ev.target === contentEl && isSeriesOpen) {
|
||||||
|
contentEl.style.maxHeight = 'none';
|
||||||
|
}
|
||||||
|
contentEl.removeEventListener('transitionend', transitionEndHandler);
|
||||||
|
};
|
||||||
|
contentEl.addEventListener('transitionend', transitionEndHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
const headers = document.querySelectorAll(
|
const headers = document.querySelectorAll(
|
||||||
'.js-toc-content h1, .js-toc-content h2, .js-toc-content h3, .js-toc-content h4, .js-toc-content h5, .js-toc-content h6'
|
'.js-toc-content h1, .js-toc-content h2, .js-toc-content h3, .js-toc-content h4, .js-toc-content h5, .js-toc-content h6'
|
||||||
@@ -61,6 +95,10 @@
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (seriesContentEl && isSeriesOpen) {
|
||||||
|
seriesContentEl.style.maxHeight = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (hasToc) tocbot.destroy();
|
if (hasToc) tocbot.destroy();
|
||||||
};
|
};
|
||||||
@@ -88,8 +126,14 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if data.series && data.seriesPosts.length > 0}
|
{#if data.series && data.seriesPosts.length > 0}
|
||||||
<details class="series-nav" open>
|
<div class="details series-nav" class:open={isSeriesOpen}>
|
||||||
<summary class="series-title" id="series-navigation-title">
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||||
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
|
<div
|
||||||
|
class="details-summary series-title"
|
||||||
|
id="series-navigation-title"
|
||||||
|
onclick={toggleSeries}
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
>{$page.data.aliases?.series || '系列'} -
|
>{$page.data.aliases?.series || '系列'} -
|
||||||
<a href={resolve('/series/[slug]', { slug: data.series.slug })}>{data.series.name}</a
|
<a href={resolve('/series/[slug]', { slug: data.series.slug })}>{data.series.name}</a
|
||||||
@@ -110,8 +154,8 @@
|
|||||||
></path></svg
|
></path></svg
|
||||||
>
|
>
|
||||||
</span>
|
</span>
|
||||||
</summary>
|
</div>
|
||||||
<div class="series-content">
|
<div bind:this={seriesContentEl} class="details-content series-content">
|
||||||
<nav>
|
<nav>
|
||||||
<ul>
|
<ul>
|
||||||
{#each data.seriesPosts as seriesPost (seriesPost.id)}
|
{#each data.seriesPosts as seriesPost (seriesPost.id)}
|
||||||
@@ -142,7 +186,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<MarkdownRenderer content={data.post.content} />
|
<MarkdownRenderer content={data.post.content} />
|
||||||
|
|
||||||
@@ -204,11 +248,7 @@
|
|||||||
padding: 0.25rem 0.75rem;
|
padding: 0.25rem 0.75rem;
|
||||||
background: #e6e6e6;
|
background: #e6e6e6;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
list-style: none;
|
user-select: none;
|
||||||
}
|
|
||||||
|
|
||||||
.series-nav .series-title::-webkit-details-marker {
|
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .details-icon — 对应 DoIt .details .details-icon > svg */
|
/* .details-icon — 对应 DoIt .details .details-icon > svg */
|
||||||
@@ -222,35 +262,25 @@
|
|||||||
transition: transform 0.2s ease;
|
transition: transform 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.series-nav[open] .details-icon > :global(svg) {
|
.series-nav.open .details-icon > :global(svg) {
|
||||||
transform: rotate(90deg);
|
transform: rotate(90deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .series-content — 展开收缩动画 */
|
/* .series-content — 展开收缩动画,与 admonition 完全一致 */
|
||||||
.series-nav .series-content {
|
.series-nav .details-content {
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
display: grid;
|
max-height: 0;
|
||||||
grid-template-rows: 0fr;
|
|
||||||
transition: grid-template-rows 0.3s ease-out;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
transition: max-height 0.3s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.series-nav[open] .series-content {
|
.series-nav .details-content > nav > ul {
|
||||||
grid-template-rows: 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
.series-nav .series-content > nav {
|
|
||||||
min-height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.series-nav .series-content > nav > ul {
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0.4rem 1rem 0.4rem 1.8rem;
|
padding: 0.4rem 1rem 0.4rem 1.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.series-nav .series-content ul {
|
.series-nav .details-content ul {
|
||||||
text-indent: -0.85rem;
|
text-indent: -0.85rem;
|
||||||
padding-left: 0.8rem;
|
padding-left: 0.8rem;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|||||||
Reference in new issue
Block a user