- 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 Co-Authored-By: Claude <noreply@anthropic.com>
65 lines
1.9 KiB
Swift
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)
|
|
}
|
|
}
|
|
}
|
|
}
|