Repository navigation
fix(theme): give the field surface a 3:1 border - #340
Merged
Merged
Conversation
WCAG 1.4.11 asks for 3:1 between a control's boundary and the colours next to it. The field border was gray-200 (1.58:1 on white), the ghost variant had no edge at rest and the read-only state differed only by a gray-50 tint (1.09:1). The shared field surface now uses gray-450 and gray-500 for the rest and hover borders, at least 3.20:1 against each fill, the read-only fills and the light and dark page backgrounds. Ghost shows a bottom border with square bottom corners, the invalid state sets the bottom colour so a ghost field's underline turns to the error colour, and read-only adds a dashed border. A new contrast test reads the tokens from the recipe and fails if any border drops below 3:1. The Input, Textarea, InputDate and OTP pages describe the new surface. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The shared surface test now checks all nine color and variant compounds with toEqual, so a wrong rest or hover token on any of them, or an extra declaration in a ghost slot, fails it. The Input Date and OTP Ghost sentences no longer open with inline code, and the Input and Textarea Ghost sections say "low-chrome layouts" like the other two pages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch was successfully deployed
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.
Description
People need to see where a field is before they can use it, and WCAG 1.4.11 asks for 3:1 between a control's boundary and the colours next to it. The shared field surface fell short in three places: the border was
gray-200(1.58:1 on white), theghostvariant had no edge at rest and the read-only state differed only by agray-50tint (1.09:1). This changesfieldSurfaceCompoundVariants, which reachesuseInputRecipe,useTextareaRecipe,useInputDateRecipeanduseOtpCellRecipe.lightcolour usesgray-450at rest andgray-500on hover in both modes,darkusesgray-500andgray-450, andneutralfollows the mode. Every pair is at least 3.20:1 against the field's fill, the read-only fills and the light and dark page backgrounds.borderBottomColor: @color.errorin all four slots. It comes after the ghost compounds, so a ghost field that is invalid gets the error underline. In the compiled CSS everyborder-bottom-colorrule follows everyborder-colorrule, so it wins in both scopes.borderStyle: @border-style.dashedand keeps thegray-50fill (gray-800in dark mode), ghost included.fieldSurfaceContrast.test.tsreads every border token from the recipe, resolves it throughuseDesignTokensPresetand checks it with culori'swcagContrast. Putting one border back togray-200fails it. The culori shim gains thewcagContrastdeclaration.Related issue
None in this repository.
Type of change
Checklist
feat(theme): …)pnpm build:nodocs && pnpm lint && pnpm typecheck && pnpm testand everything passespnpm changeset) for changes to publishable packages, or this change only touches docs/storybook/app/playground/testsdist/,.styleframe/)mainand stays focused in scopeNotes / screenshots
What ran:
pnpm build:nodocs,pnpm --filter @styleframe/theme test(3409 passed),pnpm typecheck,oxlintandoxfmt --checkon the touched TypeScript files,pnpm build:docsandpnpm --filter @styleframe/docs test:build, and the Storybook build. The fullpnpm lintandpnpm testdidn't run, so that box stays unticked.In the built Storybook, light and dark, every field computes a visible border at rest. Ghost has a transparent top edge, a
gray-450orgray-500bottom edge that swaps on hover and a0pxbottom-left radius. Read-only computes a dashed border on thegray-50orgray-800fill, and a ghost read-only field computes the fill with a dashed bottom edge. A ghost invalid field computes--color--erroron its bottom edge, at rest and on hover.A ghost field that is invalid shows the error colour on all four sides, as it did before, because the invalid compound also replaces the ghost's transparent
borderColor. With the new square bottom corners, that box has rounded top corners and square bottom ones.🤖 Generated with Claude Code