grommet / hpe-design-system

HPE Design System
45 stars 24 forks source link

Draft PR for Selector component #3840

Open taysea opened 1 month ago

taysea commented 1 month ago

Create draft PR for "Selector" component.

Code prototype

Component building checklist: Grommet Component building checklist.docx

General

What is the purpose of this component?

This component aims to streamline the process of making single and multiple selections in scenarios where options should all be exposed on the screen and may contain rich content. Unlike "Select" which seeks to condense the amount of screen real estate, this component is for cases where the controls are intended to have higher visual prominence.

The component enforces:

The component does not tightly enforce content, allowing it to be flexible to a variety of use cases.

Design link?

Designs: https://www.figma.com/file/5uOrsL2qk8XwwH8C1ZpDb6/branch/QNzyc61prL0zNDyDPHLGz1/HPE-Design-System-Components?type=design&node-id=27691-1164&mode=design&t=bBqv3mOWEbQG0nz4-0

Use cases: https://www.figma.com/file/gEl7V4t4Dd1ZGOZy6EswmQ/Selector-component-%233729?type=design&node-id=1-532&mode=design&t=fzMFObky4yCxaYRy-0

What are common use cases that Storybook examples should represent? What’s the 80% case? (Connect with Lucas)

Summary:

Examples:

Component naming

Is there a native HTML element namespace to use?

Behaviorally, this is most similar to CheckBoxGroup/RadioButtonGroup and our new "ToggleGroup". However, behavior is that you can unselect single selection (which differs from native HTML).

HeadlessUI has their RadioGroup with more flexible styling (not exactly what we're doing): https://headlessui.com/react/radio-group

Explore AirBnb namespace potentially: https://airbnb.io/visx/gallery, https://www.figma.com/community/file/1206705782258966386 (not sure if this is official from Airbnb or just replica)

Or, is there an industry standard term used by component libraries?

There isn't a clear component name.

API/Anatomy -- MVP requirements (Taylor)

Image Image Image

Based on the 80% case for custom content, it makes most sense to approach this component from a "compositional" mindset, rather than just a "configurable" one. Additionally, it feels appropriate to have a "parent"/"child" component set -- similar to Tab/Tabs or Accordion/AccordionPanel.

"Parent" component (SelectorGroup, name TBD)

SelectorGroup API

defaultValue?: string | string[] // the default selected, corresponds to child's title or some kind of key
value?: string | string[] // the selected children, corresponds to child's title or some kind of key
multiple?: boolean; // whether to allow multiple selection or not
onSelect?: (event) => {} // where event.value contains the next selected
~size?: string~ // just support "medium" default size, a bit early to introduce sizes, can support box props and people can pass whatever content which can be responsive,etc.

"Child" component (Selector, name TBD)

title?: string; description?: string; // also too opinionated icon?: JSX.Element // this feels opinionated? Yes.


**"Child" subcomponent** (SelectorBody, name TBD)

- Required anatomy:
   - N/A
- Optional anatomy:

SelectorBody API

children?: JSX.Element | JSX.Element[];



----- Review with Lucas and Matt before building -----

### Semantic structure (Brittany)

What is the proper HTML markup?

The options that were being assessed were RadioButtonGroup, CheckBoxGroup or use Buttons with `roles` similar to ToggleGroup

RadioButtonGroup
- Default behavior of RadioButtonGroup is displaying a set of mutually exclusive options from which a person may `select exactly one` The key behavior here is that the user can `select exactly one` no more or less. While reading guidance online for RadioButtonGroup if a user wanted to deselect an item, then it is recommended to add another option such as "none" or "other" within the Group. 
In our `Selector` component we want to make it so the user can select only `one` item but also unselect this item. We should not use `radio` in this example, if we change the behavior it will introduce confusion since it diverges from everyone expected behavior of radio buttons.

### Accessibility (Brittany)

What is the desired keyboard behavior? Screen reader announcements/roles/etc.

- [ ] Consider if interactive elements should be allowed inside and how to build accordingly
-
Since this is a `group` of options for users to click for the single/multiple version of this the `role=group` to convey to screen readers that actions are part of a group. 

We will not be using the `radio` role again because this does not follow the standard UI behavior of a traditional RadioButtonGroup.

Since we are putting these items into a `group` role they desired keyboard behavior is going to be `tab` to the group than use `arrow keys` to move inside the group and `space/enter` to select an item. 

The Selector is similar to toggleButton in which the they have 2 states which is `true` or `false` We will need to add `aria-pressed` to our button element which turns the button to a toggle button. This will represent the buttons current "pressed" state. 

[Toggle buttons require a full press-and-release cycle to change their value. Pressing and releasing it once changes the value to true. If it's pressed and released again, the value changes back to false.](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-pressed)

What are any additional accessibility requirements? 

### Styling

What is the desired styling for base theme? For HPE theme? 

Any theme enhancements? 

### Testing

What should test cases cover? 

![Image](https://github.com/grommet/hpe-design-system/assets/12522275/72512132-3177-4e1f-9843-89f1087eb8d7)

![Image](https://github.com/grommet/hpe-design-system/assets/12522275/6252253d-f619-408a-a23c-f25e24ea56c6)

### Other questions
- [ ] Should this be integrated with "Data+friends" out of the box?
- [ ] ...?

Deliverables:
- [ ] PR filed to Grommet