fix: header and head

This commit is contained in:
sevichecc 2022-11-17 22:37:03 +08:00
parent bc5317aa93
commit 254fc15d16
4 changed files with 100 additions and 177 deletions

View file

@ -37,6 +37,7 @@
"@sveltejs/adapter-static": "1.0.0-next.48", "@sveltejs/adapter-static": "1.0.0-next.48",
"@sveltejs/kit": "1.0.0-next.551", "@sveltejs/kit": "1.0.0-next.551",
"@tailwindcss/typography": "^0.5.8", "@tailwindcss/typography": "^0.5.8",
"@sveltejs/adapter-netlify": "1.0.0-next.84",
"@types/node": "^18.11.9", "@types/node": "^18.11.9",
"@types/unist": "^2.0.6", "@types/unist": "^2.0.6",
"@types/workbox-build": "^5.0.1", "@types/workbox-build": "^5.0.1",

View file

@ -9,6 +9,7 @@ specifiers:
'@iconify-json/simple-icons': 1.1.34 '@iconify-json/simple-icons': 1.1.34
'@iconify-json/uil': ^1.1.2 '@iconify-json/uil': ^1.1.2
'@sveltejs/adapter-auto': 1.0.0-next.88 '@sveltejs/adapter-auto': 1.0.0-next.88
'@sveltejs/adapter-netlify': 1.0.0-next.84
'@sveltejs/adapter-node': 1.0.0-next.100 '@sveltejs/adapter-node': 1.0.0-next.100
'@sveltejs/adapter-static': 1.0.0-next.48 '@sveltejs/adapter-static': 1.0.0-next.48
'@sveltejs/kit': 1.0.0-next.551 '@sveltejs/kit': 1.0.0-next.551
@ -71,6 +72,7 @@ devDependencies:
'@iconify-json/simple-icons': 1.1.34 '@iconify-json/simple-icons': 1.1.34
'@iconify-json/uil': 1.1.2 '@iconify-json/uil': 1.1.2
'@sveltejs/adapter-auto': 1.0.0-next.88 '@sveltejs/adapter-auto': 1.0.0-next.88
'@sveltejs/adapter-netlify': 1.0.0-next.84
'@sveltejs/adapter-node': 1.0.0-next.100 '@sveltejs/adapter-node': 1.0.0-next.100
'@sveltejs/adapter-static': 1.0.0-next.48 '@sveltejs/adapter-static': 1.0.0-next.48
'@sveltejs/kit': 1.0.0-next.551_svelte@3.53.1+vite@3.2.4 '@sveltejs/kit': 1.0.0-next.551_svelte@3.53.1+vite@3.2.4
@ -1410,6 +1412,10 @@ packages:
resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
dev: true dev: true
/@iarna/toml/2.2.5:
resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==}
dev: true
/@iconify-json/heroicons-outline/1.1.4: /@iconify-json/heroicons-outline/1.1.4:
resolution: {integrity: sha512-H59TKT8dK6SDonC0NXeT021Erhq7n0apg+41cUDFgv3Zps4x+2t2Sd3QWI5cs6sW/kpOlY8DTP0xUtF5T/bp4w==} resolution: {integrity: sha512-H59TKT8dK6SDonC0NXeT021Erhq7n0apg+41cUDFgv3Zps4x+2t2Sd3QWI5cs6sW/kpOlY8DTP0xUtF5T/bp4w==}
dependencies: dependencies:
@ -2592,6 +2598,14 @@ packages:
import-meta-resolve: 2.1.0 import-meta-resolve: 2.1.0
dev: true dev: true
/@sveltejs/adapter-netlify/1.0.0-next.84:
resolution: {integrity: sha512-i4vf3to0sV/iI39UPPhlVjOP+jZCZ048M4oHkqDM1FfJwACwgXaysdF2t4X0DV3loLmrkfarwbatjbGIECA9uQ==}
dependencies:
'@iarna/toml': 2.2.5
esbuild: 0.15.14
set-cookie-parser: 2.5.1
dev: true
/@sveltejs/adapter-node/1.0.0-next.100: /@sveltejs/adapter-node/1.0.0-next.100:
resolution: {integrity: sha512-XtyweoRcrnD3T/hkqv4XAlhU24VM6/QiUqR2mfs7I3Ji/KrBKWSM2GCpSptnfk3mELK193sJ0T4m6Z3x8uf47w==} resolution: {integrity: sha512-XtyweoRcrnD3T/hkqv4XAlhU24VM6/QiUqR2mfs7I3Ji/KrBKWSM2GCpSptnfk3mELK193sJ0T4m6Z3x8uf47w==}
dependencies: dependencies:

View file

@ -1,133 +1,39 @@
<script lang="ts"> <script lang="ts">
import { browser, dev } from '$app/environment' import { dev } from '$app/environment'
import { fly } from 'svelte/transition' import { head } from '$lib/config/general'
import { site } from '$lib/config/site' import { site } from '$lib/config/site'
import { theme } from '$lib/config/general' import OpenGraph from '$lib/components/head_opengraph.svelte'
import { title as storedTitle } from '$lib/stores/title' export let post: Urara.Post | undefined = undefined
import { header as headerConfig } from '$lib/config/general' export let page: Urara.Page | undefined = undefined
import { hslToHex } from '$lib/utils/color'
import Nav from '$lib/components/header_nav.svelte'
import Search from '$lib/components/header_search.svelte'
export let path: string
let title: string
let currentTheme: string
let currentThemeColor: string
let search: boolean = false
let pin: boolean = true
let percent: number
let [scrollY, lastY] = [0, 0]
storedTitle.subscribe(storedTitle => (title = storedTitle as string))
$: if (browser && currentTheme) {
document.documentElement.setAttribute('data-theme', currentTheme)
currentThemeColor = hslToHex(
...(getComputedStyle(document.documentElement)
.getPropertyValue('--b1')
.slice(dev ? 1 : 0)
.replaceAll('%', '')
.split(' ')
.map(Number) as [number, number, number])
)
}
$: if (scrollY) {
pin = lastY - scrollY > 0 || scrollY === 0 ? true : false
lastY = scrollY
if (browser)
percent =
Math.round((scrollY / (document.documentElement.scrollHeight - document.documentElement.clientHeight)) * 10000) / 100
}
if (browser)
currentTheme =
localStorage.getItem('theme') ?? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
</script> </script>
<svelte:head> <svelte:head>
<meta name="theme-color" content={currentThemeColor} /> <meta name="author" content={site.author?.name} />
{#if post}
<link rel="canonical" href={site.protocol + site.domain + post.path} />
{#if post.type === 'article'}
<title>{post.title} | {site.title}</title>
{:else if post.type === 'note'}
<title>{post.summary ?? post.path.slice(1)} | {site.title}</title>
{/if}
{#if post.tags}<meta name="keywords" content={post.tags.join(', ')} />{/if}
{#if post.summary}<meta name="description" content={post.summary} />{/if}
{:else}
<meta name="description" content={site.description} />
<meta name="keywords" content={site.keywords?.join(', ')} />
{#if page}
<title>{page.title ?? page.path.slice(1)} | {site.title}</title>
<link rel="canonical" href={site.protocol + site.domain + page.path} />
{:else}
<title>{site.subtitle ? `${site.title} - ${site.subtitle}` : site.title}</title>
<link rel="canonical" href={site.protocol + site.domain} />
{/if}
{/if}
{#if head.custom}
{#each head.custom({ dev, post, page }) as tag}
{@html tag}
{/each}
{/if}
</svelte:head> </svelte:head>
<svelte:window bind:scrollY /> <OpenGraph {post} {page} />
<header
id="header"
class:-translate-y-32={!pin && scrollY > 0}
class="fixed z-50 w-screen transition-all duration-500 ease-in-out border-b-2 border-transparent max-h-[4.125rem] {scrollY >
32 && 'backdrop-blur border-base-content/10 bg-base-100/30 md:bg-base-200/30'}">
{#if !search}
<div in:fly={{ x: -50, duration: 300, delay: 300 }} out:fly={{ x: -50, duration: 300 }} class="navbar">
<div class="navbar-start">
{#if headerConfig.nav}
<Nav {path} {title} {pin} {scrollY} nav={headerConfig.nav} />
{/if}
<a href="/" sveltekit:prefetch class="btn btn-ghost normal-case text-lg">{site.title}</a>
</div>
<div class="navbar-end">
{#if headerConfig.search}
<button aria-label="search" on:click={() => (search = !search)} tabindex="0" class="btn btn-square btn-ghost">
<span class="i-heroicons-outline-search" />
</button>
{/if}
<div id="change-theme" class="dropdown dropdown-end">
<div tabindex="0" class="btn btn-square btn-ghost">
<span class="i-heroicons-outline-color-swatch" />
</div>
<ul
tabindex="0"
class="flex flex-nowrap shadow-2xl menu dropdown-content bg-base-100 text-base-content rounded-box w-52 p-2 gap-2 overflow-y-auto max-h-[21.5rem]"
class:hidden={!pin}>
{#each theme as { name, text }}
<button
data-theme={name}
on:click={() => {
currentTheme = name
localStorage.setItem('theme', name)
}}
class:border-2={currentTheme === name}
class:border-primary={currentTheme === name}
class="btn btn-ghost w-full hover:bg-primary group rounded-lg flex bg-base-100 p-2 transition-all">
<p class="flex-1 text-left text-base-content group-hover:text-primary-content transition-color">
{text ?? name}
</p>
<div class="flex-none m-auto flex gap-1">
<div class="bg-primary w-2 h-4 rounded" />
<div class="bg-secondary w-2 h-4 rounded" />
<div class="bg-accent w-2 h-4 rounded" />
<div class="bg-neutral w-2 h-4 rounded" />
</div>
</button>
{/each}
</ul>
</div>
</div>
</div>
{:else}
<div in:fly={{ x: 50, duration: 300, delay: 300 }} out:fly={{ x: 50, duration: 300 }} class="navbar">
<Search />
<button on:click={() => (search = !search)} tabindex="0" class="btn btn-square btn-ghost">
<span class="i-heroicons-outline-x" />
</button>
</div>
{/if}
</header>
<button
id="totop"
on:click={() => window.scrollTo(0, 0)}
class:translate-y-24={!pin || scrollY === 0}
aria-label="scroll to top"
class="fixed grid group btn btn-circle btn-lg border-none backdrop-blur bottom-6 right-6 z-50 duration-500 ease-in-out {percent >
95
? 'btn-accent shadow-lg'
: 'btn-ghost bg-base-100/30 md:bg-base-200/30'}"
class:opacity-100={scrollY}>
<div
class="radial-progress text-accent transition-all duration-500 ease-in-out group-hover:text-accent-focus col-start-1 row-start-1"
style={`--size:4rem; --thickness: 0.25rem; --value:${percent};`} />
<div
class:border-transparent={percent > 95}
class="border-4 border-base-content/10 group-hover:border-transparent col-start-1 row-start-1 rounded-full w-full h-full p-4 grid duration-500 ease-in-out">
<span class="i-heroicons-solid-chevron-up !w-6 !h-6" />
</div>
</button>

View file

@ -41,7 +41,7 @@
if (browser) if (browser)
currentTheme = currentTheme =
localStorage.getItem('theme') ?? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'night' : 'lemonade') localStorage.getItem('theme') ?? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
</script> </script>
<svelte:head> <svelte:head>
@ -55,59 +55,61 @@
class:-translate-y-32={!pin && scrollY > 0} class:-translate-y-32={!pin && scrollY > 0}
class="fixed z-50 w-screen transition-all duration-500 ease-in-out border-b-2 border-transparent max-h-[4.125rem] {scrollY > class="fixed z-50 w-screen transition-all duration-500 ease-in-out border-b-2 border-transparent max-h-[4.125rem] {scrollY >
32 && 'backdrop-blur border-base-content/10 bg-base-100/30 md:bg-base-200/30'}"> 32 && 'backdrop-blur border-base-content/10 bg-base-100/30 md:bg-base-200/30'}">
<div in:fly={{ x: -50, duration: 300, delay: 300 }} out:fly={{ x: -50, duration: 300 }} class="navbar"> {#if !search}
<div class="navbar-start"> <div in:fly={{ x: -50, duration: 300, delay: 300 }} out:fly={{ x: -50, duration: 300 }} class="navbar">
{#if headerConfig.nav} <div class="navbar-start">
<Nav {path} {title} {pin} {scrollY} nav={headerConfig.nav} /> {#if headerConfig.nav}
{/if} <Nav {path} {title} {pin} {scrollY} nav={headerConfig.nav} />
<a href="/" sveltekit:prefetch class="btn btn-ghost normal-case text-lg">{site.title}</a> {/if}
</div> <a href="/" sveltekit:prefetch class="btn btn-ghost normal-case text-lg">{site.title}</a>
<div class="navbar-end"> </div>
<!-- {#if headerConfig.search} --> <div class="navbar-end">
<!-- The button to open modal --> {#if headerConfig.search}
<!-- <label for="search-modal" class="btn btn-square btn-ghost ml-2"><span class="i-heroicons-outline-search" /></label> --> <button aria-label="search" on:click={() => (search = !search)} tabindex="0" class="btn btn-square btn-ghost">
<!-- <button
on:click={() => {
search = !search
}}
type="submit"
class="btn btn-square btn-ghost ml-2">
<span class="i-heroicons-outline-search" /> <span class="i-heroicons-outline-search" />
</button> --> </button>
<!-- {/if} --> {/if}
<div id="change-theme" class="dropdown dropdown-end"> <div id="change-theme" class="dropdown dropdown-end">
<div tabindex="0" class="btn btn-square btn-ghost"> <div tabindex="0" class="btn btn-square btn-ghost">
<span class="i-heroicons-outline-color-swatch" /> <span class="i-heroicons-outline-color-swatch" />
</div>
<ul
tabindex="0"
class="flex flex-nowrap shadow-2xl menu dropdown-content bg-base-100 text-base-content rounded-box w-52 p-2 gap-2 overflow-y-auto max-h-[21.5rem]"
class:hidden={!pin}>
{#each theme as { name, text }}
<button
data-theme={name}
on:click={() => {
currentTheme = name
localStorage.setItem('theme', name)
}}
class:border-2={currentTheme === name}
class:border-primary={currentTheme === name}
class="btn btn-ghost w-full hover:bg-primary group rounded-lg flex bg-base-100 p-2 transition-all">
<p class="flex-1 text-left text-base-content group-hover:text-primary-content transition-color">
{text ?? name}
</p>
<div class="flex-none m-auto flex gap-1">
<div class="bg-primary w-2 h-4 rounded" />
<div class="bg-secondary w-2 h-4 rounded" />
<div class="bg-accent w-2 h-4 rounded" />
<div class="bg-neutral w-2 h-4 rounded" />
</div>
</button>
{/each}
</ul>
</div> </div>
<ul
tabindex="0"
class=" grid grid-cols-1 shadow-2xl menu dropdown-content bg-base-100 text-base-content rounded-box w-52 p-2 gap-2 overflow-y-auto max-h-[21.5rem]"
class:hidden={!pin}>
{#each theme as { name, text }}
<button
data-theme={name}
on:click={() => {
currentTheme = name
localStorage.setItem('theme', name)
}}
class:border-2={currentTheme === name}
class:border-primary={currentTheme === name}
class="btn btn-ghost hover:bg-primary group rounded-lg flex bg-base-100 p-2 transition-all">
<p class="flex-1 text-left text-base-content group-hover:text-primary-content transition-color">
{text ?? name}
</p>
<div class="flex-none m-auto flex gap-1">
<div class="bg-primary w-2 h-4 rounded" />
<div class="bg-secondary w-2 h-4 rounded" />
<div class="bg-accent w-2 h-4 rounded" />
<div class="bg-neutral w-2 h-4 rounded" />
</div>
</button>
{/each}
</ul>
</div> </div>
</div> </div>
</div> {:else}
<div in:fly={{ x: 50, duration: 300, delay: 300 }} out:fly={{ x: 50, duration: 300 }} class="navbar">
<Search />
<button on:click={() => (search = !search)} tabindex="0" class="btn btn-square btn-ghost">
<span class="i-heroicons-outline-x" />
</button>
</div>
{/if}
</header> </header>
<button <button
@ -128,4 +130,4 @@
class="border-4 border-base-content/10 group-hover:border-transparent col-start-1 row-start-1 rounded-full w-full h-full p-4 grid duration-500 ease-in-out"> class="border-4 border-base-content/10 group-hover:border-transparent col-start-1 row-start-1 rounded-full w-full h-full p-4 grid duration-500 ease-in-out">
<span class="i-heroicons-solid-chevron-up !w-6 !h-6" /> <span class="i-heroicons-solid-chevron-up !w-6 !h-6" />
</div> </div>
</button> </button>