---
## TimeInput
**Stability:** beta — the API shape is settled and documented; behaviour-level fixes may still land as breaking changes in a minor.
Segmented time-of-day field — hour / minute (/ second) cells in a
single unified control, with per-segment Arrow-key stepping, digit auto-advance,
and 12- or 24-hour display. Fills the last form-family gap (Calendar, DatePicker
and DateRangePicker cover dates; this covers time). The value has three states,
read off the segments alone: `undefined` while every segment is empty, `null`
while the time is half-typed (some segments filled, some blank, or, with a
`step`, a mid-entry digit leaving the time off the raster), and a canonical
24-hour `HH:MM` (or `HH:MM:SS`) string once it is complete, regardless of display
format. `step` sets a raster in seconds, as on ``. An
`onfocusout` you pass lands on the root and runs after the `min`/`max` clamp, on
every hop between segments too: the field was left when `relatedTarget` is outside
`currentTarget`.
**Import:** `import { TimeInput } from '@urbicon-ui/blocks';`
### Examples
```svelte
```
```svelte
```
```svelte
```
### Variants
- intent: danger, default, success, warning (default: default)
- variant: filled, ghost, outlined (default: outlined)
- size: lg, md, sm (default: md)
- disabled: true (default: false)
- fullWidth: true (default: false)
- messageType: error, helper (default: helper)
- readonly: true (default: false)
- required: true (default: false)
- tier: commit, modify (default: modify)
### Api
| Prop | Type | Required | Default | Description |
| --- | --- | :---: | --- | --- |
| ...HTMLAttributes | `HTMLAttributes` | no | | HTML attributes (excluding: 'class' | 'id' | 'aria-label' | 'children') |
| ...TimeInputVariants | `VariantProps` | no | | Styling variants from TimeInputVariants |
| aria-label | `string` | no | | Accessible name for the field group when no visible `label` is set. |
| class | `string` | no | | Extra classes merged onto the root wrapper. In the same Tailwind bucket `class` wins over the `slotClasses` entry for the element it lands on. Presets and provider defaults sit below both. |
| disabled | `boolean` | no | false | Blocks input and dims the whole field. |
| error | `string` | no | | Error message below the field. When set it overrides `helper`, colours the field danger, and marks the segments `aria-invalid`. |
| format | `'12h' | '24h'` | no | '24h' | Display the hour as 12-hour with an AM/PM segment. The value stays 24-hour. |
| fullWidth | `boolean` | no | false | Stretch the field to the full width of its container. |
| helper | `string` | no | | Helper text below the field — hidden when `error` is present. |
| icon | `Snippet` | no | | A custom leading icon; replaces the default clock. |
| id | `string` | no | | Root id; the segments derive their ids and ARIA wiring from it. |
| label | `string` | no | | Label text displayed above the field, linked via `aria-labelledby`. |
| max | `string` | no | | Latest allowed time, canonical 24-hour `HH:MM`(`:SS`). Values above it are clamped down on blur, to the last `step` raster point at or below it. |
| min | `string` | no | | Earliest allowed time, canonical 24-hour `HH:MM`(`:SS`). Values below it are clamped up on blur. It is also where the `step` raster starts. |
| name | `string` | no | | Name for a hidden input carrying the canonical value, for native form submission; it submits `""` while the field is empty or half-typed. |
| onValueChange | `(value: string | null | undefined) => void` | no | | Fires whenever the field changes the value (typing, the Arrow keys, Backspace, the clamp on blur) with the canonical 24-hour string, `null` while half-typed, or `undefined` once every segment is empty again. Setting `value` yourself does not fire it. |
| preset | `string` | no | | Apply a named preset registered via ``. |
| readonly | `boolean` | no | false | Shows the time but refuses edits; the segments stay focusable. |
| required | `boolean` | no | false | Marks the label with an asterisk and sets `aria-required` on the segments. It does not block a native submit — the value lives in component state, so validate it yourself before you act on it. |
| showIcon | `boolean` | no | true | Show the leading clock icon. |
| slotClasses | `Partial>` | no | | Per-slot class overrides merged with tv() styles. Slots: wrapper (what `class` also targets) | label | requiredMark | field | icon | segment | separator | meridiem | message. In the same Tailwind bucket `class` wins over the `slotClasses` entry for the element it lands on. Presets and provider defaults sit below both. |
| step | `number` | no | | Raster in seconds, counted from `min` (or midnight) as on ``: `900` is a 15-minute grid, `3600` whole hours. Unset, every minute is allowed (every second with `withSeconds`). - From a time on the raster, the Arrow keys move a segment to its next raster value and wrap inside it without carrying into the others. From a time off it (one you passed in, or a digit mid-entry), Up goes to the first raster point above and Down to the first below. `aria-valuemin`/`aria-valuemax` name the first and last raster value of each segment for the time shown. - A typed time off the raster snaps down to the raster point below it as soon as its segment is complete. While a digit is still mid-entry and the time it spells is off the raster, the value is `null`, so it never carries an off-raster time and always matches what the field shows. A time you pass in is shown as given, fixed segments included, and lands on the raster with the next edit or on blur. - The raster counts from `min`: with `min="09:10"` and `900`, a typed `10:00` lands on `09:55`. - A segment the raster pins to one value is shown but not typed: an hourly step fixes the minute (and second), a whole-minute step fixes the second. - Without `withSeconds` only the step's whole-minute points count: `30` allows every minute, `90` every third. - With a step that does not divide an hour (or a minute, with `withSeconds`), typing and the blur clamp reach every raster point, but the Arrow keys only move along points that keep the other segments; prefer a step that divides the hour. Must be a positive whole number; anything else is ignored, with a warning in dev. |
| unstyled | `boolean` | no | | Remove all default tv() classes — only user-provided classes apply. |
| value | `string | null | undefined` | no | | The time as the segments spell it, in one of three states: - `undefined` while every segment is empty, untouched or cleared back to empty. Leave the prop out (or bind `undefined`) for an empty field. - `null` while the time is half-typed: at least one segment holds a digit and at least one is blank, or, with a `step`, a mid-entry digit leaves the time off the raster. - A canonical 24-hour `HH:MM` / `HH:MM:SS` string once the time is complete; `format` never changes it. An AM/PM segment always holds a value, so it never makes a time half-typed. `""` reads as no time, like `null` and `undefined`. Passing no time clears the field: one that shows a complete time clears wherever focus is, a half-typed one only while focus is outside it. On a half-typed field with focus inside, no time is taken as the echo of the field's own report and ignored, so a consumer that stores no time as one value (`""` or `undefined`) cannot wipe the digits being typed; the cost is that a reset fired from inside a half-typed field (an Escape handler on it, or a clear button that keeps focus with a `mousedown` `preventDefault`) is ignored too, and nothing is written back, so value and segments disagree until the next edit. A reset has to change the value: a half-typed bound field already holds `null`, so reset it with `undefined`. Where neither works (a reset from inside, or a `string`-typed consumer that can only write `""`), remount the field with `{#key}`. A `null` you pass at mount renders empty and stays `null` until the user edits. Supports `bind:value`. |
| withSeconds | `boolean` | no | false | Add a seconds segment. |
| intent | `'danger' | 'default' | 'success' | 'warning'` | no | default | Controls the color theme and semantic meaning of the TimeInput. Affects the overall appearance and user perception. Available options: danger, default, success, warning. |
| variant | `'filled' | 'ghost' | 'outlined'` | no | outlined | Controls the visual style and presentation of the TimeInput. Determines the component's visual treatment. Available options: filled, ghost, outlined. |
| size | `'lg' | 'md' | 'sm'` | no | md | Controls the dimensions, padding, and text size of the TimeInput. Affects the component's physical footprint. Available options: lg, md, sm. |
| messageType | `'error' | 'helper'` | no | helper | Controls the messageType behavior and appearance of the TimeInput component. Available options: error, helper. |
| tier | `'commit' | 'modify'` | no | modify | Selects the semantic radius tier of the TimeInput — the shape family it belongs to (`--radius-commit`/`-modify`/`-contain`/`-bridge`). Shape is retuned per family in your theme, so this picks the family rather than a pixel value. Available options: commit, modify. |
Inherited from:
- Omit (omit-pattern)
- Omit, 'class' | 'id' | 'aria-label' | 'children'> (omit-pattern)
### Types
```ts
type SlotNames = keyof ReturnType & string
```
```ts
type VariantProps = Omit<
Exclude[0], undefined>,
'class'
>
```
### Slots (slotClasses keys)
`wrapper`, `label`, `requiredMark`, `field`, `icon`, `segment`, `separator`, `meridiem`, `message`