fix: cap sidebar width responsively
This commit is contained in:
1 parent
0964535ddb
commit
69bc5e0bae
2 files changed
+35
-9
No files matched your search
@@ -19,6 +19,9 @@ struct RootView: View {
|
||||
/// split view's minimum sidebar width are rejected so the tab strip keeps
|
||||
/// the user's last visible boundary.
|
||||
@State private var pinnedTabStripWidth = Metrics.Sidebar.ideal
|
||||
/// Drives the sidebar's responsive upper bound. Start at the default so the
|
||||
/// first layout pass already has a sensible value before geometry reports.
|
||||
@State private var layoutWidth = Metrics.Window.defaultWidth
|
||||
|
||||
/// `nonisolated` because geometry transforms are `Sendable` closures and
|
||||
/// this coordinate-space name is immutable, not main-actor state.
|
||||
@@ -45,6 +48,11 @@ struct RootView: View {
|
||||
maxHeight: .infinity
|
||||
)
|
||||
.coordinateSpace(.named(Self.layoutSpace))
|
||||
.onGeometryChange(for: CGFloat.self) {
|
||||
$0.size.width
|
||||
} action: {
|
||||
layoutWidth = $0
|
||||
}
|
||||
.toolbarBackground(WindowChrome.background(for: colorScheme), for: .windowToolbar)
|
||||
.toolbarBackground(.visible, for: .windowToolbar)
|
||||
// ⌘T and every Connect entry land here. A sheet rather than a page,
|
||||
@@ -123,8 +131,8 @@ struct RootView: View {
|
||||
SidebarView(detailCatalog: .standard(store: app.hostLibrary))
|
||||
.navigationSplitViewColumnWidth(
|
||||
min: Metrics.Sidebar.min,
|
||||
ideal: Metrics.Sidebar.ideal,
|
||||
max: Metrics.Sidebar.max
|
||||
ideal: min(Metrics.Sidebar.ideal, sidebarMaxWidth),
|
||||
max: sidebarMaxWidth
|
||||
)
|
||||
} detail: {
|
||||
VStack(spacing: 0) {
|
||||
@@ -153,11 +161,15 @@ struct RootView: View {
|
||||
VaultSidebarView()
|
||||
.navigationSplitViewColumnWidth(
|
||||
min: Metrics.Sidebar.min,
|
||||
ideal: Metrics.Sidebar.ideal,
|
||||
max: Metrics.Sidebar.max
|
||||
ideal: min(Metrics.Sidebar.ideal, sidebarMaxWidth),
|
||||
max: sidebarMaxWidth
|
||||
)
|
||||
}
|
||||
|
||||
private var sidebarMaxWidth: CGFloat {
|
||||
Metrics.Window.sidebarMaxWidth(for: layoutWidth)
|
||||
}
|
||||
|
||||
private func recordPinnedTabStripWidth(_ measuredDetailLeadingEdge: CGFloat) {
|
||||
pinnedTabStripWidth = PinnedTopLevelTabSizing.resolvedStripWidth(
|
||||
current: pinnedTabStripWidth,
|
||||
|
||||
@@ -271,16 +271,30 @@ nonisolated enum Metrics {
|
||||
static let detailMin: CGFloat = 320
|
||||
static let detailMinHeight: CGFloat = 440
|
||||
|
||||
/// Space to the right of the navigation sidebar in Vault's complete
|
||||
/// working layout: two dividers, the main surface, and an Edit/New
|
||||
/// detail panel.
|
||||
static let trailingContentMinWidth: CGFloat = 1
|
||||
+ Metrics.VaultContent.min
|
||||
+ 1
|
||||
+ Metrics.VaultDetail.min
|
||||
|
||||
/// Vault's complete working layout sets the application floor: the
|
||||
/// navigation sidebar, main surface, and an Edit/New detail panel, plus
|
||||
/// the two dividers between them. Reserving the third column even while
|
||||
/// it is closed prevents opening an editor inside an already-too-narrow
|
||||
/// window and keeps every host form usable from the moment it appears.
|
||||
static let minWidth: CGFloat = Metrics.Sidebar.min
|
||||
+ 1
|
||||
+ Metrics.VaultContent.min
|
||||
+ 1
|
||||
+ Metrics.VaultDetail.min
|
||||
static let minWidth: CGFloat = Metrics.Sidebar.min + trailingContentMinWidth
|
||||
|
||||
/// The sidebar may use only width left after the complete Vault work
|
||||
/// area has been reserved. It grows with the window, but never outside
|
||||
/// its own usability bounds.
|
||||
static func sidebarMaxWidth(for availableWidth: CGFloat) -> CGFloat {
|
||||
min(
|
||||
Metrics.Sidebar.max,
|
||||
max(Metrics.Sidebar.min, availableWidth - trailingContentMinWidth)
|
||||
)
|
||||
}
|
||||
|
||||
/// Root content includes the pinned tab strip and its divider above the
|
||||
/// detail floor. The macOS title bar is outside this measurement.
|
||||
|
||||
Reference in new issue
Block a user