Skip to content

chore: Add inline label to control group - #5110

Open
jperals wants to merge 22 commits into
mainfrom
dev-v3-jotresse-control-group-label
Open

jperals wants to merge 22 commits into
mainfrom
dev-v3-jotresse-control-group-label

Conversation

@jperals

@jperals jperals commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

Description

Related doc: kMUBQtg6r1WV

How has this been tested?

Added dev page. Visual regression tests for this page will be added separately.

Review checklist

The following items are to be evaluated by the author(s) and the reviewer(s).

Correctness

  • Changes include appropriate documentation updates.
  • Changes are backward-compatible if not indicated, see CONTRIBUTING.md.
  • Changes do not include unsupported browser features, see CONTRIBUTING.md.
  • Changes were manually tested for accessibility, see accessibility guidelines.

Security

Testing

  • Changes are covered with new/existing unit tests?
  • Changes are covered with new/existing integration tests?

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

jperals added 13 commits October 6, 2026 17:26
Extract the shared noop handler, operator/multiselect option lists, and
enteredTextLabel into pages/control-group/common.tsx and import them from
both the permutations and labels dev pages.

Restore the permutations page to match main aside from the dedup: drop the
inline label permutations (covered by the dedicated labels page) and the
expandToViewport additions.
Give the grouped Select and Multiselect stable data-testid hooks so visual
regression tests can target them unambiguously; both grouped and standalone
controls share aria-labels, so aria-label alone cannot disambiguate them.
Add two grouped controls below the grouped select and multiselect: one led
by an Autosuggest and one led by an Input. These cover the inline label +
focus ring interaction for Autosuggest and Input as the leading control. Both
leading controls get data-testid hooks for later visual tests.
…page

Replace the h2 section headings with a page-level description, add the shared
FocusTarget so keyboard tests can tab into the controls, and extract the
permutations page's direction settings into common.tsx (useControlGroupDirection
hook + DirectionSettings) so the labels page can also render vertically.
A ControlGroup with an inline label that leads with a Multiselect
overlapped the Multiselect's inline token row. The group's single label
pulls in the shared `inline-label` mixin's `padding-block-end: 2px`,
tuned for a normal text trigger, but a grouped Multiselect always renders
inline tokens whose row sits higher, so the label hung too low.

Mirror the proven Multiselect customization at the control-group layer:
add an `inline-label-inline-tokens` modifier (padding-block-end: 0 and
translateY(-1.5px), copied verbatim from src/select/parts/styles.scss) and
apply it from index.tsx only when a child resolves to a Multiselect
(detected by displayName). Plain-trigger groups keep the base offset and
are visually unchanged. The shared forms mixin is untouched.

Verification (from worktree root):
- npm run lint:stylelint -> exit 0
- npm run quick-build -> exit 0 (TypeScript + SCSS clean; recompiles lib)
- eslint on index.tsx + test -> exit 0 (import sort autofixed)
- jest control-group.test.tsx -> both new assertions pass (clearance class
  applied with a Multiselect child, absent with plain children). Two
  pre-existing getByRole('group') ambiguity failures are unrelated to this
  change (confirmed identical on HEAD) and left as-is.

Visual check: on the control-group labels dev page the Threshold group's
label no longer overlaps the Multiselect inline token, in both horizontal
and vertical direction; other grouped labels and the standalone Labels
Multiselect are unchanged.
@@ -0,0 +1,57 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Parts extracted from pages/control-group/permutations.page.tsx for reuse


// Specific Styling for Inline Label Text to not overlap with Inline Tokens
.inline-label-inline-tokens {
padding-block-end: 0;

@jperals jperals Oct 6, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This part is used by multiselect with inline tokens. Here it was extracted for reuse, since a control group can contain a multiselect with inline tokens, so the inline label has to be slightly shifted upwards as well to prevent it from overlapping the tokens.

@jperals
jperals marked this pull request as ready for review October 6, 2026 16:32
@jperals
jperals requested a review from a team as a code owner October 6, 2026 16:32
@jperals
jperals requested review from amanabiy and removed request for a team October 6, 2026 16:32
A control group's inline label must paint above a focused control's focus
ring but below that control's open dropdown. The ring and an inline dropdown
share the control slot's stacking context, so no slot z-index satisfies both.

Instead, Select, Multiselect, and Autosuggest now portal the dropdown when
grouped (effective expandToViewport = prop || isGrouped), so it escapes the
slot's isolation and paints over the group label while the focus ring stays
under it. This mirrors Multiselect forcing inline tokens when grouped. The
effective value also feeds getDropdownMinWidth so the portaled grouped
dropdown keeps the right min-width. The public expandToViewport prop, its
defaults, and the Dropdown component are unchanged; standalone controls are
unaffected. The labels dev page no longer needs expandToViewport.
Add a test to the Select, Multiselect, and Autosuggest control-group suites
asserting that a grouped control portals its dropdown even when
expandToViewport is not set (found with expandToViewport, absent inline).
@codecov

codecov Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.70%. Comparing base (66cba18) to head (014ffb8).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #5110   +/-   ##
=======================================
  Coverage   97.70%   97.70%           
=======================================
  Files         990      991    +1     
  Lines       31818    31832   +14     
  Branches    11753    11756    +3     
=======================================
+ Hits        31089    31103   +14     
- Misses        683      722   +39     
+ Partials       46        7   -39     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Wrap the labels dev page in the default I18nProvider via SimplePage i18n={{}}
so the Autosuggest clear button gets its default aria-label instead of
rendering unlabeled.
Add a minimal internal ControlGroupWrapper under test-utils/dom/internal with
a findInlineLabel method, and use it in the control group unit tests to locate
the inline label instead of querying by text.

import styles from '../../../internal/components/control-group/styles.selectors.js';

export default class ControlGroupWrapper extends ComponentWrapper {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

First iteration of the test utils including only findInlineLabel. The rest of methods will be included along with their corresponding features, and this file will be moved outside of internal when the control group is released.

This branch was successfully deployed

3 active deployments
dev-pages-react16 — 014ffb80 Deployed Oct 7, 2026 by jperals via deploy (React 16) / deploy #2592
dev-pages-react18 — 014ffb80 Deployed Oct 7, 2026 by jperals via deploy (React 18) / deploy #2592
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