Open jameskoster opened 1 month ago
Thank you for working on this!
In the case of listbox widgets, there is no such thing as "checkbox" or "radio" items . Rather, there is only one type of listbox options — and there can be none, one, or multiple selected at the same time.
To avoid the confusion with radios and checkboxes, I wonder if we should consider a different visual indicator for the selected items (for example, ariakit uses a tick in their multiple selection combobox example)
cc @WordPress/gutenberg-components
I wonder if we could conceptualize this as a "MenuList", as that'd allow us to, instead of creating a new component, make the existing menu component cover more use cases by making it more open. This mimic the Ariakit structure (see MenuList
) and, since we already use it for the menu, it'd make this easier to implement. Overall, I think it'd greatly lower the design, maintenance, education, and support overhead. It'd just be one more Storybook story in that component.
To be clear, what I am proposing is to add the possibility to use our current menu (DropdownMenuV2
) without a popover or a trigger. This is already supported by Ariakit and valid in terms of a11y, and the design looks pretty similar to the screencaps in this issue description:
@ciampo's suggestion of using a tick is also covered by this.
Listboxes are more generic and can be the foundation of components like CustomSelectControl
, ComboboxControl
and FormTokenField
— menus are more specific and have their different roles and semantics. I'm not sure they are compatible to the point of sharing the same underlying implementation.
We could share a lot of the styles, though.
I like the design of both the checkbox and the radio, but - as pointed out by @ciampo and @DaniGuardiola - they both look like there are from different design languages. Either the Radio is missing a border or the Checkbox shouldn't have one as in the DropdownMenu2 UX wise, I'd go with a design that shows the border even when not selected. At least on hover.
Another thing is the color blue. I like it. But currently, most components use black as indicator for being selected.
Maybe we also should consider ~"half ticked" (or how would you say that?)~ the indeterminate boolean property
Maybe we also should consider ~"half ticked" (or how would you say that?)~ the indeterminate boolean property
As mentioned above, if we're sticking with listbox
semantics, there is no such thing as checkbox semantics, and therefore I don't think that indeterminate state would apply.
At most, that could be added to places where we support menu
semantics (like DrodownMenu
and DropdownMenuV2
), since those semantics support menuitemcheckbox
roles
On my phone right now so can't check, but I think it's worth looking into the semantics that Ariakit has for MenuList. Wouldn't surprise me if it just used plain listbox semantics. The name of Ariakit components does not always correlate to the corresponding semantics.
there is no such thing as "checkbox" or "radio" items
@ciampo I appreciate they are not semantically checkbox or radio items, but isn't it correct that in terms of behavior listboxes can be configured either as single-select (similar to a select
) or multi-select (kind of like a group of checkboxes). Different style treatment can help users identify the behavior, even if it's not semantically accurate.
I suppose I should have noted that the design would not utilise actual checkboxes, they would be elements styled to look like checkboxes. This is a fairly common pattern in design systems; there's a similar example in github issue label assignment UI:
I'm trying to think what the usage guidelines for this would look like. Specifically, when should one use this Listbox over other similar controls, like:
I'm not sure you'd need a separate Listbox component unless it is for a feature that is not covered in the alternatives, like making the items sortable (as in #64686). And if the main feature we want to provide is sortability, then it might make more sense to provide it as a lower-level, headless API (e.g. SortableJS) so consumers can add sortability to a broader variety of designs.
I think it's worth looking into the semantics that Ariakit has for MenuList. Wouldn't surprise me if it just used plain listbox semantics.
@DaniGuardiola I believe that they apply role="menu"
. But even if that wasn't the case, having a checkbox or a radio item just doesn't make sense in a listbox
widget at the standard level, right?
I appreciate they are not semantically checkbox or radio items, but isn't it correct that in terms of behavior listboxes can be configured either as single-select (similar to a
select
) or multi-select (kind of like a group of checkboxes). Different style treatment can help users identify the behavior, even if it's not semantically accurate.I suppose I should have noted that the design would not utilise actual checkboxes, they would be elements styled to look like checkboxes. This is a fairly common pattern in design systems; there's a similar example in github issue label assignment UI:
@jameskoster I see your point — let me try to rephrase my feedback:
"radio" and "checkbox" are concepts that don't apply in the context of a listbox, and I'm afraid that using them even as just visual cues may set the wrong expectation to the user.
Basically, we should just pick one style (probably checkbox-like), instead of using both checkbox-like and radio-like
I'm trying to think what the usage guidelines for this would look like
@mirka I am seeing this component as a very low-level component that we can leverage to implement all of the other components that you mentioned? Similarly to Composite`
Basically, we should just pick one style (probably checkbox-like), instead of using both checkbox-like and radio-like
Don't you think there's value in the user understanding at a glance whether they can select one or many options? For example consider the the Status filter in the Pages data view. Currently the UI gives no indication whether the list is multi-select or single-select which leaves questions about the behavior:
If you see empty checkboxes then it's much clearer that you can select multiple options.
I am seeing this component as a very low-level component that we can leverage to implement all of the other components that you mentioned?
Of the components I listed, those that could possibly use this is ComboboxControl/FormTokenField (which will eventually be a unified as ComboboxControlV2) and CustomSelectControlV2. Ariakit Select and Combobox already have their own subcomponents for these things. So in that case, it would be more natural to just share/reuse the styles, not entire components, because Ariakit is already providing them (behavior + semantics).
The only reason we would want a standalone Listbox component (styles + behavior + semantics) is if we want to use it independently, or in a non-Ariakit-based component. And I'm struggling to imagine such a use case (aside from the sortable case).
The only reason we would want a standalone Listbox component (styles + behavior + semantics) is if we want to use it independently, or in a non-Ariakit-based component. And I'm struggling to imagine such a use case (aside from the sortable case).
The example that Jat posted above ( the dataviews filter) could be such a use case?
The example that Jat posted above ( the dataviews filter) could be such a use case?
I think I would prefer just making CustomSelectControlV2 flexible enough to support that design. Right now, renderSelectedValue
doesn't allow that level of customization, but we should if design requires it.
The example that Jat posted above ( the dataviews filter) could be such a use case?
I think I would prefer just making CustomSelectControlV2 flexible enough to support that design. Right now,
renderSelectedValue
doesn't allow that level of customization, but we should if design requires it.
Definitely something to consider. We'd also need to make sure we can offer the listbox itself separate from the popover / dropdown part, though, because this UI pattern can also happen:
Listboxes can be used as controls in their own right, and also power more complex components like Comboboxes and Autocomplete inputs.
Listbox Item
This is the atomic element that makes up the majority of the Listbox component. It can appear as either a checkbox for multi-select listboxes or a radio for single-select listboxes. In the multi-select variant the checkbox is not a checkbox input, merely an element styled to look like one.
Listbox
Listbox is comprised of several elements; notably:
ListboxControl
ListboxControl is the consumable component. It follows the same format as similar components by providing layout and optional elements like a label and help text. Here's a video demonstration of the assembled component:
https://github.com/user-attachments/assets/8de50935-473a-4a6e-a9af-edbf3928b2b6