Skip to main content

DurationSlider

packages/core/components/atoms/DurationSlider.js · Tier: atom · Module: core · Rendering: Client Component ('use client')

Purpose​

A range slider with a numeric readout and quick-pick chips. Used by the citizen reservation and renewal flows to pick a parking duration — by default between 20 and 150 minutes in 5-minute increments. The value is clamped into [min, max] before being propagated through onChange.

Props​

PropTypeRequiredDefaultDescription
valuenumberyes—Current duration (controlled).
onChange(next: number) => voidyes—Called with the clamped value on slider/chip change.
minnumberno20Lower bound.
maxnumberno150Upper bound.
stepnumberno5Increment.
quickPicksnumber[]no[20, 60, 90, 150]Values rendered as quick-pick chips.
formatDuration(minutes: number) => stringyes—Formats a minute count into a display string (readout, scale ends, chips).
labelstringno—Field label + slider aria-label.
hintstringno—Helper text below the control.
quickPicksLabelstringno—Caption above the chip row.
disabledbooleannofalseDisables the range input and chips.

Variants & states​

Selected quick-pick chips get the secondary-container "selected" style; the rest are outlined. Disabled state dims the control. Custom slider thumb/track styling is provided by a scoped styled-jsx block (with -webkit- and -moz- variants).

Composition​

  • Uses: native <input type="range">, chip <button>s, and a styled-jsx style block.
  • Used by: molecules/mobility/RenewStayModal, organisms/mobility/ReservationForm.

Internationalisation​

No dictionary access; all display strings come in as props (label, hint, quickPicksLabel) and via formatDuration, so the caller localises them.

Accessibility​

The range input carries aria-label={label}. The numeric readout is tabular-nums for stable width. Chips are native buttons.

Styling & tokens​

bg-surface-container, border-outline-variant, rounded-md, type-scale tokens; custom thumb colour #13696a in the scoped styles.

Usage​

<DurationSlider
value={minutes}
onChange={setMinutes}
formatDuration={(m) => `${m} min`}
label={t.parking.duration}
/>

molecules/mobility/RenewStayModal, organisms/mobility/ReservationForm.