refactor(client): Refactor menu to use refs (#37047)
* Refactor menu to use refs #37025 * Fix Header tests #37025 * Removing unneeded forwardRefs #37025
This commit is contained in:
committed by
Ahmad Abdolsaheb
parent
d0cda5820c
commit
a68345ae56
@ -41,5 +41,6 @@ describe('<NavLinks />', () => {
|
|||||||
const UniversalNavProps = {
|
const UniversalNavProps = {
|
||||||
displayMenu: false,
|
displayMenu: false,
|
||||||
menuButtonRef: {},
|
menuButtonRef: {},
|
||||||
|
searchBarRef: {},
|
||||||
toggleDisplayMenu: function() {}
|
toggleDisplayMenu: function() {}
|
||||||
};
|
};
|
||||||
|
@ -1,25 +1,24 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
const MenuButton = React.forwardRef((props, ref) => {
|
const MenuButton = props => (
|
||||||
return (
|
|
||||||
<button
|
<button
|
||||||
aria-expanded={props.displayMenu}
|
aria-expanded={props.displayMenu}
|
||||||
className={
|
className={
|
||||||
'toggle-button-nav' + (props.displayMenu ? ' reverse-toggle-color' : '')
|
'toggle-button-nav' + (props.displayMenu ? ' reverse-toggle-color' : '')
|
||||||
}
|
}
|
||||||
onClick={props.onClick}
|
onClick={props.onClick}
|
||||||
ref={ref}
|
ref={props.innerRef}
|
||||||
>
|
>
|
||||||
Menu
|
Menu
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
|
||||||
MenuButton.displayName = 'MenuButton';
|
MenuButton.displayName = 'MenuButton';
|
||||||
MenuButton.propTypes = {
|
MenuButton.propTypes = {
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
displayMenu: PropTypes.bool.isRequired,
|
displayMenu: PropTypes.bool.isRequired,
|
||||||
|
innerRef: PropTypes.object,
|
||||||
onClick: PropTypes.func.isRequired
|
onClick: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,18 +8,20 @@ import MenuButton from './MenuButton';
|
|||||||
import NavLinks from './NavLinks';
|
import NavLinks from './NavLinks';
|
||||||
import './universalNav.css';
|
import './universalNav.css';
|
||||||
|
|
||||||
export const UniversalNav = React.forwardRef(
|
export const UniversalNav = ({
|
||||||
({ displayMenu, toggleDisplayMenu }, ref) => (
|
displayMenu,
|
||||||
|
toggleDisplayMenu,
|
||||||
|
menuButtonRef,
|
||||||
|
searchBarRef
|
||||||
|
}) => (
|
||||||
<nav
|
<nav
|
||||||
className={
|
className={'universal-nav nav-padding' + (displayMenu ? ' expand-nav' : '')}
|
||||||
'universal-nav nav-padding' + (displayMenu ? ' expand-nav' : '')
|
|
||||||
}
|
|
||||||
id='universal-nav'
|
id='universal-nav'
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={'universal-nav-left' + (displayMenu ? ' display-flex' : '')}
|
className={'universal-nav-left' + (displayMenu ? ' display-flex' : '')}
|
||||||
>
|
>
|
||||||
<SearchBar />
|
<SearchBar innerRef={searchBarRef} />
|
||||||
</div>
|
</div>
|
||||||
<div className='universal-nav-middle'>
|
<div className='universal-nav-middle'>
|
||||||
<Link id='universal-nav-logo' to='/'>
|
<Link id='universal-nav-logo' to='/'>
|
||||||
@ -31,11 +33,10 @@ export const UniversalNav = React.forwardRef(
|
|||||||
</div>
|
</div>
|
||||||
<MenuButton
|
<MenuButton
|
||||||
displayMenu={displayMenu}
|
displayMenu={displayMenu}
|
||||||
|
innerRef={menuButtonRef}
|
||||||
onClick={toggleDisplayMenu}
|
onClick={toggleDisplayMenu}
|
||||||
ref={ref}
|
|
||||||
/>
|
/>
|
||||||
</nav>
|
</nav>
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
UniversalNav.displayName = 'UniversalNav';
|
UniversalNav.displayName = 'UniversalNav';
|
||||||
@ -44,5 +45,6 @@ export default UniversalNav;
|
|||||||
UniversalNav.propTypes = {
|
UniversalNav.propTypes = {
|
||||||
displayMenu: PropTypes.bool,
|
displayMenu: PropTypes.bool,
|
||||||
menuButtonRef: PropTypes.object,
|
menuButtonRef: PropTypes.object,
|
||||||
|
searchBarRef: PropTypes.object,
|
||||||
toggleDisplayMenu: PropTypes.func
|
toggleDisplayMenu: PropTypes.func
|
||||||
};
|
};
|
||||||
|
@ -12,6 +12,7 @@ export class Header extends React.Component {
|
|||||||
displayMenu: false
|
displayMenu: false
|
||||||
};
|
};
|
||||||
this.menuButtonRef = React.createRef();
|
this.menuButtonRef = React.createRef();
|
||||||
|
this.searchBarRef = React.createRef();
|
||||||
this.handleClickOutside = this.handleClickOutside.bind(this);
|
this.handleClickOutside = this.handleClickOutside.bind(this);
|
||||||
this.toggleDisplayMenu = this.toggleDisplayMenu.bind(this);
|
this.toggleDisplayMenu = this.toggleDisplayMenu.bind(this);
|
||||||
}
|
}
|
||||||
@ -29,7 +30,8 @@ export class Header extends React.Component {
|
|||||||
this.state.displayMenu &&
|
this.state.displayMenu &&
|
||||||
this.menuButtonRef.current &&
|
this.menuButtonRef.current &&
|
||||||
!this.menuButtonRef.current.contains(event.target) &&
|
!this.menuButtonRef.current.contains(event.target) &&
|
||||||
event.target.id !== 'fcc_instantsearch'
|
this.searchBarRef.current &&
|
||||||
|
!this.searchBarRef.current.contains(event.target)
|
||||||
) {
|
) {
|
||||||
this.toggleDisplayMenu();
|
this.toggleDisplayMenu();
|
||||||
}
|
}
|
||||||
@ -48,7 +50,8 @@ export class Header extends React.Component {
|
|||||||
<header>
|
<header>
|
||||||
<UniversalNav
|
<UniversalNav
|
||||||
displayMenu={displayMenu}
|
displayMenu={displayMenu}
|
||||||
ref={this.menuButtonRef}
|
menuButtonRef={this.menuButtonRef}
|
||||||
|
searchBarRef={this.searchBarRef}
|
||||||
toggleDisplayMenu={this.toggleDisplayMenu}
|
toggleDisplayMenu={this.toggleDisplayMenu}
|
||||||
/>
|
/>
|
||||||
</header>
|
</header>
|
||||||
|
@ -23,6 +23,7 @@ import './searchbar.css';
|
|||||||
configure({ ignoreTags: ['select', 'textarea'] });
|
configure({ ignoreTags: ['select', 'textarea'] });
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
|
innerRef: PropTypes.object,
|
||||||
isDropdownEnabled: PropTypes.bool,
|
isDropdownEnabled: PropTypes.bool,
|
||||||
isSearchFocused: PropTypes.bool,
|
isSearchFocused: PropTypes.bool,
|
||||||
toggleSearchDropdown: PropTypes.func.isRequired,
|
toggleSearchDropdown: PropTypes.func.isRequired,
|
||||||
@ -51,7 +52,6 @@ class SearchBar extends Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.searchBarRef = React.createRef();
|
|
||||||
this.handleChange = this.handleChange.bind(this);
|
this.handleChange = this.handleChange.bind(this);
|
||||||
this.handleSearch = this.handleSearch.bind(this);
|
this.handleSearch = this.handleSearch.bind(this);
|
||||||
this.handleMouseEnter = this.handleMouseEnter.bind(this);
|
this.handleMouseEnter = this.handleMouseEnter.bind(this);
|
||||||
@ -87,7 +87,7 @@ class SearchBar extends Component {
|
|||||||
|
|
||||||
handleFocus(e) {
|
handleFocus(e) {
|
||||||
const { toggleSearchFocused } = this.props;
|
const { toggleSearchFocused } = this.props;
|
||||||
const isSearchFocused = this.searchBarRef.current.contains(e.target);
|
const isSearchFocused = this.props.innerRef.current.contains(e.target);
|
||||||
if (!isSearchFocused) {
|
if (!isSearchFocused) {
|
||||||
// Reset if user clicks outside of
|
// Reset if user clicks outside of
|
||||||
// search bar / closes dropdown
|
// search bar / closes dropdown
|
||||||
@ -177,15 +177,11 @@ class SearchBar extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isDropdownEnabled, isSearchFocused } = this.props;
|
const { isDropdownEnabled, isSearchFocused, innerRef } = this.props;
|
||||||
const { index } = this.state;
|
const { index } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className='fcc_searchBar' data-testid='fcc_searchBar' ref={innerRef}>
|
||||||
className='fcc_searchBar'
|
|
||||||
data-testid='fcc_searchBar'
|
|
||||||
ref={this.searchBarRef}
|
|
||||||
>
|
|
||||||
<HotKeys handlers={this.keyHandlers} keyMap={this.keyMap}>
|
<HotKeys handlers={this.keyHandlers} keyMap={this.keyMap}>
|
||||||
<div className='fcc_search_wrapper'>
|
<div className='fcc_search_wrapper'>
|
||||||
<label className='fcc_sr_only' htmlFor='fcc_instantsearch'>
|
<label className='fcc_sr_only' htmlFor='fcc_instantsearch'>
|
||||||
|
Reference in New Issue
Block a user