WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.52k stars 4.21k forks source link

Expanding the `Table` component #53233

Closed jameskoster closed 5 months ago

jameskoster commented 1 year ago
Features

Out of the discussion in this issue and elsewhere it has become clear that some of the required features are quite intricate, and to capture all the details it's probably going to be best to break them down into separate issues. In those issues each feature can be explored abstractly, and contextually as required.

Original issue In https://github.com/WordPress/gutenberg/pull/50766 a `Table` component was introduced, facilitating a consistent way to render the template and template part management views in the site editor: Screenshot 2023-08-01 at 13 35 15 As we consider the [broader admin experience](https://make.wordpress.org/core/2023/07/12/admin-design/) it could be a good time to expand this component so that it is able to entertain various capabilities and contexts: | Contexts | Capabilities | | --- | --- | Templates #50430 | Search Patterns | Filtering Posts / Pages / Comments | Sorting / Ordering Users | Bulk actions Media | Column toggling Themes | Inline editing Plugins | List / Grid toggle Tools Sites (multisite) In this issue we can explore designs for a 'kitchen sink' application illustrating the full scope of the component, then concentrate on specific contexts in dedicated issues. --- [Figma](https://www.figma.com/file/qdaHwaR0sCu4z8MtPtVGp9/Table?type=design&node-id=1%3A62&mode=design&t=sFNXqRglfLbZEd0W-1).
jarekmorawski commented 1 year ago

On Woo's side, I'd add:

Contexts Capabilities
Products Quick actions
Orders Expandable rows (for product variations)
Inventory Freeze panes
Attributes Inline preview
Analytics View/density modes
Reports Grouping (e.g., by status)
Customers Download/export
Subscriptions Interactive empty states
Bookings Quick-access filters, like stock level
Categories
Transactions
jameskoster commented 1 year ago

Thanks @jarekmorawski !

Bulk select

This should be covered by 'bulk actions', right?

Grouping (e.g., by status)

How does this differ from filtering or sorting?

Freeze panes

Do you mean making columns/rows sticky, or something else?

jarekmorawski commented 1 year ago

This should be covered by 'bulk actions', right?

Right! Missed that. I'll remove it from my comment.

How does this differ from filtering or sorting?

It's a different viewing mode. Instead of filtering by status, you'd automatically see items collected into groups. This could be handy for screens like orders or transactions, which are strongly tied to specific workflows, e.g., fulfillment or disputes. With grouping, we could guide users' attention to the most pressing matters, like shipping out overdue orders or challenging disputes.

Example (source)

Do you mean making columns/rows sticky, or something else?

Yes, that's what I mean. We could even let the user decide, although we'd safely default to the first and last column (name and actions). I think it was called freezing columns back in the golden age of MS Office.

jameskoster commented 1 year ago

Here’s a first take at the design for this one:

table

Let's look at the features:

Filtering

https://github.com/WordPress/gutenberg/assets/846565/3a7add2b-4b83-4bde-b702-cac6ba575960

By default each Table instance would have at least one filter – the search input. To begin with this may only filter the title, but could be expanded in the future.

Optionally, additional default filters may be included. For instance the Posts table might opt to make a “Status” filter part of the default experience.

Beyond the prescribed default filters, the user can manually add/remove more themselves. Once added a filter is represented by a dropdown containing the appropriate options, and a “Reset” affordance appears inside the filter UI offering full-reset capability.

The filter dropdown appearance should adapt accordingly:

Many filters

I'm not sure about the best logic to handle this. Initially I thought we might simply count the number of options and say, "when there are >2, switch to a numerical label", but that won't work very well if some of the terms are very long. Perhaps it's just a character limit?

For scenarios where many filters combine the row of dropdowns can wrap beneath the search and view options:

wrapping

View options & sorting

https://github.com/WordPress/gutenberg/assets/846565/66d30345-ba9d-4541-8dfc-f833f1f94849

The sorting dropdown enables the user to sort be data points that might not be visible in the current table configuration.

If the dataset includes a visual element like a preview or a featured image, then an optional grid / list toggle can be made available. Furthermore it’s possible to toggle the visibility of columns, and to specify how many entries appear per page.

These features can all be enabled/disabled on a per-table basis.

Column options

https://github.com/WordPress/gutenberg/assets/846565/0f5e11b7-7624-43b6-aff4-5180b0877e57

Each column has a set of options which are exposed by clicking the button in the table header. A given Table instance may require granular control over these options – for example it may be impossible to hide or move the Title column in the Pages table.

Otherwise actions include sorting, moving right/left, hiding, and pinning. A pinned column behaves as if it has position: sticky applied so that is remains visible regardless of scroll position:

pinned

In the future column options may be exposed via right-click, and re-ordering could be a drag-and-drop operation.

Bulk edit

https://github.com/WordPress/gutenberg/assets/846565/eccbf2ae-ae16-4b73-a94f-91915c2e3bfa

Clicking a checkbox reveals a toolbar containing any relevant actions plus a deselect shortcut.

Quick edit

https://github.com/WordPress/gutenberg/assets/846565/0f7bba0a-62f0-4e3b-a1b7-62ee7303b6e9

To facilitate rapid changes it’s possible to double-click data points to expose a quick edit UI. Changes can be saved / discarded by clicking away, or via the dedicated confirm/cancel buttons.

The ellipsis menu at the end of each row contains access to quick-actions like deleting, reseting, etc.

cc @WordPress/gutenberg-design and @ntsekouras for feedback.

@jarekmorawski I didn't get to the following:

Density modes can probably be part of the view options. The other three might be plugin territory (perhaps @ntsekouras has some thoughts on that?), but it'd be good to explore mockups for them regardless.


Next steps: Beyond addressing feedback, we should map the functionality here to the Templates Table in the site editor (https://github.com/WordPress/gutenberg/issues/50430).

ntsekouras commented 1 year ago

If the dataset includes a visual element like a preview or a featured image, then an optional grid / list toggle can be made available.

I think this is something that don't 'fit' in data tables work much. It's a different thing and don't know yet how we could fit all the advanced handling(sorting/filtering, etc..) in a grid view that has so many specific needs. For example, what fields do we choose to show in a grid? Wouldn't that be confusing to have selected fields in table view, and in the grid view show others? It's good to have this grid view, I'm just not sure yet, how we could implement the table/grid views well..

The sorting dropdown enables the user to sort be data points that might not be visible in the current table configuration.

So in a visible column (ex Title) sorting through clicking the header should be enough, right? No need to add it to this sorting dropdown?

Extensibility

We'll definitely iterate, but it's good to have in mind extensibility from the start. A good list from @nerrad about this is here (I included only the ones that affect design):

 A starter list of extensibility needs for consideration with any list table abstract (including what you've already mentioned):

- custom filters (REST response, and controls)
- filtering quick actions for a row
- filtering bulk actions
- injected row information (eg. comment count bubbles for comments)
- filtering column names
- mobile behaviour on collapse (which columns collapse? which is primary column?)

Feature set considerations (although I imagine this would evolve over time):

- compact vs extended views
- bulk edit
- quick edit (although I imagine there is opportunity to significantly improve the flows depending on the user context)

For scenarios where many filters combine the row of dropdowns can wrap beneath the search and view options:

We would need to support custom injected filters from extenders so this might affect the design. Maybe always have the filters in a separate section that would expect that.. 🤔

Bulk edit falls into the same umbrella and we'd need to take into account more space might be utilized in the end.

jasmussen commented 1 year ago

There's a lot to like here, and enough seems right that it can definitely move into implementation and be iterated there.

The only thing that stands out here is the pagination. We can maintain the hit-area and size of the buttons, but I'd juse the tertiary style for the chevrons, not the secondary bordered style.

jameskoster commented 1 year ago

It's a different thing and don't know yet how we could fit all the advanced handling(sorting/filtering, etc..) in a grid view that has so many specific needs. For example, what fields do we choose to show in a grid?

I think the grid is much stricter about what fields are displayed. The exact requirements will be revealed when we apply the design in different contexts, but off the top of my head each item in the grid would only contain the thumbnail, the title, and the quick actions (ellipsis button). Filtering and sorting can work the same as list view, no?

So in a visible column (ex Title) sorting through clicking the header should be enough, right? No need to add it to this sorting dropdown?

We could potentially be smart and conditionally hide items there, but I don't know if it's worth it. If you're accustomed to using the dropdown instead of the column headers it might be confusing. We could hide the entire dropdown when all columns are visible, but again I'm not 100% convinced. Probably one to try in the PR :)

We would need to support custom injected filters from extenders so this might affect the design. Maybe always have the filters in a separate section that would expect that.. 🤔

We discussed this a bit, and it is an option if the proposed layout doesn't work in practise. We need to ensure we're optimising for the most common scenarios though which I anticipate to be one or two default filters added by the table itself (like Status on the Posts table), then one or two more added by the user.

Bulk edit falls into the same umbrella and we'd need to take into account more space might be utilized in the end.

Did you have something specific in mind? The pattern presented here should scale quite well, given the buttons in the toolbar can invoke pretty much any UI. We can be flexible there too. For instance instead of the "Change status" button, dropdowns might appear directly in the toolbar like so:

actions-toolbar

I suspect the design for bulk actions will become more refined when we look at the different contexts (Templates, Pages, etc) in more detail.

We can maintain the hit-area and size of the buttons, but I'd juse the tertiary style for the chevrons, not the secondary bordered style

That could work. We don't really have suitable icons for "first page" and "last page" so we may need to come up with something there, or use text buttons:

Screenshot 2023-08-25 at 10 22 26
jasmussen commented 1 year ago

That could work. We don't really have suitable icons for "first page" and "last page" so we may need to come up with something there, or use text buttons:

On the WP.org work we do this:

Screenshot 2023-08-25 at 11 34 05

That is:

1  ...  4  5  *6*  7  8  ...  49

I think that could work well here.

jameskoster commented 1 year ago

So long as we apply the same treatment in the Patterns pagination, that works for me. Though I suppose the Patterns page may eventually be replaced with the new table, so perhaps that's moot :)

pablohoneyhoney commented 1 year ago

Nice. I'll dive in a bit more, but at first sight is looking great. A few notes to ponder are: the labels row to perhaps float without borders so there's a clearer difference from the actual listing; consider also less borders around top level elements (status, sorting, views); align all the ellipsis/settings vertically; revise the density, both vertical and horizontal, perhaps in default and settings; and more hierarchy between the checkbox and the representation of the element.

javierarce commented 1 year ago

Great work! Here are some initial thoughts and questions:

annezazu commented 1 year ago

As we evolve this component and want to use it elsewhere, I wanted to highlight this issue around how the "add new" option doesn't appear on mobile: https://github.com/WordPress/gutenberg/issues/49769

SaxonF commented 1 year ago

In-row editing is convenient, but since it affects the column width when the user enters the edit mode, have you considered moving the editing to a tooltip where there is more space? Depending on how it's done, it could also help in the mobile view.

We are doing something like this in media library explorations (excuse the inconsistencies in the table) for adding/editing tags (second image) and agree it might be a little more scalable as we come across different data types / input methods. In saying that, we can also just default to using the cell if its wide enough but set a minimum width so it can float above when needed. Click cell, dialog appears "on top" of cell covering its width/height at minimum so that it appears you're editing the cell itself.

image

Notion handle this pretty well as does AirTable.

image image
SaxonF commented 1 year ago

I've spun up a PR that pulls over the wonderful work done by @kevin940726 in the media library branch with a few little adjustments (abstract away TanStack from outside Table)

cc @ntsekouras as I know you were looking at working on this. Next steps for the branch (or maybe a follow up) might be to update the existing site editor patterns page to create/make use of a generalised filtering pattern thats compatible with any type of list view, including Table and Grid.

ntsekouras commented 1 year ago

Thanks for the ping @SaxonF! I think it's great to have different explorations at this stage and I think it's the best to have the discussions kept in a single place, as much as possible. We could do that in this main issue.

Last week I opened a draft PR exploring the table component which has some overlapping work with the media library exploration, but also some differences. I think we shouldn't rush extracting one part from just one PR, before discussing a bit more about the approaches(pros and cons) and especially if the end result is exactly the same as is now(templates list is a very simple case as is right now). I mean, we could even end up with something entirely different. Of course it will be just the first iteration and things will change, as there are many nuances(for example extensibility or how third party devs can create similar lists in the admin).

I think it's a great exercise to explore different lists, as it will help us discover what we can share, what is missing and how we proceed. Right now in the two PRs, there are experimentations in the media list, template list and pages list. There is a significant difference between controlled data tables and uncontrolled ones. Uncontrolled data tables are those where we feed all the data at once(see templates list where pagination is not supported) and filtering, pagination, etc... are handled by the data table library(TanStack). Controlled data tables are those where we have dynamic data and we're responsible for making the right filtering/sorting/pagination requests etc.. so all these actions are handled manually(example is pages list and the media list should be too).

Probably the main difference in the two PRs right now IMO, is that I've implemented this by using a DataTableProvider, so we can compose components and have access to the table's instance. It doesn't really matter where the reusable components will live at first(we can lock them), but we would need some for sure. Also I'm experimenting with both controlled and uncontrolled data tables.

We should also explore/discuss how to best support extensibility, as it's a very core component.

SaxonF commented 1 year ago

Just saw that , thanks @ntsekouras ! Feel free to discard that PR if the approach doesn't make sense .

jameskoster commented 1 year ago

@pablohoneyhoney

the labels row to perhaps float without borders so there's a clearer difference from the actual listing; consider also less borders around top level elements (status, sorting, views);

Could work, especially with the hover treatment @javierarce suggested (though I'm not in love with how strong the lightest gray in the current scale is):

Screenshot 2023-08-29 at 11 39 44

revise the density, both vertical and horizontal, perhaps in default and settings;

I'd love a density view option, though unsure if it needs to be in the v1. Values can probably be adjusted in the PR if it's included:

density

A range control is nice because you can keep your eye on the table as you adjust, but a segmented control could also be an option.

Regarding the bulk action, I'm missing an option to select all the rows in the table, not just the visible ones.

It would be good to get @ntsekouras thoughts on this one. Updating (potentially) thousands of records in one go may not be performant? Any limitations here would likely inform the "Entries per page" option too (which is another way for folks to apply bulk actions to more records). Perhaps that could include an "All" option?

It might not be reflected in the prototypes yet, but I'm missing some affordance to distinguish between text-based and editable cells.

Were you thinking something visual? I was hoping the cursor change on hover would be adequate.

have you considered moving the editing to a tooltip where there is more space?

Love the tooltip / popover idea. Looks like Saxon is ahead of me on that one!

pablohoneyhoney commented 1 year ago

Could work, especially with the hover treatment @javierarce suggested (though I'm not in love with how strong the lightest gray in the current scale is):

It doesn't need to be grey either.

I'd love a density view option, though unsure if it needs to be in the v1. Values can probably be adjusted in the PR if it's included: While different density settings might be available (I don't see it as an immediate requirement), the baseline table I think needs to have just the right density as default.

SaxonF commented 1 year ago

the labels row to perhaps float without borders

@jameskoster - @pablohoneyhoney can correct me if I'm wrong but I think by labels he meant table header and I'd say surrounding table border so less of a boxy feel. I don't think we should omit borders from the table rows. If we wanted to embed a table in a space that benefited from it being "contained" we could perhaps just wrap in a Card?

Removing table border as well as using tertiary style for dropdown triggers will present some alignment challenges as well as ensuring we have enough contrast between table headers and filters.

We can take some visual inspiration from Tailwind as well https://tailwindui.com/components/application-ui/lists/tables

ciampo commented 1 year ago

Hey all!

Having a look at this conversation — I may be missing some (or a lot of) context, but I'm going to leave some comments:

SaxonF commented 1 year ago

I'd recommend locking the list of requirements before working on an actual implementation

Is there a way we can do this iteratively? We know we need filtering, sorting, pagination, bulk select and support for different views (e.g. patterns grid). It would be nice to focus on this for 6.4 by replacing the templates, template parts, and patterns pages (dynamic data) within the site editor using the new table component and its parts. This will let us focus on the core API (data, columns etc) whilst still in core while we continue to collect other requirements.

tomjn commented 1 year ago

I'd be very careful doing that, the problem is if something is shipped in 6.4 that then needs to change in some fundamental way. People will then build things accordingly only to have the rug pulled out from under them when they realise they were building on top of an intermediate design.

It's the kind of things that people have complained about as part of a poor developer experience already. Defining the requirements in advance and setting some constraints should avoid these kinds of things, especially in an iterative approach, while avoid scope creep

ellenbauer commented 1 year ago

Love what I see here, it all looks so much cleaner and more organized.

Maybe it's not a concern right now, but it would be interesting to see how multilingual support could be solved in the tables. I know that plugins the table components to add translation options. Maybe just something to have in mind moving forward.

tomjn commented 1 year ago

On that note, plugins will try to extend these tables, what should happen if too many columns are present? I see the dropdown menu to control which columns show, but not what happens when the table has too many columns, e.g. 10+, something the current admin tables struggle with

SaxonF commented 1 year ago

@tomjn you mean performance wise or responsively? Typical responsive behaviour would be horizontal scrolling on table. We can maybe add some scrolling affordable too.

tomjn commented 1 year ago

Not specifically mobile, but rather just sheer volume of data. Right now current admin tables can suffer on laptop screens with ultra thin columns when there's a lot added.

E.g. this is in Chrome on a 14" MBP:

Screenshot 2023-09-12 at 12 15 29

I've seen more columns on client sites. Obviously on mobile we'd have horizontal scrolling but on desktop there can still be more columns/data than can fit on the screen and it happens often

What about desktop horizontal scrolling might be nice, would it need to be optional though? What kind of affordances would be appropriate for users unaware?

tomjn commented 1 year ago

Note that while this is fine on my 4k display, a lot of people use 1080p monitors and it's a common laptop and desktop display size.

Re: performance, I think we'd need to perform tests at some point but I don't foresee it being an issue from what I can see unless we're displaying hundreds of items. At that point it may be a concern for lower end devices, but there are solutions for that such as virtual rows, a technical detail

tomjn commented 1 year ago

That also raises how should long column titles be handled, center aligned or left? Truncated or overflow to a second line?

jameskoster commented 1 year ago

I'm a fan of horizontal scrolling for tables. With columns being toggle-able and pin-able it can work well both on desktop and mobile.

Individual cells can theoretically adapt based on the overall viewport width to consume less horizontal space too.

A 'density' preference as discussed above might help.

jameskoster commented 1 year ago

Some of the features here are quite hefty. Rather than trying to capture everything here, let's create dedicated issues as needed. I've updated the OP accordingly, and will create new issues asap.

lesley-pizza commented 1 year ago

I love this so much!

Everything seemed really intuitive. I only have a concern about the double click for quick editing. This seemed a little hidden/hard to discover as there isn't a double-clicking action in any other part of WordPress admin (that I know of).

dannyreaktiv commented 1 year ago

Is this Component limited to the Site Editor, or could it be easily used elsewhere? (I wasn't seeing it listed in the https://developer.wordpress.org/block-editor/reference-guides/components/ )

jameskoster commented 1 year ago

@dannyreaktiv I suppose it depends what you mean by "elsewhere"? Could be a question for the engineering counter-part to this issue: https://github.com/WordPress/gutenberg/issues/55083

dannyreaktiv commented 1 year ago

@dannyreaktiv I suppose it depends what you mean by "elsewhere"? Could be a question for the engineering counter-part to this issue: #55083

Thank you! (I am curious if the Table component can be used outside of the Site Editor)

haszari commented 1 year ago

I am curious if the Table component can be used outside of the Site Editor

@dannyreaktiv I would say – yes, totally! A table has many uses across WordPress admin screens, see some examples from WooCommerce in @jarekmorawski comment above.

ciampo commented 1 year ago

Is this Component limited to the Site Editor, or could it be easily used elsewhere?

I imagine there will be some iteration needed before the component will be ready to be exported and used outside of the site editor, but that should definitely be the direction we're headed toward.

jameskoster commented 5 months ago

I think this can be closed. Most outstanding items have dedicated issues.