Files
OpenAppLock/Severed/Views/Components/DayOfWeekPicker.swift
Brendan Chen 4ee8f01d21 fix: editor usability and visual polish from UI scan
- Rule name is now an inline text field at the top of the editor; the
  pencil/rename button and alert are gone (it was unclear what the edit
  button did). Names are sanitized on commit: trimmed, falling back to
  the kind's default when emptied
- Day-of-week toggles fill the full row width with equal cells and
  >= 44pt tap targets
- 'Add Rule' commit button sits on a bar-material bottom inset so form
  content no longer collides with it while scrolling (found via
  computer-use scan; verified clean in a follow-up scan)
- Tests: 95 passing — new specs for the inline rename flow, day-toggle
  geometry, and name sanitization; three tests now scroll to reach
  bottom-of-form controls, matching real user behavior
- Spec §6 updated for the editor changes
2026-06-12 15:44:25 -04:00

65 lines
1.9 KiB
Swift

//
// DayOfWeekPicker.swift
// Severed
//
import SwiftUI
/// Seven circular day toggles (S M T W T F S) using system colors, meant to
/// sit inside a Form/List row. The day-set summary is shown by the enclosing
/// section header.
struct DayOfWeekPicker: View {
@Binding var days: Set<Weekday>
var body: some View {
HStack(spacing: 0) {
ForEach(Weekday.displayOrder, id: \.self) { day in
dayToggle(day)
}
}
}
private func dayToggle(_ day: Weekday) -> some View {
let isOn = days.contains(day)
return Button {
if isOn {
days.remove(day)
} else {
days.insert(day)
}
} label: {
Text(day.shortLabel)
.font(.subheadline.weight(.semibold))
.foregroundStyle(isOn ? Color.white : Color.secondary)
.frame(width: 38, height: 38)
.background(
isOn ? AnyShapeStyle(.tint) : AnyShapeStyle(Color(.tertiarySystemFill)),
in: Circle()
)
// Each cell takes an equal share of the row and at least a
// 44pt-tall hit area, so the whole strip is comfortably tappable.
.frame(maxWidth: .infinity, minHeight: 44)
.contentShape(Rectangle())
}
.buttonStyle(.borderless)
.accessibilityIdentifier("dayToggle-\(day.rawValue)")
.accessibilityLabel(day.abbreviation)
.accessibilityAddTraits(isOn ? .isSelected : [])
}
}
#Preview {
@Previewable @State var days = Weekday.weekdays
Form {
Section {
DayOfWeekPicker(days: $days)
} header: {
HStack {
Text("On these days").textCase(nil)
Spacer()
Text(days.summary).textCase(nil)
}
}
}
}