73 lines
1.8 KiB
Svelte
73 lines
1.8 KiB
Svelte
<script lang="ts">
|
|
import { page } from '$app/stores'
|
|
import { getContext } from 'svelte'
|
|
import { fly, reveal } from '$animations/index'
|
|
// Components
|
|
import Icon from '$components/atoms/Icon.svelte'
|
|
|
|
export let isOver: boolean = false
|
|
|
|
const { settings: { switcher_links } } = getContext('global')
|
|
|
|
let switcherEl: HTMLElement
|
|
let isOpen = false
|
|
|
|
|
|
/**
|
|
* Toggle switcher open state
|
|
*/
|
|
const toggleSwitcher = () => {
|
|
isOpen = !isOpen
|
|
}
|
|
|
|
|
|
/**
|
|
* Detect outside click
|
|
*/
|
|
const windowClick = ({ target }) => {
|
|
if (!switcherEl.contains(target) && isOpen) {
|
|
// Close switcher
|
|
toggleSwitcher()
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<svelte:window on:click={windowClick} />
|
|
|
|
<aside class="switcher" bind:this={switcherEl}
|
|
class:is-open={isOpen}
|
|
class:is-over={isOver}
|
|
use:reveal={{
|
|
animation: fly,
|
|
options: {
|
|
from: 24,
|
|
to: 0,
|
|
duration: 1000,
|
|
easing: 'easeOutQuart',
|
|
delay: 600,
|
|
}
|
|
}}
|
|
>
|
|
<ul class="switcher__links">
|
|
{#each switcher_links as { text, url, icon, icon_label }}
|
|
<li class:is-active={$page.url.pathname.startsWith(url)}>
|
|
<a href={url} on:click={toggleSwitcher}
|
|
sveltekit:noscroll sveltekit:prefetch
|
|
>
|
|
<Icon class="icon" icon={icon} label={icon_label} />
|
|
<span>{text}</span>
|
|
</a>
|
|
</li>
|
|
{/each}
|
|
</ul>
|
|
|
|
<button class="switcher__button" title="{!isOpen ? 'Open' : 'Close'} menu" tabindex="0"
|
|
on:click={toggleSwitcher}
|
|
>
|
|
<span>
|
|
{#each Array(3) as _}
|
|
<i />
|
|
{/each}
|
|
</span>
|
|
</button>
|
|
</aside> |