diff --git a/Sources/HTMLKitComponents/Components/Button.swift b/Sources/HTMLKitComponents/Components/Button.swift index 7551cc0c..e0cb8e4f 100644 --- a/Sources/HTMLKitComponents/Components/Button.swift +++ b/Sources/HTMLKitComponents/Components/Button.swift @@ -6,12 +6,21 @@ import HTMLKit import Foundation -/// A component that initiates an action. +/// A view that represents a button. +/// +/// Use `Button` to trigger an action when tapped or clicked. +/// +/// ```swift +/// Button(role: .button) { +/// "Lorem ipsum" +/// } +/// ``` public struct Button: View, Modifiable, Actionable { + /// The identifier of the button. internal var id: String? - /// The role of the button + /// The role of the button. internal var role: HTMLKit.Values.Button /// The content of the button. @@ -20,9 +29,14 @@ public struct Button: View, Modifiable, Actionable { /// The classes of the button. internal var classes: [String] + /// The events of the button. internal var events: [String]? - /// Creates a action button. + /// Create a button. + /// + /// - Parameters: + /// - role: The role of the button. + /// - content: The button's content. public init(role: HTMLKit.Values.Button, @ContentBuilder content: () -> [Content]) { self.role = role @@ -30,6 +44,18 @@ public struct Button: View, Modifiable, Actionable { self.classes = ["button"] } + /// Create a button. + /// + /// - Parameters: + /// - localizedStringKey: The key of the localized string used as a label. + /// - role: The role of the button. + public init(_ localizedStringKey: LocalizedStringKey, role: HTMLKit.Values.Button) { + + self.role = role + self.content = [LocalizedString(key: localizedStringKey)] + self.classes = ["button"] + } + public var body: Content { HTMLKit.Button { self.content @@ -146,11 +172,21 @@ extension Button: ViewModifier { } } -/// A component that initiates an action. +/// A view that represents a link button. +/// +/// Use `LinkButton`to navigate to a target. +/// +/// ```swift +/// LinkButton(destination: "https://..") { +/// "Lorem ipsum" +/// } +/// ``` public struct LinkButton: View, Modifiable, Identifiable { + /// The unique identifier of the button. internal var id: String? + /// The target behaviour for the destination internal let target: HTMLKit.Values.Target /// The url path of the target. @@ -165,7 +201,12 @@ public struct LinkButton: View, Modifiable, Identifiable { /// The events of the button. internal var events: [String]? - /// Creates a action button. + /// Create a link button. + /// + /// - Parameters: + /// - destination: The url of the target to navigate to. + /// - target: The behaviour that determines how to open the target. + /// - content: The content displayed as the label. public init(destination: String, target: HTMLKit.Values.Target = .current, @ContentBuilder content: () -> [Content]) { self.destination = destination @@ -174,7 +215,26 @@ public struct LinkButton: View, Modifiable, Identifiable { self.classes = ["button"] } - /// Creates a action button. + /// Create a link button. + /// + /// - Parameters: + /// - localizedStringKey: The key of the localized string used as the label. + /// - destination: The url of the target to navigate to. + /// - target: The behaviour that determines how to open the target. + public init(_ localizedStringKey: LocalizedStringKey, destination: String, target: HTMLKit.Values.Target = .current) { + + self.destination = destination + self.target = target + self.content = [LocalizedString(key: localizedStringKey)] + self.classes = ["button"] + } + + /// Create a link button. + /// + /// - Parameters: + /// - destination: The url of the target to navigate to. + /// - target: The behaviour that determines how to open the target. + /// - content: The content displayed as the label. public init(destination: URL, target: HTMLKit.Values.Target = .current, @ContentBuilder content: () -> [Content]) { self.destination = destination.absoluteString @@ -183,6 +243,20 @@ public struct LinkButton: View, Modifiable, Identifiable { self.classes = ["button"] } + /// Create a link button. + /// + /// - Parameters: + /// - localizedStringKey: The key of the localized string used as the label. + /// - destination: The url of the target to navigate to. + /// - target: The behaviour that determines how to open the target. + public init(_ localizedStringKey: LocalizedStringKey, destination: URL, target: HTMLKit.Values.Target = .current) { + + self.destination = destination.absoluteString + self.target = target + self.content = [LocalizedString(key: localizedStringKey)] + self.classes = ["button"] + } + public var body: Content { Anchor { self.content diff --git a/Sources/HTMLKitComponents/Components/Disclosure.swift b/Sources/HTMLKitComponents/Components/Disclosure.swift index 24d8d81d..9c819896 100644 --- a/Sources/HTMLKitComponents/Components/Disclosure.swift +++ b/Sources/HTMLKitComponents/Components/Disclosure.swift @@ -5,17 +5,34 @@ import HTMLKit -/// A component that distinguish content. +/// A view that represents a disclosure. +/// +/// Use `Disclosure` to reveal or hide content when interacted with. +/// +/// ```swift +/// Disclosure("Lorem ipsum") { +/// Text { +/// "Lorem ipsum..." +/// } +/// } +/// ``` public struct Disclosure: View, Modifiable { - internal let label: String + /// The label of the disclosure. + internal let label: Content + /// The disclosure's content. internal let content: [Content] /// The classes of the content. internal var classes: [String] - - /// Creates a card. + + /// Create a disclosure. + /// + /// - Parameters: + /// - label: The label to describe the content. + /// - content: The disclosure's content. + @_disfavoredOverload public init(_ label: String, @ContentBuilder content: () -> [Content]) { self.label = label @@ -23,6 +40,18 @@ public struct Disclosure: View, Modifiable { self.classes = ["disclosure"] } + /// Create a disclosure. + /// + /// - Parameters: + /// - label: The key of the localized string to describe the content. + /// - content: The disclosure's content. + public init(_ label: LocalizedStringKey, @ContentBuilder content: () -> [Content]) { + + self.label = LocalizedString(key: label) + self.content = content() + self.classes = ["disclosure"] + } + public var body: Content { Division { Division { diff --git a/Sources/HTMLKitComponents/Components/Form.swift b/Sources/HTMLKitComponents/Components/Form.swift index d59ffeb7..60c19497 100644 --- a/Sources/HTMLKitComponents/Components/Form.swift +++ b/Sources/HTMLKitComponents/Components/Form.swift @@ -62,7 +62,15 @@ extension Form: FormEvent { } } -/// A component that displays the name of the form control. +/// A view that represents a field label. +/// +/// Use `FieldLabel` to display the name for the form control. +/// +/// ```swift +/// FieldLabel(for: "lorem") { +/// "Lorem ipsum" +/// } +/// ``` public struct FieldLabel: View { /// The identifier of the element the label is related to. @@ -77,7 +85,11 @@ public struct FieldLabel: View { /// The events of the label. internal var events: [String]? - /// Creates a field label. + /// Create a field label. + /// + /// - Parameters: + /// - id: The identifier of the field to associate the label with. + /// - content: The text content to display in the label. public init(for id: String, @ContentBuilder content: () -> [Content]) { self.id = id @@ -85,6 +97,18 @@ public struct FieldLabel: View { self.classes = ["label"] } + /// Create a field label. + /// + /// - Parameters: + /// - localizedStringKey: The key of the localized string to look for. + /// - id: The identifier of the field to associate the label with. + public init(_ localizedStringKey: LocalizedStringKey, for id: String) { + + self.id = id + self.content = [LocalizedString(key: localizedStringKey)] + self.classes = ["label"] + } + public var body: Content { Label { content @@ -94,16 +118,23 @@ public struct FieldLabel: View { } } -/// A component that displays an editable form control. +/// A view that represents a text field. +/// +/// Use `TextField` to display an editable form control. +/// +/// ```swift +/// TextField(name: "lorem", prompt: "Lorem ipsum", value: "Lorem ipsum") +/// ``` public struct TextField: View, Modifiable, Identifiable { + /// The identifier of the field. internal var id: String? - /// The identifier of the field. + /// The name of the field. internal let name: String /// The placeholder for the field value. - internal let prompt: String? + internal let prompt: PromptType? /// The content of the field. internal let value: String? @@ -114,11 +145,31 @@ public struct TextField: View, Modifiable, Identifiable { /// The events of the field. internal var events: [String]? - /// Creates a text field. + /// Create a text field. + /// + /// - Parameters: + /// - name: The name to assign to the field. + /// - prompt: The prompt to guide the user. + /// - value: The value to edit within the field. + @_disfavoredOverload public init(name: String, prompt: String? = nil, value: String? = nil) { self.name = name - self.prompt = prompt + self.prompt = prompt.map(PromptType.string(_:)) + self.value = value + self.classes = ["textfield"] + } + + /// Create a text field. + /// + /// - Parameters: + /// - name: The name to assign to the field. + /// - prompt: The key of the localized string to guide the user. + /// - value: The value to edit within the field. + public init(name: String, prompt: LocalizedStringKey? = nil, value: String? = nil) { + + self.name = name + self.prompt = prompt.map(PromptType.value(_:)) self.value = value self.classes = ["textfield"] } @@ -216,7 +267,14 @@ extension TextField: ViewModifier { } } -/// A component that displays a editable and expandable form control. +/// A view that represents a text editor. +/// +/// Use `TextEditor` to display a editable and expandable form control. +/// +/// ```swift +/// TextEditor(name: "Lorem", prompt: "Lorem ipsum") { +/// } +/// ``` public struct TextEditor: View, Modifiable, Identifiable { internal var id: String? @@ -225,7 +283,7 @@ public struct TextEditor: View, Modifiable, Identifiable { internal let name: String /// The placeholder for the field value. - internal let prompt: String? + internal let prompt: PromptType? /// The number of lines. internal var rows: Int = 3 @@ -239,11 +297,31 @@ public struct TextEditor: View, Modifiable, Identifiable { /// The events of the editor. internal var events: [String]? - /// Creates a text editor. + /// Create a text editor. + /// + /// - Parameters: + /// - name: The name to assign to the field. + /// - prompt: The prompt to guide the user. + /// - value: The value to edit within the field. + @_disfavoredOverload public init(name: String, prompt: String? = nil, @ContentBuilder content: () -> [String]) { self.name = name - self.prompt = prompt + self.prompt = prompt.map(PromptType.string(_:)) + self.content = content() + self.classes = ["texteditor"] + } + + /// Create a text editor. + /// + /// - Parameters: + /// - name: The name to assign to the field. + /// - prompt: The key of the localized string to guide the user. + /// - value: The value to edit within the field. + public init(name: String, prompt: LocalizedStringKey? = nil, @ContentBuilder content: () -> [String]) { + + self.name = name + self.prompt = prompt.map(PromptType.value(_:)) self.content = content() self.classes = ["texteditor"] } @@ -391,13 +469,24 @@ public struct Picker: View, Modifiable, Identifiable { } } -/// A component that displays a form control +/// A view that represents a check field. +/// +/// Use `CheckField` to present a list of options, where multiple options can be selected. +/// +/// ```swift +/// Picker(name: "lorem", selection: "ipsum") { +/// CheckField(value: "ipsum") { +/// "Lorem ipsum" +/// } +/// .tag("ipsum") +/// } +/// ``` public struct CheckField: View, Modifiable, Selectable, Identifiable { - /// The identifer for the label. + /// The identifer of the field. internal var id: String? - /// The identifier for the field. + /// The name of the field. internal var name: String? /// The content of the field. @@ -407,20 +496,37 @@ public struct CheckField: View, Modifiable, Selectable, Identifiable { internal var isSelected: Bool /// The content of the field. - internal var content: String + internal var content: Content /// The classes of the field. internal var classes: [String] - /// Creates a check field. + /// Create a check field. + /// + /// - Parameters: + /// - value: The current value of the field. + /// - content: The label content for the field. public init(value: String, content: () -> String) { - + self.value = value self.isSelected = false self.content = content() self.classes = ["checkfield"] } + /// Create a check field. + /// + /// - Parameters: + /// - localizedStringKey: The key of the localized string used as the label. + /// - value: The current value of the field. + public init(_ localizedStringKey: LocalizedStringKey, value: String) { + + self.value = value + self.isSelected = false + self.content = [LocalizedString(key: localizedStringKey)] + self.classes = ["checkfield"] + } + public var body: Content { Division { Input() @@ -517,13 +623,24 @@ extension CheckField: ViewModifier { } } -/// A component that displays +/// A view that represents a radio select. +/// +/// Use `RadioSelect` to present a list of options, where only one option can be selected. +/// +/// ```swift +/// Picker(name: "lorem", selection: "ipsum") { +/// RadioSelect(value: "ipsum") { +/// "Lorem ipsum" +/// } +/// .tag("ipsum") +/// } +/// ``` public struct RadioSelect: View, Modifiable, Selectable, Identifiable { - /// The identifier for the label. + /// The identifier of the select. internal var id: String? - /// The identifier of the select. + /// The name of the select. internal var name: String? /// The content of the select. @@ -533,12 +650,16 @@ public struct RadioSelect: View, Modifiable, Selectable, Identifiable { internal var isSelected: Bool /// The content of the select. - internal var content: String + internal var content: Content /// The classes of the select. internal var classes: [String] - /// Creates a radio select. + /// Create a radio select. + /// + /// - Parameters: + /// - value: The current value of the select. + /// - content: The label content for the select. public init(value: String, content: () -> String) { self.value = value @@ -547,6 +668,19 @@ public struct RadioSelect: View, Modifiable, Selectable, Identifiable { self.classes = ["radioselect"] } + /// Create a radio select. + /// + /// - Parameters: + /// - localizedStringKey: The key of the localized string used as the label. + /// - value: The current value of the select. + public init(_ localizedStringKey: LocalizedStringKey, value: String) { + + self.value = value + self.isSelected = false + self.content = [LocalizedString(key: localizedStringKey)] + self.classes = ["radioselect"] + } + public var body: Content { Division { Input() @@ -643,17 +777,30 @@ extension RadioSelect: ViewModifier { } } -/// A component that displays +/// A view that represents a selectfield. +/// +/// Use `SelectField` to present a list of options. +/// +/// ```swift +/// SelectField(name: "lorem", selection: "ipsum") { +/// RadioSelect(value: "ipsum") { +/// "Lorem ipsum" +/// } +/// .tag("ipsum") +/// } +/// ``` public struct SelectField: View, Modifiable, Identifiable { + /// The identifier of the field. internal var id: String? - /// The identifier of the field. + /// The name of the field. internal let name: String /// The placeholder for the field value. - internal let prompt: String? + internal let prompt: PromptType? + /// The selected value of the available options. internal let selection: String? /// The content of the field. @@ -665,21 +812,67 @@ public struct SelectField: View, Modifiable, Identifiable { /// The events of the field. internal var events: [String]? - /// Creates a select field. + /// Create a select field. + /// + /// - Parameters: + /// - name: The name to assign to the field. + /// - prompt: The prompt to guide the user. + /// - selection: The option to preselect. + /// - content: The options to choose from. + @_disfavoredOverload public init(name: String, prompt: String? = nil, selection: String? = nil, @ContentBuilder content: () -> [RadioSelect]) { self.name = name - self.prompt = prompt + self.prompt = prompt.map(PromptType.string(_:)) self.selection = selection self.content = content() self.classes = ["selectfield"] } - /// Creates a select field. + /// Create a select field. + /// + /// - Parameters: + /// - name: The name to assign to the field. + /// - prompt: The key of the localized string to guide the user. + /// - selection: The option to preselect. + /// - content: The options to choose from. + public init(name: String, prompt: LocalizedStringKey? = nil, selection: String? = nil, @ContentBuilder content: () -> [RadioSelect]) { + + self.name = name + self.prompt = prompt.map(PromptType.value(_:)) + self.selection = selection + self.content = content() + self.classes = ["selectfield"] + } + + /// Create a select field. + /// + /// - Parameters: + /// - name: The name to assign to the field. + /// - prompt: The prompt to guide the user. + /// - selection: The option to preselect. + /// - content: The options to choose from. + @_disfavoredOverload public init(name: String, prompt: String? = nil, selection: String? = nil, @ContentBuilder content: () -> [CheckField]) { self.name = name - self.prompt = prompt + self.prompt = prompt.map(PromptType.string(_:)) + self.selection = selection + self.content = content() + self.classes = ["selectfield"] + } + + /// Create a select field. + /// + /// - Parameters: + /// - name: The name to assign to the field. + /// - prompt: The prompt to guide the user. + /// - selection: The option to preselect. + /// - content: The options to choose from. + public init(name: String, prompt: LocalizedStringKey? = nil, selection: String? = nil, @ContentBuilder content: () -> [CheckField]) { + + self.name = name + self.prompt = prompt.map(PromptType.value(_:)) self.selection = selection self.content = content() self.classes = ["selectfield"] @@ -780,16 +973,23 @@ extension SelectField: ViewModifier { } } -/// A component that displays +/// A view that represents a secure field. +/// +/// Use `SecureField` to enter sensitive data in a secure way. +/// +/// ```swift +/// SecureField(name: "lorem", prompt: "Lorem ipsum") +/// ``` public struct SecureField: View, Modifiable, Identifiable { + /// The identifer of the field. internal var id: String? - /// The identifier of the field. + /// The name of the field. internal let name: String /// The placeholder for the field value. - internal let prompt: String? + internal let prompt: PromptType? /// The content of the field. internal let value: String? @@ -800,11 +1000,31 @@ public struct SecureField: View, Modifiable, Identifiable { /// The events of the field. internal var events: [String]? - /// Creates a password field. + /// Create a secure field. + /// + /// - Parameters: + /// - name: The name to assign to the field. + /// - prompt: The prompt to guide the user. + /// - content: The text content to edit within the field. + @_disfavoredOverload public init(name: String, prompt: String? = nil, value: String? = nil) { self.name = name - self.prompt = prompt + self.prompt = prompt.map(PromptType.string(_:)) + self.value = value + self.classes = ["securefield"] + } + + /// Create a secure field. + /// + /// - Parameters: + /// - name: The name to assign to the field. + /// - prompt: The key of the localized string to guide the user. + /// - content: The text content to edit within the field. + public init(name: String, prompt: LocalizedStringKey? = nil, value: String? = nil) { + + self.name = name + self.prompt = prompt.map(PromptType.value(_:)) self.value = value self.classes = ["securefield"] } @@ -1188,16 +1408,23 @@ extension DatePicker: ViewModifier { } } -/// A component that displays +/// A view that represents a search field. +/// +/// Use `SearchField` to find information in content. +/// +/// ```swift +/// SearchField(name: "lorem", prompt: "Lorem ipsum") +/// ``` public struct SearchField: View, Modifiable, Identifiable { + /// The identifier of the field. internal var id: String? - /// The identifier of the search field. + /// The name of the field. internal let name: String /// The placeholder for the field value. - internal let prompt: String? + internal let prompt: PromptType? /// The content of the field. internal let value: String? @@ -1208,12 +1435,32 @@ public struct SearchField: View, Modifiable, Identifiable { /// The events of the field. internal var events: [String]? - /// Creates a search field. + /// Create a search field. + /// + /// - Parameters: + /// - name: The name to assign to the field. + /// - prompt: The prompt to guide the user. + /// - value: The value to edit within the field. + @_disfavoredOverload public init(name: String, prompt: String? = nil, value: String? = nil) { self.name = name - self.prompt = prompt self.value = value + self.prompt = prompt.map(PromptType.string(_:)) + self.classes = ["searchfield"] + } + + /// Create a search field. + /// + /// - Parameters: + /// - name: The name to assign to the field. + /// - prompt: The key of the localized string to guide the user. + /// - value: The value to edit within the field. + public init(name: String, prompt: LocalizedStringKey? = nil, value: String? = nil) { + + self.name = name + self.value = value + self.prompt = prompt.map(PromptType.value(_:)) self.classes = ["searchfield"] } @@ -1366,16 +1613,25 @@ public struct Progress: View, Modifiable, Identifiable { } } -/// A component to edit and format text content. +/// A view that represents a text pad. +/// +/// Use `TextPad` to edit and format text content. +/// +/// ```swift +/// TextPad(name: "lorem", prompt: "Lorem ipsum") { +/// "Lorem ipsum..." +/// } +/// ``` public struct TextPad: View, Modifiable, Identifiable { + /// The identifier of the textpad. internal var id: String? - /// The identifier of the textpad. + /// The name of the textpad. internal let name: String /// The placeholder for the field value. - internal let prompt: String? + internal let prompt: PromptType? /// The number of lines. internal var rows: Int = 3 @@ -1386,11 +1642,31 @@ public struct TextPad: View, Modifiable, Identifiable { /// The classes of the textpad. internal var classes: [String] - /// Creates a textpad + /// Create a textpad. + /// + /// - Parameters: + /// - name: The name to assign to the field. + /// - prompt: The prompt to guide the user. + /// - content: The text content to edit within the field. + @_disfavoredOverload public init(name: String, prompt: String? = nil, @ContentBuilder content: () -> [String]) { self.name = name - self.prompt = prompt + self.prompt = prompt.map(PromptType.string(_:)) + self.content = content() + self.classes = ["textpad"] + } + + /// Create a textpad. + /// + /// - Parameters: + /// - name: The name to assign to the field. + /// - prompt: The key of the localized string to guide the user. + /// - content: The text content to edit within the field. + public init(name: String, prompt: LocalizedStringKey? = nil, @ContentBuilder content: () -> [String]) { + + self.name = name + self.prompt = prompt.map(PromptType.value(_:)) self.content = content() self.classes = ["textpad"] } diff --git a/Sources/HTMLKitComponents/Components/Link.swift b/Sources/HTMLKitComponents/Components/Link.swift index ce1cab00..86d67bbd 100644 --- a/Sources/HTMLKitComponents/Components/Link.swift +++ b/Sources/HTMLKitComponents/Components/Link.swift @@ -6,12 +6,21 @@ import HTMLKit import Foundation -/// A component that navigates to an target. +/// A view that represents a text link. +/// +/// Use `Link` to navigate to a target. +/// +/// ```swift +/// Link(destination: "https://..") { +/// "Lorem ipsum" +/// } +/// ``` public struct Link: View, Modifiable, Identifiable { + /// The unique identifier of the link. internal var id: String? - /// The target for the destination + /// The target behaviour for the destination internal let target: HTMLKit.Values.Target /// The url path of the target. @@ -26,7 +35,12 @@ public struct Link: View, Modifiable, Identifiable { /// The events of the link. internal var events: [String]? - /// Creates a link. + /// Create a link. + /// + /// - Parameters: + /// - destination: The url of the target to navigate to. + /// - target: The behaviour that determines how to open the target. + /// - content: The content displayed as the label. public init(destination: String, target: HTMLKit.Values.Target = .current, @ContentBuilder content: () -> [Content]) { self.destination = destination @@ -35,7 +49,12 @@ public struct Link: View, Modifiable, Identifiable { self.classes = ["link"] } - /// Creates a link. + /// Create a link. + /// + /// - Parameters: + /// - destination: The url of the target to navigate to. + /// - target: The behaviour that determines how to open the target. + /// - content: The content displayed as the label. public init(destination: URL, target: HTMLKit.Values.Target = .current, @ContentBuilder content: () -> [Content]) { self.destination = destination.absoluteString diff --git a/Sources/HTMLKitComponents/Extensions/Components+Input.swift b/Sources/HTMLKitComponents/Extensions/Components+Input.swift new file mode 100644 index 00000000..ef432931 --- /dev/null +++ b/Sources/HTMLKitComponents/Extensions/Components+Input.swift @@ -0,0 +1,29 @@ +import HTMLKit + +extension HTMLKit.Input { + + internal func placeholder(_ value: PromptType) -> HTMLKit.Input { + + switch value { + case .string(let string): + return self.placeholder(string) + + case .value(let value): + return self.placeholder(value) + } + } +} + +extension HTMLKit.TextArea { + + internal func placeholder(_ value: PromptType) -> HTMLKit.TextArea { + + switch value { + case .string(let string): + return self.placeholder(string) + + case .value(let value): + return self.placeholder(value) + } + } +} diff --git a/Sources/HTMLKitComponents/Primitives/DynamicType.swift b/Sources/HTMLKitComponents/Primitives/DynamicType.swift index dadd7cd2..c08cf60e 100644 --- a/Sources/HTMLKitComponents/Primitives/DynamicType.swift +++ b/Sources/HTMLKitComponents/Primitives/DynamicType.swift @@ -5,3 +5,13 @@ public enum DynamicType { case value(EnvironmentValue) case string(String) } + +/// An enum that represents a dynamic prompt type. +internal enum PromptType { + + /// Holds a key for the localized string. + case value(LocalizedStringKey) + + /// Holds a string. + case string(String) +} diff --git a/Tests/HTMLKitComponentsTests/Localization/fr/web.strings b/Tests/HTMLKitComponentsTests/Localization/fr/web.strings index 82199495..ef2368b3 100644 --- a/Tests/HTMLKitComponentsTests/Localization/fr/web.strings +++ b/Tests/HTMLKitComponentsTests/Localization/fr/web.strings @@ -1,2 +1,8 @@ /* A button label. */ "button.submit" = "Envoyer le formulaire"; + +"Password" = "Mot de passe"; + +"Forgot password?" = "Mot de passe oublié?"; + +"Create" = "Créer"; diff --git a/Tests/HTMLKitComponentsTests/LocalizationTests.swift b/Tests/HTMLKitComponentsTests/LocalizationTests.swift index d7209f9b..629fb6d1 100644 --- a/Tests/HTMLKitComponentsTests/LocalizationTests.swift +++ b/Tests/HTMLKitComponentsTests/LocalizationTests.swift @@ -31,6 +31,116 @@ final class LocalizationTests: XCTestCase { """ ) } + + func testFieldLabelLocalization() throws { + + let view = TestView { + FieldLabel("Password", for: "password") + } + + XCTAssertEqual(try renderer!.render(view: view), + """ + + """ + ) + } + + func testDisclosureLocalization() throws { + + let view = TestView { + Disclosure("Forgot password?") { + } + } + + XCTAssertEqual(try renderer!.render(view: view), + """ +
\ +
\ +

Mot de passe oublié?

\ + \ + \ + state indicator\ + \ + \ +
\ +
\ +
\ +
\ +
+ """ + ) + } + + func testCheckFieldLocalization() throws { + + let view = TestView { + CheckField("Password", value: "password") + } + + XCTAssertEqual(try renderer!.render(view: view), + """ +
\ + \ + \ +
+ """ + ) + } + + func testRadioSelectLocalization() throws { + + let view = TestView { + RadioSelect("Password", value: "password") + } + + XCTAssertEqual(try renderer!.render(view: view), + """ +
\ + \ + \ +
+ """ + ) + } + + func testButtonLocalization() throws { + + let view = TestView { + Button("Create", role: .submit) + } + + XCTAssertEqual(try renderer!.render(view: view), + """ + + """ + ) + } + + func testLinkLocalization() throws { + + let view = TestView { + LinkButton("Create", destination: "#") + } + + XCTAssertEqual(try renderer!.render(view: view), + """ + Créer + """ + ) + } + + func testPromptLocalization() throws { + + let view = TestView { + TextField(name: "password", prompt: "Password") + } + + XCTAssertEqual(try renderer!.render(view: view), + """ + + """ + ) + } } extension LocalizationTests {