Skip to content

refactor(data-grid)!: rebuild the macOS data grid on one model and native AppKit - #3833

Merged
datlechin merged 8 commits into
mainfrom
refactor/datagrid-native
Oct 25, 2026
Merged

datlechin merged 8 commits into
mainfrom
refactor/datagrid-native

Conversation

@datlechin

@datlechin datlechin commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Every macOS data grid runs on one rebuilt grid: data and query tabs, Structure, Create Table, the Structure and dashboard lists, Compare & Sync, result comparison, Data Files, agent results, table listing and the theme preview.
  • DataGridModel owns the grid's state and outlives the view: rows by RowID, columns by DataGridColumnID, one selection, sort, value filter, layout, display formats, find and the open edit. Owners talk to it through DataGridDataSource and DataGridActions; TableViewCoordinator is gone.
  • Pure engines with their own tests: GridSelectionReducer, GridSelectionSnapshot, DataGridColumnSet, DataGridRowOrder, DataGridChange, GridFindEngine.
  • AppKit owns what it draws best: stock NSTableHeaderView and header cells, NSTableRowView selection in the system colors, an in-cell NSTextField editor, NSEditor commit and discard through an NSViewController. Cells stay drawn with CoreText: a view per cell missed the 200-column budget.
  • Frozen columns are a second table laid over the main one's leading edge; the main table keeps every column, so keyboard, find, copy and VoiceOver see one table.
  • A click selects the row with the cell cursor on the cell; drag, Shift and Command make cell ranges; row numbers and Select All pick rows (GridSelection.Mode).
  • Sort: a click sorts or reverses, Option-click adds a key, Don't Sort is in the header menu.
  • One find bar for every grid: Match Case, Whole Words, Regular Expression, a column scope and Replace. A focused grid answers Find itself. Data Files find and Replace All cover the whole file.
  • A value with a line break or over 256 characters edits in a popover anchored to the cell.
  • Themes no longer color the grid header, selection, selected text or active-cell border. A theme file that still has those six keys loads with them dropped.
  • Every edit, paste, Set Value, Fill Column and Replace All is one model.commit taken by IDs: one undo step, on the records it named.
  • Fixed on the way: a reload left no visible selection while Delete acted on old rows; a tab or Structure sub-tab switch saved an open edit into the wrong tab; edits, deletes and pastes under a value filter landed on another row; Find Next left the cursor in the old column; a temporary table and the Structure tab wrote the table's saved layout; Display As on a query result reset after Load More; Copy Rows did nothing in a data file window; VoiceOver numbered rows from 1 on every page and never named the edited cell's column; Copy as IN Clause on a join result lost MySQL's backslash escaping.
  • Grids that loaded on onChange(of:) read the previous body's values (measured on macOS 27); they load from task(id:).
  • Tests changed on purpose: the selection suites (click selects the row with the cursor, Select All leaves no cursor, Escape shrinks a range to the cursor's row), HeaderSortCycleTests and HeaderSortUITests (Option-click adds a key), the theme slot suites (six slots gone), DataFileControllerTests (find waits for the whole-file search). Suites that tested TableViewCoordinator were deleted or ported to TableProTests/Core/DataGrid and TableProTests/Views/DataGrid.
Before After
Before, light After, light
Before, dark After, dark

Test plan

  • Unit plan: 26,566 tests pass locally.
  • UI plan: passes on CI, GridFindUITests included; not run locally, since XCUITest cannot start beside the TablePro already running on this Mac.
  • Lint on all 342 changed Swift files.
  • Probes measured: drawn cells against a view per cell at 200 columns, the frozen overlay's scroll sync, NSEditor on NSViewController, onChange(of:) against task(id:) captures, the accessibility element of an NSTextField, NSTableView pixel-aligning a fractional column width.

Docs: TableProApp/docs#127

…review and focus Find in a native search field
# Conflicts:
#	apple/TablePro/Views/Main/Child/MainEditorContentView.swift
@datlechin
datlechin merged commit 94367b1 into main Oct 25, 2026
9 checks passed
@datlechin
datlechin deleted the refactor/datagrid-native branch October 25, 2026 15:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant