|
- import * as React from 'react';
- import styled, { createGlobalStyle } from 'styled-components'
- import TopBar from '../../widgets/TopBar'
- import {applyBackgroundColor, minWidthFactor} from '../../utilities/mixins'
- import {configVar, loadConfig} from '../../utilities/helpers'
-
- const Config = createGlobalStyle({
- ...loadConfig(),
- })
-
- const DisableScrolling = createGlobalStyle({
- 'body': {
- overflow: 'hidden',
- ...minWidthFactor(3)({
- overflow: 'auto',
- }),
- },
- })
-
- const ContentBase = styled('main')({
- boxSizing: 'border-box',
- paddingBottom: 'var(--size-menu, 4rem)',
- ...minWidthFactor(3)({
- paddingLeft: `calc(50% - ${configVar('base-width')} * 0.5)`,
- paddingBottom: 0,
- }),
- })
-
- const SidebarBase = styled('div')({
- boxSizing: 'border-box',
- overflow: 'hidden',
- display: 'contents',
- left: `calc(${configVar('base-width')} * -1)`,
- ...applyBackgroundColor(),
- ...minWidthFactor(3)({
- position: 'fixed',
- top: 0,
- left: 0,
- width: `calc(50% - ${configVar('base-width')} * 0.5)`,
- height: '100%',
- display: 'block',
- }),
- })
-
- const SidebarMain = styled('div')({
- boxSizing: 'border-box',
- position: 'fixed',
- top: 0,
- right: '100%',
- width: '100%',
- height: '100%',
- overflow: 'auto',
- // overflow: 'overlay',
- paddingTop: 'inherit',
- paddingBottom: 'var(--size-menu, 4rem)',
- scrollbarWidth: 'none',
- '::-webkit-scrollbar': {
- display: 'none',
- },
- ...applyBackgroundColor(),
- ...minWidthFactor(3)({
- position: 'absolute',
- right: 0,
- width: `calc(${configVar('base-width')} - var(--size-menu, 4rem))`,
- marginLeft: 'auto',
- paddingBottom: 0,
- }),
- })
-
- const OpenSidebarMain = styled(SidebarMain)({
- right: 0,
- })
-
- const SidebarMenu = styled('div')({
- boxSizing: 'border-box',
- overflow: 'auto',
- // overflow: 'overlay',
- scrollbarWidth: 'none',
- '::-webkit-scrollbar': {
- display: 'none',
- },
- position: 'fixed',
- bottom: 0,
- left: 0,
- width: '100%',
- height: 'var(--size-menu, 4rem)',
- zIndex: 1,
- ...applyBackgroundColor(),
- ...minWidthFactor(3)({
- top: 0,
- marginLeft: 'auto',
- position: 'absolute',
- height: '100%',
- paddingTop: 'inherit',
- overflow: 'auto',
- zIndex: 'auto',
- }),
- })
-
- const SidebarMenuSize = styled('div')({
- display: 'flex',
- width: '100%',
- height: '100%',
- maxWidth: `calc(${configVar('base-width')} * 2)`,
- margin: '0 auto',
- ...minWidthFactor(3)({
- maxWidth: 'none',
- marginRight: 0,
- flexDirection: 'column',
- justifyContent: 'space-between',
- alignItems: 'flex-end',
- }),
- })
-
- const SidebarMenuGroup = styled('div')({
- display: 'contents',
- ...minWidthFactor(3)({
- width: '100%',
- display: 'block',
- }),
- })
-
- const MoreItems = styled('div')({
- position: 'fixed',
- top: 0,
- left: '-100%',
- width: '100%',
- height: '100%',
- paddingTop: 'var(--height-topbar, 4rem)',
- paddingBottom: 'var(--size-menu, 4rem)',
- zIndex: -1,
- boxSizing: 'border-box',
- ...applyBackgroundColor(),
- ...minWidthFactor(3)({
- display: 'contents',
- }),
- })
-
- const OpenMoreItems = styled(MoreItems)({
- left: 0,
- })
-
- const MoreItemsScroll = styled('div')({
- width: '100%',
- height: '100%',
- overflow: 'auto',
- ...minWidthFactor(3)({
- display: 'contents',
- }),
- })
-
- const MorePrimarySidebarMenuGroup = styled(SidebarMenuGroup)({
- ...minWidthFactor(3)({
- flex: 'auto',
- }),
- })
-
- const MoreSecondarySidebarMenuGroup = styled(SidebarMenuGroup)({
- ...minWidthFactor(3)({
- order: 4,
- }),
- })
-
- const SidebarMenuItem = styled('span')({
- width: 0,
- flex: 'auto',
- height: 'var(--size-menu, 4rem)',
- '> *': {
- height: '100%',
- display: 'flex',
- alignItems: 'center',
- textDecoration: 'none',
- width: '100%',
- },
- ...minWidthFactor(3)({
- width: 'auto !important',
- flex: '0 1 auto',
- '> *': {
- height: 'auto',
- },
- }),
- })
-
- const MoreSidebarMenuItem = styled('span')({
- display: 'block',
- height: 'var(--size-menu, 4rem)',
- '> *': {
- height: '100%',
- display: 'flex',
- alignItems: 'center',
- textDecoration: 'none',
- width: '100%',
- },
- ...minWidthFactor(3)({
- width: 'auto !important',
- flex: '0 1 auto',
- }),
- })
-
- const MoreToggleSidebarMenuItem = styled(SidebarMenuItem)({
- ...minWidthFactor(3)({
- display: 'none',
- }),
- })
-
- export const SidebarMenuItemIcon = styled('span')({
- display: 'block',
- ...minWidthFactor(3)({
- width: 'var(--size-menu, 4rem)',
- height: 'var(--size-menu, 4rem)',
- display: 'grid',
- placeContent: 'center',
- }),
- })
-
- export const MoreSidebarMenuItemIcon = styled('span')({
- marginRight: '1rem',
- display: 'block',
- ...minWidthFactor(3)({
- width: 'var(--size-menu, 4rem)',
- height: 'var(--size-menu, 4rem)',
- display: 'grid',
- placeContent: 'center',
- marginRight: 0,
- }),
- })
-
- export const SidebarMenuContainer = styled('span')({
- boxSizing: 'border-box',
- display: 'grid',
- placeContent: 'center',
- width: '100%',
- textAlign: 'center',
- ...minWidthFactor(3)({
- display: 'flex',
- justifyContent: 'flex-start',
- alignItems: 'center',
- width: `${configVar('base-width')}`,
- marginLeft: 'auto',
- paddingRight: '1rem',
- textAlign: 'left',
- boxSizing: 'border-box',
- }),
- })
-
- export const MoreSidebarMenuContainer = styled('div')({
- display: 'flex',
- justifyContent: 'flex-start',
- alignItems: 'center',
- width: `calc(${configVar('base-width')} * 2)`,
- margin: '0 auto',
- padding: '0 1rem',
- textAlign: 'left',
- boxSizing: 'border-box',
- ...minWidthFactor(3)({
- marginRight: 0,
- width: `${configVar('base-width')}`,
- paddingLeft: 0,
- }),
- })
-
- export const ContentContainer = styled('div')({
- padding: '0 1rem',
- boxSizing: 'border-box',
-
- width: '100%',
- maxWidth: `calc(${configVar('base-width')} * 2)`,
- marginRight: 'auto',
- marginLeft: 'auto',
- ...minWidthFactor(3)({
- marginLeft: 0,
- }),
- })
-
- export const SidebarMainContainer = styled('div')({
- padding: '0 1rem',
- boxSizing: 'border-box',
- width: '100%',
- maxWidth: `calc(${configVar('base-width')} * 2)`,
- margin: '0 auto',
- ...minWidthFactor(3)({
- maxWidth: 'none',
- }),
- })
-
- type BaseMenuItem = {
- label: React.ReactChild,
- icon: React.ReactChild,
- url: unknown,
- }
-
- export type MenuItem = BaseMenuItem & {
- id: string,
- secondary?: boolean,
- }
-
- type Props = {
- brand?: React.ReactNode,
- sidebarMain?: React.ReactChild,
- sidebarMainOpen?: boolean,
- sidebarMenuItems: MenuItem[],
- moreItemsOpen?: boolean,
- moreLinkMenuItem: BaseMenuItem,
- menuLink?: React.ReactNode,
- userLink?: React.ReactNode,
- moreLinkComponent: React.ElementType,
- linkComponent: React.ElementType,
- topBarCenter?: React.ReactChild,
- }
-
- export const Layout: React.FC<Props> = ({
- brand,
- sidebarMain,
- sidebarMainOpen,
- sidebarMenuItems,
- moreItemsOpen,
- moreLinkMenuItem,
- menuLink,
- userLink,
- moreLinkComponent: MoreLinkComponent,
- linkComponent: LinkComponent,
- topBarCenter,
- children,
- }) => {
- const SidebarMainComponent = sidebarMainOpen ? OpenSidebarMain : SidebarMain
- const MoreItemsComponent = moreItemsOpen ? OpenMoreItems : MoreItems
- const primarySidebarMenuItems = sidebarMenuItems.filter(s => !s.secondary)
- const secondarySidebarMenuItems = sidebarMenuItems.filter(s => s.secondary)
-
- const visibleSecondarySidebarMenuItems = secondarySidebarMenuItems.slice(0, 1)
- const moreSecondarySidebarMenuItems = secondarySidebarMenuItems.slice(1)
- const visiblePrimarySidebarMenuItems = (
- visibleSecondarySidebarMenuItems.length === 1
- ? primarySidebarMenuItems.slice(0, 3)
- : primarySidebarMenuItems.slice(0, 4)
- )
- const morePrimarySidebarMenuItems = (
- visibleSecondarySidebarMenuItems.length === 1
- ? primarySidebarMenuItems.slice(3)
- : primarySidebarMenuItems.slice(4)
- )
-
- return (
- <>
- <Config />
- {
- (sidebarMainOpen || moreItemsOpen)
- && (
- <DisableScrolling />
- )
- }
- <>
- <TopBar
- wide
- brand={brand}
- menuLink={sidebarMain ? menuLink : undefined}
- userLink={userLink}
- >
- {topBarCenter}
- </TopBar>
- <SidebarBase>
- <SidebarMenu>
- <SidebarMenuSize>
- <SidebarMenuGroup>
- {visiblePrimarySidebarMenuItems.map((item) => {
- return (
- <SidebarMenuItem
- key={item.id}
- >
- <LinkComponent
- {...item}
- />
- </SidebarMenuItem>
- )
- })}
- </SidebarMenuGroup>
- <MoreItemsComponent>
- <MoreItemsScroll>
- <MorePrimarySidebarMenuGroup>
- {morePrimarySidebarMenuItems.map((item) => {
- return (
- <MoreSidebarMenuItem
- key={item.id}
- >
- <MoreLinkComponent
- {...item}
- />
- </MoreSidebarMenuItem>
- )
- })}
- </MorePrimarySidebarMenuGroup>
- <MoreSecondarySidebarMenuGroup>
- {moreSecondarySidebarMenuItems.map((item) => {
- return (
- <MoreSidebarMenuItem
- key={item.id}
- >
- <MoreLinkComponent
- {...item}
- />
- </MoreSidebarMenuItem>
- )
- })}
- </MoreSecondarySidebarMenuGroup>
- </MoreItemsScroll>
- </MoreItemsComponent>
- {
- (
- morePrimarySidebarMenuItems.length > 0
- || moreSecondarySidebarMenuItems.length > 0
- )
- && (
- <MoreToggleSidebarMenuItem>
- <SidebarMenuItem>
- <LinkComponent
- {...moreLinkMenuItem}
- />
- </SidebarMenuItem>
- </MoreToggleSidebarMenuItem>
- )
- }
- {
- visibleSecondarySidebarMenuItems.length > 0
- && (
- <SidebarMenuGroup>
- {visibleSecondarySidebarMenuItems.map((item) => (
- <SidebarMenuItem
- key={item.id}
- >
- <LinkComponent
- {...item}
- />
- </SidebarMenuItem>
- ))}
- </SidebarMenuGroup>
- )
- }
- </SidebarMenuSize>
- </SidebarMenu>
- {
- (sidebarMain as unknown)
- && (
- <SidebarMainComponent>
- {sidebarMain}
- </SidebarMainComponent>
- )
- }
- </SidebarBase>
- <ContentBase>
- {children}
- </ContentBase>
- </>
- </>
- )
- }
|