fix(ios): give a filled button a visible edge when its tint matches the surface - #78
Open
CodyPChristian wants to merge 1 commit into
Open
Conversation
…he surface A filled button whose tint resolves to the same colour as the surface it sits on has no visible edge -- it reads as text, not a control. This is easy to hit with a themed palette: a site whose brand colour is a pale cream and whose card surface is that same cream renders its primary action invisible. When primary or secondary collides with the surface, substitute a token that contrasts and keep the button filled. Filled matters: outlining it would preserve the brand colour but read as a secondary control, which is wrong for a screen's main action. The renderer cannot see what it is actually sitting on -- NodeView, which paints container backgrounds, is in the host package, so no ambient surface value reaches the button, and the same button may be used on a card or directly on the page. A candidate is therefore only accepted when it contrasts with both surface and background. Without that guard a palette whose secondary equals its page background goes invisible on the canvas while the card gets fixed. on-surface is tried next; it contrasts with the surface by construction. Semantic variants (destructive, success, accent) are never substituted -- a slate Delete button would not read as destructive -- and fall back to a hairline outline in their own label colour, as does any variant with no qualifying candidate. Detection is a channel-delta threshold tuned to catch 'same colour to the eye' without firing on light-on-light, so a normal palette is untouched.
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.
Problem
A filled button whose tint resolves to the same colour as the surface it sits on has no visible edge — it reads as text, not a control.
This is easy to hit with a themed palette. A site whose brand colour is a pale cream and whose card surface is that same cream renders its primary action invisible:
Fix
When
primaryorsecondarycollides with the surface, substitute a token that contrasts and keep the button filled. Filled matters — outlining preserves the brand colour but reads as a secondary control, which is wrong for a screen's main action.The two-parent guard
The renderer cannot see what it is actually sitting on.
NodeView, which paints container backgrounds, lives in the host package, so no ambient-surface value reaches the button — and the same button may be used on a card (surface) or directly on the page (background).So a candidate is only accepted when it contrasts with both. Without that guard, a palette whose
secondaryequals its page background gets fixed on the card and goes invisible on the canvas:on-surfaceis tried next and contrasts with the surface by construction.Scope
destructive,success,accent) are never substituted — a slate Delete button would not read as destructive. They fall back to a hairline outline in their own label colour, as does any variant with no qualifying candidate.Verified against four production white-label palettes: only the colliding one changes behaviour, the other three resolve identically to before.