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

UI: Multi-select dropdown component #5200

Merged
merged 13 commits into from
Jan 22, 2019

Conversation

DingoEatingFuzz
Copy link
Contributor

This is part one of three for faceted search in the Nomad UI

This is a relatively straightforward component for selecting multiple attributes in a single group.

It takes a set of options, a selection set, and an onSelect handler as inputs. With this it constructs a dropdown list.

It's unfortunately at a weird midpoint between ember-basic-dropdown and ember-power-select, meaning it's built on basic dropdown, but I needed to reimplement some of the nice user expectations that power select already has. This includes things like keyboard navigation and focus management.

image

image

image

In this last screenshot you can start to see where I'm going with this. Parts two and three of this project will be utilizing this component on the Jobs and Clients page to introduce faceted search/filtering by attribute.

},

openOnArrowDown(dropdown, e) {
this.capture(dropdown);
Copy link
Contributor

@johncowen johncowen Jan 17, 2019

Choose a reason for hiding this comment

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

If the capture method only does a set, would it be best to do the set here? Do you plan on having any other code in the capture method?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's no other code in capture, but capture is also called in the template in the onOpen hook.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah gotcha, missed that, makes sense then 👍

this.capture(dropdown);

if (!this.get('isOpen') && e.keyCode === ARROW_DOWN) {
dropdown.actions.open(e);
Copy link
Contributor

@johncowen johncowen Jan 17, 2019

Choose a reason for hiding this comment

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

Not sure, but you may need to bind this to dropdown so this within actions.open refers to the component rather than the actions object - guessing here btw. If you do need to do that, don't miss the close one below also.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It works as is and this is how it is used in the docs.

image

Copy link
Contributor

Choose a reason for hiding this comment

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

Cool, if thats how they document it then fair enough

Copy link

@alisdair alisdair left a comment

Choose a reason for hiding this comment

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

Code looks great! I appreciate the attention to detail on keyboard navigation, it feels great to use.

I found a positioning bug when opening the right-aligned dropdown in the styleguide, but I think it's probably just caused the flex-end CSS. Screenshot:

screen shot 2019-01-17 at 08 41 23

Copy link
Contributor

@johncowen johncowen left a comment

Choose a reason for hiding this comment

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

Sorry! I've had this mid review for most of the day and forgot it was there. Just a couple of additions, nothing major. Like the freestyle demo page btw! I spotted the more or less the same visual thing as alisdair. Although I saw it on other menus apart from the right hand one, shout me if you need any extra detail.

dropdown.actions.close(e);
// Return focus to the trigger so tab works as expected
const trigger = this.element.querySelector('.dropdown-trigger');
if (trigger) trigger.focus();
Copy link
Contributor

@johncowen johncowen Jan 17, 2019

Choose a reason for hiding this comment

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

Below here where you preventDefault it's wrapped within the conditional - this is actually different, but thought I'd check in case the preventDefault here should be inside the conditional also?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm. It probably should, just for the correctness, but in practice I'm not concerned about the ESC key. The reason to be careful about preventDefault in the UP and DOWN case is preventDefault prevents page scrolling with arrow keys, so I wanted to make sure if you mash the down key it will traverse the full list, then carry on scrolling the page.

Copy link
Contributor

Choose a reason for hiding this comment

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

Cool no prob, I see why its different, thanks!

return haystack.includes(needle);
}

export default Helper.helper(includes);
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like ember-composable-helpers contains does the same as this? I might be wrong as it looks like it does a bit more.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

D'oh, I should definitely use contains instead of my own thing. Will change.

@DingoEatingFuzz
Copy link
Contributor Author

@alisdair and @johncowen, thanks for the reviews! I looked more into the positioning bug and learned a couple things.

  1. It happens every time the list is positioned above the trigger
  2. scrolling/repositioning after it is bugged corrects the issue
  3. power select doesn't seem to have this problem despite wrapping ember-basic-dropdown just like this

I suspect this has to do with some weird CSS relatively positioned ancestors headache, but I'm not sure yet. I'll give it a couple hours to see if I can't fix it before merging.

@DingoEatingFuzz
Copy link
Contributor Author

@alisdair and @johncowen, I pushed another commit to fix the wonky top positioning issue. It had to with dimension calculations happening before the dropdown was moved into the wormhole.

I fixed it with css, but I also filed an issue to fix the underlying issue of prematurely measuring dimensions: cibernox/ember-basic-dropdown#443

@DingoEatingFuzz DingoEatingFuzz merged commit 2e52b92 into f-ui-faceted-search Jan 22, 2019
@DingoEatingFuzz DingoEatingFuzz deleted the f-ui-multiselect-dropdown branch January 22, 2019 18:01
@DingoEatingFuzz DingoEatingFuzz mentioned this pull request Jan 24, 2019
4 tasks
@github-actions
Copy link

I'm going to lock this pull request because it has been closed for 120 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 19, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants