Skip to content

Draw the true/false switch the markup always promised - #6

Merged
AllTerrainDeveloper merged 3 commits into
mainfrom
fix/switch-control
Aug 17, 2026
Merged

AllTerrainDeveloper merged 3 commits into
mainfrom
fix/switch-control

Conversation

@AllTerrainDeveloper

Copy link
Copy Markdown
Owner

The bug

The true/false field looked like a blue rectangle wearing a checkmark. The reason is almost funny: atcf_control_true_false() has printed a .atcf-switch__track span since day one — and the stylesheet never once mentioned it. All the CSS did was inflate the native checkbox to 40×22px, which is exactly the ugly pill in the screenshot. The JS renderer (repeater rows, Field Inspector widget) was worse off still: it never emitted the track span at all.

The fix

The checkbox is now visually hidden but keeps its place in the tree — keyboard focus, screen-reader announcement, and the form submission (including the hidden-0 off-value trick) all remain the input's job — stretched over the track so the click target is the thing that looks clickable. The track becomes a real switch:

  • pill + thumb, with :checked + doing all the state work — no JavaScript owns this
  • :focus-visible ring, :disabled dimming (and the label loses its pointer cursor via :has())
  • logical properties throughout, so RTL mirrors for free
  • transitions that honour prefers-reduced-motion
  • a forced-colors block that says with borders and system colours (ButtonText / Highlight) what the track normally says with background — high-contrast themes flatten backgrounds, which was everything the design had

The JS renderer gains the same track span the PHP renderer prints, so switches inside repeater rows and the Field Inspector now match the metabox exactly. No markup contract changed — the builder's canvas preview and the vitest class-parity guard already spoke these class names; this is the stylesheet finally holding up its end.

(Not touched here: the shell's own <os-switch> off-state bug documented in BUG-os-switch-off-state-holo-fill.md — that lives in the OpenStation component, upstream of this repo. This PR fixes every switch this plugin draws itself.)

Verification

  • Vitest: 369 green (the field-preview suite already asserts the track/label classes)
  • PHPUnit: 195 green
  • tsc clean, bundles rebuilt

🤖 Generated with Claude Code

https://claude.ai/code/session_01HLZL6dY61BkPPmGyy6F9Us

AllTerrainDeveloper and others added 3 commits August 17, 2026 00:07
atcf_control_true_false() has printed a track span since day one, and
the stylesheet never once mentioned it — it just inflated the native
checkbox to 40×22, which renders as a blue rectangle wearing a tick.
The JS renderer was worse off still: it never emitted the track at all.

Now the checkbox is visually hidden but keeps its place in the tree —
keyboard focus, screen reader announcement and form submission are all
still the input's job — stretched over the track so the click target
is the thing that looks clickable, and the track is a real switch: a
pill, a thumb, `:checked +` doing all the state work with no
JavaScript. Focus-visible ring, disabled dimming, logical properties
so RTL mirrors for free, transitions that honour
prefers-reduced-motion, and a forced-colors block that says with
borders and system colours what the track normally says with
background.

The JS renderer gains the same track span the PHP renderer prints, so
switches inside repeater rows and the Field Inspector match the
metabox exactly. The builder's canvas preview and the class-parity
guard already spoke these class names — this is the stylesheet finally
holding up its end.

369 JS and 195 PHP tests green; no markup contract changed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HLZL6dY61BkPPmGyy6F9Us
The second box of the link control said "Add" — the generic button
string borrowed via the wrong l10n key — which reads as a mystery
input rather than as the box for the words a link shows. A
placeholder is the only name an optional input gets, so it now says
"Link text", with its own translatable string.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HLZL6dY61BkPPmGyy6F9Us
# Conflicts:
#	assets/js/builder.min.js
#	assets/js/fields.min.js
#	assets/js/widget.min.js
@AllTerrainDeveloper
AllTerrainDeveloper merged commit 52afa67 into main Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant