Skip to content

Conversation

@kevinparkerson
Copy link
Contributor

@kevinparkerson kevinparkerson commented Nov 12, 2018

Fixes #1362

Following PR review, I've created a "Pill Container" component, addressing the following:

  • Move listbox-of-pill-options.jsx to it's own "PillContainer" folder
  • Change name of "onRemovePill" to "onRequestRemovePill" and preserve focus after an item is removed
  • Add variant:base, bare that enables using the bare modifier for the whole pill container.
  • Add style and className props
  • Options should be an array with objects a defined shape
  • Switch data examples to react components (icon, avatar)
  • Allow icon and avatar to be regular nodes as well

Additionally, I found a bug in the combobox when attempting to tab to the selected items and fixed it :)


CONTRIBUTOR checklist (do not remove)

Please complete for every pull request

  • First-time contributors should sign the Contributor License Agreement. It's a fancy way of saying that you are giving away your contribution to this project. If you haven't before, wait a few minutes and a bot will comment on this pull request with instructions.
  • npm run lint:fix has been run and linting passes.
  • Mocha, Jest (Storyshots), and components/component-docs.json CI tests pass (npm test).
  • Tests have been added for new props to prevent regressions in the future. See readme.
  • Review the appropriate Storybook stories. Open http://localhost:9001/.
  • The Accessibility panel of each Storybook story has 0 violations (aXe). Open http://localhost:9001/.
  • Review tests are passing in the browser. Open http://localhost:8001/.
  • Review markup conforms to SLDS by looking at DOM snapshot strings.

REVIEWER checklist (do not remove)

  • TravisCI tests pass. This includes linting, Mocha, Jest, Storyshots, and components/component-docs.json tests.
  • Tests have been added for new props to prevent regressions in the future. See readme.
  • Review the appropriate Storybook stories. Open http://localhost:9001/.
  • The Accessibility panel of each Storybook story has 0 violations (aXe). Open http://localhost:9001/.
  • Review tests are passing in the browser. Open http://localhost:8001/.
  • Review markup conforms to SLDS by looking at DOM snapshot strings.
Required only if there are markup / UX changes
  • Add year-first date and commit SHA to last-slds-markup-review in package.json and push.
  • Request a review of the deployed Heroku app by the Salesforce UX Accessibility Team.
  • Add year-first review date, and commit SHA, last-accessibility-review, to package.json and push.
  • While the contributor's branch is checked out, run npm run local-update within locally cloned site repo to confirm the site will function correctly at the next release.

@kevinparkerson kevinparkerson changed the title Adds Listbox of Pill Options component Adds Listbox of Pill Options component (called "Pill Container") Nov 22, 2018
@interactivellama
Copy link
Contributor

@vargasd We should be able to get Listbox of Pill Options component to you by the end of the week.

handleKeyDownTab = () => {
if (this.selectedListboxRef) {
this.setState({
activeSelectedOption: this.props.selection[0],
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

@kevinparkerson kevinparkerson Nov 28, 2018

Choose a reason for hiding this comment

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

@interactivellama if you are focused on the combobox input, pressing tab should move focus to the listbox of pills. Before this code was added it would switch away from the entire combobox (and listbox) altogether. Pressing tab while in the listbox moves focus away to the next item in the page, which I believe is correct behavior. This code isn't in PillContainer because it is not attached to a combobox input like in this case.

Copy link
Contributor

@interactivellama interactivellama left a comment

Choose a reason for hiding this comment

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

A few question here and there, but component is manually testing well.

I'm unsure about the reason to return focus to the first pill after tabbing forward.

/* eslint-disable global-require */

const siteStories = [
require('raw-loader!@salesforce/design-system-react/components/pill/__examples__/base.jsx'),
Copy link
Contributor

Choose a reason for hiding this comment

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

These should be importing from pill-container

this.state = {
options: [
{
bare: true,
Copy link
Contributor

Choose a reason for hiding this comment

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

I think bare is set by the container and not on the pill.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@interactivellama it can be both. The SLDS Listbox of Pills .slds-pill_bare modifier shows a class on the pill itself, but there's also a .slds-pill_container_bare class for the container. See below:
screen shot 2018-11-28 at 11 35 23 am

afterEach(unmountComponent);

it('Renders the base Pill Container correctly', function() {
let currentPill = 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we update this to currentPillId?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought that said "current pilld" 😆I will probably call it idOfCurrentPill to make it easier to read

});
});
});
});
Copy link
Contributor

Choose a reason for hiding this comment

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

We'll need some focus detection to ensure the keyboard arrow keys and del/backspace work. These should be able to be directly copied from https://github.com/salesforce/design-system-react/blob/master/components/combobox/__tests__/combobox.browser-test.jsx#L261

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@interactivellama had to do them a bit differently here, but I added them!

@@ -0,0 +1,32 @@
/* eslint-env jest */
Copy link
Contributor

Choose a reason for hiding this comment

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

This file shouldn't be needed. Storyshots should take care of this. https://github.com/salesforce/design-system-react/blob/master/components/story-based-tests.js#L17

@@ -0,0 +1,7 @@
{
"component": "pill-listbox",
Copy link
Contributor

Choose a reason for hiding this comment

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

Please update the name.

variant: PropTypes.string,
}),
]),
bare: PropTypes.bool,
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 be set by the parent/PillContainer

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@interactivellama we need to discuss this as there is a discrepancy on SLDS in regards to the bare pill class and bare container class

const skipIndex =
options.length > nextIndex &&
nextIndex >= 0 &&
options[nextIndex].type === 'separator';
Copy link
Contributor

Choose a reason for hiding this comment

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

There shouldn't be any separator.

const options = this.props.options;
let activeSelectedOptionIndex = this.state.activeSelectedOptionIndex;

while (
Copy link
Contributor

Choose a reason for hiding this comment

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

I would prefer a foreach or map here for the loop.

@@ -94,20 +179,16 @@ const SelectedListBox = (props) =>
>
{props.selection.map((option, renderIndex) => {
const setActiveBasedOnstateFromParent =
renderIndex === props.activeOptionIndex &&
isEqual(option, props.activeOption);
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the reason for removal of this line?

Copy link
Contributor Author

@kevinparkerson kevinparkerson Nov 28, 2018

Choose a reason for hiding this comment

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

@interactivellama it's actually a modification to:
const setActiveBasedOnStateFromParent = renderIndex === props.activeOptionIndex;

It's unnecessary to check whether an individual option in a particular iteration deeply equals the activeOption as props.selection is an array and therefore consistently ordered, so renderIndex is always reliable when compared to props.activeOptionIndex. Since activeOption and activeOptionIndex are always set at the same time by the parent combobox and pill-container components and selected-listbox is a private component, it's impossible for those two props to ever get out of sync. It also didn't seem appropriate for the selected-listbox to care about the contents of a particular option while managing focus, which only requires position. Ultimately simplifying that line makes it easier to read and marginally improves performance.

kparkerson added 2 commits November 28, 2018 12:39
>
<span
aria-selected={true}
aria-selected={false}
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 be true, since tabIndex="0"

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 pill that can be tabbed to from outside the component has tabIndex="0" and it can have that value before focus is actually on the pill. Hopefully that's correct behavior? I added the onPillFocus stuff to make sure that when the pill was tabbed to it properly reflected aria-selected={true} at that point.

@interactivellama interactivellama temporarily deployed to design-system-react-co-pr-1645 November 29, 2018 19:56 Inactive
“~” which is used for string replacement, should only be used in examples for the doc site
Update package.json,
Add clarity to component descriptions
Build docs
@interactivellama interactivellama temporarily deployed to design-system-react-co-pr-1645 November 30, 2018 07:05 Inactive
@interactivellama interactivellama temporarily deployed to design-system-react-co-pr-1645 November 30, 2018 07:10 Inactive
@interactivellama interactivellama merged commit d209d2e into salesforce:master Nov 30, 2018
@interactivellama interactivellama changed the title Adds Listbox of Pill Options component (called "Pill Container") Add Pill Container: Listbox of Pill Options component Nov 30, 2018
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.

Add Listbox Of Pill Options component

2 participants