Skip to content

Commit 8d35721

Browse files
committed
chore: borders and background colors (#998)
Signed-off-by: Pierre-Yves Lapersonne <pierreyves.lapersonne@orange.com>
1 parent 17cfba3 commit 8d35721

File tree

4 files changed

+93
-18
lines changed

4 files changed

+93
-18
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//
2+
// Software Name: OUDS iOS
3+
// SPDX-FileCopyrightText: Copyright (c) Orange SA
4+
// SPDX-License-Identifier: MIT
5+
//
6+
// This software is distributed under the MIT license,
7+
// the text of which is available at https://opensource.org/license/MIT/
8+
// or see the "LICENSE" file for more details.
9+
//
10+
// Authors: See CONTRIBUTORS.txt
11+
// Software description: A SwiftUI components library with code examples for Orange Unified Design System
12+
//
13+
14+
#if !os(watchOS) && !os(macOS)
15+
import OUDSTokensSemantic
16+
import SwiftUI
17+
18+
/// `ViewModifier` to draw borders on text fields in `OUDSPinCodeInput`` component
19+
struct PinCodeInputBorderModifier: ViewModifier {
20+
21+
let isOutlined: Bool
22+
let isError: Bool
23+
let isFocused: Bool
24+
25+
@Environment(\.theme) private var theme
26+
27+
func body(content: Content) -> some View {
28+
if !isOutlined {
29+
content
30+
.overlay(
31+
Rectangle()
32+
.frame(height: borderWidth)
33+
.oudsForegroundColor(borderColor),
34+
alignment: .bottom)
35+
} else {
36+
content
37+
.oudsBorder(style: theme.borders.styleDefault,
38+
width: borderWidth,
39+
radius: theme.textInput.borderRadiusDefault,
40+
color: borderColor)
41+
}
42+
}
43+
44+
// MARK: - Helpers
45+
46+
private var borderColor: MultipleColorSemanticToken {
47+
if isError {
48+
return theme.colors.actionNegativeEnabled
49+
}
50+
if isFocused {
51+
return theme.textInput.colorBorderFocus
52+
}
53+
return theme.textInput.colorBorderEnabled
54+
}
55+
56+
private var borderWidth: BorderWidthSemanticToken {
57+
isFocused ? theme.textInput.borderWidthFocus : theme.textInput.borderWidthDefault
58+
}
59+
}
60+
#endif

OUDS/Core/Components/Sources/Controls/PinCodeInput/Internal/PinCodeInputContainer.swift

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@
1515
import OUDSTokensSemantic
1616
import SwiftUI
1717

18-
// MARK: - PIN Code Input Container
19-
2018
struct PinCodeInputContainer: View {
2119

22-
// MARK: Properties
20+
// MARK: - Properties
2321

2422
/// The `Binding` exposing the final result when everything is written
2523
@Binding private var value: String
@@ -38,7 +36,7 @@ struct PinCodeInputContainer: View {
3836
@Environment(\.colorScheme) private var colorScheme
3937
@Environment(\.theme) private var theme
4038

41-
// MARK: Black magic
39+
// MARK: - Black magic
4240

4341
// These properties prevent double backspace processing by tracking which field was cleared and when.
4442
// When a backspace occurs, we mark the field index and timestamp, then skip onChange events
@@ -52,7 +50,7 @@ struct PinCodeInputContainer: View {
5250
@State private var lastBackspaceTime: Date = .distantPast
5351
// swiftlint:enable implicit_optional_initialization
5452

55-
// MARK: Initializer
53+
// MARK: - Initializer
5654

5755
init(_ value: Binding<String>,
5856
length: OUDSPinCodeInput.Length,
@@ -68,7 +66,7 @@ struct PinCodeInputContainer: View {
6866
_digits = State(initialValue: empty)
6967
}
7068

71-
// MARK: Body
69+
// MARK: - Body
7270

7371
// swiftlint:disable accessibility_trait_for_button
7472
var body: some View {
@@ -83,15 +81,9 @@ struct PinCodeInputContainer: View {
8381
.background(
8482
RoundedRectangle(cornerRadius: theme.textInput.borderRadiusDefault)
8583
.fill(backgroundColor))
86-
.overlay(
87-
RoundedRectangle(cornerRadius: theme.textInput.borderRadiusDefault)
88-
.oudsBorder(
89-
style: theme.borders.styleDefault,
90-
width: theme.textInput.borderWidthDefault,
91-
radius: theme.textInput.borderRadiusDefault,
92-
color: borderColor))
9384
.contentShape(Rectangle())
94-
.foregroundColor(backgroundColor)
85+
.foregroundColor(foregroundColor)
86+
.modifier(PinCodeInputBorderModifier(isOutlined: isOutlined, isError: isError, isFocused: focusedIndex == index))
9587
.onTapGesture {
9688
// Focus on the first empty field or the last one
9789
if let firstEmpty = digits.firstIndex(where: { $0.isEmpty }) {
@@ -112,22 +104,38 @@ struct PinCodeInputContainer: View {
112104

113105
// swiftlint:enable accessibility_trait_for_button
114106

115-
// MARK: Helpers
107+
// MARK: - Colors
108+
109+
private var foregroundColor: Color {
110+
if isOutlined {
111+
.red
112+
} else if isError {
113+
theme.colors.surfaceStatusNegativeMuted.color(for: colorScheme)
114+
} else { // Not oulined, no error
115+
theme.colors.actionSupportEnabled.color(for: colorScheme)
116+
}
117+
}
116118

117119
private var backgroundColor: Color {
118120
if isOutlined {
119121
.clear
120122
} else if isError {
121123
theme.colors.surfaceStatusNegativeMuted.color(for: colorScheme)
122-
} else {
124+
} else { // Not oulined, no error
123125
theme.colors.actionSupportEnabled.color(for: colorScheme)
124126
}
125127
}
126128

127129
private var borderColor: MultipleColorSemanticToken {
128-
isError ? theme.colors.actionNegativeEnabled : theme.colors.actionSupportEnabled
130+
if isError {
131+
theme.colors.actionNegativeEnabled
132+
} else { // Same color of border for both outlined and not outlined layouts
133+
theme.textInput.colorBorderEnabled
134+
}
129135
}
130136

137+
// MARK: - Digits fields
138+
131139
private func digitField(at index: Int) -> some View {
132140
BackspaceDetectingTextField(
133141
text: $digits[index],
@@ -136,6 +144,7 @@ struct PinCodeInputContainer: View {
136144
handleBackspace(at: index)
137145
})
138146
.oudsForegroundColor(theme.colors.contentDefault)
147+
.oudsAccentColor(theme.colors.contentDefault)
139148
.focused($focusedIndex, equals: index)
140149
.padding(.vertical, theme.textInput.spacePaddingBlockDefault)
141150
.padding(.horizontal, theme.textInput.spacePaddingInlineDefault)

OUDS/Core/Components/Sources/_/Resources/Localizable.xcstrings

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,10 @@
681681
}
682682
}
683683
}
684+
},
685+
"Digit %lld" : {
686+
"comment" : "A label for each digit in the PIN code input. The number inside the label corresponds to the digit's position (e.g. \"Digit 1\").",
687+
"isCommentAutoGenerated" : true
684688
}
685689
},
686690
"version" : "1.1"

OUDS/Core/Components/Tests/Controls/PinCodeInput/OUDSPinCodeInputTests.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,18 @@
1111
// Software description: A SwiftUI components library with code examples for Orange Unified Design System
1212
//
1313

14+
#if !os(watchOS) && !os(macOS)
1415
import OUDSComponents
1516
import Testing
1617

1718
/// Tests some API for `OUDSPinCodeInput`
1819
struct OUDSPinCodeInputTests {
1920

2021
/// Test the raw values for the length of the component
21-
@Test func pinCodeInputLengthValues() {
22+
func pinCodeInputLengthValues() {
2223
#expect(OUDSPinCodeInput.Length.four.rawValue == 4)
2324
#expect(OUDSPinCodeInput.Length.six.rawValue == 6)
2425
#expect(OUDSPinCodeInput.Length.eight.rawValue == 8)
2526
}
2627
}
28+
#endif

0 commit comments

Comments
 (0)