Add .switch toggle and .input-group (input with attached buttons/selects) form components
Specification
Add .switch and .input-group form components
Motivation
.field covers labelled controls, but there is no toggle switch and no input with an attached button. In a benchmark, agents fell back to plain checkboxes and hand-wrote flex CSS for attached buttons, which violates AI Generation Rule 2 (no custom CSS). Both patterns should be first-class components.
Scope
.switch
Markup:
<label class="switch"><input type="checkbox" role="switch" checked> Require admin approval</label>
- Styles the native
input[type=checkbox]inside.switchwithappearance: none, drawn as a track with a thumb (pseudo-element). - On state (
:checked): the track uses--color-primaryand the thumb moves to the end side. :disabledgets reduced opacity andcursor: not-allowed. The label text is styled to match.- The thumb and track transition use
--duration-fastand--ease-standard. Assumption: transitions are disabled underprefers-reduced-motion: reduce, if the framework already follows that pattern. :focus-visibleuses the existing--focus-*tokens.- Only existing tokens are used. Assumption: the switch dimensions are derived from existing size or spacing tokens, and new tokens are added only if they are documented in the token reference.
.input-group
Markup:
<div class="input-group"><input type="url" readonly value="…"><button type="button" class="button">Copy</button></div>
- An inline flex row. Children can be
input,selectand.button. - Adjacent children share borders, with no doubled borders. Only the outer corners (first child's start and last child's end) are rounded. Inner corners are square.
- Inputs grow (
flex: 1 1 auto; min-width: 0). Buttons and selects keep their intrinsic size. - All children share a height that respects
--input-height/--control-height. - A focused child's focus ring is not clipped by its neighbours (for example, by raising its
z-index). - Assumption: non-button addons such as unit labels are out of scope unless the proposer confirms otherwise.
Contract and docs
- Add both components to Component Vocabulary and Intent Mapping in
synthcss.llm.md, with exactly one Valid Example each. - Mirror these additions in
synthcss.ai.jsonso the existing sync verification passes.
Acceptance criteria
-
.switchis a native checkbox withrole="switch". It toggles with Space, is reachable by Tab, and shows a visible focus ring. -
.switchreflectscheckedanddisabledwith no extra classes. -
.input-groupjoins an input with one or more.buttonand/or<select>children. The result has no doubled borders and rounded outer corners only, and needs no custom CSS. - Both components render correctly inside
.field, alongside.field-label,.field-helpand.field-error. - Both components use only existing design tokens (or newly documented ones). There are no hard-coded colours.
-
synthcss.llm.mdandsynthcss.ai.jsonare updated, and all existing tests, lint, build and sync-verification checks pass. - Tests are added or extended, following existing repo conventions (for example, CSS selector presence and contract sync), to cover the new classes.
Out of scope
- JavaScript behaviour, such as copy-to-clipboard.
- Size variants, vertical input groups, and addon text segments.
- Showcase updates, unless the proposer confirms them.
Discussion · 0
No comments yet.