Files
housesof/apps/website/src/components/molecules/Switcher/Switcher.svelte
Félix Péault 6f8a619af2 refactor: migrate to Svelte 5
use runes ($props, $state, $derived, $effect, etc)
2024-08-02 17:50:16 +02:00

79 lines
1.9 KiB
Svelte

<style lang="scss">
@import "./Switcher";
</style>
<script lang="ts">
import { page } from '$app/stores'
import { getContext } from 'svelte'
import reveal from '$animations/reveal'
import { sendEvent } from '$utils/analytics'
// Components
import Icon from '$components/atoms/Icon.svelte'
const { settings: { switcher_links } }: any = getContext('global')
let switcherEl = $state<HTMLElement>()
let isOpen = $state(false)
/**
* Toggle switcher open state
*/
const toggleSwitcher = () => {
isOpen = !isOpen
// Record opening event
!isOpen && sendEvent('switcherOpen')
}
/**
* Detect outside click
*/
const windowClick = ({ target }) => {
if (!switcherEl.contains(target) && isOpen) {
// Close switcher
toggleSwitcher()
}
}
</script>
<svelte:window onclick={windowClick} />
<aside
bind:this={switcherEl}
class="switcher"
class:is-open={isOpen}
use:reveal={{
animation: { y: [24, 0], opacity: [0, 1] },
options: {
duration: 1,
delay: 0.6,
threshold: 0,
},
}}
>
<button
class="switcher__button"
title="{!isOpen ? 'Open' : 'Close'} menu"
tabindex="0"
onclick={toggleSwitcher}
>
<span>
{#each Array(3) as _}
<i></i>
{/each}
</span>
</button>
<ul class="switcher__links" data-sveltekit-noscroll>
{#each switcher_links as { text, url, icon, icon_label }}
<li class:is-active={$page.url.pathname === url}>
<a href={url} onclick={toggleSwitcher} tabindex="0">
<Icon class="icon" icon={icon} label={icon_label} />
<span>{text}</span>
</a>
</li>
{/each}
</ul>
</aside>