From 46c20b04674bf36d1f2509810837e4bde4888a89 Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Fri, 26 Apr 2019 17:11:45 -0400 Subject: [PATCH 01/22] build suggestions --- .../atoms/forms/InputTextFuzzy/index.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/react/src/components/atoms/forms/InputTextFuzzy/index.js b/react/src/components/atoms/forms/InputTextFuzzy/index.js index 8f50280aea..3fb47afb9f 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/index.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/index.js @@ -13,13 +13,28 @@ class InputTextFuzzy extends React.Component { super(props); this.state = { value: this.props.selected || '', - suggestions: [], + suggestions: this.optionsToSuggestions(this.props.options), highlightedItemIndex: null }; const fuseOptions = this.props.fuseOptions; fuseOptions.keys = this.props.keys; this.fuse = new Fuse(this.props.options, fuseOptions); } + optionsToSuggestions = (options) => { + const suggestions = options.map((item) => ({ + item: { + text: item.text, + value: item.value + }, + matches: [{ + indices: [], + value: item.value, + key: 'text', + arrayIndex: 0 + }] + })); + return suggestions; + } handleChange = (e) => { const suggestions = this.fuse.search(e.target.value); this.setState({ From 07102dcd66431aadd54d7970b4b97413317f7b5e Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Fri, 26 Apr 2019 17:16:58 -0400 Subject: [PATCH 02/22] tie suggestions to focuz --- react/src/components/atoms/forms/InputTextFuzzy/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/react/src/components/atoms/forms/InputTextFuzzy/index.js b/react/src/components/atoms/forms/InputTextFuzzy/index.js index 3fb47afb9f..3c9b7b6d6e 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/index.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/index.js @@ -13,7 +13,7 @@ class InputTextFuzzy extends React.Component { super(props); this.state = { value: this.props.selected || '', - suggestions: this.optionsToSuggestions(this.props.options), + suggestions: [], highlightedItemIndex: null }; const fuseOptions = this.props.fuseOptions; @@ -84,6 +84,9 @@ class InputTextFuzzy extends React.Component { value: this.state.value, disabled: this.props.disabled, id: this.props.inputId, + onFocus: (event) => { + this.setState({ suggestions: this.optionsToSuggestions(this.props.options) }); + }, onKeyDown: (event, { newHighlightedSectionIndex, newHighlightedItemIndex }) => { switch (event.key) { case 'ArrowDown': From 013c982b5d61e23df94ba916fb2f32bc16ef2f05 Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Fri, 26 Apr 2019 17:28:57 -0400 Subject: [PATCH 03/22] styling overflow --- react/src/components/atoms/forms/InputTextFuzzy/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react/src/components/atoms/forms/InputTextFuzzy/index.js b/react/src/components/atoms/forms/InputTextFuzzy/index.js index 3c9b7b6d6e..6d6e24fe56 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/index.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/index.js @@ -28,7 +28,7 @@ class InputTextFuzzy extends React.Component { }, matches: [{ indices: [], - value: item.value, + value: item.text, key: 'text', arrayIndex: 0 }] From b8a244b41ca50a28b31d9a3e27ad0268b3019efa Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Fri, 26 Apr 2019 17:29:05 -0400 Subject: [PATCH 04/22] styling overflow --- assets/scss/01-atoms/_input-fuzzy.scss | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/assets/scss/01-atoms/_input-fuzzy.scss b/assets/scss/01-atoms/_input-fuzzy.scss index aa1fa09f7b..ac06063029 100644 --- a/assets/scss/01-atoms/_input-fuzzy.scss +++ b/assets/scss/01-atoms/_input-fuzzy.scss @@ -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; } } @@ -47,4 +49,4 @@ &--highlighted { background-color: $c-gray-lightest; } -} \ No newline at end of file +} From 67e4b06f0979046d491049d9626abb339cf0194f Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Fri, 26 Apr 2019 17:33:15 -0400 Subject: [PATCH 05/22] add onBlur --- react/src/components/atoms/forms/InputTextFuzzy/index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/react/src/components/atoms/forms/InputTextFuzzy/index.js b/react/src/components/atoms/forms/InputTextFuzzy/index.js index 6d6e24fe56..5f4c979929 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/index.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/index.js @@ -87,6 +87,9 @@ class InputTextFuzzy extends React.Component { onFocus: (event) => { this.setState({ suggestions: this.optionsToSuggestions(this.props.options) }); }, + onBlur: (event) => { + this.setState({ suggestions: [] }); + }, onKeyDown: (event, { newHighlightedSectionIndex, newHighlightedItemIndex }) => { switch (event.key) { case 'ArrowDown': From a80a4bcbfd06d4ad5c487ac072a7eae2cbb301a4 Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Fri, 26 Apr 2019 17:40:39 -0400 Subject: [PATCH 06/22] persist event to get keydown target --- react/src/components/atoms/forms/InputTextFuzzy/index.js | 6 ++++-- .../forms/InputTextTypeAhead/InputTextTypeAhead.stories.js | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/react/src/components/atoms/forms/InputTextFuzzy/index.js b/react/src/components/atoms/forms/InputTextFuzzy/index.js index 5f4c979929..968768a312 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/index.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/index.js @@ -84,13 +84,15 @@ class InputTextFuzzy extends React.Component { value: this.state.value, disabled: this.props.disabled, id: this.props.inputId, - onFocus: (event) => { + onFocus: () => { this.setState({ suggestions: this.optionsToSuggestions(this.props.options) }); }, - onBlur: (event) => { + onBlur: () => { this.setState({ suggestions: [] }); }, onKeyDown: (event, { newHighlightedSectionIndex, newHighlightedItemIndex }) => { + event.persist(); + console.log(event) switch (event.key) { case 'ArrowDown': case 'ArrowUp': diff --git a/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.stories.js b/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.stories.js index 1361fad166..d3c97097f5 100644 --- a/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.stories.js +++ b/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.stories.js @@ -24,7 +24,8 @@ storiesOf('atoms/forms', module) '' ), onChange: action('InputTextTypeAhead onChange'), - disabled: boolean('disabled', false) + disabled: boolean('disabled', false), + onKeyDown: action('down') }; return(); }), From 861767680d865d335622c30dc5ba05aa7a5d3d2e Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Mon, 29 Apr 2019 11:27:19 -0400 Subject: [PATCH 07/22] install console addon to storybook --- react/.storybook/addons.js | 4 +--- react/.storybook/config.js | 3 ++- react/package-lock.json | 9 +++++++++ react/package.json | 1 + 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/react/.storybook/addons.js b/react/.storybook/addons.js index 6e8e3ce365..2686f0c333 100644 --- a/react/.storybook/addons.js +++ b/react/.storybook/addons.js @@ -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'; diff --git a/react/.storybook/config.js b/react/.storybook/config.js index a0ad0efdf7..c96af12aed 100644 --- a/react/.storybook/config.js +++ b/react/.storybook/config.js @@ -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$/); @@ -33,6 +34,6 @@ function loadStories() { }) ); addDecorator(withA11y); + addDecorator((storyFn, context) => withConsole()(storyFn)(context)); } configure(loadStories, module); - diff --git a/react/package-lock.json b/react/package-lock.json index 4e95d30ab1..40d9f5975c 100644 --- a/react/package-lock.json +++ b/react/package-lock.json @@ -2691,6 +2691,15 @@ } } }, + "@storybook/addon-console": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@storybook/addon-console/-/addon-console-1.1.0.tgz", + "integrity": "sha512-G36/KB0uN5OB30W/QQU/NIbQ2EA4ZjJGORvYNx83bojRN2cKF0NFae5hEwlAAhKZK31qe3g3bsymWvc7+WBCpA==", + "dev": true, + "requires": { + "global": "^4.3.2" + } + }, "@storybook/addon-info": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/@storybook/addon-info/-/addon-info-5.0.5.tgz", diff --git a/react/package.json b/react/package.json index af0eeee5f4..d4fd2d03db 100644 --- a/react/package.json +++ b/react/package.json @@ -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", From 85779b9f766116f57d80ba7308044c1b47e5062f Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Mon, 29 Apr 2019 11:29:41 -0400 Subject: [PATCH 08/22] fix keyboard accessibility on default options --- react/src/components/atoms/forms/InputTextFuzzy/index.js | 5 ++--- react/src/components/atoms/forms/InputTextTypeAhead/index.js | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/react/src/components/atoms/forms/InputTextFuzzy/index.js b/react/src/components/atoms/forms/InputTextFuzzy/index.js index 968768a312..1d719d5c6b 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/index.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/index.js @@ -90,15 +90,14 @@ class InputTextFuzzy extends React.Component { onBlur: () => { this.setState({ suggestions: [] }); }, - onKeyDown: (event, { newHighlightedSectionIndex, newHighlightedItemIndex }) => { + onKeyDown: (event, { newHighlightedItemIndex }) => { event.persist(); - console.log(event) 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 }; diff --git a/react/src/components/atoms/forms/InputTextTypeAhead/index.js b/react/src/components/atoms/forms/InputTextTypeAhead/index.js index e9627ddd55..9b05578e88 100644 --- a/react/src/components/atoms/forms/InputTextTypeAhead/index.js +++ b/react/src/components/atoms/forms/InputTextTypeAhead/index.js @@ -102,7 +102,6 @@ class InputTextTypeAhead extends Component { parts.map((part, index) => { const className = part.highlight ? 'highlight' : null; const key = `suggestion_${index}`; - console.log(part.text); return( {part.text} ); From 6e0d328315c5040ed4af7fce46a98b10ed8db54e Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Mon, 29 Apr 2019 11:34:46 -0400 Subject: [PATCH 09/22] reset highlight index on blur --- react/src/components/atoms/forms/InputTextFuzzy/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/react/src/components/atoms/forms/InputTextFuzzy/index.js b/react/src/components/atoms/forms/InputTextFuzzy/index.js index 1d719d5c6b..9a2795aea4 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/index.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/index.js @@ -88,7 +88,10 @@ class InputTextFuzzy extends React.Component { this.setState({ suggestions: this.optionsToSuggestions(this.props.options) }); }, onBlur: () => { - this.setState({ suggestions: [] }); + this.setState({ + suggestions: [], + highlightedItemIndex: null + }); }, onKeyDown: (event, { newHighlightedItemIndex }) => { event.persist(); From aea649cd3c94b19a97b94f5e7010bb73534d01d5 Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Mon, 29 Apr 2019 11:51:38 -0400 Subject: [PATCH 10/22] add renderDefaultSuggestion prop to inputTextFuzzy --- .../atoms/forms/InputTextFuzzy/index.js | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/react/src/components/atoms/forms/InputTextFuzzy/index.js b/react/src/components/atoms/forms/InputTextFuzzy/index.js index 9a2795aea4..963cf7e600 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/index.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/index.js @@ -20,6 +20,12 @@ class InputTextFuzzy extends React.Component { fuseOptions.keys = this.props.keys; this.fuse = new Fuse(this.props.options, fuseOptions); } + clearSuggestions = () => { + this.setState({ + suggestions: [], + highlightedItemIndex: null + }); + } optionsToSuggestions = (options) => { const suggestions = options.map((item) => ({ item: { @@ -41,10 +47,18 @@ class InputTextFuzzy extends React.Component { value: e.target.value, suggestions }); - if (typeof this.props.onChange === 'function') { + if (is.fn(this.props.onChange)) { this.props.onChange(e); } }; + handleFocus = () => { + if (this.props.renderDefaultSuggestion) { + const suggestions = this.optionsToSuggestions(this.props.options); + this.setState({ + suggestions + }); + } + } renderItem = (suggestion) => ( @@ -84,14 +98,9 @@ class InputTextFuzzy extends React.Component { value: this.state.value, disabled: this.props.disabled, id: this.props.inputId, - onFocus: () => { - this.setState({ suggestions: this.optionsToSuggestions(this.props.options) }); - }, + onFocus: this.handleFocus, onBlur: () => { - this.setState({ - suggestions: [], - highlightedItemIndex: null - }); + this.clearSuggestions(); }, onKeyDown: (event, { newHighlightedItemIndex }) => { event.persist(); @@ -132,10 +141,7 @@ class InputTextFuzzy extends React.Component { return match; }); if (suggestion) { - this.setState({ - suggestions: [], - highlightedItemIndex: null - }); + this.clearSuggestions(); if (is.fn(this.props.onSuggestionClick)) { this.props.onSuggestionClick(event, { suggestion: { @@ -178,12 +184,12 @@ class InputTextFuzzy extends React.Component { this.props.onSuggestionClick(event, { suggestion }); } }, - onMouseEnter: (event) => { + onMouseEnter: () => { this.setState({ highlightedItemIndex: itemIndex }); }, - onMouseLeave: (event) => { + onMouseLeave: () => { this.setState({ highlightedItemIndex: null }); @@ -230,7 +236,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 = { @@ -247,7 +255,8 @@ InputTextFuzzy.defaultProps = { minMatchCharLength: 1 }, disabled: false, - boxed: false + boxed: false, + renderDefaultSuggestion: true }; export default InputTextFuzzy; From 0182463fc70b624a90ffbdcc1a2382d6ef72ef08 Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Mon, 29 Apr 2019 11:51:55 -0400 Subject: [PATCH 11/22] remove inputTextTypeAhead --- assets/scss/01-atoms/_input-typeahead.scss | 85 --------- .../InputTextFuzzy/InputTextFuzzy.stories.js | 1 + .../InputTextTypeAhead.knobs.options.js | 37 ---- .../InputTextTypeAhead/InputTextTypeAhead.md | 5 - .../InputTextTypeAhead.stories.js | 33 ---- .../atoms/forms/InputTextTypeAhead/index.js | 175 ------------------ .../atoms/forms/InputTextTypeAhead/style.scss | 2 - react/src/index.js | 1 - 8 files changed, 1 insertion(+), 338 deletions(-) delete mode 100644 assets/scss/01-atoms/_input-typeahead.scss delete mode 100644 react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.knobs.options.js delete mode 100644 react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.md delete mode 100644 react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.stories.js delete mode 100644 react/src/components/atoms/forms/InputTextTypeAhead/index.js delete mode 100644 react/src/components/atoms/forms/InputTextTypeAhead/style.scss diff --git a/assets/scss/01-atoms/_input-typeahead.scss b/assets/scss/01-atoms/_input-typeahead.scss deleted file mode 100644 index fda60ff7f4..0000000000 --- a/assets/scss/01-atoms/_input-typeahead.scss +++ /dev/null @@ -1,85 +0,0 @@ -.ma__input-typeahead { - font-size: 1.25rem; - - .highlight { - color: $c-primary-alt; - font-weight: bold; - } - - input { - width: 100%; - -webkit-appearance: none; - &::-ms-clear { - display: none; - } - } - - ul { - width: 100%; - margin: 0px; - padding: 0px; - li { - border: 1px solid $c-gray-light; - width: 100%; - padding: 0px 18px; - } - } - - &--boxed { - border: 1px solid $c-gray-light; - input{ - margin: .75rem; - width: calc(100% - 1.5rem); - } - } - - &--disabled { - color: $c-gray; - input{ - background-color: $c-gray-lightest; - color: $c-gray; - } - } -} - -input[type=search]{ - -webkit-appearance: none; - &::-webkit-search-cancel-button { - -webkit-appearance: searchfield-cancel-button; - } -} - -.react-autosuggest{ - &__container { - width: 100%; - position: relative; - } - - &__input--focused{ - outline: none; - } - - &__suggestion{ - cursor: pointer; - &-list{ - list-style-type: none; - } - &--highlighted{ - background-color: $c-gray-lightest; - } - } - - &__suggestions{ - &-container--open{ - display: block; - position: absolute; - left: 0; - width: 100%; - z-index: 2; - max-height: 15.6em; - overflow-y: auto; - box-shadow: 0 0.25rem 0.5rem rgba(1,1,1,0.2); - background: $c-white; - } - } -} diff --git a/react/src/components/atoms/forms/InputTextFuzzy/InputTextFuzzy.stories.js b/react/src/components/atoms/forms/InputTextFuzzy/InputTextFuzzy.stories.js index 92eea945c7..26a9dfd812 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/InputTextFuzzy.stories.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/InputTextFuzzy.stories.js @@ -25,6 +25,7 @@ storiesOf('atoms/forms', module) inputOptions.options.orgSelector.map((option) => option.text), '' ), + renderDefaultSuggestion: boolean('renderDefaultSuggestion', true), fuseOptions: object('fuseOptions', { shouldSort: true, findAllMatches: true, diff --git a/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.knobs.options.js b/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.knobs.options.js deleted file mode 100644 index ba38adee9a..0000000000 --- a/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.knobs.options.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Option definitions for the Input Text Type Aheads's enumerable properties (imported in stories) - */ -export default { - options: { - orgSelector: [ - { text: '', value: '' }, - { text: 'Org Having (Parentheses in the Name)', value: 'org-having-parentheses-in-the-name' }, - { text: "Attorney General's Office", value: 'attorney-general-office' }, - { text: "Governor's Office", value: 'governors-office' }, - { text: 'Bureau of Environmental Health', value: 'bureau-of-environmental-health' }, - { text: 'Department of Conservation & Recreation', value: 'department-of-conservation--recreation' }, - { text: 'Department of Unemployment Assistance', value: 'department-of-unemployment-assistance' }, - { text: '495/MetroWest Suburban Edge Community Commission', value: '495metrowest-suburban-edge-community-commission' }, - { text: 'Administrative Council on Toxics Use Reduction', value: 'administrative-council-on-toxics-use-reduction' }, - { text: 'Advisory Committee to the Administrative Council on Toxics Use Reduction', value: 'advisory-committee-to-the-administrative-council-on-toxics-use-reduction' }, - { text: 'Alcoholic Beverages Control Commission', value: 'alcoholic-beverages-control-commission' }, - { text: 'Appeals Court', value: 'appeals-court' }, - { text: 'Architectural Access Board', value: 'architectural-access-board' }, - { text: 'Berkshire District Attorney Paul J. Caccaviello', value: 'berkshire-district-attorney-paul-j-caccaviello' }, - { text: 'Board of Registration in Dentistry', value: 'board-of-registration-in-dentistry' }, - { text: 'Board of Registration in Medicine', value: 'board-of-registration-in-medicine' } - ], - pressTypes: [ - { text: 'Press Release', value: 'press-release' }, - { text: 'Press Statement', value: 'press-statement' }, - { text: 'News Article', value: 'news-article' }, - { text: 'Blog Post', value: 'blog-poast' }, - { text: 'Speech', value: 'speech' } - ], - typeOfCare: [ - { text: 'Group Child Care', value: 'group-child-care' }, - { text: 'Family Child Care', value: 'family-child-care' }, - { text: 'Center Based Programs', value: 'center-based-programs' } - ] - } -}; diff --git a/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.md b/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.md deleted file mode 100644 index 769b375bec..0000000000 --- a/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.md +++ /dev/null @@ -1,5 +0,0 @@ -#### Description -A typeahead input text field. This atom is only available in Mayflower-React. - -#### 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) \ No newline at end of file diff --git a/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.stories.js b/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.stories.js deleted file mode 100644 index d3c97097f5..0000000000 --- a/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.stories.js +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; - -import { storiesOf } from '@storybook/react'; -import { withKnobs, text, object, select, boolean } from '@storybook/addon-knobs'; -import { action } from '@storybook/addon-actions'; - -import InputTextTypeAhead from './index'; -import inputOptions from './InputTextTypeAhead.knobs.options'; -import InputTextTypeAheadDocs from './InputTextTypeAhead.md'; - -storiesOf('atoms/forms', module) - .addDecorator(withKnobs({ escapeHTML: false })) - .add( - 'InputTextTypeAhead', (() => { - const props = { - boxed: boolean('boxed', true), - label: text('label', 'State Organization'), - placeholder: text('placeholder', 'All Organizations'), - id: text('id', 'org-typeahead'), - options: object('options', inputOptions.options.orgSelector), - selected: select( - 'selected', - inputOptions.options.orgSelector.map((option) => option.text), - '' - ), - onChange: action('InputTextTypeAhead onChange'), - disabled: boolean('disabled', false), - onKeyDown: action('down') - }; - return(); - }), - { info: InputTextTypeAheadDocs } - ); diff --git a/react/src/components/atoms/forms/InputTextTypeAhead/index.js b/react/src/components/atoms/forms/InputTextTypeAhead/index.js deleted file mode 100644 index 9b05578e88..0000000000 --- a/react/src/components/atoms/forms/InputTextTypeAhead/index.js +++ /dev/null @@ -1,175 +0,0 @@ -import React, { Component } from 'react'; -import Autosuggest from 'react-autosuggest'; -import parse from 'autosuggest-highlight/parse'; -import match from 'autosuggest-highlight/match'; -import PropTypes from 'prop-types'; -import classNames from 'classnames'; -import './style.css'; - -class InputTextTypeAhead extends Component { - constructor(props) { - super(props); - this.state = { - value: (props.clearInputTextTypeAheadSelected || !props.selected) ? '' : props.selected, - suggestions: [] - }; - this.selectTag = ''; - this.onChange = this.onChange.bind(this); - this.onBlur = this.onBlur.bind(this); - this.onSuggestionsFetchRequested = this.onSuggestionsFetchRequested.bind(this); - this.onSuggestionsClearRequested = this.onSuggestionsClearRequested.bind(this); - this.onSuggestionSelected = this.onSuggestionSelected.bind(this); - this.getSuggestions = this.getSuggestions.bind(this); - this.onKeyDown = this.onKeyDown.bind(this); - } - componentWillReceiveProps(nextProps) { - this.setState({ value: nextProps.selected }); - this.selectTag.selectedIndex = nextProps.options.findIndex((option) => option.text === nextProps.selected); - } - onKeyDown(event) { - if (typeof this.props.onKeyDown === 'function') { - this.props.onKeyDown(event); - } - } - onChange(event, { newValue }) { - this.setState({ - value: newValue - }); - if (newValue.length === 0 && (typeof this.props.onChange === 'function')) { - // Change the filter back to "" if the user clears the typeahead input. - const suggestion = { text: '', value: '' }; - this.props.onChange(event, { suggestion }); - } - } - onBlur(event) { - if (typeof this.props.onBlur === 'function') { - this.props.onBlur(event); - } - } - onSuggestionsFetchRequested({ value }) { - this.setState({ - suggestions: this.getSuggestions(value) - }); - } - onSuggestionsClearRequested() { - this.setState({ - suggestions: [] - }); - } - onSuggestionSelected(event, { suggestion }) { - // invokes custom function if passed in the component - if (typeof this.props.onChange === 'function') { - this.props.onChange(event, { suggestion }); - } - } - getSuggestions(value) { - const escapeRegexCharacters = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); - const escapedValue = escapeRegexCharacters(value.trim()); - const regex = new RegExp(`${escapedValue}`, 'i'); - const { options } = this.props; - if (escapedValue === '') { - return options; - } - return options.filter((item) => regex.test(item.text)); - } - - render() { - const { suggestions } = this.state; - const { - boxed, id, label, placeholder, autoFocusInput, disabled - } = this.props; - const value = JSON.parse(JSON.stringify(this.state.value)); - const inputProps = { - value, - onKeyDown: this.onKeyDown, - onChange: this.onChange, - onBlur: this.onBlur, - type: 'search', - autoFocus: autoFocusInput, - placeholder, - disabled - }; - const shouldRenderSuggestions = (x) => x.trim().length >= 0; - const getSuggestionValue = (suggestion) => suggestion.text; - const renderSuggestion = (suggestion, { query }) => { - const suggestionText = `${suggestion.text}`; - const matches = match(suggestionText, query); - const parts = parse(suggestionText, matches); - return( - - - { - parts.map((part, index) => { - const className = part.highlight ? 'highlight' : null; - const key = `suggestion_${index}`; - return( - {part.text} - ); - }) - } - - - ); - }; - const inputTextTypeAheadClasses = classNames({ - 'ma__input-typeahead': true, - 'ma__input-typeahead--boxed': boxed, - 'ma__input-typeahead--disabled': disabled - }); - return( - - {label && ()} -
- { this.selectTag = select; }} - /> -
-
- ); - } -} - -InputTextTypeAhead.propTypes = { - /** Style the input with a box outline */ - boxed: PropTypes.bool, - /** The label text above the input text box */ - label: PropTypes.string, - /** The placeholder text to appear in the input text box */ - placeholder: PropTypes.string.isRequired, - /** The id of the typeahead element */ - id: PropTypes.string.isRequired, - /** An array of options for the typeahead */ - options: PropTypes.arrayOf(PropTypes.shape({ - value: PropTypes.string.isRequired, - text: PropTypes.string.isRequired - })), - /** Custom keydown callback */ - onKeyDown: PropTypes.func, - /** Custom change function */ - onChange: PropTypes.func, - /** Custom blur handler function */ - onBlur: PropTypes.func, - /** The default value for the select box */ - selected: PropTypes.string, - /** Focus on typeahead input */ - autoFocusInput: PropTypes.bool, - clearInputTextTypeAheadSelected: PropTypes.bool, - disabled: PropTypes.bool -}; - -InputTextTypeAhead.defaultProps = { - autoFocusInput: false, - clearInputTextTypeAheadSelected: false, - disabled: false -}; - -export default InputTextTypeAhead; diff --git a/react/src/components/atoms/forms/InputTextTypeAhead/style.scss b/react/src/components/atoms/forms/InputTextTypeAhead/style.scss deleted file mode 100644 index 22ef664b44..0000000000 --- a/react/src/components/atoms/forms/InputTextTypeAhead/style.scss +++ /dev/null @@ -1,2 +0,0 @@ -@import 'global'; -@import '01-atoms/input-typeahead'; \ No newline at end of file diff --git a/react/src/index.js b/react/src/index.js index f5e997abee..d67604a07e 100644 --- a/react/src/index.js +++ b/react/src/index.js @@ -23,7 +23,6 @@ export InputDate from './components/atoms/forms/InputDate'; export InputText from './components/atoms/forms/InputText'; export SelectBox from './components/atoms/forms/SelectBox'; export InputRadio from './components/atoms/forms/InputRadio'; -export InputTextTypeAhead from './components/atoms/forms/InputTextTypeAhead'; export InputTextFuzzy from './components/atoms/forms/InputTextFuzzy'; export Input from './components/atoms/forms/Input'; export Error from './components/atoms/forms/Input/error'; From 0e2ab8cf97e301c3644023df1aa65c5b3b61de02 Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Mon, 29 Apr 2019 11:56:48 -0400 Subject: [PATCH 12/22] add changelog --- changelogs/DP-13688.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 changelogs/DP-13688.md diff --git a/changelogs/DP-13688.md b/changelogs/DP-13688.md new file mode 100644 index 0000000000..2390e850fb --- /dev/null +++ b/changelogs/DP-13688.md @@ -0,0 +1,7 @@ +Minor +Added +- (React) [InputTextFuzzy] DP-13688: Added option to render all options as suggestions by default, via prop `renderDefaultSuggestion` +- (React) [Storybook Config] DP-13688: Added storybook console addon + +Removed +- (React) [InputTextTypeAhead] DP-13688: Removed InputTextTypeAhead component (can be fully replaced by InputTextFuzzy) From cc1a3d44180da336437c0d48fa1342829aa79f13 Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Mon, 29 Apr 2019 11:57:14 -0400 Subject: [PATCH 13/22] add changelog --- changelogs/DP-13688.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/changelogs/DP-13688.md b/changelogs/DP-13688.md index 2390e850fb..fea335a82a 100644 --- a/changelogs/DP-13688.md +++ b/changelogs/DP-13688.md @@ -1,7 +1,7 @@ Minor Added -- (React) [InputTextFuzzy] DP-13688: Added option to render all options as suggestions by default, via prop `renderDefaultSuggestion` -- (React) [Storybook Config] DP-13688: Added storybook console addon +- (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: Removed InputTextTypeAhead component (can be fully replaced by InputTextFuzzy) +- (React) [InputTextTypeAhead] DP-13688: Removed InputTextTypeAhead component (can be fully replaced by InputTextFuzzy) #544 From 3740f2528ddb22b9c77dab2cb3126efcb9563891 Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Mon, 29 Apr 2019 12:23:36 -0400 Subject: [PATCH 14/22] Revert "remove inputTextTypeAhead" This reverts commit 0182463fc70b624a90ffbdcc1a2382d6ef72ef08. --- assets/scss/01-atoms/_input-typeahead.scss | 85 +++++++++ .../InputTextFuzzy/InputTextFuzzy.stories.js | 1 - .../InputTextTypeAhead.knobs.options.js | 37 ++++ .../InputTextTypeAhead/InputTextTypeAhead.md | 5 + .../InputTextTypeAhead.stories.js | 33 ++++ .../atoms/forms/InputTextTypeAhead/index.js | 175 ++++++++++++++++++ .../atoms/forms/InputTextTypeAhead/style.scss | 2 + react/src/index.js | 1 + 8 files changed, 338 insertions(+), 1 deletion(-) create mode 100644 assets/scss/01-atoms/_input-typeahead.scss create mode 100644 react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.knobs.options.js create mode 100644 react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.md create mode 100644 react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.stories.js create mode 100644 react/src/components/atoms/forms/InputTextTypeAhead/index.js create mode 100644 react/src/components/atoms/forms/InputTextTypeAhead/style.scss diff --git a/assets/scss/01-atoms/_input-typeahead.scss b/assets/scss/01-atoms/_input-typeahead.scss new file mode 100644 index 0000000000..fda60ff7f4 --- /dev/null +++ b/assets/scss/01-atoms/_input-typeahead.scss @@ -0,0 +1,85 @@ +.ma__input-typeahead { + font-size: 1.25rem; + + .highlight { + color: $c-primary-alt; + font-weight: bold; + } + + input { + width: 100%; + -webkit-appearance: none; + &::-ms-clear { + display: none; + } + } + + ul { + width: 100%; + margin: 0px; + padding: 0px; + li { + border: 1px solid $c-gray-light; + width: 100%; + padding: 0px 18px; + } + } + + &--boxed { + border: 1px solid $c-gray-light; + input{ + margin: .75rem; + width: calc(100% - 1.5rem); + } + } + + &--disabled { + color: $c-gray; + input{ + background-color: $c-gray-lightest; + color: $c-gray; + } + } +} + +input[type=search]{ + -webkit-appearance: none; + &::-webkit-search-cancel-button { + -webkit-appearance: searchfield-cancel-button; + } +} + +.react-autosuggest{ + &__container { + width: 100%; + position: relative; + } + + &__input--focused{ + outline: none; + } + + &__suggestion{ + cursor: pointer; + &-list{ + list-style-type: none; + } + &--highlighted{ + background-color: $c-gray-lightest; + } + } + + &__suggestions{ + &-container--open{ + display: block; + position: absolute; + left: 0; + width: 100%; + z-index: 2; + max-height: 15.6em; + overflow-y: auto; + box-shadow: 0 0.25rem 0.5rem rgba(1,1,1,0.2); + background: $c-white; + } + } +} diff --git a/react/src/components/atoms/forms/InputTextFuzzy/InputTextFuzzy.stories.js b/react/src/components/atoms/forms/InputTextFuzzy/InputTextFuzzy.stories.js index 26a9dfd812..92eea945c7 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/InputTextFuzzy.stories.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/InputTextFuzzy.stories.js @@ -25,7 +25,6 @@ storiesOf('atoms/forms', module) inputOptions.options.orgSelector.map((option) => option.text), '' ), - renderDefaultSuggestion: boolean('renderDefaultSuggestion', true), fuseOptions: object('fuseOptions', { shouldSort: true, findAllMatches: true, diff --git a/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.knobs.options.js b/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.knobs.options.js new file mode 100644 index 0000000000..ba38adee9a --- /dev/null +++ b/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.knobs.options.js @@ -0,0 +1,37 @@ +/** + * Option definitions for the Input Text Type Aheads's enumerable properties (imported in stories) + */ +export default { + options: { + orgSelector: [ + { text: '', value: '' }, + { text: 'Org Having (Parentheses in the Name)', value: 'org-having-parentheses-in-the-name' }, + { text: "Attorney General's Office", value: 'attorney-general-office' }, + { text: "Governor's Office", value: 'governors-office' }, + { text: 'Bureau of Environmental Health', value: 'bureau-of-environmental-health' }, + { text: 'Department of Conservation & Recreation', value: 'department-of-conservation--recreation' }, + { text: 'Department of Unemployment Assistance', value: 'department-of-unemployment-assistance' }, + { text: '495/MetroWest Suburban Edge Community Commission', value: '495metrowest-suburban-edge-community-commission' }, + { text: 'Administrative Council on Toxics Use Reduction', value: 'administrative-council-on-toxics-use-reduction' }, + { text: 'Advisory Committee to the Administrative Council on Toxics Use Reduction', value: 'advisory-committee-to-the-administrative-council-on-toxics-use-reduction' }, + { text: 'Alcoholic Beverages Control Commission', value: 'alcoholic-beverages-control-commission' }, + { text: 'Appeals Court', value: 'appeals-court' }, + { text: 'Architectural Access Board', value: 'architectural-access-board' }, + { text: 'Berkshire District Attorney Paul J. Caccaviello', value: 'berkshire-district-attorney-paul-j-caccaviello' }, + { text: 'Board of Registration in Dentistry', value: 'board-of-registration-in-dentistry' }, + { text: 'Board of Registration in Medicine', value: 'board-of-registration-in-medicine' } + ], + pressTypes: [ + { text: 'Press Release', value: 'press-release' }, + { text: 'Press Statement', value: 'press-statement' }, + { text: 'News Article', value: 'news-article' }, + { text: 'Blog Post', value: 'blog-poast' }, + { text: 'Speech', value: 'speech' } + ], + typeOfCare: [ + { text: 'Group Child Care', value: 'group-child-care' }, + { text: 'Family Child Care', value: 'family-child-care' }, + { text: 'Center Based Programs', value: 'center-based-programs' } + ] + } +}; diff --git a/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.md b/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.md new file mode 100644 index 0000000000..769b375bec --- /dev/null +++ b/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.md @@ -0,0 +1,5 @@ +#### Description +A typeahead input text field. This atom is only available in Mayflower-React. + +#### 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) \ No newline at end of file diff --git a/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.stories.js b/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.stories.js new file mode 100644 index 0000000000..d3c97097f5 --- /dev/null +++ b/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.stories.js @@ -0,0 +1,33 @@ +import React from 'react'; + +import { storiesOf } from '@storybook/react'; +import { withKnobs, text, object, select, boolean } from '@storybook/addon-knobs'; +import { action } from '@storybook/addon-actions'; + +import InputTextTypeAhead from './index'; +import inputOptions from './InputTextTypeAhead.knobs.options'; +import InputTextTypeAheadDocs from './InputTextTypeAhead.md'; + +storiesOf('atoms/forms', module) + .addDecorator(withKnobs({ escapeHTML: false })) + .add( + 'InputTextTypeAhead', (() => { + const props = { + boxed: boolean('boxed', true), + label: text('label', 'State Organization'), + placeholder: text('placeholder', 'All Organizations'), + id: text('id', 'org-typeahead'), + options: object('options', inputOptions.options.orgSelector), + selected: select( + 'selected', + inputOptions.options.orgSelector.map((option) => option.text), + '' + ), + onChange: action('InputTextTypeAhead onChange'), + disabled: boolean('disabled', false), + onKeyDown: action('down') + }; + return(); + }), + { info: InputTextTypeAheadDocs } + ); diff --git a/react/src/components/atoms/forms/InputTextTypeAhead/index.js b/react/src/components/atoms/forms/InputTextTypeAhead/index.js new file mode 100644 index 0000000000..9b05578e88 --- /dev/null +++ b/react/src/components/atoms/forms/InputTextTypeAhead/index.js @@ -0,0 +1,175 @@ +import React, { Component } from 'react'; +import Autosuggest from 'react-autosuggest'; +import parse from 'autosuggest-highlight/parse'; +import match from 'autosuggest-highlight/match'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; +import './style.css'; + +class InputTextTypeAhead extends Component { + constructor(props) { + super(props); + this.state = { + value: (props.clearInputTextTypeAheadSelected || !props.selected) ? '' : props.selected, + suggestions: [] + }; + this.selectTag = ''; + this.onChange = this.onChange.bind(this); + this.onBlur = this.onBlur.bind(this); + this.onSuggestionsFetchRequested = this.onSuggestionsFetchRequested.bind(this); + this.onSuggestionsClearRequested = this.onSuggestionsClearRequested.bind(this); + this.onSuggestionSelected = this.onSuggestionSelected.bind(this); + this.getSuggestions = this.getSuggestions.bind(this); + this.onKeyDown = this.onKeyDown.bind(this); + } + componentWillReceiveProps(nextProps) { + this.setState({ value: nextProps.selected }); + this.selectTag.selectedIndex = nextProps.options.findIndex((option) => option.text === nextProps.selected); + } + onKeyDown(event) { + if (typeof this.props.onKeyDown === 'function') { + this.props.onKeyDown(event); + } + } + onChange(event, { newValue }) { + this.setState({ + value: newValue + }); + if (newValue.length === 0 && (typeof this.props.onChange === 'function')) { + // Change the filter back to "" if the user clears the typeahead input. + const suggestion = { text: '', value: '' }; + this.props.onChange(event, { suggestion }); + } + } + onBlur(event) { + if (typeof this.props.onBlur === 'function') { + this.props.onBlur(event); + } + } + onSuggestionsFetchRequested({ value }) { + this.setState({ + suggestions: this.getSuggestions(value) + }); + } + onSuggestionsClearRequested() { + this.setState({ + suggestions: [] + }); + } + onSuggestionSelected(event, { suggestion }) { + // invokes custom function if passed in the component + if (typeof this.props.onChange === 'function') { + this.props.onChange(event, { suggestion }); + } + } + getSuggestions(value) { + const escapeRegexCharacters = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const escapedValue = escapeRegexCharacters(value.trim()); + const regex = new RegExp(`${escapedValue}`, 'i'); + const { options } = this.props; + if (escapedValue === '') { + return options; + } + return options.filter((item) => regex.test(item.text)); + } + + render() { + const { suggestions } = this.state; + const { + boxed, id, label, placeholder, autoFocusInput, disabled + } = this.props; + const value = JSON.parse(JSON.stringify(this.state.value)); + const inputProps = { + value, + onKeyDown: this.onKeyDown, + onChange: this.onChange, + onBlur: this.onBlur, + type: 'search', + autoFocus: autoFocusInput, + placeholder, + disabled + }; + const shouldRenderSuggestions = (x) => x.trim().length >= 0; + const getSuggestionValue = (suggestion) => suggestion.text; + const renderSuggestion = (suggestion, { query }) => { + const suggestionText = `${suggestion.text}`; + const matches = match(suggestionText, query); + const parts = parse(suggestionText, matches); + return( + + + { + parts.map((part, index) => { + const className = part.highlight ? 'highlight' : null; + const key = `suggestion_${index}`; + return( + {part.text} + ); + }) + } + + + ); + }; + const inputTextTypeAheadClasses = classNames({ + 'ma__input-typeahead': true, + 'ma__input-typeahead--boxed': boxed, + 'ma__input-typeahead--disabled': disabled + }); + return( + + {label && ()} +
+ { this.selectTag = select; }} + /> +
+
+ ); + } +} + +InputTextTypeAhead.propTypes = { + /** Style the input with a box outline */ + boxed: PropTypes.bool, + /** The label text above the input text box */ + label: PropTypes.string, + /** The placeholder text to appear in the input text box */ + placeholder: PropTypes.string.isRequired, + /** The id of the typeahead element */ + id: PropTypes.string.isRequired, + /** An array of options for the typeahead */ + options: PropTypes.arrayOf(PropTypes.shape({ + value: PropTypes.string.isRequired, + text: PropTypes.string.isRequired + })), + /** Custom keydown callback */ + onKeyDown: PropTypes.func, + /** Custom change function */ + onChange: PropTypes.func, + /** Custom blur handler function */ + onBlur: PropTypes.func, + /** The default value for the select box */ + selected: PropTypes.string, + /** Focus on typeahead input */ + autoFocusInput: PropTypes.bool, + clearInputTextTypeAheadSelected: PropTypes.bool, + disabled: PropTypes.bool +}; + +InputTextTypeAhead.defaultProps = { + autoFocusInput: false, + clearInputTextTypeAheadSelected: false, + disabled: false +}; + +export default InputTextTypeAhead; diff --git a/react/src/components/atoms/forms/InputTextTypeAhead/style.scss b/react/src/components/atoms/forms/InputTextTypeAhead/style.scss new file mode 100644 index 0000000000..22ef664b44 --- /dev/null +++ b/react/src/components/atoms/forms/InputTextTypeAhead/style.scss @@ -0,0 +1,2 @@ +@import 'global'; +@import '01-atoms/input-typeahead'; \ No newline at end of file diff --git a/react/src/index.js b/react/src/index.js index d67604a07e..f5e997abee 100644 --- a/react/src/index.js +++ b/react/src/index.js @@ -23,6 +23,7 @@ export InputDate from './components/atoms/forms/InputDate'; export InputText from './components/atoms/forms/InputText'; export SelectBox from './components/atoms/forms/SelectBox'; export InputRadio from './components/atoms/forms/InputRadio'; +export InputTextTypeAhead from './components/atoms/forms/InputTextTypeAhead'; export InputTextFuzzy from './components/atoms/forms/InputTextFuzzy'; export Input from './components/atoms/forms/Input'; export Error from './components/atoms/forms/Input/error'; From d08f4505454763fdc2c195a4f20e14474b60b6ec Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Mon, 29 Apr 2019 12:57:30 -0400 Subject: [PATCH 15/22] add deprecation note --- changelogs/DP-13688.md | 2 +- .../atoms/forms/InputTextTypeAhead/InputTextTypeAhead.md | 6 +++++- .../src/components/atoms/forms/InputTextTypeAhead/index.js | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/changelogs/DP-13688.md b/changelogs/DP-13688.md index fea335a82a..29d9fd65a8 100644 --- a/changelogs/DP-13688.md +++ b/changelogs/DP-13688.md @@ -4,4 +4,4 @@ Added - (React) [Storybook Config] DP-13688: Added storybook console addon #544 Removed -- (React) [InputTextTypeAhead] DP-13688: Removed InputTextTypeAhead component (can be fully replaced by InputTextFuzzy) #544 +- (React) [InputTextTypeAhead] DP-13688: Deprecate InputTextTypeAhead. diff --git a/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.md b/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.md index 769b375bec..b931d4b5cf 100644 --- a/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.md +++ b/react/src/components/atoms/forms/InputTextTypeAhead/InputTextTypeAhead.md @@ -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) \ No newline at end of file +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) diff --git a/react/src/components/atoms/forms/InputTextTypeAhead/index.js b/react/src/components/atoms/forms/InputTextTypeAhead/index.js index 9b05578e88..05d5757153 100644 --- a/react/src/components/atoms/forms/InputTextTypeAhead/index.js +++ b/react/src/components/atoms/forms/InputTextTypeAhead/index.js @@ -21,6 +21,7 @@ class InputTextTypeAhead extends Component { this.onSuggestionSelected = this.onSuggestionSelected.bind(this); this.getSuggestions = this.getSuggestions.bind(this); this.onKeyDown = this.onKeyDown.bind(this); + console.warn('This component is deprecated and will be archived in v10. Use InputTextFuzzy instead.'); } componentWillReceiveProps(nextProps) { this.setState({ value: nextProps.selected }); From 746a882c9007cba3cefccf79849447dce22ccf61 Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Mon, 29 Apr 2019 13:05:26 -0400 Subject: [PATCH 16/22] check for env variable for warning --- react/src/components/atoms/forms/InputTextTypeAhead/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/react/src/components/atoms/forms/InputTextTypeAhead/index.js b/react/src/components/atoms/forms/InputTextTypeAhead/index.js index 05d5757153..b5d0cd1b43 100644 --- a/react/src/components/atoms/forms/InputTextTypeAhead/index.js +++ b/react/src/components/atoms/forms/InputTextTypeAhead/index.js @@ -21,7 +21,9 @@ class InputTextTypeAhead extends Component { this.onSuggestionSelected = this.onSuggestionSelected.bind(this); this.getSuggestions = this.getSuggestions.bind(this); this.onKeyDown = this.onKeyDown.bind(this); - console.warn('This component is deprecated and will be archived in v10. Use InputTextFuzzy instead.'); + 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 }); From 14ee1716fdaab02260b84246b35dd3638576f10f Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Mon, 29 Apr 2019 16:20:39 -0400 Subject: [PATCH 17/22] show default suggestions on clear --- .../atoms/forms/InputTextFuzzy/index.js | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/react/src/components/atoms/forms/InputTextFuzzy/index.js b/react/src/components/atoms/forms/InputTextFuzzy/index.js index 963cf7e600..b3e89520ef 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/index.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/index.js @@ -42,14 +42,25 @@ class InputTextFuzzy extends React.Component { return suggestions; } handleChange = (e) => { - const suggestions = this.fuse.search(e.target.value); - this.setState({ - value: e.target.value, - suggestions - }); + const { value } = e.target; if (is.fn(this.props.onChange)) { this.props.onChange(e); } + if (is.empty(value)) { + if (this.props.renderDefaultSuggestion) { + const suggestions = this.optionsToSuggestions(this.props.options); + this.setState({ + suggestions, + value: '' + }); + } + } else { + const suggestions = this.fuse.search(value); + this.setState({ + value, + suggestions + }); + } }; handleFocus = () => { if (this.props.renderDefaultSuggestion) { From 3a84290380e43fcd59c014889f30bfbdef797e94 Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Mon, 29 Apr 2019 17:08:40 -0400 Subject: [PATCH 18/22] pass value to onchange callback --- react/src/components/atoms/forms/InputTextFuzzy/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react/src/components/atoms/forms/InputTextFuzzy/index.js b/react/src/components/atoms/forms/InputTextFuzzy/index.js index b3e89520ef..0207a6f5ee 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/index.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/index.js @@ -44,7 +44,7 @@ class InputTextFuzzy extends React.Component { handleChange = (e) => { const { value } = e.target; if (is.fn(this.props.onChange)) { - this.props.onChange(e); + this.props.onChange(e, { value }); } if (is.empty(value)) { if (this.props.renderDefaultSuggestion) { From 104084bf580aac65829f2d580065ba3159128356 Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Tue, 30 Apr 2019 16:12:40 -0400 Subject: [PATCH 19/22] Updates InputTextFuzzy component logic using setState, fixes onChange to actually pass useful information. --- .../atoms/forms/InputTextFuzzy/index.js | 44 +++++++++++-------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/react/src/components/atoms/forms/InputTextFuzzy/index.js b/react/src/components/atoms/forms/InputTextFuzzy/index.js index 8f50280aea..3fc721e0a4 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/index.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/index.js @@ -21,14 +21,16 @@ class InputTextFuzzy extends React.Component { this.fuse = new Fuse(this.props.options, fuseOptions); } handleChange = (e) => { + e.persist(); const suggestions = this.fuse.search(e.target.value); this.setState({ value: e.target.value, suggestions + }, () => { + if (typeof this.props.onChange === 'function') { + this.props.onChange({ event: e, value: e.target.value, suggestions }); + } }); - if (typeof this.props.onChange === 'function') { - this.props.onChange(e); - } }; renderItem = (suggestion) => ( @@ -73,6 +75,7 @@ class InputTextFuzzy extends React.Component { switch (event.key) { case 'ArrowDown': case 'ArrowUp': + event.persist(); event.preventDefault(); this.setState((currentState) => { if (currentState.suggestions.length > 0 && currentState.value && currentState.value.length > 0) { @@ -83,6 +86,7 @@ class InputTextFuzzy extends React.Component { }); break; case 'Enter': + event.persist(); // If there are suggestions and the user chose one. if (this.state.suggestions.length > 0 && this.state.highlightedItemIndex !== null && this.state.highlightedItemIndex > -1) { const suggestion = this.state.suggestions[this.state.highlightedItemIndex]; @@ -90,11 +94,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) => { @@ -110,14 +115,15 @@ class InputTextFuzzy extends React.Component { this.setState({ suggestions: [], highlightedItemIndex: null + }, () => { + if (is.fn(this.props.onSuggestionClick)) { + this.props.onSuggestionClick(event, { + suggestion: { + item: { text: this.state.value } + } + }); + } }); - if (is.fn(this.props.onSuggestionClick)) { - this.props.onSuggestionClick(event, { - suggestion: { - item: { text: this.state.value } - } - }); - } } } break; @@ -143,15 +149,17 @@ 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) => { this.setState({ From 3b7dedff3f7020657b62b1daf55ba366637ee59c Mon Sep 17 00:00:00 2001 From: Steven Murray Date: Wed, 1 May 2019 10:01:40 -0400 Subject: [PATCH 20/22] Bug Fixes. --- .../atoms/forms/InputTextFuzzy/index.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/react/src/components/atoms/forms/InputTextFuzzy/index.js b/react/src/components/atoms/forms/InputTextFuzzy/index.js index db79e3bbf2..63656d0288 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/index.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/index.js @@ -20,12 +20,12 @@ class InputTextFuzzy extends React.Component { fuseOptions.keys = this.props.keys; this.fuse = new Fuse(this.props.options, fuseOptions); } - clearSuggestions = (event) => { + clearSuggestions = (event = null) => { this.setState({ suggestions: [], highlightedItemIndex: null }, () => { - if (is.fn(this.props.onSuggestionClick)) { + if (event && is.fn(this.props.onSuggestionClick)) { this.props.onSuggestionClick(event, { suggestion: { item: { text: this.state.value } @@ -63,10 +63,9 @@ class InputTextFuzzy extends React.Component { this.props.onChange({ event: e, value, suggestions }); } }); - } else { - if (typeof this.props.onChange === 'function') { - this.props.onChange({ event: e, value, suggestions }); - } + } else if (typeof this.props.onChange === 'function') { + const suggestions = this.fuse.search(value); + this.props.onChange({ event: e, value, suggestions }); } } else { const suggestions = this.fuse.search(value); @@ -124,9 +123,8 @@ class InputTextFuzzy extends React.Component { disabled: this.props.disabled, id: this.props.inputId, onFocus: this.handleFocus, - onBlur: (event) => { - event.persist(); - this.clearSuggestions(event); + onBlur: () => { + this.clearSuggestions(); }, onKeyDown: (event, { newHighlightedItemIndex }) => { event.persist(); From 9b87a979c26764d277b6b825a97ff7193bcb4b5c Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Wed, 1 May 2019 11:08:58 -0400 Subject: [PATCH 21/22] update is and add onChange --- .../forms/InputTextFuzzy/InputTextFuzzy.stories.js | 3 ++- .../src/components/atoms/forms/InputTextFuzzy/index.js | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/react/src/components/atoms/forms/InputTextFuzzy/InputTextFuzzy.stories.js b/react/src/components/atoms/forms/InputTextFuzzy/InputTextFuzzy.stories.js index 92eea945c7..78602762d6 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/InputTextFuzzy.stories.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/InputTextFuzzy.stories.js @@ -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(); }), diff --git a/react/src/components/atoms/forms/InputTextFuzzy/index.js b/react/src/components/atoms/forms/InputTextFuzzy/index.js index 63656d0288..cbdb0bab43 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/index.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/index.js @@ -53,17 +53,17 @@ class InputTextFuzzy extends React.Component { e.persist(); const { value } = e.target; if (is.empty(value)) { + const suggestions = this.optionsToSuggestions(this.props.options); if (this.props.renderDefaultSuggestion) { - const suggestions = this.optionsToSuggestions(this.props.options); this.setState({ suggestions, value: '' }, () => { - if (typeof this.props.onChange === 'function') { + if (is.fn(this.props.onChange)) { this.props.onChange({ event: e, value, suggestions }); } }); - } else if (typeof this.props.onChange === 'function') { + } else if (is.fn(this.props.onChange)) { const suggestions = this.fuse.search(value); this.props.onChange({ event: e, value, suggestions }); } @@ -72,6 +72,10 @@ class InputTextFuzzy extends React.Component { this.setState({ value, suggestions + }, () => { + if (is.fn(this.props.onChange)) { + this.props.onChange({ event: e, value, suggestions }); + } }); } }; From aaa46705c040cb826aa07a236d271517b1d956af Mon Sep 17 00:00:00 2001 From: Minghua Sun Date: Wed, 1 May 2019 11:11:43 -0400 Subject: [PATCH 22/22] remove search on empty query --- react/src/components/atoms/forms/InputTextFuzzy/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/react/src/components/atoms/forms/InputTextFuzzy/index.js b/react/src/components/atoms/forms/InputTextFuzzy/index.js index cbdb0bab43..fe1f8d2006 100644 --- a/react/src/components/atoms/forms/InputTextFuzzy/index.js +++ b/react/src/components/atoms/forms/InputTextFuzzy/index.js @@ -64,7 +64,6 @@ class InputTextFuzzy extends React.Component { } }); } else if (is.fn(this.props.onChange)) { - const suggestions = this.fuse.search(value); this.props.onChange({ event: e, value, suggestions }); } } else {