From 17f257ff01c1ee5de8b7a99de06d94474555cb35 Mon Sep 17 00:00:00 2001 From: Abhishek Reddy <62020972+AbhishekReddy1127@users.noreply.github.com> Date: Tue, 28 Feb 2023 11:32:27 -0600 Subject: [PATCH] OUI combo box refine (#183) * Added a prop clearOnBlur Signed-off-by: AbhishekReddy1127 * Added example for prop clearOnBlur Signed-off-by: AbhishekReddy1127 --------- Signed-off-by: AbhishekReddy1127 --- src-docs/src/views/combo_box/clear_on_blur.js | 93 +++++++++++++++++++ .../src/views/combo_box/combo_box_example.js | 34 +++++++ src/components/combo_box/combo_box.tsx | 16 +++- 3 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 src-docs/src/views/combo_box/clear_on_blur.js diff --git a/src-docs/src/views/combo_box/clear_on_blur.js b/src-docs/src/views/combo_box/clear_on_blur.js new file mode 100644 index 0000000000..01c3585240 --- /dev/null +++ b/src-docs/src/views/combo_box/clear_on_blur.js @@ -0,0 +1,93 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +import React, { useState } from 'react'; + +import { OuiComboBox } from '../../../../src/components'; + +export default () => { + const [options, updateOptions] = useState([ + { + label: 'Titan', + 'data-test-subj': 'titanOption', + }, + { + label: 'Enceladus is disabled', + }, + { + label: 'Mimas', + }, + { + label: 'Dione', + }, + { + label: 'Iapetus', + }, + { + label: 'Phoebe', + }, + { + label: 'Rhea', + }, + { + label: + "Pandora is one of Saturn's moons, named for a Titaness of Greek mythology", + }, + { + label: 'Tethys', + }, + { + label: 'Hyperion', + }, + ]); + + const [selectedOptions, setSelected] = useState([options[2], options[4]]); + + const onChange = (selectedOptions) => { + setSelected(selectedOptions); + }; + + const onCreateOption = (searchValue, flattenedOptions) => { + const normalizedSearchValue = searchValue.trim().toLowerCase(); + + if (!normalizedSearchValue) { + return; + } + + const newOption = { + label: searchValue, + }; + + // Create the option if it doesn't exist. + if ( + flattenedOptions.findIndex( + (option) => option.label.trim().toLowerCase() === normalizedSearchValue + ) === -1 + ) { + updateOptions([...options, newOption]); + } + + // Select the option. + setSelected((prevSelected) => [...prevSelected, newOption]); + }; + + return ( + + ); +}; diff --git a/src-docs/src/views/combo_box/combo_box_example.js b/src-docs/src/views/combo_box/combo_box_example.js index 3822d11104..4b94785685 100644 --- a/src-docs/src/views/combo_box/combo_box_example.js +++ b/src-docs/src/views/combo_box/combo_box_example.js @@ -39,6 +39,7 @@ const comboBoxSnippet = ``; import Containers from './containers'; @@ -206,6 +207,17 @@ const duplicateOptionsSnippet = `const options = [{ key: 'Label2', }]`; +import ClearOnBlur from './clear_on_blur'; +const clearOnBlurSource = require('!!raw-loader!./clear_on_blur'); +const clearOnBlurSourceOptionsHtml = renderToHtml(ClearOnBlur); +const clearOnBlurSnippet = ``; + export const ComboBoxExample = { title: 'Combo box', intro: ( @@ -600,5 +612,27 @@ export const ComboBoxExample = { demo: , snippet: duplicateOptionsSnippet, }, + { + title: 'Clear on blur', + source: [ + { + type: GuideSectionTypes.JS, + code: clearOnBlurSource, + }, + { + type: GuideSectionTypes.HTML, + code: clearOnBlurSourceOptionsHtml, + }, + ], + text: ( +

+ Set the prop clearOnBlur to make the combo box + input text clear when user focuses out of text box. +

+ ), + props: { OuiComboBox, OuiComboBoxOptionOption }, + snippet: clearOnBlurSnippet, + demo: , + }, ], }; diff --git a/src/components/combo_box/combo_box.tsx b/src/components/combo_box/combo_box.tsx index 0cd51a7eba..fa1de7d014 100644 --- a/src/components/combo_box/combo_box.tsx +++ b/src/components/combo_box/combo_box.tsx @@ -166,6 +166,10 @@ export interface _OuiComboBoxProps * Specifies that the input should have focus when the component loads */ autoFocus?: boolean; + /** + * When `true` clears the input text when user focus out of the input box + */ + clearOnBlur?: boolean; } /** @@ -466,10 +470,20 @@ export class OuiComboBox extends Component< options, selectedOptions, singleSelection, + clearOnBlur, } = this.props; - const { matchingOptions } = this.state; + const { hasFocus, isListOpen } = this.state; + if ( + clearOnBlur && + searchValue && + (hasFocus === false || isListOpen === false) + ) { + this.clearSearchValue(); + return; + } + if (this.doesSearchMatchOnlyOption()) { this.onAddOption(matchingOptions[0], isContainerBlur); return;