Time Picker

Visual time selector.

2:30 PM 12h
  • 1:00 PM
  • 1:30 PM
  • 2:30 PM
  • 3:00 PM
  • 3:30 PM

html

<div class="tp">
  <label class="tp__label" for="tp-1">Appointment time</label>
  <details class="tp__details">
    <summary class="tp__summary" id="tp-1" style="--accent:#E8A020;">
      <span>2:30 PM</span>
      <span class="tp__format">12h</span>
    </summary>
    <ul class="tp__list" style="--accent:#E8A020;">
      <li class="tp__item">1:00 PM</li>
      <li class="tp__item">1:30 PM</li>
      <li class="tp__item tp__item--sel">2:30 PM</li>
      <li class="tp__item">3:00 PM</li>
      <li class="tp__item">3:30 PM</li>
    </ul>
  </details>
</div>
<style>
.tp { font: 14px system-ui, sans-serif; color: #241430; max-width: 220px; }
.tp__label { display: block; margin-bottom: 6px; font-weight: 500; }
.tp__req { color: #241430; }
.tp__summary { display: flex; justify-content: space-between; gap: 8px; align-items: center; list-style: none; cursor: pointer; padding: 10px 12px; border: 1.5px solid #24143040; border-radius: 8px; background: #FAF7F2; }
.tp__summary::-webkit-details-marker { display: none; }
.tp__format { font-size: 11px; color: #24143080; text-transform: uppercase; }
.tp__details[open] .tp__summary { border-color: var(--accent); }
.tp__list { list-style: none; margin: 8px 0 0; padding: 4px; border: 1.5px solid #24143020; border-radius: 8px; max-height: 140px; overflow-y: auto; }
.tp__item { padding: 6px 8px; border-radius: 6px; font-size: 13px; }
.tp__item:hover { background: #24143010; }
.tp__item--sel { background: var(--accent); font-weight: 600; }
</style>

tailwind

<div class="font-sans text-sm text-[#241430] max-w-[220px]">
  <label class="block mb-1.5 font-medium" for="tp-tw-1">Appointment time</label>
  <details>
    <summary id="tp-tw-1" class="tp-tw-summary flex justify-between items-center gap-2 list-none cursor-pointer px-3 py-2.5 border-[1.5px] border-[#24143040] rounded-lg bg-[#FAF7F2]" style="border-color:#E8A020;">
      <span>2:30 PM</span>
      <span class="text-[11px] text-[#24143080] uppercase">12h</span>
    </summary>
    <ul class="list-none mt-2 p-1 border-[1.5px] border-[#24143020] rounded-lg max-h-[140px] overflow-y-auto">
      <li class="px-2 py-1.5 rounded text-[13px] hover:bg-[#24143010]">1:00 PM</li>
      <li class="px-2 py-1.5 rounded text-[13px] hover:bg-[#24143010]">1:30 PM</li>
      <li class="px-2 py-1.5 rounded text-[13px] font-semibold" style="background:#E8A020;">2:30 PM</li>
      <li class="px-2 py-1.5 rounded text-[13px] hover:bg-[#24143010]">3:00 PM</li>
      <li class="px-2 py-1.5 rounded text-[13px] hover:bg-[#24143010]">3:30 PM</li>
    </ul>
  </details>
</div>
<style>
.tp-tw-summary::-webkit-details-marker { display: none; }
</style>

react

export function TimePicker({
  label = "Appointment time",
  format = "12h",
  value = "2:30 PM",
  accent = "#E8A020",
  required = false,
}) {
  return (
    <div style={{ fontFamily: "system-ui, sans-serif", fontSize: 14, color: "#241430", maxWidth: 220 }}>
      <label style={{ display: "block", marginBottom: 6, fontWeight: 500 }}>{label}{required && " *"}</label>
      <details>
        <summary style={{
          display: "flex", justifyContent: "space-between", alignItems: "center", gap: 8, listStyle: "none",
          cursor: "pointer", padding: "10px 12px", border: `1.5px solid ${accent}`, borderRadius: 8, background: "#FAF7F2",
        }}>
          <span>{value}</span>
          <span style={{ fontSize: 11, color: "#24143080", textTransform: "uppercase" }}>{format}</span>
        </summary>
        <ul style={{ listStyle: "none", margin: "8px 0 0", padding: 4, border: "1.5px solid #24143020", borderRadius: 8, maxHeight: 140, overflowY: "auto" }}>
          {["1:00 PM", "1:30 PM", "2:30 PM", "3:00 PM", "3:30 PM"].map((t) => (
            <li key={t} style={{
              padding: "6px 8px", borderRadius: 6, fontSize: 13,
              background: t === "2:30 PM" ? accent : undefined,
              fontWeight: t === "2:30 PM" ? 600 : undefined,
            }}>{t}</li>
          ))}
        </ul>
      </details>
    </div>
  );
}