Time Picker

Clock or dropdown-based time selection input.

24-Hour (native)

Wraps <input type="time"> directly — the browser supplies the picker UI, keyboard input, and a valid HH:MM value with zero custom JS. Use this whenever the project doesn't need AM/PM-styled chrome.

<label class="sc-field">
  <span class="sc-field-label">Pickup time</span>
  <input type="time" class="input sc-time-input" value="14:30" step="60"/>
</label>

Minute step (15-min slots)

Same native input — only the step attribute changes. No JavaScript needed to enforce the interval; the browser's own picker restricts selectable minutes to the step.

12-hour, AM/PM dropdown

A button that opens a small panel with three selects (hour / minute / AM-PM). Use when the design calls for a consistent AM/PM-labelled control rather than relying on the OS locale.

<div x-data="timePickerDropdown({ hour: 2, minute: 30, meridiem: 'PM' })">
  <button type="button" class="btn btn-outline justify-between" @click="toggle()">
    <span x-text="display"></span>
  </button>
  <div x-show="open" x-collapse @click.outside="open = false">
    <select x-model.number="hour">...</select>
    <select x-model.number="minute">...</select>
    <select x-model="meridiem"><option>AM</option><option>PM</option></select>
  </div>
</div>

Scroll-wheel

Three scroll-snap columns (hour / minute / AM-PM) with a fixed selection window in the middle. Pure CSS scroll-snap handles the snapping; Alpine only reads each column's centred value on scroll-end.

Scroll each column — it snaps to the nearest value.

Combined date & time

Two native inputs composed side by side — the most common real-world pairing (e.g. "schedule for"). Stacks vertically once the row is narrower than both fields need.

States

Default, disabled, error, and empty — the states every input in the form category needs to support.

Default

Disabled

Error

Must be within business hours.

Empty