fix(Search Input): use popper to control the popup in advanced search#7621
Conversation
|
Preview: https://patternfly-react-pr-7621.surge.sh A11y report: https://patternfly-react-pr-7621-a11y.surge.sh |
783c3c8 to
346efb7
Compare
3cfdc2e to
4fd7d62
Compare
4fd7d62 to
cb46af6
Compare
| <div className={css(className, styles.searchInput)} ref={searchInputRef} {...props}> | ||
| {buildSearchTextInputGroupWithExtraButtons()} | ||
| const advancedSearch = ( | ||
| <span> |
There was a problem hiding this comment.
we need a native HTML markup here, otherwise, the popper is not going to calculate the position and set the item absolute
| trigger={buildSearchTextInputGroupWithExtraButtons({ id: 'custom-advanced-search' })} | ||
| popper={advancedSearch} | ||
| isVisible={isSearchMenuOpen} | ||
| enableFlip={false} |
There was a problem hiding this comment.
I think we should enableFlip=true by default
| popper={advancedSearch} | ||
| isVisible={isSearchMenuOpen} | ||
| enableFlip={false} | ||
| appendTo={() => document.querySelector('#custom-advanced-search')} |
There was a problem hiding this comment.
We cannot hardcode this value. It should be something that is configurable the prop could be the same or inspired by the appendTo prop from TimePicker.tsx
/** The container to append the advanced search form to. Defaults to 'parent'.
* If your form is being cut off you can append it to an element higher up the DOM tree.
* Some examples:
* appendTo="parent"
* appendTo={() => document.body}
* appendTo={document.getElementById('target')}
*/
appendTo?: HTMLElement | (() => HTMLElement) | 'inline' | 'parent';
There was a problem hiding this comment.
I am not sure about that.
We want to append this menu to 'SearchTextInputGroup' (we set the value 'custom-advanced-search' as id) every time and not to an external DOM element.
Maybe I am missing something.
Could you please provide an example of where we need to configure this element outside the component?
There was a problem hiding this comment.
It's possible that someone will put an advanced search into a Wizard modal for example and that would get clipped or formatted incorrectly relative to the wizard or modal. Those tend to be some the edge cases we are allowing for.
Additionally, if someone wants an inline advanced search, where opening the modal does (for whatever reason) push down the contents of the page so the advanced search is not overlaying the results, that should be possible using the 'inline' value of 'appendTo'
There was a problem hiding this comment.
Got it, thanks! 👍🏼
So I think we can:
- keep the current behavior as default (without passing the prop appendTo). (popper)
- provide the inline option to push down the content ( no popper)
- add the possibility to pass an external DOM element (popper)
64be51d to
83c784e
Compare
| * menuAppendTo={() => document.body} | ||
| * menuAppendTo={document.getElementById('target')} | ||
| */ | ||
| menuAppendTo?: HTMLElement | (() => HTMLElement) | 'inline'; |
There was a problem hiding this comment.
I think the prop name menuAppendTo is a little misleading since the Menu is a component we have and we are not using a Menu in this case, but a panel. So I think it could be panelAppendTo or appendTo or maybe something else.
nicolethoen
left a comment
There was a problem hiding this comment.
sorry, I have one request to update the prop name
83c784e to
da06c6a
Compare
wise-king-sullyman
left a comment
There was a problem hiding this comment.
This looks great! One request: can you add a couple of tests to verify the behavior of appendTo? After that I'll be ready to approve 🙂
wise-king-sullyman
left a comment
There was a problem hiding this comment.
Just a couple nits!
| userEvent.click(screen.getByRole('button', { name: 'Search' })); | ||
|
|
||
| userEvent.click(screen.getByRole('button', { name: 'Open advanced search' })); | ||
| expect(screen.getByTestId('test-id').querySelector('.pf-c-panel')).toBeInTheDocument() |
There was a problem hiding this comment.
Nit: rather than using querySelector + toBeInTheDocument to determine where the search menu is being placed in the DOM can you use an RTL query to select the form (or something in it) and maybe the toContainElement matcher?
Reason being that I believe this would better replicate the actual user experience with the component.
eafa708 to
9cd5fb7
Compare
9cd5fb7 to
f726d50
Compare
wise-king-sullyman
left a comment
There was a problem hiding this comment.
Looks great! 🚀
…patternfly#7621) * fix(SearchInput): use popper to control the popup in advanced search * refactor(Search input): update PR comments * refactor(SearchInput): add unit tets
| <div className={css(className, styles.searchInput)} ref={searchInputRef} {...props}> | ||
| {buildSearchTextInputGroupWithExtraButtons()} | ||
| const AdvancedSearch = ( | ||
| <span> |
There was a problem hiding this comment.
@bartoval Apologies for the super late comment, I was following up on something I made a note about a while ago. FWIW with the original issue, we should always try and avoid applying multiple component styles to an element (ie, .pf-c-panel.pf-c-search-intput__menu).
This element should be a <div> though, a <span> is an inline element and its permitted content is phrasing content. So technically it's invalid HTML to put non-phrasing content in a <span>, though it works just fine. Created an issue for that here - #7796
Also it's worth noting that appendTo="inline" just drops the panel in the layout and pushes everything below it down (it doesn't display on top of the stuff below it). A few questions around that:
- Should
appendTobemenuAppendTolike the other components that have a menu in them that popper can position? - Is that the intended behavior of
appendTo="inline"or should that display on top of the stuff below it like it used to - it just won't use popper. Not sure how we'd do that if we want to continue to use the panel component there, but that would be inline with the other menus that supportmenuAppendTo. - If we are going to leave it so that it pushes the stuff below the panel down, should we remove the "raised" modifier from the panel since the shadow implies depth/overlay?
There was a problem hiding this comment.
@mcoker thanks for your comments! They are very interesting.
- I will pick up the issue
Regarding your questions:
-
there is comment above about that and using menuAppendTo is a little misleading since the Menu is a component we have and we are not using a Menu in this case.
-
Yes this behaviour is predicted like the TimePicker (@nicolethoen )
-
Not sure about it.
There was a problem hiding this comment.
@bartoval thanks!!
there is comment above about that and using menuAppendTo is a little misleading since the Menu is a component we have and we are not using a Menu in this case.
👍 got it. I agree, that could be confusing. I would probably argue that menu is more of a concept there to refer to the thing that pops open in the component, and that could be used with whatever component pops up. It seems like it might be more predictable/consistent that way. As in if we stopped using the "menu" component and used some other component for the thing that pops up, menuAppendTo would still be fine and wouldn't necessarily need to change IMO since we shouldn't be tying the prop name to the component used in the first place and we're using menu as a concept. Also I'd probably say that [menu/thing]AppendTo would be used on the component that has a thing that pops up, and appendTo would be more appropriate on the thing that pops up itself. Just my $0.02 😁
What: Closes #7592