File: /var/www/quadcode.com/src/components/blocks/investment-calculator/CalculatorInput.svelte
<script lang="ts">
import { locale } from '$lib/translations';
import { investmentCalculator } from "../../../store";
import type { ChangeEventHandler } from "svelte/elements";
import type { IIdsList, IInvestmentCalculator } from '$type/investmentCalculator';
export let id: IIdsList;
export let title: string = '';
export let hint: string = '';
export let value: string;
export let className: string = '';
export let extraPlaceholder: string = '';
export let subLabel: string = '';
export let placeholder: string = '';
let showExtraPlaceholder: boolean = true;
let investmentCalculatorData: IInvestmentCalculator;
const isPercent = className.includes('percent');
const formatValue = (val: string): string => {
if (!isPercent || val === '') return val;
const clean = val.replace(/%/g, '');
return clean !== '' ? `${clean}%` : '';
}
investmentCalculator.subscribe((newValue: IInvestmentCalculator): void => {
investmentCalculatorData = newValue;
const raw = investmentCalculatorData[id]?.toString() ?? '';
value = formatValue(raw);
});
const handleInput: ChangeEventHandler<any> = (event) => {
const cleaned = event.currentTarget.value
.replace(/%/g, '')
.replace(/[^0-9.]/g, '')
.replace(/\.(?=.*\.)/g, '');
event.currentTarget.value = isPercent ? formatValue(cleaned) : cleaned;
value = isPercent ? formatValue(cleaned) : cleaned;
if (isPercent && value !== '') {
const pos = value.length - 1;
event.currentTarget.value = value;
event.currentTarget.setSelectionRange(pos, pos);
}
showExtraPlaceholder = false;
if (cleaned === '' || cleaned.endsWith('.') || /\.\d*0$/.test(cleaned)) return;
investmentCalculatorData[id] = Number(cleaned);
investmentCalculator.set(investmentCalculatorData);
}
</script>
<div class="calculatorInput {$locale} {className}">
{#if title !== ''}
<div class="calculatorInput__Label">{title}</div>
{/if}
{#if title !== ''}
<div class="calculatorInput__Hint">{hint}</div>
{/if}
{#if subLabel !== ''}
<div class="calculatorInput__SubLabel">{subLabel}</div>
{/if}
<div class="calculatorInput__inputContainer">
{#if showExtraPlaceholder}
<div class="calculatorInput__extraPlaceholder">
{extraPlaceholder}
</div>
{/if}
<input class="calculatorInput__input" type="text" value="{value}" on:input={handleInput} placeholder={placeholder} />
</div>
</div>
<style lang="scss">
@import 'src/scss/variables';
@import 'src/scss/media';
@import 'src/scss/mixins';
.calculatorInput {
width: 100%;
margin-bottom: 7px;
&.money {
input {
padding-left: 20px;
}
.calculatorInput {
&__inputContainer {
position: relative;
&:before {
position: absolute;
left: 12px;
top: 8px;
content: "$";
font-family: $Suisse;
font-weight: 400;
font-size: 14px;
line-height: 18px;
}
}
}
}
&.smaller {
margin-bottom: 5px;
.calculatorInput{
&__Label {
font-family: $Suisse;
font-weight: 600;
font-size: 12px;
line-height: 14px;
}
&__Hint {
font-size: 10px;
line-height: 14px;
margin-bottom: 9px;
}
}
}
&.extended {
.calculatorInput {
&__Label {
@include breakpoint-down('tabL') {
font-size: 18px;
line-height: 26px;
letter-spacing: -0.4px;
margin-bottom: 3px;
}
}
}
}
&__Label {
font-family: $Suisse;
font-weight: 500;
font-size: 18px;
line-height: 26px;
margin-bottom: 3px;
@include breakpoint-down('tabL') {
font-size: 16px;
line-height: 24px;
}
}
&__Hint {
color: $qc-tech-blue;
font-family: $Suisse;
font-weight: 400;
font-size: 12px;
line-height: 14px;
margin-bottom: 13px;
}
&__SubLabel {
font-family: $Suisse;
font-weight: 400;
font-size: 14px;
line-height: 20px;
color: $qc-tech_grey;
margin-bottom: 13px;
@include breakpoint-down('tabL') {
font-size: 12px;
line-height: 14px;
}
}
&__inputContainer {
position: relative;
}
&__extraPlaceholder {
position: absolute;
font-family: $Suisse;
font-weight: 400;
font-size: 12px;
line-height: 14px;
color: $qc-tech;
top: 10px;
right: 12px;
text-overflow: ellipsis;
max-width: 200px;
white-space: nowrap;
overflow: hidden;
}
&__input {
border: 1px solid #323232;
border-radius: 8px;
width: 100%;
height: 34px;
padding: 8px 12px;
font-family: $Suisse;
font-weight: 400;
font-size: 14px;
line-height: 18px;
}
}
</style>