diff --git a/Documentation/Reference/structs/OverlaySplitView.md b/Documentation/Reference/structs/OverlaySplitView.md index 210096b..2208670 100644 --- a/Documentation/Reference/structs/OverlaySplitView.md +++ b/Documentation/Reference/structs/OverlaySplitView.md @@ -17,6 +17,10 @@ The split view's main content. Whether the sidebar is at the trailing position. +### `visible` + +Whether the sidebar is visible. + ### `sidebarID` The sidebar content's id. @@ -26,10 +30,11 @@ The sidebar content's id. The main content's id. ## Methods -### `init(sidebar:content:)` +### `init(visible:sidebar:content:)` Initialize an overlay split view. - Parameters: + - visible: Whether the sidebar is visible. - sidebar: The sidebar content. - content: The main content. @@ -55,3 +60,4 @@ Update the view storage of the overlay split view widget. ### `updatePosition(_:)` Update the sidebar's position in the split view. +- Parameter splitView: The overlay split view. diff --git a/Icons/Demo.png b/Icons/Demo.png index b3f1a90..e7c9bd4 100644 Binary files a/Icons/Demo.png and b/Icons/Demo.png differ diff --git a/Sources/Adwaita/View/OverlaySplitView.swift b/Sources/Adwaita/View/OverlaySplitView.swift index b4d0308..678eda0 100644 --- a/Sources/Adwaita/View/OverlaySplitView.swift +++ b/Sources/Adwaita/View/OverlaySplitView.swift @@ -16,6 +16,8 @@ public struct OverlaySplitView: Widget { var content: () -> Body /// Whether the sidebar is at the trailing position. var trailing = false + /// Whether the sidebar is visible. + var visible: Bool /// The sidebar content's id. let sidebarID = "sidebar" @@ -24,11 +26,17 @@ public struct OverlaySplitView: Widget { /// Initialize an overlay split view. /// - Parameters: + /// - visible: Whether the sidebar is visible. /// - sidebar: The sidebar content. /// - content: The main content. - public init(@ViewBuilder sidebar: @escaping () -> Body, @ViewBuilder content: @escaping () -> Body) { + public init( + visible: Bool = true, + @ViewBuilder sidebar: @escaping () -> Body, + @ViewBuilder content: @escaping () -> Body + ) { self.sidebar = sidebar self.content = content + self.visible = visible } /// The position of the sidebar. @@ -77,8 +85,14 @@ public struct OverlaySplitView: Widget { } /// Update the sidebar's position in the split view. + /// - Parameter splitView: The overlay split view. func updatePosition(_ splitView: Libadwaita.OverlaySplitView) { _ = splitView.position(trailing: trailing) + if visible { + splitView.showSidebar() + } else { + splitView.hideSidebar() + } } } diff --git a/Sources/Adwaita/View/Toggle.swift b/Sources/Adwaita/View/Toggle.swift index ac7571e..7713bbd 100644 --- a/Sources/Adwaita/View/Toggle.swift +++ b/Sources/Adwaita/View/Toggle.swift @@ -55,6 +55,9 @@ public struct Toggle: Widget { public func container(modifiers: [(View) -> View]) -> ViewStorage { let toggle: Libadwaita.ToggleButton = .init(label ?? "") updateState(toggle: toggle) + toggle.handler { + self.isOn.toggle() + } return .init(toggle) } diff --git a/Tests/Demo.swift b/Tests/Demo.swift index 57958c0..1e0de86 100644 --- a/Tests/Demo.swift +++ b/Tests/Demo.swift @@ -57,11 +57,12 @@ struct Demo: App { @State private var selection: Page = .welcome @State private var toast: Signal = .init() + @State private var sidebarVisible = true var window: GTUIApplicationWindow var app: GTUIApp! var view: Body { - NavigationSplitView { + OverlaySplitView(visible: sidebarVisible) { ScrollView { List(Page.allCases, selection: $selection) { element in Text(element.label) @@ -72,21 +73,7 @@ struct Demo: App { } .topToolbar { HeaderBar.end { - Menu(icon: .default(icon: .openMenu), app: app, window: window) { - MenuButton("New Window", window: false) { - app.addWindow("main") - } - .keyboardShortcut("n".ctrl()) - MenuButton("Close Window") { - window.close() - } - .keyboardShortcut("w".ctrl()) - MenuSection { - MenuButton("About") { app.addWindow("about", parent: window) } - MenuButton("Quit", window: false) { app.quit() } - .keyboardShortcut("q".ctrl()) - } - } + menu } } .navigationTitle("Demo") @@ -95,16 +82,52 @@ struct Demo: App { selection.label, icon: selection.icon, description: selection.description - ) { - selection.view(app: app, window: window, toast: toast) - } + ) { selection.view(app: app, window: window, toast: toast) } .topToolbar { - HeaderBar.empty() + HeaderBar { + Toggle(icon: .default(icon: .sidebarShow), isOn: $sidebarVisible) + } end: { + if sidebarVisible { + Text("") + .transition(.crossfade) + } else { + menu + .transition(.crossfade) + } + } + .headerBarTitle { + if sidebarVisible { + Text("") + .transition(.crossfade) + } else { + Text("Swift Adwaita Demo") + .style("heading") + .transition(.crossfade) + } + } } .toast("This is a toast!", signal: toast) } } + var menu: View { + Menu(icon: .default(icon: .openMenu), app: app, window: window) { + MenuButton("New Window", window: false) { + app.addWindow("main") + } + .keyboardShortcut("n".ctrl()) + MenuButton("Close Window") { + window.close() + } + .keyboardShortcut("w".ctrl()) + MenuSection { + MenuButton("About") { app.addWindow("about", parent: window) } + MenuButton("Quit", window: false) { app.quit() } + .keyboardShortcut("q".ctrl()) + } + } + } + } }