Skip to content

Commit

Permalink
Adding two new components (#72)
Browse files Browse the repository at this point in the history
* Implements a enumerated list component

* Implements a SwiftUI ScrollIfNeeded component for iOS 16.4 and upwards to wrap views that should scroll if the space is limited

* Adds documentation to init of EnumeratedList
  • Loading branch information
LukasLiebl authored Oct 8, 2024
1 parent 9126dcb commit 682261b
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 0 deletions.
75 changes: 75 additions & 0 deletions Sources/UIExtensions/Components/SwiftUI/Pure/EnumeratedList.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright © 2024 Lautsprecher Teufel GmbH. All rights reserved.

import SwiftUI

/// Enumerated list of Strings such as for instructions or help usage. Enumeration is
/// shown as `CircledNumber`.
struct EnumeratedList<TextView: View>: View {
let items: EnumeratedSequence<[String]>
let horizontalSpacing: CGFloat
let verticalSpacing: CGFloat
let circledNumberStrokeColor: Color
let textView: (String) -> TextView

/// Initialises a new EnumeratedList
/// - Parameters:
/// - items: Items to be shown on the right hand sides, next to the numbers.
/// For each element the enumeration item gets incremented.
/// - horizontalSpacing: The spacing between the enumeration and text.
/// - verticalSpacing: The vertical spacing between elements
/// - circledNumberStrokeColor: Stroke colour used around the enumerations
/// - textBuilder: A view builder to modify the shown text on the right hand side for each element.
init(items: EnumeratedSequence<[String]>,
horizontalSpacing: CGFloat = 12,
verticalSpacing: CGFloat = 16,
circledNumberStrokeColor: Color,
@ViewBuilder
textBuilder: @escaping (String) -> TextView) {
self.items = items
self.horizontalSpacing = horizontalSpacing
self.verticalSpacing = verticalSpacing
self.circledNumberStrokeColor = circledNumberStrokeColor
self.textView = textBuilder
}

var body: some View {
VStack(alignment: .leading, spacing: verticalSpacing) {
ForEach(Array(items), id: \.element) { index, item in
descriptionText(index: index, description: item)
}
}
}

private func descriptionText(index: Int, description: String) -> some View {
HStack(alignment: .firstTextBaseline, spacing: horizontalSpacing) {
CircledNumber(
number: index + 1,
length: 24,
strokeContent: circledNumberStrokeColor,
content: { Text("\($0)") })
textView(description)
.multilineTextAlignment(.leading)
.fixedSize(horizontal: false, vertical: true)
}
}
}

#if DEBUG
#Preview {
EnumeratedList(
items: [
"*Recipe for a nice commit message*",
"1 clear purpose (don’t be afraid to reduce scope)",
"2 cups of meaningful context (preferably bug-free)",
"1 well-chopped action verb (e.g., “fix,” “add,” “update”)",
"A handful of concise explanations (remove unnecessary details)",
"1 tsp of consistency (refer to previous commit messages for taste)",
"Optional: sprinkle with emojis, but use sparingly (:sparkles: for feature additions, :bug: for bug fixes)",
"Thanks ChatGPT"
].enumerated(),
circledNumberStrokeColor: Color.black
) { text in
Text(text)
}
}
#endif
29 changes: 29 additions & 0 deletions Sources/UIExtensions/Components/SwiftUI/Pure/ScrollIfNeeded.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright © 2024 Lautsprecher Teufel GmbH. All rights reserved.

import SwiftUI

@available(iOS 16.4, *)
/// A view that embeds content in a scroll view if content overflows.
public struct ScrollIfNeeded<Content: View>: View {
private let content: () -> Content
private let axis: Axis.Set

/// Initializes a new instance of `ScrollIfNeeded`.
///
/// - Parameters:
/// - axis: The axis along which scrolling should occur. Defaults to vertical.
/// - content: A closure returning the content to embed within the scroll view.
public init(
in axis: Axis.Set = [.vertical],
@ViewBuilder
content: @escaping () -> Content
) {
self.axis = axis
self.content = content
}

public var body: some View {
ScrollView(axis, content: content)
.scrollBounceBehavior(.basedOnSize)
}
}

0 comments on commit 682261b

Please sign in to comment.