diff --git a/Sources/OversizeUI/Controls/HUD/HUD.swift b/Sources/OversizeUI/Controls/HUD/HUD.swift
index 96c5f30..0f31dbb 100644
--- a/Sources/OversizeUI/Controls/HUD/HUD.swift
+++ b/Sources/OversizeUI/Controls/HUD/HUD.swift
@@ -1,52 +1,50 @@
//
// Copyright © 2023 Alexander Romanov
// File.swift, created on 22.05.2023
-//
+//
import SwiftUI
public struct HUD
: View where Title: View, Icon: View {
-
@Environment(\.screenSize) var screenSize
-
+
private let text: String?
-
+
private let title: Title?
private let icon: Icon?
-
+
private let isAutoHide: Bool
-
+
@Binding private var isPresented: Bool
-
+
@State private var bottomOffset: CGFloat = 0
@State private var opacity: CGFloat = 0
-
+
// MARK: Initializers
+
public init(
autoHide: Bool = true,
isPresented: Binding,
@ViewBuilder title: () -> Title,
@ViewBuilder icon: () -> Icon
) {
- self._isPresented = isPresented
- self.text = nil
+ _isPresented = isPresented
+ text = nil
self.title = title()
self.icon = icon()
- self.isAutoHide = autoHide
+ isAutoHide = autoHide
}
-
-
+
public var body: some View {
HStack(spacing: .xSmall) {
if icon != nil {
icon
}
if let text {
-
Text(text)
.body(.medium)
.foregroundColor(.onSurfaceHighEmphasis)
-
+
} else if let title {
title
}
@@ -70,7 +68,7 @@ public struct HUD: View where Title: View, Icon: View {
}
})
}
-
+
private func presentAnimated() {
withAnimation {
bottomOffset = 0
@@ -84,7 +82,7 @@ public struct HUD: View where Title: View, Icon: View {
}
}
}
-
+
private func dismissAnimated() {
withAnimation {
bottomOffset = -200
@@ -99,11 +97,11 @@ public extension HUD where Title == EmptyView, Icon == EmptyView {
autoHide: Bool = true,
isPresented: Binding
) {
- self._isPresented = isPresented
+ _isPresented = isPresented
self.text = text
- self.title = nil
- self.icon = nil
- self.isAutoHide = autoHide
+ title = nil
+ icon = nil
+ isAutoHide = autoHide
}
}
@@ -114,10 +112,10 @@ public extension HUD where Title == EmptyView {
isPresented: Binding,
@ViewBuilder icon: () -> Icon
) {
- self._isPresented = isPresented
+ _isPresented = isPresented
self.text = text
- self.title = nil
- self.isAutoHide = autoHide
+ title = nil
+ isAutoHide = autoHide
self.icon = icon()
}
}
@@ -128,41 +126,41 @@ public extension HUD where Icon == EmptyView {
isPresented: Binding,
@ViewBuilder title: () -> Title
) {
- self._isPresented = isPresented
- self.text = nil
+ _isPresented = isPresented
+ text = nil
self.title = title()
- self.icon = nil
- self.isAutoHide = autoHide
+ icon = nil
+ isAutoHide = autoHide
}
}
public extension View {
func hud(_ text: String, isPresented: Binding) -> some View {
- self.overlay(alignment: .top) {
+ overlay(alignment: .top) {
HUD(text, isPresented: isPresented)
}
}
-
- func hud(_ text: String, isPresented: Binding, @ViewBuilder icon: () -> Icon) -> some View {
- self.overlay(alignment: .top) {
+
+ func hud(_ text: String, isPresented: Binding, @ViewBuilder icon: () -> some View) -> some View {
+ overlay(alignment: .top) {
HUD(text, isPresented: isPresented, icon: icon)
}
}
-
- func hud(isPresented: Binding, @ViewBuilder title: () -> Title) -> some View {
- self.overlay(alignment: .top) {
+
+ func hud(isPresented: Binding, @ViewBuilder title: () -> some View) -> some View {
+ overlay(alignment: .top) {
HUD(isPresented: isPresented, title: title)
}
}
-
- func hud(isPresented: Binding, @ViewBuilder title: () -> Title, @ViewBuilder icon: () -> Icon) -> some View {
- self.overlay(alignment: .top) {
+
+ func hud(isPresented: Binding, @ViewBuilder title: () -> some View, @ViewBuilder icon: () -> some View) -> some View {
+ overlay(alignment: .top) {
HUD(isPresented: isPresented, title: title, icon: icon)
}
}
-
+
func hudLoader(_ text: String = "Loading", isPresented: Binding) -> some View {
- self.overlay(alignment: .top) {
+ overlay(alignment: .top) {
HUD(text, autoHide: false, isPresented: isPresented) {
ProgressView()
}
diff --git a/Sources/OversizeUI/Controls/Loader/LoaderOverlayView.swift b/Sources/OversizeUI/Controls/Loader/LoaderOverlayView.swift
index 7375ad6..cc9d37d 100644
--- a/Sources/OversizeUI/Controls/Loader/LoaderOverlayView.swift
+++ b/Sources/OversizeUI/Controls/Loader/LoaderOverlayView.swift
@@ -18,7 +18,6 @@ public struct LoaderOverlayView: View {
private let isShowBackground: Bool
@Binding var isLoading: Bool
-
@State private var jump = false
@State private var rotationImage = false
@@ -48,28 +47,11 @@ public struct LoaderOverlayView: View {
}
public var body: some View {
+ VStack {
+ Spacer()
-
- VStack {
- Spacer()
-
- if surface {
- Surface {
- VStack(spacing: 20) {
- containedView()
-
- if showText {
- Text(text.isEmpty ? "Loading" : text)
- .headline(.semibold)
- .onSurfaceDisabledForegroundColor()
- .offset(y: 8)
- }
- }
- .padding()
- }
- .surfaceStyle(.primary)
- .elevation(.z4)
- } else {
+ if surface {
+ Surface {
VStack(spacing: 20) {
containedView()
@@ -81,24 +63,39 @@ public struct LoaderOverlayView: View {
}
}
.padding()
- .background {
- Capsule()
- .fillSurfaceSecondary()
+ }
+ .surfaceStyle(.primary)
+ .elevation(.z4)
+ } else {
+ VStack(spacing: 20) {
+ containedView()
+
+ if showText {
+ Text(text.isEmpty ? "Loading" : text)
+ .headline(.semibold)
+ .onSurfaceDisabledForegroundColor()
+ .offset(y: 8)
}
}
-
- Spacer()
+ .padding()
+ .background {
+ Capsule()
+ .fillSurfaceSecondary()
+ }
}
- .frame(
- maxWidth: .infinity,
- maxHeight: .infinity,
- alignment: .center
- )
- .background(
- .ultraThinMaterial.opacity(isShowBackground ? 1 : 0),
- ignoresSafeAreaEdges: .all
- )
- .opacity(isLoading ? 1 : 0)
+
+ Spacer()
+ }
+ .frame(
+ maxWidth: .infinity,
+ maxHeight: .infinity,
+ alignment: .center
+ )
+ .background(
+ .ultraThinMaterial.opacity(isShowBackground ? 1 : 0),
+ ignoresSafeAreaEdges: .all
+ )
+ .opacity(isLoading ? 1 : 0)
}
@ViewBuilder
@@ -134,7 +131,7 @@ public struct LoaderOverlayView: View {
public extension View {
func loader(_ text: String? = nil, isPresented: Binding) -> some View {
- self.overlay {
+ overlay {
LoaderOverlayView(text: text ?? "", isLoading: isPresented)
}
}
diff --git a/Sources/OversizeUI/Controls/Row/Row.swift b/Sources/OversizeUI/Controls/Row/Row.swift
index efc0e2d..8d7c67a 100644
--- a/Sources/OversizeUI/Controls/Row/Row.swift
+++ b/Sources/OversizeUI/Controls/Row/Row.swift
@@ -7,14 +7,13 @@ import SwiftUI
public protocol RowLeadingContentProtocol: View {}
-public struct RowLeadingContent: View {// where Content: View {
-
+public struct RowLeadingContent: View { // where Content: View {
private let content: Content
-
+
public init(@ViewBuilder content: () -> Content) {
self.content = content()
}
-
+
public var body: some View {
content
}
@@ -35,7 +34,7 @@ public struct Row: View where LeadingLabel: View, T
private let title: String
private let subtitle: String?
-
+
private let leadingSize: CGSize?
private let leadingRadius: CGFloat?
@@ -149,8 +148,6 @@ public struct Row: View where LeadingLabel: View, T
}
.padding(controlPadding)
}
-
-
private var text: some View {
VStack(alignment: textAlignment, spacing: .zero) {
@@ -204,9 +201,62 @@ public struct Row: View where LeadingLabel: View, T
}
}
+// MARK: - Modificators
+
+public extension Row {
+ func premium(_ premium: Bool = true) -> Row {
+ var control = self
+ control.isPremiumOption = premium
+ return control
+ }
+
+ func rowArrow(_ showArrowIcon: Bool = true) -> Row {
+ var control = self
+ control.isShowArrowIcon = showArrowIcon
+ return control
+ }
+
+ func rowIconBackgroundColor(_ color: Color?) -> Row {
+ var control = self
+ control.iconBackgroundColor = color
+ return control
+ }
+
+ func rowClearButton(style: RowClearIconStyle = .default, action: (() -> Void)?) -> Row {
+ var control = self
+ control.сlearButtonStyle = style
+ control.сlearAction = action
+ return control
+ }
+
+ @available(*, deprecated, message: "Use leading: {} and tralling: {}")
+ func rowLeading(_ leading: RowLeadingType?) -> Row {
+ var control = self
+ control.leadingType = leading
+ return control
+ }
+
+ @available(*, deprecated, message: "Use leading: {} and tralling: {}")
+ func rowTrailing(_ trailing: RowTrailingType?) -> Row {
+ var control = self
+ control.trallingType = trailing
+ return control
+ }
+}
+
+public extension View {
+ func rowOnSurface(_ elevation: Elevation = .z4, backgroundColor: Color? = nil) -> some View {
+ Surface {
+ self.rowContentInset(.zero)
+ }
+ .surfaceBackgroundColor(backgroundColor)
+ .elevation(elevation)
+ }
+}
+
// MARK: - Icon init
-public extension Row where LeadingLabel == Icon {
+public extension Row where LeadingLabel == Icon, TrailingLabel: View {
init(_ title: String,
subtitle: String? = nil,
action: (() -> Void)? = nil,
@@ -251,7 +301,7 @@ public extension Row where LeadingLabel == Image, TrailingLabel == EmptyView {
{
self.title = title
self.subtitle = subtitle
- self.action = nil
+ action = nil
leadingLabel = leading().resizable()
trailingLabel = nil
leadingSize = .init(
@@ -270,7 +320,7 @@ public extension Row where LeadingLabel == Image {
{
self.title = title
self.subtitle = subtitle
- self.action = nil
+ action = nil
leadingLabel = leading()
.resizable()
trailingLabel = trailing()
@@ -294,7 +344,7 @@ public extension Row where LeadingLabel == Image {
self.action = action
leadingLabel = leading()
.resizable()
- //.renderingMode(.template)
+ // .renderingMode(.template)
trailingLabel = trailing()
leadingSize = .init(
width: subtitle == nil ? 24 : 48,
@@ -366,59 +416,6 @@ public extension Row where LeadingLabel == EmptyView {
}
}
-// MARK: - Modificators
-
-public extension Row {
- func premium(_ premium: Bool = true) -> Row {
- var control = self
- control.isPremiumOption = premium
- return control
- }
-
- func rowArrow(_ showArrowIcon: Bool = true) -> Row {
- var control = self
- control.isShowArrowIcon = showArrowIcon
- return control
- }
-
- func rowIconBackgroundColor(_ color: Color?) -> Row {
- var control = self
- control.iconBackgroundColor = color
- return control
- }
-
- func rowClearButton(style: RowClearIconStyle = .default, action: (() -> Void)?) -> Row {
- var control = self
- control.сlearButtonStyle = style
- control.сlearAction = action
- return control
- }
-
- @available(*, deprecated, message: "Use leading: {} and tralling: {}")
- func rowLeading(_ leading: RowLeadingType?) -> Row {
- var control = self
- control.leadingType = leading
- return control
- }
-
- @available(*, deprecated, message: "Use leading: {} and tralling: {}")
- func rowTrailing(_ trailing: RowTrailingType?) -> Row {
- var control = self
- control.trallingType = trailing
- return control
- }
-}
-
-public extension View {
- func rowOnSurface(_ elevation: Elevation = .z4, backgroundColor: Color? = nil) -> some View {
- Surface {
- self.rowContentInset(.zero)
- }
- .surfaceBackgroundColor(backgroundColor)
- .elevation(elevation)
- }
-}
-
// MARK: - Preview
// swiftlint:disable all
diff --git a/Sources/OversizeUI/Controls/Surface/Surface.swift b/Sources/OversizeUI/Controls/Surface/Surface.swift
index d327803..6babfa4 100644
--- a/Sources/OversizeUI/Controls/Surface/Surface.swift
+++ b/Sources/OversizeUI/Controls/Surface/Surface.swift
@@ -20,6 +20,8 @@ public struct Surface: View {
@Environment(\.surfaceContentInsets) var contentInsets: EdgeSpaceInsets
@Environment(\.isAccent) private var isAccent: Bool
+ let forceContentInsets: EdgeSpaceInsets?
+
private enum Constants {
/// Colors
static var colorPrimary: Color { Color.surfacePrimary }
@@ -39,45 +41,8 @@ public struct Surface: View {
{
self.label = label()
self.action = action
+ forceContentInsets = nil
}
-
-
- public init(
- action: (() -> Void)? = nil,
- @ViewBuilder label: () -> Label) where Label == Row, LeadingLabel: View, TrailingLabel: View {
- self.label = label()
- self.action = action
- self.backgroundColor = .red
- }
-
- public init(
- @ViewBuilder label: () -> Label) where Label == Row, LeadingLabel: View, TrailingLabel: View {
- self.label = label()
- self.action = nil
- self.backgroundColor = .red
- }
-
-// public init(
-// @ViewBuilder label: () -> Label) where Label == Row, LeadingLabel: View, TrailingLabel: Never {
-// self.label = label()
-// self.action = nil
-// self.backgroundColor = .red
-// }
-
-// public init(
-// action: (() -> Void)? = nil,
-// @ViewBuilder label: () -> Label) where Label == Row, LeadingLabel: View, TrailingLabel: View
-// {
-// self.label = label()
-// self.action = action
-// self.backgroundColor = .red
-// }
-
-// public init(
-// url: URL?,
-// scale: CGFloat = 1,
-// @ViewBuilder content: @escaping (Image) -> I,
-// @ViewBuilder placeholder: @escaping () -> P) where Content == _ConditionalContent, I : View, P : View
public var body: some View {
if action != nil {
@@ -98,10 +63,10 @@ public struct Surface: View {
private var surface: some View {
label
- .padding(.top, contentInsets.top)
- .padding(.bottom, contentInsets.bottom)
- .padding(.leading, contentInsets.leading)
- .padding(.trailing, contentInsets.trailing)
+ .padding(.top, forceContentInsets?.top ?? contentInsets.top)
+ .padding(.bottom, forceContentInsets?.bottom ?? contentInsets.bottom)
+ .padding(.leading, forceContentInsets?.leading ?? contentInsets.leading)
+ .padding(.trailing, forceContentInsets?.trailing ?? contentInsets.trailing)
.background(
RoundedRectangle(cornerRadius: surfaceRadius, style: .continuous)
.fill(surfaceBackgroundColor)
@@ -189,138 +154,6 @@ public struct SurfaceButtonStyle: ButtonStyle {
}
}
-// extension Optional : View where Wrapped : View {
-//Anchor : Hashable where Value : Hashable {
-
-// where Content == PresentedWindowContent, D : Decodable, D : Encodable, D : Hashable, C : View
-// public init(id: String, for type: D.Type, @ViewBuilder content: @escaping (Binding) -> C) where Content == PresentedWindowContent, D : Decodable, D : Encodable, D : Hashable, C : View
-//public extension Surface where Label == Row {
-
-//extension ExclusiveGesture.Value : Equatable where First.Value : Equatable, Second.Value : Equatable {
-
-// init(
-// action: (() -> Void)? = nil,
-// @ViewBuilder label: @escaping () -> (LeadingLabel, TrailingLabel)) where Label == Row, LeadingLabel: View, TrailingLabel : View
-
-//public extension Surface where Label == Row: View, LeadingLabel: View, TrailingLabel: View {
-//extension ForEach where Data == Range, ID == Int, Content : View {
-//
-//
-// extension ForEach where Data == Range, ID == Int, Content : View {
-//
-// /// Creates an instance that computes views on demand over a given constant
-// /// range.
-// ///
-// /// The instance only reads the initial value of the provided `data` and
-// /// doesn't need to identify views across updates. To compute views on
-// /// demand over a dynamic range, use ``ForEach/init(_:id:content:)``.
-// ///
-// /// - Parameters:
-// /// - data: A constant range.
-// /// - content: The view builder that creates views dynamically.
-// public init(_ data: Range, @ViewBuilder content: @escaping (Int) -> Content)
-// }
-
-////extension Surface where Label == Row: View, TrailingLabel: View> {
-//
-//extension Surface where Label == Row {
-//
-// public init(
-// action: (() -> Void)? = nil,
-// @ViewBuilder label: () -> Label) where Label == Row, LeadingLabel : View, TrailingLabel : View {
-// self.label = label()
-// self.action = action
-// self.backgroundColor = .red
-// }
-//}
-
-//extension Surface: View where Label == VStack> {
-//
-// public init(action: (() -> Void)? = nil,
-// @ViewBuilder label: () -> Label)
-// {
-// self.label = label()
-// self.action = action
-// self.backgroundColor = .red
-// }
-//}
-
-
-//extension Surface where Label == VStack> {
-//
-// public init(action: (() -> Void)? = nil,
-// @ViewBuilder label: () -> Label)
-// {
-// self.label = label()
-// self.action = action
-// self.backgroundColor = .red
-// }
-//}
-
-//extension Surface where Label == Row, LeadingLabel: View, TrailingLabel: View {
-// public init(
-// @ViewBuilder label: () -> Label) where Label == Row, LeadingLabel: View, TrailingLabel: View {
-// self.label = label()
-// self.action = nil
-// self.backgroundColor = .red
-// }
-//}
-
-//extension Surface where Label == Row {
-//
-// public init(action: (() -> Void)? = nil,
-// @ViewBuilder label: () -> Label)
-// {
-// self.label = label()
-// self.action = action
-// self.backgroundColor = .red
-// }
-//
-//}
-
-//extension Surface where Label == Row, A: View, B: View {
-//
-//}
-
-//extension Surface where Label == Row {
-//
-// public init(_ title: String,
-// subtitle: String? = nil,
-// action: (() -> Void)? = nil,
-// @ViewBuilder leading: () -> LeadingLabel,
-// @ViewBuilder trailing: () -> TrailingLabel)
-// {
-// self.title = title
-// self.subtitle = subtitle
-// self.action = action
-// leadingLabel = leading()
-// trailingLabel = trailing()
-// leadingSize = nil
-// leadingRadius = nil
-//
-//}
-
-
-//public struct Row: View where LeadingLabel: View, TrailingLabel: View {
-
-//public init(_ title: String,
-// subtitle: String? = nil,
-// action: (() -> Void)? = nil,
-// @ViewBuilder leading: () -> LeadingLabel,
-// @ViewBuilder trailing: () -> TrailingLabel)
-//{
-// self.title = title
-// self.subtitle = subtitle
-// self.action = action
-// leadingLabel = leading()
-// trailingLabel = trailing()
-// leadingSize = nil
-// leadingRadius = nil
-//}
-
-//extension TableColumn where RowValue == Sort.Compared, Label == Text {
-
-// swiftlint:disable opening_brace
public extension View {
func surface() -> some View {
Surface { self }
@@ -364,6 +197,26 @@ public extension View {
}
}
+public extension Surface where Label == VStack, Row)>> {
+ init(action: (() -> Void)? = nil,
+ @ViewBuilder label: () -> Label)
+ {
+ self.label = label()
+ self.action = action
+ forceContentInsets = .init(horizontal: .zero, vertical: .small)
+ }
+}
+
+public extension Surface where Label == Row {
+ init(action: (() -> Void)? = nil,
+ @ViewBuilder label: () -> Label)
+ {
+ self.label = label()
+ self.action = action
+ forceContentInsets = .init(horizontal: .zero, vertical: .small)
+ }
+}
+
struct Surface_Previews: PreviewProvider {
static var previews: some View {
VStack {
diff --git a/Sources/OversizeUI/Controls/Toast/Snackbar.swift b/Sources/OversizeUI/Controls/Toast/Snackbar.swift
index 9fb08d7..391a529 100644
--- a/Sources/OversizeUI/Controls/Toast/Snackbar.swift
+++ b/Sources/OversizeUI/Controls/Toast/Snackbar.swift
@@ -1,52 +1,49 @@
//
// Copyright © 2023 Alexander Romanov
// Snackbar.swift, created on 21.05.2023
-//
+//
import SwiftUI
public struct Snackbar