-
Notifications
You must be signed in to change notification settings - Fork 433
Add Pill Container: Listbox of Pill Options component #1645
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 Pill Container: Listbox of Pill Options component #1645
Conversation
… and made it preserve focus following removal
…tions array objects, added support for error pills, added className and style props
|
@vargasd We should be able to get Listbox of Pill Options component to you by the end of the week. |
components/combobox/combobox.jsx
Outdated
| handleKeyDownTab = () => { | ||
| if (this.selectedListboxRef) { | ||
| this.setState({ | ||
| activeSelectedOption: this.props.selection[0], |
There was a problem hiding this comment.
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 the tab reset here? We are not doing it in PillContainer right now either http://localhost:9001/?selectedKind=SLDSPillContainer&selectedStory=Base%20Pill%20Container&full=0&addons=1&stories=1&panelRight=0&addonPanel=storybook%2Factions%2Factions-panel
There was a problem hiding this comment.
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.
interactivellama
left a comment
There was a problem hiding this 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'), |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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:

| afterEach(unmountComponent); | ||
|
|
||
| it('Renders the base Pill Container correctly', function() { | ||
| let currentPill = 1; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
| }); | ||
| }); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 */ | |||
There was a problem hiding this comment.
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
components/pill-container/docs.json
Outdated
| @@ -0,0 +1,7 @@ | |||
| { | |||
| "component": "pill-listbox", | |||
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
components/pill-container/index.jsx
Outdated
| const skipIndex = | ||
| options.length > nextIndex && | ||
| nextIndex >= 0 && | ||
| options[nextIndex].type === 'separator'; |
There was a problem hiding this comment.
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.
components/pill-container/index.jsx
Outdated
| const options = this.props.options; | ||
| let activeSelectedOptionIndex = this.state.activeSelectedOptionIndex; | ||
|
|
||
| while ( |
There was a problem hiding this comment.
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); | |||
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
…avior correct for combobox, fix a bug with aria-selected, and more
| > | ||
| <span | ||
| aria-selected={true} | ||
| aria-selected={false} |
There was a problem hiding this comment.
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"
There was a problem hiding this comment.
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.
“~” 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
Fixes #1362
Following PR review, I've created a "Pill Container" component, addressing the following:
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
npm run lint:fixhas been run and linting passes.components/component-docs.jsonCI tests pass (npm test).REVIEWER checklist (do not remove)
components/component-docs.jsontests.Required only if there are markup / UX changes
last-slds-markup-reviewinpackage.jsonand push.last-accessibility-review, topackage.jsonand push.npm run local-updatewithin locally cloned site repo to confirm the site will function correctly at the next release.