Skip to content

chore(docs): Add example of a full-page sortable table - #2516

Merged
VincentSmedinga merged 12 commits into
developfrom
chore/DES-1722-sortable-table-page
Apr 10, 2026
Merged

chore(docs): Add example of a full-page sortable table#2516
VincentSmedinga merged 12 commits into
developfrom
chore/DES-1722-sortable-table-page

Conversation

@VincentSmedinga

@VincentSmedinga VincentSmedinga commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

Add example of a full-page sortable table

Thank you for contributing to the project!
Please use this template to help us handle your PR smoothly.

What

A new “Table Page” in Storybook’s internal pages section with a realistic data table example.
It demonstrates sorting via a Select control, using 300 Amsterdam BAG address records as mock data.

Why

Teams using the design system have been asking for realistic examples of tables with features like sorting, filtering and pagination.
This page is the first of a few that will show how to build these patterns with our components.

How

  • A typed dataset of 300 BAG addresses with 21 fields (strings, numbers, optional values) provides varied, realistic mock data.
  • The table displays 30 rows and 10 columns and uses Table.Caption for its accessible label.
  • A sortAddresses utility handles sorting on any field, including optional values.
  • The SortOrder type is derived from sortOptions via as const, so the type narrows to only the offered sort values.

Checklist

  • Add or update unit tests
  • Add or update documentation
  • Add or update stories
  • Add or update exports in index.* files
  • Comment /chromatic test and verify visual regression tests pass
  • Start the PR title with a Conventional Commit prefix, as explained here.

Additional notes

  • Implements DES-1722.
  • Positioning the Select is tricky; we’d likely want it to the top right of the table, vertically aligned with the heading, and horizontally with the end of the table (also if it’s narrower). Created a new ticket for that.
  • The dataset displays 10 of 21 available columns in the table; the remaining fields (coordinates, ligging, document dates, etc.) are available for future examples like filtering or detail views.

@VincentSmedinga
VincentSmedinga requested a review from a team as a code owner April 1, 2026 11:32
Copilot AI review requested due to automatic review settings April 1, 2026 11:32
@VincentSmedinga
VincentSmedinga requested review from alimpens and dlnr April 1, 2026 11:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new internal Storybook page (“Table Page”) that demonstrates rendering a realistic, sortable data table using the design system’s Table component and mock BAG address data.

Changes:

  • Add a new Storybook internal page with a sortable address table controlled via a Select.
  • Introduce a typed mock dataset (BagAddress) and a sortAddresses utility plus sort options.
  • Add page-specific documentation and styling for the internal page layout.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
storybook/src/pages/internal/TablePage/TablePage.stories.tsx New internal page story rendering the sortable table UI.
storybook/src/pages/internal/TablePage/TablePage.docs.mdx Documentation for the Table Page patterns and state-sharing guidance.
storybook/src/pages/internal/TablePage/table-page.css Styling intended to support the “full-page” layout presentation.
storybook/src/pages/internal/TablePage/common/sortAddresses.ts Sorting helper for ordering the address dataset by selected field/direction.
storybook/src/pages/internal/TablePage/common/options.ts Sort option definitions and derived SortOrder type.
storybook/src/pages/internal/TablePage/common/index.ts Barrel exports for the Table Page common utilities/components.
storybook/src/pages/internal/TablePage/common/bagAddresses.ts Typed BAG address mock dataset.
storybook/src/pages/internal/TablePage/common/AddressTableHeaderRow.tsx Table header row component for the address table.
storybook/src/pages/internal/TablePage/common/AddressTableBody.tsx Table body renderer for the address rows and empty state.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread storybook/src/pages/internal/TablePage/TablePage.stories.tsx Outdated
Comment thread storybook/src/pages/internal/TablePage/table-page.css Outdated
Comment thread storybook/src/pages/internal/TablePage/common/bagAddresses.ts
Comment thread storybook/src/pages/internal/TablePage/common/sortAddresses.ts
@VincentSmedinga VincentSmedinga changed the title chore(Table): Add example of a full-page sortable table chore(docs): Add example of a full-page sortable table Apr 1, 2026

@dlnr dlnr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good start! I would also love to see search and pagination at some point.

@RubenSibon RubenSibon left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that it is a good start, but a few remarks.

Multi-column sorting

With complex data tables you often want to have multi-column sorting. Where data is in one column is closely related to data in another column, and it doesn't make sense to sort it independently.

With the current dataset and sorting options users can sort on huisnummer. But does that make sense? Why would someone want to sort on huisnummer if there is no connection with the straat column?

I do see that columns that are not sorted upon via the select are always sorted A-Z if there are multiple rows for a value in the currently sorted-on column, i.e. "Korte 's-Gravesandestraat 4" comes before "Nieuwe Achtergracht 4" when sorting on huisnummer.

Common pattern to have carets or arrows in the table's header

Often complex data tables have arrows in the table's header row to allow direct sorting of that column. I think this may have a few advantages:

  • It might be more intuitive for users; they can directly click on something to affect it, and they are probably used to the pattern.
  • It's immediately visible what column is (not) sorted upon.
  • It does allow for multi-column or connected sorting.

I briefly looked for accessibility concern. I found that w3 and thewcag have examples with said arrows.

Note that even if the arrows are not interactive, they can still exist to give visual feedback.

Does the decision to expand the existing Table for more complex data usage prevent this pattern? Or are there other reasons not to use this pattern?

Reactive components

Our tables are components are currently stateless and not reactive. Remember the criticism from some about Pagination where a new request to the server had to be done to refresh the view.

I suspect that as we provide more documentation on how to turn the basic Table into more complex data tables we'll get more feedback that developers want to have the option to fetch data and update the view dynamically. Or they will create their own workarounds to get what they want. This is already happening I can tell you. Can we work with those developers somehow and allow for more ways to use our components?

@VincentSmedinga

Copy link
Copy Markdown
Contributor Author

I agree that it is a good start, but a few remarks.

Thanks for this thoughtful feedback.

Multi-column sorting

With complex data tables you often want to have multi-column sorting. Where data is in one column is closely related to data in another column, and it doesn't make sense to sort it independently.

Sorting through a Select is just one pattern that we intend to offer as an example. Some others can be found in Amsterdam/design-system-prototypes#652. Multi-column sorting could surely follow.

With the current dataset and sorting options users can sort on huisnummer. But does that make sense? Why would someone want to sort on huisnummer if there is no connection with the straat column?

Yes, this column might be not the best example.

I do see that columns that are not sorted upon via the select are always sorted A-Z if there are multiple rows for a value in the currently sorted-on column, i.e. "Korte 's-Gravesandestraat 4" comes before "Nieuwe Achtergracht 4" when sorting on huisnummer.

Do we agree that this is expected?

Common pattern to have carets or arrows in the table's header

Often complex data tables have arrows in the table's header row to allow direct sorting of that column. I think this may have a few advantages: (…)

This is also a pattern we intend to offer. It’s partially implemented in the prototypes poc.

Does the decision to expand the existing Table for more complex data usage prevent this pattern? Or are there other reasons not to use this pattern?

No, it’s just that this branch introduces only one pattern. This makes the PR easier to review. And it allows feedback on this table example to be applied to the next ones from the start.

Reactive components

Our tables are components are currently stateless and not reactive. Remember the criticism from some about Pagination where a new request to the server had to be done to refresh the view.

This is also reactive, no?

<Table>
  {data.map(row) => (
    <Table.Row>
      <Table.Cell>{row.value1}</Table.Cell>
      <Table.Cell>{row.value2}</Table.Cell>
      <Table.Cell>{row.value3}</Table.Cell>
    </Table.Row>
  )}
</Table>

If data changes, React will rerender.

I suspect that as we provide more documentation on how to turn the basic Table into more complex data tables we'll get more feedback that developers want to have the option to fetch data and update the view dynamically. Or they will create their own workarounds to get what they want. This is already happening I can tell you. Can we work with those developers somehow and allow for more ways to use our components?

We’ve discussed this earlier in the front-end guild. Let’s do that once more if we have a couple of patterns up and running. State management can be added later if necessary, it would probably not break the API.

@RubenSibon

RubenSibon commented Apr 10, 2026

Copy link
Copy Markdown
Contributor

I do see that columns that are not sorted upon via the select are always sorted A-Z if there are multiple rows for a value in the currently sorted-on column, i.e. "Korte 's-Gravesandestraat 4" comes before "Nieuwe Achtergracht 4" when sorting on huisnummer.

Do we agree that this is expected?

I guess it's okay, but currently, it when a user first sorts Straat from Z-A and then Huisnummer from Z-A, Straat (and all other columns) reset to A-Z sorting. It would be nice if that reset didn't happen, but it remembered the last sorting. I think this is possible in JavaScript, by just not touching any other columns than the one the user is now actively sorting on. This way you already get the multi-column sorting functionality to some extent.

I suspect that as we provide more documentation on how to turn the basic Table into more complex data tables we'll get more feedback that developers want to have the option to fetch data and update the view dynamically. Or they will create their own workarounds to get what they want. This is already happening I can tell you. Can we work with those developers somehow and allow for more ways to use our components?

We’ve discussed this earlier in the front-end guild. Let’s do that once more if we have a couple of patterns up and running. State management can be added later if necessary, it would probably not break the API.

You're right that the data in the table view will re-render if the provided data changes, but typically the data will come paginated from some API (very sensible when you're dealing with large datasets). Our Pagination currently works with links and not buttons which means that client-side sorting (or filtering for that matter) on the current view does not make much sense because the entire page has to be refreshed. I know that multiple teams do not respect this approach and have their own implementations to allow for data tables that fetch data programmatically with buttons while still using the design system's CSS styling.

This is indeed a discussion that we need to have again.

@VincentSmedinga

Copy link
Copy Markdown
Contributor Author

We agreed to pick up multi-column sorting with a later example, and to address the ‘links in single page applications’ approach in an upcoming meeting of our front-end guild.

@VincentSmedinga

Copy link
Copy Markdown
Contributor Author

/chromatic test

@VincentSmedinga
VincentSmedinga enabled auto-merge (squash) April 10, 2026 10:28
@VincentSmedinga
VincentSmedinga merged commit 20c9403 into develop Apr 10, 2026
9 checks passed
@VincentSmedinga
VincentSmedinga deleted the chore/DES-1722-sortable-table-page branch April 10, 2026 10:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants