Honeycomb

quantity

Props

Prop nameTypeDefaultDescription
extraClassesstring | undefined

Injection in className

activeboolean | undefined

sets active state

captionstring | undefined

caption text injected in

disabledboolean | undefined

Disables input and buttons

errorboolean | undefined

sets error state

infoReactNode

Provides extra information for this input field

infoErrorReactNode

Provides extra information for an error, gets displayed only when `error` is set to true

inlineboolean | undefined

Enforces label and input to appear in one line

innerRefRefObject<HTMLInputElement> | undefined

Ref forwarded to the input element

maxnumber | undefined

Maximum allowed value

minnumber | undefined

Minimum allowed value

minusBtnPropsActionBtnPropsRequired

Rest props for minus button

plusBtnPropsActionBtnPropsRequired

Rest props for plus button

stepnumber | undefined

Increment/decrement amount

valuenumber | undefined

Input value

idstringRequired

Id for this input, also used to bind it to the label and validation messages.

labelReactNode

Provides label text, required if aria-label is not passed

Quantity picker offers a thin layer of event handling by default.

It will try to keep the value of the input between min and max by increasing or decreasing by step.

It will also disable the buttons when any of the boundaries is reached.

import { Quantity } from '@flixbus/honeycomb-react';

<Quantity
  label="Passengers"
  id="quantity-passenger"
  name="quantity-passenger"
  value={15}
  min={10}
  max={20}
  plusBtnProps={{ 'aria-label': 'Add passenger' }}
  minusBtnProps={{ 'aria-label': 'Remove passenger' }}
  info="min 10 / max 20"
/>

Readonly

import { Quantity } from '@flixbus/honeycomb-react';

<Quantity
  label="Passengers"
  id="quantity-passenger-readonly"
  name="quantity-passenger-readonly"
  value={15}
  min={10}
  max={20}
  info="min 10 / max 20"
  plusBtnProps={{ 'aria-label': 'Add passenger' }}
  minusBtnProps={{ 'aria-label': 'Remove passenger' }}
  readOnly
/>

Error state

import { Quantity } from '@flixbus/honeycomb-react';

<Quantity
  label="Passengers"
  id="quantity-passenger-error"
  name="quantity-passenger-error"
  value={15}
  min={10}
  max={20}
  info="min 10 / max 20"
  plusBtnProps={{ 'aria-label': 'Add passenger' }}
  minusBtnProps={{ 'aria-label': 'Remove passenger' }}
  infoError="There was a glitch, try again later :)"
  error
/>

Inline passengers selection:

import { Balloon, Fieldset, Divider, Quantity } from '@flixbus/honeycomb-react';

<Balloon position="bottom" alignment="start">
  <Fieldset itemSpacing="2">
    <Quantity
      label="Adults"
      id="adults"
      inline
      max={42}
      plusBtnProps={{ 'aria-label': 'Add passenger' }}
      minusBtnProps={{ 'aria-label': 'Remove passenger' }}
    />
    <Divider />
    <Quantity
      label="Children"
      id="children"
      inline
      max={42}
      plusBtnProps={{ 'aria-label': 'Add passenger' }}
      minusBtnProps={{ 'aria-label': 'Remove passenger' }}
      caption="0 to 14 years"
    />
    <Divider />
    <Quantity
      label="Bikes"
      id="bikes"
      inline
      max={5}
      plusBtnProps={{ 'aria-label': 'Add passenger' }}
      minusBtnProps={{ 'aria-label': 'Remove passenger' }}
      caption="E-bikes and scooters  are not allowed on buses"
    />
  </Fieldset>
</Balloon>

Custom behaviour:

You can pass a custom function via provided onChange prop, this will receive an event object from the input field, from there the value can be obtained as event.target.value property.

You can combine three event handlers: onChange, minusBtnProps.onClick, plusBtnProps.onClick allowing various sorts of custom behaviour, where necessary:

import { Fieldset, Legend, Quantity } from '@flixbus/honeycomb-react';

const max = 3;
const [salami, setSalami] = React.useState(0);
const [cheese, setCheese] = React.useState(0);
const [olives, setOlives] = React.useState(0);
const [total, setTotal] = React.useState(0);

React.useEffect(() => {
  setTotal(salami + cheese + olives);
}, [salami, cheese, olives]);

const handleChange = (setter, value) => {
  if (total < max) setter(parseInt(value, 10));
};

const addItemProps = (getter, setter, label) => ({
  'aria-label': label,
  onClick: (e) => total < max && setter((old) => old + 1),
  disabled: total >= max || getter >= max,
});

const removeItemProps = (getter, setter, label) => ({
  'aria-label': label,
  onClick: (e) => total > 0 && setter((old) => old > 0 ? old - 1 : old),
  disabled: total <= 0 || getter <= 0,
});

<Fieldset info={`You can pick up to ${max} items.`} horizontal>
  <Legend>Extra toppings:</Legend>
  <Quantity
    label="Salami"
    id="salami"
    onChange={(e) => handleChange(setSalami, e.target.value)}
    plusBtnProps={addItemProps(salami, setSalami, 'Add Salami')}
    minusBtnProps={removeItemProps(salami, setSalami, 'Remove Salami')}
    max={max}
    value={salami}
  />
  <Quantity
    label="Cheese"
    id="cheese"
    onChange={(e) => handleChange(setCheese, e.target.value)}
    plusBtnProps={addItemProps(cheese, setCheese, 'Add Cheese')}
    minusBtnProps={removeItemProps(cheese, setCheese, 'Remove Cheese')}
    max={max}
    value={cheese}
  />
  <Quantity
    label="Olives"
    id="olives"
    onChange={(e) => handleChange(setOlives, e.target.value)}
    plusBtnProps={addItemProps(olives, setOlives, 'Add Olives')}
    minusBtnProps={removeItemProps(olives, setOlives, 'Remove Olives')}
    max={max}
    value={olives}
  />
</Fieldset>