Skip to content

Commit

Permalink
Create MultiPartTextView
Browse files Browse the repository at this point in the history
  • Loading branch information
mohamede1945 committed Jan 11, 2024
1 parent c51d71d commit e6277b0
Show file tree
Hide file tree
Showing 2 changed files with 362 additions and 8 deletions.
95 changes: 87 additions & 8 deletions UI/NoorUI/Components/MultipartText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

import SwiftUI
import UIx

public struct HighlightingRange {
// MARK: Lifecycle
Expand Down Expand Up @@ -124,6 +125,10 @@ public struct MultipartText: ExpressibleByStringInterpolation {
parts.append(.plain(text: plain))
}

public mutating func appendInterpolation(_ other: MultipartText) {
parts.append(contentsOf: other.parts)
}

// MARK: Fileprivate

fileprivate var parts: [TextPart] = []
Expand All @@ -139,6 +144,44 @@ public struct MultipartText: ExpressibleByStringInterpolation {
parts = [.plain(text: value)]
}

// MARK: Public

public enum FontSize {
case body
case caption
case footnote

// MARK: Internal

var plainFont: Font {
switch self {
case .body: return .body
case .footnote: return .footnote
case .caption: return .caption
}
}

var suraFont: Font {
switch self {
case .body: return .custom(.suraNames, size: 20, relativeTo: .body)
case .footnote: return .custom(.suraNames, size: 16, relativeTo: .footnote)
case .caption: return .custom(.suraNames, size: 15, relativeTo: .caption)
}
}

var verseFont: Font {
switch self {
case .body: return .custom(.quran, size: 20, relativeTo: .body)
case .footnote: return .custom(.suraNames, size: 16, relativeTo: .footnote)
case .caption: return .custom(.quran, size: 15, relativeTo: .caption)
}
}
}

public mutating func append(_ other: MultipartText) {
parts.append(contentsOf: other.parts)
}

// MARK: Internal

enum FontSize {
Expand Down Expand Up @@ -173,22 +216,58 @@ public struct MultipartText: ExpressibleByStringInterpolation {
parts.map(\.rawValue).joined()
}

@ViewBuilder
func view(ofSize size: FontSize) -> some View {
HStack(spacing: 0) {
ForEach(0 ..< parts.count, id: \.self) { i in
TextPartView(part: parts[i], size: size)
}
}
MultiPartTextView(text: self, size: size)
}

// MARK: Private
// MARK: Fileprivate

private let parts: [TextPart]
fileprivate var parts: [TextPart]
}

extension MultipartText {
public static func text(_ plain: String) -> MultipartText {
MultipartText(stringLiteral: plain)
}
}

public struct MultiPartTextView: View {
// MARK: Lifecycle

public init(text: MultipartText, size: MultipartText.FontSize, alignment: Alignment = .leading) {
self.text = text
self.size = size
self.alignment = alignment
}

// MARK: Public

public var body: some View {
wrap {
ForEach(0 ..< text.parts.count, id: \.self) { i in
TextPartView(part: text.parts[i], size: size)
}
}
}

// MARK: Internal

let text: MultipartText
let size: MultipartText.FontSize
let alignment: Alignment

// MARK: Private

@ViewBuilder
private func wrap(@ViewBuilder content: () -> some View) -> some View {
if #available(iOS 16.0, *) {
WrappingHStack(alignment: alignment, horizontalSpacing: 0) {
content()
}
} else {
HStack(spacing: 0) {
content()
}
}
}
}
Loading

0 comments on commit e6277b0

Please sign in to comment.