File: /var/www/fintechfuel/src/components/Select/Select.svelte
<script lang="ts">
import arrow from '../../assets/images/arrow.svg';
import clickOutside from '../../utils/outsideClick.js';
import { browser } from '$app/environment';
import { t } from '$lib/translations';
export let className = '';
export let onChange: (value: number | undefined) => void;
const options = [
$t('Investor'),
$t('Affiliate & IB'),
$t('Forex broker representative'),
$t('Gambling & Betting provider'),
];
let open = false;
let value: string | undefined = undefined;
let matches = false;
if (browser) {
matches = window.matchMedia('(max-width: 1024px)').matches;
}
</script>
<div
class="select {className} {open ? 'active' : ''}"
use:clickOutside={() => {
open = false;
}}
>
{#if matches}
{#if value}
<div
class="selectDefaultClear"
on:click={() => {
open = false;
value = undefined;
onChange(undefined);
}}
on:keydown={() => false}
role="button"
tabindex="0"
>
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M24 8L8 24M8 8L24 24"
stroke="#313236"
stroke-width="3"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
{/if}
<select
class="selectDefault"
on:change={(e) => {
if (!e.target?.value) {
value = undefined;
onChange(undefined);
} else {
value = options[Number(e.target.value)];
onChange(Number(e.target.value));
}
const block = document.querySelector('.solutionContentScroll');
if (block) {
block.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
}}
required
>
<option value="" selected={true}>{$t('Choose a role')}</option>
{#each options as option, index}
<option value={index} selected={option === value}>{option}</option>
{/each}
</select>
{:else}
<div
class="selectBtn"
on:click={() => {
open = !open;
}}
on:keydown={() => false}
role="button"
tabindex="0"
>
<div class="selectText">
{#if value !== undefined}
<p>{value}</p>
{/if}
{#if value === undefined}
<p class="placeholder">{$t('Choose a role')}</p>
{/if}
</div>
<div class="selectArrow">
{#if value !== undefined}
<div
class="selectArrowItem clear"
on:click={() => {
open = false;
value = undefined;
onChange(undefined);
}}
on:keydown={() => false}
role="button"
tabindex="0"
>
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M24 8L8 24M8 8L24 24"
stroke="#313236"
stroke-width="3"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
{/if}
<div class="selectArrowItem arrow">
<img src={arrow} alt="" />
</div>
</div>
</div>
<div class="selectList">
{#each options as option, index}
<div
tabindex={index}
class={value === option ? 'selected' : ''}
data-value={option}
on:click={({ target }) => {
onChange(index);
value = target.dataset.value;
open = false;
}}
on:keydown={() => false}
role="button"
>
{option}
</div>
{/each}
</div>
{/if}
</div>
<style lang="scss">
@import '../../scss/media';
.select {
position: relative;
&.solutionSelects {
max-width: 782px;
width: 100%;
z-index: 1;
@include breakpoint-down('deskS') {
max-width: 616px;
}
@include breakpoint-down('tabM') {
max-width: none;
}
}
.selectBtn {
background: #f0ede8;
padding: 19px 40px;
display: flex;
align-items: center;
justify-content: space-between;
border-radius: 24px;
cursor: pointer;
transition: 0.3s cubic-bezier(0.65, 0.05, 0.36, 1);
@include breakpoint-down('tabS') {
padding: 19px 20px;
}
&:hover {
background: #d9d7cc;
}
}
.selectText {
width: calc(100% - 24px - 104px);
font-size: 48px;
font-weight: 600;
line-height: 62.4px;
@include breakpoint-down('tabS') {
font-size: 32px;
line-height: 42px;
}
@include breakpoint-down('mobM') {
font-size: 24px;
line-height: 29px;
width: calc(100% - 24px - 55px);
}
p {
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.placeholder {
color: #a6a49c;
}
}
.selectArrow {
display: flex;
align-items: center;
.selectArrowItem {
border-right: 2px solid #bfbdb4;
margin-right: 8px;
padding-right: 16px;
width: 48px;
min-width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
img {
width: 80%;
}
&.clear {
@include breakpoint-down('mobM') {
padding-right: 12px;
svg {
width: 24px;
height: 24px;
}
}
&:hover {
svg {
path {
stroke: #fe4d0d;
}
}
}
}
&.arrow {
transition: 0.3s cubic-bezier(0.65, 0.05, 0.36, 1);
}
&:last-of-type {
border: none;
margin-right: 0;
padding-right: 0;
@include breakpoint-down('mobM') {
padding-right: 8px;
padding-left: 8px;
}
}
}
}
.selectList {
background: #f0ede8;
border-radius: 24px;
position: absolute;
top: calc(100% + 16px);
left: 0;
right: 0;
padding: 24px;
pointer-events: none;
opacity: 0;
@include breakpoint-down('tabM') {
display: none;
}
> div {
cursor: pointer;
padding: 19px 24px;
font-size: 48px;
font-weight: 600;
line-height: 62px;
border-radius: 16px;
transition: 0.3s cubic-bezier(0.65, 0.05, 0.36, 1);
@include breakpoint-down('tabS') {
font-size: 32px;
line-height: 42px;
}
@include breakpoint-down('mobM') {
font-size: 24px;
line-height: 29px;
}
&:hover {
background: #d9d7cc;
}
&:active {
background: #bfbdb4;
}
&.selected {
color: #fe4d0d;
}
}
}
&.active {
.selectBtn {
background: #d9d7cc;
}
.selectArrow {
.selectArrowItem {
&.arrow {
transform: rotate(-180deg);
}
}
}
.selectList {
pointer-events: all;
opacity: 1;
}
}
}
.selectDefaultClear {
position: absolute;
right: 45px;
top: 50%;
transform: translateY(-50%);
display: flex;
border-right: 2px solid #bfbdb4;
padding-right: 8px;
@include breakpoint-down('mobM') {
svg {
width: 20px;
height: 20px;
}
}
}
.selectDefault {
width: 100%;
background-color: #f0ede8;
background-image: url("data:image/svg+xml,%3Csvg width='28' height='16' viewBox='0 0 28 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2 2L14 14L26 2' stroke='%23313236' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E%0A");
background-repeat: no-repeat;
background-size: 16px 10px;
background-position: calc(100% - 20px) center;
padding: 19px 80px 19px 20px;
display: flex;
align-items: center;
justify-content: space-between;
border-radius: 24px;
cursor: pointer;
transition: 0.3s cubic-bezier(0.65, 0.05, 0.36, 1);
border: none;
outline: none;
appearance: none;
z-index: 1;
font-size: 48px;
font-weight: 600;
line-height: 62.4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #313236;
@include breakpoint-down('tabS') {
font-size: 32px;
line-height: 42px;
}
@include breakpoint-down('mobM') {
font-size: 24px;
line-height: 29px;
}
&:invalid {
color: #a6a49c;
}
option {
color: #313236;
font-size: 16px;
font-weight: 400;
line-height: 24px;
}
}
</style>