Skip to content

Commit 881cfc4

Browse files
authored
Merge pull request #9 from leboncoin/feature/intents
[Intent] Add new cases - Add effect on pressed
2 parents 44f21e6 + 58ef822 commit 881cfc4

File tree

66 files changed

+622
-136
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+622
-136
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//
2+
// TextLinkConstants.swift
3+
// SparkComponentTextLink
4+
//
5+
// Created by robin.lemaire on 22/09/2025.
6+
// Copyright © 2025 Leboncoin. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import SwiftUI
11+
12+
enum TextLinkConstants {
13+
/// Animation duration is 200ms
14+
static let animationDuration = 0.2
15+
}

Sources/Core/Enum/Public/TextLinkIntent.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,50 @@
99
/// The intent of the text link.
1010
public enum TextLinkIntent: CaseIterable {
1111
case accent
12+
case accentContainer
13+
@available(*, deprecated, message: "Use accentContainer instead.")
1214
case onAccentContainer
1315
case alert
16+
case alertContainer
1417
case basic
18+
case basicContainer
1519
case danger
20+
case dangerContainer
1621
case info
22+
case infoContainer
1723
case main
24+
case mainContainer
1825
case neutral
26+
case neutralContainer
27+
case surface
28+
@available(*, deprecated, message: "Use surface instead.")
1929
case onSurface
2030
case success
31+
case successContainer
2132
case support
33+
case supportContainer
34+
35+
// MARK: - Properties
36+
37+
static public var allCases: [TextLinkIntent] = [
38+
.accent,
39+
.accentContainer,
40+
.alert,
41+
.alertContainer,
42+
.basic,
43+
.basicContainer,
44+
.danger,
45+
.dangerContainer,
46+
.info,
47+
.infoContainer,
48+
.main,
49+
.mainContainer,
50+
.neutral,
51+
.neutralContainer,
52+
.surface,
53+
.success,
54+
.successContainer,
55+
.support,
56+
.supportContainer
57+
]
2258
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//
2+
// TextLinkHoverStyle.swift
3+
// SparkComponentTextLink
4+
//
5+
// Created by robin.lemaire on 14/12/2023.
6+
// Copyright © 2023 Leboncoin. All rights reserved.
7+
//
8+
9+
import Foundation
10+
@_spi(SI_SPI) import SparkTheming
11+
12+
struct TextLinkHoverStyle: Equatable {
13+
14+
// MARK: - Properties
15+
16+
var horizontalPadding: CGFloat = 0
17+
var verticalPadding: CGFloat = 0
18+
var cornerRadius: CGFloat = 0
19+
var backgroundColor: any ColorToken = ColorTokenClear()
20+
var dim: CGFloat = 0
21+
22+
// MARK: - Equatable
23+
24+
static func == (lhs: TextLinkHoverStyle, rhs: TextLinkHoverStyle) -> Bool {
25+
return lhs.horizontalPadding == rhs.horizontalPadding &&
26+
lhs.verticalPadding == rhs.verticalPadding &&
27+
lhs.cornerRadius == rhs.cornerRadius &&
28+
lhs.backgroundColor.equals(rhs.backgroundColor) &&
29+
lhs.dim == rhs.dim
30+
}
31+
}

Sources/Core/UseCase/GetColor/TextLinkGetColorUseCase.swift

Lines changed: 0 additions & 54 deletions
This file was deleted.
Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ import SparkTheming
1515
protocol TextLinkGetAttributedStringUseCaseable {
1616

1717
// sourcery: textColorToken = "Identical"
18-
func execute(frameworkType: FrameworkType,
19-
text: String,
20-
textColorToken: any ColorToken,
21-
textDim: CGFloat,
22-
textHighlightRange: NSRange?,
23-
isHighlighted: Bool,
24-
variant: TextLinkVariant,
25-
typographies: TextLinkTypographies) -> AttributedStringEither
18+
func execute(
19+
frameworkType: FrameworkType,
20+
text: String,
21+
textColorToken: any ColorToken,
22+
textHighlightRange: NSRange?,
23+
isHighlighted: Bool,
24+
variant: TextLinkVariant,
25+
typographies: TextLinkTypographies
26+
) -> AttributedStringEither
2627
}
2728

2829
struct TextLinkGetAttributedStringUseCase: TextLinkGetAttributedStringUseCaseable {
@@ -43,7 +44,6 @@ struct TextLinkGetAttributedStringUseCase: TextLinkGetAttributedStringUseCaseabl
4344
frameworkType: FrameworkType,
4445
text: String,
4546
textColorToken: any ColorToken,
46-
textDim: CGFloat,
4747
textHighlightRange: NSRange?,
4848
isHighlighted: Bool,
4949
variant: TextLinkVariant,
@@ -62,7 +62,6 @@ struct TextLinkGetAttributedStringUseCase: TextLinkGetAttributedStringUseCaseabl
6262
let attributedString = self.makeNSAttributedString(
6363
text: text,
6464
textColorToken: textColorToken,
65-
textDim: textDim,
6665
textHighlightRange: textHighlightRange,
6766
underlineStyle: underlineStyle,
6867
typographies: typographies
@@ -73,7 +72,6 @@ struct TextLinkGetAttributedStringUseCase: TextLinkGetAttributedStringUseCaseabl
7372
let attributedString = self.makerAttributedString(
7473
text: text,
7574
textColorToken: textColorToken,
76-
textDim: textDim,
7775
textHighlightRange: textHighlightRange,
7876
underlineStyle: underlineStyle,
7977
typographies: typographies
@@ -88,13 +86,12 @@ struct TextLinkGetAttributedStringUseCase: TextLinkGetAttributedStringUseCaseabl
8886
private func makeNSAttributedString(
8987
text: String,
9088
textColorToken: any ColorToken,
91-
textDim: CGFloat,
9289
textHighlightRange: NSRange?,
9390
underlineStyle: NSUnderlineStyle?,
9491
typographies: TextLinkTypographies
9592
) -> NSAttributedString {
9693
var attributedString: NSMutableAttributedString
97-
let textColor = textColorToken.uiColor.withAlphaComponent(textDim)
94+
let textColor = textColorToken.uiColor
9895

9996
var highlightAttributes: [NSAttributedString.Key: Any] = [
10097
.foregroundColor: textColor,
@@ -135,13 +132,12 @@ struct TextLinkGetAttributedStringUseCase: TextLinkGetAttributedStringUseCaseabl
135132
private func makerAttributedString(
136133
text: String,
137134
textColorToken: any ColorToken,
138-
textDim: CGFloat,
139135
textHighlightRange: NSRange?,
140136
underlineStyle: NSUnderlineStyle?,
141137
typographies: TextLinkTypographies
142138
) -> AttributedString {
143139
var attributedString = AttributedString(text)
144-
attributedString.foregroundColor = textColorToken.color.opacity(textDim)
140+
attributedString.foregroundColor = textColorToken.color
145141

146142
if let textHighlightRangeTemp = textHighlightRange,
147143
let textHighlightRange = Range(textHighlightRangeTemp, in: attributedString) {
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//
2+
// TextLinkGetColorUseCase.swift
3+
// SparkComponentTextLink
4+
//
5+
// Created by robin.lemaire on 05/12/2023.
6+
// Copyright © 2023 Leboncoin. All rights reserved.
7+
//
8+
9+
import SparkTheming
10+
11+
// sourcery: AutoMockable, AutoMockTest
12+
protocol TextLinkGetColorUseCaseable {
13+
14+
// sourcery: colors = "Identical", return = "Identical"
15+
func execute(
16+
intent: TextLinkIntent,
17+
isHighlighted: Bool,
18+
colors: any Colors
19+
) -> any ColorToken
20+
}
21+
22+
struct TextLinkGetColorUseCase: TextLinkGetColorUseCaseable {
23+
24+
// MARK: - Methods
25+
26+
func execute(
27+
intent: TextLinkIntent,
28+
isHighlighted: Bool,
29+
colors: any Colors
30+
) -> any ColorToken {
31+
return switch intent {
32+
33+
case .accent: isHighlighted ? colors.states.accentPressed : colors.accent.accent
34+
case .accentContainer, .onAccentContainer: colors.accent.onAccentContainer
35+
36+
case .alert: isHighlighted ? colors.states.alertPressed : colors.feedback.alert
37+
case .alertContainer: colors.feedback.onAlertContainer
38+
39+
case .basic: isHighlighted ? colors.states.basicPressed : colors.basic.basic
40+
case .basicContainer: colors.basic.onBasicContainer
41+
42+
case .danger: isHighlighted ? colors.states.errorPressed : colors.feedback.error
43+
case .dangerContainer: colors.feedback.onErrorContainer
44+
45+
case .info: isHighlighted ? colors.states.infoPressed : colors.feedback.info
46+
case .infoContainer: colors.feedback.onInfoContainer
47+
48+
case .main: isHighlighted ? colors.states.mainPressed : colors.main.main
49+
case .mainContainer: colors.main.onMainContainer
50+
51+
case .neutral: isHighlighted ? colors.states.neutralPressed : colors.feedback.neutral
52+
case .neutralContainer: colors.feedback.onNeutralContainer
53+
54+
case .surface, .onSurface: colors.base.onSurface
55+
56+
case .success: isHighlighted ? colors.states.successPressed : colors.feedback.success
57+
case .successContainer: colors.feedback.onSuccessContainer
58+
59+
case .support: isHighlighted ? colors.states.supportPressed : colors.support.support
60+
case .supportContainer: colors.support.onSupportContainer
61+
}
62+
}
63+
}

Sources/Core/UseCase/GetDim/TextLinkGetDimUseCase.swift renamed to Sources/Core/UseCase/TextLinkGetDimUseCase.swift

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ import Foundation
1313
protocol TextLinkGetDimUseCaseable {
1414

1515
// sourcery: dims = "Identical"
16-
func execute(intent: TextLinkIntent,
17-
isHighlighted: Bool,
18-
dims: any Dims) -> CGFloat
16+
func execute(
17+
intent: TextLinkIntent,
18+
isHighlighted: Bool,
19+
dims: any Dims
20+
) -> CGFloat
1921
}
2022

2123
struct TextLinkGetDimUseCase: TextLinkGetDimUseCaseable {
@@ -27,10 +29,24 @@ struct TextLinkGetDimUseCase: TextLinkGetDimUseCaseable {
2729
isHighlighted: Bool,
2830
dims: any Dims
2931
) -> CGFloat {
30-
switch intent {
31-
case .onAccentContainer, .onSurface:
32+
33+
let applyDim1 = switch intent {
34+
case .accentContainer,
35+
.onAccentContainer,
36+
.alertContainer,
37+
.basicContainer,
38+
.dangerContainer,
39+
.infoContainer,
40+
.mainContainer,
41+
.neutralContainer,
42+
.successContainer,
43+
.supportContainer: true
44+
default: false
45+
}
46+
47+
return if applyDim1 {
3248
isHighlighted ? dims.dim1 : dims.none
33-
default:
49+
} else {
3450
dims.none
3551
}
3652
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//
2+
// TextLinkGetHoverStyleUseCase.swift
3+
// SparkComponentTextLink
4+
//
5+
// Created by robin.lemaire on 22/09/2025.
6+
// Copyright © 2025 Leboncoin. All rights reserved.
7+
//
8+
9+
import SparkTheming
10+
11+
// sourcery: AutoMockable, AutoMockTest
12+
protocol TextLinkGetHoverStyleUseCaseable {
13+
14+
// sourcery: theme = "Identical"
15+
func execute(
16+
theme: any Theme,
17+
intent: TextLinkIntent
18+
) -> TextLinkHoverStyle
19+
}
20+
21+
struct TextLinkGetHoverStyleUseCase: TextLinkGetHoverStyleUseCaseable {
22+
23+
// MARK: - Methods
24+
25+
func execute(
26+
theme: any Theme,
27+
intent: TextLinkIntent
28+
) -> TextLinkHoverStyle {
29+
let colors = theme.colors
30+
let backgroundColor = switch intent {
31+
case .accent, .accentContainer, .onAccentContainer: colors.accent.accent
32+
case .alert, .alertContainer: colors.feedback.alert
33+
case .basic, .basicContainer: colors.basic.basic
34+
case .danger, .dangerContainer: colors.feedback.error
35+
case .info, .infoContainer: colors.feedback.info
36+
case .main, .mainContainer: colors.main.main
37+
case .neutral, .neutralContainer: colors.feedback.neutral
38+
case .surface, .onSurface: colors.base.surface
39+
case .success, .successContainer: colors.feedback.success
40+
case .support, .supportContainer: colors.support.support
41+
}
42+
43+
return .init(
44+
horizontalPadding: theme.layout.spacing.medium,
45+
verticalPadding: theme.layout.spacing.small,
46+
cornerRadius: theme.border.radius.medium,
47+
backgroundColor: backgroundColor,
48+
dim: theme.dims.dim5
49+
)
50+
}
51+
}

0 commit comments

Comments
 (0)