3.5 KiB
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
InputGroupcompanion pattern with prefix and suffix slots - keep the existing
InputAPI 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
- add a public
- Out of scope:
- redesigning
Fieldor introducing a second label/help-text abstraction - broad visual restyling of all text-entry surfaces
- migrating every existing search field in one pass
- redesigning
Constraints
- Preserve the existing
Inputref and prop contract for non-grouped usage. - Follow the current
Fieldstate inheritance rules for disabled, invalid, readonly, and required behavior. - Expose stable
data-slothooks 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.mdpackages/ui/src/lib/contracts.tspackages/ui/src/components/input.tsxpackages/ui/src/components/input-group.tsxpackages/ui/src/components/input-group.variants.tspackages/ui/src/components/input-group.test.tsxpackages/ui/src/components/data-table.tsxpackages/ui/src/components/command.tsxpackages/ui/src/components/command.test.tsxpackages/ui/src/index.tsapps/docs/src/components/input-group.stories.tsxapps/docs/src/revenue-dashboard.stories.tsxregistry/index.json
Plan
- Add the execution plan and define the new input-affix pattern against the existing
Input/Fieldcontract. - Implement
InputGroupplus grouped-input behavior without regressing standaloneInput. - Migrate the most obvious repeated search wrapper surfaces to the new composition layer.
- 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.tsxpnpm --filter @ai-ui/ui typecheckpnpm harness:validate:docspnpm registry:build
Orchestration Task Sketch
T1: implement the input group component and integrate standalone input behaviorT2 -> T1: migrate docs usage and command/data-table composition to the new slotsT3 -> T1: add tests, stories, and registry updates
Status Log
2026-03-25 14:29Read the system-of-record files and confirmed the currentInputcontract has no affix composition layer.2026-03-25 14:35Chose a siblingInputGrouppattern over mutatingInputinto a wrapped root so the existing input API stays stable outside grouped usage.2026-03-25 15:17ImplementedInputGroup, grouped input behavior, and the first consumer migrations inCommandInput,DataTableSearch, and the revenue dashboard story.2026-03-25 15:24Verifiedpnpm --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, andpnpm registry:build.