diff --git a/Examples/DemosApp/DemosApp/ComponentsPreview/Helpers/ModalPreview+Helpers.swift b/Examples/DemosApp/DemosApp/ComponentsPreview/Helpers/ModalPreview+Helpers.swift index feba64d7..32755715 100644 --- a/Examples/DemosApp/DemosApp/ComponentsPreview/Helpers/ModalPreview+Helpers.swift +++ b/Examples/DemosApp/DemosApp/ComponentsPreview/Helpers/ModalPreview+Helpers.swift @@ -65,6 +65,7 @@ struct ModalPreviewHelpers { Text("Warning Background").tag(ComponentColor.warning.background) Text("Danger Background").tag(ComponentColor.danger.background) } + BorderWidthPicker(selection: self.$model.borderWidth) Toggle("Closes On Overlay Tap", isOn: self.$model.closesOnOverlayTap) .disabled(self.footer == nil) Picker("Outer Paddings", selection: self.$model.outerPaddings) { diff --git a/Examples/DemosApp/DemosApp/ComponentsPreview/Helpers/PreviewPickers.swift b/Examples/DemosApp/DemosApp/ComponentsPreview/Helpers/PreviewPickers.swift index 46c3b0fe..4645fa94 100644 --- a/Examples/DemosApp/DemosApp/ComponentsPreview/Helpers/PreviewPickers.swift +++ b/Examples/DemosApp/DemosApp/ComponentsPreview/Helpers/PreviewPickers.swift @@ -32,6 +32,21 @@ struct AutocapitalizationPicker: View { } } +// MARK: - BorderWidthPicker + +struct BorderWidthPicker: View { + @Binding var selection: BorderWidth + + var body: some View { + Picker("Border Width", selection: self.$selection) { + Text("None").tag(BorderWidth.none) + Text("Small").tag(BorderWidth.small) + Text("Medium").tag(BorderWidth.medium) + Text("Large").tag(BorderWidth.large) + } + } +} + // MARK: - ComponentColorPicker struct ComponentColorPicker: View { diff --git a/Examples/DemosApp/DemosApp/ComponentsPreview/PreviewPages/AlertPreview.swift b/Examples/DemosApp/DemosApp/ComponentsPreview/PreviewPages/AlertPreview.swift index 72b919b2..e791b250 100644 --- a/Examples/DemosApp/DemosApp/ComponentsPreview/PreviewPages/AlertPreview.swift +++ b/Examples/DemosApp/DemosApp/ComponentsPreview/PreviewPages/AlertPreview.swift @@ -89,6 +89,7 @@ struct AlertPreview: View { Text("Warning Background").tag(ComponentColor.warning.background) Text("Danger Background").tag(ComponentColor.danger.background) } + BorderWidthPicker(selection: self.$model.borderWidth) Toggle("Closes On Overlay Tap", isOn: self.$model.closesOnOverlayTap) Picker("Content Paddings", selection: self.$model.contentPaddings) { Text("12px").tag(Paddings(padding: 12)) diff --git a/Examples/DemosApp/DemosApp/ComponentsPreview/PreviewPages/CardPreview.swift b/Examples/DemosApp/DemosApp/ComponentsPreview/PreviewPages/CardPreview.swift index 33a4ebf2..c64ae340 100644 --- a/Examples/DemosApp/DemosApp/ComponentsPreview/PreviewPages/CardPreview.swift +++ b/Examples/DemosApp/DemosApp/ComponentsPreview/PreviewPages/CardPreview.swift @@ -23,6 +23,7 @@ struct CardPreview: View { Text("Warning Background").tag(ComponentColor.warning.background) Text("Danger Background").tag(ComponentColor.danger.background) } + BorderWidthPicker(selection: self.$model.borderWidth) Picker("Content Paddings", selection: self.$model.contentPaddings) { Text("12px").tag(Paddings(padding: 12)) Text("16px").tag(Paddings(padding: 16)) diff --git a/Sources/ComponentsKit/Components/Alert/Models/AlertVM.swift b/Sources/ComponentsKit/Components/Alert/Models/AlertVM.swift index 1f1fcc41..3fdbd192 100644 --- a/Sources/ComponentsKit/Components/Alert/Models/AlertVM.swift +++ b/Sources/ComponentsKit/Components/Alert/Models/AlertVM.swift @@ -21,6 +21,11 @@ public struct AlertVM: ComponentVM { /// The background color of the modal. public var backgroundColor: UniversalColor? + /// The border thickness of the alert. + /// + /// Defaults to `.small`. + public var borderWidth: BorderWidth = .small + /// A Boolean value indicating whether the modal should close when tapping on the overlay. /// /// Defaults to `false`. @@ -56,6 +61,7 @@ extension AlertVM { var modalVM: CenterModalVM { return CenterModalVM { $0.backgroundColor = self.backgroundColor + $0.borderWidth = self.borderWidth $0.closesOnOverlayTap = self.closesOnOverlayTap $0.contentPaddings = self.contentPaddings $0.cornerRadius = self.cornerRadius diff --git a/Sources/ComponentsKit/Components/Card/Models/CardVM.swift b/Sources/ComponentsKit/Components/Card/Models/CardVM.swift index 9834cdae..a6baf586 100644 --- a/Sources/ComponentsKit/Components/Card/Models/CardVM.swift +++ b/Sources/ComponentsKit/Components/Card/Models/CardVM.swift @@ -5,6 +5,11 @@ public struct CardVM: ComponentVM { /// The background color of the card. public var backgroundColor: UniversalColor? + /// The border thickness of the card. + /// + /// Defaults to `.medium`. + public var borderWidth: BorderWidth = .medium + /// The padding applied to the card's content area. /// /// Defaults to a padding value of `16` for all sides. diff --git a/Sources/ComponentsKit/Components/Card/SUCard.swift b/Sources/ComponentsKit/Components/Card/SUCard.swift index bfea52e4..77127a48 100644 --- a/Sources/ComponentsKit/Components/Card/SUCard.swift +++ b/Sources/ComponentsKit/Components/Card/SUCard.swift @@ -44,7 +44,7 @@ public struct SUCard: View { .cornerRadius(self.model.cornerRadius.value) .overlay( RoundedRectangle(cornerRadius: self.model.cornerRadius.value) - .stroke(UniversalColor.divider.color, lineWidth: 1.0) + .stroke(UniversalColor.divider.color, lineWidth: self.model.borderWidth.value) ) .shadow(self.model.shadow) } diff --git a/Sources/ComponentsKit/Components/Card/UKCard.swift b/Sources/ComponentsKit/Components/Card/UKCard.swift index 2864b9b7..d3ddea83 100644 --- a/Sources/ComponentsKit/Components/Card/UKCard.swift +++ b/Sources/ComponentsKit/Components/Card/UKCard.swift @@ -140,7 +140,7 @@ extension UKCard { static func mainView(_ view: UIView, model: Model) { view.backgroundColor = UniversalColor.background.uiColor view.layer.cornerRadius = model.cornerRadius.value - view.layer.borderWidth = 1 + view.layer.borderWidth = model.borderWidth.value view.layer.borderColor = UniversalColor.divider.cgColor view.layer.shadowRadius = model.shadow.radius view.layer.shadowOffset = model.shadow.offset diff --git a/Sources/ComponentsKit/Components/Modal/Models/BottomModalVM.swift b/Sources/ComponentsKit/Components/Modal/Models/BottomModalVM.swift index d4edd9dd..b2fed090 100644 --- a/Sources/ComponentsKit/Components/Modal/Models/BottomModalVM.swift +++ b/Sources/ComponentsKit/Components/Modal/Models/BottomModalVM.swift @@ -5,6 +5,11 @@ public struct BottomModalVM: ModalVM { /// The background color of the modal. public var backgroundColor: UniversalColor? + /// The border thickness of the modal. + /// + /// Defaults to `.small`. + public var borderWidth: BorderWidth = .small + /// A Boolean value indicating whether the modal should close when tapping on the overlay. /// /// Defaults to `true`. diff --git a/Sources/ComponentsKit/Components/Modal/Models/CenterModalVM.swift b/Sources/ComponentsKit/Components/Modal/Models/CenterModalVM.swift index 2cb39cf9..17af179b 100644 --- a/Sources/ComponentsKit/Components/Modal/Models/CenterModalVM.swift +++ b/Sources/ComponentsKit/Components/Modal/Models/CenterModalVM.swift @@ -5,6 +5,11 @@ public struct CenterModalVM: ModalVM { /// The background color of the modal. public var backgroundColor: UniversalColor? + /// The border thickness of the modal. + /// + /// Defaults to `.small`. + public var borderWidth: BorderWidth = .small + /// A Boolean value indicating whether the modal should close when tapping on the overlay. /// /// Defaults to `true`. diff --git a/Sources/ComponentsKit/Components/Modal/Models/ModalVM.swift b/Sources/ComponentsKit/Components/Modal/Models/ModalVM.swift index 96b1b9c9..55af7ea3 100644 --- a/Sources/ComponentsKit/Components/Modal/Models/ModalVM.swift +++ b/Sources/ComponentsKit/Components/Modal/Models/ModalVM.swift @@ -5,6 +5,9 @@ public protocol ModalVM: ComponentVM { /// The background color of the modal. var backgroundColor: UniversalColor? { get set } + /// The border thickness of the modal. + var borderWidth: BorderWidth { get set } + /// A Boolean value indicating whether the modal should close when tapping on the overlay. var closesOnOverlayTap: Bool { get set } diff --git a/Sources/ComponentsKit/Components/Modal/SwiftUI/ModalContent.swift b/Sources/ComponentsKit/Components/Modal/SwiftUI/ModalContent.swift index 7e38352f..f3e66db3 100644 --- a/Sources/ComponentsKit/Components/Modal/SwiftUI/ModalContent.swift +++ b/Sources/ComponentsKit/Components/Modal/SwiftUI/ModalContent.swift @@ -60,9 +60,11 @@ struct ModalContent: View { .frame(maxWidth: self.model.size.maxWidth, alignment: .leading) .background(self.model.preferredBackgroundColor.color) .background(UniversalColor.background.color) - .clipShape(RoundedRectangle( - cornerRadius: self.model.cornerRadius.value - )) + .clipShape(RoundedRectangle(cornerRadius: self.model.cornerRadius.value)) + .overlay( + RoundedRectangle(cornerRadius: self.model.cornerRadius.value) + .stroke(UniversalColor.divider.color, lineWidth: self.model.borderWidth.value) + ) .padding(self.model.outerPaddings.edgeInsets) } diff --git a/Sources/ComponentsKit/Components/Modal/UIKit/UKModalController.swift b/Sources/ComponentsKit/Components/Modal/UIKit/UKModalController.swift index 4957dbc3..7d3b9c39 100644 --- a/Sources/ComponentsKit/Components/Modal/UIKit/UKModalController.swift +++ b/Sources/ComponentsKit/Components/Modal/UIKit/UKModalController.swift @@ -86,6 +86,12 @@ open class UKModalController: UIViewController { target: self, action: #selector(self.handleOverlayTap) )) + + if #available(iOS 17.0, *) { + self.registerForTraitChanges([UITraitUserInterfaceStyle.self]) { (controller: Self, _: UITraitCollection) in + controller.handleTraitChanges() + } + } } @objc func handleOverlayTap() { @@ -188,6 +194,21 @@ open class UKModalController: UIViewController { } self.containerWidthConstraint?.isActive = true } + + // MARK: - UIViewController Methods + + open override func traitCollectionDidChange( + _ previousTraitCollection: UITraitCollection? + ) { + super.traitCollectionDidChange(previousTraitCollection) + self.handleTraitChanges() + } + + // MARK: - Helpers + + @objc private func handleTraitChanges() { + Self.Style.content(self.content, model: self.model) + } } // MARK: - Style Helpers @@ -211,7 +232,8 @@ extension UKModalController { static func content(_ view: UIView, model: VM) { view.backgroundColor = model.preferredBackgroundColor.uiColor view.layer.cornerRadius = model.cornerRadius.value - view.clipsToBounds = true + view.layer.borderColor = UniversalColor.divider.cgColor + view.layer.borderWidth = model.borderWidth.value } static func bodyWrapper(_ scrollView: UIScrollView) { scrollView.delaysContentTouches = false diff --git a/Sources/ComponentsKit/Configuration/Layout.swift b/Sources/ComponentsKit/Configuration/Layout.swift index e3c54d31..24c83a28 100644 --- a/Sources/ComponentsKit/Configuration/Layout.swift +++ b/Sources/ComponentsKit/Configuration/Layout.swift @@ -243,9 +243,9 @@ extension ComponentsKitConfig { /// The border width configuration for components. public var borderWidth: BorderWidth = .init( - small: 1.0, - medium: 2.0, - large: 3.0 + small: 0.5, + medium: 1.0, + large: 2.0 ) /// The animation scale configuration for components. diff --git a/Sources/ComponentsKit/Shared/Types/BorderWidth.swift b/Sources/ComponentsKit/Shared/Types/BorderWidth.swift index f5bd6d32..2ebb7082 100644 --- a/Sources/ComponentsKit/Shared/Types/BorderWidth.swift +++ b/Sources/ComponentsKit/Shared/Types/BorderWidth.swift @@ -2,6 +2,8 @@ import Foundation /// An enumeration that defines border thickness for components. public enum BorderWidth: Hashable { + /// No border. + case none /// A small border width. case small /// A medium border width. @@ -14,6 +16,8 @@ extension BorderWidth { /// The numeric value of the border width as a `CGFloat`. public var value: CGFloat { switch self { + case .none: + return 0.0 case .small: return ComponentsKitConfig.shared.layout.borderWidth.small case .medium: