Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add localization key to placeholder #19

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
6ABA3EEE2C52A3580052571D /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 6ABA3EED2C52A3580052571D /* Localizable.xcstrings */; };
A328FAB125FD8A5300B9CE72 /* ResponsiveTextFieldApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A328FAB025FD8A5300B9CE72 /* ResponsiveTextFieldApp.swift */; };
A328FAB325FD8A5300B9CE72 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A328FAB225FD8A5300B9CE72 /* ContentView.swift */; };
A328FAB525FD8A5400B9CE72 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A328FAB425FD8A5400B9CE72 /* Assets.xcassets */; };
Expand All @@ -15,6 +16,7 @@
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
6ABA3EED2C52A3580052571D /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; };
A328FAAD25FD8A5300B9CE72 /* ResponsiveTextFieldDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ResponsiveTextFieldDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
A328FAB025FD8A5300B9CE72 /* ResponsiveTextFieldApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResponsiveTextFieldApp.swift; sourceTree = "<group>"; };
A328FAB225FD8A5300B9CE72 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -60,6 +62,7 @@
A328FAB425FD8A5400B9CE72 /* Assets.xcassets */,
A328FAB925FD8A5400B9CE72 /* Info.plist */,
A328FAB625FD8A5400B9CE72 /* Preview Content */,
6ABA3EED2C52A3580052571D /* Localizable.xcstrings */,
);
path = ResponsiveTextFieldDemo;
sourceTree = "<group>";
Expand Down Expand Up @@ -124,6 +127,7 @@
knownRegions = (
en,
Base,
ar,
);
mainGroup = A328FAA425FD8A5300B9CE72;
productRefGroup = A328FAAE25FD8A5300B9CE72 /* Products */;
Expand All @@ -142,6 +146,7 @@
files = (
A328FAB825FD8A5400B9CE72 /* Preview Assets.xcassets in Resources */,
A328FAB525FD8A5400B9CE72 /* Assets.xcassets in Resources */,
6ABA3EEE2C52A3580052571D /* Localizable.xcstrings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
27 changes: 19 additions & 8 deletions Demo Project/ResponsiveTextFieldDemo/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import SwiftUI
import Combine

struct ContentView: View {
@State
var fullName: String = ""

@State
var email: String = ""

Expand Down Expand Up @@ -60,7 +63,7 @@ struct ContentView: View {
NavigationView {
VStack {
ResponsiveTextField(
placeholder: "Email address",
placeholder: "email_address_label",
text: $email,
firstResponderDemand: $emailResponderDemand.animation(),
configuration: .email,
Expand All @@ -86,7 +89,7 @@ struct ContentView: View {

HStack(alignment: .center) {
ResponsiveTextField(
placeholder: "Password",
placeholder: "password_label",
text: $password,
isSecure: hidePassword,
firstResponderDemand: $passwordResponderDemand.animation(),
Expand All @@ -113,24 +116,32 @@ struct ContentView: View {
}
}
.padding(.bottom)

ResponsiveTextField(
placeholder: "full_name_label",
text: $fullName
)
.responsiveKeyboardReturnType(.next)
.fixedSize(horizontal: false, vertical: true)
.padding(.bottom)

Toggle("Editing Email?", isOn: isEditingEmail)
Toggle("editing_email_label", isOn: isEditingEmail)
.padding(.bottom)

Toggle("Editing Password?", isOn: isEditingPassword)
Toggle("editing_password_label", isOn: isEditingPassword)
.padding(.bottom)

Toggle("Hide Password?", isOn: $hidePassword)
Toggle("hide_password_label", isOn: $hidePassword)
.padding(.bottom)

Toggle("Enabled?", isOn: $isEnabled)
Toggle("enable_label", isOn: $isEnabled)
.padding(.bottom)

Button("Random password") {
Button("random_password_label") {
password = UUID().uuidString
}

Text("You typed the following email:")
Text("typed_email_label")
.padding(.bottom)

Text(email).font(.caption)
Expand Down
159 changes: 159 additions & 0 deletions Demo Project/ResponsiveTextFieldDemo/Localizable.xcstrings
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
{
"sourceLanguage" : "en",
"strings" : {
"editing_email_label" : {
"extractionState" : "manual",
"localizations" : {
"ar" : {
"stringUnit" : {
"state" : "translated",
"value" : "تحرير البريد الإلكتروني؟"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editing Email?"
}
}
}
},
"editing_password_label" : {
"extractionState" : "manual",
"localizations" : {
"ar" : {
"stringUnit" : {
"state" : "translated",
"value" : "تعديل كلمة المرور؟"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Editing Password?"
}
}
}
},
"email_address_label" : {
"extractionState" : "manual",
"localizations" : {
"ar" : {
"stringUnit" : {
"state" : "translated",
"value" : "عنوان البريد الإلكتروني"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Email address"
}
}
}
},
"enable_label" : {
"extractionState" : "manual",
"localizations" : {
"ar" : {
"stringUnit" : {
"state" : "translated",
"value" : "ممكن؟"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Enabled?"
}
}
}
},
"full_name_label" : {
"extractionState" : "manual",
"localizations" : {
"ar" : {
"stringUnit" : {
"state" : "translated",
"value" : "الاسم الكامل"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Full Name"
}
}
}
},
"hide_password_label" : {
"extractionState" : "manual",
"localizations" : {
"ar" : {
"stringUnit" : {
"state" : "translated",
"value" : "اخفاء كلمة المرور؟"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hide Password?"
}
}
}
},
"password_label" : {
"extractionState" : "manual",
"localizations" : {
"ar" : {
"stringUnit" : {
"state" : "translated",
"value" : "كلمة المرور"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Password"
}
}
}
},
"random_password_label" : {
"extractionState" : "manual",
"localizations" : {
"ar" : {
"stringUnit" : {
"state" : "translated",
"value" : "كلمة مرور عشوائية"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Random password"
}
}
}
},
"typed_email_label" : {
"extractionState" : "manual",
"localizations" : {
"ar" : {
"stringUnit" : {
"state" : "translated",
"value" : "لقد كتبت البريد الإلكتروني التالي:"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "You typed the following email:"
}
}
}
}
},
"version" : "1.0"
}
2 changes: 1 addition & 1 deletion Sources/ResponsiveTextField/ResponsiveTextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ extension ResponsiveTextField: UIViewRepresentable {
textField.handleDelete = handleDelete
textField.supportedStandardEditActions = supportedStandardEditActions
textField.standardEditActionHandler = standardEditActionHandler
textField.placeholder = placeholder
textField.placeholder = NSLocalizedString(placeholder, comment: "Responsive TextField placeholder")
textField.text = text.wrappedValue
textField.isEnabled = isEnabled
textField.isSecureTextEntry = isSecure
Expand Down
62 changes: 62 additions & 0 deletions Tests/ResponsiveTextFieldTests/ResponsiveTextFieldTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,66 @@ final class ResponsiveTextFieldTests: XCTestCase {
named: "Right"
)
}

@MainActor
func testTextFieldInArabic() {
// Set the locale to Arabic
setLanguage("ar")

assertSnapshot(
of: ResponsiveTextField(
placeholder: "نص العنصر النائب", // Arabic for "Placeholder Text"
text: .constant(""),
isSecure: false,
firstResponderDemand: nil,
configuration: .empty
).padding(),
as: .fixedSizeTextFieldImage,
named: "ArabicEmpty"
)

assertSnapshot(
of: ResponsiveTextField(
placeholder: "نص العنصر النائب",
text: .constant("نص في حقل الإدخال"),
isSecure: false,
firstResponderDemand: nil,
configuration: .empty
).padding(),
as: .fixedSizeTextFieldImage,
named: "ArabicText"
)

// Reset to default language
setLanguage("en")
}

@MainActor
func testTextFieldWithDifferentConfigurations() {
let configurations: [(ResponsiveTextField.Configuration, String)] = [
(.empty, "Empty Configuration"),
(.password, "Password"),
(.autoclears, "Auto clear"),
(.email, "Email")
]

for (config, name) in configurations {
assertSnapshot(
of: ResponsiveTextField(
placeholder: "Placeholder Text",
text: .constant("Sample text"),
isSecure: false,
firstResponderDemand: nil,
configuration: config
).padding(),
as: .fixedSizeTextFieldImage,
named: name
)
}
}

private func setLanguage(_ language: String) {
UserDefaults.standard.set([language], forKey: "AppleLanguages")
UserDefaults.standard.synchronize()
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading