feat: Updates styles

This commit is contained in:
2025-02-26 22:13:38 -05:00
parent a15e54e0e4
commit 36e00cd007
11 changed files with 67 additions and 43 deletions

View File

@@ -1,7 +1,5 @@
@import 'tailwindcss';
@config '../tailwind.config.js';
/*
The default border color has changed to `currentColor` in Tailwind CSS v4,
so we've added these compatibility styles to make sure everything still

File diff suppressed because one or more lines are too long

View File

@@ -4,7 +4,7 @@ import Routes
import Vapor
import VaporElementary
@preconcurrency import VaporRouting
import ViewControllerLive
import ViewController
// configures your application
public func configure(_ app: Application) async throws {

View File

@@ -11,8 +11,10 @@ public struct SubmitButton: HTML, Sendable {
button(
.type(.submit),
.class("""
w-full \(bg: .blue) \(text: .yellow) font-bold py-3 rounded-md
hover:\(bg: .darkBlue) transition-colors
w-full font-bold py-3 rounded-md transition-colors
bg-yellow-300 dark:bg-blue-500
hover:bg-yellow-400 hover:dark:bg-blue-600
text-blue-500 dark:text-yellow-300
""")
) { label }
}

View File

@@ -32,12 +32,16 @@ public enum Color {
}
public enum BorderColor: Sendable {
case blue
case darkGray
case darkYellow
case gray
case yellow
var color: String {
switch self {
case .blue: return "border-blue-500"
case .darkGray: return "border-gray-400"
case .darkYellow: return "border-yellow-800"
case .gray: return "border-gray-300"
case .yellow: return "border-yellow-300"

View File

@@ -18,7 +18,7 @@ public struct FormHeader: HTML, Sendable {
public var content: some HTML {
LabeledContent {
h2(.class("text-2xl font-extrabold dark:\(text: .white)")) { label }
h2(.class("text-2xl font-extrabold text-gray-600 dark:text-slate-200")) { label }
} label: {
SVG(svg, color: .blue)
}
@@ -50,8 +50,8 @@ public struct Input: HTML, Sendable {
input(
.id(id), .placeholder(placeholder), .name(name ?? id),
.class("""
w-full px-4 py-2 border \(border: .gray) rounded-md focus:ring-2
focus:ring-yellow-800 focus:border-yellow-800 \(text: .darkGray) dark:\(text: .white)
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
""")
)
}
@@ -74,7 +74,7 @@ public struct InputLabel<InputLabel: HTML>: HTML {
public var content: some HTML<HTMLTag.label> {
label(
.for(forInputId),
.class("block text-sm font-medium \(text: .darkGray) dark:\(text: .gray) mb-2")
.class("block text-sm font-medium text-blue-500 dark:text-gray-300 mb-2")
) {
self.inputLabel
}

View File

@@ -10,8 +10,12 @@ public struct ResultContainer<Body: HTML>: HTML {
}
public var content: some HTML {
div(.class("mt-6 p-6 bg-blue-50 dark:bg-slate-400 rounded-lg")) {
h3(.class("text-xl font-semibold \(text: .darkGray) mb-4")) { "Results" }
div(.class("""
mt-6 p-6 rounded-lg border border-blue-500
bg-blue-50 dark:bg-slate-600
text-blue-500 dark:text-slate-200
""")) {
h3(.class("text-xl font-semibold mb-4")) { "Results" }
body
}
}

View File

@@ -0,0 +1,14 @@
import Foundation
private let numberFormatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.maximumFractionDigits = 2
return formatter
}()
extension String.StringInterpolation {
mutating func appendInterpolation(double: Double) {
appendInterpolation(numberFormatter.string(from: NSNumber(value: double))!)
}
}

View File

@@ -31,7 +31,7 @@ struct MainPage<Inner: HTML>: SendableHTMLDocument where Inner: Sendable {
}
var body: some HTML {
main(.class("bg-white dark:bg-gray-800")) {
main(.class("bg-slate-100 dark:bg-gray-800")) {
div(.class("min-h-screen")) {
Header()
PageContent(body: inner)
@@ -46,12 +46,13 @@ private struct Header: HTML {
header(.class("\(bg: .blue) mb-8 flex flex-row gap-2 border \(border: .yellow)")) {
a(
.href(route: .index),
.class("flex flex-row gap-2 \(bg: .yellow) pe-2 rounded-e-lg \(text: .blue) hover:\(text: .darkBlue)")
.class("group flex flex-row gap-2 \(bg: .yellow) pe-2 rounded-e-lg \(text: .blue) hover:text-blue-600")
) {
img(.src("/images/toolbox.svg"), .width(40), .height(40), .class("py-1"))
div(.class("flex flex-row mt-2")) {
h2(.class("text-2xl font-extrabold pe-3")) { "HVAC-Toolbox" }
SVG(.wind, color: .blue)
.attributes(.class("group-hover:text-blue-600"))
}
}
nav(.class("flex flex-row gap-2 p-2 mt-2")) {
@@ -78,7 +79,7 @@ private struct PageContent<Body: HTML>: HTML where Body: Sendable {
var content: some HTML {
div(.class("mx-5 lg:mx-20")) {
div(.class("rounded-xl shadow-lg \(bg: .slate) dark:\(bg: .darkSlate) p-8")) {
div(.class("rounded-xl shadow-lg bg-white dark:bg-slate-700 p-8")) {
body()
}
}

View File

@@ -7,7 +7,7 @@ struct MoldRiskForm: HTML {
var content: some HTML {
FormHeader(label: "Mold Risk Calculator", svg: .thermometer)
form {
form(.action("#")) {
div(.class("space-y-6")) {
LabeledContent(label: "Indoor Temperature (°F)") {
Input(id: "temperature", placeholder: "Dry bulb temperature")
@@ -43,7 +43,7 @@ struct MoldRiskResponse: HTML {
"Risk Level: \(response.riskLevel.rawValue.capitalized)"
}
} label: {
SVG(.exclamation, color: "\(text: .green) dark:text-lime-600")
SVG(.exclamation, color: "text-green-600 dark:text-lime-600")
}
.attributes(.class("flex items-center gap-2"))
}
@@ -51,8 +51,8 @@ struct MoldRiskResponse: HTML {
PsychrometricPropertiesGrid(properties: response.psychrometricProperties)
.attributes(.class("mx-6"))
div(.class("mt-8 p-4 bg-gray-700 rounded-md shadow-md border border-blue-500")) {
p(.class("text-sm \(text: .blue)")) {
div(.class("mt-8 p-4 bg-gray-100 dark:bg-gray-700 rounded-md shadow-md border border-blue-500")) {
p(.class("text-sm text-blue-500")) {
span(.class("font-extrabold pe-2")) { "Note:" }
"""
These calculations are based on typical indoor conditions and common mold species. Actual mold growth can
@@ -70,22 +70,35 @@ struct PsychrometricPropertiesGrid: HTML {
var content: some HTML<HTMLTag.div> {
div(.class("grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mt-6 md:mx-20")) {
displayProperty("Dew Point", "\(properties.dewPoint.value) \(properties.dewPoint.units.symbol)")
displayProperty("Wet Bulb", "\(properties.wetBulb.value) \(properties.wetBulb.units.symbol)")
displayProperty("Enthalpy", "\(properties.enthalpy.value) \(properties.wetBulb.units.symbol)")
displayProperty("Density", "\(properties.density.value) \(properties.density.units.rawValue)")
displayProperty("Vapor Pressure", "\(properties.vaporPressure.value) \(properties.vaporPressure.units.symbol)")
displayProperty("Specific Volume", "\(properties.specificVolume.rawValue)")
displayProperty("Absolute Humidity", "\(properties.absoluteHumidity.value) \(properties.absoluteHumidity.units.symbol)")
displayProperty("Humidity Ratio", "\(properties.humidityRatio.value)")
displayProperty("Degree of Saturation", "\(properties.degreeOfSaturation.value)")
displayProperty("Dew Point", \.dewPoint.rawValue)
displayProperty("Wet Bulb", \.wetBulb.rawValue)
displayProperty("Enthalpy", \.enthalpy.rawValue)
displayProperty("Density", \.density.rawValue)
displayProperty("Vapor Pressure", \.vaporPressure.rawValue)
displayProperty("Specific Volume", properties.specificVolume.rawValue)
displayProperty("Absolute Humidity", \.absoluteHumidity)
displayProperty("Humidity Ratio", properties.humidityRatio.value)
displayProperty("Degree of Saturation", properties.degreeOfSaturation.value)
}
}
func displayProperty(_ label: String, _ value: String) -> some HTML {
p(.class("\(text: .darkGray) dark:\(text: .white)")) {
private func displayProperty(_ label: String, _ value: Double, _ symbol: String? = nil) -> some HTML {
let symbol = "\(symbol == nil ? "" : " \(symbol!)")"
return p(.class("text-blue-500 dark:text-slate-200")) {
span(.class("font-semibold")) { "\(label): " }
span(.class("font-light")) { value }
span(.class("font-light")) {
"\(double: value)\(symbol)"
}
}
}
private func displayProperty<N: NumberWithUnitOfMeasure>(
_ label: String,
_ keyPath: KeyPath<PsychrometricProperties, N>
) -> some HTML where N.Number == Double, N.Units: RawRepresentable, N.Units.RawValue == String {
let property = properties[keyPath: keyPath]
return displayProperty(label, property.rawValue, property.units.rawValue)
}
}

View File

@@ -1,12 +0,0 @@
import defaultTheme from "tailwindcss/defaultTheme";
const colors = require('tailwindcss/colors');
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./Sources/ViewControllerLive/Views/*.swift",
"./Sources/ViewControllerLive/*.swift",
"./Public/images/*.svg",
"./Sources/Styleguide/*.swift"
],
};