refactor(datagrid): consolidate sort click cycle into header view#944
refactor(datagrid): consolidate sort click cycle into header view#944
Conversation
… binding-mutation Task pattern
…edundant calls, add coordinator + schema-shift tests
…t trigger rebuild path
…lacement, syncSortDescriptors state
…er on every sorted column
…rop SF Symbol fallback and highlightedTableColumn duplication
… not double-draw on primary
…awing duplicate chevron over custom cell
…ryLabelColor to match AppKit's subtle gray
…t so fill respects only image alpha
… subtle gray match
…ator to match modern AppKit native style
…d tertiary label color
…icator for pixel-perfect chevron rendering on every sorted column
…ve HIG-correct unsort UX
…3-state, SortableHeaderView only intercepts shift-click for multi-sort
…Cell to fix ARC crash on sort
… in offscreen context to avoid ARC crash on sort
…ew setIndicatorImage API to fix crash
…icators — pure native, no NSCell subclass
…raw duplicate chevron + bold title on primary
…dicator on primary sort column
…tIndicator to no-op — kills AppKit auto-indicator at source, no Swift property = no ARC crash
…eral col_0 identifier
…t-click-cycle # Conflicts: # TablePro/Views/Results/DataGridView.swift # TablePro/Views/Results/Extensions/DataGridView+Sort.swift # TablePro/Views/Results/SortableHeaderView.swift
💡 Codex ReviewTablePro/TablePro/Views/Results/SortableHeaderView.swift Lines 140 to 144 in 232a476
The new single-column cycle emits ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Summary
Follow-up cleanup to #942. The three-state sort cycle (asc → desc → cleared) was split across two layers:
SortableHeaderView.mouseDowntook over the click and calleddataGridSort(..., isMultiSort: true)directly.tableView(_:sortDescriptorsDidChange:)post-hoc intercepted the desc → asc transition and rewrote it as "clear".Two paths for the same UX, with the single-column path fighting AppKit's descriptor model. Any other code that produced a same-key desc → asc transition would have accidentally triggered clear.
This PR consolidates both paths into
SortableHeaderView.mouseDown. The cycle decision is now a pure function (HeaderSortCycle.nextAction) and unit tested.tableView(_:sortDescriptorsDidChange:)and theisSyncingSortDescriptorsreentry guard are deleted.tableView.sortDescriptorsis still written one-way from the model insyncSortDescriptorsfor VoiceOver accessibility; nothing in our code reads it anymore.Test plan
xcodebuild test—HeaderSortCycleTests(9 tests) and existingSortStateTestspass.swiftlint lint --strict— 0 violations.