1import { css } from '@emotion/react'; 2import { theme, spacing, breakpoints } from '@expo/styleguide'; 3import React from 'react'; 4 5import { SidebarGroup, SidebarSection, VersionSelector } from './index'; 6 7import { NavigationType, NavigationRoute } from '~/types/common'; 8 9const STYLES_SIDEBAR = css` 10 padding: ${spacing[4]}px; 11 width: 280px; 12 position: relative; 13 background-color: ${theme.background.default}; 14 15 @media screen and (max-width: ${breakpoints.medium + 124}px) { 16 width: 100%; 17 } 18`; 19 20const STYLES_SIDEBAR_FADE = css` 21 background: linear-gradient(${theme.background.default}, transparent); 22 height: 30px; 23 width: 274px; 24 position: fixed; 25 margin-top: -${spacing[4]}px; 26 left: 0; 27 z-index: 10; 28 pointer-events: none; 29 30 @media screen and (max-width: ${breakpoints.medium + 124}px) { 31 display: none; 32 } 33`; 34 35type SidebarProps = React.PropsWithChildren<{ 36 routes?: NavigationRoute[]; 37}>; 38 39export type SidebarNodeProps = { 40 route: NavigationRoute; 41 parentRoute?: NavigationRoute; 42}; 43 44export const Sidebar = ({ routes = [] }: SidebarProps) => { 45 const renderTypes: Record<NavigationType, React.ComponentType<SidebarNodeProps> | null> = { 46 section: SidebarSection, 47 group: SidebarGroup, 48 page: null, // Pages are rendered inside groups and should not be rendered directly 49 }; 50 51 return ( 52 <nav css={STYLES_SIDEBAR} data-sidebar> 53 <div css={[STYLES_SIDEBAR_FADE]} /> 54 <VersionSelector /> 55 {routes.map(route => { 56 const Component = renderTypes[route.type]; 57 return !!Component && <Component key={`${route.type}-${route.name}`} route={route} />; 58 })} 59 </nav> 60 ); 61}; 62