Skip to main content
← Blog

Tables Are Greedy — the Desktop Table View

VauDium ·

We built a table view for desktop. It started with inline cell editing and ended with column resizing, reordering, visibility settings, per-header sort and filters, and saved filter chips — the story of a table that ate a whole day.

Tables Are Greedy — the Desktop Table View

The desktop task screen already had a list, a calendar, and a kanban board. We added a fourth view: a table where each row is a task and the columns are state, project, assignee, priority, and due date.

The initial goal was modest: “let me click a cell value to change it.” Click the priority cell and a priority picker pops up right there; click the due date cell and a calendar appears. Finish everything on the table without opening the detail screen.

But tables are greedy. Grant one wish and the next one feels obvious.

The Wishes We Granted

  • Inline editing — state, project, assignee, priority, due date, even the star color. Everything except the task title is editable right in its cell. State and priority show an icon plus the name.
  • Column resizing — hover over a column boundary and a full-height guide line appears; drag it to resize.
  • Column reordering — grab a header and an outline the exact width of the column follows your mouse, with a vertical line marking where it will land.
  • Show/hide columns — beyond the default seven, there are now sixteen toggleable columns: difficulty, satisfaction, planned time, start date, completed time, created date, task code, location, and labels. You can also drag-reorder them inside the settings menu.
  • Per-header sort and filters — hover a header and a ⋯ button appears. Every column gets sorting (ascending/descending) and filters: state, color, project, keyword, date ranges, priority, difficulty, satisfaction, assignee, labels. The server API grew alongside it that day.
  • Saved filters — name and save your frequent combinations, pin them, and they show up as chips in a bar above the table. One click and you’re there.

Order, widths, and visibility are all remembered. The table you built should still be your table tomorrow.

A Record of Small Defeats

I wrote that as if it went smoothly. It did not.

The resize handle wouldn’t show up. It turned out absolute positioning inside a table cell isn’t reliable in WebKit. We abandoned embedding handles in cells and switched to a full-height hotspot that appears when the mouse nears a column boundary. Then the hotspot flickered — the moment the overlay appeared under the cursor, the container fired mouseleave, hiding it, showing it, hiding it again in a loop. Moving the overlay inside the container stopped it.

The star color popup once opened behind the table. To pin columns to the left we gave cells position: sticky, which made each cell its own stacking context — so a popup rendered inside it stayed trapped there no matter how high its z-index went. Rendering popups through a portal at the document root solved it.

Drag and drop spent a long time in the “works, but doesn’t feel right” zone. Only after making the default ghost image transparent and drawing our own column-width outline that sticks to the mouse did it finally feel like carrying a whole column around.

What the Table Taught Us

On paper it’s just a table, but it ended up the densest screen on desktop. We decided not to build it on mobile. We also decided not to add more sorting and filtering to the list view. A screen that’s good because it has many options and a screen that’s good because it’s simple are different screens — and trying to be both in one place loses both. The table taught us that, one granted wish at a time.