File: /var/www/quadcode.com/src/components/blocks/glossary/GlossaryControls.svelte
<script lang="ts">
import { onMount } from 'svelte';
import Swiper from 'swiper';
import 'swiper/css';
import 'swiper/css/pagination';
import 'swiper/css/navigation';
import Search from './Search.svelte';
import { glossaryAnchor, glossarySearchWord } from '../../../store';
import { Navigation } from 'swiper/modules';
import {t} from '$lib/translations';
const letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
let isMobile: boolean = true;
let lettersElements: HTMLDivElement;
const handleLetterClick = (event: MouseEvent & {
currentTarget: EventTarget & HTMLDivElement;
}) => {
Array.from(lettersElements.children).forEach(element => {
element.classList.remove('active');
});
event.currentTarget.classList.add('active');
glossaryAnchor.set(event.currentTarget.textContent);
};
let visible = '';
onMount(() => {
isMobile = window.innerWidth < 1023;
const container: HTMLElement | null = document.querySelector('.swiper');
const nextEl: HTMLElement | null = document.querySelector('.next-el');
const prevEl: HTMLElement | null = document.querySelector('.prev-el');
let deltaY = 0;
let lastKnownScrollPosition = 0;
window.addEventListener('scroll', function () {
let ticking = false;
if (!ticking) {
window.requestAnimationFrame(function () {
deltaY = (window.scrollY < 0 ? 0 : window.scrollY) - lastKnownScrollPosition;
lastKnownScrollPosition = window.scrollY < 0 ? 0 : window.scrollY;
ticking = false;
});
ticking = true;
}
if (deltaY > 0 && (window.scrollY < 0 ? 0 : window.scrollY) > 0) {
visible = 'hide';
} else if (deltaY && (window.scrollY < 0 ? 0 : window.scrollY) >= window.screen.height) {
visible = 'hideMenu';
} else {
visible = '';
}
});
if (!container) return;
new Swiper(container, {
modules: [Navigation],
spaceBetween: 8,
slidesPerView: 'auto',
width: 40,
navigation: {
prevEl: prevEl,
nextEl: nextEl,
},
pagination: {
// el: pagination,
clickable: true,
},
breakpoints: {
// 320: {
// slidesPerView: 1,
// spaceBetween: 20,
// },
480: {
height: 33,
width: 29,
},
768: {
width: 40,
},
// 1366: {
// slidesPerView: 3,
// spaceBetween: 32,
// },
// 1800: {
// slidesPerView: 3,
// spaceBetween: 40,
// },
},
});
});
</script>
<div class="glossary-controlls {visible}">
<div class="glossary-controlls__container glossary-controlls__search-container">
<div class="glossary-controlls__logo-container">
<div class="glossary-controlls__logo">{$t('Glossary')}</div>
<div class="glossary-controlls__description">{@html $t('Essential Terms You Should Know: Your Guide to Understanding Key Concepts and Terminology')}</div>
</div>
<div class="glossary-controlls__search">
<Search onInput={(event) => glossarySearchWord.set(event.currentTarget.value)} />
</div>
</div>
{#if !isMobile}
<div bind:this={lettersElements} class="glossary-controlls__container glossary-controlls__letters ">
{#each letters as letter}
<div role="button" tabindex="0" on:keydown={null} class="glossary-controlls__letter" on:click={handleLetterClick}>{letter}</div>
{/each}
</div>
{:else}
<div class="glossary-controlls__container glossary-controlls__letters">
<div class="swiper">
<div class="swiper-wrapper" bind:this={lettersElements}>
{#each letters as letter}
<div role="button" tabindex="0" on:keydown={null} class="glossary-controlls__letter swiper-slide" on:click={handleLetterClick}>{letter}</div>
{/each}
</div>
<div class="swiper-button-next glossary-controlls__letter next-el ">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13 17L18 12L13 7" stroke="#445667" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6 17L11 12L6 7" stroke="#445667" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
<div class="swiper-button-prev glossary-controlls__letter prev-el ">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13 17L18 12L13 7" stroke="#445667" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6 17L11 12L6 7" stroke="#445667" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
</div>
</div>
{/if}
</div>
<style lang="scss">
@import 'src/scss/variables';
@import 'src/scss/media';
@import 'src/scss/mixins';
.swiper {
width: 100%;
}
.mobile {
display: none;
@include breakpoint-down('tabM') {
display: block;
}
}
.glossary-controlls {
background: $techBlue2;
display: flex;
flex-direction: column;
gap: 29px;
position: sticky;
transition: 0.3s cubic-bezier(0.65, 0.05, 0.36, 1) 0.3s;
padding: 10px 0;
top: 133px;
z-index: 6;
@include breakpoint-down('deskL') {
padding-top: 9px;
gap: 25px;
}
@include breakpoint-down('deskS') {
top: 99px;
}
@include breakpoint-down('tabL') {
gap: 16px;
width: 100%;
}
@include breakpoint-down('tabM') {
gap: 20px;
}
&.hide {
transform: translateY(-133px);
pointer-events: none;
@include breakpoint-down('tabM') {
transform: translateY(calc(-100% - 1px)) !important;
}
}
&.hideMenu {
transform: translateY(calc(-51px));
@include breakpoint-down('tabM') {
transform: none !important;
}
}
&__container {
display: flex;
align-items: center;
gap: 7px;
}
&__search-container {
@include breakpoint-down('tabM') {
flex-direction: column;
gap: 20px;
}
}
&__logo-container {
display: flex;
align-items: center;
gap: 48px;
position: relative;
@include breakpoint-down('tabL') {
flex-direction: column;
align-items: start;
gap: 12px;
width: 100%;
}
@include breakpoint-down('tabM') {
align-items: center;
gap: 12px;
}
}
&__logo {
font-size: 55px;
line-height: 60.5px;
font-weight: 700;
letter-spacing: -3px;
@include breakpoint-down('deskL') {
font-size: 55px;
line-height: 60.5px;
font-weight: 700;
}
@include breakpoint-down('tabL') {
font-size: 36px;
line-height: 39.6px;
letter-spacing: normal;
}
@include breakpoint-down('tabM') {
font-size: 31px;
line-height: 34.1px;
text-align: center;
}
}
&__description {
width: 467px;
font-size: 20px;
line-height: 22px;
letter-spacing: -0.9px;
@include breakpoint-down('deskL') {
width: 420px;
}
@include breakpoint-down('tabL') {
width: 100%;
font-size: 16px;
line-height: 17.6px;
letter-spacing: normal;
}
@include breakpoint-down('tabM') {
font-size: 12px;
line-height: 16.8px;
text-align: center;
}
}
&__search {
flex: 1;
@include breakpoint-down('tabL') {
position: absolute;
top: 8px;
width: 362px;
right: -12px;
}
@include breakpoint-down('tabM') {
position: static;
width: 100%;
}
}
&__letters {
padding: 21px 16px;
border-radius: 8px;
gap: 8px;
background-color: $techWhite;
border: thin solid $techBlue3;
justify-content: space-between;
width: 100%;
position: relative;
@include breakpoint-down('deskL') {
padding: 21px 24px;
gap: 7px;
}
@include breakpoint-down('tabM') {
padding: 15px 16px;
}
}
&__letter{
width: 50px;
height: 58px;
border-radius: 8px;
display: flex;
justify-content: center;
align-items: center;
font-size: 18px;
line-height: 19.8px;
font-weight: 700;
background-color: $techGrey5;
cursor: pointer;
@include breakpoint-down('tabM') {
font-size: 12px;
line-height: 13.2px;
width: 29px;
height: 33px;
}
&.next-el{
position: absolute;
top: 0;
bottom: 0;
margin-top: 0;
right: 0;
z-index: 10;
border-radius: 0;
width: calc(60px);
background-color: $techWhite;
@include breakpoint-down('tabM') {
width: 20px;
}
svg {
height: 24px;
}
&.hidden {
display: none;
}
}
&.prev-el{
position: absolute;
top: 0;
bottom: 0;
margin-top: 0;
left: 0;
z-index: 10;
border-radius: 0;
background-color: $techWhite;
transform: rotate(180deg);
@include breakpoint-down('tabM') {
width: 20px;
}
svg {
height: 24px;
}
&.hidden {
display: none;
}
}
@include breakpoint-down('deskL') {
padding-top: 3px;
height: 45px;
}
@include breakpoint-down('deskS') {
}
@include breakpoint-down('tabM') {
}
&.active {
color: $fontWhite;
background-color: $techGrey;
}
}
:global(.glossary-controlls__letter.active){
color: $fontWhite;
background-color: $techGrey;
}
:global(.swiper-button-disabled ){
display: none;
}
}
</style>