elastic / elastic/eui

[EuiSelectable] Evaluate supporting groups and "bulk" selection

Open
#8,994 6 comments 0 reactions 0 assignees View on GitHub
request
Dominant language
TypeScript
Stars
6.4k
Forks
911
Avg merge
2d 11h
Merged PRs (30d)
65

Description

**Problem Statement**

Working with groups of options in `EuiSelectable` is not ideal.

There are ["group labels"](https://eui.elastic.co/docs/components/forms/selection/selectable/#group-labels) (with the `option.isGroupLabel` setting):

> An option is allowed to be passed that is just a header for the options that follow it. It takes no mouse handlers and renders similar to a title.

but since there's no parent-child relationship in the component state, searching can break hierarchies and provide useless results (if you search for "foo" and there was a group under the "foo" heading, you'll see the heading but not its options).

It would also be useful to be able to do bulk selection (checking or unchecking all options in a group).

Request by @ArtemS-ela @jovana-andjelkovic

**Proposed Solution**

Make the component handle groups in a smarter way, in order to:
- enable better searching for groups
- allow bulk/group selection

**Value / Impact**

🟡 TBD

**Do alternatives or workarounds exist?**

Kind of. Searching could be improved with some custom logic in a custom `optionMatcher` function. And bulk selection is possible lifting the options state and adding controls to the group labels via append/prepend, but these appear to have accessibility issues.

- [workaround implementation in Kibana](https://github.com/elastic/autoops/pull/438/files#diff-0e017fc6276433631a1fb2dd42d82f4a7ad7fbf465113ae2e4a14d34a042dc40R134)
- https://codesandbox.io/p/sandbox/objective-gauss-5mxxkh

**Additional context (Optional)**

This came as a request in Slack.

**Designs or Specs (Optional)**

Image

---

Sketch ideas from consumer:

New option shape:
- `groupId?: string` for children.
- `isGroup?: true` for group rows (instead of isGroupLabel).

New props on EuiSelectable:
- `allowGroupSelection?: boolean` (default false).
- `groupSelectionScope?: 'all' | 'visible'` (default 'all').
- `onGroupToggle?(groupId: string, next: 'none' | 'all', scope: 'all' | 'visible'): void` (optional hook; if omitted, component manages state internally like it does for single items).
- `renderGroupControls?(state: 'none' | 'some' | 'all', groupId: string): ReactNode` (custom action area).
- `selectGroupOnLabelClick?: boolean` (wrap group label in a ).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.