Accessibility
RecurrenceField composes a Select for frequency and time zone, a custom panel for custom cadences, a DateInput for the start, two TimeInput fields for the window, a Switch for all day, and end-rule selectors. The summary uses aria-live="polite" and aria-atomic. formatRecurrenceSummary returns the same sentence for a chip. When trigger is set, the popover is named by copy.popoverTitle.Combobox, Switch, Calendar, TimeInput, Input, Label) is a Prepared-shipped component with its own a11y story: labels, keyboard handling, and focus styling.confirm + trigger are set, the picker holds draft changes internally and only emits onValueChange when Apply fires: so closing the popover via Escape discards the draft without committing.disabled passes down to every sub-control so a parent "view only" state doesn't leave part of the rule editable.formatRecurrenceSummary returns the sentence the field shows. The field already announces draft changes with aria-live="polite".role="group" with aria-labelledby pointing at a visible heading (e.g. "Schedule"), or aria-label if no heading exists.trigger is set, the trigger element owns its accessible name; icon-only triggers need aria-label.formatRecurrenceSummary for a chip. The field's own live region covers the draft.Combobox (or your preferred entry point) when the popover opens so keyboard users land inside the panel.Comboboxs move between options; Enter or Space commits the focused option; Escape closes the combobox without committing.Calendar match Calendar: Up / Down by week, Left / Right by day.Switch.confirm + trigger are set).role="group" with a name.Select listboxes. The time zone value is an identifier and stays left-to-right.FlexBox with Combobox and selectors; each selector owns its own semantics.@prepared911/ui primitive with its own roles and labels.<button> via @prepared911/ui Button.aria-live="polite". formatRecurrenceSummary is the same sentence for a chip beside the trigger.Combobox, Calendar, or Switch show up here, too: validate against those components' individual guidance.confirm is false, every sub-control change emits onValueChange. Surfaces that rely on draft-only behavior should always pair confirm with trigger.GMT-4 (New York).