eui
eui copied to clipboard
[Spec] Utility bar for meta information and bulk selection actions
Summary
I believe we have a need for a new EUI component that would allow us to prepend meta information and bulk actions to adjacent, related EUI components (namely the tabular-focused ones). The use case for such a supplementary component would be to:
- Provide users basic meta information on object/row counts for tabular components (though there may be benefits in using such a component outside of tabular-only contexts).
- Conditionally inform users of any current selection status (for example, selected object/row counts).
- Conditionally make available bulk actions, if/when such selections are made.
- Optionally provide an open area for additional controls and actions.
- Provide a consistent means in which to deliver this information and actions to users across EUI and Kibana.
History
Specifically regarding bulk selection and actions, past patterns have emerged across Kibana that required either:
- Shuffling around other interface elements (for example, within an
EuiSearchBar
component) to make way for the conditional appearance of bulk action buttons. - Static appearance of bulk action buttons in a disabled state, until bulk selection occurs (at which point the buttons would become enabled for use).
Neither of the above are desirable solutions. The shuffling of interface elements can be confusing and potentially obtrusive to users, as it usually demands diminishing the presence of other elements on the page (such as a search bar). The disabling of bulk action buttons artificially bloats the page with controls users are unable to interact with until a bulk selection is made. The hope is that this newly proposed component would alleviate both of these concerns and provide a consistent design pattern.
It's also worth mentioning that the arrival of the new EuiDataGrid
component also brought with it a means in which designers and engineers are able to implement bulk actions, but it is currently not an independent component and is tied to EuiDataGrid
. Ideally, this would be a separate, agnostic component that could be prepended to any existing EUI element (EuiDataGrid
, EuiBasicTable
, others) to provide meta information and bulk actions in a consistent and predictable manner.
Desired Features
Functional
Default Meta Information
The component should be expected to always present the user with a minimum amount of information related to the content the are currently viewing. In the case of tabular data, the default expectation would be to show a total count of the current objects/rows being presented (based on the currently applied search/filter values or lack thereof).
Conditional Bulk Selection Information & Actions
Assuming the content related to the utility bar supports bulk actions, the selection of one or more objects/rows should cause a count of those selected objects/rows to appear adjacent to the aforementioned total count.
This selection count should also double as a button. Interacting with this button should open a context menu of bulk actions the user can perform on the selected objects/rows. The bulk action context menu should include the option to clear the current bulk selection and at least one additional bulk action at a minimum. This bulk selection count button (and by relation, the total count) should be left-aligned in order to maintain a close proximity to the related content's bulk selection controls (which typically appear in the first, left-hand column of tabular components).
If the related content (ex. tabular component) is paginated, then the use of any "select-all-objects-on-this-page" option should trigger the conditional appearance of a "Select everything on all pages" button (which will cause all objects/rows on all pages to be included within the current bulk selection). Choosing either the clear selection action from the bulk action context menu or interacting with the "select-all-objects-on-this-page" option again should clear the current bulk selection entirely (causing all conditional bulk actions to disappear again).
Optional Props & Children
Ideally, there would be an optional border prop included in this component, which would allow designers and developers to choose how the component should appear in close proximity to a variety of existing EUI components.
Assuming all meta information and bulk actions are left-aligned as detailed above, we can also utilize the right-hand portion of the proposed utility bar component by making it available as a freeform actions area (that accepts any React node). As we cannot assume all actions for content will always be bulk-oriented actions, this will give designers an additional area of possible interactivity without demanding additional space be used (further ensuring consistency). For example, here is an older example of the utility bar concept that was proposed for SIEM to allow users to perform aggregation and column customization actions, in addition the any bulk actions.
Aesthetic
In order to support the easy accompaniment of this component with a wide variety of EUI components, I believe that a minimal design would be best.
Open Questions
- Should such a component as this replace or otherwise alter the current controls of the
EuiDataGrid
component? I assume the answer will be "yes" for consistency, but to what degree may be worth discussing in advance. - Assuming the current design from the provided examples is to be adopted to some degree, does this also warrant the need for a new button size (
xxs
) to be made available? I've personally desired a 12px font-sizeEuiButtonEmpty
option in a number of circumstances, including here. - @hbharding from the Observability team recently extended this concept by including a bar chart to the proposed utility bar component to provide additional context to the related content. Do we wish to account for such possibilities as being part of the proposed utility bar component? We could keep the utility bar and bar chart separate from one another, however there may be semantic and accessibility value in keeping such a visualization and its legend together in the markup.
Additional Examples
Related #3500 #2405
Hey, all! It's been asked that I update this issue with some more exact specifications for this proposed component. I'll attempt to break it down by section and elaborate below. If additional detail is desired, please let me know.
Utility Bar
"Kitchen sink" example

Section breakdown

Container
Overview

Border
Provide a prop to apply an optional border to the component container. Options should include none (default), bottom, top, and both. The reason to include this decorative border as a prop on the component rather than utilize EuiHorizontalRule
is because using an hr
element may not be semantic in all scenarios.
Padding
Provide a prop to adjust the vertical padding for the component container. Options should include none, 4px, 6px, and 8px (default). This will give developers control to match padding with common adjacent components (i.e. EuiBasicTable
) and also control how close the border should appear to the component contents.
Primary content
Overview

Visible item count
A count of the total visible items this component is referencing should always appear within the primary content area. This count should be able to support automatic updates to reflect new item counts due to the application of a search/filter.
Customizable item name
Developers should be able to supply a string to be used as the item name to be displayed in various areas of the component (i.e. visible item count, selected item count). If no string is supplied, we can simply default to items
as the string. It may also be useful for developers to account for both singular and plural item names within the component as well.
Dividing border
A dividing vertical border ($euiBorderThin
) should conditionally appear after the visible item count when one or more items has been selected by the user. This will help visually separate the visible item count from the bulk actions portion of the primary content section.
Selected item count
A count of the currently selected items should conditionally appear when one or more items has been selected by the user. This count should also optionally be able to double as a button that triggers the bulk action context menu (described further below).
Button to select all items on all pages
A button to select all items on all pages should conditionally appear if the referenced component's items is paginated and all items on the currently viewed page are in a selected state. Interacting with this button should allow the user to perform bulk actions on all items in the referenced component, update the selected item count appropriately, and finally hide this button from the page (as it is no longer needed if all items are selected).
Bulk actions menu

The bulk actions menu appears by users interacting with the selected item count button. Developers should be able to add one or more bulk actions that they wish for users to be able to perform when items in the referenced component are selected. Each action should allow developers to provide an icon, text, onClick action, and the ability to disable.
Additionally, the bulk actions menu should always have Clear selection
as the final option. Interacting with this option should clear all items from their selected state in the referenced component.
Supplementary content
The supplementary content section should allow developers to add optional supporting actions or information (i.e. any JSX.Element
). In my personal exploration, these tended to take the form of simple buttons or links laid out in an EuiFlexGroup
. Some other explorations by folks on the Observability team have also used the space to display a legend for a subsequent bar chart visualization. I think leaving it open to accept any type of content makes the most sense, given the potential diversity of items that may be desirable to add as the component gains adoption.
Other considerations
Button sizes
The intended font size for this component's text and buttons is 12px. Using the v7 theme, this would require either custom styles or the creation of a new smaller EuiButton
size. The v8 (Amsterdam) theme changes the font sizes so that an EuiButton
with size="xs"
is now 12px (where it was previously 14px in v7). How do we best maintain visual consistency of the text/button font size between the two theme versions? Or should we be focusing our efforts on v8 and not be worrying about minor inconsistencies?
@MichaelMarcialis Sorry it's taken so long, just trying to find the right time to tackle this one. Thanks for the detailed writeup/breakdown of the Spec. At one point I had also worked through some of the intricacies of table selection, especially across multiple pages. See this Whimsical. At the time I had use a more primitive version of this toolbar, but I think there is still some cross-over that I'd like to pull from that to this, mainly when it comes to the Primary Content which I have also started to pull into a Figma component.
My counter-proprosal:
Primary content
Customizable item name
Developers should be able to supply a string to be used as the item name to be displayed in various areas of the component (i.e. visible item count, selected item count). If no string is supplied, we can simply default to
items
as the string.
At the very least an "item name" or "title" should be required to name the list of things (if the toolbar exists since it will be optional). But we only need to display it once (not repeated in the bulk actions menu).
This matches the "Feature visibility" mockup provided
It may also be useful for developers to account for both singular and plural item names within the component as well.
Good call!
Visible item count
A count of the total visible items this component is referencing should always appear within the primary content area.
I think we need to take this a step further and show both total count and currently visible. My suggestion is the format of Showing 1-10 of 50
.
Clear selection button
While having a "Clear selection" button in the bulk actions dropdown is very helpful, it's also not a quick action. I'd suggest rolling it into the utility bar itself.
Other considerations
Button sizes
Or should we be focusing our efforts on v8 and not be worrying about minor inconsistencies?
Yes, the primary focus is Amsterdam (Kibana v8 theme). There may be a few inconsistencies for a while but v7 will be removed in Kibana 8.0.
Container
Border
Provide a prop to apply an optional border to the component container. Options should include none (default), bottom, top, and both.
We can add this as an actual CSS border
property like we do with EuiPageHeader's bottomBorder
prop. But why all the side options? When would you need a top border that shouldn't be provided by the consumer?
Padding
Provide a prop to adjust the vertical padding for the component container. Options should include none, 4px, 6px, and 8px (default). This will give developers control to match padding with common adjacent components (i.e.
EuiBasicTable
) and also control how close the border should appear to the component contents.
This should be more tied to the table's density/compressed prop than asking the consumer to make that decision.
I think we need to take this a step further and show both total count and currently visible. My suggestion is the format of
Showing 1-10 of 50
.
Love this addition for paginated tables!
While having a "Clear selection" button in the bulk actions dropdown is very helpful, it's also not a quick action. I'd suggest rolling it into the utility bar itself.
I went back and forth on this myself. Some of my earlier concepts for this component also had the clear selection action exposed in the utility bar, rather than nested within the currently selected actions context menu. Ultimately, I chose to put it in the currently selected actions context menu for two reasons:
- It made sense organizationally, as everything contained within does something (unselecting in this case) to the currently selected items.
- I could see situations arising where, aside from clearing selection, there is only one item in the currently selected actions context menu. Including the clear selection action in the menu ensured there would always be at least two actions in that menu. Alternatively, we could account for situations where there is only one action and conditionally not use the context menu (exposing the single action immediately in the utility bar).
Thoughts?
We can add this as an actual CSS
border
property like we do with EuiPageHeader'sbottomBorder
prop. But why all the side options? When would you need a top border that shouldn't be provided by the consumer?
Good question. I believe my original thinking was to include such options for extensibility's sake, allowing it to flank a component from above or below. But maybe that's not necessary and should be omitted until a use case arises.
This should be more tied to the table's density/compressed prop than asking the consumer to make that decision.
If we're only considering integrating this directly into table-based components (EuiBasicTable
, EuiDataGrid
), then I agree with you. However, I was thinking there may be use cases for this to exist as its own standalone component, in which case a separate padding prop could prove useful. For example, here's an old concept I had of using this utility bar pattern with an EuiSelectable
:

👋 Hey there. This issue hasn't had any activity for 180 days. We'll automatically close it if that trend continues for another week. If you feel this issue is still valid and needs attention please let us know with a comment.
I had a meeting today with @evangelia-mitsopoulou and she will help us implement this component.
We're going to start with a component spec that can be found here.
This component has been highly requested and I think by having @evangelia-mitsopoulou helping we should go ahead and add it to EUI.
I'll be helping with the design. Likely we're use the one we already have in Figma. But I'll do a research in our products to find the usage of bulk actions and to see if this design is suitable for all the use cases.
CC @chandlerprall @MichaelMarcialis
Yay! I'm glad to see this getting picked up again. Let me know if want any help or input from me on the design side, @miukimiu. Caroline and I debated on a number of different ways to approach various aspects of this proposed component, so I'd be happy to assist or provide any historical context.
With Elizabet gone, we've lost context for this work and currently do not have any plans to start it. Is there anyone currently on this thread that would be interested in catching up the team as to need and priority level for this issue?
With Elizabet gone, we've lost context for this work and currently do not have any plans to start it. Is there anyone currently on this thread that would be interested in catching up the team as to need and priority level for this issue?
Thanks, @cee-chen! I'd be happy to provide context to the team on this issue as I'm able. Just let me know when and where would be best to chat.
We discussed this in a synchronous meeting today. Adding some notes:
From the design side, it sounds like there are still some details to work out, so next steps are:
- Finalize the pattern
- Create a literal pattern page in EUI+
Keep the EUI team up to date and when you feel it's ready for us to take a look at from the technical perspective, we'll do so. The things we'll consider:
- What the component design and API might look like
- The size of the effort
- Whether or not this is a better fit for the Shared UX project
Also, for tracking, here is a link to an internal design-system-team repository: https://github.com/elastic/design-system-team/issues/183 where the work on this pattern is being tracked as well.
I'm marking this as High priority because I believe this type of work is in-line with the type of value our team and library can uniquely add to Elastic.
👋 Hi there - this issue hasn't had any activity in 6 months. If the EUI team has not explicitly expressed that this is something on our roadmap, it's unlikely that we'll pick this issue up. We would sincerely appreciate a PR/community contribution if this is something that matters to you! If not, and there is no further activity on this issue for another 6 months (i.e. it's stale for over a year), the issue will be auto-closed.