@econnect/webcomponents-library
Documentation
Styleguide
Documentation
Styleguide
  • Getting Started

    • Installation
    • Patch Notes
    • Styleguide
  • Styling

    • e-connect colors
  • UI Components

    • Form

      • Search Field
      • Form Field
      • Forms
    • Filter

      • Filter
      • Search Filter
    • Grid

      • Grid
      • Grid Row
    • Inputs

      • File Input
      • Input Checkbox
      • Input Dropdown
      • Input Date
      • Input Date Time
      • Input Date Time Local
      • Input File
      • Input Label
      • Input Multi Select
      • Input Number
      • Input Radio
      • Input Range
      • Input Select
      • Input Switch
      • Input Slider
      • Input Text
      • Input TextArea
      • Input Time
      • Input Time Range
    • Controls

      • Booleans
      • Button
      • Checkboxes
      • Date Displays
      • Dropdown Lists
      • Text Displays
    • Headers

      • e-header
    • Cards

      • e-card
    • Images

      • Icon
      • Images
      • Flag Image
      • Hamburger
    • Iframe
    • Pager
    • Settings
    • Document Validation
    • Navigation

      • Navigation
      • Navigation Menu
      • Navigation Footer
      • Navigation Button
      • Navigation Button Item
      • Navigation Search Item

Input Number v1.0

The <e-input-number> component is a component that can be used for .

Usage

An e-input-number has attributes that must be provided,

<e-input-number
  id="example id"
  value="'1'"
  label=""
  placeholder=""
/>

Attributes

id | Type: String | required
value | Type: String | Default: ''
label | Type: String | Default: ''
placeholder | Type: String | Default: ''
required | Type: Boolean | Default: false
meta | Type: MetaModel | Default: { disabled: false, nullable: false }

Examples

Below a few interactive examples of unavailable can be found.

Default
<e-input-number
  id="numberInputWithOptions"
  :value="'exampleText1'"
/>
Labelled, label='numberInput with Label'
<div class="input-example-field">
  <e-input-label
    :id="'numberInputWithLabel'"
    :value="'numberInput with Label'"
  />
  <e-input-number
    :id="'numberInputWithLabel'"
    :label="'numberInput with Label'"
    :value="'1'"
  />
</div>

Source Code

e-input-number.vue
<script setup lang="ts">
import { computed, ref } from 'vue';
import { isNil, clamp } from 'lodash-es';

import { EInput_Number } from 'types/e-input/interfaces/EInput_Number';

export type Props = EInput_Number;
const props = withDefaults(defineProps<Props>(), {
  value: '',
  label: '',
  placeholder: '',
  required: false,
  meta: () => {
    return {
      disabled: false,
      nullable: false
    };
  }
});

const emit = defineEmits<{
  (e: 'blur', event: FocusEvent): void;
  (e: 'keyup.enter', event: KeyboardEvent): void;
  (e: 'update:value', value: number): void;
}>();

const input = ref<HTMLInputElement>();

const numberValue = computed(() => {
  switch (typeof props.value) {
    case 'number':
      return props.value;
    default:
      return Number.parseInt(props.value);
  }
});

const isDisabled = computed(() => props.disabled ?? props.meta?.disabled);

const isNullable = computed(() => {
  return props.meta?.nullable || false;
});

const hasMinValue = computed(() => !isNil(props.meta.min));
const hasMaxValue = computed(() => !isNil(props.meta.max));

// Ensure acceptable nullish value, fall back to minValue or 0
function confirmNullability(targetValue: number) {
  if (Number.isNaN(targetValue)) {
    if (!isNullable.value) {
      return (props.meta?.min || 0) as number;
    } else {
      return null;
    }
  }
  return targetValue;
}

// Clamp new value to be within min / max
function clampValue(targetValue: number) {
  if (hasMaxValue.value && hasMinValue.value) {
    return clamp(targetValue, props.meta.min, props.meta.max);
  }

  if (hasMaxValue.value) {
    return Math.min(targetValue, props.meta.max);
  }

  if (hasMinValue.value) {
    return Math.max(targetValue, props.meta.min);
  }

  return targetValue;
}

function emitUpdate(event: Event): void {
  const target = event.target as HTMLInputElement;
  const parsedValue = Number.parseInt(target.value);

  let numberValue = confirmNullability(parsedValue);
  // Only clamp when there is actual number.
  if (numberValue) {
    numberValue = clampValue(numberValue);
  }

  // Update input value, with clamped value
  input.value.value = `${numberValue}`;

  emit('update:value', numberValue);
}

const timer = ref<NodeJS.Timeout>();
function debounceEmit(event: Event, msDelay: number = 500): void {
  clearTimeout(timer.value);

  timer.value = setTimeout(() => {
    emitUpdate(event);
  }, msDelay);
}
</script>

<template>
  <input
    :id="id"
    ref="input"
    class="e-input-number"
    type="number"
    :name="id"
    :value="numberValue"
    :placeholder="placeholder"
    :required="required"
    :disabled="isDisabled"
    :min="meta.min"
    :max="meta.max"
    @input="debounceEmit($event, 500)"
    @blur="emit('blur', $event)"
    @keyup.enter="emit('keyup.enter', $event)"
  />
</template>

<style scoped lang="scss">
.e-input-number {
  background-color: var(--e-input-background);
  border: none;
  border-radius: 15px;
  color: var(--e-body-font-color);
  font: normal normal normal 16px/20px var(--e-body-font-family);
  padding: 15px;

  &::placeholder {
    color: var(--e-gray-300);
  }

  &[required] {
    + label::after {
      content: '*';
      padding-left: 2px;
      color: var(--e-required);
      font-weight: bold;
    }
  }
}
</style>
Last Updated:: 9/26/24, 3:32 PM
Contributors: Marcel Lommers
Prev
Input Multi Select
Next
Input Radio