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

87 lines
1.9 KiB
Swift

import Elementary
/// 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")) { 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 rounded-md
focus:ring-2 focus:ring-yellow-800 focus:border-yellow-800
placeholder-shown:!border-gray-400
invalid:border-red-500 out-of-range:border-red-500
""")
)
}
}
/// 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 mb-2")
) {
self.inputLabel
}
}
}
extension InputLabel: Sendable where InputLabel: Sendable {}