Rewrote all the docs - more noob friendly now.

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-05-05 23:55:26 +05:00
parent e483bf73e7
commit f6ae86617c
35 changed files with 2159 additions and 2341 deletions
+45 -81
View File
@@ -1,53 +1,18 @@
# TimePicker
A styled time picker. The user selects hours, minutes, and optionally AM/PM. The component always writes the selected time as `HH:MM` (24-hour) to the hidden input, regardless of whether 12-hour display mode is used. Optionally renders a visible label and description.
A styled time selector with separate dropdowns for hours and minutes (and optionally AM/PM). The selected time is always stored in a hidden input as `HH:MM` in 24-hour format, regardless of whether you show the 12-hour display mode.
---
## HTML structure
## Quick example
```
div.flex.flex-col.gap-1.5
label.text-sm.font-medium ← omitted when empty
{label}
div.flex.items-center.gap-1.rounded-md.border.border-input.bg-background.px-3.py-2
select.timepicker-h[name={name}-h] ← hour select (112 or 023)
span.text-muted-foreground :
select.timepicker-m[name={name}-m] ← minute select (0059)
select.timepicker-ampm[name={name}-ampm] ← AM/PM (12h mode only)
input.sr-only[type=hidden, name={name}] ← hidden input holding HH:MM
p.text-sm.text-muted-foreground ← omitted when empty
{description}
```csharp
new TimePicker(name: "startTime", label: "Start time")
```
---
## CSS mechanics
| Class | Effect |
|---|---|
| `rounded-md border border-input bg-background` | Consistent styling with other form fields |
| `sr-only` on hidden input | Hidden visually but included in form submission |
| `appearance-none` on `<select>` elements | Removes native browser dropdown arrow for uniform style |
| `focus:outline-none` on selects | Focus ring deferred to the wrapper `div` |
---
## JavaScript (`syncTime` in `components.js`)
Runs on `DOMContentLoaded` and `htmx:afterSwap`.
### `syncTime(wrapper)`
1. Finds `.timepicker-h`, `.timepicker-m`, `.timepicker-ampm`, and the hidden `input`
2. On any `change` event across the three visible selects:
- Reads hour, minute, and AM/PM values
- Converts 12h → 24h if AM/PM select is present
- Writes `HH:MM` to the hidden input
---
## Constructor signature
## All the options
```csharp
public TimePicker(
@@ -58,49 +23,24 @@ public TimePicker(
bool use12h = false)
```
| Parameter | Description |
| Parameter | What it does |
|---|---|
| `name` | Form field name; hidden input gets this name, visible selects get `{name}-h`, `{name}-m`, `{name}-ampm` |
| `selected` | Pre-selected time as `"HH:MM"` (24h format); defaults to current time |
| `label` | Optional visible label |
| `description` | Optional helper text |
| `use12h` | If `true`, shows AM/PM select and hour range 112 |
| `name` | Form field name. The hidden input gets this name and always holds a `HH:MM` value. The visible selects get `{name}-h`, `{name}-m`, `{name}-ampm`. |
| `selected` | Pre-selected time as `"HH:MM"` in 24-hour format. Defaults to the current time. |
| `label` | Visible text label above the picker. |
| `description` | Small hint text below the picker. |
| `use12h` | Show 12-hour mode with an AM/PM dropdown. The hidden input still stores 24h format. |
---
## Usage examples
## Real-world examples
### Basic time picker (24h)
```csharp
new TimePicker(name: "startTime", label: "Start time")
```
### 12-hour mode
```csharp
new TimePicker(
name: "meetingTime",
label: "Meeting time",
use12h: true)
```
### Pre-selected time
```csharp
new TimePicker(
name: "alarmTime",
selected: "07:30",
label: "Alarm",
use12h: true)
```
### Inside a form
### Appointment booking with start and end times
```html
<!-- ScheduleForm.htmx -->
<form method="post" action="/schedule">
$$AntiforgeryToken$$
<form method="post" action="/schedule" class="space-y-4">
$$Token$$
$$StartTime$$
$$EndTime$$
<button type="submit">Save</button>
@@ -108,16 +48,40 @@ new TimePicker(
```
```csharp
public ScheduleForm()
{
StartTime = new TimePicker(name: "startTime", label: "Start", selected: "09:00");
EndTime = new TimePicker(name: "endTime", label: "End", selected: "17:00");
}
// ScheduleForm.htmx.cs
_startTime = new TimePicker(name: "startTime", label: "Start", selected: "09:00");
_endTime = new TimePicker(name: "endTime", label: "End", selected: "17:00");
```
**Reading the submitted values:**
Reading on the server:
```csharp
public record Command(
[property: FromForm] string StartTime, // "HH:MM"
[property: FromForm] string EndTime
);
var start = TimeOnly.ParseExact(command.StartTime, "HH:mm");
var end = TimeOnly.ParseExact(command.EndTime, "HH:mm");
```
### 12-hour display mode with a pre-selected time
```csharp
new TimePicker(
name: "alarmTime",
selected: "07:30",
label: "Alarm time",
use12h: true)
```
The user sees `7:30 AM` in the dropdowns, but `07:30` is what gets submitted.
---
## How it works
TimePicker renders three `<select>` elements (hours, minutes, and optionally AM/PM) styled to look like a single field, plus a hidden `<input>` that holds the combined value. JavaScript in `components.js` listens for changes on any of the three selects and writes the correctly formatted `HH:MM` value to the hidden input, converting from 12h to 24h when needed.
public record Command(
[property: FromForm] string StartTime, // "09:00"
[property: FromForm] string EndTime // "17:00"