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:
@@ -302,6 +302,12 @@ struct CardWindowHost: View {
|
||||
/// threading the pair through a view that would then have to publish them back up.
|
||||
@AppStorage(AppPreferences.showCommentsKey) private var showComments = true
|
||||
@AppStorage(AppPreferences.commentsBesideBodyKey) private var commentsBesideBody = true
|
||||
/// The sidebar's own visibility bit, read here for `showComments`' one reason: the window's
|
||||
/// **minimum size** depends on it too (`minimumSize`). The toolbar item reads
|
||||
/// `AppPreferences.showCardSidebar` directly (`CardToolbar`, an AppKit seam with no `@AppStorage`
|
||||
/// of its own), and `CardWindowView` reads this same key again itself — three readers of one
|
||||
/// `UserDefaults` key, `showComments`' own arrangement.
|
||||
@AppStorage(AppPreferences.showCardSidebarKey) private var showSidebar = true
|
||||
|
||||
private enum Phase {
|
||||
case opening
|
||||
@@ -426,15 +432,23 @@ struct CardWindowHost: View {
|
||||
isClosePending = false
|
||||
windowController.closeAfterFlush()
|
||||
}
|
||||
// **The toolbar's Show Sidebar item, nudged fresh** — `WindowToolbarController`'s own
|
||||
// observation tracking only sees `@Observable` reads (its header explains why: menu
|
||||
// commands and AppKit have no `@Environment` to poll), and `AppPreferences.showCardSidebar`
|
||||
// is a plain `UserDefaults` read, not one. The toolbar's own click already revalidates
|
||||
// itself (`toggleFired`); this is the same nudge for the View-menu row's write, which is
|
||||
// the only other place this bit changes.
|
||||
.onChange(of: showSidebar) { _, _ in windowController.revalidateToolbar() }
|
||||
.onDisappear { finish() }
|
||||
}
|
||||
|
||||
/// **The minimum grows only while the comments pane is beside the body** (05-card-window.md ▸
|
||||
/// Composition) — which is the whole reason the stacked mount exists, so a narrow display keeps
|
||||
/// the minimum it always had.
|
||||
/// **The minimum grows only while the comments pane is beside the body, and shrinks while the
|
||||
/// sidebar is hidden** (05-card-window.md ▸ Composition) — the stacked mount's own reason, and
|
||||
/// View ▸ Show Sidebar's mirror of it: a window with neither costs the width of neither.
|
||||
private var minimumSize: CGSize {
|
||||
CardWindowMetrics.minimumSize(
|
||||
bodyPointSize: CardWindowMetrics.bodyPointSize,
|
||||
sidebar: showSidebar,
|
||||
commentsColumn: showComments && commentsBesideBody
|
||||
)
|
||||
}
|
||||
@@ -915,8 +929,11 @@ struct CardWindowHost: View {
|
||||
|
||||
// The window's customizable toolbar — Edit Body · Raw Source · Add Attachment, "the
|
||||
// window's three committed functions" (03-board-ui.md ▸ Toolbar; 05-card-window.md ▸
|
||||
// Window). It carries the three window-scoped handles above rather than a store, which is
|
||||
// why it is installed here and not at attach: those are this window's, and so is it.
|
||||
// Window), joined by Show Sidebar (below). It carries the three window-scoped handles above
|
||||
// rather than a store, which is why it is installed here and not at attach: those are this
|
||||
// window's, and so is it. Show Sidebar needs none of them — its read and write default to
|
||||
// `AppPreferences.showCardSidebar` / `.setShowCardSidebar`, the same app-wide bit every card
|
||||
// window answers to, so this call leaves the two injectable parameters unnamed.
|
||||
windowController.installToolbar(
|
||||
CardToolbar.controller(body: bodyPresentation, rawSource: rawSource, attachments: attachments)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user