The combo's trigger retires — each picker is one rectangle again, taller, and Style becomes Appearance in the sidebar

Both the symbol picker and the background color control give up the two-zone combo chrome from the 2026-08-09 rework: no more face/trigger split, no more trailing chevron square. Each is now a single bordered rectangle with one hit zone, 2.1em tall and 1.5x that wide (a 4:6 ratio, 50% taller than the retired chrome's 18pt). A click anywhere opens the same curated popover the trigger used to gate.

The background rectangle's popover is new: a None-plus-sixteen palette grid mirroring the Style… popover's own wells, with an Other… row onto the shared, pre-debounced Colors panel session — replacing the old NSMenu dropdown outright. The symbol rectangle keeps its existing popover (search, curated grid, tint colors, More Symbols…) verbatim; only its entry point collapsed to one zone.

ComboFieldControl/ComboFieldMetrics (ComboField.swift) are replaced by PickerRectControl/PickerRectMetrics (PickerRect.swift). ColorComboView and its NSMenu-building pure model are retired wholesale in favor of ColorSwatchPicker. SymbolComboControl becomes SymbolGlyphControl. PaletteSwatch.rectImage, the last caller of which was the retired dropdown's menu rows, goes with it.

In the card window sidebar, the "Style" section header becomes "Appearance" (sidebar only — the board context menu's Style… item and StyleEditorView's own naming are untouched), and the symbol and background controls move from stacked rows to side-by-side columns, each captioned above rather than leading. CardStyleSection no longer carries its own debounce Task for background panel picks — the shared Colors-panel session now delivers an already-settled value.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
This commit is contained in:
2026-08-09 20:44:47 -04:00
parent 01aa9a0c94
commit 4210bbe0a7
17 changed files with 964 additions and 1321 deletions
+1 -1
View File
@@ -120,7 +120,7 @@ final class SymbolBrowserModel {
var query: String = ""
/// The presenting surface's write. `@ObservationIgnored` because nothing observes it, and
/// unannotated for `ComboFieldControl.onFaceClick`'s reason this class is already main-actor
/// unannotated for `PickerRectControl.onClick`'s reason this class is already main-actor
/// isolated, so the closure is called there by construction.
@ObservationIgnored
var onSelect: ((String?) -> Void)?