diff --git a/apps/calendar-macos/CompassData/Sources/CompassData/NativeCalendarRootModel+EventForm.swift b/apps/calendar-macos/CompassData/Sources/CompassData/NativeCalendarRootModel+EventForm.swift index 975b600139..c6048ccdbb 100644 --- a/apps/calendar-macos/CompassData/Sources/CompassData/NativeCalendarRootModel+EventForm.swift +++ b/apps/calendar-macos/CompassData/Sources/CompassData/NativeCalendarRootModel+EventForm.swift @@ -19,7 +19,7 @@ extension NativeCalendarRootModel { } /// Web `EventColorPicker` order: the calendar-default swatch, then each slot. - public static let colorSwatchOptions: [EventColorSlot?] = [nil] + EventColorSlot.allCases.map(Optional.some) + public static let colorSwatchOptions: [EventColorSlot?] = [nil] + EventColorSlot.webOrder.map(Optional.some) /// Web picker arrows: move focus between swatches without changing the color. public func moveColorSwatchFocus(by delta: Int) { diff --git a/apps/calendar-macos/CompassData/Tests/CompassDataTests/EventFormColorSwatchKeysTests.swift b/apps/calendar-macos/CompassData/Tests/CompassDataTests/EventFormColorSwatchKeysTests.swift index 68c41e7e47..8072064f7a 100644 --- a/apps/calendar-macos/CompassData/Tests/CompassDataTests/EventFormColorSwatchKeysTests.swift +++ b/apps/calendar-macos/CompassData/Tests/CompassDataTests/EventFormColorSwatchKeysTests.swift @@ -32,7 +32,8 @@ final class EventFormColorSwatchKeysTests: XCTestCase { let model = try model(color: nil) model.focusEventFormField(.color) model.pickColorSwatch(at: 1) - XCTAssertEqual(model.draftStore.gridDraft?.color, NativeCalendarRootModel.colorSwatchOptions[1]) + // Web pick key 1 is lavender (EventColorSlotSchema order). + XCTAssertEqual(model.draftStore.gridDraft?.color, .lavender) XCTAssertEqual(model.colorSwatchFocusIndex, 1) model.pickColorSwatch(at: 0) XCTAssertNil(model.draftStore.gridDraft?.color) diff --git a/apps/calendar-macos/CompassKit/Sources/CompassKit/Calendars/EventColorSlotHex.swift b/apps/calendar-macos/CompassKit/Sources/CompassKit/Calendars/EventColorSlotHex.swift index 0733e99323..437b8cb336 100644 --- a/apps/calendar-macos/CompassKit/Sources/CompassKit/Calendars/EventColorSlotHex.swift +++ b/apps/calendar-macos/CompassKit/Sources/CompassKit/Calendars/EventColorSlotHex.swift @@ -27,3 +27,11 @@ public enum EventColorSlotHex { return details.color.map(hex(for:)) } } + +public extension EventColorSlot { + /// Web `EventColorSlotSchema` order. The generated enum is alphabetical, + /// so swatches and their pick keys follow this list instead. + static let webOrder: [EventColorSlot] = [ + .lavender, .mint, .plum, .coral, .gold, .orange, .blue, .slate, .indigo, .green, .red, + ] +} diff --git a/apps/calendar-macos/CompassKitTests/EventColorSlotOrderTests.swift b/apps/calendar-macos/CompassKitTests/EventColorSlotOrderTests.swift new file mode 100644 index 0000000000..e7e6a52867 --- /dev/null +++ b/apps/calendar-macos/CompassKitTests/EventColorSlotOrderTests.swift @@ -0,0 +1,15 @@ +import CompassKit +import XCTest + +/// Web `EventColorSlotSchema` order drives swatch positions and pick keys. +final class EventColorSlotOrderTests: XCTestCase { + func testWebOrderListsEverySlotOnce() { + XCTAssertEqual(EventColorSlot.webOrder.count, EventColorSlot.allCases.count) + XCTAssertEqual(Set(EventColorSlot.webOrder), Set(EventColorSlot.allCases)) + } + + func testWebOrderStartsWithLavender() { + XCTAssertEqual(EventColorSlot.webOrder.first, .lavender) + XCTAssertEqual(EventColorSlot.webOrder.last, .red) + } +} diff --git a/apps/calendar-macos/CompassUI/Sources/CompassUI/EventForm/EventFormTimeField.swift b/apps/calendar-macos/CompassUI/Sources/CompassUI/EventForm/EventFormTimeField.swift index 85cf82eb61..31b64f47a0 100644 --- a/apps/calendar-macos/CompassUI/Sources/CompassUI/EventForm/EventFormTimeField.swift +++ b/apps/calendar-macos/CompassUI/Sources/CompassUI/EventForm/EventFormTimeField.swift @@ -79,8 +79,9 @@ struct EventFormTimeField: View { } .frame(width: 120, height: 220) .background(theme.surfacePanelColor) - .clipShape(RoundedRectangle(cornerRadius: NativeWebLayoutTokens.radiusDefault)) - .shadow(color: .black.opacity(0.08), radius: 4, y: 2) + // Fill the popover's own inset too, like the date popover; the + // system material there read as a dark frame around the list. + .presentationBackground(theme.surfacePanelColor) .accessibilityElement(children: .contain) .accessibilityIdentifier("\(accessibilityIdentifier)-menu") } diff --git a/docs/features/desktop-web-parity-checklist.md b/docs/features/desktop-web-parity-checklist.md index 56d9068f31..97c79765d8 100644 --- a/docs/features/desktop-web-parity-checklist.md +++ b/docs/features/desktop-web-parity-checklist.md @@ -116,7 +116,7 @@ This checklist compares **apps/calendar-web** (reference UI) with **apps/calenda | Datepicker open Enter/Space/ArrowDown | 🟑 | Audit `EventFormScheduleSection.swift` vs web | | 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 keys and hints | βœ… | Like web `EventColorPicker`: trailing ⌘ 6 keycaps; once color has focus (Mod+6 or E then C) ← β†’ move a focus ring, Space / Enter pick, pick keys 1-9 0 - = choose a swatch and show on each swatch, and the hint swaps to ← β†’ Β· Enter. 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 | +| Color row keys and hints | βœ… | Like web `EventColorPicker`: trailing ⌘ 6 keycaps; once color has focus (Mod+6 or E then C) ← β†’ move a focus ring, Space / Enter pick, pick keys 1-9 0 - = choose a swatch and show on each swatch (swatches in web `EventColorSlotSchema` order, lavender first), and the hint swaps to ← β†’ Β· Enter. 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) | | Mod+digit field jump + hold-Mod chips | βœ… | `ModHoldChipsOverlay`, layout snapshots; chips sit at the anchor's top-right corner like web `DigitHintChipOverlay` (top + 2px, flush right), so the month picker chip no longer hides the Lv badge's "v" | | Hold-Mod day header keycaps (⇧SU, ⇧M, ...) | βœ… | Week headers swap the weekday for `WeekDayColumnHeaderControl` keycaps while Mod is held; bare letters in event-jump mode | @@ -343,6 +343,7 @@ Each PR should link a child issue, include before/after screenshots (web Chromiu | 2026-10-21 | Event jump chips use web day-prefix labels (W1, SU2) and digits after a day pick | | 2026-10-22 | Parity capture draws popover windows (form date picker, time list) over the window render, so those surfaces stop showing a closed field | | 2026-10-22 | macOS capture: register `onboarding-welcome-account-choice` so the welcome account step exports instead of timing out | +| 2026-10-22 | Color swatches and pick keys follow web slot order (lavender, mint, plum, ...) instead of the alphabetical generated enum; time list popover fills its inset with the panel color | ---