Skip to content

Add new InputGroup compound component with Addon, Suffix, and Button support#249

Open
pedromenezes1 wants to merge 7 commits intocloudflare:mainfrom
pedromenezes1:feat/input-group-addon
Open

Add new InputGroup compound component with Addon, Suffix, and Button support#249
pedromenezes1 wants to merge 7 commits intocloudflare:mainfrom
pedromenezes1:feat/input-group-addon

Conversation

@pedromenezes1
Copy link
Contributor

@pedromenezes1 pedromenezes1 commented Mar 18, 2026

New InputGroup compound component for building inputs with icons, addons, inline suffixes, and action buttons.

Includes comprehensive documentation page with demos and unit tests.

Features

  • Field Integration — InputGroup accepts label, description, error, required, and labelTooltip props directly; automatically wraps in Field when label is provided
  • Addons — Place icons or text before/after the input using align="start" or align="end"
  • Compact Button — Small button inside an Addon for secondary actions (copy, clear, toggle visibility)
  • Action Button — Full-height flush button as a direct child for primary actions (submit, search)
  • Inline Suffix — Text that flows seamlessly next to the typed value (e.g., .workers.dev); input width adjusts automatically as user types
  • Size Variants — xs, sm, base, lg sizes cascade to all children via context
  • Error State — Error flows through context; InputGroup.Input auto-sets aria-invalid="true" when error is present
  • Disabled State — disabled prop disables all interactive children

Sub-components

Component Description
InputGroup Root container; provides context and accepts Field props
InputGroup.Input Styled input; inherits size, disabled, error from context
InputGroup.Addon Container for icons, text, or compact buttons; align="start" (default) or align="end"
InputGroup.Button Full-height button (direct child) or compact button (inside Addon)
InputGroup.Suffix Inline text suffix with automatic width measurement

Usage Examples

// With Field props (label, description, error, tooltip)
<InputGroup
  label="Email"
  description="We'll never share your email"
  error={{ message: "Invalid email", match: "typeMismatch" }}
  labelTooltip="Used for account recovery"
>
  <InputGroup.Input type="email" />
  <InputGroup.Addon align="end">@example.com</InputGroup.Addon>
</InputGroup>

// Inline suffix with auto-measuring width
<InputGroup>
  <InputGroup.Input placeholder="my-worker" />
  <InputGroup.Suffix>.workers.dev</InputGroup.Suffix>
</InputGroup>

// Search with icon addon and action button
<InputGroup>
  <InputGroup.Addon><MagnifyingGlassIcon /></InputGroup.Addon>
  <InputGroup.Input placeholder="Search..." />
  <InputGroup.Button variant="primary">Search</InputGroup.Button>
</InputGroup>

// Password with compact toggle button inside addon
<InputGroup label="Password">
  <InputGroup.Input type={show ? "text" : "password"} />
  <InputGroup.Addon align="end">
    <InputGroup.Button variant="ghost" size="sm" onClick={toggle}>
      {show ? <EyeSlashIcon /> : <EyeIcon />}
    </InputGroup.Button>
  </InputGroup.Addon>
</InputGroup>

Caveats

  • InputGroup.Input omits label, description, error, size, and labelTooltip props — these are handled by the parent InputGroup
  • When using InputGroup.Suffix, the input width is measured dynamically via a hidden ghost element
  • InputGroup.Button renders differently based on placement: full-height flush when direct child, compact when inside Addon

Screenshots

Screenshot 2026-03-18 at 14 13 05 Screenshot 2026-03-18 at 14 13 10 Screenshot 2026-03-18 at 14 13 13
Screenshot 2026-03-18 at 14 13 15 Screenshot 2026-03-18 at 14 13 18 Screenshot 2026-03-18 at 14 13 21
Screenshot 2026-03-18 at 14 13 25
Screenshot 2026-03-18 at 14 13 39 Screenshot 2026-03-18 at 14 13 42 Screenshot 2026-03-18 at 14 13 46
Screenshot 2026-03-18 at 14 13 50 Screenshot 2026-03-18 at 14 13 53 Screenshot 2026-03-18 at 14 13 59
Screenshot 2026-03-18 at 14 14 02

@pedromenezes1 pedromenezes1 force-pushed the feat/input-group-addon branch from b348d28 to 86e9d5d Compare March 18, 2026 01:38
@pedromenezes1 pedromenezes1 changed the title fix(InputGroup): flush button properly covers container ring border feat(InputGroup): revamp component with new compound API Mar 18, 2026
@pedromenezes1 pedromenezes1 changed the title feat(InputGroup): revamp component with new compound API feat: new InputGroup compound component with Addon, Suffix, and Button support Mar 18, 2026
@pedromenezes1 pedromenezes1 changed the title feat: new InputGroup compound component with Addon, Suffix, and Button support Add new InputGroup compound component with Addon, Suffix, and Button support Mar 18, 2026
@pedromenezes1 pedromenezes1 force-pushed the feat/input-group-addon branch 17 times, most recently from 1f88e51 to ca11f35 Compare March 18, 2026 14:10
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 18, 2026

npm i https://pkg.pr.new/@cloudflare/kumo@249

commit: d8a5c08

…on support

New InputGroup compound component for building inputs with icons, addons, inline suffixes, and action buttons.

Features:
- Field Integration — Accepts label, description, error, required, and labelTooltip props
- Addons — Place icons or text before/after the input using align="start" or align="end"
- Compact Button — Small button inside an Addon for secondary actions
- Action Button — Full-height flush button as a direct child for primary actions
- Inline Suffix — Text that flows seamlessly next to the typed value
- Size Variants — xs, sm, base, lg sizes cascade to all children via context
- Error State — Error flows through context; InputGroup.Input auto-sets aria-invalid
- Disabled State — disabled prop disables all interactive children

Sub-components:
- InputGroup — Root container; provides context and accepts Field props
- InputGroup.Input — Styled input; inherits size, disabled, error from context
- InputGroup.Addon — Container for icons, text, or compact buttons
- InputGroup.Button — Full-height button (direct child) or compact button (inside Addon)
- InputGroup.Suffix — Inline text suffix with automatic width measurement

Includes comprehensive documentation page with demos and unit tests.
@pedromenezes1 pedromenezes1 force-pushed the feat/input-group-addon branch from ca11f35 to 5c4d6f2 Compare March 18, 2026 14:12
@github-actions
Copy link
Contributor

github-actions bot commented Mar 18, 2026

Docs Preview

View docs preview

Commit: d8a5c08

@github-actions
Copy link
Contributor

github-actions bot commented Mar 18, 2026

Visual Regression Report

23 screenshot(s) with visual changes:

Button / Variants

1 px (0%) changed

Before After Diff
Before After Diff

Button / Sizes

52,939 px (1.81%) changed

Before After Diff
Before After Diff

Button / With Icon

40,226 px (1.38%) changed

Before After Diff
Before After Diff

Button / Icon Only

4 px (0%) changed

Before After Diff
Before After Diff

Button / Loading State

58,790 px (2.01%) changed

Before After Diff
Before After Diff

Button / Disabled State

64,597 px (2.21%) changed

Before After Diff
Before After Diff

Dialog / Basic Dialog

127,440 px (2.3%) changed

Before After Diff
Before After Diff

Dialog / Alert Dialog (role=“alertdialog”)

125,071 px (2.26%) changed

Before After Diff
Before After Diff

Dialog / Confirmation Dialog (with disablePointerDismissal)

20,300 px (0.37%) changed

Before After Diff
Before After Diff

Dialog / With Actions

146,027 px (2.64%) changed

Before After Diff
Before After Diff

Dialog / With Select

136,436 px (2.46%) changed

Before After Diff
Before After Diff

Dialog / With Combobox

137,423 px (2.48%) changed

Before After Diff
Before After Diff

Dialog / With Dropdown

4,137 px (0.07%) changed

Before After Diff
Before After Diff

Select / Without Visible Label

9,532 px (1.69%) changed

Before After Diff
Before After Diff

Select / With Description and Error

13,041 px (1.86%) changed

Before After Diff
Before After Diff

Select / Placeholder

1,428 px (0.22%) changed

Before After Diff
Before After Diff

Select / Label with Tooltip

12,894 px (1.83%) changed

Before After Diff
Before After Diff

Select / Loading

12,828 px (1.81%) changed

Before After Diff
Before After Diff

Select / Multiple Item

19,371 px (2.3%) changed

Before After Diff
Before After Diff

Select / More Example

23,445 px (2.57%) changed

Before After Diff
Before After Diff

Select / Select

705 px (0.08%) changed

Before After Diff
Before After Diff

Select / Select.Option

23,306 px (2.72%) changed

Before After Diff
Before After Diff

Select (Open)

0 px (0%) changed

Before After Diff
Before After Diff
3 screenshot(s) unchanged
  • Dialog (Open)
  • Select / Basic Usage
  • Select / Custom Rendering

Generated by Kumo Visual Regression

…on support

New InputGroup compound component for building inputs with icons, addons, inline suffixes, and action buttons.

Features:
- Field Integration — Accepts label, description, error, required, and labelTooltip props
- Addons — Place icons or text before/after the input using align="start" or align="end"
- Compact Button — Small button inside an Addon for secondary actions
- Action Button — Full-height flush button as a direct child for primary actions
- Inline Suffix — Text that flows seamlessly next to the typed value (uses CSS field-sizing)
- Size Variants — xs, sm, base, lg sizes cascade to all children via context
- Error State — Error flows through context; InputGroup.Input auto-sets aria-invalid
- Disabled State — disabled prop disables all interactive children

Sub-components:
- InputGroup — Root container; provides context and accepts Field props
- InputGroup.Input — Styled input; inherits size, disabled, error from context
- InputGroup.Addon — Container for icons, text, or compact buttons
- InputGroup.Button — Full-height button (direct child) or compact button (inside Addon)
- InputGroup.Suffix — Inline text suffix with CSS-based automatic width sizing

Includes comprehensive documentation page with demos and unit tests.
@mattrothenberg mattrothenberg force-pushed the feat/input-group-addon branch from 0caf233 to 5bbecc8 Compare March 18, 2026 14:40
- Suppress outline on inner input with outline-none!
- Add has-[:focus-visible]:outline-auto to container in grouped mode
- When inner input receives keyboard focus, the native focus ring appears on the entire InputGroup container
- Uses browser's native -webkit-focus-ring-color for consistent appearance
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.

2 participants