Skip to content

Commit 7cce354

Browse files
committed
refactor: remove view model
1 parent 80eae9f commit 7cce354

File tree

1 file changed

+43
-58
lines changed

1 file changed

+43
-58
lines changed

WireUI/Sources/WireReusableUIComponents/PasswordField/PasswordField.swift

+43-58
Original file line numberDiff line numberDiff line change
@@ -19,47 +19,36 @@
1919
import SwiftUI
2020
import WireDesign
2121

22-
public final class PasswordFieldViewModel: ObservableObject {
23-
@Published public private(set) var arePasswordRulesVisible: Bool
24-
@Published public fileprivate(set) var isPasswordValid: Bool
25-
@Published public fileprivate(set) var isPasswordVisible: Bool
26-
@Published public fileprivate(set) var password: String
27-
28-
fileprivate let passwordValidator: any PasswordValidator
29-
30-
public init(
31-
arePasswordRulesVisible: Bool = false,
32-
isPasswordVisible: Bool = false,
33-
password: String = "",
34-
passwordValidator: any PasswordValidator
35-
) {
36-
self.arePasswordRulesVisible = arePasswordRulesVisible
37-
38-
self.isPasswordVisible = isPasswordVisible
39-
self.password = password
40-
self.passwordValidator = passwordValidator
41-
42-
self.isPasswordValid = passwordValidator.validate(password)
43-
}
44-
}
45-
4622
// TODO: [WPB-15571] Add accessibility strings to the mask / unmask buttons
4723
public struct PasswordField: View {
4824
@FocusState private var isFocused: Bool
49-
@ObservedObject private var viewModel: PasswordFieldViewModel
5025
// TextField and SecureField have different heights. Switching between them causes the view to jump.
5126
// But we also want their height to change with dynamic font sizes. Hence @ScaledMetric.
5227
@ScaledMetric private var fieldHeight: CGFloat = 48
5328

29+
@State public private(set) var arePasswordRulesVisible: Bool
30+
@State public fileprivate(set) var isPasswordVisible: Bool
31+
@Binding public fileprivate(set) var isPasswordValid: Bool
32+
@Binding public fileprivate(set) var password: String
33+
34+
private let passwordValidator: any PasswordValidator
5435
private let placeholder: String
5536
private let title: String
5637

5738
public init(
58-
viewModel: PasswordFieldViewModel,
39+
arePasswordRulesVisible: Bool = false,
40+
isPasswordVisible: Bool = false,
41+
isPasswordValid: Binding<Bool>,
42+
password: Binding<String>,
43+
passwordValidator: any PasswordValidator,
5944
placeholder: String,
6045
title: String
6146
) {
62-
self.viewModel = viewModel
47+
self.arePasswordRulesVisible = arePasswordRulesVisible
48+
self.isPasswordVisible = isPasswordVisible
49+
self._isPasswordValid = isPasswordValid
50+
self._password = password
51+
self.passwordValidator = passwordValidator
6352
self.placeholder = placeholder
6453
self.title = title
6554
}
@@ -71,21 +60,21 @@ public struct PasswordField: View {
7160
.foregroundColor(calculatedColor)
7261

7362
HStack {
74-
if viewModel.isPasswordVisible {
75-
TextField(placeholder, text: $viewModel.password)
63+
if isPasswordVisible {
64+
TextField(placeholder, text: $password)
7665
.wireTextStyle(.body1)
7766
.frame(height: fieldHeight)
7867
.focused($isFocused)
7968
} else {
80-
SecureField(placeholder, text: $viewModel.password)
69+
SecureField(placeholder, text: $password)
8170
.frame(height: fieldHeight)
8271
.focused($isFocused)
8372
}
8473
Spacer()
8574
Button(action: {
86-
viewModel.isPasswordVisible.toggle()
75+
isPasswordVisible.toggle()
8776
}, label: {
88-
Image(systemName: viewModel.isPasswordVisible ? "eye" : "eye.slash")
77+
Image(systemName: isPasswordVisible ? "eye" : "eye.slash")
8978
.foregroundColor(.gray)
9079
})
9180
}
@@ -94,27 +83,27 @@ public struct PasswordField: View {
9483
RoundedRectangle(cornerRadius: 5)
9584
.stroke(
9685
calculatedColor,
97-
lineWidth: viewModel.password.isEmpty ? 0 : 1
86+
lineWidth: password.isEmpty ? 0 : 1
9887
)
9988
)
10089

101-
if let passwordRules = viewModel.passwordValidator.localizedRulesDescription,
102-
viewModel.arePasswordRulesVisible {
90+
if let passwordRules = passwordValidator.localizedRulesDescription,
91+
arePasswordRulesVisible {
10392
Text(passwordRules)
10493
.font(.caption)
10594
.foregroundColor(calculatedColor)
10695
}
10796
}
10897
.padding(.horizontal)
109-
.onChange(of: viewModel.password, perform: { newPassword in
110-
viewModel.isPasswordValid = viewModel.passwordValidator.validate(newPassword)
98+
.onChange(of: password, perform: { newPassword in
99+
isPasswordValid = passwordValidator.validate(newPassword)
111100
})
112101
}
113102

114103
// MARK: - Helper
115104

116105
private var calculatedColor: Color {
117-
switch (viewModel.password.isEmpty, viewModel.isPasswordValid) {
106+
switch (password.isEmpty, isPasswordValid) {
118107
case (_, false):
119108
ColorTheme.Base.error.color
120109
case (true, _):
@@ -146,11 +135,10 @@ package struct MockPasswordValidator: PasswordValidator {
146135
@available(iOS 17, *)
147136
#Preview("Invalid Password - Hidden") {
148137
PasswordField(
149-
viewModel: PasswordFieldViewModel(
150-
isPasswordVisible: false,
151-
password: "Invalid password",
152-
passwordValidator: MockPasswordValidator(validationCallback: { _ in false })
153-
),
138+
isPasswordVisible: false,
139+
isPasswordValid: .constant(false),
140+
password: .constant("Invalid password"),
141+
passwordValidator: MockPasswordValidator(validationCallback: { _ in false }),
154142
placeholder: L10n.Passwordtextfield.Preview.placeholder,
155143
title: L10n.Passwordtextfield.Preview.title
156144
)
@@ -159,11 +147,10 @@ package struct MockPasswordValidator: PasswordValidator {
159147
@available(iOS 17, *)
160148
#Preview("Invalid Password - Visible") {
161149
PasswordField(
162-
viewModel: PasswordFieldViewModel(
163-
isPasswordVisible: true,
164-
password: "Invalid password",
165-
passwordValidator: MockPasswordValidator(validationCallback: { _ in false })
166-
),
150+
isPasswordVisible: true,
151+
isPasswordValid: .constant(false),
152+
password: .constant("Invalid password"),
153+
passwordValidator: MockPasswordValidator(validationCallback: { _ in false }),
167154
placeholder: L10n.Passwordtextfield.Preview.placeholder,
168155
title: L10n.Passwordtextfield.Preview.title
169156
)
@@ -172,11 +159,10 @@ package struct MockPasswordValidator: PasswordValidator {
172159
@available(iOS 17, *)
173160
#Preview("Valid Password - Hidden") {
174161
PasswordField(
175-
viewModel: PasswordFieldViewModel(
176-
isPasswordVisible: false,
177-
password: "Valid password!",
178-
passwordValidator: MockPasswordValidator(validationCallback: { _ in true })
179-
),
162+
isPasswordVisible: false,
163+
isPasswordValid: .constant(true),
164+
password: .constant("Valid password!"),
165+
passwordValidator: MockPasswordValidator(validationCallback: { _ in true }),
180166
placeholder: L10n.Passwordtextfield.Preview.placeholder,
181167
title: L10n.Passwordtextfield.Preview.title
182168
)
@@ -185,11 +171,10 @@ package struct MockPasswordValidator: PasswordValidator {
185171
@available(iOS 17, *)
186172
#Preview("Valid Password - Visible") {
187173
PasswordField(
188-
viewModel: PasswordFieldViewModel(
189-
isPasswordVisible: true,
190-
password: "Valid password!",
191-
passwordValidator: MockPasswordValidator(validationCallback: { _ in true })
192-
),
174+
isPasswordVisible: true,
175+
isPasswordValid: .constant(true),
176+
password: .constant("Valid password!"),
177+
passwordValidator: MockPasswordValidator(validationCallback: { _ in true }),
193178
placeholder: L10n.Passwordtextfield.Preview.placeholder,
194179
title: L10n.Passwordtextfield.Preview.title
195180
)

0 commit comments

Comments
 (0)