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(DualListSelector): add new component #5120

Merged
merged 20 commits into from
Nov 17, 2020

Conversation

nicolethoen
Copy link
Contributor

What: Closes #5019

@patternfly-build
Copy link
Contributor

patternfly-build commented Nov 11, 2020

Copy link
Member

@mcarrano mcarrano left a comment

Choose a reason for hiding this comment

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

Great start @nicolethoen . Just a couple comments:

  • Arrow buttons should be disabled when there is nothing selected to move.
  • In the second example, the text above the list boxes ("# available" or "#chosen") does not seem right. Is there a reason this should be different than for the first example?

@mmenestr would be good if you can also review.

@nicolethoen
Copy link
Contributor Author

@mcarrano In the second example I was just demonstrating that the default status can be overwritten and consumer defined. By default it behaves like the first example

@codecov-io
Copy link

codecov-io commented Nov 11, 2020

Codecov Report

Merging #5120 (aba9a5f) into master (198dd0f) will decrease coverage by 0.31%.
The diff coverage is 30.71%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #5120      +/-   ##
==========================================
- Coverage   52.59%   52.28%   -0.32%     
==========================================
  Files         568      571       +3     
  Lines       10474    10627     +153     
  Branches     3917     3958      +41     
==========================================
+ Hits         5509     5556      +47     
- Misses       4263     4366     +103     
- Partials      702      705       +3     
Flag Coverage Δ
patternfly4 52.28% <30.71%> (-0.32%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...c/components/DualListSelector/DualListSelector.tsx 17.89% <17.89%> (ø)
...mponents/DualListSelector/DualListSelectorPane.tsx 50.00% <50.00%> (ø)
...ents/DualListSelector/DualListSelectorListItem.tsx 62.50% <62.50%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5191590...aba9a5f. Read the comment docs.

@evwilkin
Copy link
Member

@nicolethoen there are 2 things in the examples that are a bit confusing to me - first, when deselecting an item, the background color remains on the item until you click away (the text color does change from blue to black as expected):
Screen Shot 2020-11-11 at 4 43 17 PM

Also - in the second example, it looks like the count for the "Chosen options" is mirroring the state for the "Available options" instead of actually giving the count for the chosen options:
Screen Shot 2020-11-11 at 4 47 28 PM

availableOptionsStatus={`${this.state.availableOptions.length} available`}
availableOptionsActions={availableOptionsActions}
chosenOptions={this.state.chosenOptions}
chosenOptionsStatus={`${this.state.availableOptions.length} chosen`}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
chosenOptionsStatus={`${this.state.availableOptions.length} chosen`}
chosenOptionsStatus={`${this.state.chosenOptions.length} chosen`}

@nicolethoen
Copy link
Contributor Author

@evwilkin
nice catch on the second note. that's my bad.
as far as the background color - I think that's because the button still has focus after you deselect it. so the grey background is a result of the focus being on the item even though it's been deselected.
@mcoker do you know if that's an implementation problem on my end? or is that a css issue as far you can tell?

@mcarrano
Copy link
Member

@mcarrano In the second example I was just demonstrating that the default status can be overwritten and consumer defined. By default it behaves like the first example

Can we note/document that as part of the example then? In looking at this, not sure I'd understand why the text is different. Maybe even just rename the example "Custom header with filter" or something like that?

@evwilkin
Copy link
Member

@nicolethoen it looks like there's a bug in the keyboard interaction, I can't select either of the < or << options with the keyboard unless one of the "Available options" is selected. The buttons will appear active as expected and can be clicked, but cannot be accessed via keyboard.

In the top example below I can't navigate down inside the controls panel, and in the bottom example I can only navigate down to the first control (>>) unless I select an "Available option", then I can use the keyboard to navigate between all available controls.

Screen Shot 2020-11-12 at 11 33 35 AM

@mmenestr
Copy link
Collaborator

mmenestr commented Nov 12, 2020

To add to the discussion on the customizable text underneath the filters, I feel like we should keep them the same for both examples. Even if they are customizable, we want to encourage people to stick with the same wording of "X out of X selected", so I would keep it the same throughout the examples.

It goes back to the debate of how much freedom/customizability we want to give people and I don't think that should be one that we should "encourage" customizability for. I can add some text in the design guidelines i'm drafting up for this to say that it's customizable but I'd still recommend keeping it as designed!

The other thing is that the filters don't seem to work - is that as intended?

@tlabaj
Copy link
Contributor

tlabaj commented Nov 12, 2020

I agree with Evan. It is a confusing to me that the the item that is not selected but is hovered on has the same background color as a selected item.

@nicolethoen
Copy link
Contributor Author

@jessiehuff Tell me how you think this sounds:

As I understand it, the relationship between the html structure as written in core and the expectations of the VO tools is a little misaligned.

the VO tools are expecting role='listbox' to be tracking focus on its role='option' children which in the case of a list, should be the ul and li elements. But our list has buttons within the li and the buttons are what are getting the focus when the user uses the keyboard to navigate.

i propose we open a core issue to do two things:

  1. consider removing the buttons in each li so we can add the event handlers to the li and move focus around the list items like this example
  2. add the appropriate aria attributes to the core examples so we can be sure that the html structure matches what the VO tools expect. This way the relationship between html and VO expectations will be better defined before adding js interactions.

@mcoker
Copy link
Contributor

mcoker commented Nov 12, 2020

@nicolethoen @evwilkin @mcarrano

when deselecting an item, the background color remains on the item until you click away (the text color does change from blue to black as expected)
do you know if that's an implementation problem on my end? or is that a css issue as far you can tell?

Yep that's a CSS issue because the element is still focused after you click on it, even when you've deselected it. Maybe we should update to remove the focus styles or make them unique?

/** Actions to be displayed above the available options pane. */
availableOptionsActions?: React.ReactNode[];
/** Title applied to the chosen options pane. */
chosenOptionsTitle?: string;
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want to have a default for this or should it be required by the user to give the panes a name?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the default for this is set on line 78. It defaults to "Chosen options" but the user can override it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh sorry, I was asking if we should just make this required instead of providing a default title. I wasn't expecting the title to come with the component by default, though maybe it's fine. wdyt @mcarrano, if you don't pass a title to either the available or chosen panes, should we provide this title by default?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, I think that's fine.

return (
<DualListSelectorListItem
key={index}
isSelected={selectedOptions.indexOf(index) !== -1}
Copy link
Contributor

Choose a reason for hiding this comment

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

This should go on the button (<DualListSelectorItem>)

Copy link
Contributor

@mcoker mcoker left a comment

Choose a reason for hiding this comment

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

Looks really good! The selected class just needs to go on the item <button>, not the parent <li>. That will also make the selected item bold.

Copy link
Contributor

@jessiehuff jessiehuff left a comment

Choose a reason for hiding this comment

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

This is seriously awesome, Nicole!!!! Really nice job with this so far, this one is a complicated one. The keyboard interaction is mostly good, but I noticed one odd behavior. Once all of the options are to the right, I'm having trouble accessing the arrow buttons. If I were to choose all the options and then change my mind or notice that one of the options weren't right, I wouldn't be able to move it back over to the available options section:
Screen Shot 2020-11-13 at 9 45 13 AM
Also, I'm still struggling to use this with VO at all. It doesn't announce when items are selected (always says "not selected"), and I can't seem to perform any of the actions. I suspect it's the same issue that we've been talking about with the structure of the li and buttons. We may need to determine what the right structure and aria attributes are needed in react and then update core so that we can ensure that it's the right interaction. As long as we're able to potentially change the structure in the future, I'm ok with this going in and following up with another issue if you're unable to fix it here.

@nicolethoen nicolethoen force-pushed the add_dual_list_selector branch 2 times, most recently from 8970c9b to a778d0d Compare November 13, 2020 19:10
@evwilkin
Copy link
Member

@nicolethoen the fixes look good but I caught one keyboard bug - if your search returns a subset of the options, it doesn't look like there's a way to keyboard in to select any of the options. Note that if I try a search that returns all options (such as searching the word 'Option') it appears to work just fine.

Screen Shot 2020-11-16 at 2 39 20 PM

};

componentDidMount() {
window.addEventListener('keydown', this.handleKeys);
Copy link
Member

@evwilkin evwilkin Nov 16, 2020

Choose a reason for hiding this comment

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

This is killing all arrow key functionality for me as it calls event.preventDefault() on line 259 above for any arrow key. Even outside of the component, this is disabling the arrow keys - maybe @jessiehuff knows a better way to attach this listener

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh you're right, the preventDefault is in the wrong place :)

@kmcfaul
Copy link
Contributor

kmcfaul commented Nov 17, 2020

I'm noticing now that clicking the sort button the first time doesn't sort the options. If you toggle it a second time, it sorts, but is backwards to what it should be as indicated by the button. Moving options between the lists does sort them now, and will 'fix' the sort order if its backwards, but then hitting the sort button again after that will again not sort the options.

It seems like the code thinks the list is already sorted properly for the first sort button press?

@nicolethoen
Copy link
Contributor Author

It seems like the code thinks the list is already sorted properly for the first sort button press?

@kmcfaul Do you think I should default the list to be unsorted by default? I think the icons are facing the correct direction based on their names.
if you click it while it is a 'descending icon' it makes the items descend highest to lowest.
It may be a little confusing on the first click because it sorts them ascending (and the icon is the ascending icon) but by default the list is already ascending.

@kmcfaul
Copy link
Contributor

kmcfaul commented Nov 17, 2020

Not sure how to clip a video, so here's what I was doing to see this behavior:

From a fresh page, clicking the sort icon on the Available pane doesn't change the order. If you move any items out to the Chosen pane, or move all options to Chosen and back, the lists' sorting gets updated. If you click the Available sort button again, it again doesn't change the order. If you click the button a second time, the order is changed, but it is backwards from what the icon indicates. If you move the options, the sorting is updated.

I think it could be this line:
if (prevState.availableDescending) returnValue = returnValue * -1; in the onSort function.
Changing prevState.availableDescending to !prevState.availableDescending appears to fix it for me (and the same change in the chosen pane counterpart).

@nicolethoen
Copy link
Contributor Author

I simplified it. I removed the changing asc/desc icon since it wasnt clear if clicking an ascending icon would make sort it in ascending order, or if it was already in ascending order.

Now in the beginning the list is not sorted so that clicking the button clearly sorts it in ascending order. And as you move items around, the items are not automatically sorted, but you can click the button to sort them in ascending order.

is this approach better?

Copy link
Member

@evwilkin evwilkin left a comment

Choose a reason for hiding this comment

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

LGTM!

Copy link
Contributor

@kmcfaul kmcfaul left a comment

Choose a reason for hiding this comment

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

LGTM the example sorts now 👍

Copy link
Member

@mcarrano mcarrano left a comment

Choose a reason for hiding this comment

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

Looks good! Thanks @nicolethoen .

Copy link
Contributor

@jessiehuff jessiehuff left a comment

Choose a reason for hiding this comment

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

LGTM! Really awesome job with this, Nicole!! 🏆 🎉

I created an issue for the follow up screen reader work. 🙂

@nicolethoen
Copy link
Contributor Author

LGTM! Really awesome job with this, Nicole!! 🏆 🎉

I created an issue for the follow up screen reader work. 🙂

@jessiehuff ah i meant to do that, thank you!!

@evwilkin evwilkin merged commit 0ed1c5a into patternfly:master Nov 17, 2020
@nicolethoen nicolethoen deleted the add_dual_list_selector branch February 8, 2023 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Dual-list selector component