refactor(datagrid): correctness, a11y, perf, tests#946
Conversation
… and use native focus ring
…and clear edge cases
…d-name edge cases
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6a7c4523ff
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
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".
| if let cached = coordinator.displayFormatsCache[tab.id], | ||
| cached.schemaVersion == tab.schemaVersion, | ||
| cached.smartDetectionEnabled == smartDetectionEnabled, | ||
| cached.overridesVersion == overridesVersion { | ||
| return cached.formats |
There was a problem hiding this comment.
Invalidate display format cache on result-set switch
The cache lookup only keys on tab.id, schemaVersion, settings, and overridesVersion, so it returns cached formats even after switchActiveResultSet(to:in:) replaces tableRows for the same tab without bumping schemaVersion (see MainContentCoordinator+TableRowsMutation.swift). In pinned multi-result workflows, switching between result sets with different columns/sample values can reuse stale detected formats, causing wrong per-column rendering (or missing formatting) until another schema-version-changing action occurs.
Useful? React with 👍 / 👎.
Summary
Batch of fixes from the post-#945 datagrid audit. All Tier 1 / Tier 2 / Tier 3 items, plus 48 new tests for previously untested critical paths.
Correctness fixes
DataGridCellView): change-row highlights (deleted/inserted/modified) and the focus ring now re-resolve viaviewDidChangeEffectiveAppearance()when the user toggles Light/Dark mid-session.DataGridCellView): replaced the hardcoded CALayer border withfocusRingMaskBounds+drawFocusRingMask()so the ring tracks the system accent color, contrast settings, and appearance automatically.CellOverlayEditor): a column resize while editing a multiline cell now discards the in-progress edit instead of silently committing partial text.DataGridView+ coordinator): the SwiftUI bridge that writes new sortedIDs to the coordinator now also callsupdateCache()immediately, removing the window wherenumberOfRowscould disagree with the live sort permutation.Accessibility
SortableHeaderCell): column headers now announce sort direction and multi-sort priority (e.g. "Column: Name, Sorted ascending, Priority 2") viaaccessibilityLabel()override.Performance
MainContentCoordinator):ValueDisplayDetector.detectnow runs once per result schema instead of on every SwiftUI body evaluation. Cache keyed by(tab.id, schemaVersion, smartDetectionEnabled, overridesVersion).acceptsMouseMovedEvents(SortableHeaderView): the window-level flag was redundant with the tracking area; removed.Test coverage (+48 tests)
FileColumnLayoutPersisterTests: clear-removes-file, isolation across connections, save-overwrites,columnOrder == nilround-trip, empty JSON recovery (+7).ColumnIdentitySchemaTests: positional schema doesn't resolve raw duplicates, name-based schema doesn't resolvecol_N, reserved__rowNumber__triggers positional, three-duplicates path (+7).MainContentCoordinatorTabSwitchTests: 19 tests covering filter/visibility/changeManager/selection/toolbar save+restore, switch-from-nil, switch-to-nil, unknown ids, isHandlingTabSwitch lifecycle.MainContentCoordinatorSortTests: 15 tests covering single/multi-column cycles, removal, replacement across columns, schemaVersion cache invariants, pagination reset.Out of scope (future work)
FileColumnLayoutPersisterwidths/order vsColumnVisibilityManagerhidden state). Needs design decision on canonical store.dataGridDidReplaceAllRows()before SwiftUI pushes new sortedIDs, so same-row-count re-sorts may render in old order until next mutation. Separate fix.Test plan
displayFormatsre-detection.xcodebuild test— all four new test files pass.swiftlint lint --strict— 0 violations.