Skip to content

test(color-handle): tests and docs (phases 6-7)#6465

Open
blunteshwar wants to merge 6 commits into
color-handle-migrationfrom
color-handle/Tests
Open

test(color-handle): tests and docs (phases 6-7)#6465
blunteshwar wants to merge 6 commits into
color-handle-migrationfrom
color-handle/Tests

Conversation

@blunteshwar

@blunteshwar blunteshwar commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Description

Phases 6 (Testing) and 7 (Documentation) of the sp-color-handleswc-color-handle migration, stacked on the Phase 2–5 work merged via #6443. No component behavior changes.

Testing (Phase 6)

Unit / behavior (test/color-handle.test.ts, Storybook play tests):

  • Role-less, name-less host (no role/aria-label/aria-labelledby/tabindex); color applied to the fill layer; adaptive --_swc-color-handle-border-alpha set.
  • Touch pointerdown/pointerup/pointercancel open-close; mouse does not auto-open.
  • disabled suppresses the built-in loupe even when open.
  • fill=false renders outline-only (via the reflected boolean property).

Contrast helper (computeBorderAlpha/findMinAlpha/contrastRatio):

Accessibility (test/color-handle.a11y.spec.ts, Playwright):

  • Role-less/name-less host and built-in loupe SVG aria-hidden across chromium/firefox/webkit.

Documentation (Phase 7)

  • New per-component MDX (color-handle.mdx): Anatomy, Options (Colors, Fill), States, Behaviors (Adaptive contrast), Accessibility (features + best practices), and Upcoming features. Documents the handle as a visual primitive whose name/role/value/keyboard belong to the parent color-area/slider/wheel.
  • Stories: dropped autodocs from Playground so the MDX is the single docs page (kept dev); finalized the Accessibility story.
  • Public prop JSDoc lives on ColorHandleBase and feeds the Storybook <ApiTable />; no public --swc-* properties, so no @cssprop tags.

Motivation and context

Locks in the migrated behavior and the SWC-2295 adaptive-border logic with regression protection (answering the "no tests" feedback on #6443), and adds the Storybook docs page so the component is usable and understandable by others.

Related issue(s)

Verification

Local (Node 24.11.1): Vitest storybook project — 13 passed (5 play tests + 8 story smoke renders); Playwright a11y — 12 passed (3 browsers). yarn lint:docs-pages passes; Storybook shows a single color-handle docs entry (no duplicate). test-storybook aXe is blocked locally by an unrelated @swc/core native-binding failure + stray-worktree jest haste collision; aXe still runs in CI.

Out of scope / follow-ups

  • Consumer-facing breaking-change and migration guidance (tag rename, --mod-* removal, fill property-vs-attribute) lands in the dedicated consumer migration guide, not the per-component MDX.
  • Parent-embedded stories and full-spectrum contrast VRT come when a parent color picker (swc-color-area/-slider/-wheel) is migrated.

Author's checklist

  • I have read the CONTRIBUTING and PULL_REQUESTS documents.
  • I have reviewed the Accessibility Practices for this feature.
  • I have added automated tests to cover my changes.
  • I have included a well-written changeset if my change needs to be published. (Tests/docs only; no changeset.)
  • I have included updated documentation (per-component MDX docs page).

Accessibility testing checklist

Color handle is a non-interactive visual primitive; name/role/value/keyboard belong to the parent picker. This PR adds the a11y regression tests and docs rather than changing behavior.

  • Keyboard — no focusable parts on the handle itself (parent owns keyboard); confirm no focusable node is introduced.

    1. Open Storybook story Color Handle/Overview.
    2. Tab through the canvas.
    3. Expect the handle host to not receive focus / expose no role.
  • Screen reader — handle exposes no role/name; built-in loupe SVG is aria-hidden.

    1. Open Color Handle/Accessibility.
    2. Inspect the accessibility tree.
    3. Expect no role/name on the host and the loupe SVG hidden.

…(phase 6)

- color-handle.test.ts (Storybook play tests): role-less/name-less host,
  color applied to the fill layer, adaptive border-alpha variable set,
  touch pointerdown/up/cancel open-close (mouse does not auto-open),
  disabled suppresses the loupe, and fill=false outline-only via the
  reflected boolean property.
- Contrast-helper unit coverage (computeBorderAlpha, findMinAlpha,
  contrastRatio): parser yields no NaN across named/hex/rgb/hsl/rgba,
  floor fallback for invalid input, white-first floor vs escalation.
  Covers the PR-review parser concern with a regression test.
- color-handle.a11y.spec.ts (Playwright): role-less/name-less host and
  built-in loupe SVG aria-hidden across chromium/firefox/webkit.

Verified locally (Node 24.11.1): Vitest storybook 13 passed, Playwright
a11y 12 passed. Also corrected the plan's B7 consumer path: outline-only
is set via the `fill` property (reflected boolean), not `fill="false"`.

Refs SWC-2137, SWC-2295
@blunteshwar blunteshwar requested a review from a team as a code owner July 2, 2026 09:27
@changeset-bot

changeset-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: df98f04

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

📚 Branch Preview Links

🔍 First Generation Visual Regression Test Results

When a visual regression test fails (or has previously failed while working on this branch), its results can be found in the following URLs:

Deployed to Azure Blob Storage: pr-6465

If the changes are expected, update the current_golden_images_cache hash in the circleci config to accept the new images. Instructions are included in that file.
If the changes are unexpected, you can investigate the cause of the differences and update the code accordingly.

- color-handle.mdx: Anatomy, Options (Colors, Fill), States, Behaviors
  (Adaptive contrast), Accessibility (features + best practices), and
  Upcoming features. Documents the handle as a visual primitive whose
  name/role/value/keyboard belong to the parent color-area/slider/wheel.
- Stories: drop `autodocs` from Playground so the MDX is the single docs
  page (keep `dev`); finalize the Accessibility story.

Public prop JSDoc already lives on ColorHandleBase and feeds the ApiTable;
no public `--swc-*` properties, so no `@cssprop` tags. Consumer-facing
breaking-change/migration notes are deferred to the consumer migration
guide. `yarn lint:docs-pages` passes; Storybook shows a single docs entry.

Refs SWC-2137, SWC-2295
@blunteshwar blunteshwar changed the title test(color-handle): behavior, contrast-helper, and a11y coverage (phase 6) test(color-handle): tests and docs (phases 6-7) Jul 2, 2026
Story prose lives in the per-component MDX (Behaviors section), not above
story exports. Removes the JSDoc block flagged by the conformance pass.
Add the Spectrum 1 to Spectrum 2 upgrade guide for application developers:
tag/import rename, removal of the `--mod-colorhandle-*` surface (no public
replacement), the new `fill` attribute (outline-only via the property), and
the automatic adaptive-border / grow-on-focus behavior. Accessibility stance
is unchanged from 1st-gen (parent owns name/role/value/keyboard).

Refs SWC-2137, SWC-2295
…r Handle

Meta title used lowercase "Color handle", which does not match the component
title "Color Handle" (Storybook titles are case-sensitive), so the guide did
not nest under the component and left it rendering as a standalone node.
Use title case to group it under Color Handle, matching Color Loupe.
The handle is position:absolute and centers on its containing block's origin
via negative margins, so in the old 24x24 anchor it landed on the corner
(misaligned with the centered caption) and an open loupe overflowed the frame.
Anchor each handle to a zero-size relative point at the bottom-center of a
fixed 48x96 box with headroom above, so the handle centers over its caption
and the loupe stays inside the frame.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant