mirror of
https://github.com/bitwarden/ios.git
synced 2025-12-10 17:46:07 -06:00
[PM-26063] Consolidates several view extensions to BitwardenKit (#2094)
This commit is contained in:
parent
ea01caa62d
commit
7a9aa82c90
@ -1,23 +0,0 @@
|
||||
import SwiftUI
|
||||
|
||||
// MARK: - NavigationBarViewModifier
|
||||
|
||||
/// A modifier that customizes a navigation bar's title and title display mode.
|
||||
///
|
||||
struct NavigationBarViewModifier: ViewModifier {
|
||||
// MARK: Properties
|
||||
|
||||
/// The navigation bar title.
|
||||
var title: String
|
||||
|
||||
/// The navigation bar title display mode.
|
||||
var navigationBarTitleDisplayMode: NavigationBarItem.TitleDisplayMode
|
||||
|
||||
// MARK: View
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content
|
||||
.navigationBarTitleDisplayMode(navigationBarTitleDisplayMode)
|
||||
.navigationTitle(title)
|
||||
}
|
||||
}
|
||||
@ -1,145 +0,0 @@
|
||||
import BitwardenKit
|
||||
import BitwardenResources
|
||||
import SwiftUI
|
||||
|
||||
/// Helper functions extended off the `View` protocol for supporting buttons and menus in toolbars.
|
||||
///
|
||||
extension View {
|
||||
// MARK: Buttons
|
||||
|
||||
/// Returns a toolbar button configured for adding an item.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - hidden: Whether to hide the toolbar item.
|
||||
/// - action: The action to perform when the button is tapped.
|
||||
/// - Returns: A `Button` configured for adding an item.
|
||||
///
|
||||
func addToolbarButton(hidden: Bool = false, action: @escaping () -> Void) -> some View {
|
||||
toolbarButton(asset: SharedAsset.Icons.plus16, label: Localizations.add, action: action)
|
||||
.hidden(hidden)
|
||||
.accessibilityIdentifier("AddItemButton")
|
||||
}
|
||||
|
||||
/// Returns a toolbar button configured for cancelling an operation in a view.
|
||||
///
|
||||
/// - Parameter action: The action to perform when the button is tapped.
|
||||
/// - Returns: A `Button` configured for cancelling an operation in a view.
|
||||
///
|
||||
func cancelToolbarButton(action: @escaping () -> Void) -> some View {
|
||||
toolbarButton(asset: SharedAsset.Icons.close16, label: Localizations.cancel, action: action)
|
||||
.accessibilityIdentifier("CancelButton")
|
||||
}
|
||||
|
||||
/// Returns a toolbar button configured for closing a view.
|
||||
///
|
||||
/// - Parameter action: The action to perform when the button is tapped.
|
||||
/// - Returns: A `Button` configured for closing a view.
|
||||
///
|
||||
func closeToolbarButton(action: @escaping () -> Void) -> some View {
|
||||
toolbarButton(asset: SharedAsset.Icons.close16, label: Localizations.close, action: action)
|
||||
.accessibilityIdentifier("CloseButton")
|
||||
}
|
||||
|
||||
/// Returns a toolbar button configured for editing an item.
|
||||
///
|
||||
/// - Parameter action: The action to perform when the button is tapped.
|
||||
/// - Returns: A `Button` configured for closing a view.
|
||||
///
|
||||
func editToolbarButton(action: @escaping () -> Void) -> some View {
|
||||
toolbarButton(Localizations.edit, action: action)
|
||||
.accessibilityIdentifier("EditItemButton")
|
||||
}
|
||||
|
||||
/// Returns a `Button` that displays an image for use in a toolbar.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - asset: The image asset to show in the button.
|
||||
/// - label: The label associated with the image, used as an accessibility label.
|
||||
/// - action: The action to perform when the button is tapped.
|
||||
/// - Returns: A `Button` for displaying an image in a toolbar.
|
||||
///
|
||||
func toolbarButton(asset: SharedImageAsset, label: String, action: @escaping () -> Void) -> some View {
|
||||
Button(action: action) {
|
||||
Image(asset: asset, label: Text(label))
|
||||
.imageStyle(.toolbarIcon)
|
||||
}
|
||||
// Ideally we would set both `minHeight` and `minWidth` to 44. Setting `minWidth` causes
|
||||
// padding to be applied equally on both sides of the image. This results in extra padding
|
||||
// along the margin though.
|
||||
.frame(minHeight: 44)
|
||||
}
|
||||
|
||||
/// Returns a `Button` that displays a text label for use in a toolbar.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - label: The label to display in the button.
|
||||
/// - action: The action to perform when the button is tapped.
|
||||
/// - Returns: A `Button` for displaying a text label in a toolbar.
|
||||
///
|
||||
func toolbarButton(_ label: String, action: @escaping () async -> Void) -> some View {
|
||||
AsyncButton(label, action: action)
|
||||
.foregroundColor(Asset.Colors.primaryBitwarden.swiftUIColor)
|
||||
// Ideally we would set both `minHeight` and `minWidth` to 44. Setting `minWidth` causes
|
||||
// padding to be applied equally on both sides of the image. This results in extra padding
|
||||
// along the margin though.
|
||||
.frame(minHeight: 44)
|
||||
}
|
||||
|
||||
// MARK: Menus
|
||||
|
||||
/// Returns a `Menu` for use in a toolbar.
|
||||
///
|
||||
/// - Parameter content: The content to display in the menu when the more icon is tapped.
|
||||
/// - Returns: A `Menu` for use in a toolbar.
|
||||
///
|
||||
func optionsToolbarMenu(@ViewBuilder content: () -> some View) -> some View {
|
||||
Menu {
|
||||
content()
|
||||
} label: {
|
||||
Image(asset: SharedAsset.Icons.ellipsisVertical24, label: Text(Localizations.options))
|
||||
.imageStyle(.toolbarIcon)
|
||||
.accessibilityIdentifier("HeaderBarOptionsButton")
|
||||
}
|
||||
// Ideally we would set both `minHeight` and `minWidth` to 44. Setting `minWidth` causes
|
||||
// padding to be applied equally on both sides of the image. This results in extra padding
|
||||
// along the margin though.
|
||||
.frame(height: 44)
|
||||
}
|
||||
|
||||
// MARK: Toolbar Items
|
||||
|
||||
/// A `ToolbarItem` for views with an add button.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - hidden: Whether to hide the toolbar item.
|
||||
/// - action: The action to perform when the add button is tapped.
|
||||
/// - Returns: A `ToolbarItem` with an add button.
|
||||
///
|
||||
func addToolbarItem(hidden: Bool = false, _ action: @escaping () -> Void) -> some ToolbarContent {
|
||||
ToolbarItem(placement: .topBarTrailing) {
|
||||
addToolbarButton(hidden: hidden, action: action)
|
||||
}
|
||||
}
|
||||
|
||||
/// A `ToolbarItem` for views with a dismiss button.
|
||||
///
|
||||
/// - Parameter action: The action to perform when the dismiss button is tapped.
|
||||
/// - Returns: A `ToolbarItem` with a dismiss button.
|
||||
///
|
||||
func cancelToolbarItem(_ action: @escaping () -> Void) -> some ToolbarContent {
|
||||
ToolbarItem(placement: .topBarTrailing) {
|
||||
cancelToolbarButton(action: action)
|
||||
}
|
||||
}
|
||||
|
||||
/// A `ToolbarItem` for views with a more button.
|
||||
///
|
||||
/// - Parameter content: The content to display in the menu when the more icon is tapped.
|
||||
/// - Returns: A `ToolbarItem` with a more button that shows a menu.
|
||||
///
|
||||
func optionsToolbarItem(@ViewBuilder _ content: () -> some View) -> some ToolbarContent {
|
||||
ToolbarItem(placement: .topBarTrailing) {
|
||||
optionsToolbarMenu(content: content)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,15 +3,6 @@ import SwiftUI
|
||||
/// Helper functions extended off the `View` protocol.
|
||||
///
|
||||
extension View {
|
||||
@ViewBuilder var navStackWrapped: some View {
|
||||
if #available(iOSApplicationExtension 16.0, *) {
|
||||
NavigationStack { self }
|
||||
} else {
|
||||
NavigationView { self }
|
||||
.navigationViewStyle(.stack)
|
||||
}
|
||||
}
|
||||
|
||||
/// On iOS 16+, configures the scroll view to dismiss the keyboard immediately.
|
||||
///
|
||||
func dismissKeyboardImmediately() -> some View {
|
||||
@ -60,24 +51,6 @@ extension View {
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies a custom navigation bar title and title display mode to a view.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - title: The navigation bar title.
|
||||
/// - titleDisplayMode: The navigation bar title display mode.
|
||||
///
|
||||
/// - Returns: A view with a custom navigation bar.
|
||||
///
|
||||
func navigationBar(
|
||||
title: String,
|
||||
titleDisplayMode: NavigationBarItem.TitleDisplayMode,
|
||||
) -> some View {
|
||||
modifier(NavigationBarViewModifier(
|
||||
title: title,
|
||||
navigationBarTitleDisplayMode: titleDisplayMode,
|
||||
))
|
||||
}
|
||||
|
||||
/// Applies the `ScrollViewModifier` to a view.
|
||||
///
|
||||
/// - Parameter addVerticalPadding: Whether or not to add vertical padding. Defaults to `true`.
|
||||
|
||||
@ -34,3 +34,25 @@ public struct NavigationBarViewModifier: ViewModifier {
|
||||
.navigationTitle(title)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: View + NavigationBarViewModifier
|
||||
|
||||
public extension View {
|
||||
/// Applies a custom navigation bar title and title display mode to a view.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - title: The navigation bar title.
|
||||
/// - titleDisplayMode: The navigation bar title display mode.
|
||||
///
|
||||
/// - Returns: A view with a custom navigation bar.
|
||||
///
|
||||
func navigationBar(
|
||||
title: String,
|
||||
titleDisplayMode: NavigationBarItem.TitleDisplayMode,
|
||||
) -> some View {
|
||||
modifier(NavigationBarViewModifier(
|
||||
title: title,
|
||||
navigationBarTitleDisplayMode: titleDisplayMode,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,24 @@
|
||||
import BitwardenKit
|
||||
import BitwardenResources
|
||||
import SwiftUI
|
||||
|
||||
/// Helper functions extended off the `View` protocol for supporting buttons and menus in toolbars.
|
||||
///
|
||||
extension View {
|
||||
public extension View {
|
||||
// MARK: Buttons
|
||||
|
||||
/// Returns a toolbar button configured for adding an item.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - hidden: Whether to hide the toolbar item.
|
||||
/// - action: The action to perform when the button is tapped.
|
||||
/// - Returns: A `Button` configured for adding an item.
|
||||
///
|
||||
func addToolbarButton(hidden: Bool = false, action: @escaping () -> Void) -> some View {
|
||||
toolbarButton(asset: SharedAsset.Icons.plus16, label: Localizations.add, action: action)
|
||||
.hidden(hidden)
|
||||
.accessibilityIdentifier("AddItemButton")
|
||||
}
|
||||
|
||||
/// Returns a toolbar button configured for cancelling an operation in a view.
|
||||
///
|
||||
/// - Parameters:
|
||||
@ -116,7 +128,7 @@ extension View {
|
||||
/// - action: The action to perform when the button is tapped.
|
||||
/// - Returns: A `Button` for displaying an image in a toolbar.
|
||||
///
|
||||
func toolbarButton(asset: ImageAsset, label: String, action: @escaping () -> Void) -> some View {
|
||||
func toolbarButton(asset: SharedImageAsset, label: String, action: @escaping () -> Void) -> some View {
|
||||
Button(action: action) {
|
||||
Image(asset: asset, label: Text(label))
|
||||
.imageStyle(.toolbarIcon)
|
||||
@ -185,6 +197,19 @@ extension View {
|
||||
|
||||
// MARK: Toolbar Items
|
||||
|
||||
/// A `ToolbarItem` for views with an add button.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - hidden: Whether to hide the toolbar item.
|
||||
/// - action: The action to perform when the add button is tapped.
|
||||
/// - Returns: A `ToolbarItem` with an add button.
|
||||
///
|
||||
func addToolbarItem(hidden: Bool = false, _ action: @escaping () -> Void) -> some ToolbarContent {
|
||||
ToolbarItem(placement: .topBarTrailing) {
|
||||
addToolbarButton(hidden: hidden, action: action)
|
||||
}
|
||||
}
|
||||
|
||||
/// A `ToolbarItem` for views with a cancel text button.
|
||||
///
|
||||
/// - Parameters:
|
||||
@ -5,6 +5,21 @@ import SwiftUI
|
||||
/// Helper functions for fundamental `View` manipulation.
|
||||
///
|
||||
public extension View {
|
||||
// MARK: Computed Properties
|
||||
|
||||
/// Wraps the view in a `NavigationStack`.
|
||||
///
|
||||
@ViewBuilder var navStackWrapped: some View {
|
||||
if #available(iOSApplicationExtension 16.0, *) {
|
||||
NavigationStack { self }
|
||||
} else {
|
||||
NavigationView { self }
|
||||
.navigationViewStyle(.stack)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Methods
|
||||
|
||||
/// Apply an arbitrary block of modifiers to a view. This is particularly useful
|
||||
/// if the modifiers in question might only be available on particular versions
|
||||
/// of iOS.
|
||||
|
||||
@ -33,24 +33,6 @@ extension View {
|
||||
}
|
||||
}
|
||||
|
||||
/// Applies a custom navigation bar title and title display mode to a view.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - title: The navigation bar title.
|
||||
/// - titleDisplayMode: The navigation bar title display mode.
|
||||
///
|
||||
/// - Returns: A view with a custom navigation bar.
|
||||
///
|
||||
func navigationBar(
|
||||
title: String,
|
||||
titleDisplayMode: NavigationBarItem.TitleDisplayMode,
|
||||
) -> some View {
|
||||
modifier(NavigationBarViewModifier(
|
||||
title: title,
|
||||
navigationBarTitleDisplayMode: titleDisplayMode,
|
||||
))
|
||||
}
|
||||
|
||||
/// Returns a floating action button positioned at the bottom-right corner of the screen.
|
||||
///
|
||||
/// - Parameters:
|
||||
|
||||
@ -443,16 +443,3 @@ class VaultItemCoordinator: NSObject, Coordinator, HasStackNavigator { // swiftl
|
||||
extension VaultItemCoordinator: HasErrorAlertServices {
|
||||
var errorAlertServices: ErrorAlertServices { services }
|
||||
}
|
||||
|
||||
// MARK: - View Extension
|
||||
|
||||
extension View {
|
||||
@ViewBuilder var navStackWrapped: some View {
|
||||
if #available(iOSApplicationExtension 16.0, *) {
|
||||
NavigationStack { self }
|
||||
} else {
|
||||
NavigationView { self }
|
||||
.navigationViewStyle(.stack)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user