You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Corrected 2026-08-20. This issue as originally written was wrong twice, and acting on it as written would have broken production. Both corrections are folded into the body below rather than appended as comments.
FormError is NOT dead — it is live.src/components/forms/ValidatedInput.tsx:6 imports it and renders it at :225. ValidatedInput is used by CaptainShipCrewWithNPC.tsx:606, which src/app/game/page.tsx mounts. Deleting FormError would break validation errors on /game. Only FormField is dead.
There are no 5-file siblings to remove.src/components/forms/ contains only FormError.tsx, FormField.tsx, ValidatedInput.tsx and index.ts — all three are recorded as intentionally bare in scripts/audit-components.js:64-66 (KNOWN_BARE_COMPONENTS). Deletion is cheaper than claimed; adoption is more expensive, since it would mean creating five files that do not exist.
Also: the help-text gate is at FormField.tsx:84, not :82.
The finding
src/components/forms/FormField.tsx (140 lines) has been in the tree since the initial commit and is rendered nowhere. The only references outside the file itself are its own barrel re-export (src/components/forms/index.ts:10-11), two script comments, and two unrelated FormFieldConfig types. It has no .stories.tsx, so it never appears in Storybook either.
Every form in the product hand-rolls its own markup instead — ContactForm, SignInForm, SignUpForm.
Why it matters
It is not merely unused, it is misleading. It looks like the project's form-field abstraction, so the natural move when adding a field is to reach for it. Two things make that a trap:
It renders a label with htmlFor={name} but leaves the input entirely to the caller, so the ARIA wiring its own docstring advertises is not actually guaranteed by using it.
The decision
Delete FormField.tsx (leaving FormError and ValidatedInput alone), or adopt it across ContactForm / SignInForm / SignUpForm after first fixing the && !error gate and giving it the five-file structure it currently lacks.
The evidence now leans to delete: #858 has already shipped the help-text pattern by hand in ContactForm, so adopting would mean rewriting working, tested markup onto a component that has never rendered.
Hand-rolling the ContactForm pattern into the auth forms for #857 effectively votes "delete" here. Either settle this first, or state the pre-commitment explicitly in #857's PR body. See also #547, of which this is a scoped subset.
The finding
src/components/forms/FormField.tsx(140 lines) has been in the tree since the initial commit and is rendered nowhere. The only references outside the file itself are its own barrel re-export (src/components/forms/index.ts:10-11), two script comments, and two unrelatedFormFieldConfigtypes. It has no.stories.tsx, so it never appears in Storybook either.Every form in the product hand-rolls its own markup instead —
ContactForm,SignInForm,SignUpForm.Why it matters
It is not merely unused, it is misleading. It looks like the project's form-field abstraction, so the natural move when adding a field is to reach for it. Two things make that a trap:
{helpText && !error}(FormField.tsx:84) — the hint disappears the moment an error appears, removing the constraint exactly when the user needs it. That is the opposite of what Contact form constraints are invisible until submit fails — add help text to subject and message #855 asked for, and feat(#855): tell people the length limits before Send fails, not after #858 deliberately hand-rolled the hints inContactFormrather than adopt this.htmlFor={name}but leaves the input entirely to the caller, so the ARIA wiring its own docstring advertises is not actually guaranteed by using it.The decision
Delete
FormField.tsx(leavingFormErrorandValidatedInputalone), or adopt it acrossContactForm/SignInForm/SignUpFormafter first fixing the&& !errorgate and giving it the five-file structure it currently lacks.The evidence now leans to delete: #858 has already shipped the help-text pattern by hand in
ContactForm, so adopting would mean rewriting working, tested markup onto a component that has never rendered.Blocks #857
Hand-rolling the
ContactFormpattern into the auth forms for #857 effectively votes "delete" here. Either settle this first, or state the pre-commitment explicitly in #857's PR body. See also #547, of which this is a scoped subset.