The 96-line, 7+ branch updateSegment was doing three things in one
method: running the consumer callback, applying cross-segment
cascades (month→day, hour→dayPeriod, dayPeriod→hour), and committing
the new value with sema event dispatch. Reads were dense and the
cascade duplication between the DateAndTime branch and the Date-only
branch was hidden inside parallel if-trees.
Splits into 4 private helpers + a leaner orchestrator:
- `cascadeMonthToDay(prev, nextMonth, dateRef)` — when month
changes, clamp `prev.day` to the new month's length (e.g. day=31
on Feb → 28). Same helper used by both top-level branches.
- `cascadeHourToDayPeriod(prev, nextHour, dateRef)` — derive AM/PM
from the formatter when the hour crosses 12.
- `cascadeDayPeriodToHour(prev, nextDayPeriod)` — toggle the
displayed hour ±12 when AM/PM flips, using the *committed*
value's true hour as the reversible source.
- `setSegmentUpdating(part, next)` — stage in-flight value in
`this.states[part].updating`. No-op when the segment has no
staging slot (e.g. literals).
- `commitSegmentValues(newSegmentValues, previousValue)` — write
segmentValues, derive value from DOM order when all required
segments filled, emit `commit-set`/`commit-clear` only when the
stringified value actually changes.
Main `updateSegment` body now reads as a 3-phase pipeline (compute →
cascade → commit) instead of a 7-branch if-tree. Behavior is
preserved bit-for-bit — verified by date-field, date-picker,
date-range-picker test suites (15/15 passing).
Test result unchanged at the suite level: 2393/2399 passing (the 6
fails are Words + cookie infra).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>