Skip to content

Instantly share code, notes, and snippets.

@mireabot
Created February 7, 2025 05:40
Show Gist options
  • Save mireabot/a24e419f8965040ca3e28c70dd2d3d28 to your computer and use it in GitHub Desktop.
Save mireabot/a24e419f8965040ca3e28c70dd2d3d28 to your computer and use it in GitHub Desktop.
Configurable TextField SwiftUI component
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