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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user