Files
swift-hvac-toolbox/Sources/Styleguide/FormElements.swift

87 lines
2.0 KiB
Swift

import Elementary
// TODO: Experiment with removing text colors and move them further up the call stack.
/// A styled header for a form element, which consists of an
/// svg image and label / name for the form.
///
public struct FormHeader: HTML, Sendable {
let label: String
let svg: SVGType
public init(
label: String,
svg: SVGType
) {
self.label = label
self.svg = svg
}
public var content: some HTML {
LabeledContent {
h2(.class("text-2xl font-extrabold text-gray-600 dark:text-slate-200")) { label }
} label: {
SVG(svg, color: .blue)
}
.attributes(.class("flex items-center gap-3 mb-6"))
}
}
/// A styled form input, does not contain the input type which is generally
/// added at the call site.
///
/// **Example:**
/// ```swift
/// Input(id: "email", placeholder: "Email")
/// .attributes(.type(.email))
/// ```
///
public struct Input: HTML, Sendable {
let id: String
let name: String?
let placeholder: String
public init(id: String, name: String? = nil, placeholder: String) {
self.id = id
self.name = name
self.placeholder = placeholder
}
public var content: some HTML<HTMLTag.input> {
input(
.id(id), .placeholder(placeholder), .name(name ?? id),
.class("""
w-full px-4 py-2 border border-gray-300 dark:border-gray-400 rounded-md focus:ring-2
focus:ring-yellow-800 focus:border-yellow-800 text-blue-600 dark:text-gray-300
""")
)
}
}
/// A style form input label.
public struct InputLabel<InputLabel: HTML>: HTML {
let forInputId: String
let inputLabel: InputLabel
public init(
for forInputId: String,
@HTMLBuilder label: () -> InputLabel
) {
self.forInputId = forInputId
self.inputLabel = label()
}
public var content: some HTML<HTMLTag.label> {
label(
.for(forInputId),
.class("block text-sm font-medium text-blue-500 dark:text-gray-300 mb-2")
) {
self.inputLabel
}
}
}
extension InputLabel: Sendable where InputLabel: Sendable {}