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

Add multiselect component #219

Merged
merged 24 commits into from
Jul 21, 2023
Merged

Add multiselect component #219

merged 24 commits into from
Jul 21, 2023

Conversation

ynotdraw
Copy link
Contributor

@ynotdraw ynotdraw commented Jul 19, 2023

🚀 Description

This PR adds the Multiselect control component.

What's next in downstream PRs:

  • MultiselectField
  • MulitselectField exposed to toucan-form
  • Select all support

🔬 How to Test

  • Visit https://5a89e728.ember-toucan-core.pages.dev/docs/components/multiselect and exercise the multiselect
  • (NOTE: All of the functionality described below has tests!)
  • You should be able to select multiple options
  • When an option is selected, the checkbox next to it should be checked
  • The popover should stay open until you click away or tab out
  • Filtering should work like Autocomplete
  • When there are selected chips, and the input is empty, pressing BACKSPACE/DELETE should delete the last selected item
  • Reselecting an already selected item should remove it
  • Keyboard interaction with arrow keys, page, home, etc. should operate the same as autocomplete
  • Entering garbage into the input without selecting anything and then tabbing out should make the input clear
  • Clicking the chevron should open the popover
  • Clicking a chip's X button should remove it from the list

📸 Images/Videos of Functionality

Screen.Recording.2023-07-19.at.2.05.02.PM.mov

@ynotdraw ynotdraw self-assigned this Jul 19, 2023
@changeset-bot
Copy link

changeset-bot bot commented Jul 19, 2023

🦋 Changeset detected

Latest commit: 73ed7de

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@crowdstrike/ember-toucan-core Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Contributor

github-actions bot commented Jul 19, 2023

Preview URLs

Env: preview
Docs: https://a98d4d82.ember-toucan-core.pages.dev

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This essentially matches the autocomplete demo. Almost copy/paste, with a few modifications.

@onChange={{this.onChange}}
@options={{this.options}}
@contentClass='z-10'
@removeButtonLabelFunction={{this.formatRemoveButtonAriaLabelStringObject}}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

More about this below!

docs/components/multiselect/index.md Outdated Show resolved Hide resolved
docs/components/multiselect/index.md Outdated Show resolved Hide resolved
docs/components/multiselect/index.md Outdated Show resolved Hide resolved
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Most of this should resemble the autocomplete component. The difference (mostly) is how the selected items are rendered as chips.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A big chunk of this was taken from autocomplete as well. There are a few changes sprinkled throughout though. I tried to comment all of the actions and logic as best I could. Please let me know if I missed anything or if I can explain things better!

@ynotdraw ynotdraw marked this pull request as ready for review July 19, 2023 18:06
@ynotdraw ynotdraw marked this pull request as draft July 19, 2023 19:34
Copy link
Contributor

@nicolechung nicolechung left a comment

Choose a reason for hiding this comment

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

Reviewed just the tests for now, left a few comments - thank you for writing these exhaustive tests!


assert.dom('[data-multiselect-selected-option]').exists({ count: 2 });

let chips = document.querySelectorAll('[data-multiselect-selected-option]');

This comment was marked as resolved.


await click('[data-multiselect]');

// Since `@selected=["blue"]`, we expect it to be selected

This comment was marked as resolved.

['b', 'c'],
'Expected "a" to be removed on change as it was re-selected'
);
assert.step('handleChange');

This comment was marked as resolved.

assert.dom('[role="listbox"]').exists();

// Now blur the elment
await click('[data-input]');
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm confused, doesn't this focus the <input /> element?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

assert.dom('[role="option"]').exists({ count: 2 });
// We can also verify our data attributes are spread to each option
Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you! Very helpful

@github-actions github-actions bot requested a deployment to ember-toucan-core (Preview) July 20, 2023 17:11 Abandoned
Comment on lines 137 to 143
assert('The `:remove` block is required.', removeBlockExists);

if (!removeBlockExists) {
return false;
}

return true;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This gets cleaned up in the next commit

{{yield
(hash
option=option
Remove=(component
Copy link
Contributor

@clintcs clintcs Jul 20, 2023

Choose a reason for hiding this comment

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

Whose bright idea was it to name this "Remove"? 😆

assert.dom('[data-multiselect]').hasAttribute('aria-expanded');
});

test('it sets `aria-controls`', async function (assert) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I could see this test being slightly more valuable if its value were also tested for and not just its existence. Though I could also see an argument for removing this test given its minimal value.

aria-activedescendant strikes me as perhaps a better test candidate.

{{! template-lint-disable no-pointer-down-event-binding }}
<button
aria-label={{@label}}
class="focusable reset-styles p-1"
Copy link
Contributor

Choose a reason for hiding this comment

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

Mind dumping a copy of our reset-styles TODO here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great catch, thank you! Added at 73ed7de

@ynotdraw
Copy link
Contributor Author

Going to go ahead and merge as to unblock other downstream work, but please feel free to keep commenting and reviewing! I'll also have Komal take a look over everything in the middle of next week.

@ynotdraw ynotdraw merged commit 706f44e into main Jul 21, 2023
14 checks passed
@ynotdraw ynotdraw deleted the add-multi-autocomplete branch July 21, 2023 11:43
@github-actions github-actions bot mentioned this pull request Jul 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants