mirror of https://github.com/VERT-sh/VERT.git
feat: sliding navbar
This commit is contained in:
parent
c88112d226
commit
ef20f76a85
|
@ -7,6 +7,8 @@
|
||||||
import { theme } from "$lib/store/index.svelte";
|
import { theme } from "$lib/store/index.svelte";
|
||||||
import { blur, duration } from "$lib/animation";
|
import { blur, duration } from "$lib/animation";
|
||||||
import { quintOut } from "svelte/easing";
|
import { quintOut } from "svelte/easing";
|
||||||
|
import { browser } from "$app/environment";
|
||||||
|
import type { SvelteComponent } from "svelte";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
items: {
|
items: {
|
||||||
|
@ -19,17 +21,32 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
let { items }: Props = $props();
|
let { items }: Props = $props();
|
||||||
|
|
||||||
|
let links = $state<HTMLAnchorElement[]>([]);
|
||||||
|
let container = $state<HTMLDivElement>();
|
||||||
|
let containerRect = $derived(container?.getBoundingClientRect());
|
||||||
|
$effect(() => {
|
||||||
|
$inspect(containerRect);
|
||||||
|
});
|
||||||
|
|
||||||
|
const linkRects = $derived(links.map((l) => l.getBoundingClientRect()));
|
||||||
|
|
||||||
|
const selectedIndex = $derived(
|
||||||
|
items.findIndex((i) => i.activeMatch($page.url.pathname)),
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#snippet link(item: (typeof items)[0])}
|
{#snippet link(item: (typeof items)[0], index: number)}
|
||||||
{@const Icon = item.icon}
|
{@const Icon = item.icon}
|
||||||
<a
|
<a
|
||||||
|
bind:this={links[index]}
|
||||||
href={item.url}
|
href={item.url}
|
||||||
aria-label={item.name}
|
aria-label={item.name}
|
||||||
class={clsx(
|
class={clsx(
|
||||||
"w-32 h-full rounded-xl flex items-center justify-center gap-3 overflow-hidden",
|
"w-32 h-full relative z-10 rounded-xl flex items-center justify-center gap-3 overflow-hidden",
|
||||||
{
|
{
|
||||||
"bg-panel-accented": item.activeMatch($page.url.pathname),
|
"bg-panel-accented":
|
||||||
|
item.activeMatch($page.url.pathname) && !browser,
|
||||||
},
|
},
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
@ -117,23 +134,36 @@
|
||||||
</a>
|
</a>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
|
|
||||||
<Panel class="w-fit h-20 flex items-center gap-3">
|
<div bind:this={container}>
|
||||||
<div
|
<Panel class="w-fit h-20 flex items-center gap-3 relative">
|
||||||
class="w-32 h-full bg-accent rounded-xl flex items-center justify-center"
|
{#if linkRects[selectedIndex]}
|
||||||
>
|
<div
|
||||||
<div class="h-5 w-full">
|
class="absolute bg-panel-accented rounded-xl"
|
||||||
<Logo />
|
style="width: {linkRects[selectedIndex]
|
||||||
|
.width}px; height: {linkRects[selectedIndex]
|
||||||
|
.height}px; top: {linkRects[selectedIndex].top -
|
||||||
|
32}px; left: {linkRects[selectedIndex].left -
|
||||||
|
(containerRect?.left ||
|
||||||
|
0)}px; transition: left var(--transition) {duration}ms, top var(--transition) {duration}ms;"
|
||||||
|
></div>
|
||||||
|
{/if}
|
||||||
|
<div
|
||||||
|
class="w-32 h-full bg-accent rounded-xl flex items-center justify-center"
|
||||||
|
>
|
||||||
|
<div class="h-5 w-full">
|
||||||
|
<Logo />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{#each items as item, i (item.url)}
|
||||||
{#each items as item (item.url)}
|
{@render link(item, i)}
|
||||||
{@render link(item)}
|
{/each}
|
||||||
{/each}
|
<div class="w-0.5 bg-separator h-full"></div>
|
||||||
<div class="w-0.5 bg-separator h-full"></div>
|
<button
|
||||||
<button
|
onclick={theme.toggle}
|
||||||
onclick={theme.toggle}
|
class="w-14 h-full flex items-center justify-center"
|
||||||
class="w-14 h-full flex items-center justify-center"
|
>
|
||||||
>
|
<SunIcon class="dynadark:hidden block" />
|
||||||
<SunIcon class="dynadark:hidden block" />
|
<MoonIcon class="dynadark:block hidden" />
|
||||||
<MoonIcon class="dynadark:block hidden" />
|
</button>
|
||||||
</button>
|
</Panel>
|
||||||
</Panel>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { blur, duration } from "$lib/animation";
|
||||||
import Dropdown from "$lib/components/functional/Dropdown.svelte";
|
import Dropdown from "$lib/components/functional/Dropdown.svelte";
|
||||||
import Uploader from "$lib/components/functional/Uploader.svelte";
|
import Uploader from "$lib/components/functional/Uploader.svelte";
|
||||||
|
import ProgressiveBlur from "$lib/components/visual/effects/ProgressiveBlur.svelte";
|
||||||
import Panel from "$lib/components/visual/Panel.svelte";
|
import Panel from "$lib/components/visual/Panel.svelte";
|
||||||
import ProgressBar from "$lib/components/visual/ProgressBar.svelte";
|
import ProgressBar from "$lib/components/visual/ProgressBar.svelte";
|
||||||
import { files } from "$lib/store/index.svelte";
|
import { files } from "$lib/store/index.svelte";
|
||||||
|
@ -12,6 +14,7 @@
|
||||||
RotateCwIcon,
|
RotateCwIcon,
|
||||||
XIcon,
|
XIcon,
|
||||||
} from "lucide-svelte";
|
} from "lucide-svelte";
|
||||||
|
import { quintOut } from "svelte/easing";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#snippet fileItem(file: VertFile, index: number)}
|
{#snippet fileItem(file: VertFile, index: number)}
|
||||||
|
@ -107,3 +110,36 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="fixed w-screen h-screen opacity-75 overflow-hidden top-0 left-0 -z-50 pointer-events-none grid grid-cols-1 grid-rows-1"
|
||||||
|
>
|
||||||
|
{#if files.files.length === 1}
|
||||||
|
<div
|
||||||
|
class="w-full relative"
|
||||||
|
transition:blur={{
|
||||||
|
blurMultiplier: 24,
|
||||||
|
duration,
|
||||||
|
easing: quintOut,
|
||||||
|
scale: {
|
||||||
|
start: 1.02,
|
||||||
|
end: 1,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
class="object-cover w-full h-full blur-xs"
|
||||||
|
src={files.files[0].blobUrl}
|
||||||
|
alt={files.files[0].name}
|
||||||
|
/>
|
||||||
|
<div class="absolute bottom-0 left-0 w-full h-full">
|
||||||
|
<ProgressiveBlur
|
||||||
|
direction="bottom"
|
||||||
|
endIntensity={256}
|
||||||
|
iterations={8}
|
||||||
|
fadeTo="var(--bg)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue