Created
February 7, 2025 05:40
-
-
Save mireabot/a24e419f8965040ca3e28c70dd2d3d28 to your computer and use it in GitHub Desktop.
Configurable TextField SwiftUI component
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
// MARK: - Internal Configurations | |
public struct ColorConfiguration { | |
public var light: Color | |
public var dark: Color | |
public init(light: Color, dark: Color) { | |
self.light = light | |
self.dark = dark | |
} | |
} | |
public struct PaddingConfiguration { | |
public var vertical: CGFloat | |
public var horizontal: CGFloat | |
public init( | |
vertical: CGFloat, | |
horizontal: CGFloat | |
) { | |
self.vertical = vertical | |
self.horizontal = horizontal | |
} | |
} | |
// MARK: - Text Field Configuration | |
public struct SXTextFieldConfiguration { | |
// MARK: - Properties | |
var backgroundColor: ColorConfiguration | |
var placeholderColor: ColorConfiguration | |
var placeholderFont: Font | |
var padding: PaddingConfiguration | |
var cornerRadius: CGFloat | |
// MARK: - Default configuration | |
public static let `default` = SXTextFieldConfiguration( | |
backgroundColor: ColorConfiguration( | |
light: .init(uiColor: .systemGray2), | |
dark: .black | |
), | |
placeholderColor: ColorConfiguration( | |
light: .secondary, | |
dark: .secondary | |
), | |
placeholderFont: .footnote, | |
padding: .init(vertical: 12, horizontal: 12), | |
cornerRadius: 8 | |
) | |
// MARK: - Initializer for custom configuration | |
public init( | |
backgroundColor: ColorConfiguration, | |
placeholderColor: ColorConfiguration, | |
placeholderFont: Font, | |
padding: PaddingConfiguration, | |
cornerRadius: CGFloat | |
) { | |
self.backgroundColor = backgroundColor | |
self.placeholderColor = placeholderColor | |
self.placeholderFont = placeholderFont | |
self.padding = padding | |
self.cornerRadius = cornerRadius | |
} | |
} | |
// MARK: - Text Field Component | |
public struct SXTextField: View { | |
var text: Binding<String> | |
var header: String | |
var placeholder: String | |
var configuration: SXTextFieldConfiguration | |
@Environment(\.colorScheme) private var colorScheme | |
public init( | |
text: Binding<String>, | |
header: String, | |
placeholder: String, | |
configuration: SXTextFieldConfiguration = .default | |
) { | |
self.text = text | |
self.header = header | |
self.placeholder = placeholder | |
self.configuration = configuration | |
} | |
private var currentBackgroundColor: Color { | |
colorScheme == .light ? | |
configuration.backgroundColor.light : | |
configuration.backgroundColor.dark | |
} | |
private var currentTextColor: Color { | |
colorScheme == .light ? | |
configuration.placeholderColor.light : | |
configuration.placeholderColor.dark | |
} | |
public var body: some View { | |
VStack(alignment: .leading, spacing: 5) { | |
Text(header) | |
.font(configuration.placeholderFont) | |
.foregroundColor(currentTextColor) | |
TextField(placeholder, text: text) | |
.font(.headlineRegular) | |
.autocorrectionDisabled(true) | |
} | |
.padding(.vertical, configuration.padding.vertical) | |
.padding(.horizontal, configuration.padding.horizontal) | |
.background(currentBackgroundColor) | |
.cornerRadius(configuration.cornerRadius) | |
} | |
} | |
// MARK: - Custom configuration | |
extension SXTextFieldConfiguration { | |
static var customConfig : SXTextFieldConfiguration { | |
return .init( | |
backgroundColor: .init( | |
light: .init(uiColor: .systemGray6), | |
dark: .init(uiColor: .systemGray6).opacity(0.3)), | |
placeholderColor: .init( | |
light: .purple, | |
dark: .purple.opacity(0.3)), | |
placeholderFont: .subheadline, | |
padding: .init(vertical: 16, horizontal: 16), | |
cornerRadius: 12) | |
} | |
} | |
// MARK: - Usage Example | |
struct TextFieldDemo: View { | |
@State private var message = "" | |
var body: some View { | |
SXTextField( | |
text: $message, | |
header: "Transaction Name", | |
placeholder: "What did you spend money on?", | |
configuration: .default | |
) | |
SXTextField( | |
text: $message, | |
header: "Transaction Name", | |
placeholder: "What did you spend money on?", | |
configuration: .customConfig | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment