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

React/DP-13718: Fuzzy search default suggestions. #544

Merged
merged 23 commits into from
May 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
46c20b0
build suggestions
clairesunstudio Apr 26, 2019
07102dc
tie suggestions to focuz
clairesunstudio Apr 26, 2019
013c982
styling overflow
clairesunstudio Apr 26, 2019
b8a244b
styling overflow
clairesunstudio Apr 26, 2019
67e4b06
add onBlur
clairesunstudio Apr 26, 2019
a80a4bc
persist event to get keydown target
clairesunstudio Apr 26, 2019
8617676
install console addon to storybook
clairesunstudio Apr 29, 2019
85779b9
fix keyboard accessibility on default options
clairesunstudio Apr 29, 2019
6e0d328
reset highlight index on blur
clairesunstudio Apr 29, 2019
aea649c
add renderDefaultSuggestion prop to inputTextFuzzy
clairesunstudio Apr 29, 2019
0182463
remove inputTextTypeAhead
clairesunstudio Apr 29, 2019
0e2ab8c
add changelog
clairesunstudio Apr 29, 2019
cc1a3d4
add changelog
clairesunstudio Apr 29, 2019
3740f25
Revert "remove inputTextTypeAhead"
clairesunstudio Apr 29, 2019
d08f450
add deprecation note
clairesunstudio Apr 29, 2019
746a882
check for env variable for warning
clairesunstudio Apr 29, 2019
14ee171
show default suggestions on clear
clairesunstudio Apr 29, 2019
3a84290
pass value to onchange callback
clairesunstudio Apr 29, 2019
104084b
Updates InputTextFuzzy component logic using setState, fixes onChange…
smurrayatwork Apr 30, 2019
d9a2870
Fixes merge conflict.
smurrayatwork Apr 30, 2019
3b7dedf
Bug Fixes.
smurrayatwork May 1, 2019
9b87a97
update is and add onChange
clairesunstudio May 1, 2019
aaa4670
remove search on empty query
clairesunstudio May 1, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions assets/scss/01-atoms/_input-fuzzy.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,20 @@
}
}

.react-autowhatever__suggestions-container {
.react-autowhatever__items-container {
display: none;

&--open {
display: block;
position: relative;
top: -1px;
border: 1px solid $c-gray-light;
background-color: #fff;
font-weight: 400;
font-size: 1.375rem;
position: absolute;
left: 0;
width: 100%;
z-index: 2;
max-height: 15em;
overflow: scroll;
overflow-y: auto;
box-shadow: 0 0.25rem 0.5rem rgba(1,1,1,0.2);
background: $c-white;
}
}

Expand All @@ -47,4 +49,4 @@
&--highlighted {
background-color: $c-gray-lightest;
}
}
}
7 changes: 7 additions & 0 deletions changelogs/DP-13688.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Minor
Added
- (React) [InputTextFuzzy] DP-13688: Added option to render all options as suggestions by default, via prop `renderDefaultSuggestion` #544
- (React) [Storybook Config] DP-13688: Added storybook console addon #544

Removed
- (React) [InputTextTypeAhead] DP-13688: Deprecate InputTextTypeAhead.
4 changes: 1 addition & 3 deletions react/.storybook/addons.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@ import '@storybook/addon-links/register';
import '@storybook/addon-viewport/register';
import '@storybook/addon-storysource/register';
import '@storybook/addon-a11y/register';



import '@storybook/addon-console';
3 changes: 2 additions & 1 deletion react/.storybook/config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {configure, addDecorator } from '@storybook/react';
import { withA11y } from '@storybook/addon-a11y';
import { withInfo } from '@storybook/addon-info';
import { withConsole } from '@storybook/addon-console';

// automatically import all files ending in *.stories.js
const req = require.context('../src', true, /.stories.js$/);
Expand Down Expand Up @@ -33,6 +34,6 @@ function loadStories() {
})
);
addDecorator(withA11y);
addDecorator((storyFn, context) => withConsole()(storyFn)(context));
}
configure(loadStories, module);

9 changes: 9 additions & 0 deletions react/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@storybook/addon-a11y": "^5.0.5",
"@storybook/addon-actions": "^5.0.5",
"@storybook/addon-console": "^1.1.0",
"@storybook/addon-info": "^5.0.5",
"@storybook/addon-knobs": "^5.0.5",
"@storybook/addon-links": "^5.0.5",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ storiesOf('atoms/forms', module)
minMatchCharLength: 1
}),
onChange: action('fuzzy input onChange'),
onSuggestionClick: action('fuzzy suggestion onClick')
onSuggestionClick: action('fuzzy suggestion onClick'),
renderDefaultSuggestion: boolean('fuzzy renderDefaultSuggestion', true)
};
return(<InputTextFuzzy {...props} />);
}),
Expand Down
119 changes: 88 additions & 31 deletions react/src/components/atoms/forms/InputTextFuzzy/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,72 @@ class InputTextFuzzy extends React.Component {
fuseOptions.keys = this.props.keys;
this.fuse = new Fuse(this.props.options, fuseOptions);
}
handleChange = (e) => {
const suggestions = this.fuse.search(e.target.value);
clearSuggestions = (event = null) => {
this.setState({
value: e.target.value,
suggestions
suggestions: [],
highlightedItemIndex: null
}, () => {
if (event && is.fn(this.props.onSuggestionClick)) {
this.props.onSuggestionClick(event, {
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 don't think we should pass this callback in blur

Copy link
Contributor Author

Choose a reason for hiding this comment

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

onSuggestionClick is when you select on a suggestion, e.g. we use it to navigate to a url and that shouldn't be triggered onBlur

suggestion: {
item: { text: this.state.value }
}
});
}
});
if (typeof this.props.onChange === 'function') {
this.props.onChange(e);
}
optionsToSuggestions = (options) => {
const suggestions = options.map((item) => ({
item: {
text: item.text,
value: item.value
},
matches: [{
indices: [],
value: item.text,
key: 'text',
arrayIndex: 0
}]
}));
return suggestions;
}
handleChange = (e) => {
e.persist();
const { value } = e.target;
if (is.empty(value)) {
const suggestions = this.optionsToSuggestions(this.props.options);
if (this.props.renderDefaultSuggestion) {
this.setState({
suggestions,
value: ''
}, () => {
if (is.fn(this.props.onChange)) {
this.props.onChange({ event: e, value, suggestions });
}
});
} else if (is.fn(this.props.onChange)) {
this.props.onChange({ event: e, value, suggestions });
}
} else {
const suggestions = this.fuse.search(value);
this.setState({
value,
suggestions
}, () => {
if (is.fn(this.props.onChange)) {
this.props.onChange({ event: e, value, suggestions });
}
});
}
};
handleFocus = () => {
if (this.props.renderDefaultSuggestion) {
const suggestions = this.optionsToSuggestions(this.props.options);
this.setState({
suggestions
});
}
}
renderItem = (suggestion) => (
<span className="ma__suggestion-content">
<span className="ma__suggestion-content-name">
Expand Down Expand Up @@ -69,13 +125,18 @@ class InputTextFuzzy extends React.Component {
value: this.state.value,
disabled: this.props.disabled,
id: this.props.inputId,
onKeyDown: (event, { newHighlightedSectionIndex, newHighlightedItemIndex }) => {
onFocus: this.handleFocus,
onBlur: () => {
this.clearSuggestions();
},
onKeyDown: (event, { newHighlightedItemIndex }) => {
event.persist();
switch (event.key) {
case 'ArrowDown':
case 'ArrowUp':
event.preventDefault();
this.setState((currentState) => {
if (currentState.suggestions.length > 0 && currentState.value && currentState.value.length > 0) {
if (currentState.suggestions.length > 0) {
return{
highlightedItemIndex: !(newHighlightedItemIndex) ? 0 : newHighlightedItemIndex
};
Expand All @@ -90,11 +151,12 @@ class InputTextFuzzy extends React.Component {
value: suggestion.item.text,
suggestions: [],
highlightedItemIndex: null
}, () => {
if (is.fn(this.props.onSuggestionClick)) {
// Suggestion is an object that can contain info on score, matches, etc.
this.props.onSuggestionClick(event, { suggestion });
}
});
if (is.fn(this.props.onSuggestionClick)) {
// Suggestion is an object that can contain info on score, matches, etc.
this.props.onSuggestionClick(event, { suggestion });
}
} else {
// Try to see if the typed in value is in the options array.
const suggestion = this.props.options.find((option) => {
Expand All @@ -107,17 +169,7 @@ class InputTextFuzzy extends React.Component {
return match;
});
if (suggestion) {
this.setState({
suggestions: [],
highlightedItemIndex: null
});
if (is.fn(this.props.onSuggestionClick)) {
this.props.onSuggestionClick(event, {
suggestion: {
item: { text: this.state.value }
}
});
}
this.clearSuggestions(event);
}
}
break;
Expand All @@ -143,22 +195,24 @@ class InputTextFuzzy extends React.Component {
return{
'data-item-index': itemIndex,
onMouseDown: (event) => {
event.persist();
this.setState({
value: suggestion.item.text,
suggestions: [],
highlightedItemIndex: null
}, () => {
if (is.fn(this.props.onSuggestionClick)) {
// Suggestion is an object that can contain info on score, matches, etc.
this.props.onSuggestionClick(event, { suggestion });
}
});
if (is.fn(this.props.onSuggestionClick)) {
// Suggestion is an object that can contain info on score, matches, etc.
this.props.onSuggestionClick(event, { suggestion });
}
},
onMouseEnter: (event) => {
onMouseEnter: () => {
this.setState({
highlightedItemIndex: itemIndex
});
},
onMouseLeave: (event) => {
onMouseLeave: () => {
this.setState({
highlightedItemIndex: null
});
Expand Down Expand Up @@ -205,7 +259,9 @@ InputTextFuzzy.propTypes = {
/** The default value for the select box. */
selected: PropTypes.string,
/** The id of the the input tag */
inputId: PropTypes.string
inputId: PropTypes.string,
/** By default all options will be rendered as suggestions on input focus */
renderDefaultSuggestion: PropTypes.bool
};

InputTextFuzzy.defaultProps = {
Expand All @@ -222,7 +278,8 @@ InputTextFuzzy.defaultProps = {
minMatchCharLength: 1
},
disabled: false,
boxed: false
boxed: false,
renderDefaultSuggestion: true
};

export default InputTextFuzzy;
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#### Description
A typeahead input text field. This atom is only available in Mayflower-React.

This component is deprecated and is replaced by [InputTextFuzzy](../InputTextFuzzy).

This component will be archive in the next major version.

#### Dependencies
This atom is dependent on the module [react-autosuggest](https://github.com/moroshko/react-autosuggest) and parse from the module [autosuggest-highlight](https://github.com/moroshko/autosuggest-highlight)
This atom is dependent on the module [react-autosuggest](https://github.com/moroshko/react-autosuggest) and parse from the module [autosuggest-highlight](https://github.com/moroshko/autosuggest-highlight)
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ storiesOf('atoms/forms', module)
''
),
onChange: action('InputTextTypeAhead onChange'),
disabled: boolean('disabled', false)
disabled: boolean('disabled', false),
onKeyDown: action('down')
};
return(<InputTextTypeAhead {...props} />);
}),
Expand Down
4 changes: 3 additions & 1 deletion react/src/components/atoms/forms/InputTextTypeAhead/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ class InputTextTypeAhead extends Component {
this.onSuggestionSelected = this.onSuggestionSelected.bind(this);
this.getSuggestions = this.getSuggestions.bind(this);
this.onKeyDown = this.onKeyDown.bind(this);
if (process.env.NODE_ENV === 'development') {
console.warn('This component is deprecated and will be archived in v10. Use InputTextFuzzy instead.');
}
}
componentWillReceiveProps(nextProps) {
this.setState({ value: nextProps.selected });
Expand Down Expand Up @@ -102,7 +105,6 @@ class InputTextTypeAhead extends Component {
parts.map((part, index) => {
const className = part.highlight ? 'highlight' : null;
const key = `suggestion_${index}`;
console.log(part.text);
return(
<span className={className} key={key}>{part.text}</span>
);
Expand Down