Task 5.10 of #269's change. The Issue grant form showed a yellow alert
under its lead whenever its Product select offered a product marked
with the warning sign, before anything was chosen, so it read as a
standing warning. The sentence now reads "This grant would supersede a
tier a subscription pays for; its billing pauses until the grant ends."
and is the Product field's one hint line, hidden until the operator
chooses a marked product and hidden again when an unmarked one is
chosen. A refused submission that chose a marked product renders it
shown. The form's message is the lead alone.
The forms library gains the mechanism, for any Stacked form: a select
declares HintOnChoice with its Hint, options carry ShowsHint, and the
field part renders the hint only when an offered option shows it,
hidden unless the chosen one does, and named by the select's
aria-describedby only while it shows. One external script,
hint-on-choice.js, loaded with defer by the operator shell, follows
later choices and htmx swaps through data-hint-toggle and
data-shows-hint. The invariants refuse HintOnChoice off a Stacked
select, without a Hint or with a Notice, and the escape hatch refuses
data-hint-toggle.
The change's text gains a form-library requirement ("A select's hint
can wait for the option that shows it") and modifies form-conventions'
"Every control has a label, and its hint and error are described" so a
hint is described while it shows. docs/design-system.md describes the
mechanism in section 8 and adds the script to the
progressive-enhancement table.
Tests: TestOrgEnrollmentIssueGrantSupersedeHint (at rest, no marked
product, a refused submission with a marked, an unmarked and no
product, the message the lead alone), TestOperatorShellLoadsTheHintToggle,
TestRenderHintOnChoiceFollowsTheChosenOption,
TestInvariantsHintOnChoiceBelongsToAStackedSelectWithItsHint, the
escape hatch's and the invariant messages' rows, and
TestGrantSupersedeHintWalkthrough, which chooses a marked and then an
unmarked product on the demo's Carlos Member organization and checks
the hint and aria-describedby both ways. Three organization goldens
change only in the message and the Product field.
Review: round 1, three majors (the hint supplied per render, bypassing
the registry's hint checks; no spec for the library's new contract,
with form-conventions saying the opposite; the script's break
unreachable while the app serves its embedded copy) and five minors,
all fixed; round 2, no major.
Breaks: 12 of 12 caught. 8 in code; the script's 4 run as a second
list whose preparation rebuilds and restarts the app on the broken
tree. Full suite on reset databases: 4843 pass, 14 skip.
make screens: Carlos Member's organization, open and refused, at both
widths, loses the alert. Hand captures of the form at rest, with a
marked product chosen and with an unmarked one chosen after it sit
beside the change's screens.