Skip to content

feat(SearchInput): new expandable button for masthead variant#7903

Merged
tlabaj merged 13 commits intopatternfly:mainfrom
andyyvo:iss7380
Sep 14, 2022
Merged

feat(SearchInput): new expandable button for masthead variant#7903
tlabaj merged 13 commits intopatternfly:mainfrom
andyyvo:iss7380

Conversation

@andyyvo
Copy link
Copy Markdown
Contributor

@andyyvo andyyvo commented Aug 30, 2022

What: Closes #7380 . Introduced two new props isExpanded and onToggleExpand in SearchInput.tsx. These new props allow the search input component to expand and collapse via a button. This wrapper can be found in the buildSearchTextInputGroupWithExpand and buildSearchTextInputGroupWithExtraButtonsAndExpand functions where the former adds the button to the basic search input and the latter adds the button to the search input with submit button. An example was created that demonstrates the use of a basic search input with the expand toggle button.

Additional issues: Code regarding the advanced search is repeated. Writing it as a function messed up something about the state so it was simply copied twice.

@patternfly-build
Copy link
Copy Markdown
Collaborator

patternfly-build commented Aug 30, 2022

Copy link
Copy Markdown
Contributor

@nicolethoen nicolethoen left a comment

Choose a reason for hiding this comment

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

@mcarrano Should we add a new masthead demo to include this search input feature as past of this issue? Or is there a follow up issue?

Also, @mmenestr or @mcarrano, I feel like it looks a little strange once I start typing in the search input because there are two close buttons next to each other - one for clearing the input and one for collapsing the search. Is that something we considered?


const expandedLabel = () => {
if (isExpanded) {
return 'Close';
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.

These need to be something the consumer can override - consider internationalization where people need to be able to translate their sites into different languages.

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.

Going off of Nicole's comment above, the default value for the "close" button could be more similar to button in the collapsed state, e.g. "Close search".

Though because this is something that can collapse/expand, I'm thinking an alternative would be to omit an aria-label that includes the state (though not getting rid of it entirely), and just use aria-expanded on the button to announce the expanded state.

Going that route would still allow a consumer to pass in an aria-label to this button via a new prop, then aria-expanded can be set based on the isExpanded prop. @nicolethoen wdyt?

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.

+1 about aria-expanded with a separate ariaLabel type prop.

Small nit is that I would prefer this to not be a function (an inline if block should work the same), but either way.

if (!!onSearch || attributes.length > 0 || !!onToggleAdvancedSearch) {
if (attributes.length > 0) {
const AdvancedSearch = (
<span>
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 this code simply repeated from the code around lines 333? If so, we should avoid duplicate code as much as possible.

@mcarrano
Copy link
Copy Markdown
Member

mcarrano commented Sep 1, 2022

@andyyvo @nicolethoen Yes, I think it would be useful to add a demo and no, I didn't already open an issue for that.

Regarding the two close/clear buttons, yes, I do think that was an oversight and we shouldn't have that. We basically want this to work like the search in the masthead on the PatternFly site. There, the field does not have a separate clear, but collapsing the field also clears the field. Could this be made to work that way?

Finally comment/question. I found it a bit confusing that the example starts with the field expanded because it's not obvious how to expand it. Maybe start with the search field hidden?

@nicolethoen
Copy link
Copy Markdown
Contributor

@mcarrano Should collapsing the search input also clear the input? so when it expands again, it's empty?

@mcarrano
Copy link
Copy Markdown
Member

mcarrano commented Sep 1, 2022

@mcarrano Should collapsing the search input also clear the input? so when it expands again, it's empty?

Yes, I think so.

Comment thread packages/react-core/src/components/SearchInput/SearchInput.tsx Outdated
Comment thread packages/react-core/src/components/SearchInput/SearchInput.tsx Outdated
const [searchValue, setSearchValue] = React.useState(value);
const searchInputRef = React.useRef(null);
const searchInputInputRef = innerRef || React.useRef(null);
const [isSearchInputExpanded, setIsSearchInputExpanded] = React.useState(true);
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.

Could we omit this state entirely and base logic elsewhere off of the isExpanded prop? It doesn't seem like it's entirely needed since consumers will have to pass in both the isExpanded and onToggleExpand props to control the expanding functionality.

Copy link
Copy Markdown
Contributor

@kmcfaul kmcfaul Sep 9, 2022

Choose a reason for hiding this comment

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

I think it could be removed. The state could be used to enable uncontrolled expansion, but as is it doesn't appear to work after playing with the example (onToggleExpand is required to turn the input into an expandable variant, and removing isExpanded prevents expansion entirely).

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.

if we are going the support uncontrolled, I would update the comment to mention that.


const expandedLabel = () => {
if (isExpanded) {
return 'Close';
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.

Going off of Nicole's comment above, the default value for the "close" button could be more similar to button in the collapsed state, e.g. "Close search".

Though because this is something that can collapse/expand, I'm thinking an alternative would be to omit an aria-label that includes the state (though not getting rid of it entirely), and just use aria-expanded on the button to announce the expanded state.

Going that route would still allow a consumer to pass in an aria-label to this button via a new prop, then aria-expanded can be set based on the isExpanded prop. @nicolethoen wdyt?


export const SearchInputWithExpandable: React.FunctionComponent = () => {
const [value, setValue] = React.useState('');
const [isExpanded, setIsExpanded] = React.useState(true);
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.

Similar to what @mcarrano said, I'd opt to have this false by default

Comment thread packages/react-core/src/components/SearchInput/SearchInput.tsx Outdated
Copy link
Copy Markdown
Contributor

@mcoker mcoker left a comment

Choose a reason for hiding this comment

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

LGTM! If you're going to add a demo in the masthead, part of the core PR adds a .pf-m-plain variation to the input group that removes the white background for use against a non-white background, otherwise it will look like this:

Screen Shot 2022-09-08 at 5 20 15 PM

Screen Shot 2022-09-08 at 5 20 01 PM

@tlabaj
Copy link
Copy Markdown
Contributor

tlabaj commented Sep 12, 2022

@mcarrano @nicole I opened issue #7968 to add the new demo

@wise-king-sullyman
Copy link
Copy Markdown
Collaborator

I'm buttoning this work up now, as far as the API goes do you all have any thoughts on having separate props for isExpanded, onToggleExpanded, and a new aria label prop for the toggle vs combining all those props into a single object prop? @tlabaj @thatblindgeye @nicolethoen @kmcfaul

@nicolethoen
Copy link
Copy Markdown
Contributor

I like them combined into a single, well documented prop - especially if we expect people to need to use more than one at a time to implement the feature.

@thatblindgeye
Copy link
Copy Markdown
Contributor

Agreed with Nicole's comment. It maaaay also differentiate those props a little more from some other props (aria-label, onToggleAdvancedSearch)

@tlabaj
Copy link
Copy Markdown
Contributor

tlabaj commented Sep 13, 2022

I like the idea of grouping props together that otherwise do not make sense on there own like in this case.

Copy link
Copy Markdown
Contributor

@thatblindgeye thatblindgeye left a comment

Choose a reason for hiding this comment

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

Had a few comments below, two related to the a11y error that'll need an update, and one that's non-blocking/I can create a followup for

value={value}
onChange={onChange}
onClear={() => onChange('')}
expandableProps={{ isExpanded, onToggleExpand }}
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.

This needs the toggleAriaLabel prop passed in.

Comment on lines +217 to +220
const onExpandHandler = (event: React.SyntheticEvent<HTMLButtonElement>) => {
setSearchValue('');
onToggleExpand(isExpanded, event);
};
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.

Not blocking and more of a followup issue since it'll depend whether the behavior should be built-in or just part of the example, but we should tidy up the focus management when the search input in the new example expands and collapses. Currently the behavior makes it difficult to know what has focus after interaction:

Expandable.search.input.focus.mov

/** Callback function to toggle the expandable search input */
onToggleExpand: (isExpanded: boolean, event: React.SyntheticEvent<HTMLButtonElement>) => void;
/** An accessible label for the expandable search input toggle */
toggleAriaLabel?: string;
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.

Because an a11y error will get flagged for the icon button not having an accessible name, we should make this a required prop as well.

Copy link
Copy Markdown
Contributor

@thatblindgeye thatblindgeye left a comment

Choose a reason for hiding this comment

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

🔥 Awesome job on this to both of you, @andyyvo and @wise-king-sullyman !

@wise-king-sullyman
Copy link
Copy Markdown
Collaborator

@mcarrano does the behavior in the example now line up with what you expected?

Convenience link: https://patternfly-react-pr-7903.surge.sh/components/search-input#with-expandable-button

Copy link
Copy Markdown
Member

@mcarrano mcarrano left a comment

Choose a reason for hiding this comment

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

@mcarrano does the behavior in the example now line up with what you expected?

Yes. This looks great. Thanks @andyyvo @wise-king-sullyman

hint?: string;

/** Object that makes the search input expandable/collapsible */
expandableProps?: expandableProps;
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.

As discussed on slack. I change this prop name to not be suffixed with "Props".

Copy link
Copy Markdown
Contributor

@tlabaj tlabaj left a comment

Choose a reason for hiding this comment

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

LGTM. Thank you Andy and Austin.

@tlabaj tlabaj merged commit d2a6c47 into patternfly:main Sep 14, 2022
@patternfly-build
Copy link
Copy Markdown
Collaborator

Your changes have been released in:

  • eslint-plugin-patternfly-react@4.77.0
  • @patternfly/react-catalog-view-extension@4.89.0
  • @patternfly/react-charts@6.91.0
  • @patternfly/react-code-editor@4.79.0
  • @patternfly/react-console@4.89.0
  • @patternfly/react-core@4.238.0
  • @patternfly/react-docs@5.99.0
  • @patternfly/react-icons@4.89.0
  • @patternfly/react-inline-edit-extension@4.83.0
  • demo-app-ts@4.198.0
  • @patternfly/react-integration@4.200.0
  • @patternfly/react-log-viewer@4.83.0
  • @patternfly/react-styles@4.88.0
  • @patternfly/react-table@4.107.0
  • @patternfly/react-tokens@4.90.0
  • @patternfly/react-topology@4.85.0
  • @patternfly/react-virtualized-extension@4.85.0
  • transformer-cjs-imports@4.76.0

Thanks for your contribution! 🎉

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.

Search input - expandable masthead variant

9 participants