Two widths, one height — the symbol picker squares to 5:4, colour holds 6:4, and None's slash follows the swatch out of the grid

The owner's follow-up review on the shipped rectangles (Pipeline card
5004c540): height was close, so it stays exactly 2.1em on both controls;
width now diverges by role via PickerRectMetrics.WidthRatio (color 1.5,
symbol 1.25) instead of one shared multiplier. The symbol glyph gets a
small em-derived inset back (SymbolGlyphControl.glyphInset) — a sliver of
breath, not the old padded ring — applied to the face rect before sizing
and fitting, still centred on the same midpoint. The collapsed colour
swatch reuses ColorSwatchNoneStrike's own geometry to draw the popover's
None slash whenever the stored value is nil or unresolvable, rather than
sitting empty. Both mounting anchors (the card sidebar's side-by-side
columns, the board popover beside the rename field) pick up .fixedSize()
so the controls render at their own intrinsic size instead of stretching
into whatever slack an HStack proposal leaves them.

KanbanTests/SymbolCatalogTests.swift and ColorSwatchPickerTests.swift
updated for the per-role widths, the shared-height claim, the glyph
inset rule, and the None-face predicate.
This commit is contained in:
2026-08-09 21:37:29 -04:00
parent ac4f8b9050
commit f191e5c3ce
7 changed files with 264 additions and 63 deletions
+12
View File
@@ -143,6 +143,14 @@ struct CardStyleSection: View {
// and the board's inline-editing rule alike, unchanged across the layout reshape and the
// control's own two-zone-to-one-zone change.
.disabled(!store.acceptsBoardMutations)
// **Pinned to the control's own intrinsic size** (owner's 2026-08-10 follow-up: the two
// pickers' ratios have to actually render). `SymbolGlyphView.sizeThatFits` honours *any*
// explicit finite width proposal, which is right for a caller that wants to constrain it
// but this row's own `HStack` sits under an outer `.frame(maxWidth: .infinity)`, and
// without `.fixedSize()` here the row can propose more than the control's intrinsic width
// once there is slack to give it, silently drowning the 5:4 ratio the owner asked for.
// `.fixedSize()` makes SwiftUI always ask for the ideal size instead.
.fixedSize()
}
}
@@ -206,6 +214,10 @@ struct CardStyleSection: View {
onChange: { commitBackground($0) },
onPanelChange: { applyPanelBackground($0) }
)
// `symbolColumn`'s own fix, restated: pins this rectangle to its intrinsic 6:4 size
// rather than whatever width the row's outer `.frame(maxWidth: .infinity)` leaves slack
// for `ColorSwatchView.sizeThatFits` to honour.
.fixedSize()
}
}