Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import PackageDescription
let package = Package(
name: "ExpandableText",
platforms: [
.iOS(.v13)
.iOS(.v15)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
Expand Down
32 changes: 16 additions & 16 deletions Sources/ExpandableText/ExpandableText+Modifiers.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// ExpandableText+Modifiers.swift
//
//
//
// Created by ned on 25/02/23.
//
Expand All @@ -22,13 +22,13 @@ public extension ExpandableText {
}

/**
Sets the foreground color for the text in the `ExpandableText` instance.
- Parameter color: The foreground color to use for the text. Defaults to `primary`
Sets the foreground style for the text in the `ExpandableText` instance.
- Parameter color: The foreground style to use for the text. Defaults to `primary`
- Returns: A new `ExpandableText` instance with the specified foreground color applied.
*/
func foregroundColor(_ color: Color) -> Self {
func foregroundColor<S: ShapeStyle>(_ style: S) -> Self {
var copy = self
copy.color = color
copy.style = style
return copy
}

Expand Down Expand Up @@ -70,9 +70,9 @@ public extension ExpandableText {
- Parameter color: The color to use for the "show more" button. Defaults to `accentColor`
- Returns: A new `ExpandableText` instance with the specified "show more" button color applied.
*/
func moreButtonColor(_ color: Color) -> Self {
func moreButtonColor<S: ShapeStyle>(_ style: S) -> Self {
var copy = self
copy.moreButtonColor = color
copy.moreButtonStyle = style
return copy
}

Expand All @@ -88,15 +88,15 @@ public extension ExpandableText {
}

/**
Enables collapsing behavior by tapping on the text body when the state is expanded.
- Parameter value: Whether or not to enable collapse functionality.
- Returns: A new `ExpandableText` instance with the specified collapse ability applied.
*/
func enableCollapse(_ value: Bool) -> Self {
var copy = self
copy.collapseEnabled = value
return copy
}
Enables collapsing behavior by tapping on the text body when the state is expanded.
- Parameter value: Whether or not to enable collapse functionality.
- Returns: A new `ExpandableText` instance with the specified collapse ability applied.
*/
func enableCollapse(_ value: Bool) -> Self {
var copy = self
copy.collapseEnabled = value
return copy
}

/**
Sets whether multiple consecutive newline characters should be trimmed when truncating the text in the `ExpandableText` instance.
Expand Down
47 changes: 24 additions & 23 deletions Sources/ExpandableText/ExpandableText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,39 @@ import Foundation
import SwiftUI

/**
An expandable text view that displays a truncated version of its contents with a "show more" button that expands the view to show the full contents.

An expandable text view that displays a truncated version of its contents with a "show more" button that expands the view to show the full contents.
To create a new ExpandableText view, use the init method and provide the initial text string as a parameter. The text string will be automatically trimmed of any leading or trailing whitespace and newline characters.

Example usage with default parameters:
Example usage with default parameters:
```swift
ExpandableText("Lorem ipsum dolor sit amet, consectetur adipiscing elit...")
.font(.body)
.foregroundColor(.primary)
.lineLimit(3)
.moreButtonText("more")
.moreButtonColor(.accentColor)
.expandAnimation(.default)
.trimMultipleNewlinesWhenTruncated(true)
ExpandableText("Lorem ipsum dolor sit amet, consectetur adipiscing elit...")
.font(.body)
.foregroundStyle(.primary)
.lineLimit(3)
.moreButtonText("more")
.moreButtonColor(.accentColor)
.expandAnimation(.default)
.trimMultipleNewlinesWhenTruncated(true)
```
*/
*/
public struct ExpandableText: View {

@State private var isExpanded: Bool = false
@State private var isTruncated: Bool = false

@State private var intrinsicSize: CGSize = .zero
@State private var truncatedSize: CGSize = .zero
@State private var moreTextSize: CGSize = .zero

private let text: String
internal var font: Font = .body
internal var color: Color = .primary
internal var style: any ShapeStyle = HierarchicalShapeStyle.primary

internal var lineLimit: Int = 3
internal var moreButtonText: String = "more"
internal var moreButtonFont: Font?
internal var moreButtonColor: Color = .accentColor
internal var moreButtonStyle: any ShapeStyle = .tint
internal var expandAnimation: Animation = .default
internal var collapseEnabled: Bool = false
internal var trimMultipleNewlinesWhenTruncated: Bool = true
Expand Down Expand Up @@ -81,7 +82,7 @@ public struct ExpandableText: View {
.contentShape(Rectangle())
.onTapGesture {
if (isExpanded && collapseEnabled) ||
shouldShowMoreButton {
shouldShowMoreButton {
withAnimation(expandAnimation) { isExpanded.toggle() }
}
}
Expand All @@ -92,7 +93,7 @@ public struct ExpandableText: View {
} label: {
Text(moreButtonText)
.font(moreButtonFont ?? font)
.foregroundColor(moreButtonColor)
.foregroundStyle(AnyShapeStyle(moreButtonStyle))
}
}
}))
Expand All @@ -101,14 +102,14 @@ public struct ExpandableText: View {
private var content: some View {
Text(.init(
trimMultipleNewlinesWhenTruncated
? (shouldShowMoreButton ? textTrimmingDoubleNewlines : text)
: text
? (shouldShowMoreButton ? textTrimmingDoubleNewlines : text)
: text
))
.font(font)
.foregroundColor(color)
.foregroundStyle(AnyShapeStyle(style))
.frame(maxWidth: .infinity, alignment: .leading)
}

private var shouldShowMoreButton: Bool {
!isExpanded && isTruncated
}
Expand Down