feat(webkit): give Switch its own disabled state - #846
Open
gabriel-lisboa-azion wants to merge 2 commits into
Open
feat(webkit): give Switch its own disabled state#846gabriel-lisboa-azion wants to merge 2 commits into
gabriel-lisboa-azion wants to merge 2 commits into
Conversation
robsongajunior
previously approved these changes
Aug 3, 2026
Switch had no `disabled` prop: the disabled visual was owned by the FieldSwitch / FieldSwitchBlock wrappers, which faked it with an opacity wash and pointer-events-none over the live control. That works only where a wrapper exists — a bare Switch, used wherever the label already sits outside the control (an ItemGroup row naming the field with Item.Title), had no wrapper to defer to, so `:disabled` blocked interaction natively while the control still looked live. The control now owns the state. `disabled` renders the token surfaces (--bg-disabled track, --text-disabled handle, cursor-not-allowed) rather than an opacity wash, and wins over the checked tokens so a locked switch reads the same in both positions. The root is natively <button disabled>, so it leaves the tab order and neither click nor Space/Enter emits update:modelValue; `aria-disabled` and `data-disabled` mirror the prop. The hover overlay is suppressed while keeping the element hit-testable, so cursor-not-allowed is what the pointer shows. FieldSwitch and FieldSwitchBlock drop their opacity/pointer-events hacks and forward `disabled` to the control.
gabriel-lisboa-azion
force-pushed
the
feat/switch-disabled
branch
from
August 3, 2026 19:38
b5d9e57 to
25668bc
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Switchgains adisabledprop, so the locked state is visible at every call site instead of only inside a wrapper.The gap.
Switchhad nodisabledprop — the disabled visual lived inFieldSwitch/FieldSwitchBlock, which faked it withopacity-50(+pointer-events-none) over a still-live control. That covers only the wrapped case. A bareSwitchis legitimate wherever the label already sits outside the control — anItemGrouprow names the field withItem.Title— and there the consumer had no wrapper to own the visual::disabledblocked interaction natively while the switch still looked interactive.Now the control owns it.
--bg-disabledtrack +--border-defaultborder +--text-disabledhandle +cursor-not-allowed. The disabled treatment wins over the checked tokens, so a locked switch reads the same in the off and on positions.<button disabled>, so it leaves the tab order and neither click norSpace/Enteremitsupdate:modelValue(both handlers early-return too).aria-disabledanddata-disabledfollow the prop.--bg-hoveroverlay is suppressed (data-[disabled]:hover:shadow-none) while the element stays hit-testable, socursor-not-allowedis what the pointer actually shows.FieldSwitch/FieldSwitchBlockdrop their opacity +pointer-events-nonehacks and simply forwarddisabledto the control.Notes
false, so existing call sites are unchanged (the two wrappers move from a visual hack to the real prop).spec_version9,.specs/switch.mdchecksum refreshed; the spec records why the earlier "Disabled is omitted" decision was reversed.catalog.jsonregenerated (switch only).Disabledstory renders both positions;switch.test.tsgrows to 28 passing cases, including a computed-style assertion that the locked track is identical off vs on and genuinely different from the enabled checked track, plus an axe pass on the disabled render.test(storybook)commit.