Skip to content

Numeric Stepper13.10.5

Bundle


$ npm i @if-design-system/Numeric Stepper@13.10.5

18 + 18 +
The number of bedrooms in your house
< 18
Edit this section

Overview

There is currently no documentation for this section yet.
Contact the Design System team for questions.

If you want to contribute, you can also add the documentation yourself!

Edit this section

Usage

Use the numeric stepper when you want the users to step numbers.

The numeric stepper should only be used for values between 0 and 9!

Edit this section

Behaviours

Many of the behaviours for this input control is inherited of the default component.

Modifiers

Disabled

18 +
Disabled numeric stepper

Large

Use the class .large to get a larger numeric stepper.

A bathroom does not count towards the total number of rooms in the apartment Error
Large
<div class="if numeric-stepper large">
  <div class="if numeric-wrapper">
    <button type="button" class="if down" aria-label="Remove 1"></button>
    <input
      type="number"
      id="<identifier>"
      name="<identifier>"
      class="if"
      value="1"
      max="9"
      min="0"
      aria-live="polite"
      tabindex="-1"
    />
    <button type="button" class="if up" aria-label="Add 1"></button>
  </div>
  <label for="<identifier>" class="if"> How many rooms does the apartment have? </label>
  <span class="if input-help">A bathroom does not count towards the total number of rooms in the apartment</span>
  <span class="if input-error">Error</span>
</div>
Edit this section

Anatomy

18 + 18 +

Numeric stepper
  1. Decrease
  2. Label
  3. Help text
  4. Increase
Edit this section

Specs

18 + 18 +
A bathroom does not count towards the total number of rooms in the apartment Error
Edit this section

Implementation

<div class="if numeric-stepper">
  <button aria-label="Remove 1" class="if down" type="button"></button>
  <input
    aria-live="polite"
    class="if"
    id="<identifier>"
    max="9"
    min="0"
    name="<identifier>"
    tabindex="-1"
    type="number"
    value="2"
  />
  <label class="if" for="<identifier>">Adults</label>
  <span class="if input-help">18 +</span>
  <span class="if input-error">18 +</span>
  <button aria-label="Add 1" class="if up" type="button"></button>
</div>

And here is the mandatory javascript code:

const numericSteppers = document.querySelectorAll('.if.numeric-stepper');

const handleNumericStepperIncrementClick = e => {
  const incrementButton = e.target;
  const decrementButton = incrementButton.parentElement.querySelector('button.down');
  const stepper = incrementButton.parentElement.querySelector('input[type=number]');

  if (stepper.getAttribute('disabled')) {
    return false;
  }

  let oldValue = stepper.value;
  let newValue = 0;

  // Don't allow incrementing over 9
  if (oldValue < 9) {
    newValue = parseFloat(oldValue) + 1;
    incrementButton.removeAttribute('disabled');
    incrementButton.removeAttribute('aria-disabled');
  } else {
    newValue = 9;
  }

  if (newValue === 9) {
    incrementButton.setAttribute('disabled', true);
    incrementButton.setAttribute('aria-disabled', true);
  }

  decrementButton.removeAttribute('disabled');
  decrementButton.removeAttribute('aria-disabled');

  stepper.value = newValue;
};

const handleNumericStepperDecrementClick = e => {
  const decrementButton = e.target;
  const incrementButton = decrementButton.parentElement.querySelector('button.up');
  const stepper = decrementButton.parentElement.querySelector('input[type=number]');

  if (stepper.getAttribute('disabled')) {
    return false;
  }

  let oldValue = stepper.value;
  let newValue = 0;

  // Don't allow decrementing below zero
  if (oldValue > 0) {
    newValue = parseFloat(oldValue) - 1;
    decrementButton.removeAttribute('disabled');
    decrementButton.removeAttribute('aria-disabled');
  } else {
    newValue = 0;
  }

  if (newValue === 0) {
    decrementButton.setAttribute('disabled', true);
    decrementButton.setAttribute('aria-disabled', true);
  }

  incrementButton.removeAttribute('disabled');
  incrementButton.removeAttribute('aria-disabled');

  stepper.value = newValue;
};

const maxLengthCheck = e => {
  const object = e.target;
  if (object.value.length > object.max.length) object.value = object.value.slice(0, object.max.length);
};

const isNumeric = e => {
  const _event = e || window.event;
  let key = _event.key;
  const regex = /[0-9]|\./;
  if (!regex.test(key)) {
    _event.returnValue = false;
    if (_event.preventDefault) _event.preventDefault();
  }
};

numericSteppers.forEach(numericStepper => {
  const input = numericStepper.querySelector('input[type=number]');
  input.removeEventListener('input', maxLengthCheck);
  input.addEventListener('input', maxLengthCheck);
  input.removeEventListener('keypress', isNumeric);
  input.addEventListener('keypress', isNumeric);
  const incrementButton = numericStepper.querySelector('button.up');
  incrementButton.removeEventListener('click', handleNumericStepperIncrementClick);
  incrementButton.addEventListener('click', handleNumericStepperIncrementClick);
  const decrementButton = numericStepper.querySelector('button.down');
  decrementButton.removeEventListener('click', handleNumericStepperDecrementClick);
  decrementButton.addEventListener('click', handleNumericStepperDecrementClick);
});
Edit this section

Contact us