HEX
Server: nginx/1.18.0
System: Linux test-ipsremont 5.4.0-214-generic #234-Ubuntu SMP Fri Mar 14 23:50:27 UTC 2025 x86_64
User: ips (1000)
PHP: 8.0.30
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
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>