@shopify/polaris
Version:
Shopify’s product component library
59 lines (58 loc) • 2.94 kB
JavaScript
import React from 'react';
import { MobileHamburgerMajorMonotone } from '@shopify/polaris-icons';
import { classNames } from '../../utilities/css';
import { getWidth } from '../../utilities/get-width';
import { useI18n } from '../../utilities/i18n';
import { useTheme } from '../../utilities/theme';
import { useForcibleToggle } from '../../utilities/use-toggle';
import { Icon } from '../Icon';
import { Image } from '../Image';
import { UnstyledLink } from '../UnstyledLink';
import { SearchField, UserMenu, Search, Menu } from './components';
import styles from './TopBar.scss';
// TypeScript can't generate types that correctly infer the typing of
// subcomponents so explicitly state the subcomponents in the type definition.
// Letting this be implicit works in this project but fails in projects that use
// generated *.d.ts files.
export const TopBar = function TopBar({ showNavigationToggle, userMenu, searchResults, searchField, secondaryMenu, searchResultsVisible, onNavigationToggle, onSearchResultsDismiss, contextControl, }) {
const i18n = useI18n();
const { logo } = useTheme();
const [focused, { forceTrue: forceTrueFocused, forceFalse: forceFalseFocused },] = useForcibleToggle(false);
const className = classNames(styles.NavigationIcon, focused && styles.focused);
const navigationButtonMarkup = showNavigationToggle ? (<button type="button" className={className} onClick={onNavigationToggle} onFocus={forceTrueFocused} onBlur={forceFalseFocused} aria-label={i18n.translate('Polaris.TopBar.toggleMenuLabel')}>
<Icon source={MobileHamburgerMajorMonotone} color="white"/>
</button>) : null;
const width = getWidth(logo, 104);
let contextMarkup;
if (contextControl) {
contextMarkup = (<div testID="ContextControl" className={styles.ContextControl}>
{contextControl}
</div>);
}
else if (logo) {
contextMarkup = (<div className={styles.LogoContainer}>
<UnstyledLink url={logo.url || ''} className={styles.LogoLink} style={{ width }}>
<Image source={logo.topBarSource || ''} alt={logo.accessibilityLabel || ''} className={styles.Logo} style={{ width }}/>
</UnstyledLink>
</div>);
}
const searchResultsMarkup = searchResults && searchResultsVisible ? (<Search visible={searchResultsVisible} onDismiss={onSearchResultsDismiss}>
{searchResults}
</Search>) : null;
const searchMarkup = searchField ? (<React.Fragment>
{searchField}
{searchResultsMarkup}
</React.Fragment>) : null;
return (<div className={styles.TopBar}>
{navigationButtonMarkup}
{contextMarkup}
<div className={styles.Contents}>
<div className={styles.SearchField}>{searchMarkup}</div>
<div className={styles.SecondaryMenu}>{secondaryMenu}</div>
{userMenu}
</div>
</div>);
};
TopBar.Menu = Menu;
TopBar.SearchField = SearchField;
TopBar.UserMenu = UserMenu;