Work

Establishing a scalable data table pattern across products

Context

Our platform is made of seven product UIs, built at different times with different technologies. Over the years, tables quietly multiplied. Same purpose, different behaviors. Filters worked differently. Actions moved around. Accessibility was inconsistent. Performance varied depending on who built what and when.

The result was predictable. A fragmented experience for users and constant friction for designers and developers.

Tables were not broken in isolation. The pattern was.

An empty table state from the pattern docs: a search field with Filter and Customize buttons above a folder illustration with a sleepy face. The message reads “No standard found. Similar data, multiple implementations, no shared standard.” A Create new pattern button sits below.

Goal

The goal was not to redesign a single table.

It was to establish a scalable, accessible table pattern that could work across products, technologies, and use cases.

One that:
  • Feels consistent for users
  • Is fast to design in Figma
  • Is modular and predictable to implement
  • Scales from simple lists to complex data-heavy views

The table became the test case for aligning design, code, and product teams around a shared system pattern.

The table preset inside the Phrase platform, on the Projects page. Tabs for Translation, QA, Revision, Client review and All jobs sit above a search field with Filter and Customize. The table lists 459 jobs with columns for number, confidence, file, source path, status, target language, provider, due date and job owner.

Approach

Instead of optimizing for one “perfect” table, I focused on modularity.

The table was designed as a composition of interchangeable parts rather than a monolithic component. Layout, filters, search, pagination, row actions, loading states, and column behavior could be mixed and matched depending on context.

This allowed teams to build what they needed without reinventing interaction patterns or breaking consistency.

Design specs for a table cell with a text label and a count suffix. Red markers show 0.25 padding on both sides. Dark Development notes say every cell has padding around it, the prefix and suffix stay visible when long text is cut off with an ellipsis, and the suffix can be placed at the end of the cell.

Spotlight: Filters as a system

Filters were one of the most impactful pieces of the pattern.

Previously, each product solved filtering differently. Now, filters are designed as a plug-and-play system:

  • Multiple filter types with clear data models
  • A dedicated filter menu and active filter bar
  • Strict interaction and visual guidelines
  • Accessibility baked in from the start

For developers, filters became composable and predictable. For users, filtering became familiar across products, even when the data changed.

The Syntax documentation site on Patterns, Tables, Filter, under the heading Filter Anatomy. A projects table is annotated with its parts: the active filter bar, the filter button, the filter dropdown and the secondary filter dropdown. A filter menu is open on the Client filter.

Impact so far

This work is still evolving, but the benefits are already visible:
  • Faster implementation thanks to clear component boundaries
  • Stronger alignment between design and code
  • More consistent experiences across products
  • Accessible filtering patterns reused instead of re-implemented

Even when individual tables are not yet “perfect” in production, teams now have a clear reference point instead of guesswork.

Storybook for the SynTableNew component. A table of 25 jobs with status, progress, date and language flag columns has view tabs, a search field, Filter, Customize and Actions. The Controls panel below lists 79 props, and the component tree sits on the left.

Reflection and next steps

The table pattern proved that complex components are best designed as systems, not one-off solutions.

Filters are only one piece of the puzzle. Next steps include more advanced filtering logic, such as negation, conditional operators, and richer query building. The same modular thinking will guide those additions.

This case study is less about tables and more about how a design system can turn fragmentation into momentum.

A spec slide on logical operators in filters. Three notes say a filter can have different operators, that the operator differs by data type, and that the operator shows on the active filter. One example is a Project name menu listing is, is not, contains, does not contain, starts with, ends with and is empty, with starts with checked. Another shows the active filters Tag contains 4 values and Created is after 31.08.2024.