Skip to content

Composite fieldset input (e.g. date+time pair) with one shared warning wired to each member control #42

Description

@joshbruce

Describe the feature

A composite field type: a fieldset with a legend grouping several logically-linked inputs (e.g. a date input + a time input forming one date-time moment), where a single warning message renders once for the group and aria-describedby/aria-invalid are wired onto each member control.

Sketch of the consumer-facing shape:

DateTimeInput::create('Start', 'start')          // legend + name prefix
    ->warningMessage($messageOrElement);         // renders once, inside the fieldset
<fieldset>
  <legend>Start</legend>
  <label for="start-date">Date</label><input id="start-date" name="start-date" type="date" aria-invalid="true" aria-describedby="start-warning">
  <label for="start-time">Time</label><input id="start-time" name="start-time" type="time" aria-invalid="true" aria-describedby="start-warning">
  <p id="start-warning">The start date and time could not be understood.</p>
</fieldset>

Why is this feature necessary?

The 4.x form inputs cover single-control fields well, and Select 4.1.1 established the pattern for one-warning-per-group (radio/checkbox). A date+time pair is the same shape — one logical value across two controls — but currently has no library home. Consumers (this came up in a WCAG 2.2 SC 3.3.1 inline-warnings implementation) must hand-assemble the fieldset, the legend, the visually-hidden sub-labels, and the shared-warning wiring, and must take care not to hand the warning to either sub-input (which would render it twice). A library type would make the accessible pattern the default rather than a per-consumer rebuild.

Describe alternatives you've considered

  • Composing two TextInputs inside a hand-built fieldset (what the consumer does today): works, but the shared-warning semantics — one message, wired to both controls — have to be re-derived by every consumer, and the warning API on the single inputs actively encourages the wrong thing (pass the warning to one sub-input, leaving the other unmarked).
  • Handing the warning to a wrapping Select-like group type: Select is options-based; a free-form input group is a different contract and probably deserves its own class rather than overloading Select.

Happy to share the consumer implementation (legend, sr-only sub-labels, pair naming by {name}-date/{name}-time suffix) as a starting point if useful.

Activity

  1. joshbruce commented on Oct 5, 2026

    @joshbruce
    MemberAuthor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions