Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand ItemGroup #64445

Open
jameskoster opened this issue Aug 12, 2024 · 17 comments
Open

Expand ItemGroup #64445

jameskoster opened this issue Aug 12, 2024 · 17 comments
Labels
Design System Issues related to the system of combining components according to best practices. Needs Design Feedback Needs general design feedback. [Package] Components /packages/components

Comments

@jameskoster
Copy link
Contributor

jameskoster commented Aug 12, 2024

In recent times ItemGroup instances have been extended ad hoc to accommodate required features, for example:

Shadows Font Library Data view fields Block bindings Font size presets
Screenshot 2024-08-12 at 15 12 01 Screenshot 2024-08-12 at 15 13 51 Screenshot 2024-08-12 at 15 15 37 Screenshot 2024-08-12 at 15 18 41 Screenshot 2024-08-12 at 15 22 28
  • Shadows – adds a button to remove the item
  • Font Library – adds a suffix/value and chevron to indicate drilldown behavior
  • Data view fields – Allows re-ordering, includes button to toggle visibility
  • Block bindings: adds a suffix/value and a button to remove items
  • Font size presets – adds a suffix/value and chevron to indicate drilldown behavior

The more this components is arbitrarily customised the more tech debt we create. It would be good to define and implement a modern spec based on the use cases outlined above.

@jameskoster jameskoster converted this from a draft issue Aug 12, 2024
@jameskoster jameskoster added Needs Design Needs design efforts. [Package] Components /packages/components labels Aug 12, 2024
@jameskoster
Copy link
Contributor Author

jameskoster commented Aug 12, 2024

Here's an initial take on this, where I've split the items into two types; Item and DrilldownItem.

The list of props concentrate on new functionality. Any existing Item props (e.g. as and onClick are still supported).

Item

Spec-Item

Props

  • Decoration: Provides an option to display a decorative element such as a color swatch, image preview, icon, etc.
  • Has value: Provides an option to display a secondary text element.
  • Has re-ordering: Provides an option for the user to re-order items in the group
  • Has primary action: Allows the consumer to attach a primary action to the item. Appears on hover.
  • Has secondary action(s): Allows the consumer to attach secondary actions to the item. Adds an overflow button that opens a DropdownMenu.

The states are hopefully clear enough, though one detail to decide upon here is how the hover / pressed states behave when the item itself has no on-click action. In this case a hover style is probably unnecessary.

DrilldownItem

spec-drilldown

Props

  • Decoration: Same as Item.

Contextual examples

If we apply these conventions to some upcoming / existing UIs, here are the results. I also included a demonstration of how the title / value truncation should work.

Examples

@jameskoster jameskoster added Needs Design Feedback Needs general design feedback. and removed Needs Design Needs design efforts. labels Aug 12, 2024
@jasmussen
Copy link
Contributor

Nice, this feels mostly exhaustive and a good system. Only a few pieces feel like they are missing, and some of those are question-marks. First off, there's the stacked color-swatch:

Screenshot 2024-08-13 at 12 10 51

This feels like a pattern worth keeping. But how much can it stack? Currently in Global Styles > Colors, there's this drilldown:

Screenshot 2024-08-13 at 12 10 39

I think that drilldown works fairly well as indication of where you'll go. But does it work in this swatches-only state? Can the pattern be accommodated in these guidelines? Or should this example usage be changed, and if so, to which variant here?

@jameskoster
Copy link
Contributor Author

Good catch. Agree the two-color-stack is worth keeping. It bugs me a bit how it makes the text alignment ragged though... I wonder if there's something we could do about that?

Screenshot 2024-08-13 at 16 47 45

But does it work in this swatches-only state?

This doesn't feel like the best use of ItemGroup imo, mostly because in that particular UI there will only ever be a single button. The lack of text may not be ideal from an a11y perspective too. I'd probably be inclined to explore a different treatment for that button.

@jasmussen
Copy link
Contributor

That same river bugs me too, but making the swatches smaller creates a different kind of river, in the swatches themselves now lining up weirdly.

I think it's probably fine to keep the text river. An alternative is to start the text further in, though that might look awkward in its own way. Perhaps grouping the color stacks so they are all at the bottom would make it feel more coherent?

@jameskoster
Copy link
Contributor Author

Yeah a guideline to group by decoration type by default could help 👍

@jameskoster
Copy link
Contributor Author

Pinging @WordPress/gutenberg-components for any feedback on the designs, as time allows.

@ciampo
Copy link
Contributor

ciampo commented Aug 15, 2024

👋 Thank you for starting the conversation on this!

I'll list a few thoughts that came up while going through the issue:

  • We could definitely consider adding a prefix/suffix system to the Item component, similarly to what we're doing for DropdownMenuV2
  • For the text alignment, we could also borrow the same technique employed for DropdownMenuV2 to make sure that item labels are all aligned horizontally
  • The stacked color swatch would just be a prefix that we inject in the Item (without being part of the item itself)
  • In the same way, "primary actions" and "dropdowns" could just be part of the suffix. The more generic the component is, the more flexible and open to extensibility it is.
  • Is a DrilldownItem basically an Item with the chevron as a suffix? Or is there more to it?
  • Since Items can be buttons, we need to be careful in adding more interactive UI (ie. action buttons, reordering, dropdowns...) on the same item. It can definitely be done by making sure that those interactive elements are not children of the item button, but in general we should be careful also in terms of UX with having interactive elements overlapping other interactive elements. In that sense, it may be good to make sure that such interactive overlays (primary action, reordering, dropdown menu) can only be added if the Item is not interactive;
  • Not sure that we need a dedicated "has value" prop — the contents on the Item could just be determined via its children instead. We could offer sub components (like ItemLabel and ItemHelpText) to make it easier for consumers to re-use the same styles, but ultimately I think it's better to allow more freedom to the component's consumers;
  • for the same reason, the best strategy in terms on sizing would be to apply a minimum height to Item, and allow the item to grow in height based on its contents

@jameskoster
Copy link
Contributor Author

In the same way, "primary actions" and "dropdowns" could just be part of the suffix. The more generic the component is, the more flexible and open to extensibility it is.

I go a bit back and forth on this... when a component has a specific purpose – in this case grouping and listing related objects – doesn't it make sense to draw some lines in the sand? There's a reasonably narrow scope of properties we can associate with such UIs.

Could there be a case for an underlying Item component that is extensible as you described, then a ResourceItem component which consumes Item and adds the guardrails?

Is a DrilldownItem basically an Item with the chevron as a suffix? Or is there more to it?

In practise the difference is the onClick behavior. I appreciate there's no way for the component to know that natively. However a drilldown item should not have inline actions. I guess this relates a bit to the previous point... I'm unsure if it needs to be a separate component :)

Since Items can be buttons, we need to be careful in adding more interactive UI

Absolutely. Perhaps we can reuse some of the work done in the Shadow management UI:

Screenshot 2024-08-15 at 16 51 49

@jasmussen jasmussen added the Design System Issues related to the system of combining components according to best practices. label Sep 24, 2024
@auareyou auareyou moved this to Inbox 📥 in Design systems — Backlog Oct 7, 2024
@jasmussen
Copy link
Contributor

GitHubs reordering mechanism provides a good and small footprint that might work well for the ItemGroup size:

Image

@jameskoster
Copy link
Contributor Author

I like that. Theoretically the drag handle could trigger a menu, allowing all move controls to be grouped together. Then in some cases the ellipsis can be omitted entirely.

Image

@ciampo
Copy link
Contributor

ciampo commented Oct 27, 2024

Based on the conversation in #66413, just going to add that we should consider making ItemGroup a composite widget, ie. the whole thing is one tab stop, and focus between different items (and other interactive bits) would be moved via arrow keys.

@jameskoster
Copy link
Contributor Author

@ciampo do you think it would be feasible to include hierarchy/nesting in this component? In #65828 there's a suggestion to use ItemGroup to list items in a navigation menu. Obviously these items can be nested to create submenus, so that would need to be visualised, and users would need tools for changing the tree structure (drag / drop etc). Or do we need to consider a different component (treegrid) for this use case? It's a bit tricky because there's a lot of overlap.

@afercia
Copy link
Contributor

afercia commented Dec 3, 2024

Noting that the Edit palette with 'multi color-swatches' is being proposed to be removed in #66169:

  • it's a unique case in the whole editor and it doesn't add much value
  • it's functionally limited and potentially confusing because the swatches are arbitrarily sliced to 5, while a theme palette may contain way more than 5 colors and as such the (still experimental) color randomizer wouldn't show any change in the color swatches.

@afercia
Copy link
Contributor

afercia commented Dec 3, 2024

Based on the conversation in #66413, just going to add that we should consider making ItemGroup a composite widget, ie. the whole thing is one tab stop, and focus between different items (and other interactive bits) would be moved via arrow keys.

As reported in #67425 it's important to remind everyone that, so far, ItemGroup is the equivalent of an unordered list i.e. an <ul> element.

In fact, by default it renders a div with role=list. The documentation states that is should be used in combination with the Item sub-component, which in turn renders a div with role=listitem. As such, in terms of HTML it's the equivalent of an unordered list and we all should see it as a list (so far) to consider future changes and more importantly a correct usage. Think at it like this:

<ul>
    <li> .. some content ... </li>
    <li> .. some content ... </li>
</ul>

Even when <Item> is rendered as a button or a link by the means of the as prop, it still renders a role=listitem around it so that semantically it's still an unordered list.

Unfortunately, as reported in #67425, at the moment there are many cases in the codebase where ItemGroup is used only for visual purposes, mainly to draw a gray border aroun other elements, so there are cases where:

  • the equivalent of an <ul> contains a button (without list items)
  • the equivalent of an <ul> contains a <span> (without list items)
  • etc.

Those usages are semantically wrong. I would appreciate that components enforce rendering correct, semantic, markup but I see that in practice they are often used only for visual purposes. I'd strongly encourage any proposed chang e in this issue to first consider what kind of semantic markup this component should render. If it's a list, then it should be just a plain list with no special keyboard interaction. If it's going to be an ARIA composite widget with only one tab stop and arrow keys navigation, then it should use one of the ARIA design patterns with the expected semantics and interaction but I doubt that in that case the items can contain other interactive elements as proposed in this issue.

@ciampo
Copy link
Contributor

ciampo commented Dec 5, 2024

I agree that semantics are central to building any UI, and should be one of the first aspects to consider when designing a component's APIs.

I'm open to changing the default semantics of the component — from the designs above, I think we may consider changing it to a composite widget with role="grid". Alternatively, we could also consider leaving it "vanilla" (ie. without any particular roles). What is important is that we allow consumers of the component to pass all the necessary attributes to set the right semantics.

@afercia
Copy link
Contributor

afercia commented Dec 5, 2024

I'm not sure the role=grid would be appropriate and I'm not sure this component should ever provide arrows navigation. A grid is... a grid with vertical and horizontal arrows navigation, while this is a list with vertically stacked items.

Also, looking at the actual usage of this component in the codebase (see a few examples reported on #67425)) it appears in many cases ItemGroup has been used just to draw a border around other components. Which is unfortunate. This component was originally meant to be a simple list, and to only be used with Items sub-components. It's a simple list. If there is a need to have a Listbox with multi-selection, I think it should use a new, separate component.

@jameskoster
Copy link
Contributor Author

Today I realise that the use cases in the OP overlap considerably with the features of 'List' layout in DataViews:

So if we conclude that ItemGroup should be left alone, perhaps this could be extracted as a base to formalise a new reusable component?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design System Issues related to the system of combining components according to best practices. Needs Design Feedback Needs general design feedback. [Package] Components /packages/components
Projects
Status: Next
Status: 🏗️ In Progress
Development

No branches or pull requests

4 participants