sdxc

Type to search, or start from one of these:

TimeField

A convenience wrapper composing a labeled, described, and validated time field in one call.

Thursday 24 September

Front desk · Ana Ruiz

Between 09:00 and 17:00, in quarter-hour steps.

The shift ends before it starts.
View code
<form
	method="post"
	action="/rota"
	mix={[on<HTMLFormElement, "submit">("submit", (event) => event.preventDefault())]}
>
	<Card>
		<Card.Header>
			<Card.Title>Thursday 24 September</Card.Title>
			<Card.Description>Front desk · Ana Ruiz</Card.Description>
		</Card.Header>
		<Card.Content mix={[vstack({ gap: 4, align: "stretch" })]}>
			<TimeField
				label="Shift starts"
				name="startTime"
				required
				min="09:00"
				max="17:00"
				step={900}
				defaultValue="09:30"
				description="Between 09:00 and 17:00, in quarter-hour steps."
			/>

			<TimeField
				label="Shift ends"
				name="endTime"
				required
				min="09:00"
				max="17:00"
				step={900}
				defaultValue="09:00"
				errorMessage={issues.endTime}
			/>
		</Card.Content>
		<Card.Footer mix={[hstack({ gap: 2, align: "center", justify: "end" })]}>
			<Button type="submit">Save the shift</Button>
		</Card.Footer>
	</Card>
</form>

Installation

An ordinary dependency: install it, import the theme once, and import the component where it is used.

npm add @sdxc/ui
import "@sdxc/ui/theme.css";

Usage

import { TimeField } from "@sdxc/ui";

Composes Label, a native <input type="time"> control through Input, Description, and FieldError into one field, computing every id and aria-describedby link from this identifier.

Examples

<TimeField
	label={t("event.reminderTime.label")}
	min="09:00"
	max="18:00"
	description={t("event.reminderTime.hint")}
/>
<TimeField
	label={t("event.endTime.label")}
	name="endTime"
	defaultValue="09:00"
	errorMessage={t("event.endTime.beforeStart")}
/>

Props

Read from the component's own types, so every prop, every default and every allowed value is listed.

PropTypeDescription
color?"brand" | "neutral" | "success" | "warning" | "danger"Semantic color role for the control's focus ring. Defaults to "neutral" when omitted.
labelRemixNodeThe field's caption, rendered through Label and associated with the control through a native for/id relationship computed from this instance's own identifier.
description?RemixNodeSupporting copy rendered through Description beneath the control and referenced by the control's aria-describedby. Omit to render no description.
errorMessage?RemixNodeValidation message rendered through FieldError beneath the control, marking aria-invalid unless set explicitly. Falls back to a Form's own issues message by name; an explicit value wins.
autoFocus?booleanNative autofocus. Defaults to true for the first invalid field of an enclosing Form's issues, landing keyboard focus on the problem with no client JavaScript; pass explicitly to override.
name?stringNative name submitted with an enclosing form.
value?stringCurrent value, in the platform's "HH:mm" (or "HH:mm:ss") format, for a control a consumer tracks itself.
defaultValue?stringInitial value, in that same format, for a control left to the platform's own uncontrolled state.
min?stringEarliest accepted time, in the same "HH:mm"/"HH:mm:ss" format.
max?stringLatest accepted time, in the same "HH:mm"/"HH:mm:ss" format.
step?numberGranularity of the accepted value, in seconds — set to 1 to surface a seconds digit alongside hours and minutes.
required?booleanMarks the control required for its enclosing form.
disabled?booleanMarks the control inert and excluded from the tab order.
readOnly?booleanMarks the control's value fixed, while keeping it focusable and included in form submission.
autoComplete?stringNative autofill hint, e.g. "bday".
parts?PartsPropsPer-part styling for this wrapper's internally composed elements.

Also accepts everything in Omit<TagProps<"div">, "children">.

Types

NameValuesWhat it decides
Color"brand" | "neutral" | "success" | "warning" | "danger"Semantic color role for the control's keyboard focus ring, each mapped to its matching --ui-* variables.