Functional Weave
Code in Python

react.form.date-input@1.0.1

README.md

3,586 bytes · view raw

# react.form.date-input

A date asked as three text boxes - Day, Month, Year - under one `<legend>`,
with a hint and an error message described to the whole group. It is the
GOV.UK Design System date input as a React component, and it is made to take
`form.date-parts`'s answer directly: its `message` is the `error`, its
`fields` the `errorFields`, so exactly the boxes that need fixing are marked.

```tsx
"use client";
import { useState } from "react";
import { DateInput } from "#fune/react.form.date-input@^1";
import { validateDateParts, type DateParts } from "#fune/form.date-parts@^1";

const [dob, setDob] = useState<DateParts>({ day: "", month: "", year: "" });
const check = submitted
  ? validateDateParts(dob, "Date of birth", { today, timing: "past", notBefore: null, notAfter: null })
  : null;

<DateInput id="dob" legend="What is your date of birth?" hint="For example, 27 3 2007" birthday
  value={dob} onChange={setDob}
  error={check?.message} errorFields={check?.fields} />
```

The same `validateDateParts` runs in a Python or Rust API on the posted
`dob-day`, `dob-month` and `dob-year`, with the same messages.

- **ids and names**: the `fune-date-input` wrapper is `id` (as GOV.UK), the hint and error `<id>-hint` and `<id>-error`, the boxes `<id>-day`,
  `<id>-month`, `<id>-year` (so an error summary can link to `#dob-day`);
  their names are `<name>-day` and so on, `name` defaulting to the id.
- **Boxes in error**: with an `error`, the boxes listed in `errorFields` get
  `fune-input--error` and `aria-invalid="true"`; with none listed, all three
  do, which is GOV.UK's style for an error about the whole date. Without an
  `error`, nothing is marked.
- **Keyboard**: `type="text"` with `inputMode="numeric"`, as GOV.UK does:
  `type="number"` rounds, scrolls and refuses "jan", which GOV.UK asks
  services to accept.
- **birthday** adds `autoComplete` `bday-day`, `bday-month`, `bday-year`
  (WCAG 2.2, 1.3.5 Identify Input Purpose).
- **value** with **onChange** is controlled; **defaultValue** alone is
  uncontrolled. Either way `onChange` receives all three boxes' text
  (`{ day, month, year }`), untrimmed, never the event.
- **onBlur** is called, with nothing, whenever any of the three boxes loses
  focus, so a form can mark the date touched (`form.state`'s blur action).
- It keeps the boxes' text in state for onChange, so it is a client component
  and its file starts with `"use client"`.

GOV.UK also puts `role="group"` on the date's `<fieldset>`; `react.form.fieldset`
1.0.0 does not take a role, so this does not either. A fieldset is already a
group to assistive technology, so nothing is lost.

Classes: those of `react.form.fieldset` and `react.form.form-field` (each box
sits in its own `fune-field` with a `fune-label`), plus `fune-date-input`,
`fune-date-input-item`, `fune-input` (and `fune-input--error`),
`fune-input--width-2` (day, month) and `fune-input--width-4` (year). Style a
box inside a date with `.fune-date-input .fune-input`.

Sources: GOV.UK Design System, "Date input"
https://design-system.service.gov.uk/components/date-input/ and the "Dates"
pattern https://design-system.service.gov.uk/patterns/dates/; WCAG 2.2, 1.3.5
Identify Input Purpose https://www.w3.org/WAI/WCAG22/Understanding/identify-input-purpose.

## Notices

Portions derived from GOV.UK Frontend (https://github.com/alphagov/govuk-frontend), Copyright (c) 2017 Crown Copyright (Government Digital Service), under the MIT License; the full notice is in NOTICE.

1.0.1 adds its attribution notices (NOTICE). The code and the tests are unchanged.