adobe / react-spectrum

A collection of libraries and tools that help you build adaptive, accessible, and robust user experiences.
https://react-spectrum.adobe.com
Apache License 2.0
12.97k stars 1.13k forks source link

feat(TableView): Multi-column sorting #3680

Closed alirezamirian closed 1 year ago

alirezamirian commented 2 years ago

πŸ™‹ Feature Request

TableView (and the corresponding hooks in react-aria), support a sortDescriptor prop, which accepts a single sort descriptor. A more advanced use case would be an array of sort descriptors, to support multi-column sorting. Is that something you would be willing to implement or accept contribution on?

πŸ€” Expected Behavior

Couldn't find the wai-aria spec even for single column sorting, but here is an example reference for the expected behaviour: https://mui.com/x/react-data-grid/sorting/

😯 Current Behavior

A single SortDescriptor is supported.

πŸ’ Possible Solution

TableState can be changed to support an array of sortDescriptors. The sort function should also be updated to accept extra information about if sort is being replaced or amended. Then useTableColumnHeader should also be updated to pass that information, when calling .sort().

πŸ”¦ Context

In some use cases of table, where many columns have enum values, multi-column sorting helps a lot in finding the right information based on a couple of fields.

πŸ’» Examples

https://mui.com/x/react-data-grid/sorting/

🧒 Your Company/Team

Danske Bank

devongovett commented 2 years ago

That UI where it shows numbers above each column is super confusing IMO. I wonder if it's better to do this outside the column headers themselves, in a separate UI where the sorting criteria could be in a reorderable list for example.

That said, I think if you're using react-aria, you could do this fairly easily. Actually sorting the data is up to the application anyway, so it would just be rendering some custom UI in the column headers.

I'm not sure ARIA has a way to indicate that multiple columns are sorted either. The spec says that aria-sort should only be applied to one header at a time.

alirezamirian commented 2 years ago

Yes, the actual sorting is of course out of scope here, but the behaviour and state management of multi-column sorting could be relevant to react-aria/react-stately. For example how a sort column should be appended by cmd+click (if multi-column sorting is enabled), and how the state can hold an array of sortDescriptors.

If the UX is not considered a good pattern or is against the ARIA specs, that's a different discussion of course.

I searched for a few other examples of multi-column sorting in the wild, to see how it's done, and all of them seem to follow the same pattern of showing numbers to indicate the order: https://js.devexpress.com/Demos/WidgetsGallery/Demo/DataGrid/MultipleSorting/React/Light/ https://www.ag-grid.com/react-data-grid/row-sorting/#multi-column-sorting https://www.syncfusion.com/react-components/react-data-grid/sorting https://www.telerik.com/kendo-react-ui/components/grid/sorting/#toc-customize-sorting

I tend to agree a separate reorderable list of columns is nicer, but I think it's kind of a downside too to have two inconsistent UX pattern based on the number of sort columns being 1 or more than 1.

devongovett commented 2 years ago

I still think you could implement that on top of our hooks without requiring it to be built in. You could apply your own click handler to the column header element, and store the state yourself. Doesn't seem like it should be too hard. Not saying we would never support multi-column sorting, but I think we'd need to do some research. If you want it in the short term, implementing it on top of our hooks seems like a reasonable approach.

alirezamirian commented 2 years ago

Makes sense. Thanks :)

LFDanLu commented 1 year ago

I'm closing this issue for now, we will reopen in the future after doing more research and if more people want this specific feature.