File: /var/www/blog.affstore/src/components/header/Lang.svelte
<script lang="ts">
import { t, locale, defaultLocale, config } from './../../lib/translations/index.js';
import { page } from '$app/stores';
import arrow from '../../assets/images/arrow.svg';
import clickOutside from '../../utils/outsideClick.js';
import WebIcon from '../../assets/images/WebIcon.svelte';
import { postAlternates } from '../../store.js';
let postAlternateItems: {[locale: string]: string};
postAlternates.subscribe((item) => {
postAlternateItems = item;
});
const langUrls = Object.keys(config.translations).map((lc) => {
const prefix = lc === defaultLocale ? '' : `/${lc}`;
const route = $page.data.route;
const url = Object.keys(postAlternateItems).find((lang) => lang === lc)
? `${prefix}/${postAlternateItems[lc]}`
: `${prefix}${route !== '/' ? route : ''}`
return {url, lc}
});
let open = false;
</script>
<div class={`lang ${open ? 'active' : ''}`} use:clickOutside={() => (open = false)}>
<div class="langBtn" on:click={() => (open = !open)} on:keydown={() => false} role="button" tabindex="0">
<div class="icon">
<WebIcon />
</div>
<div class="text">
{ $locale ? $t(`lang.${$locale}`) : 'Language'}
</div>
<img src={arrow} alt="" />
</div>
<div class="langList">
{#each langUrls as item}
<a href={item.url}
class={item.lc === $locale ? 'active' : ''}
>
{$t(`lang.${item.lc}`)}
</a>
{/each}
</div>
</div>
<style lang="scss">
@import 'src/scss/variables';
@import 'src/scss/media';
.lang {
position: relative;
user-select: none;
.langBtn {
display: flex;
align-items: center;
gap: 8px;
border-radius: 16px;
.icon {
width: 20px;
height: 20px;
}
.text {
font-size: 14px;
line-height: 20px;
font-weight: 400;
@include breakpoint-down('deskS') {
display: none;
}
}
cursor: pointer;
line-height: 24px;
font-weight: 500;
letter-spacing: 0.08px;
height: 44px;
transition: 0.3s cubic-bezier(0.65, 0.05, 0.36, 1);
> img {
width: 20px;
height: 20px;
transition: 0.3s cubic-bezier(0.65, 0.05, 0.36, 1);
}
&:hover {
}
&:active {
background: transparent;
}
}
.langList {
position: absolute;
top: calc(100% + 8px);
left: 0;
right: 0;
opacity: 0;
gap: 5px;
pointer-events: none;
border-radius: 8px;
background: #FFFFFF;
border: 1px solid $grey50;
padding: 8px;
box-shadow: 0px 4px 6px -2px #2D2A2C08;
box-shadow: 0px 2px 16px -4px #2D2A2C0D;
@include breakpoint-down('deskS') {
width: fit-content;
}
> a {
cursor: pointer;
display: block;
padding: 8px 12px 8px 12px;
font-size: 12px;
line-height: 18px;
font-weight: 400;
border-radius: 8px;
color: #201E1F;
transition: 0.3s cubic-bezier(0.65, 0.05, 0.36, 1);
&:hover {
background: $white200;
}
&:active {
color: $green50;
}
&.active {
color: $green50;
}
}
}
&.active {
.langBtn {
// background: #f0ede8;
// border: 1px solid #f0ede8;
}
.langList {
opacity: 1;
pointer-events: all;
}
.langBtn {
img {
transform: rotate(-180deg);
}
}
}
}
</style>