Skip to content

docs(meter): 2nd-gen migration plan#6215

Open
blunteshwar wants to merge 3 commits into
meter-migrationfrom
pvashish/docs-meter-migration-plan-swc-2007
Open

docs(meter): 2nd-gen migration plan#6215
blunteshwar wants to merge 3 commits into
meter-migrationfrom
pvashish/docs-meter-migration-plan-swc-2007

Conversation

@blunteshwar
Copy link
Copy Markdown
Contributor

Description

Adds the Phase 1 (Preparation) migration plan for the <sp-meter><swc-meter> 2nd-gen migration at CONTRIBUTOR-DOCS/03_project-planning/03_components/meter/migration-plan.md. This is a planning deliverable only — no code, CSS, or component changes are included. The components README TOC is regenerated by the contributor-docs nav script.

The plan codifies the public API, breaking changes, additive items, architecture (core vs SWC split), migration sequencing, and per-phase checklists for the remaining tickets in the Meter migration epic.

Key decisions documented:

  • Align <swc-meter> with the React Spectrum S2 Meter API and the supplied Figma S2 / Web (Desktop scale) Meter frame.
  • Rename progressvalue; add minValue/maxValue (defaults 0/100); replace side-label boolean with label-position enum ('top' default, 'side'); expose value-label and format-options; normalize the variant set to {informative (default), positive, notice, negative}.
  • Migrate as an independent component — no shared base with <swc-progress-bar> or <swc-progress-circle>. Bar/track/fill styles are inlined in meter.css from spectrum-css spectrum-two (progressbar/index.css + meter/index.css).
  • Render plain <label class="spectrum-FieldLabel ..."> matching spectrum-css spectrum-two HTML output until <swc-field-label> is migrated.
  • Fix the invalid combined role="meter progressbar" to a single role="meter"; add missing aria-valuemin, aria-valuemax, and aria-valuetext.
  • Ship static-color="black" and a help-text slot as net-new from S2.

Motivation and context

This is the first deliverable in the Meter migration epic. The plan is the shared baseline that every later phase (SWC-2008 setup → SWC-2016 review) consumes for naming, public API, behavioral semantics, and architecture decisions, per .claude/skills/migration-prep/references/migration-plan-contract.md. Aligning with React Spectrum and Figma now avoids a second, more disruptive migration later, and resolves the 1st-gen ARIA bug (combined role string + missing value attributes) before consumers depend on the 2nd-gen API.

Related issue(s)

  • SWC-2007 (Meter migration planning, child of epic SWC-2005)

Screenshots (if appropriate)

N/A — planning document only; no rendered UI changes.

Author's checklist

  • I have read the CONTRIBUTING and PULL_REQUESTS documents.
  • I have reviewed at the Accessibility Practices for this feature, see: Aria Practices — the plan addresses the WAI-ARIA meter pattern explicitly.
  • I have added automated tests to cover my changes. (N/A — planning document only; tests ship in SWC-2013.)
  • I have included a well-written changeset if my change needs to be published. (N/A — internal contributor docs; no published package change.)
  • I have included updated documentation if my change required it.

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

  • Plan content review

    1. Open CONTRIBUTOR-DOCS/03_project-planning/03_components/meter/migration-plan.md on the PR branch.
    2. Read the TL;DR, Changes overview, 2nd-gen API decisions, and Architecture: core vs SWC split sections.
    3. Confirm the API matches the React Spectrum S2 Meter reference and the Figma S2 / Web (Desktop scale) Meter frame supplied during planning. Flag any divergence.
  • Architecture call

    1. Review the Migration sequencing and prerequisites and Architecture: core vs SWC split sections.
    2. Confirm the independent-component decision (no shared ProgressBase) is acceptable given the upcoming <swc-progress-bar> migration on a separate epic.
    3. Flag any objection before SWC-2008 (Setup) starts.
  • Doc structure and links

    1. Open the file on GitHub in rendered mode.
    2. Click each anchor in the Table of Contents and confirm it scrolls to the matching heading.
    3. Spot-check the relative links to accessibility-migration-analysis.md, rendering-and-styling-migration-analysis.md, 1st-gen/packages/meter/src/Meter.ts, and the CSS style guide pages.
    4. Confirm node update-nav.js (run from CONTRIBUTOR-DOCS/01_contributor-guides/07_authoring-contributor-docs/) reports no new broken links introduced by this PR.

Device review

  • Did it pass in Desktop? (N/A — planning document only; no rendered UI.)
  • Did it pass in (emulated) Mobile? (N/A — planning document only; no rendered UI.)
  • Did it pass in (emulated) iPad? (N/A — planning document only; no rendered UI.)

Accessibility testing checklist

This PR ships a planning document, not a rendered component. The full accessibility testing checklist applies to SWC-2010 (Implement accessibility features) and SWC-2013 (Review and complete test suites). Steps below verify that the plan itself is reviewable with assistive technology and that the documented ARIA recommendations are coherent.

  • Keyboard — no focusable component is added by this PR; verify the rendered markdown is navigable.

    1. Open the PR's Files changed view on GitHub and locate migration-plan.md.
    2. Press Tab through the doc body. Confirm the only focusable elements are anchor links and that focus order follows reading order.
    3. Press Enter on a TOC anchor (e.g. 2nd-gen API decisions); expect focus to move to the corresponding heading.
    4. Confirm no focus traps and no keyboard interactions are introduced anywhere in the repo by this PR (it touches docs only).
  • Screen reader — verify the documented ARIA contract reads cleanly and the rendered doc structure is correct.

    1. With VoiceOver (macOS) or NVDA (Windows) active, open the rendered migration-plan.md on GitHub.
    2. Use the screen reader's heading-navigation shortcut (VO+Cmd+H on VoiceOver; H on NVDA) to traverse h1h2h3h4. Expect a logical hierarchy with no skipped levels.
    3. Verify each table is announced as a table with the documented column headers (Property, Type, Default, Attribute, Notes).
    4. Read the 2nd-gen API decisions → Accessibility semantics notes section. Confirm the documented role="meter", aria-valuemin/aria-valuemax/aria-valuenow/aria-valuetext, and aria-describedby wiring matches the WAI-ARIA 1.2 meter spec and the APG meter pattern.
    5. Confirm the documented dev-mode missing-name warning aligns with the precedent in ProgressCircleBase.updated.

- align meter API with React Spectrum S2 (`progress` -> `value`, add
`minValue`/`maxValue`, replace `side-label` with `label-position` enum,
expose `value-label` and `format-options`)
- normalize variant set to `{informative, positive, notice, negative}`
per Figma `S2 / Web (Desktop scale)` Meter frame
- migrate as an independent component; bar/track/fill styles live in
`meter.css` (no shared base with progress-bar / progress-circle)
- render plain `<label class="spectrum-FieldLabel ...">` matching
`spectrum-css` `spectrum-two` HTML output until `<swc-field-label>`
is migrated
- fix 1st-gen `role="meter progressbar"` to single `role="meter"`;
add missing `aria-valuemin`/`aria-valuemax`/`aria-valuetext`
- ship `static-color="black"` and a `help-text` slot net-new from S2

SWC-2007 (epic SWC-2005)

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

changeset-bot Bot commented Apr 28, 2026

⚠️ No Changeset found

Latest commit: 27f1d47

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
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 28, 2026

📚 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-6215

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.

@blunteshwar blunteshwar added the Status:Ready for review PR ready for review or re-review. label Apr 28, 2026
Copy link
Copy Markdown
Contributor

@5t3ph 5t3ph left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if you need clarification on any of these!

The most impactful is to re-consider having a shared base between meter and progress bar.


- 1st-gen `<sp-meter>` extended progress-bar visuals via CSS `@import` of `spectrum-progress-bar.css` and `progress-bar-overrides.css`. In 2nd-gen, this is replaced with a self-contained `meter.css` that copies the relevant bar/track/fill rules from `spectrum-css` `spectrum-two` ([`components/progressbar/index.css`](https://github.com/adobe/spectrum-css/blob/spectrum-two/components/progressbar/index.css)) plus the meter-specific rules from [`components/meter/index.css`](https://github.com/adobe/spectrum-css/blob/spectrum-two/components/meter/index.css).
- The 1st-gen progress-bar package is not migrated yet; making meter wait on or share with it would couple two epics unnecessarily and slow SWC-2005.
- The components have different ARIA semantics (`role="meter"` vs `role="progressbar"`), different default behaviors (meter is determinate-only; progress-bar can be indeterminate), and different value semantics. A shared base would have to gate most of its API per subclass anyway.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would challenge this as a reason to not have a shared base in core. The ARIA role would be on the rendering layer and not shared in core anyway. Styles would be fine to remain separate, at least for now.

Many of the exposed consumer attributes are the same, and the ones that are different can be reserved and added via the rendering layer. This is how we are approaching Button as well, for reference (you could have your agent look at that migration plan for comparison).

The lingering issue may be deciding how to name it in core - maybe progress-meter?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be done as a mixin or controller?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pushing on reuse — we’re aligned that role and styling living in SWC don’t rule out pulling out small shared pieces later (localized formatting, normalized fill fraction, label-from-slot) via helpers, a mixin, or a controller if it stays cheap to maintain.

I'd still gently suggest treating meter and progress-bar as separate semantic cores, not one shared base type, mainly because the parity numbers don’t look like Button vs action-button:

Properties (1st gen): 5 of 8 line up on both (progress, label, side-label, static-color, size). 3 of 8 are only on one (variant on meter; indeterminate and over-background on progress-bar), so cross-component duplication is already partial.
Slots: Same default label slot/hoisting pattern (1/1) in gen 1 — good candidate for helpers, less so for inheritance.
Role / ARIA: Only naming via label → aria-label lines up cleanly; role, aria-valuemin/max, aria-valuetext, and aria-valuenow when indeterminate don’t align with meter’s shape today — that mismatch grows once meter picks up value/min/max and progress-bar locks its own gen‑2 API.
Templates: Visibility rules for the label chrome and the percent/value row differ materially; shared bar markup is mechanical, not a shared semantic contract like Button’s family.
Button/action-button deliberately share one interactive primitive and a roadmap of sibling components on the same semantic contract. Here we have different roles/use cases, uneven property overlap, and different timelines — so I'd suggest keeping MeterBase meter-scoped, and optional shared utilities once progress-bar’s gen‑2 design is settled, rather than coupling this epic on a hypothetical *-base. Happy to revise if we later see a firmer convergence on API and semantics.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In 1st gen they already don’t share a TypeScript base class — they’re separate components; only styling is shared

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any difference in the APIs?

Comment thread CONTRIBUTOR-DOCS/03_project-planning/03_components/meter/migration-plan.md Outdated
Comment thread CONTRIBUTOR-DOCS/03_project-planning/03_components/meter/migration-plan.md Outdated
Comment thread CONTRIBUTOR-DOCS/03_project-planning/03_components/meter/migration-plan.md Outdated

Sourced from [`accessibility-migration-analysis.md`](./accessibility-migration-analysis.md) and the React Spectrum S2 Meter API:

- `role="meter"` set in `firstUpdated` if not already set. Fixed; not author-overridable.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be simplified as it should be part of the render template permanently.

Copy link
Copy Markdown
Contributor

@nikkimk nikkimk Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be simplified as it should be part of the render template permanently.

@5t3ph If the role is on an element in the shadow DOM we will not be able to use IDREFs like aria-labelledby, although eventually we will have a corss-root ARIA solution.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going with role + aria-value* on host (not on the shadow .swc-Meter wrapper). This keeps consumer IDREFs (aria-labelledby, aria-describedby) working — light-DOM IDs can't resolve into shadow DOM today. Cross-root ARIA (Reference Target) is not yet shipped in stable browsers, so host placement is the only safe option right now.

- [ ] Static-color rules for both `staticWhite` and `staticBlack` modifiers
- [ ] `label-position="side"` layout rule (`.swc-Meter--sideLabel`) mirroring `spectrum-css` `spectrum-two` `.spectrum-ProgressBar--sideLabel`
- [ ] Help-text spacing rule (`--swc-meter-help-text-spacing`) and visibility gating when `slot="help-text"` is empty
- [ ] Hide the percent label cell when `static-color` is set (matches Figma `Static white` / `Static black` panels)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reminder not to do this, remove this item.


#### Naming and semantics

- [ ] Single `role="meter"` on host. No combined role string.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- [ ] Single `role="meter"` on host. No combined role string.
- [ ] Single `role="meter"` on `.swc-Meter` container. No combined role string.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disregard for now, pending aria discussion

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is valid again since you are taking aria off the host, per other comment discussion.

#### Naming and semantics

- [ ] Single `role="meter"` on host. No combined role string.
- [ ] `aria-valuemin=<minValue>`, `aria-valuemax=<maxValue>`, `aria-valuenow=<clamped value>`, `aria-valuetext=<formatted value>` on host
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- [ ] `aria-valuemin=<minValue>`, `aria-valuemax=<maxValue>`, `aria-valuenow=<clamped value>`, `aria-valuetext=<formatted value>` on host
- [ ] `aria-valuemin=<minValue>`, `aria-valuemax=<maxValue>`, `aria-valuenow=<clamped value>`, `aria-valuetext=<formatted value>` on `.swc-Meter` container

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disregard for now, pending aria discussion

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is valid again since you are taking aria off the host, per other comment discussion.


- [ ] Single `role="meter"` on host. No combined role string.
- [ ] `aria-valuemin=<minValue>`, `aria-valuemax=<maxValue>`, `aria-valuenow=<clamped value>`, `aria-valuetext=<formatted value>` on host
- [ ] Accessible name from `label`, default slot text, `aria-label`, or `aria-labelledby`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update pending @nikkimk feedback on earlier comment


All drafting-time questions are resolved. Resolutions:

- **Q1 (architecture)** — Closed. Independent `<swc-meter>` with no shared base. Bar styles live in `meter.css`. Reflected in [Architecture: core vs SWC split](#architecture-core-vs-swc-split) and [Migration sequencing and prerequisites](#migration-sequencing-and-prerequisites).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noting that the shared base idea should be re-opened, see earlier comment.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interested in this outcome too! My first impression is 2 bases with the shared mixin sounds like a reasonable approach.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would love to chat about this as I'm currently assigned to progress bar!

@blunteshwar blunteshwar requested review from 5t3ph and nikkimk April 30, 2026 11:06
- **Progress bar** ([`1st-gen/packages/progress-bar`](../../../../1st-gen/packages/progress-bar/)) — independent migration on its own epic. No coupling to this work.
- **Progress circle** ([`2nd-gen/packages/swc/components/progress-circle`](../../../../2nd-gen/packages/swc/components/progress-circle/)) — already migrated. Used as the structural precedent for `aria-value*` plumbing, slot-as-label hoisting, locale-aware formatting, and the dev-mode accessible-name warning. Not extended.
- **Field label** — internal render dependency; not migrated. 2nd-gen `<swc-meter>` renders plain `<label class="spectrum-FieldLabel ...">` matching `spectrum-css` `spectrum-two` HTML output. No dependency on `<swc-field-label>`.
- **Help text** — 1st-gen `<sp-help-text>` package is not migrated. The `help-text` slot in `<swc-meter>` accepts any DOM, so consumers can place 1st-gen `<sp-help-text>` or any composed help-text element until `<swc-help-text>` exists.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a string attribute instead? I'm not sure we need a slot here...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could see folks trying to add like a link, or an icon/tooltip. But, maybe we're comfortable with those being a reason they might have to extend the component.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On it

| ------------- | -------------------- | ----- |
| (default) | Visible meter label | **Confirmed.** Slot text hoists into `label` property via `slotchange` + `getLabelFromSlot`. Single naming path. |
| `value-label` | Custom value content | **Confirmed.** Optional. Renders inside the percent label region. Used for richer value displays (e.g. `<strong>1</strong> of 4`). When the slot is empty and `value-label` attribute is unset, the auto-formatted value is rendered. |
| `help-text` | Optional help text | **Confirmed.** Renders inside the meter's S2 `helptext` region (per `spectrum-css` `spectrum-two` HTML output). Consumers compose `<sp-help-text>` (1st-gen, until `<swc-help-text>` exists) or any DOM. Wire to `aria-describedby` if the slot is non-empty. |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above - I think we can simplify this with a property.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense

- [ ] `staticColor` set matches `spectrum-css` `spectrum-two` (`staticWhite`, `staticBlack`) and Figma `Static white` / `Static black` panels; React's `'auto'` is deferred (no S2 CSS support)
- [ ] `labelPosition` matches React Spectrum (`top` default, `side`); side-label coverage backed by `spectrum-css` `spectrum-two` `progressbar/index.css` `.spectrum-ProgressBar--sideLabel`
- [ ] `value-label` slot + attribute matches React Spectrum `valueLabel`
- [ ] `format-options` matches React Spectrum `formatOptions` (property only — no string serialization)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React forwards these options to Intl.NumberFormat. If we want this parity we probably shouldn’t try to flatten or remap everything the native API supports today (and may support in the future).
I think the cleanest option is to expose this as a JavaScript property only, I don't see a very scalable path trying to model it as attributes.

Also, we'll need to hook this up to our LanguageResolutionController (which now that I think about it, should actually be named LocaleResolutionController 😛

Copy link
Copy Markdown
Contributor

@5t3ph 5t3ph left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest making these updates, then asking the agent to run a consistency pass based on your staged changes before committing as I didn't mark every instance of where these changes impact the plan. You should see changes throughout the checklists as well.


- **Progress bar** ([`1st-gen/packages/progress-bar`](../../../../1st-gen/packages/progress-bar/)) — independent migration on its own epic. No coupling to this work.
- **Progress circle** ([`2nd-gen/packages/swc/components/progress-circle`](../../../../2nd-gen/packages/swc/components/progress-circle/)) — already migrated. Used as the structural precedent for `aria-value*` plumbing, slot-as-label hoisting, locale-aware formatting, and the dev-mode accessible-name warning. Not extended.
- **Field label** — internal render dependency; not migrated. 2nd-gen `<swc-meter>` renders plain `<label class="swc-Meter-label">` / `<label class="swc-Meter-value">` (SWC-namespaced selectors per the [contributor docs selector patterns](../../../../CONTRIBUTOR-DOCS/02_style-guide/01_css/01_component-css.md#selector-patterns)). No dependency on `<swc-field-label>`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just validated that use of role="meter" does not make it eligible to be attached to <label> - it would only work if we were going to use native meter.

Image

Since you will be creating the meter with aria attributes to support custom styling, it is semantically meaningless to use <label> and instead a span could be used given the plan is to use aria-labelledby to associate it to the meter.

- **Progress bar** ([`1st-gen/packages/progress-bar`](../../../../1st-gen/packages/progress-bar/)) — independent migration on its own epic. No coupling to this work.
- **Progress circle** ([`2nd-gen/packages/swc/components/progress-circle`](../../../../2nd-gen/packages/swc/components/progress-circle/)) — already migrated. Used as the structural precedent for `aria-value*` plumbing, slot-as-label hoisting, locale-aware formatting, and the dev-mode accessible-name warning. Not extended.
- **Field label** — internal render dependency; not migrated. 2nd-gen `<swc-meter>` renders plain `<label class="swc-Meter-label">` / `<label class="swc-Meter-value">` (SWC-namespaced selectors per the [contributor docs selector patterns](../../../../CONTRIBUTOR-DOCS/02_style-guide/01_css/01_component-css.md#selector-patterns)). No dependency on `<swc-field-label>`.
- **Help text** — exposed as a `help-text` string attribute on `<swc-meter>` (not a slot). Renders as plain text inside the internal `swc-Meter-helptext` region. Consumers needing rich/interactive help-text content compose externally and wire `aria-describedby` themselves.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the current plan to move ARIA internally, consumers will not be able to successfully use aria-describedby for external help text due to cross-root ARIA.

Comment on lines +300 to +302
- `role="meter"` set on the host in `firstUpdated`. Always set (no "if not already set" conditional). Fixed; not author-overridable.
- `aria-valuemin=<minValue>`, `aria-valuemax=<maxValue>`, `aria-valuenow=<value>` (clamped), `aria-valuetext=<formatted value>` set on host. Update on every relevant property change and on locale change.
- **Placement rationale.** `role` + `aria-value*` live on the host (not on the shadow `.swc-Meter` wrapper) so consumer-supplied IDREFs bind correctly. Cross-root ARIA (Reference Target / cross-root ARIA spec) is not yet shipped in stable browsers.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These need updated as well with the decision to move aria internal. Essentially, nothing will be set on the host after all.


| Slot | Content | Notes |
| ------------- | -------------------- | ----- |
| (default) | Primary visible meter label | **Confirmed.** Default slot is the **primary** visible label and primary a11y name source. Slot text hoists into `accessibleLabel` via `slotchange` + `getLabelFromSlot` only when `accessibleLabel` is unset. |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads to me as if you will be forcing the default slot text into aria-label which wouldn't be correct since it would be intended to be a visible label. Am I misinterpreting this?

Comment on lines +328 to +333
<label class="swc-Meter-label">
<slot @slotchange=...>{accessibleLabel}</slot>
</label>
<label class="swc-Meter-value">
{valueLabel ?? auto-formatted value}
</label>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explained in earlier comment, but these should be simple <span> elements

Comment on lines +337 to +339
<div class="swc-Meter-helptext" id="<internal-id>" hidden=${!helpText}>
{helpText}
</div>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than toggling the hidden attribute, you can conditionally prevent this entire block from showing if there isn't help text. True for the other labeling parts as well.

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

Labels

Status:Ready for review PR ready for review or re-review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants