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:
+13
-32
@@ -118,12 +118,10 @@ enum Palette {
|
||||
}
|
||||
|
||||
// The pathfinder's panel round-trip helpers, ported below (`NSColor.paletteHexString`,
|
||||
// `Palette.name(forHex:in:)`): the reusable colour-picker combo (`ColorComboView`, ColorCombo.swift)
|
||||
// is the surface that finally needs them — a colour the *system picker* returns has to become a
|
||||
// stored value the same way a palette pick already does: the palette NAME when the colour lands
|
||||
// exactly on one of the twelve, the hex otherwise. Its swatch drawing, unchanged in spirit, is
|
||||
// below: a menu can only render `Image`/`Text`, so both the quick-style row's dots and the combo's
|
||||
// rows have to be pictures.
|
||||
// `Palette.name(forHex:in:)`): the reusable colour-picker rectangle (`ColorSwatchPicker`,
|
||||
// ColorSwatchPicker.swift) is the surface that finally needs them — a colour the *system picker*
|
||||
// returns has to become a stored value the same way a palette pick already does: the palette NAME
|
||||
// when the colour lands exactly on one of the twelve, the hex otherwise.
|
||||
|
||||
// MARK: - Menu swatches
|
||||
|
||||
@@ -131,6 +129,11 @@ enum Palette {
|
||||
/// items**. AppKit renders a menu row from its label's image and text, so the quick-style recents row
|
||||
/// (03-board-ui.md § Styling ▸ Controls) needs an `NSImage` per dot where the editor's own wells are
|
||||
/// ordinary views.
|
||||
///
|
||||
/// **`rectImage`, the wide sibling this enum used to carry, is retired (2026-08-10).** It built the
|
||||
/// `NSMenuItem` images for `ColorComboView`'s dropdown rows and its collapsed face — both gone with
|
||||
/// that control (`ColorSwatchPicker.swift`'s own header). `circleImage` below is the one caller left:
|
||||
/// the quick-style recents row is still a menu, and a menu can still only render `Image`/`Text`.
|
||||
enum PaletteSwatch {
|
||||
|
||||
/// A filled dot for `value` (a palette name or `#RRGGBB[AA]` hex), hairline-bordered.
|
||||
@@ -159,28 +162,6 @@ enum PaletteSwatch {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
/// A wide rectangular swatch for `value` — `ColorComboView`'s own rows and its collapsed face,
|
||||
/// which are wide and short rather than the quick-style row's small dots (hence a sibling
|
||||
/// function rather than a parameter on `circleImage`: the two shapes are never interchangeable at
|
||||
/// their call sites). `nil` draws the border alone, exactly `circleImage`'s "there is no colour,
|
||||
/// so show none" — the collapsed face's **None** state and the dropdown's own **None** row both
|
||||
/// call this with `nil` rather than a sentinel string.
|
||||
static func rectImage(for value: String?, size: NSSize) -> NSImage {
|
||||
let color = value.flatMap(Palette.nsColor(for:))
|
||||
return NSImage(size: size, flipped: false) { rect in
|
||||
let inset = rect.insetBy(dx: 0.5, dy: 0.5)
|
||||
let path = NSBezierPath(rect: inset)
|
||||
NSColor.textBackgroundColor.setFill()
|
||||
path.fill()
|
||||
color?.setFill()
|
||||
path.fill()
|
||||
NSColor.separatorColor.setStroke()
|
||||
path.lineWidth = 1
|
||||
path.stroke()
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Palette {
|
||||
@@ -215,10 +196,10 @@ extension Palette {
|
||||
}
|
||||
|
||||
/// The name of `palette`'s entry whose hex matches `hex`, case-insensitively — the pathfinder's
|
||||
/// round trip, ported for `ColorComboView`'s panel handoff: a colour the system picker returns
|
||||
/// comes back as `NSColor.paletteHexString`'s canonical `#RRGGBB[AA]`, and this is what turns
|
||||
/// that back into "the user picked Light Cayenne" instead of leaving it as an anonymous hex.
|
||||
/// `nil` when nothing in `palette` matches, which the caller reads as "store the hex instead."
|
||||
/// round trip, ported for `SystemColorPanel`'s own panel handoff: a colour the system picker
|
||||
/// returns comes back as `NSColor.paletteHexString`'s canonical `#RRGGBB[AA]`, and this is what
|
||||
/// turns that back into "the user picked Light Cayenne" instead of leaving it as an anonymous
|
||||
/// hex. `nil` when nothing in `palette` matches, which the caller reads as "store the hex instead."
|
||||
static func name(forHex hex: String, in palette: [PaletteColor]) -> String? {
|
||||
palette.first { $0.hex.caseInsensitiveCompare(hex) == .orderedSame }?.name
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user