Files
cadence-ui/docs/exec-plans/2026-03-25-input-group-affixes.md
T

3.5 KiB

Input Group Affixes

  • Status: completed
  • Owner: codex
  • Date: 2026-03-25

Goal

Add a reusable input-affix composition layer so search icons, badges, and suffix actions stop being page-level absolute-position wrappers and instead ship as a stable Cadence UI pattern.

Scope

  • In scope:
    • add a public InputGroup companion pattern with prefix and suffix slots
    • keep the existing Input API intact while letting it compose cleanly inside the new group
    • update at least one real docs surface that currently hand-rolls affix layout
    • add Storybook coverage and unit tests for the new slot and field wiring behavior
  • Out of scope:
    • redesigning Field or introducing a second label/help-text abstraction
    • broad visual restyling of all text-entry surfaces
    • migrating every existing search field in one pass

Constraints

  • Preserve the existing Input ref and prop contract for non-grouped usage.
  • Follow the current Field state inheritance rules for disabled, invalid, readonly, and required behavior.
  • Expose stable data-slot hooks for the new affix anatomy.
  • Keep the new pattern token-driven and visually aligned with the current input chrome.

Affected Surfaces

  • docs/exec-plans/2026-03-25-input-group-affixes.md
  • packages/ui/src/lib/contracts.ts
  • packages/ui/src/components/input.tsx
  • packages/ui/src/components/input-group.tsx
  • packages/ui/src/components/input-group.variants.ts
  • packages/ui/src/components/input-group.test.tsx
  • packages/ui/src/components/data-table.tsx
  • packages/ui/src/components/command.tsx
  • packages/ui/src/components/command.test.tsx
  • packages/ui/src/index.ts
  • apps/docs/src/components/input-group.stories.tsx
  • apps/docs/src/revenue-dashboard.stories.tsx
  • registry/index.json

Plan

  1. Add the execution plan and define the new input-affix pattern against the existing Input/Field contract.
  2. Implement InputGroup plus grouped-input behavior without regressing standalone Input.
  3. Migrate the most obvious repeated search wrapper surfaces to the new composition layer.
  4. Add stories, tests, and registry updates, then run the narrowest useful validation passes.

Validation

  • pnpm --filter @ai-ui/ui test -- --run packages/ui/src/components/input-group.test.tsx packages/ui/src/components/input.test.tsx packages/ui/src/components/command.test.tsx
  • pnpm --filter @ai-ui/ui typecheck
  • pnpm harness:validate:docs
  • pnpm registry:build

Orchestration Task Sketch

  • T1: implement the input group component and integrate standalone input behavior
  • T2 -> T1: migrate docs usage and command/data-table composition to the new slots
  • T3 -> T1: add tests, stories, and registry updates

Status Log

  • 2026-03-25 14:29 Read the system-of-record files and confirmed the current Input contract has no affix composition layer.
  • 2026-03-25 14:35 Chose a sibling InputGroup pattern over mutating Input into a wrapped root so the existing input API stays stable outside grouped usage.
  • 2026-03-25 15:17 Implemented InputGroup, grouped input behavior, and the first consumer migrations in CommandInput, DataTableSearch, and the revenue dashboard story.
  • 2026-03-25 15:24 Verified pnpm --filter @ai-ui/ui test -- --run packages/ui/src/components/input-group.test.tsx packages/ui/src/components/input.test.tsx packages/ui/src/components/command.test.tsx packages/ui/src/components/data-table.test.tsx, pnpm --filter @ai-ui/ui typecheck, pnpm harness:validate:docs, and pnpm registry:build.