Skip to content

feat: Input prefix suffix - #4755

Open
NathanZlion wants to merge 4 commits into
mainfrom
feat/input-prefix-suffix
Open

feat: Input prefix suffix#4755
NathanZlion wants to merge 4 commits into
mainfrom
feat/input-prefix-suffix

Conversation

@NathanZlion

Copy link
Copy Markdown
Member

Description

Related links, issue #, if available: n/a

How has this been tested?

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.

@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.63%. Comparing base (850a244) to head (d93293d).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4755   +/-   ##
=======================================
  Coverage   97.63%   97.63%           
=======================================
  Files         957      957           
  Lines       31097    31127   +30     
  Branches    11435    11455   +20     
=======================================
+ Hits        30361    30391   +30     
  Misses        689      689           
  Partials       47       47           

☔ 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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds first-class prefix/suffix “adornment” support to the Input component, including rendering, styling, test-utils accessors, documentation output, and a new demo page to showcase usage patterns.

Changes:

  • Introduces prefix and suffix props (ReactNode) on Input and wires them through to internal rendering.
  • Adds a new adorned layout wrapper and related SCSS for prefix/suffix cells + dividers.
  • Extends DOM test-utils and adds unit tests + snapshot updates for the new API surface.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/test-utils/dom/input/index.ts Adds findPrefix / findSuffix helpers for test-utils.
src/input/styles.scss Adds styling for adorned container, prefix/suffix cells, and divider; strips native input border when adorned.
src/input/internal.tsx Implements adorned rendering structure and applies input-adorned class when prefix/suffix present.
src/input/interfaces.ts Adds public prefix / suffix props to InputProps.
src/input/index.tsx Passes prefix / suffix through to internal input implementation.
src/input/tests/adornments.test.tsx New tests covering rendering, dividers, state modifiers, and basic a11y expectations.
src/tests/snapshot-tests/snapshots/test-utils-selectors.test.tsx.snap Updates selector snapshots to include new classes.
src/tests/snapshot-tests/snapshots/documenter.test.ts.snap Updates generated docs snapshots for new props and test-utils methods.
pages/input/adornments.page.tsx Adds a demo page with multiple adornment examples and state toggles.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/input/internal.tsx Outdated
Comment on lines +133 to +135
const hasPrefix = !!prefix;
const hasSuffix = !!suffix;
const hasAdornment = hasPrefix || hasSuffix;
Comment thread src/input/styles.scss Outdated
Comment on lines +228 to +236
// Wrapper owns the border, radius, background, and focus ring when a prefix or suffix is present.
.input-adorned-container {
display: flex;
align-items: stretch;
inline-size: 100%;
box-sizing: border-box;
background-color: awsui.$color-background-input-default;
border-block: awsui.$border-width-field solid awsui.$color-border-input-default;
border-inline: awsui.$border-width-field solid awsui.$color-border-input-default;
Comment thread src/input/styles.scss
Comment on lines +287 to +291
padding-block: styles.$control-padding-vertical;
padding-inline: styles.$control-padding-horizontal;
color: awsui.$color-text-form-secondary;
white-space: nowrap;
user-select: none;
Comment thread src/input/internal.tsx
Comment on lines +261 to +270
{hasAdornment ? (
// [prefix][divider][input][divider][suffix] — one flex bar owns the border and focus ring.
<div
className={clsx(
styles['input-adorned-container'],
invalid && styles['input-adorned-container-invalid'],
warning && !invalid && styles['input-adorned-container-warning'],
disabled && styles['input-adorned-container-disabled'],
readOnly && !disabled && styles['input-adorned-container-readonly']
)}
setInvalid: (v: boolean) => void;
warning: boolean;
setWarning: (v: boolean) => void;
compact: boolean;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Compact density is already in the top nav controls (and RTL should ideally be as well at some point)


// ─── Main page ────────────────────────────────────────────────────────────────

export default function AdornmentsPage() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For visual regression testing, a screenshot area will be needed.

My suggestion would be a separate permutations page, so that only the component to be tested is included in the screenshots and no other extraneous content which lead to unnecessary collateral diffs.

Comment thread src/input/internal.tsx
__rightIcon = __rightIcon ?? searchProps.__rightIcon;
__onRightIconClick = __onRightIconClick ?? searchProps.__onRightIconClick;

// Search inputs use built-in search and clear icons that would overlap adornments.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sounds like a good case for a dev warning?

Comment thread src/input/internal.tsx
Comment on lines +142 to +143
const hasPrefix = hasAdornmentContent(prefix);
const hasSuffix = hasAdornmentContent(suffix);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Non blocking: Could this be just

const hasPrefix = !!prefix;
const hasSuffix = !!suffix;

I think the only possible difference would arise if someone sets prefix={true} or suffix={true}, but I would not expect that?

Comment thread src/input/internal.tsx
content !== null && content !== undefined && typeof content !== 'boolean' && content !== '';
const hasPrefix = hasAdornmentContent(prefix);
const hasSuffix = hasAdornmentContent(suffix);
const hasAdornment = hasPrefix || hasSuffix;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I find "adornment" not very clear, although I won't block on this because I can't think of perfect alternatives.

I think I would even prefer hasPrefixOrSuffix. Alternatively hasAffix ("affix" includes prefix and suffix) though not a common term.

Comment thread src/input/internal.tsx
mainInput
);

const rightIcon = __rightIcon ? (

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Non-blocking because it doesn't technically break anything, but this terminology is not RTL-friendly and it is easy to name these elements like suffixIcon, and even clearer IMO.

Same with class names e.g, input-icon-suffix.

}

/**
* Returns the prefix adornment element, or null if no prefix is set.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Again I wouldn't call this blocking but an adornment is purely decorational while this is not necessarily the case since it has a functional purpose in helping the user understanding how the input value will be used etc.

Comment thread src/input/styles.scss
}
}

&.input-adorned-container-disabled {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For some reason now the height of an input with prefix or suffix jumps from 20px to 22px when disabled or readOnly.

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.

3 participants