import SwiftUI /// An adaptable stack view that switches between `HStack` and `VStack` based on the dynamic text size. struct AdaptableStack: View where Content: View { @Environment(\.dynamicTypeSize) private var size: DynamicTypeSize /// The primary axis along which the stack arranges its children. private var axis: StackAxis /// The dynamic type size threshold above which the stack axis will switch. private var sizeThreshold: DynamicTypeSize /// Alignment of children along the X-axis for vertical stack. private var vAlignment: HorizontalAlignment /// Spacing between children for vertical stack. private var vSpacing: CGFloat? /// Alignment of children along the Y-axis for horizontal stack. private var hAlignment: VerticalAlignment /// Spacing between children for horizontal stack. private var hSpacing: CGFloat? /// Closure providing the stack's content. private var content: () -> Content /// Creates an `AdaptableStack` with the given properties. /// /// - Parameters: /// - axis: The primary axis for the stack (`vertical` or `horizontal`). /// - sizeThreshold: The size above which to switch the axis. Default is `.accessibility1`. /// - vAlignment: The X-axis alignment for a vertical stack. Default is `.center`. /// - vSpacing: The spacing for a vertical stack. Default is `nil`. /// - hAlignment: The Y-axis alignment for a horizontal stack. Default is `.center`. /// - hSpacing: The spacing for a horizontal stack. Default is `nil`. /// - content: The content of the stack. init( _ axis: StackAxis, sizeThreshold: DynamicTypeSize = .accessibility1, vAlignment: HorizontalAlignment = .center, vSpacing: CGFloat? = nil, hAlignment: VerticalAlignment = .center, hSpacing: CGFloat? = nil, @ViewBuilder content: @escaping () -> Content ) { self.axis = axis self.sizeThreshold = sizeThreshold self.vAlignment = vAlignment self.vSpacing = vSpacing self.hAlignment = hAlignment self.hSpacing = hSpacing self.content = content } var body: some View { layout { content() } } } extension AdaptableStack { /// Enum to represent the primary axis for the stack. enum StackAxis { case vertical case horizontal } } private extension AdaptableStack { /// Determines the layout to use based on the `axis` and `size`. var layout: AnyLayout { switch axis { case .vertical: return size > threshold ? AnyLayout(HStackLayout(alignment: hAlignment, spacing: hSpacing)) : AnyLayout(VStackLayout(alignment: vAlignment, spacing: vSpacing)) case .horizontal: return size > threshold ? AnyLayout(VStackLayout(alignment: vAlignment, spacing: vSpacing)) : AnyLayout(HStackLayout(alignment: hAlignment, spacing: hSpacing)) } } }