fix: TOC component overflows the webpage (#209)

This commit is contained in:
saicaca 2024-10-28 18:44:06 +08:00
parent 18fcf6dd83
commit e1a98c4149
4 changed files with 32 additions and 12 deletions

View File

@ -51,10 +51,10 @@ const maxLevel = siteConfig.toc.depth;
---
<div class:list={[className]}>
{headings.filter((heading) => heading.depth < minDepth + maxLevel).map((heading) =>
<a href={`#${heading.slug}`} class="px-2 transition flex w-full gap-2 h-9 rounded-xl items-center
hover:bg-[var(--toc-btn-hover)] active:bg-[var(--toc-btn-active)]
<a href={`#${heading.slug}`} class="px-2 flex gap-2 relative transition w-full min-h-9 rounded-xl
hover:bg-[var(--toc-btn-hover)] active:bg-[var(--toc-btn-active)] py-2
">
<div class:list={["w-5 h-5 rounded-lg text-xs flex items-center justify-center font-bold",
<div class:list={["w-5 h-5 shrink-0 rounded-lg text-xs flex items-center justify-center font-bold",
{
"bg-[var(--toc-badge-bg)] text-[var(--btn-content)]": heading.depth == minDepth,
"ml-4": heading.depth == minDepth + 1,

View File

@ -14,3 +14,6 @@ export const BANNER_HEIGHT_HOME = BANNER_HEIGHT + BANNER_HEIGHT_EXTEND
// The height the main panel overlaps the banner, unit: rem
export const MAIN_PANEL_OVERLAPS_BANNER_HEIGHT = 3.5
// Page width: rem
export const PAGE_WIDTH = 75

View File

@ -15,6 +15,7 @@ import {
BANNER_HEIGHT,
BANNER_HEIGHT_EXTEND,
BANNER_HEIGHT_HOME,
PAGE_WIDTH,
} from '../constants/constants'
import { defaultFavicons } from '../constants/icon'
import type { Favicon } from '../types/config'
@ -108,8 +109,14 @@ const bannerOffset =
media={favicon.theme && `(prefers-color-scheme: ${favicon.theme})`}
/>
))}
<style define:vars={{
configHue,
'page-width': `${PAGE_WIDTH}rem`,
}}></style> <!-- defines global css variables. This will be applied to <html> <body> and some other elements idk why -->
<!-- Set the theme before the page is rendered to avoid a flash -->
<script is:inline define:vars={{DEFAULT_THEME, LIGHT_MODE, DARK_MODE, AUTO_MODE, BANNER_HEIGHT_EXTEND}}>
<script is:inline define:vars={{DEFAULT_THEME, LIGHT_MODE, DARK_MODE, AUTO_MODE, BANNER_HEIGHT_EXTEND, PAGE_WIDTH}}>
const theme = localStorage.getItem('theme') || DEFAULT_THEME;
switch (theme) {
case LIGHT_MODE:
@ -130,6 +137,12 @@ const bannerOffset =
let offset = Math.floor(window.innerHeight * (BANNER_HEIGHT_EXTEND / 100));
offset = offset - offset % 4;
document.documentElement.style.setProperty('--banner-height-extend', `${offset}px`);
// calculate the width of TOC widget
const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize)
const mainGridWidthPx = PAGE_WIDTH * rootFontSize
const tocWidth = (window.innerWidth - mainGridWidthPx) / 2 - rootFontSize
document.documentElement.style.setProperty('--toc-width', `${tocWidth}px`);
</script>
<slot name="head"></slot>
@ -138,8 +151,6 @@ const bannerOffset =
<link rel="alternate" type="application/rss+xml" title={profileConfig.name} href={`${Astro.site}rss.xml`}/>
<style define:vars={{ configHue }}></style> <!-- defines global css variables. This will be applied to <html> <body> and some other elements idk why -->
</head>
<body class=" min-h-screen transition " class:list={[{"lg:is-home": isHomePage, "enable-banner": enableBanner}]}
data-overlayscrollbars-initialize
@ -157,7 +168,6 @@ const bannerOffset =
<style is:global>
:root {
--hue: var(--configHue);
--page-width: 75rem;
}
</style>
@ -210,7 +220,8 @@ import {
BANNER_HEIGHT,
BANNER_HEIGHT_HOME,
BANNER_HEIGHT_EXTEND,
MAIN_PANEL_OVERLAPS_BANNER_HEIGHT
MAIN_PANEL_OVERLAPS_BANNER_HEIGHT,
PAGE_WIDTH
} from "../constants/constants";
/* Preload fonts */
@ -463,11 +474,17 @@ function scrollFunction() {
}
window.onscroll = scrollFunction
// calculate the --banner-height-extend, which needs to be a multiple of 4 to avoid blurry text
window.onresize = () => {
// calculate the --banner-height-extend, which needs to be a multiple of 4 to avoid blurry text
let offset = Math.floor(window.innerHeight * (BANNER_HEIGHT_EXTEND / 100));
offset = offset - offset % 4;
document.documentElement.style.setProperty('--banner-height-extend', `${offset}px`);
// calculate the width of TOC widget
const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize)
const mainGridWidthPx = PAGE_WIDTH * rootFontSize
const tocWidth = (window.innerWidth - mainGridWidthPx) / 2 - rootFontSize
document.documentElement.style.setProperty('--toc-width', `${tocWidth}px`);
}
</script>

View File

@ -93,8 +93,8 @@ const mainPanelTop = siteConfig.banner.enable ? `calc(${BANNER_HEIGHT}vh - ${MAI
<div class="absolute w-full z-0">
<div class="relative max-w-[var(--page-width)] mx-auto">
<!-- TOC component -->
{siteConfig.toc.enable && <div id="toc-wrapper" class="transition absolute top-0 -right-[30rem] w-[30rem] flex items-center toc-hide">
<div id="toc-inner-wrapper" class="fixed top-14 w-96 h-[calc(100vh_-_20rem)] overflow-y-scroll overflow-x-hidden hide-scrollbar">
{siteConfig.toc.enable && <div id="toc-wrapper" class="transition absolute top-0 -right-[var(--toc-width)] w-[var(--toc-width)] flex items-center toc-hide">
<div id="toc-inner-wrapper" class="fixed top-14 w-[var(--toc-width)] h-[calc(100vh_-_20rem)] overflow-y-scroll overflow-x-hidden hide-scrollbar">
<div id="toc" class="w-full h-full transition-swup-fade">
<div class="h-8 w-full"></div>
<TOC headings={headings}></TOC>