Skip to content

feat(meter): scaffold 2nd-gen meter (setup, API, a11y, styling) — SWC-2008..2011#6316

Open
blunteshwar wants to merge 1 commit into
meter-migrationfrom
swc-2008-2009-2010-2011-meter-migration
Open

feat(meter): scaffold 2nd-gen meter (setup, API, a11y, styling) — SWC-2008..2011#6316
blunteshwar wants to merge 1 commit into
meter-migrationfrom
swc-2008-2009-2010-2011-meter-migration

Conversation

@blunteshwar
Copy link
Copy Markdown
Contributor

Description

Scaffolds the 2nd-gen <swc-meter> against the approved migration plan, covering four sequential phase tickets (Setup, API, Accessibility, Styling). Targets the long-lived meter-migration integration branch — not main. Subsequent phase tickets (conformance, testing, documentation, consumer migration guide, final review) ship as follow-up PRs into the same base.

Phases delivered:

  • SWC-2008 — Setup. Core / SWC file structure, package.json exports for @spectrum-web-components/core/components/meter, swc/shared/linear-progress-base.css stub.
  • SWC-2009 — API. LinearProgressMixin owns value clamping, fill-fraction, Intl.NumberFormat locale formatting via LanguageResolutionController, label / description slot tracking, and the DEBUG-mode accessible-name warning. MeterBase adds variant plus DEBUG variant validation. formatOptions is a JS-only Intl.NumberFormatOptions pass-through.
  • SWC-2010 — Accessibility. role="meter" on the shadow .swc-Meter wrapper (host carries no ARIA); aria-valuemin / aria-valuemax / aria-valuenow / aria-valuetext on the role element; label slot → aria-labelledby, accessibleLabelaria-label fallback when no label slot, description slot → aria-describedby; non-focusable.
  • SWC-2011 — Styling. Ports spectrum-css spectrum-two progressbar/index.css + meter/index.css to the swc-Meter namespace, replaces all --mod-* with --swc-meter-* tokens, covers variants (informative / positive / notice / negative), sizes (s / m / l / xl), label-position="side", static-color="white" / "black", and a forced-colors block. Stylelint, ESLint, and Prettier all clean; build green.

Motivation and context

Phase-1 plan is merged via #6215. This PR is the first implementation pass against that plan. ARIA contract follows the binding decisions in CONTRIBUTOR-DOCS/03_project-planning/03_components/meter/accessibility-migration-analysis.md (role on shadow, label slot + accessibleLabel fallback, description slot, no host ARIA).

Related issue(s)

  • SWC-2008 — Setup
  • SWC-2009 — Migrate API and TypeScript code
  • SWC-2010 — Implement accessibility features
  • SWC-2011 — Full S2 visual fidelity

Known deferrals

  • Shared linear-progress CSS stays inlined in meter.css for this PR; the lift-out to swc/shared/linear-progress-base.css happens when <swc-progress-bar> migrates (vite's postcss pipeline does not include postcss-import, and no other 2nd-gen component uses @import).
  • Description container is always emitted with an is-empty class instead of being fully omitted via nothing, so the <slot> stays mounted and slotchange fires reliably when content is added at runtime. ARIA-describedby is still gated on the tracked flag, and the empty container is hidden via CSS.
  • Stories and tests are scaffolded under separate tickets (SWC-2013, SWC-2014). This PR does not include meter.stories.ts or meter.test.ts.

Author's checklist

  • I have read the CONTRIBUTING and PULL_REQUESTS documents.
  • I have reviewed the Accessibility Practices for this feature, see: Aria Practices
  • I have added automated tests to cover my changes. (Deferred — tests ship under SWC-2013.)
  • I have included a well-written changeset if my change needs to be published. (N/A — meter-migration branch; no published package version bump until the integration branch lands on main.)
  • I have included updated documentation if my change required it. (Deferred — documentation ships under SWC-2014.)

Reviewer's checklist

  • Includes a GitHub issue with appropriate flag or Jira ticket number without a link
  • Includes thoughtfully written changeset if changes suggested include patch, minor, or major features
  • Automated tests cover all use cases and follow best practices for writing
  • Validated on all supported browsers
  • All VRTs are approved before the author can update Golden Hash

Manual review test cases

  • Default meter renders with role="meter" on the shadow .swc-Meter.

    1. Build 2nd-gen (yarn build:2nd-gen).
    2. Import @adobe/spectrum-wc/components/meter/swc-meter.js in a sandbox page.
    3. Render <swc-meter value="40"><span slot="label">Storage used</span></swc-meter>.
    4. Inspect the shadow root. Expect role="meter" only on the inner .swc-Meter element; the host element has no role attribute. aria-valuemin="0", aria-valuemax="100", aria-valuenow="40", aria-valuetext matches the rendered percent.
  • Accessible name resolves from the label slot.

    1. Render the same meter as above.
    2. Confirm the role element has aria-labelledby pointing at the shadow id of the label container.
    3. Remove the label slot and add accessible-label="Storage usage".
    4. Confirm the role element switches to aria-label="Storage usage" and aria-labelledby is absent.
  • Variants and sizes apply S2 tokens.

    1. Render meters with variant values informative, positive, notice, negative across sizes s, m, l, xl.
    2. Confirm fill colors match the *-visual-color tokens (and accent-content-color-default for informative) and bar thickness matches the size token.
  • Static color and side label.

    1. Render <swc-meter value="50" static-color="white" label-position="side">...</swc-meter> against a dark background.
    2. Confirm the bar, label, and value use the static-white-* tokens and the label sits inline with the bar.

Device review

  • Did it pass in Desktop?
  • Did it pass in (emulated) Mobile?
  • Did it pass in (emulated) iPad?

Accessibility testing checklist

  • Keyboard (required — document steps below)

    1. Tab through a page containing <swc-meter> instances at varying values.
    2. Expect Tab focus to skip the meter; no focus ring should appear on the host or any shadow descendant.
    3. Confirm no focus traps and no surprising focus stops on adjacent components.
  • Screen reader (required — document steps below)

    1. Open a story with <swc-meter value="40" variant="positive"><span slot="label">Storage used</span><span slot="description">2 GB of 5 GB used</span></swc-meter> in NVDA / JAWS / VoiceOver.
    2. Switch to browse mode (NVDA / JAWS) or VO arrow navigation.
    3. Encounter the meter and confirm the announcement includes: name from the label slot, role of "meter" (or platform equivalent), the value text (40% in en-US, Arabic-Indic digits + ٪ in ar-sa), and the description text.
    4. Replace the label slot with accessible-label="Storage usage" and confirm the announcement now uses that name instead, with aria-labelledby no longer referenced.

🤖 Generated with Claude Code

Implements SWC-2008, SWC-2009, SWC-2010, and SWC-2011 against the meter
migration plan, targeting the long-lived `meter-migration` integration
branch.

- SWC-2008 (Setup): core/swc file structure, package.json exports,
  shared/linear-progress-base.css stub.
- SWC-2009 (API): LinearProgressMixin holds value clamping, fill-fraction,
  Intl.NumberFormat locale formatting via LanguageResolutionController,
  label/description slot tracking, and DEBUG-mode accessible-name warning.
  MeterBase adds variant + DEBUG variant validation.
- SWC-2010 (A11y): role="meter" on shadow `.swc-Meter` (host carries no
  ARIA); aria-valuemin/max/now/text on role element; label slot ->
  aria-labelledby with accessibleLabel fallback -> aria-label; description
  slot -> aria-describedby; non-focusable.
- SWC-2011 (Styling): ports spectrum-css spectrum-two progressbar + meter
  to swc-Meter namespace, replaces --mod-* with --swc-meter-* tokens,
  covers variants, sizes, side-label, static white/black, forced-colors.
  Stylelint clean; ESLint clean; Prettier clean; build green.

Known deferrals:
- Shared CSS inlined in meter.css; lift-out to
  swc/shared/linear-progress-base.css happens when <swc-progress-bar>
  migrates (vite postcss pipeline lacks postcss-import; no other 2nd-gen
  component uses @import).
- Description container always emitted with `is-empty` class so the
  <slot> stays mounted for reliable slotchange (full conditional render
  loses slotchange across content-add transitions).
- Stories and tests scaffolded under SWC-2013 / SWC-2014.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@blunteshwar blunteshwar requested a review from a team as a code owner May 18, 2026 14:36
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 18, 2026

⚠️ No Changeset found

Latest commit: d1f4d0f

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

@blunteshwar blunteshwar added the Status:WIP PR is a work in progress or draft label May 18, 2026
@github-actions
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-6316

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Status:WIP PR is a work in progress or draft

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant