tui: detect array-of-enum on items.enum alone#1752
Conversation
The TUI schemaToForm array-of-enum branch was nested under an outer
`if (property.enum)` guard, so a standard array-of-enums schema —
`{ type: "array", items: { enum: [...] } }` with no top-level `enum` — never
reached it and fell through to a plain string input. The web SchemaForm already
guards on `items?.enum` alone; this aligns the TUI with it.
Restructure the enum handling so the array-of-enums case keys on
`property.type === "array" && property.items?.enum` independently of a top-level
`enum`, falling back to the single-select `property.enum` branch otherwise. The
enumNames labeling from #1691 applies unchanged.
Tests: the array-of-enum cases now use the standard `items.enum`-only shape
(dropping the redundant top-level `enum` the old nesting required), plus a case
asserting a redundant top-level `enum` still works.
Closes #1751
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5
|
@claude review |
|
Claude finished @cliffhall's task in 34s —— View job Review — tui: detect array-of-enum on items.enum alone
Verdict: LGTM. The restructuring is correct, matches the stated goal, and is well-tested. CorrectnessThe new ordering keys the array-of-enums case on if (fieldSchema.type === "array" && fieldSchema.items?.enum) { … }So the two clients now agree on which array shapes render as a select. Good fix for the divergence. No behavioral regressions from reorderingI walked the four relevant input shapes to confirm flipping the branch order changes nothing except the intended case:
The only changed outcome is the first row — the intended fix. The added "redundant top-level enum" test locks in row 2. TestsCoverage is thorough: standard Minor (non-blocking) observations
Nothing to change. Clean, focused, matches web behavior. |
|
Thanks — LGTM noted, and the four-shape regression table matches my analysis. Both observations are pre-existing and out of scope: the single-select-for-array limitation is inherent to ink-form (no multiselect) and already commented; the |
Before/after of the TUI tool form for an array-of-enums field with no top-level
`enum`: before the fix it renders as a plain text field (raw "m"); with the fix
it renders as a select resolving the enumNames title ("Medium").
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5
Closes #1751
Follow-up from the review of #1691 (PR #1750).
Problem
The TUI
schemaToFormarray-of-enum branch was nested under an outerif (property.enum)guard:So a standard array-of-enums schema —
{ type: "array", items: { enum: [...] } }with no top-levelenum— never reached the array branch and fell through to a plain string input. To get a select the schema had to redundantly carry a top-levelenum. The webSchemaFormalready guards onitems?.enumalone, so the two clients diverged on which array shapes they recognized.Fix
Restructure the enum handling so the array-of-enums case keys on
property.type === "array" && property.items?.enumindependently of a top-levelenum, falling back to the single-selectproperty.enumbranch otherwise. Matches the web guard. TheenumNameslabeling from #1691 applies unchanged.Tests
items.enum-only shape (dropping the redundant top-levelenumthe old nesting required), including theenumNameslabel + mismatched-length fallback cases.enumstill renders as a select (no regression).schemaToForm.tsstays at 100% lines/functions/statements.npm run cipasses (validate → coverage → smoke → Storybook).Verified via a standalone render of the real
schemaToForm: a{ type: "array", items: { enum, enumNames } }field with no top-levelenumnow yieldsSmall=>s | Medium=>m | Large=>linstead of an empty/plain-string field.Smoke test (screenshots)
Rendered the real
ink-formbuilt by the realschemaToFormfor the #1751 case: aSizesarray-of-enums field (enum: [s,m,l]+enumNames: [Small,Medium,Large],default: "m", no top-levelenum) plus aPrioritysingle-enum control (has a top-levelenum). Non-interactive capture of the initial frame — the "before" column reproduces the pre-#1751 nesting.Sizesfalls through to a plain text field showing the raw defaultm— never a select, soenumNamescan't apply.Sizesis now a select; the defaultmresolves to its titleMedium.The
Prioritycontrol (top-levelenum) showsHighin both — unchanged, confirming the reorder only affects the intendeditems.enum-only case. More detail + images inpr-screenshots/README.md.🤖 Generated with Claude Code
https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5