diff --git a/Sources/OpenSwiftUI/Layout/LayoutFundamentals/Separators/Divider.swift b/Sources/OpenSwiftUI/Layout/LayoutFundamentals/Separators/Divider.swift new file mode 100644 index 0000000..0a73ad9 --- /dev/null +++ b/Sources/OpenSwiftUI/Layout/LayoutFundamentals/Separators/Divider.swift @@ -0,0 +1,14 @@ +// +// Divider.swift +// OpenSwiftUI +// +// Audited for RELEASE_2021 +// Status: TODO + +/// A visual element that can be used to separate other content. +/// +/// When contained in a stack, the divider extends across the minor axis of the +/// stack, or horizontally when not in a stack. +public struct Divider: UnaryView, PrimitiveView { + public init() {} +} diff --git a/Sources/OpenSwiftUI/Layout/LayoutFundamentals/Separators/Spacer.swift b/Sources/OpenSwiftUI/Layout/LayoutFundamentals/Separators/Spacer.swift new file mode 100644 index 0000000..20c35d6 --- /dev/null +++ b/Sources/OpenSwiftUI/Layout/LayoutFundamentals/Separators/Spacer.swift @@ -0,0 +1,124 @@ +// +// Spacer.swift +// OpenSwiftUI +// +// Audited for RELEASE_2021 +// Status: TODO + +import Foundation + +/// A flexible space that expands along the major axis of its containing stack +/// layout, or on both axes if not contained in a stack. +/// +/// A spacer creates an adaptive view with no content that expands as much as +/// it can. For example, when placed within an ``HStack``, a spacer expands +/// horizontally as much as the stack allows, moving sibling views out of the +/// way, within the limits of the stack's size. +/// OpenSwiftUI sizes a stack that doesn't contain a spacer up to the combined +/// ideal widths of the content of the stack's child views. +/// +/// The following example provides a simple checklist row to illustrate how you +/// can use a spacer: +/// +/// struct ChecklistRow: View { +/// let name: String +/// +/// var body: some View { +/// HStack { +/// Image(systemName: "checkmark") +/// Text(name) +/// } +/// .border(Color.blue) +/// } +/// } +/// +/// ![A figure of a blue rectangular border that marks the boundary of an +/// HStack, wrapping a checkmark image to the left of the name Megan. The +/// checkmark and name are centered vertically and separated by system +/// standard-spacing within the stack.](Spacer-1.png) +/// +/// Adding a spacer before the image creates an adaptive view with no content +/// that expands to push the image and text to the right side of the stack. +/// The stack also now expands to take as much space as the parent view allows, +/// shown by the blue border that indicates the boundary of the stack: +/// +/// struct ChecklistRow: View { +/// let name: String +/// +/// var body: some View { +/// HStack { +/// Spacer() +/// Image(systemName: "checkmark") +/// Text(name) +/// } +/// .border(Color.blue) +/// } +/// } +/// +/// ![A figure of a blue rectangular border that marks the boundary of an +/// HStack, wrapping a checkmark image to the left of the name Megan. The +/// checkmark and name are centered vertically, separated by system-standard +/// spacing, and pushed to the right side of the stack.](Spacer-2.png) +/// +/// Moving the spacer between the image and the name pushes those elements to +/// the left and right sides of the ``HStack``, respectively. Because the stack +/// contains the spacer, it expands to take as much horizontal space as the +/// parent view allows; the blue border indicates its size: +/// +/// struct ChecklistRow: View { +/// let name: String +/// +/// var body: some View { +/// HStack { +/// Image(systemName: "checkmark") +/// Spacer() +/// Text(name) +/// } +/// .border(Color.blue) +/// } +/// } +/// +/// ![A figure of a blue rectangular border that marks the boundary of an +/// HStack, wrapping a checkmark image to the left of the name Megan. The +/// checkmark and name are centered vertically, with the checkmark on the +/// left edge of the stack, and the text on the right side of the +/// stack.](Spacer-3.png) +/// +/// Adding two spacer views on the outside of the stack leaves the image and +/// text together, while the stack expands to take as much horizontal space +/// as the parent view allows: +/// +/// struct ChecklistRow: View { +/// let name: String +/// +/// var body: some View { +/// HStack { +/// Spacer() +/// Image(systemName: "checkmark") +/// Text(name) +/// Spacer() +/// } +/// .border(Color.blue) +/// } +/// } +/// +/// ![A figure of a blue rectangular border marks the boundary of an HStack, +/// wrapping a checkmark image to the left of text spelling the name Megan. +/// The checkmark and name are centered vertically, separated by +/// system-standard spacing, and centered horizontally +/// in the stack.](Spacer-4.png) +@frozen +public struct Spacer { + /// The minimum length this spacer can be shrunk to, along the axis or axes + /// of expansion. + /// + /// If `nil`, the system default spacing between views is used. + public var minLength: CGFloat? + + @inlinable + public init(minLength: CGFloat? = nil) { + self.minLength = minLength + } +} + +extension Spacer: PrimitiveView {} diff --git a/Sources/OpenSwiftUI/OpenSwiftUI.docc/Layout/LayoutFundamentals/Layout-Fundamentals.md b/Sources/OpenSwiftUI/OpenSwiftUI.docc/Layout/LayoutFundamentals/Layout-Fundamentals.md index 5f0d6ad..5cb4f6f 100644 --- a/Sources/OpenSwiftUI/OpenSwiftUI.docc/Layout/LayoutFundamentals/Layout-Fundamentals.md +++ b/Sources/OpenSwiftUI/OpenSwiftUI.docc/Layout/LayoutFundamentals/Layout-Fundamentals.md @@ -15,3 +15,8 @@ custom layout containers, see . For design guidance, see [Layout](https://developer.apple.com/design/human-interface-guidelines/foundations/layout) in the Human Interface Guidelines. ## Topics + +### Separators + +- ``Spacer`` +- ``Divider``