mirror of
https://github.com/reonokiy/blog.nokiy.net.git
synced 2025-06-17 03:56:19 +02:00
🚀 refactor: redesign the layout, reduce page size, and significantly improve build speed
This commit is contained in:
parent
89e1359bb5
commit
51ae238192
18 changed files with 390 additions and 486 deletions
67
src/components/Button.astro
Normal file
67
src/components/Button.astro
Normal file
|
@ -0,0 +1,67 @@
|
|||
---
|
||||
import { moreLocales } from '@/config'
|
||||
import { getNextGlobalLangPath, getNextSupportedLangPath } from '@/i18n/path'
|
||||
import { isPostPage, isTagPage } from '@/utils/page'
|
||||
|
||||
interface Props {
|
||||
supportedLangs: string[]
|
||||
}
|
||||
|
||||
const { supportedLangs } = Astro.props
|
||||
const currentPath = Astro.url.pathname
|
||||
const isPost = isPostPage(currentPath)
|
||||
const isTag = isTagPage(currentPath)
|
||||
|
||||
// Check if there are other languages to switch
|
||||
const showLanguageSwitcher = moreLocales.length > 0
|
||||
|
||||
// Check if only the supported language switch list is used
|
||||
const useSupportedLangs = isPost || (isTag && supportedLangs.length > 0)
|
||||
|
||||
// Choose a language switch list according to the page type
|
||||
const nextUrl = useSupportedLangs
|
||||
? getNextSupportedLangPath(currentPath, supportedLangs) // Switch between supported languages
|
||||
: getNextGlobalLangPath(currentPath) // Switch between all languages
|
||||
---
|
||||
|
||||
<div
|
||||
class:list={[
|
||||
'absolute flex gap-6 top-14.6 right-7.25vw min-[823px]:max-[1024px]:right-[calc(50vw-22rem)]',
|
||||
'[@supports(-webkit-touch-callout:none)]:top-13.6', // fix position issue on ios
|
||||
'lg:(fixed w-14rem top-auto bottom-47 right-[max(5.625rem,calc(50vw-34.375rem))])'
|
||||
]}
|
||||
>
|
||||
<!-- Language switcher -->
|
||||
{showLanguageSwitcher && (
|
||||
<a
|
||||
href={nextUrl}
|
||||
class="aspect-square w-4 c-secondary active:scale-90 hover:c-primary"
|
||||
aria-label="Switch website language"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
aria-hidden="true"
|
||||
class="h-full w-full"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path d="M19 21 12.3 2h-1L4.7 21l-2.5.2v.8h6.3v-.8L5.7 21l2-5.9h7.5l2 5.9-3.3.2v.8h7.9v-.8zM8 14.3l3.4-10.1 3.5 10.1z" />
|
||||
</svg>
|
||||
</a>
|
||||
)}
|
||||
|
||||
<!-- Theme toggle -->
|
||||
<button
|
||||
aria-label="Switch light/dark theme"
|
||||
class="button-theme-toggle aspect-square w-4.2 c-secondary active:scale-90 hover:c-primary"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path d="m12 1c-6.1 0-11 4.9-11 11s4.9 11 11 11 11-4.9 11-11-4.9-11-11-11m0 20c-5.8 0-10.5-4-10.5-9s4.7-9 10.5-9 10.5 4 10.5 9-4.7 9-10.5 9" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
|
@ -1,21 +1,18 @@
|
|||
---
|
||||
import LanguageSwitcher from '@/components/Widgets/LanguageSwitcher.astro'
|
||||
import ThemeToggle from '@/components/Widgets/ThemeToggle.astro'
|
||||
import { defaultLocale, themeConfig } from '@/config'
|
||||
import { getLangFromPath } from '@/i18n/lang'
|
||||
|
||||
interface Props {
|
||||
class?: string
|
||||
supportedLangs: string[]
|
||||
}
|
||||
|
||||
const { class: className, supportedLangs = [] } = Astro.props
|
||||
const { author } = themeConfig.site
|
||||
const { links: configLinks, startYear } = themeConfig.footer
|
||||
const { links: socialLinks, startYear } = themeConfig.footer
|
||||
|
||||
const currentYear = new Date().getFullYear()
|
||||
const year = Number(startYear) === currentYear
|
||||
? startYear
|
||||
: `${startYear}-${currentYear}`
|
||||
|
||||
// i18n rss path
|
||||
const currentLang = getLangFromPath(Astro.url.pathname)
|
||||
const links = configLinks.map((link) => {
|
||||
const links = socialLinks.map((link) => {
|
||||
if (link.name === 'RSS') {
|
||||
return {
|
||||
...link,
|
||||
|
@ -24,25 +21,12 @@ const links = configLinks.map((link) => {
|
|||
}
|
||||
return link
|
||||
})
|
||||
|
||||
const currentYear = new Date().getFullYear()
|
||||
const year = Number(startYear) === currentYear
|
||||
? startYear
|
||||
: `${startYear}-${currentYear}`
|
||||
---
|
||||
|
||||
<footer
|
||||
class:list={[
|
||||
'bottom-22 text-3 lg:text-3.5 leading-4.75 font-navbar',
|
||||
className,
|
||||
]}
|
||||
class="text-3 leading-4.75 font-navbar lg:text-3.5"
|
||||
lg="uno-desktop-column bottom-20"
|
||||
>
|
||||
<!-- Desktop widget -->
|
||||
<div class="mb-11.5 ml-1.5 hidden gap-7 lg:flex">
|
||||
<ThemeToggle />
|
||||
<LanguageSwitcher supportedLangs={supportedLangs} />
|
||||
</div>
|
||||
|
||||
<p>
|
||||
{links.map((link, index) => (
|
||||
<>
|
||||
|
|
64
src/components/Header.astro
Normal file
64
src/components/Header.astro
Normal file
|
@ -0,0 +1,64 @@
|
|||
---
|
||||
import themeConfig from '@/config'
|
||||
import { ui } from '@/i18n/ui'
|
||||
import { getPageInfo } from '@/utils/page'
|
||||
|
||||
const { currentLang, getLocalizedPath, isPost } = getPageInfo(Astro.url.pathname)
|
||||
const { title, subtitle, i18nTitle } = themeConfig.site
|
||||
const { titleGap } = themeConfig.global
|
||||
|
||||
const currentUI = ui[currentLang as keyof typeof ui]
|
||||
const headerTitle = i18nTitle ? currentUI.title : title
|
||||
const headerSubtitle = i18nTitle ? currentUI.subtitle : subtitle
|
||||
|
||||
const marginBottom = {
|
||||
1: 'mb-0.9',
|
||||
2: 'mb-1.8',
|
||||
3: 'mb-2.7',
|
||||
}[titleGap] || 'mb-1.8 '
|
||||
|
||||
const postMarginBottom = {
|
||||
1: 'mb-1.9 lg:mb-0.9',
|
||||
2: 'mb-2.8 lg:mb-1.8',
|
||||
3: 'mb-3.7 lg:mb-2.7',
|
||||
}[titleGap] || 'mb-2.8 lg:mb-1.8'
|
||||
|
||||
const TitleTag = isPost ? 'h2' : 'h1'
|
||||
const SubtitleTag = isPost ? 'div' : 'h2'
|
||||
---
|
||||
|
||||
<header
|
||||
class="mb-10.5"
|
||||
lg="uno-desktop-column top-20"
|
||||
>
|
||||
<TitleTag
|
||||
class:list={[
|
||||
isPost
|
||||
? `${postMarginBottom} mt-3.2 text-5.375 c-secondary lg:(mt-0 text-9 c-primary)`
|
||||
: `${marginBottom} text-8 w-75% c-primary lg:(text-9 w-full)`,
|
||||
'font-bold font-title',
|
||||
]}
|
||||
>
|
||||
<a
|
||||
href={getLocalizedPath('/')}
|
||||
transition:name={`site-title-${currentLang}`}
|
||||
data-disable-transition-on-theme
|
||||
>
|
||||
{headerTitle}
|
||||
</a>
|
||||
</TitleTag>
|
||||
|
||||
{headerSubtitle && (
|
||||
<SubtitleTag
|
||||
class:list={[
|
||||
isPost
|
||||
? `opacity-0 lg:opacity-100`
|
||||
: 'w-75% text-balance lg:w-full',
|
||||
'c-secondary font-navbar text-3.5 lg:text-4',
|
||||
]}
|
||||
aria-hidden={isPost}
|
||||
>
|
||||
{headerSubtitle}
|
||||
</SubtitleTag>
|
||||
)}
|
||||
</header>
|
|
@ -1,40 +0,0 @@
|
|||
---
|
||||
import themeConfig from '@/config'
|
||||
import { ui } from '@/i18n/ui'
|
||||
import { getPageInfo } from '@/utils/page'
|
||||
|
||||
const { currentLang, getLocalizedPath } = getPageInfo(Astro.url.pathname)
|
||||
const currentUI = ui[currentLang as keyof typeof ui]
|
||||
|
||||
const { title, subtitle, i18nTitle } = themeConfig.site
|
||||
const headerTitle = i18nTitle ? currentUI.title : title
|
||||
const headerSubtitle = i18nTitle ? currentUI.subtitle : subtitle
|
||||
|
||||
const { titleGap } = themeConfig.global
|
||||
const marginBottom = {
|
||||
1: 'mb-0.625',
|
||||
2: 'mb-1.875',
|
||||
3: 'mb-3.125',
|
||||
}[titleGap] || 'mb-3.125'
|
||||
---
|
||||
|
||||
<header class="mb-10.5 lg:fixed">
|
||||
<h1 class={`${marginBottom} text-8 c-primary font-bold font-title lg:(text-9 w-full) w-75%`}>
|
||||
<!-- Fix text cropping issues during view transition on ios by adding a div tag -->
|
||||
<div
|
||||
class="box-content inline-block pr-1.25"
|
||||
transition:name={`site-title-${currentLang}`}
|
||||
data-disable-transition-on-theme
|
||||
>
|
||||
<a href={getLocalizedPath('/')}>
|
||||
{headerTitle}
|
||||
</a>
|
||||
</div>
|
||||
</h1>
|
||||
|
||||
{headerSubtitle && (
|
||||
<h2 class="w-75% text-balance text-3.5 c-secondary font-navbar lg:(w-full text-4)">
|
||||
{headerSubtitle}
|
||||
</h2>
|
||||
)}
|
||||
</header>
|
|
@ -1,43 +0,0 @@
|
|||
---
|
||||
import themeConfig from '@/config'
|
||||
import { ui } from '@/i18n/ui'
|
||||
import { getPageInfo } from '@/utils/page'
|
||||
|
||||
const { currentLang, getLocalizedPath } = getPageInfo(Astro.url.pathname)
|
||||
const currentUI = ui[currentLang as keyof typeof ui]
|
||||
|
||||
const { title, subtitle, i18nTitle } = themeConfig.site
|
||||
const headerTitle = i18nTitle ? currentUI.title : title
|
||||
const headerSubtitle = i18nTitle ? currentUI.subtitle : subtitle
|
||||
|
||||
const { titleGap } = themeConfig.global
|
||||
const marginBottom = {
|
||||
1: 'mb-1.625',
|
||||
2: 'mb-2.875',
|
||||
3: 'mb-4.125',
|
||||
}[titleGap] || 'mb-2.875'
|
||||
---
|
||||
|
||||
<header class="mb-15 lg:hidden">
|
||||
<h2 class={`${marginBottom} mt-3 text-5.375 c-secondary font-bold font-title`}>
|
||||
<!-- Fix text cropping issues during view transition on ios by adding a div tag -->
|
||||
<div
|
||||
class="box-content inline-block pr-1.25"
|
||||
transition:name={`site-title-${currentLang}`}
|
||||
data-disable-transition-on-theme
|
||||
>
|
||||
<a href={getLocalizedPath('/')}>
|
||||
{headerTitle}
|
||||
</a>
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
{headerSubtitle && (
|
||||
<div
|
||||
class="text-3.5 opacity-0"
|
||||
aria-hidden="true"
|
||||
>
|
||||
{headerSubtitle}
|
||||
</div>
|
||||
)}
|
||||
</header>
|
|
@ -33,8 +33,11 @@ const navItems = [
|
|||
---
|
||||
|
||||
<nav
|
||||
class="mb-10.5 text-3.6 font-semibold leading-8.75 font-navbar"
|
||||
lg="fixed bottom-50 text-4 leading-9.72"
|
||||
class:list={[
|
||||
isPost ? 'hidden lg:block' : '',
|
||||
'mb-10.5 text-3.6 font-semibold leading-8.75 font-navbar',
|
||||
'lg:(uno-desktop-column text-4 leading-9.72 bottom-50)',
|
||||
]}
|
||||
>
|
||||
<ul>
|
||||
{navItems.map(item => (
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
---
|
||||
import { moreLocales } from '@/config'
|
||||
import { getNextGlobalLangPath, getNextSupportedLangPath } from '@/i18n/path'
|
||||
import { isPostPage, isTagPage } from '@/utils/page'
|
||||
|
||||
interface Props {
|
||||
supportedLangs: string[]
|
||||
}
|
||||
|
||||
const { supportedLangs } = Astro.props
|
||||
const currentPath = Astro.url.pathname
|
||||
const isPost = isPostPage(currentPath)
|
||||
const isTag = isTagPage(currentPath)
|
||||
|
||||
// Check if there are other languages to switch
|
||||
const showLanguageSwitcher = moreLocales.length > 0
|
||||
|
||||
// Check if only the supported language switch list is used
|
||||
const useSupportedLangs = isPost || (isTag && supportedLangs.length > 0)
|
||||
|
||||
// Choose a language switch list according to the page type
|
||||
const nextUrl = useSupportedLangs
|
||||
? getNextSupportedLangPath(currentPath, supportedLangs) // Switch between supported languages
|
||||
: getNextGlobalLangPath(currentPath) // Switch between all languages
|
||||
---
|
||||
|
||||
{showLanguageSwitcher && (
|
||||
<a
|
||||
href={nextUrl}
|
||||
class="aspect-square w-4 c-secondary active:scale-90 hover:c-primary"
|
||||
aria-label="Switch website language"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
aria-hidden="true"
|
||||
class="h-full w-full"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path d="M19 21 12.3 2h-1L4.7 21l-2.5.2v.8h6.3v-.8L5.7 21l2-5.9h7.5l2 5.9-3.3.2v.8h7.9v-.8zM8 14.3l3.4-10.1 3.5 10.1z" />
|
||||
</svg>
|
||||
</a>
|
||||
)}
|
|
@ -1,13 +0,0 @@
|
|||
<button
|
||||
aria-label="Switch light/dark theme"
|
||||
class="button-theme-toggle aspect-square w-4.2 c-secondary active:scale-90 hover:c-primary"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
aria-hidden="true"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path d="m12 1c-6.1 0-11 4.9-11 11s4.9 11 11 11 11-4.9 11-11-4.9-11-11-11m0 20c-5.8 0-10.5-4-10.5-9s4.7-9 10.5-9 10.5 4 10.5 9-4.7 9-10.5 9" />
|
||||
</svg>
|
||||
</button>
|
Loading…
Add table
Add a link
Reference in a new issue