1import { css } from '@emotion/react'; 2import { theme, breakpoints, HamburgerIcon, iconSize, spacing } from '@expo/styleguide'; 3import React from 'react'; 4 5import { Search } from '../Search'; 6import { Logo } from './Logo'; 7import { ThemeSelector } from './ThemeSelector'; 8 9import { Button } from '~/ui/components/Button'; 10import { SidebarFooter, SidebarHead } from '~/ui/components/Sidebar'; 11import { BOLD } from '~/ui/components/Text'; 12 13type HeaderProps = { 14 sidebar: React.ReactNode; 15 sidebarActiveGroup: string; 16 isMobileMenuVisible: boolean; 17 setMobileMenuVisible: (isMobileMenuVisible: boolean) => void; 18}; 19 20export const Header = ({ 21 sidebar, 22 sidebarActiveGroup, 23 isMobileMenuVisible, 24 setMobileMenuVisible, 25}: HeaderProps) => { 26 return ( 27 <> 28 <nav css={[containerStyle, isMobileMenuVisible]}> 29 <div css={[columnStyle, leftColumnStyle]}> 30 <Logo /> 31 </div> 32 <div css={[columnStyle, rightColumnStyle]}> 33 <Search /> 34 <div css={hideOnMobileStyle}> 35 <ThemeSelector /> 36 </div> 37 <div css={showOnMobileStyle}> 38 <Button 39 theme="transparent" 40 css={[mobileButtonStyle, isMobileMenuVisible && mobileButtonActiveStyle]} 41 onClick={() => { 42 setMobileMenuVisible(!isMobileMenuVisible); 43 }}> 44 <HamburgerIcon size={iconSize.sm} /> 45 </Button> 46 </div> 47 </div> 48 </nav> 49 {isMobileMenuVisible && ( 50 <nav css={[containerStyle, showOnMobileStyle]}> 51 <div css={[columnStyle, leftColumnStyle]}> 52 <BOLD>Theme</BOLD> 53 </div> 54 <div css={[columnStyle, rightColumnStyle]}> 55 <ThemeSelector /> 56 </div> 57 </nav> 58 )} 59 {isMobileMenuVisible && ( 60 <div css={mobileSidebarStyle}> 61 <SidebarHead sidebarActiveGroup={sidebarActiveGroup} /> 62 {sidebar} 63 <SidebarFooter /> 64 </div> 65 )} 66 </> 67 ); 68}; 69 70const containerStyle = css` 71 display: flex; 72 align-items: center; 73 justify-content: flex-end; 74 position: relative; 75 background-color: ${theme.background.default}; 76 z-index: 2; 77 margin: 0 auto; 78 padding: 0 ${spacing[4]}px; 79 height: 60px; 80 box-sizing: border-box; 81 border-bottom: 1px solid ${theme.border.default}; 82 gap: ${spacing[4]}px; 83`; 84 85const columnStyle = css` 86 flex-shrink: 0; 87 display: flex; 88 background-color: transparent; 89`; 90 91const leftColumnStyle = css` 92 flex-grow: 1; 93 align-items: center; 94 95 @media screen and (max-width: ${(breakpoints.medium + breakpoints.large) / 2}px) { 96 flex-basis: auto; 97 width: auto; 98 } 99`; 100 101const rightColumnStyle = css` 102 justify-content: flex-end; 103 104 @media screen and (max-width: ${(breakpoints.medium + breakpoints.large) / 2}px) { 105 flex-basis: auto; 106 width: auto; 107 } 108`; 109 110const showOnMobileStyle = css` 111 display: none; 112 113 @media screen and (max-width: ${(breakpoints.medium + breakpoints.large) / 2}px) { 114 display: flex; 115 } 116`; 117 118const hideOnMobileStyle = css` 119 @media screen and (max-width: ${(breakpoints.medium + breakpoints.large) / 2}px) { 120 display: none; 121 } 122`; 123 124const mobileButtonStyle = css` 125 padding: 0 ${spacing[3]}px; 126 margin-left: ${spacing[2]}px; 127 128 &:hover { 129 background-color: ${theme.background.element}; 130 box-shadow: none; 131 } 132`; 133 134const mobileButtonActiveStyle = css` 135 background-color: ${theme.background.subtle}; 136`; 137 138const mobileSidebarStyle = css` 139 background-color: ${theme.background.subtle}; 140 height: calc(100vh - (60px * 2)); 141 overflow-y: auto; 142 overflow-x: hidden; 143`; 144