Repository navigation
Components: Apply Button / ToggleButton state-ownership decision #4215
Description
Summary
Apply the confirmed Button / ToggleButton state-ownership boundary to the reviewed local contracts and divergence records. The ownership decision is made; repository source alignment and ToggleButton implementation are not yet completed.
Confirmed owner decision - 2026-10-02 (UTC; 2026-10-01 PDT)
Button can display selected or not-selected presentation. Real toggle behavior is owned by a distinct ToggleButton.
| Component | State contract | Activation |
|---|---|---|
| Button | Optional externally driven selected; selected icon/weight/layout presentation may remain. |
Reports onPress; does not mutate selected and has no self-driving defaultSelected / onSelectedChange API. |
| ToggleButton | Controlled/uncontrolled selected / defaultSelected / onSelectedChange, resolved by useToggleState. |
Requests the next value when controlled; updates internally when uncontrolled. Pointer, keyboard, and native toggle actions share the same exactly-once state owner. |
Controlled false is not omission. Disabled activation must not toggle or report an accidental state change.
Observed source state - 2026-10-02 (UTC)
Audited main at 75c55923873124201d2ffbf3b3e67960047bd481:
- Button already renders selected state without changing it on press; its tests cover that behavior.
- Supplying selected currently also enables checked accessibility presentation and the selected icon/ghost-label path. This is observable compatibility behavior, not component-owned toggling; do not silently remove it as part of this decision.
- Button's contract still classifies
button-selection-axisas deferred alignment and uses toggle-oriented terminology. Review/update the disposition and wording to match the confirmed boundary; this issue edit does not alter those files. - Shape currently supports rounded/square/circle; square is documented as an accepted local extension. The single icon plus iconPosition/selectedIcon layout remains a separately deferred alignment.
- ToggleButton has no implementation or colocated contract on main. Its generation remains Components: Generate Toggle Button #4247 under Components: Missing components #4273.
Scope
- Apply the confirmed selection-ownership boundary to Button's SPEC, provenance divergence record, relevant companions, and public documentation/comments without removing its externally driven selected presentation.
- Review the ToggleButton native contract and state/activation/accessibility responsibilities in Components: Generate Toggle Button #4247. Reuse Button's rendering/styles/focus foundation where the contracts match; state ownership stays in ToggleButton.
- Keep shape and independent leading/trailing-icon alignment separate. Preserve existing Button APIs unless a separately reviewed proposal authorizes a migration; the owner has not selected an unrelated shape/icon breaking change here.
- Document V1 checked/defaultChecked versus the agentic selected/defaultSelected/onSelectedChange naming when ToggleButton ships.
Acceptance
- Record the owner decision and remove the unanswered ownership gate from Components: Generate Toggle Button #4247 and Components: Missing components #4273.
- Update reviewed Button contract/source divergence records and relevant wording to distinguish selected presentation from owned toggling.
- Review ToggleButton's contract with controlled/uncontrolled behavior, exactly-once pointer/keyboard/native action activation, disabled behavior, and compatibility boundaries.
- Preserve Button's existing selected presentation, ref/focus behavior, shape, and icon APIs unless a separate reviewed API change is approved.
- Add or retain runtime/type/story evidence for Button not auto-toggling and ToggleButton owning transitions; validate any resulting source changes through package scripts and add an appropriate changeset.
Dependencies and status
The ownership decision no longer blocks #4247 contract authoring. Keep this issue open for the source/contract follow-through above; do not claim a source update or a shipped ToggleButton based solely on this decision record. The completed #4252 provides the contract/provenance workflow. Broader coverage and readiness remain #4216 and #4251.
Evidence
packages/agentic/components/src/components/button/button.types.ts.packages/agentic/components/src/components/button/useButton.tsandpackages/agentic/components/src/components/button/button.test.tsx.packages/agentic/components/src/components/button/SPEC.md.packages/framework-base/src/hooks/useToggleState.ts.packages/agentic/components/src/components/AGENTS.md.
Activity
[-]Align Button and ToggleButton contracts against upstream[/-][+]Components: Align Button and ToggleButton contracts against upstream[/+][-]Components: Align Button and ToggleButton contracts against upstream[/-][+]Components: Apply Button / ToggleButton state-ownership decision[/+]