From ef3ddcdd7a5d0cb0291f4d6b6aa4aa38cd556f29 Mon Sep 17 00:00:00 2001 From: Alan Wizemann Date: Thu, 23 Apr 2026 21:56:36 +0200 Subject: [PATCH] fix(config-sheet): EnumControl always uses Menu picker, never Segmented MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Configuration sheet's clipping bug persisted after the earlier VStack maxWidth fix (d616935) and the user's Part-C manifest rewrite to use [label](url) markdown. Re-diagnosed: the actual overflow source was EnumControl's `.pickerStyle(.segmented)` branch, active when options.count ≤ 4. Segmented pickers on macOS size to the intrinsic width of all their labels concatenated. They refuse offered width constraints, refuse to wrap, refuse to truncate. A schema with three long labels like "Claude Opus 4 (Recommended - Most Capable)" produced a ~650pt segmented picker that pushed the fieldRow past the sheet's 560pt viewport. No amount of .frame(maxWidth: .infinity) on parent containers can rein in a segmented picker — the picker ignores them. Fix: remove the segmented branch. Always use the default Menu picker (dropdown). Dropdowns respect offered width and surface long labels in the popup list, so the sheet can't overflow regardless of label length or option count. Loses the segmented look for short-enum cases like a 3-option "Daily / Weekly / Monthly" picker — compactness traded for correctness. If a future template author wants segmented rendering for a specific short-label enum, we can add a manifest hint (e.g., "uiHint": "segmented") that explicitly opts in; not worth the machinery until there's demand. 58/58 Swift tests still pass. No schema changes, no migration. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Templates/Views/TemplateConfigSheet.swift | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/scarf/scarf/Features/Templates/Views/TemplateConfigSheet.swift b/scarf/scarf/Features/Templates/Views/TemplateConfigSheet.swift index c9d4875..0c7ce02 100644 --- a/scarf/scarf/Features/Templates/Views/TemplateConfigSheet.swift +++ b/scarf/scarf/Features/Templates/Views/TemplateConfigSheet.swift @@ -312,24 +312,23 @@ private struct EnumControl: View { let options: [TemplateConfigField.EnumOption] @Binding var value: String var body: some View { - // Segmented for ≤ 4 options, dropdown otherwise — fits Scarf's - // existing settings UI. - if options.count <= 4 { - Picker("", selection: $value) { - ForEach(options) { opt in - Text(opt.label).tag(opt.value) - } + // Always use the default Menu picker (dropdown). An earlier + // version switched to `.pickerStyle(.segmented)` when + // `options.count ≤ 4` for a more compact look, but on macOS + // segmented pickers size to the intrinsic width of all their + // labels concatenated — they refuse offered width constraints + // and refuse to wrap. A schema with three long labels like + // "Claude Opus 4 (Recommended - Most Capable)" produced a + // ~650pt picker that overflowed the 560pt sheet viewport, + // clipping the entire form. Menu pickers respect the fieldRow's + // offered width and show long labels in the popup list, so the + // sheet can't overflow regardless of label length. + Picker("", selection: $value) { + ForEach(options) { opt in + Text(opt.label).tag(opt.value) } - .pickerStyle(.segmented) - .labelsHidden() - } else { - Picker("", selection: $value) { - ForEach(options) { opt in - Text(opt.label).tag(opt.value) - } - } - .labelsHidden() } + .labelsHidden() } }