Skip to content

WIP: Autocomplete component - #190

Closed
danseethaler wants to merge 10 commits into
patternfly:masterfrom
danseethaler:autocomplete-component
Closed

danseethaler wants to merge 10 commits into
patternfly:masterfrom
danseethaler:autocomplete-component

Conversation

@danseethaler

Copy link
Copy Markdown
Contributor

What:
Adding a proposed auto-complete component. This component will show a dropdown of items while a user is typing. The items in the dropdown list are managed outside of the auto-complete component. The component implements the visual rendering of the items as well as keyboard support (tab, up, down, enter) and a11y accessibility. This component supports disabled items, headers, and dividers.

This is still a WIP and additional discussion is had in #189.

Link to Storybook:
https://rawgit.com/danseethaler/patternfly-react/autocomplete-component-storybook/index.html?selectedKind=AutoComplete&selectedStory=AutoComplete&full=0&addons=1&stories=1&panelRight=0&addonPanel=storybooks%2Fstorybook-addon-knobs

Additional issues:
Fixes #189


return (
<Downshift
onStateChange={({ inputValue, ...rest }) => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

sooo nice ;)... render props are so powerful!

<InputGroup>
<AutoCompleteInput
onKeyPress={e => {
const TAB_KEY = 9;

@priley86 priley86 Jan 26, 2018 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

maybe we can go ahead and move these to common/helpers.js ? export const KEY_CODES = { TAB_KEY: 9, ... }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I wish there was a way to destructure the properties but I like having them in the common folder.

@sharvit sharvit left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice @danseethaler 👍

While reviewing, I was surprised to see the show info button was disappeared from your storybook 😕

Comment thread src/common/helpers.js

export const noop = Function.prototype;

export const KEY_CODES = { TAB_KEY: 9, ENTER_KEY: 13 };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it really common?
If not, it should live under AutoComplete/constants.js

tbh, I'm not sure but let agree the first one outside of the autocomplete scope that wants to use it, will just move it into common/helpers?

Check out how the Alert is using inner helpers and constants:
https://github.com/patternfly/patternfly-react/tree/master/src/components/Alert

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Great point. Thoughts @priley86?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

keyboard key codes will be used very often when implementing a11y from a JS standpoint. it's mostly about handling enter press/escape press/tab press from the JS side...so for that reason, i would propose keeping it common to all.

import AutoCompleteItems from './AutoCompleteItems';
import { KEY_CODES } from '../../common/helpers';

export const getActiveItems = items =>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It should move into AutoComplete/helpers.js, see how it works in the Alert component:
https://github.com/patternfly/patternfly-react/tree/master/src/components/Alert


return (
<Downshift
onStateChange={({ inputValue, ...rest }) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's try to keep this method lean.
Can you move this method into this.handleStateChange?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I like abstracting like that when possible. The extra challenge here is needed the onInputUpdate function in the scope. We could forward it through by currying or something but I think it's easier to see inline.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It's a prop, it should always be available under, this.props

selectedItem={this.state.inputValue}
{...rest}
>
{({

@sharvit sharvit Jan 29, 2018 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It just looks really weird to pass a method as children in react JSX.
Downshift API support a render prop that can be used instead, I think it would feel better.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah I'm totally open on this concept. It's just a preference since Downshift supports both. I'll change it and we'll take a look!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Having a render prop sounds interesting, as it would allow us to customize the options (e.g. think you would like to add an avatar in the user dropdown)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@ohadlevy yeah that's exactly the idea here. This implementation is pushing for a standardized auto-complete using the MenuItem component with just text but Downshift can be used to compose any kind of dropdown interface you want.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

yep... render prop vs children as a function is just semantics i believe... either is fine w/ me 👍 ... i see people posting polls about this lol

{labelText && <label {...getLabelProps()}>{labelText}</label>}
<InputGroup>
<AutoCompleteInput
onKeyPress={e => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's try to keep this method lean.
Can you move this method into this.handleKeyPress?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Same thing here with all the closure scope we need. It would be nice to isolate but I don't see how without forward a bunch of variables which I'm not a fan of.

@priley86 priley86 Jan 29, 2018 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

yea... that is one thing that appears different about render props... the scope is different. I was noticing the same a bit back in the Wizard and it was hitting my brain. I think you can bind it if you want, but it's not as clean.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah I'm not a fan of binding in this context. I think it's easier to see what's happening inline even though it's long.

}

AutoComplete.propTypes = {
items: PropTypes.arrayOf(PropTypes.object).isRequired,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Wow that's cool! Thanks for sharing 👍 Added them in now.

@@ -0,0 +1,54 @@
/* eslint-disable no-alert */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Forget it here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah guess this was an issue the foreman lint config but not a problem here. Good catch!

</Col>
</Row>
</div>
))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Really need this decorator?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The main purpose of this is to show how the dropdown will stick to the input field regardless of where it is on the screen.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I still don't understand why the general design won't address this need.

this.ref && this.ref.removeEventListener('keydown', this.handeKeyPress);
}

handeKeyPress = e => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

handle.
you forgot the l

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Your english is better than mine 👋


return (
<MenuItem
{...getItemProps({

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think it would be more readable as a separate var

const itemProps = getItemProps({ ... });

<MenuItem {...itemProps}>{text}</MenuItem>;

@sharvit sharvit left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks much better,
I think it is very important to show a storybook with documentation.
Right now, if I am getting into the storybook, I have no information about how to use it in my project.


return (
<Downshift
onStateChange={({ inputValue, ...rest }) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It's a prop, it should always be available under, this.props

</Col>
</Row>
</div>
))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I still don't understand why the general design won't address this need.

@danseethaler

Copy link
Copy Markdown
Contributor Author

Thanks for the tips on the storybook info @sharvit. I haven't used that before so I patterned my info on the Alert component. Let me know what you think.

Also open to other thoughts/reviews! There is a new discussion in pf-design linked above that's worth checking out.

@danseethaler
danseethaler force-pushed the autocomplete-component branch from 14487e1 to f399287 Compare January 31, 2018 21:46

@sharvit sharvit left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Awesome, Thanks @danseethaler

One last minor issue with the AutoComplete class and I am really happy with the result here 👍

{labelText && <label {...getLabelProps()}>{labelText}</label>}
<InputGroup>
<AutoCompleteInput
onKeyPress={e => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you move this function to be apart of the class like you did with handleStateChange?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately we don't have the render prop props (say that three times fast :) in a class function so we'd have to do some pass-throughs which I'm not a fan of.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cool, I understand your point now, it will actually be really messy...

@sharvit

sharvit commented Feb 1, 2018

Copy link
Copy Markdown
Contributor

@danseethaler Can you also redeploy the storybook?
I had to run it locally in order to see it.

withInfo({
source: false,
propTables: [AutoComplete],
propTablesExclude: [MockAutoComplete],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@priley86 This approach can fix some problems we are facing with the storybook?

@danseethaler 👍

@gilad215 /cc

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

👍 yes - that is the suggestion right now... nice job.

sharvit
sharvit previously approved these changes Feb 1, 2018

@sharvit sharvit left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @danseethaler, Feels really good 👍

selectedItem
}) => (
<Dropdown.Menu
style={{

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@priley86 while we're waiting for a pf-design for this component - is there a particular way we want to handle styling so it's not inline? I don't see any .scss files except at the top level to import pf core styles.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@danseethaler i've just been adding them here in the sass directory while demonstrating them in my PRs (then we can review it here first and consider adding it to PF Core after as a subsequent PR). Make sense? I believe @jgiardino is further detailing how to do this in #195

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@priley86 ah perfect. I'll update accordingly.

@danseethaler
danseethaler force-pushed the autocomplete-component branch from 40a366b to d077833 Compare February 5, 2018 15:19
@sharvit

sharvit commented Feb 8, 2018

Copy link
Copy Markdown
Contributor

@danseethaler is it still WIP?
Feels to me like it's ready to review and merge...

@danseethaler

Copy link
Copy Markdown
Contributor Author

@sharvit yeah I spoke with @priley86 and it sounds like the PF team would like the design confirmed in core before this component is merged. Hopefully that won't take too long but it may be another week or two.

@dabeng

dabeng commented Feb 26, 2018 •

Copy link
Copy Markdown
Contributor

Hi @danseethaler . Awesome component 👍 . I used jquery version of autocomplete. I think Bootstrap-3-Typeahead and typeahead.js will give you inspirations if you want to add interesting features.

@ohadlevy

Copy link
Copy Markdown
Member

@LaViro any chance you can take over this component? sadly I don't that @danseethaler will complete it in the near future :) thanks!

@Ron-Lavi

Copy link
Copy Markdown
Collaborator

@ohadlevy, sure.. I will do my best to (auto)complete this :)

@dabeng

dabeng commented Jun 4, 2018

Copy link
Copy Markdown
Contributor

It will be better to highlight key words with bold font.

screen shot 2018-06-04 at 12 30 25 pm

Ron-Lavi pushed a commit to Ron-Lavi/patternfly-react that referenced this pull request Jun 13, 2018
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.

6 participants