Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ struct EventFormTimeField: View {
_showsMenu = State(initialValue: openPicker)
}

/// The row for the selected time, or the quarter hour before it (3:10 opens on 3 PM).
private var selectedQuarterHourLabel: String {
let quarter = (date.timeIntervalSince1970 / 900).rounded(.down) * 900
return EventFormTimeFormat.formatLabel(for: Date(timeIntervalSince1970: quarter))
}

var body: some View {
Button {
showsMenu = true
Expand All @@ -39,32 +45,37 @@ struct EventFormTimeField: View {
.buttonStyle(.plain)
.accessibilityIdentifier(accessibilityIdentifier)
.popover(isPresented: $showsMenu, arrowEdge: .bottom) {
ScrollView {
LazyVStack(alignment: .leading, spacing: 0) {
ForEach(EventFormTimeFormat.quarterHourLabels(), id: \.self) { label in
Button {
if let merged = EventFormTimeFormat.mergeTime(into: date, label: label) {
date = merged
ScrollViewReader { proxy in
ScrollView {
LazyVStack(alignment: .leading, spacing: 0) {
ForEach(EventFormTimeFormat.quarterHourLabels(), id: \.self) { label in
Button {
if let merged = EventFormTimeFormat.mergeTime(into: date, label: label) {
date = merged
}
showsMenu = false
} label: {
Text(label)
.font(.rubik(NativeWebLayoutTokens.fontSizeBody))
.foregroundStyle(
label == EventFormTimeFormat.formatLabel(for: date)
? theme.onAccentColor : theme.textColor
)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, 10)
.padding(.vertical, 6)
.background(
label == EventFormTimeFormat.formatLabel(for: date)
? theme.accentColor : Color.clear
)
}
showsMenu = false
} label: {
Text(label)
.font(.rubik(NativeWebLayoutTokens.fontSizeBody))
.foregroundStyle(
label == EventFormTimeFormat.formatLabel(for: date)
? theme.onAccentColor : theme.textColor
)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, 10)
.padding(.vertical, 6)
.background(
label == EventFormTimeFormat.formatLabel(for: date)
? theme.accentColor : Color.clear
)
.buttonStyle(.plain)
.id(label)
}
.buttonStyle(.plain)
}
}
// Web opens the list centered on the selected time, not at 12 AM.
.onAppear { proxy.scrollTo(selectedQuarterHourLabel, anchor: .center) }
}
.frame(width: 120, height: 220)
.background(theme.surfacePanelColor)
Expand Down
2 changes: 1 addition & 1 deletion docs/features/desktop-web-parity-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ This checklist compares **apps/calendar-web** (reference UI) with **apps/calenda
| Replaces sidebar body while open | ✅ | `EventFormView` in `RootView` |
| Date field **MM.DD.YY** closed display | 🟡 | `EventFormCompactDateField` + `EventFormDateFormat`; verify parity capture after merge |
| Datepicker open Enter/Space/ArrowDown | 🟡 | Audit `EventFormScheduleSection.swift` vs web |
| Time pickers | 🟡 | Visual parity pass needed |
| Time pickers | 🟡 | The list opens centered on the selected time (or the quarter hour before it) like web. Still differs: macOS shows the list and the date picker as AppKit popovers that can open to the side of the field, while web drops them below it |
| Location / Meet / guests grouping | ✅ | #4607 single `EventFormCard` + description card (web #4599) |
| Color row Mod+digit hint | 🟡 | Trailing ⌘ 6 keycaps like web `EventColorPicker`; web swaps to ← → · Enter while a swatch has focus, macOS has no swatch arrow keys yet. The demo capture also shows a guest row on macOS only: the demo fixture calendar can invite (UI tests need it), the real local calendar cannot |
| Save bar: accent fill, on-accent text, space-between, **⌘Enter** hint | 🟡 | macOS save bar matches accent + Mod+Enter keycap (#4610); sidebar shows web save-draft tip (#4614) |
Expand Down
Loading