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

Feat/nds 253 combobox tokens #1243

Merged
merged 13 commits into from
May 14, 2024
Merged

Feat/nds 253 combobox tokens #1243

merged 13 commits into from
May 14, 2024

Conversation

akdetrick
Copy link
Collaborator

@akdetrick akdetrick commented May 13, 2024

  • Updates DropdownTrigger to accept start and end content (useful for managing tokens)
  • Adds MultiSelect component
  • Updates behavior of FieldToken component, so it works within a dropdown trigger

useMultipleSelection

This hook from downshift is a state manager for more than one selectedItem, because useSelect only manages a single selectedItem.

I'm using state reducers in both hooks to control the behavior we want when users interact with the options list OR the chips in the dropdown trigger.

@akdetrick akdetrick marked this pull request as draft May 13, 2024 21:18
@akdetrick akdetrick marked this pull request as ready for review May 13, 2024 21:34
@@ -31,7 +35,8 @@ const FieldToken = ({ label, onDismiss = noop, testId }) => {
role="button"
aria-label={`Remove ${label}`}
tabIndex={0}
onClick={() => {
onClick={(e) => {
e.stopPropagation();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want this click to bubble up to any parent, as it may trigger another event. The dismissal click should be isolated to FieldToken

import React from "react";
import PropTypes from "prop-types";

const MultiSelectItem = ({ children }) => <>{children}</>;
Copy link
Collaborator Author

@akdetrick akdetrick May 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This component gathers information about items so we can have an interface like this:

<MultiSelect>
    <MultiSelect.Item>My item jsx</MultiSelect.Item>
</MultiSelect>

Instead of accepting a big data structure like this: <MultiSelect options={{ ...bigJsObject }} />.

I'm exposing this Thing.Item style of interface for two reasons:

  • This would be consistent with other components, like Select and Tabs
  • This gives consumers full control over what gets rendered in each item

Comment on lines +230 to +231
role="option"
aria-selected={isSelected(selectedItems, item).toString()}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When using a useMultiSelect in combination with a useSelect, we get the incorrect aria-selected value on items in the listbox. Here I'm just overriding what the prop getter returns, using my own helper to determine if the item is selected or not.

The role prop is only needed here to expose the linter to it (it's otherwise added by getItemProps)

Copy link
Contributor

@agreatscott agreatscott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested this locally and it works and is keyboard accessible 🥳

Copy link

📘 Storybook Preview Available 👀

View the Storybook build from this PR in your browser:
https://60620d422ffdf100216415b2-gmskfeddih.chromatic.com/

(This action will publish a new comment and url if this PR is modified)

@agreatscott agreatscott merged commit aa0915a into main May 14, 2024
7 checks passed
@narmirobot
Copy link

🎉 This PR is included in version 3.37.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants