Fix widget layout clipping and add comprehensive widget previews

- Fix LargeVotingView mood icons getting clipped at edges by using
  flexible HStack spacing with maxWidth: .infinity
- Fix VotingView medium layout with smaller icons and even distribution
- Add comprehensive #Preview macros for all widget states:
  - Vote widget: small/medium, voted/not voted, all mood states
  - Timeline widget: small/medium/large with various data states
- Reduce icon sizes and padding to fit within widget bounds
- Update accessibility labels and hints across views

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-12-24 09:53:40 -06:00
parent 5f7d909d62
commit be84825aba
33 changed files with 10467 additions and 9725 deletions

View File

@@ -172,12 +172,12 @@ extension DayView {
HStack(spacing: 10) {
// Calendar icon
Image(systemName: "calendar")
.font(.system(size: 16, weight: .semibold))
.font(.body.weight(.semibold))
.foregroundColor(textColor.opacity(0.6))
.accessibilityHidden(true)
Text("\(Random.monthName(fromMonthInt: month)) \(String(year))")
.font(.system(size: 20, weight: .bold, design: .rounded))
.font(.title3.weight(.bold))
.foregroundColor(textColor)
Spacer()
@@ -194,7 +194,7 @@ extension DayView {
HStack(spacing: 0) {
// Large month number as hero element
Text(String(format: "%02d", month))
.font(.system(size: 48, weight: .black, design: .rounded))
.font(.largeTitle.weight(.black))
.foregroundStyle(
LinearGradient(
colors: [textColor, textColor.opacity(0.4)],
@@ -206,12 +206,12 @@ extension DayView {
VStack(alignment: .leading, spacing: 2) {
Text(Random.monthName(fromMonthInt: month).uppercased())
.font(.system(size: 14, weight: .bold, design: .rounded))
.font(.subheadline.weight(.bold))
.tracking(3)
.foregroundColor(textColor)
Text(String(year))
.font(.system(size: 12, weight: .medium, design: .rounded))
.font(.caption.weight(.medium))
.foregroundColor(textColor.opacity(0.5))
}
@@ -253,12 +253,12 @@ extension DayView {
HStack(alignment: .firstTextBaseline, spacing: 12) {
// Large serif month name
Text(Random.monthName(fromMonthInt: month).uppercased())
.font(.system(size: 28, weight: .regular, design: .serif))
.font(.title.weight(.regular))
.foregroundColor(textColor)
// Year in lighter weight
Text(String(year))
.font(.system(size: 16, weight: .light, design: .serif))
.font(.body.weight(.light))
.italic()
.foregroundColor(textColor.opacity(0.5))
@@ -266,7 +266,7 @@ extension DayView {
// Decorative flourish
Text("§")
.font(.system(size: 20, weight: .regular, design: .serif))
.font(.title3.weight(.regular))
.foregroundColor(textColor.opacity(0.3))
}
.padding(.horizontal, 16)
@@ -284,12 +284,12 @@ extension DayView {
HStack(spacing: 12) {
// Glowing terminal prompt
Text(">")
.font(.system(size: 18, weight: .bold, design: .monospaced))
.font(.headline.weight(.bold).monospaced())
.foregroundColor(Color(red: 0.4, green: 1.0, blue: 0.4))
.shadow(color: Color(red: 0.4, green: 1.0, blue: 0.4).opacity(0.8), radius: 4, x: 0, y: 0)
Text("\(Random.monthName(fromMonthInt: month).uppercased())_\(String(year))")
.font(.system(size: 16, weight: .bold, design: .monospaced))
.font(.body.weight(.bold).monospaced())
.foregroundColor(.white)
.shadow(color: .white.opacity(0.3), radius: 2, x: 0, y: 0)
@@ -329,12 +329,12 @@ extension DayView {
VStack(alignment: .leading, spacing: 2) {
Text(Random.monthName(fromMonthInt: month))
.font(.system(size: 18, weight: .thin))
.font(.headline.weight(.thin))
.tracking(4)
.foregroundColor(textColor)
Text(String(year))
.font(.system(size: 11, weight: .ultraLight))
.font(.caption2.weight(.ultraLight))
.foregroundColor(textColor.opacity(0.4))
}
@@ -371,7 +371,7 @@ extension DayView {
// Glass content
HStack(spacing: 12) {
Text(Random.monthName(fromMonthInt: month))
.font(.system(size: 20, weight: .semibold))
.font(.title3.weight(.semibold))
.foregroundColor(textColor)
Capsule()
@@ -379,7 +379,7 @@ extension DayView {
.frame(width: 4, height: 4)
Text(String(year))
.font(.system(size: 16, weight: .medium))
.font(.body.weight(.medium))
.foregroundColor(textColor.opacity(0.6))
Spacer()
@@ -405,11 +405,11 @@ extension DayView {
VStack(alignment: .leading, spacing: 2) {
Text("SIDE A")
.font(.system(size: 10, weight: .bold, design: .monospaced))
.font(.caption2.weight(.bold).monospaced())
.foregroundColor(textColor.opacity(0.4))
Text("\(Random.monthName(fromMonthInt: month).uppercased()) '\(String(year).suffix(2))")
.font(.system(size: 16, weight: .black, design: .rounded))
.font(.body.weight(.black))
.foregroundColor(textColor)
.tracking(1)
}
@@ -418,7 +418,7 @@ extension DayView {
// Track counter
Text(String(format: "%02d", month))
.font(.system(size: 20, weight: .bold, design: .monospaced))
.font(.title3.weight(.bold).monospaced())
.foregroundColor(textColor.opacity(0.3))
}
.padding(.horizontal, 16)
@@ -443,11 +443,11 @@ extension DayView {
HStack(spacing: 16) {
Text(Random.monthName(fromMonthInt: month))
.font(.system(size: 22, weight: .light))
.font(.title2.weight(.light))
.foregroundColor(textColor)
Text(String(year))
.font(.system(size: 14, weight: .regular))
.font(.subheadline.weight(.regular))
.foregroundColor(textColor.opacity(0.4))
Spacer()
@@ -483,11 +483,11 @@ extension DayView {
.frame(width: 2)
Text(Random.monthName(fromMonthInt: month))
.font(.system(size: 18, weight: .regular, design: .serif))
.font(.headline.weight(.regular))
.foregroundColor(textColor)
Text(String(year))
.font(.system(size: 14, weight: .light, design: .serif))
.font(.subheadline.weight(.light))
.italic()
.foregroundColor(textColor.opacity(0.5))
@@ -524,7 +524,7 @@ extension DayView {
return HStack(spacing: 0) {
// Month number
Text(String(format: "%02d", month))
.font(.system(size: 32, weight: .thin))
.font(.title.weight(.thin))
.foregroundColor(hasData ? barColor.opacity(0.6) : textColor.opacity(0.3))
.frame(width: 50)
@@ -554,16 +554,16 @@ extension DayView {
VStack(alignment: .trailing, spacing: 2) {
Text(Random.monthName(fromMonthInt: month))
.font(.system(size: 14, weight: .medium))
.font(.subheadline.weight(.medium))
.foregroundColor(textColor)
if hasData {
Text(String(format: "%.1f avg", averageMood + 1)) // Display as 1-5
.font(.system(size: 10, weight: .semibold))
.font(.caption2.weight(.semibold))
.foregroundColor(barColor)
} else {
Text(String(year))
.font(.system(size: 11, weight: .regular))
.font(.caption2.weight(.regular))
.foregroundColor(textColor.opacity(0.4))
}
}
@@ -576,11 +576,11 @@ extension DayView {
private func patternSectionHeader(month: Int, year: Int) -> some View {
HStack(spacing: 10) {
Image(systemName: "calendar")
.font(.system(size: 16, weight: .semibold))
.font(.body.weight(.semibold))
.foregroundColor(textColor.opacity(0.6))
Text("\(Random.monthName(fromMonthInt: month)) \(String(year))")
.font(.system(size: 20, weight: .bold, design: .rounded))
.font(.title3.weight(.bold))
.foregroundColor(textColor)
Spacer()
@@ -630,12 +630,12 @@ extension DayView {
VStack(alignment: .leading, spacing: 2) {
Text(Random.monthName(fromMonthInt: month).uppercased())
.font(.system(size: 16, weight: .bold, design: .serif))
.font(.body.weight(.bold))
.foregroundColor(Color(red: 0.9, green: 0.85, blue: 0.75))
.shadow(color: .black.opacity(0.3), radius: 1, x: 0, y: 1)
Text(String(year))
.font(.system(size: 12, weight: .medium, design: .serif))
.font(.caption.weight(.medium))
.foregroundColor(Color(red: 0.8, green: 0.7, blue: 0.55))
}
.padding(.leading, 12)
@@ -726,17 +726,17 @@ extension DayView {
.blur(radius: 4)
Text(String(format: "%02d", month))
.font(.system(size: 14, weight: .semibold, design: .rounded))
.font(.subheadline.weight(.semibold))
.foregroundColor(textColor)
}
VStack(alignment: .leading, spacing: 2) {
Text(Random.monthName(fromMonthInt: month))
.font(.system(size: 18, weight: .medium))
.font(.headline.weight(.medium))
.foregroundColor(textColor)
Text(String(year))
.font(.system(size: 12, weight: .regular))
.font(.caption.weight(.regular))
.foregroundColor(textColor.opacity(0.5))
}
@@ -811,18 +811,18 @@ extension DayView {
.frame(width: 44, height: 44)
Image(systemName: "gyroscope")
.font(.system(size: 22, weight: .medium))
.font(.title2.weight(.medium))
.foregroundColor(.white)
}
.shadow(color: Color.purple.opacity(0.3), radius: 8, x: 0, y: 4)
VStack(alignment: .leading, spacing: 2) {
Text(Random.monthName(fromMonthInt: month))
.font(.system(size: 20, weight: .semibold))
.font(.title3.weight(.semibold))
.foregroundColor(textColor)
Text(String(year))
.font(.system(size: 13, weight: .medium))
.font(.caption.weight(.medium))
.foregroundColor(textColor.opacity(0.5))
}
@@ -830,7 +830,7 @@ extension DayView {
// Tilt indicator
Image(systemName: "iphone.gen3.radiowaves.left.and.right")
.font(.system(size: 18))
.font(.headline)
.foregroundColor(textColor.opacity(0.3))
}
.padding(.horizontal, 18)
@@ -852,15 +852,15 @@ extension DayView {
.frame(width: 3, height: 16)
Text("\(Random.monthName(fromMonthInt: month).prefix(3).uppercased())")
.font(.system(size: 11, weight: .bold, design: .monospaced))
.font(.caption2.weight(.bold).monospaced())
.foregroundColor(textColor.opacity(0.6))
Text("")
.font(.system(size: 8))
.font(.caption2)
.foregroundColor(textColor.opacity(0.3))
Text(String(year))
.font(.system(size: 11, weight: .medium, design: .monospaced))
.font(.caption2.weight(.medium).monospaced())
.foregroundColor(textColor.opacity(0.4))
// Thin separator line