The board popover goes tabbed — Info, Background, Git, three empty rooms awaiting their own sessions
The symbol/name header keeps the top; below it a segmented tab bar replaces the styling embed and the git section, both parked in-file — their seams are settled, test-pinned design, and the tab sessions rehome surfaces, not rulings. Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -4,11 +4,14 @@ import SwiftUI
|
||||
/// **The board popover** — "the one board-level surface" (03-board-ui.md § Board popover), and the
|
||||
/// widget in the window's titlebar that opens it.
|
||||
///
|
||||
/// Two sections, in the design's own order: the board rename and the embedded style editor aimed at
|
||||
/// the board. A third, contextual note joins them only on a board that carries an inert `.git` — see
|
||||
/// `BoardGitNote` for the wording and why base's posture there is a quiet signpost rather than a
|
||||
/// standing section (12-editions.md § Base and `.git`, ruled 2026-07-27, superseding the earlier
|
||||
/// reserved-slot placeholder this file once carried).
|
||||
/// **Restructuring in progress (2026-08-07): the popover is going tabbed.** The symbol/name header
|
||||
/// stays at the top; below it sit three tabs — **Info**, **Background**, **Git** — each a settings
|
||||
/// surface for one aspect of board configuration, each deliberately *empty* today: their contents
|
||||
/// are to be settled one per dedicated design session. The former body — the embedded style editor
|
||||
/// and the mode-aware git section — is unrendered for the interim but parked in this file (see the
|
||||
/// "Parked" marks below), because its pure seams (`BoardGitSection`, the posture notes,
|
||||
/// `BoardSettingsAvailability`'s caller) are settled design and will rehome into the tabs as those
|
||||
/// sessions rule.
|
||||
///
|
||||
/// ### One home, deliberately
|
||||
///
|
||||
@@ -250,14 +253,30 @@ func boardInfoTitlebarAccessory(
|
||||
return controller
|
||||
}
|
||||
|
||||
// MARK: - Tabs
|
||||
|
||||
/// The popover's three aspects, one tab each (03-board-ui.md § Board popover, the 2026-08-07 tab
|
||||
/// restructure): **Info**, **Background**, **Git**. All three are placeholders — empty on purpose —
|
||||
/// until each gets its dedicated design session; the enum exists now so the popover's shape is the
|
||||
/// tabs' from day one and each session only has to fill its case in.
|
||||
enum BoardInfoTab: String, CaseIterable, Identifiable {
|
||||
|
||||
case info = "Info"
|
||||
case background = "Background"
|
||||
case git = "Git"
|
||||
|
||||
var id: Self { self }
|
||||
}
|
||||
|
||||
// MARK: - The popover's content
|
||||
|
||||
/// Two sections and, on a `.git`-bearing board, a contextual note — one view (03-board-ui.md §
|
||||
/// Board popover; 12-editions.md § Base and `.git`).
|
||||
/// The symbol/name header, then the tab bar, then the selected tab's surface — one view
|
||||
/// (03-board-ui.md § Board popover).
|
||||
///
|
||||
/// Width is the style editor's — 268 points, the number that keeps the Style… popover narrow enough
|
||||
/// to sit beside a card — so the embedded editor lays out here exactly as it does at its other two
|
||||
/// anchors rather than being stretched by a container with its own opinion.
|
||||
/// Width is the style editor's — the number that keeps the Style… popover narrow enough to sit
|
||||
/// beside a card — kept through the restructure so the popover's footprint doesn't wander while the
|
||||
/// tabs are placeholders; whether the tabbed surface wants its own width is each tab session's
|
||||
/// question to raise.
|
||||
struct BoardInfoView: View {
|
||||
|
||||
let store: BoardStore
|
||||
@@ -272,6 +291,12 @@ struct BoardInfoView: View {
|
||||
/// handed the widget's binding to put it down.
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
|
||||
/// The selected tab. `@State` on the popover's content, which `BoardInfoWidget` hands `.popover`
|
||||
/// fresh on every open — so the selection resets to Info per open. Whether the popover should
|
||||
/// instead remember its last tab is a question for the tab sessions, once the tabs have content
|
||||
/// worth returning to.
|
||||
@State private var tab: BoardInfoTab = .info
|
||||
|
||||
/// Whether this board carries a `.git` — checked once, off disk, when the view is built (which
|
||||
/// is every time the popover opens, since `BoardInfoWidget` hands `.popover` a fresh instance).
|
||||
/// See `BoardGitNote.hasGitDirectory(at:)` for why a live-updating fact isn't needed here.
|
||||
@@ -335,25 +360,36 @@ struct BoardInfoView: View {
|
||||
|
||||
Divider()
|
||||
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
sectionHeader("Styling")
|
||||
.padding(.horizontal, inset)
|
||||
.padding(.top, inset)
|
||||
// Always the board, whatever is selected. The ⌥⌘S anchor is the selection-aware one
|
||||
// ("nothing selected = the board"); this embed is the surface that exists *because*
|
||||
// the board is a style target, so it can have no other target (§ Styling ▸
|
||||
// Controls: "the board popover's target is the board itself").
|
||||
// No symbol section — the inline `SymbolPicker` beside the rename field above is
|
||||
// the board glyph's one surface in this popover.
|
||||
StyleEditorView(store: store, recents: recents, target: .board, showsSymbols: false)
|
||||
// The tab bar: a segmented control rather than a `TabView`, because the popover is a
|
||||
// compact settings surface and the segmented idiom is the macOS shape for switching
|
||||
// between a handful of peer panes inside one. The label is hidden visually but stays
|
||||
// the control's accessibility name.
|
||||
Picker("Board configuration", selection: $tab) {
|
||||
ForEach(BoardInfoTab.allCases) { tab in
|
||||
Text(tab.rawValue)
|
||||
}
|
||||
}
|
||||
.pickerStyle(.segmented)
|
||||
.labelsHidden()
|
||||
.padding(.horizontal, inset)
|
||||
.padding(.top, inset)
|
||||
|
||||
// Contextual, not standing (12-editions.md, settled 2026-07-27): an ordinary free-tier
|
||||
// board adds nothing here at all — no header, no divider, no placeholder — and the
|
||||
// popover ends at Styling, complete in itself. What a Pro board adds instead is the
|
||||
// mode-aware git section (03-board-ui.md ▸ Board popover), which is a *section*, header
|
||||
// and all, because under Pro git is a feature of the board rather than a signpost.
|
||||
gitSection
|
||||
// Each tab's surface — empty today, on purpose: the contents are each their own design
|
||||
// session's to settle (the file-top note). The switch is already the shape those
|
||||
// sessions will fill in, and the fixed placeholder height is exactly that — a
|
||||
// placeholder, so the popover reads as a surface awaiting content rather than a
|
||||
// collapsed sliver; it goes the moment any tab has real content to size itself by.
|
||||
Group {
|
||||
switch tab {
|
||||
case .info:
|
||||
EmptyView()
|
||||
case .background:
|
||||
EmptyView()
|
||||
case .git:
|
||||
EmptyView()
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity, minHeight: 120)
|
||||
}
|
||||
// The style editor's popover width, taken from the editor rather than restated: the embed
|
||||
// below must lay out here exactly as it does at its other two anchors, and that number is
|
||||
@@ -361,6 +397,15 @@ struct BoardInfoView: View {
|
||||
.frame(width: StyleEditorLayout.popover(bodyPointSize: CardWindowMetrics.bodyPointSize).width)
|
||||
}
|
||||
|
||||
// MARK: Parked pending the tab sessions (2026-08-07)
|
||||
//
|
||||
// Nothing below this mark renders today. The style-editor embed left the body with the tab
|
||||
// restructure (its Background-tab fate is that session's), and the git section — postures,
|
||||
// notes, and the Board Settings… row — waits here for the Git tab's session. Parked rather
|
||||
// than deleted because every seam it hangs on is settled, test-pinned design
|
||||
// (`BoardGitSectionTests`, `BoardSettingsAvailabilityTests`), and the tab sessions rehome
|
||||
// surfaces, not rulings.
|
||||
|
||||
/// The popover's closing section, whichever of the six postures this board is in — see
|
||||
/// `BoardGitSection`.
|
||||
@ViewBuilder
|
||||
|
||||
Reference in New Issue
Block a user