A card window toolbar control shows and hides the trailing sidebar — View ▸ Show Sidebar joins Edit Body, Raw Source and Add Attachment
The card window's trailing attributes sidebar has always been unconditional since m6; this adds View ▸ Show Sidebar (a checkmark toggle, ShowComments' shape) and a matching toolbar item on the customizable card toolbar (NSToolbar/WindowToolbarController), a fourth default beside Edit Body, Raw Source and Add Attachment. sidebar.right for the trailing pane; one shared animated write path (AppPreferences.setShowCardSidebar) both faces call, structural-voice reflow with a trailing slide-and-fade transition (Motion.cardSidebarTransition), Reduce Motion respected throughout. CardWindowMetrics.minimumSize gains a sidebar: Bool = true parameter so a hidden sidebar shrinks the window's floor, composing with the existing commentsColumn parameter. The toolbar item's read/write are injectable closures (defaulted to the real UserDefaults-backed pair) so its plumbing is testable without touching the developer's own preferences domain. WindowToolbarController's observation tracking only sees @Observable reads, so a small HostedWindowController.revalidateToolbar() plus an onChange nudge keeps the toolbar button's on-state in step with the View-menu row's write. Scope held narrowly to visibility, per the card: no sidebar section reordering, no action-moving. Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
This commit is contained in:
@@ -127,6 +127,41 @@ public enum AppPreferences {
|
||||
/// `double(forKey:)` reading safe here in a way `boardZoomLevel`'s note warns it usually is not.
|
||||
public static let commentsColumnWidthKey = "commentsColumnWidth"
|
||||
|
||||
// MARK: The attributes sidebar's visibility
|
||||
|
||||
/// **View ▸ Show Sidebar** — the card window's trailing attributes sidebar (05-card-window.md ▸
|
||||
/// Composition), `showComments`'s shape and reasons exactly: one bit, app-wide, persisted across
|
||||
/// restarts, and the checkmark (and the toolbar toggle that mirrors it, `CardToolbar`) reads
|
||||
/// exactly this value so neither ever lies.
|
||||
///
|
||||
/// **Default on.** The sidebar has been part of every card window since m6; an unset key must
|
||||
/// read as the window everyone already knows rather than as a surprise collapse the first time
|
||||
/// this preference exists to read.
|
||||
public static let showCardSidebarKey = "showCardSidebar"
|
||||
|
||||
/// Read outside a view — `CardToolbar`'s toggle item, which is AppKit rather than SwiftUI and so
|
||||
/// has no `@AppStorage` of its own (`lastCardWindowSize`'s reason).
|
||||
public static var showCardSidebar: Bool {
|
||||
UserDefaults.standard.object(forKey: showCardSidebarKey) as? Bool ?? true
|
||||
}
|
||||
|
||||
/// Show/Hide Sidebar's whole behaviour — **the one write path both of its faces share**
|
||||
/// (`BoardStore.setTrashVisible`'s precedent: "a toolbar item is a menu command with a different
|
||||
/// face, never a second implementation of it"), so `ShowSidebarCommand`'s Toggle and
|
||||
/// `CardToolbar`'s item call this rather than writing `UserDefaults` each in their own words.
|
||||
///
|
||||
/// **A user-initiated structural change**, so it animates in the structural voice and goes
|
||||
/// instant under Reduce Motion — the Show Trash re-divide's own reasoning, applied to a pane
|
||||
/// leaving a window instead of a lane leaving a strip. Reduce Motion is read from AppKit rather
|
||||
/// than from `@Environment` for the same reason `setTrashVisible` reads it that way: a toolbar
|
||||
/// item's action and a menu row's both run outside any rendered hierarchy.
|
||||
@MainActor
|
||||
public static func setShowCardSidebar(_ shown: Bool) {
|
||||
withAnimation(Motion.structural(reduced: Motion.prefersReducedMotion)) {
|
||||
UserDefaults.standard.set(shown, forKey: showCardSidebarKey)
|
||||
}
|
||||
}
|
||||
|
||||
/// The quick-style row's recently-used backgrounds — an array of palette names / hex strings,
|
||||
/// most-recent-first (03-board-ui.md § Styling ▸ Controls: "Recents are app-wide and persist
|
||||
/// app-side (user preference, never board data)"; 11-command-nexus.md files it under the
|
||||
|
||||
Reference in New Issue
Block a user