From 5182e6f22c9a85fef9ac3b0b6e1dc07a07aedc2a Mon Sep 17 00:00:00 2001 From: Austin Sullivan Date: Tue, 11 Jan 2022 15:15:38 -0500 Subject: [PATCH 1/5] fix(TextInputGroup): address various issues on auto complete search: undoes default tab behavior prevention undoes input clearing on escape when focused on menu adds input clearing on tab when focused on menu adds placeholder text and custom aria label clarifies reasoning for conditionally rendered search icon on text input group main: sets falsy input values as an empty string exposes value and placeholder props --- .../TextInputGroup/TextInputGroupMain.tsx | 8 +++++++- .../TextInputGroup/AttributeValueFiltering.tsx | 2 +- .../TextInputGroup/AutoCompleteSearch.tsx | 16 ++++++++++------ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/packages/react-core/src/components/TextInputGroup/TextInputGroupMain.tsx b/packages/react-core/src/components/TextInputGroup/TextInputGroupMain.tsx index 5f3d5eb341a..620d845698d 100644 --- a/packages/react-core/src/components/TextInputGroup/TextInputGroupMain.tsx +++ b/packages/react-core/src/components/TextInputGroup/TextInputGroupMain.tsx @@ -31,6 +31,10 @@ export interface TextInputGroupMainProps extends Omit void; /** Accessibility label for the input */ 'aria-label'?: string; + /** Value for the input */ + value?: string | number; + /** Placeholder value for the input */ + placeholder?: string; } export const TextInputGroupMain: React.FunctionComponent = ({ @@ -43,6 +47,7 @@ export const TextInputGroupMain: React.FunctionComponent { const { isDisabled } = React.useContext(TextInputGroupContext); @@ -64,7 +69,8 @@ export const TextInputGroupMain: React.FunctionComponent diff --git a/packages/react-core/src/demos/examples/TextInputGroup/AttributeValueFiltering.tsx b/packages/react-core/src/demos/examples/TextInputGroup/AttributeValueFiltering.tsx index b2b2cc053ff..2f67156db8f 100644 --- a/packages/react-core/src/demos/examples/TextInputGroup/AttributeValueFiltering.tsx +++ b/packages/react-core/src/demos/examples/TextInputGroup/AttributeValueFiltering.tsx @@ -205,7 +205,7 @@ export const AttributeValueFiltering: React.FunctionComponent = () => { } }; - /** only show the search icon when no chips are selected */ + /** show the search icon only when there are no chips to prevent the chips from being displayed behind the icon */ const showSearchIcon = !currentChips.length; /** only show the clear button when there is something that can be cleared */ diff --git a/packages/react-core/src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx b/packages/react-core/src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx index 475e29b5a30..3e08ab46876 100644 --- a/packages/react-core/src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx +++ b/packages/react-core/src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx @@ -92,10 +92,9 @@ export const AutoCompleteSearch: React.FunctionComponent = () => { } }; - const handleTab = (event: React.KeyboardEvent) => { + const handleTab = () => { if (menuItems.length === 3) { setInputValue(menuItems[2].props.children); - event.preventDefault(); } }; @@ -129,7 +128,7 @@ export const AutoCompleteSearch: React.FunctionComponent = () => { handleEscape(); break; case 'Tab': - handleTab(event); + handleTab(); break; case 'ArrowUp': case 'ArrowDown': @@ -167,13 +166,16 @@ export const AutoCompleteSearch: React.FunctionComponent = () => { /** enable keyboard only usage while focused on the menu */ const handleMenuKeyDown = (event: React.KeyboardEvent) => { if (event.key === 'Escape') { - setInputValue(''); focusTextInput(); setMenuIsOpen(false); } + + if (event.key === 'Tab') { + setInputValue(''); + } }; - /** only show the search icon when no chips are selected */ + /** show the search icon only when there are no chips to prevent the chips from being displayed behind the icon */ const showSearchIcon = !currentChips.length; /** only show the clear button when there is something that can be cleared */ @@ -188,6 +190,8 @@ export const AutoCompleteSearch: React.FunctionComponent = () => { onChange={handleInputChange} onFocus={() => setMenuIsOpen(true)} onKeyDown={handleTextInputKeyDown} + placeholder="search" + aria-label="Search input" > {currentChips.map(currentChip => ( @@ -199,7 +203,7 @@ export const AutoCompleteSearch: React.FunctionComponent = () => { {showClearButton && ( - )} From b7b85b55fa8182562d3ba87f485e752db30964b0 Mon Sep 17 00:00:00 2001 From: Austin Sullivan Date: Wed, 12 Jan 2022 16:23:09 -0500 Subject: [PATCH 2/5] updates test snapshots --- .../__tests__/__snapshots__/TextInputGroup.test.tsx.snap | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/react-core/src/components/TextInputGroup/__tests__/__snapshots__/TextInputGroup.test.tsx.snap b/packages/react-core/src/components/TextInputGroup/__tests__/__snapshots__/TextInputGroup.test.tsx.snap index 61eb544a120..1d0e1fefed5 100644 --- a/packages/react-core/src/components/TextInputGroup/__tests__/__snapshots__/TextInputGroup.test.tsx.snap +++ b/packages/react-core/src/components/TextInputGroup/__tests__/__snapshots__/TextInputGroup.test.tsx.snap @@ -22,6 +22,7 @@ exports[`TextInputGroup gets custom class and id 1`] = ` className="pf-c-text-input-group__text-input" onChange={[Function]} type="text" + value="" /> @@ -53,6 +54,7 @@ exports[`TextInputGroup renders content 1`] = ` className="pf-c-text-input-group__text-input" onChange={[Function]} type="text" + value="" /> @@ -87,6 +89,7 @@ exports[`TextInputGroup renders with the proper stying when disabled 1`] = ` disabled={true} onChange={[Function]} type="text" + value="" /> @@ -115,6 +118,7 @@ exports[`TextInputGroupMain renders content 1`] = ` disabled={false} onChange={[Function]} type="text" + value="" /> @@ -172,6 +176,7 @@ exports[`TextInputGroupMain renders given input icon props 1`] = ` disabled={false} onChange={[Function]} type="text" + value="" /> @@ -195,6 +200,7 @@ exports[`TextInputGroupMain renders the input with custom aria label when given disabled={false} onChange={[Function]} type="text" + value="" /> From 89a5f6a811457b517ff5f099140ee653f26592a3 Mon Sep 17 00:00:00 2001 From: Austin Sullivan Date: Thu, 13 Jan 2022 15:49:09 -0500 Subject: [PATCH 3/5] closes menu and focuses input on tab, enter, and space --- .../TextInputGroup/AutoCompleteSearch.tsx | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/react-core/src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx b/packages/react-core/src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx index 3e08ab46876..8400c9b37ab 100644 --- a/packages/react-core/src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx +++ b/packages/react-core/src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx @@ -95,6 +95,8 @@ export const AutoCompleteSearch: React.FunctionComponent = () => { const handleTab = () => { if (menuItems.length === 3) { setInputValue(menuItems[2].props.children); + } else { + setMenuIsOpen(false); } }; @@ -165,13 +167,17 @@ export const AutoCompleteSearch: React.FunctionComponent = () => { /** enable keyboard only usage while focused on the menu */ const handleMenuKeyDown = (event: React.KeyboardEvent) => { - if (event.key === 'Escape') { - focusTextInput(); - setMenuIsOpen(false); - } - - if (event.key === 'Tab') { - setInputValue(''); + switch (event.key) { + case 'Tab': + case 'Escape': + event.preventDefault(); + focusTextInput(); + setMenuIsOpen(false); + break; + case 'Enter': + case ' ': + setTimeout(() => setMenuIsOpen(false), 0); + break; } }; From ecdc2cbde214d07b7fa4884e573978fa865d2349 Mon Sep 17 00:00:00 2001 From: Austin Sullivan Date: Mon, 17 Jan 2022 09:34:30 -0500 Subject: [PATCH 4/5] updates tab to always close the menu --- .../src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/react-core/src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx b/packages/react-core/src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx index 8400c9b37ab..3123e9f60df 100644 --- a/packages/react-core/src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx +++ b/packages/react-core/src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx @@ -95,9 +95,8 @@ export const AutoCompleteSearch: React.FunctionComponent = () => { const handleTab = () => { if (menuItems.length === 3) { setInputValue(menuItems[2].props.children); - } else { - setMenuIsOpen(false); } + setMenuIsOpen(false); }; /** close the menu when escape is hit */ From 0b266d4989be84a98628f314c6008a2787933551 Mon Sep 17 00:00:00 2001 From: Austin Sullivan Date: Tue, 18 Jan 2022 11:14:48 -0500 Subject: [PATCH 5/5] conditionally renders text input group utilities --- .../examples/TextInputGroupFilters.tsx | 19 ++++++++++++------- .../TextInputGroupUtilitiesAndIcon.tsx | 19 ++++++++++++------- .../AttributeValueFiltering.tsx | 19 ++++++++++++------- .../TextInputGroup/AutoCompleteSearch.tsx | 19 ++++++++++++------- 4 files changed, 48 insertions(+), 28 deletions(-) diff --git a/packages/react-core/src/components/TextInputGroup/examples/TextInputGroupFilters.tsx b/packages/react-core/src/components/TextInputGroup/examples/TextInputGroupFilters.tsx index ebc86cd6c28..9e5c40d352a 100644 --- a/packages/react-core/src/components/TextInputGroup/examples/TextInputGroupFilters.tsx +++ b/packages/react-core/src/components/TextInputGroup/examples/TextInputGroupFilters.tsx @@ -40,6 +40,9 @@ export const TextInputGroupFilters: React.FunctionComponent = () => { /** show the input/chip clearing button only when either the text input or chip group are not empty */ const showClearButton = !!inputValue || !!currentChips.length; + /** render the utilities component only when a component it contains is being rendered */ + const showUtilities = showClearButton; + /** callback for clearing all selected chips and the text input */ const clearChipsAndInput = () => { setCurrentChips([]); @@ -57,13 +60,15 @@ export const TextInputGroupFilters: React.FunctionComponent = () => { ))} - - {showClearButton && ( - - )} - + {showUtilities && ( + + {showClearButton && ( + + )} + + )} ); }; diff --git a/packages/react-core/src/components/TextInputGroup/examples/TextInputGroupUtilitiesAndIcon.tsx b/packages/react-core/src/components/TextInputGroup/examples/TextInputGroupUtilitiesAndIcon.tsx index d1266aea05f..828454d50ae 100644 --- a/packages/react-core/src/components/TextInputGroup/examples/TextInputGroupUtilitiesAndIcon.tsx +++ b/packages/react-core/src/components/TextInputGroup/examples/TextInputGroupUtilitiesAndIcon.tsx @@ -14,6 +14,9 @@ export const TextInputGroupUtilitiesAndIcon: React.FunctionComponent = () => { /** show the input clearing button only when the input is not empty */ const showClearButton = !!inputValue; + /** render the utilities component only when a component it contains is being rendered */ + const showUtilities = showClearButton; + /** callback for clearing the text input */ const clearInput = () => { setInputValue(''); @@ -22,13 +25,15 @@ export const TextInputGroupUtilitiesAndIcon: React.FunctionComponent = () => { return ( } value={inputValue} onChange={handleInputChange} /> - - {showClearButton && ( - - )} - + {showUtilities && ( + + {showClearButton && ( + + )} + + )} ); }; diff --git a/packages/react-core/src/demos/examples/TextInputGroup/AttributeValueFiltering.tsx b/packages/react-core/src/demos/examples/TextInputGroup/AttributeValueFiltering.tsx index 2f67156db8f..a5b7457d4cc 100644 --- a/packages/react-core/src/demos/examples/TextInputGroup/AttributeValueFiltering.tsx +++ b/packages/react-core/src/demos/examples/TextInputGroup/AttributeValueFiltering.tsx @@ -211,6 +211,9 @@ export const AttributeValueFiltering: React.FunctionComponent = () => { /** only show the clear button when there is something that can be cleared */ const showClearButton = !!inputValue || !!currentChips.length; + /** render the utilities component only when a component it contains is being rendered */ + const showUtilities = showClearButton; + const inputGroup = (
@@ -229,13 +232,15 @@ export const AttributeValueFiltering: React.FunctionComponent = () => { ))} - - {showClearButton && ( - - )} - + {showUtilities && ( + + {showClearButton && ( + + )} + + )}
); diff --git a/packages/react-core/src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx b/packages/react-core/src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx index 3123e9f60df..089f0426e89 100644 --- a/packages/react-core/src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx +++ b/packages/react-core/src/demos/examples/TextInputGroup/AutoCompleteSearch.tsx @@ -186,6 +186,9 @@ export const AutoCompleteSearch: React.FunctionComponent = () => { /** only show the clear button when there is something that can be cleared */ const showClearButton = !!inputValue || !!currentChips.length; + /** render the utilities component only when a component it contains is being rendered */ + const showUtilities = showClearButton; + const inputGroup = (
@@ -206,13 +209,15 @@ export const AutoCompleteSearch: React.FunctionComponent = () => { ))} - - {showClearButton && ( - - )} - + {showUtilities && ( + + {showClearButton && ( + + )} + + )}
);