Browse Source

Make Left Sidebar w/ Menu fully mobile-functional

This implements the router based on Next.js for left-sidebar-with-menu
layout.

In addition, the other layouts have been genericized for wider framework
support, although the underlying API is still based on Next.js
components.
master
TheoryOfNekomata 3 years ago
parent
commit
96c84e8801
14 changed files with 833 additions and 189 deletions
  1. +20
    -0
      src/components/molecules/Link/index.tsx
  2. +43
    -1
      src/components/organisms/layouts/Basic/index.tsx
  3. +62
    -1
      src/components/organisms/layouts/LeftSidebar/index.tsx
  4. +337
    -14
      src/components/organisms/layouts/LeftSidebarWithMenu/index.tsx
  5. +63
    -3
      src/components/organisms/layouts/RightSidebar/index.tsx
  6. +53
    -26
      src/components/organisms/widgets/TopBar/index.tsx
  7. +18
    -10
      src/components/templates/BasicLayout/index.tsx
  8. +23
    -27
      src/components/templates/LeftSidebarLayout/index.tsx
  9. +123
    -80
      src/components/templates/LeftSidebarWithMenuLayout/index.tsx
  10. +23
    -26
      src/components/templates/RightSidebarLayout/index.tsx
  11. +16
    -1
      src/pages/layouts/basic/index.tsx
  12. +16
    -0
      src/pages/layouts/left-sidebar/index.tsx
  13. +20
    -0
      src/pages/layouts/left-sidebar/with-menu/index.tsx
  14. +16
    -0
      src/pages/layouts/right-sidebar/index.tsx

+ 20
- 0
src/components/molecules/Link/index.tsx View File

@@ -0,0 +1,20 @@
import NextLink from 'next/link'

const Link = ({ href, as, prefetch, replace, shallow, component: Component = 'a', ...etcProps }) => {
return (
<NextLink
href={href}
as={as}
passHref
replace={replace}
shallow={shallow}
prefetch={prefetch}
>
<Component
{...etcProps}
/>
</NextLink>
)
}

export default Link

+ 43
- 1
src/components/organisms/layouts/Basic/index.tsx View File

@@ -1,20 +1,62 @@
import * as React from 'react' import * as React from 'react'
import styled from 'styled-components'; import styled from 'styled-components';
import TopBar from '../../widgets/TopBar'; import TopBar from '../../widgets/TopBar';
import {UrlObject} from 'url';


const Main = styled('main')({ const Main = styled('main')({
boxSizing: 'border-box', boxSizing: 'border-box',
}) })


export const Container = styled('div')({
padding: '0 1rem',
boxSizing: 'border-box',
margin: '0 auto',
maxWidth: 'calc(var(--width-base, 360px) * 2)',
width: '100%',
})

type Props = { type Props = {
query?: string, query?: string,
brand?: React.ReactNode,
onSearch?: React.FormEventHandler,
searchLabel?: string,
searchName?: string,
searchHint?: string,
linkComponent?: React.ElementType,
menuLink?: UrlObject,
userLink?: UrlObject,
menuLinkLabel?: string,
userLinkLabel?: string,
} }


const BasicLayout: React.FC<Props> = ({ query, children }) => {
const BasicLayout: React.FC<Props> = ({
query,
children,
brand,
onSearch,
searchLabel,
searchName,
searchHint,
linkComponent,
menuLinkLabel,
menuLink,
userLink,
userLinkLabel,
}) => {
return ( return (
<> <>
<TopBar <TopBar
query={query} query={query}
brand={brand}
onSearch={onSearch}
searchHint={searchHint}
searchLabel={searchLabel}
searchName={searchName}
linkComponent={linkComponent}
menuLink={menuLink}
menuLinkLabel={menuLinkLabel}
userLink={userLink}
userLinkLabel={userLinkLabel}
/> />
<Main> <Main>
{children} {children}


+ 62
- 1
src/components/organisms/layouts/LeftSidebar/index.tsx View File

@@ -1,6 +1,7 @@
import * as React from 'react'; import * as React from 'react';
import styled, {createGlobalStyle} from 'styled-components'; import styled, {createGlobalStyle} from 'styled-components';
import TopBar from '../../widgets/TopBar'; import TopBar from '../../widgets/TopBar';
import {UrlObject} from 'url';


const DisableScrolling = createGlobalStyle({ const DisableScrolling = createGlobalStyle({
'body': { 'body': {
@@ -52,11 +53,61 @@ const OpenLeftSidebar = styled(LeftSidebar)({
left: 0, left: 0,
}) })


const LeftSidebarLayout = ({
export const SidebarContainer = styled('div')({
margin: '0 auto',
padding: '0 1rem',
boxSizing: 'border-box',
maxWidth: 'calc(var(--width-base, 360px) * 2)',
'@media (min-width: 1080px)': {
width: 'var(--width-base, 360px)',
marginRight: 0,
},
})

export const Container = styled('div')({
padding: '0 1rem',
boxSizing: 'border-box',

width: '100%',
maxWidth: 'calc(var(--width-base, 360px) * 2)',
marginRight: 'auto',
marginLeft: 'auto',
'@media (min-width: 1080px)': {
marginLeft: 0,
},
})

type Props = {
query?: string,
onSearch?: React.FormEventHandler,
searchLabel?: string,
searchName?: string,
searchHint?: string,
brand?: React.ReactNode,
linkComponent?: React.ElementType,
sidebarMain?: React.ReactChild,
sidebarMainOpen?: boolean,
menuLink?: UrlObject,
userLink?: UrlObject,
menuLinkLabel?: string,
userLinkLabel?: string,
}

const LeftSidebarLayout: React.FC<Props> = ({
query, query,
sidebarMain, sidebarMain,
sidebarMainOpen, sidebarMainOpen,
children, children,
onSearch,
searchLabel,
searchName,
searchHint,
brand,
linkComponent,
menuLinkLabel,
menuLink,
userLink,
userLinkLabel,
}) => { }) => {
const LeftSidebarComponent = sidebarMainOpen ? OpenLeftSidebar : LeftSidebar const LeftSidebarComponent = sidebarMainOpen ? OpenLeftSidebar : LeftSidebar


@@ -72,6 +123,16 @@ const LeftSidebarLayout = ({
wide wide
query={query} query={query}
withMenu withMenu
onSearch={onSearch}
searchHint={searchHint}
searchLabel={searchLabel}
searchName={searchName}
brand={brand}
linkComponent={linkComponent}
menuLink={menuLink}
menuLinkLabel={menuLinkLabel}
userLink={userLink}
userLinkLabel={userLinkLabel}
/> />
<LeftSidebarComponent> <LeftSidebarComponent>
<SidebarOverflow> <SidebarOverflow>


+ 337
- 14
src/components/organisms/layouts/LeftSidebarWithMenu/index.tsx View File

@@ -1,6 +1,8 @@
import * as React from 'react'; import * as React from 'react';
import * as T from '@tesseract-design/react-common';
import styled, { createGlobalStyle } from 'styled-components'; import styled, { createGlobalStyle } from 'styled-components';
import TopBar from '../../widgets/TopBar'; import TopBar from '../../widgets/TopBar';
import {UrlObject} from 'url';


const DisableScrolling = createGlobalStyle({ const DisableScrolling = createGlobalStyle({
'body': { 'body': {
@@ -14,6 +16,7 @@ const DisableScrolling = createGlobalStyle({
const Wrapper = styled('div')({ const Wrapper = styled('div')({
'--width-base': '360px', '--width-base': '360px',
'--size-menu': '4rem', '--size-menu': '4rem',
'--height-topbar': '4rem',
}) })


const Main = styled('main')({ const Main = styled('main')({
@@ -86,8 +89,8 @@ const SidebarMenu = styled('div')({
left: 0, left: 0,
width: '100%', width: '100%',
height: 'var(--size-menu, 4rem)', height: 'var(--size-menu, 4rem)',
backgroundColor: 'var(--color-bg, white)',
zIndex: 1, zIndex: 1,
backgroundColor: 'var(--color-bg, white)',
'@media (prefers-color-scheme: dark)': { '@media (prefers-color-scheme: dark)': {
backgroundColor: 'var(--color-bg, black)', backgroundColor: 'var(--color-bg, black)',
}, },
@@ -117,7 +120,7 @@ const SidebarMenuSize = styled('div')({
}, },
}) })


export const SidebarMenuGroup = styled('div')({
const SidebarMenuGroup = styled('div')({
display: 'contents', display: 'contents',
'@media (min-width: 1080px)': { '@media (min-width: 1080px)': {
width: '100%', width: '100%',
@@ -125,19 +128,85 @@ export const SidebarMenuGroup = styled('div')({
}, },
}) })


export const SidebarMenuItem = styled('a')({
height: 'var(--size-menu, 4rem)',
display: 'flex',
alignItems: 'center',
textDecoration: 'none',
const MoreItems = styled('div')({
position: 'fixed',
top: 0,
left: '-100%',
width: '100%',
height: '100%',
paddingTop: 'var(--height-topbar, 4rem)',
paddingBottom: 'var(--size-menu, 4rem)',
backgroundColor: 'var(--color-bg, white)',
zIndex: -1,
boxSizing: 'border-box',
'@media (prefers-color-scheme: dark)': {
backgroundColor: 'var(--color-bg, black)',
},
'@media (min-width: 1080px)': {
display: 'contents',
},
})

const OpenMoreItems = styled(MoreItems)({
left: 0,
})

const MoreItemsScroll = styled('div')({
width: '100%',
height: '100%',
overflow: 'auto',
'@media (min-width: 1080px)': {
display: 'contents',
},
})

const MorePrimarySidebarMenuGroup = styled(SidebarMenuGroup)({
'@media (min-width: 1080px)': {
flex: 'auto',
},
})

const MoreSecondarySidebarMenuGroup = styled(SidebarMenuGroup)({
'@media (min-width: 1080px)': {
order: 4,
},
})

const SidebarMenuItem = styled('span')({
width: 0, width: 0,
flex: 'auto', flex: 'auto',
height: 'var(--size-menu, 4rem)',
'> *': {
height: '100%',
},
'@media (min-width: 1080px)': {
width: 'auto !important',
flex: '0 1 auto',
'> *': {
height: 'auto',
}
},
})

const MoreSidebarMenuItem = styled('span')({
display: 'block',
height: 'var(--size-menu, 4rem)',
'> *': {
height: '100%',
},
'@media (min-width: 1080px)': {
width: 'auto !important',
flex: '0 1 auto',
},
})

const MoreToggleSidebarMenuItem = styled(SidebarMenuItem)({
'@media (min-width: 1080px)': { '@media (min-width: 1080px)': {
width: 'auto',
display: 'none',
}, },
}) })


export const SidebarMenuItemIcon = styled('span')({
const SidebarMenuItemIcon = styled('span')({
display: 'block', display: 'block',
'@media (min-width: 1080px)': { '@media (min-width: 1080px)': {
width: 'var(--size-menu, 4rem)', width: 'var(--size-menu, 4rem)',
@@ -147,7 +216,19 @@ export const SidebarMenuItemIcon = styled('span')({
}, },
}) })


export const SidebarMenuContainer = styled('span')({
const MoreSidebarMenuItemIcon = styled('span')({
marginRight: '1rem',
display: 'block',
'@media (min-width: 1080px)': {
width: 'var(--size-menu, 4rem)',
height: 'var(--size-menu, 4rem)',
display: 'grid',
placeContent: 'center',
marginRight: 0,
},
})

const SidebarMenuContainer = styled('span')({
boxSizing: 'border-box', boxSizing: 'border-box',
display: 'grid', display: 'grid',
placeContent: 'center', placeContent: 'center',
@@ -161,22 +242,117 @@ export const SidebarMenuContainer = styled('span')({
marginLeft: 'auto', marginLeft: 'auto',
paddingRight: '1rem', paddingRight: '1rem',
textAlign: 'left', textAlign: 'left',
boxSizing: 'border-box',
},
})

const MoreSidebarMenuContainer = styled('div')({
display: 'flex',
justifyContent: 'flex-start',
alignItems: 'center',
width: 'calc(var(--width-base, 360px) * 2)',
margin: '0 auto',
padding: '0 1rem',
textAlign: 'left',
boxSizing: 'border-box',
'@media (min-width: 1080px)': {
marginRight: 0,
width: 'var(--width-base, 360px)',
paddingLeft: 0,
}, },
}) })


const LeftSidebarWithMenuLayout = ({
export const Container = styled('div')({
padding: '0 1rem',
boxSizing: 'border-box',

width: '100%',
maxWidth: 'calc(var(--width-base, 360px) * 2)',
marginRight: 'auto',
marginLeft: 'auto',
'@media (min-width: 1080px)': {
marginLeft: 0,
},
})

export const SidebarMainContainer = styled('div')({
padding: '0 1rem',
boxSizing: 'border-box',
width: '100%',
maxWidth: 'calc(var(--width-base, 360px) * 2)',
margin: '0 auto',
'@media (min-width: 1080px)': {
maxWidth: 'none',
},
})

type MenuItem = {
id: string,
label: string,
url: UrlObject,
secondary?: boolean,
icon: React.ReactChild,
}

type Props = {
query?: string,
onSearch?: React.FormEventHandler,
searchLabel?: string,
searchName?: string,
searchHint?: string,
brand?: React.ReactNode,
linkComponent?: React.ElementType,
sidebarMain?: React.ReactChild,
sidebarMenuItems?: MenuItem[],
sidebarMainOpen?: boolean,
menuLink?: UrlObject,
userLink?: UrlObject,
menuLinkLabel?: string,
userLinkLabel?: string,
moreItemsOpen?: boolean,
}

const LeftSidebarWithMenuLayout: React.FC<Props> = ({
query, query,
children, children,
sidebarMain, sidebarMain,
sidebarMenu,
sidebarMenuItems,
sidebarMainOpen, sidebarMainOpen,
brand,
onSearch,
searchLabel,
searchName,
searchHint,
linkComponent: LinkComponent = 'a',
menuLinkLabel,
menuLink,
userLink,
userLinkLabel,
moreItemsOpen,
}) => { }) => {
const SidebarMainComponent = sidebarMainOpen ? OpenSidebarMain : SidebarMain 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 ( return (
<> <>
{ {
sidebarMainOpen
(sidebarMainOpen || moreItemsOpen)
&& ( && (
<DisableScrolling /> <DisableScrolling />
) )
@@ -186,11 +362,158 @@ const LeftSidebarWithMenuLayout = ({
withMenu withMenu
query={query} query={query}
wide wide
brand={brand}
onSearch={onSearch}
linkComponent={LinkComponent}
searchHint={searchHint}
searchLabel={searchLabel}
searchName={searchName}
menuLink={menuLink}
menuLinkLabel={menuLinkLabel}
userLink={userLink}
userLinkLabel={userLinkLabel}
/> />
<LeftSidebar> <LeftSidebar>
<SidebarMenu> <SidebarMenu>
<SidebarMenuSize> <SidebarMenuSize>
{sidebarMenu}
<SidebarMenuGroup>
{visiblePrimarySidebarMenuItems.map((item) => {
return (
<SidebarMenuItem
key={item.id}
>
<LinkComponent
href={item.url}
style={{
display: 'flex',
alignItems: 'center',
textDecoration: 'none',
width: '100%',
}}
>
<SidebarMenuContainer>
<SidebarMenuItemIcon>
{item.icon}
</SidebarMenuItemIcon>
{item.label}
</SidebarMenuContainer>
</LinkComponent>
</SidebarMenuItem>
)
})}
</SidebarMenuGroup>
<MoreItemsComponent>
<MoreItemsScroll>
<MorePrimarySidebarMenuGroup>
{morePrimarySidebarMenuItems.map((item) => {
return (
<MoreSidebarMenuItem
key={item.id}
>
<LinkComponent
href={item.url}
style={{
display: 'flex',
alignItems: 'center',
textDecoration: 'none',
width: '100%',
}}
>
<MoreSidebarMenuContainer>
<MoreSidebarMenuItemIcon>
{item.icon}
</MoreSidebarMenuItemIcon>
{item.label}
</MoreSidebarMenuContainer>
</LinkComponent>
</MoreSidebarMenuItem>
)
})}
</MorePrimarySidebarMenuGroup>
<MoreSecondarySidebarMenuGroup>
{moreSecondarySidebarMenuItems.map((item) => {
return (
<MoreSidebarMenuItem
key={item.id}
>
<LinkComponent
href={item.url}
style={{
display: 'flex',
alignItems: 'center',
textDecoration: 'none',
width: '100%',
}}
>
<MoreSidebarMenuContainer>
<MoreSidebarMenuItemIcon>
{item.icon}
</MoreSidebarMenuItemIcon>
{item.label}
</MoreSidebarMenuContainer>
</LinkComponent>
</MoreSidebarMenuItem>
)
})}
</MoreSecondarySidebarMenuGroup>
</MoreItemsScroll>
</MoreItemsComponent>
<MoreToggleSidebarMenuItem>
<SidebarMenuItem>
<LinkComponent
href={{
query: {
more: '',
}
}}
style={{
display: 'flex',
alignItems: 'center',
textDecoration: 'none',
width: '100%',
}}
>
<SidebarMenuContainer>
<SidebarMenuItemIcon>
<T.Icon
name="more-horizontal"
label=""
/>
</SidebarMenuItemIcon>
More
</SidebarMenuContainer>
</LinkComponent>
</SidebarMenuItem>
</MoreToggleSidebarMenuItem>
{
visibleSecondarySidebarMenuItems.length > 0
&& (
<SidebarMenuGroup>
{visibleSecondarySidebarMenuItems.map((item, i) => (
<SidebarMenuItem
key={item.id}
>
<LinkComponent
href={item.url}
style={{
display: 'flex',
alignItems: 'center',
textDecoration: 'none',
width: '100%',
}}
>
<SidebarMenuContainer>
<SidebarMenuItemIcon>
{item.icon}
</SidebarMenuItemIcon>
{item.label}
</SidebarMenuContainer>
</LinkComponent>
</SidebarMenuItem>
))}
</SidebarMenuGroup>
)
}
</SidebarMenuSize> </SidebarMenuSize>
</SidebarMenu> </SidebarMenu>
<SidebarMainComponent> <SidebarMainComponent>


+ 63
- 3
src/components/organisms/layouts/RightSidebar/index.tsx View File

@@ -1,5 +1,7 @@
import * as React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import TopBar from '../../widgets/TopBar'; import TopBar from '../../widgets/TopBar';
import {UrlObject} from 'url';


const Main = styled('main')({ const Main = styled('main')({
boxSizing: 'border-box', boxSizing: 'border-box',
@@ -32,22 +34,80 @@ const RightSidebar = styled('div')({
}, },
}) })


const RightSidebarLayout = ({
export const SidebarContainer = styled('div')({
padding: '0 1rem',
boxSizing: 'border-box',
width: '100%',
maxWidth: 'calc(var(--width-base, 360px) * 2)',
margin: '0 auto',
'@media (min-width: 1080px)': {
width: 'var(--width-base, 360px)',
marginLeft: 0,
},
})

export const Container = styled('div')({
padding: '0 1rem',
boxSizing: 'border-box',
width: '100%',
maxWidth: 'calc(var(--width-base, 360px) * 2)',
margin: '0 auto',
'@media (min-width: 1080px)': {
marginRight: 0,
},
})

type Props = {
query?: string,
onSearch?: React.FormEventHandler,
searchLabel?: string,
searchName?: string,
searchHint?: string,
brand?: React.ReactNode,
linkComponent?: React.ElementType,
sidebarMain?: React.ReactChild,
menuLink: UrlObject,
userLink: UrlObject,
menuLinkLabel?: string,
userLinkLabel?: string,
}

const RightSidebarLayout: React.FC<Props> = ({
query, query,
sidebar,
sidebarMain,
children, children,
brand,
linkComponent,
searchHint,
searchName,
searchLabel,
onSearch,
menuLinkLabel,
menuLink,
userLink,
userLinkLabel,
}) => { }) => {
return ( return (
<> <>
<TopBar <TopBar
query={query} query={query}
wide wide
brand={brand}
linkComponent={linkComponent}
searchHint={searchHint}
searchName={searchName}
searchLabel={searchLabel}
onSearch={onSearch}
menuLink={menuLink}
menuLinkLabel={menuLinkLabel}
userLink={userLink}
userLinkLabel={userLinkLabel}
/> />
<Main> <Main>
{children} {children}
</Main> </Main>
<RightSidebar> <RightSidebar>
{sidebar}
{sidebarMain}
</RightSidebar> </RightSidebar>
</> </>
) )


+ 53
- 26
src/components/organisms/widgets/TopBar/index.tsx View File

@@ -1,17 +1,16 @@
import * as React from 'react' import * as React from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import * as T from '@tesseract-design/react-common' import * as T from '@tesseract-design/react-common'
import {UrlObject} from 'url';


const Base = styled('div')({ const Base = styled('div')({
'--width-base': '360px',
'--height-topbar': '4rem',
position: 'fixed', position: 'fixed',
top: 0, top: 0,
left: 0, left: 0,
width: '100%', width: '100%',
height: 'var(--height-topbar, 4rem)', height: 'var(--height-topbar, 4rem)',
backgroundColor: 'var(--color-bg, white)', backgroundColor: 'var(--color-bg, white)',
zIndex: 1,
zIndex: 2,
'@media (prefers-color-scheme: dark)': { '@media (prefers-color-scheme: dark)': {
backgroundColor: 'var(--color-bg, black)', backgroundColor: 'var(--color-bg, black)',
}, },
@@ -56,6 +55,9 @@ const SearchContainer = styled('form')({
flex: 'auto', flex: 'auto',
padding: '0 1rem', padding: '0 1rem',
boxSizing: 'border-box', boxSizing: 'border-box',
':first-child': {
paddingLeft: 0,
},
}) })


const UserContainer = styled('div')({ const UserContainer = styled('div')({
@@ -67,21 +69,13 @@ const UserContainer = styled('div')({
}, },
}) })


const UserLink = styled('a')({
width: 'var(--height-topbar, 4rem)',
height: '100%',
display: 'inline-grid',
placeContent: 'center',
})

const MenuUserLink = styled(UserLink)({
const MenuUserLinkContainer = styled('span')({
'@media (min-width: 1080px)': { '@media (min-width: 1080px)': {
position: 'absolute', position: 'absolute',
left: -999999, left: -999999,
}, },
}) })



type Props = { type Props = {
query?: string, query?: string,
onSearch?: React.FormEventHandler, onSearch?: React.FormEventHandler,
@@ -90,6 +84,12 @@ type Props = {
searchHint?: string, searchHint?: string,
wide?: boolean, wide?: boolean,
withMenu?: boolean, withMenu?: boolean,
brand?: React.ReactNode,
linkComponent?: React.ElementType,
menuLink: UrlObject,
userLink: UrlObject,
menuLinkLabel?: string,
userLinkLabel?: string,
} }


const TopBar: React.FC<Props> = ({ const TopBar: React.FC<Props> = ({
@@ -100,14 +100,25 @@ const TopBar: React.FC<Props> = ({
searchHint = 'e.g. keywords, names…', searchHint = 'e.g. keywords, names…',
wide, wide,
withMenu, withMenu,
brand,
linkComponent: LinkComponent = 'a',
menuLink,
menuLinkLabel = 'Menu',
userLink,
userLinkLabel = 'Guest',
}) => { }) => {
const ContainerComponent = wide ? WideContainer : Container const ContainerComponent = wide ? WideContainer : Container
return ( return (
<Base> <Base>
<ContainerComponent> <ContainerComponent>
<BrandContainer>
Brand
</BrandContainer>
{
Boolean(brand)
&& (
<BrandContainer>
{brand}
</BrandContainer>
)
}
<SearchContainer <SearchContainer
onSubmit={onSearch} onSubmit={onSearch}
> >
@@ -130,22 +141,38 @@ const TopBar: React.FC<Props> = ({
{ {
withMenu withMenu
&& ( && (
<MenuUserLink
href="?sidebar"
>
<T.Icon
name="menu"
label="Guest"
/>
</MenuUserLink>
<MenuUserLinkContainer>
<LinkComponent
href={menuLink}
style={{
width: 'var(--height-topbar, 4rem)',
height: '100%',
display: 'inline-grid',
placeContent: 'center',
}}
>
<T.Icon
name="menu"
label={menuLinkLabel}
/>
</LinkComponent>
</MenuUserLinkContainer>
) )
} }
<UserLink>
<LinkComponent
href={userLink}
style={{
width: 'var(--height-topbar, 4rem)',
height: '100%',
display: 'inline-grid',
placeContent: 'center',
}}
>
<T.Icon <T.Icon
name="user" name="user"
label="Guest"
label={userLinkLabel}
/> />
</UserLink>
</LinkComponent>
</UserContainer> </UserContainer>
</ContainerComponent> </ContainerComponent>
</Base> </Base>


+ 18
- 10
src/components/templates/BasicLayout/index.tsx View File

@@ -1,26 +1,34 @@
import * as React from 'react' import * as React from 'react'
import styled from 'styled-components'
import Basic from '../../organisms/layouts/Basic'
import Basic, { Container } from '../../organisms/layouts/Basic'
import DummyContent from '../../molecules/DummyContent'; import DummyContent from '../../molecules/DummyContent';

const Container = styled('div')({
padding: '0 1rem',
boxSizing: 'border-box',
margin: '0 auto',
maxWidth: 'calc(var(--width-base, 360px) * 2)',
width: '100%',
})
import {UrlObject} from 'url';


type Props = { type Props = {
query: string, query: string,
linkComponent: React.ElementType,
menuLink: UrlObject,
userLink: UrlObject,
menuLinkLabel: string,
userLinkLabel: string,
} }


const BasicLayoutTemplate: React.FC<Props> = ({ const BasicLayoutTemplate: React.FC<Props> = ({
query, query,
linkComponent,
menuLinkLabel,
menuLink,
userLink,
userLinkLabel,
}) => { }) => {
return ( return (
<Basic <Basic
brand="Brand"
query={query} query={query}
linkComponent={linkComponent}
menuLink={menuLink}
menuLinkLabel={menuLinkLabel}
userLink={userLink}
userLinkLabel={userLinkLabel}
> >
<Container> <Container>
<DummyContent /> <DummyContent />


+ 23
- 27
src/components/templates/LeftSidebarLayout/index.tsx View File

@@ -1,41 +1,37 @@
import * as React from 'react' import * as React from 'react'
import styled from 'styled-components';
import LeftSidebarLayout from '../../organisms/layouts/LeftSidebar';
import LeftSidebarLayout, { SidebarContainer, Container } from '../../organisms/layouts/LeftSidebar';
import DummyContent from '../../molecules/DummyContent'; import DummyContent from '../../molecules/DummyContent';
import {UrlObject} from 'url';


const SidebarContainer = styled('div')({
margin: '0 auto',
padding: '0 1rem',
boxSizing: 'border-box',
maxWidth: 'calc(var(--width-base, 360px) * 2)',
'@media (min-width: 1080px)': {
width: 'var(--width-base, 360px)',
marginRight: 0,
},
})

const Container = styled('div')({
padding: '0 1rem',
boxSizing: 'border-box',

width: '100%',
maxWidth: 'calc(var(--width-base, 360px) * 2)',
marginRight: 'auto',
marginLeft: 'auto',
'@media (min-width: 1080px)': {
marginLeft: 0,
},
})

type Props = {
query: string,
linkComponent: React.ElementType,
sidebarMainOpen: boolean,
menuLink: UrlObject,
userLink: UrlObject,
menuLinkLabel: string,
userLinkLabel: string,
}


const LeftSidebarLayoutTemplate = ({
const LeftSidebarLayoutTemplate: React.FC<Props> = ({
query, query,
sidebarMainOpen, sidebarMainOpen,
linkComponent,
menuLinkLabel,
menuLink,
userLink,
userLinkLabel,
}) => { }) => {
return ( return (
<LeftSidebarLayout <LeftSidebarLayout
brand="Brand"
query={query} query={query}
sidebarMainOpen={sidebarMainOpen} sidebarMainOpen={sidebarMainOpen}
linkComponent={linkComponent}
menuLink={menuLink}
menuLinkLabel={menuLinkLabel}
userLink={userLink}
userLinkLabel={userLinkLabel}
sidebarMain={ sidebarMain={
<SidebarContainer> <SidebarContainer>
<DummyContent /> <DummyContent />


+ 123
- 80
src/components/templates/LeftSidebarWithMenuLayout/index.tsx View File

@@ -1,102 +1,145 @@
import * as React from 'react' import * as React from 'react'
import styled from 'styled-components';
import * as T from '@tesseract-design/react-common'; import * as T from '@tesseract-design/react-common';
import LeftSidebarWithMenuLayout, { import LeftSidebarWithMenuLayout, {
SidebarMenuItemIcon,
SidebarMenuContainer,
SidebarMenuGroup,
SidebarMenuItem,
Container,
SidebarMainContainer,
} from '../../organisms/layouts/LeftSidebarWithMenu'; } from '../../organisms/layouts/LeftSidebarWithMenu';
import DummyContent from '../../molecules/DummyContent'; import DummyContent from '../../molecules/DummyContent';
import {UrlObject} from 'url';


const Container = styled('div')({
padding: '0 1rem',
boxSizing: 'border-box',

width: '100%',
maxWidth: 'calc(var(--width-base, 360px) * 2)',
marginRight: 'auto',
marginLeft: 'auto',
'@media (min-width: 1080px)': {
marginLeft: 0,
},
})

const SidebarMainContainer = styled('div')({
padding: '0 1rem',
boxSizing: 'border-box',
width: '100%',
maxWidth: 'calc(var(--width-base, 360px) * 2)',
margin: '0 auto',
'@media (min-width: 1080px)': {
maxWidth: 'none',
},
})
type Props = {
query: string,
linkComponent: React.ElementType,
sidebarMainOpen: boolean,
menuLink: UrlObject,
userLink: UrlObject,
menuLinkLabel: string,
userLinkLabel: string,
moreItemsOpen: boolean,
}


const LeftSidebarLayoutTemplate = ({
const LeftSidebarLayoutTemplate: React.FC<Props> = ({
query, query,
sidebarMainOpen, sidebarMainOpen,
linkComponent,
menuLinkLabel,
menuLink,
userLink,
userLinkLabel,
moreItemsOpen,
}) => { }) => {
return ( return (
<LeftSidebarWithMenuLayout <LeftSidebarWithMenuLayout
brand="Brand"
moreItemsOpen={moreItemsOpen}
query={query} query={query}
linkComponent={linkComponent}
sidebarMainOpen={sidebarMainOpen} sidebarMainOpen={sidebarMainOpen}
sidebarMain={ sidebarMain={
<SidebarMainContainer> <SidebarMainContainer>
<DummyContent /> <DummyContent />
</SidebarMainContainer> </SidebarMainContainer>
} }
sidebarMenu={
<>
<SidebarMenuGroup>
<SidebarMenuItem>
<SidebarMenuContainer>
<SidebarMenuItemIcon>
<T.Icon
name="square"
label=""
/>
</SidebarMenuItemIcon>
Hello
</SidebarMenuContainer>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuContainer>
<SidebarMenuItemIcon>
<T.Icon
name="square"
label=""
/>
</SidebarMenuItemIcon>
Hello
</SidebarMenuContainer>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuContainer>
<SidebarMenuItemIcon>
<T.Icon
name="square"
label=""
/>
</SidebarMenuItemIcon>
Hello
</SidebarMenuContainer>
</SidebarMenuItem>
</SidebarMenuGroup>
<SidebarMenuGroup>
<SidebarMenuItem>
<SidebarMenuContainer>
<SidebarMenuItemIcon>
<T.Icon
name="square"
label=""
/>
</SidebarMenuItemIcon>
World
</SidebarMenuContainer>
</SidebarMenuItem>
</SidebarMenuGroup>
</>
menuLink={menuLink}
menuLinkLabel={menuLinkLabel}
userLink={userLink}
userLinkLabel={userLinkLabel}
sidebarMenuItems={
[
{
id: '1',
label: 'P1',
url: {
href: '/hello',
},
icon: (
<T.Icon
name="square"
label=""
/>
),
},
{
id: '2',
label: 'P2',
url: {
href: '/hello',
},
icon: (
<T.Icon
name="square"
label=""
/>
),
},
{
id: '3',
label: 'P3',
url: {
href: '/hello',
},
icon: (
<T.Icon
name="square"
label=""
/>
),
},
{
id: '100',
label: 'P4',
url: {
href: '/hello',
},
icon: (
<T.Icon
name="square"
label=""
/>
),
},
{
id: '101',
label: 'P5',
url: {
href: '/hello',
},
icon: (
<T.Icon
name="square"
label=""
/>
),
},
{
id: '4',
label: 'S1',
url: {
href: '/hello',
},
icon: (
<T.Icon
name="square"
label=""
/>
),
secondary: true,
},
{
id: '5',
label: 'S2',
url: {
href: '/hello',
},
icon: (
<T.Icon
name="square"
label=""
/>
),
secondary: true,
},
]
} }
> >
<Container> <Container>


+ 23
- 26
src/components/templates/RightSidebarLayout/index.tsx View File

@@ -1,38 +1,35 @@
import * as React from 'react' import * as React from 'react'
import styled from 'styled-components';
import RightSidebarLayout from '../../organisms/layouts/RightSidebar';
import RightSidebarLayout, { SidebarContainer, Container } from '../../organisms/layouts/RightSidebar';
import DummyContent from '../../molecules/DummyContent'; import DummyContent from '../../molecules/DummyContent';
import {UrlObject} from 'url';


const SidebarContainer = styled('div')({
padding: '0 1rem',
boxSizing: 'border-box',
width: '100%',
maxWidth: 'calc(var(--width-base, 360px) * 2)',
margin: '0 auto',
'@media (min-width: 1080px)': {
width: 'var(--width-base, 360px)',
marginLeft: 0,
},
})

const Container = styled('div')({
padding: '0 1rem',
boxSizing: 'border-box',
width: '100%',
maxWidth: 'calc(var(--width-base, 360px) * 2)',
margin: '0 auto',
'@media (min-width: 1080px)': {
marginRight: 0,
},
})
type Props = {
query: string,
linkComponent: React.ElementType,
menuLink: UrlObject,
userLink: UrlObject,
menuLinkLabel: string,
userLinkLabel: string,
}


const RightSidebarLayoutTemplate = ({
const RightSidebarLayoutTemplate: React.FC<Props> = ({
query, query,
linkComponent,
menuLinkLabel,
menuLink,
userLink,
userLinkLabel,
}) => { }) => {
return ( return (
<RightSidebarLayout <RightSidebarLayout
brand="Brand"
query={query} query={query}
sidebar={
linkComponent={linkComponent}
menuLink={menuLink}
menuLinkLabel={menuLinkLabel}
userLink={userLink}
userLinkLabel={userLinkLabel}
sidebarMain={
<SidebarContainer> <SidebarContainer>
<DummyContent /> <DummyContent />
</SidebarContainer> </SidebarContainer>


+ 16
- 1
src/pages/layouts/basic/index.tsx View File

@@ -1,5 +1,6 @@
import {GetServerSideProps, NextPage} from 'next' import {GetServerSideProps, NextPage} from 'next'
import Template from '../../../components/templates/BasicLayout' import Template from '../../../components/templates/BasicLayout'
import Link from '../../../components/molecules/Link';


type Props = { type Props = {
query: string, query: string,
@@ -10,7 +11,22 @@ const Page: NextPage<Props> = ({
}) => { }) => {
return ( return (
<Template <Template
linkComponent={Link}
query={query} query={query}
menuLink={{
query: {
q: query,
sidebar: '',
}
}}
menuLinkLabel="Menu"
userLink={{
pathname: '/profile',
query: {
q: query,
},
}}
userLinkLabel="User"
/> />
) )
} }
@@ -25,4 +41,3 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => {
} }
} }
} }


+ 16
- 0
src/pages/layouts/left-sidebar/index.tsx View File

@@ -1,5 +1,6 @@
import {GetServerSideProps, NextPage} from 'next' import {GetServerSideProps, NextPage} from 'next'
import Template from '../../../components/templates/LeftSidebarLayout' import Template from '../../../components/templates/LeftSidebarLayout'
import Link from '../../../components/molecules/Link';


type Props = { type Props = {
query: string, query: string,
@@ -14,6 +15,21 @@ const Page: NextPage<Props> = ({
<Template <Template
query={query} query={query}
sidebarMainOpen={sidebarMainOpen} sidebarMainOpen={sidebarMainOpen}
linkComponent={Link}
menuLink={{
query: {
q: query,
sidebar: '',
}
}}
menuLinkLabel="Menu"
userLink={{
pathname: '/profile',
query: {
q: query,
},
}}
userLinkLabel="User"
/> />
) )
} }


+ 20
- 0
src/pages/layouts/left-sidebar/with-menu/index.tsx View File

@@ -1,19 +1,38 @@
import {GetServerSideProps, NextPage} from 'next' import {GetServerSideProps, NextPage} from 'next'
import Template from '../../../../components/templates/LeftSidebarWithMenuLayout' import Template from '../../../../components/templates/LeftSidebarWithMenuLayout'
import Link from '../../../../components/molecules/Link';


type Props = { type Props = {
query: string, query: string,
sidebarMainOpen: boolean, sidebarMainOpen: boolean,
moreItemsOpen: boolean,
} }


const Page: NextPage<Props> = ({ const Page: NextPage<Props> = ({
query, query,
sidebarMainOpen, sidebarMainOpen,
moreItemsOpen,
}) => { }) => {
return ( return (
<Template <Template
query={query} query={query}
sidebarMainOpen={sidebarMainOpen} sidebarMainOpen={sidebarMainOpen}
linkComponent={Link}
menuLink={{
query: {
q: query,
sidebar: '',
}
}}
menuLinkLabel="Menu"
userLink={{
pathname: '/profile',
query: {
q: query,
},
}}
userLinkLabel="User"
moreItemsOpen={moreItemsOpen}
/> />
) )
} }
@@ -26,6 +45,7 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => {
props: { props: {
query, query,
sidebarMainOpen: 'sidebar' in ctx.query, sidebarMainOpen: 'sidebar' in ctx.query,
moreItemsOpen: 'more' in ctx.query,
} }
} }
} }


+ 16
- 0
src/pages/layouts/right-sidebar/index.tsx View File

@@ -1,5 +1,6 @@
import {GetServerSideProps, NextPage} from 'next' import {GetServerSideProps, NextPage} from 'next'
import Template from '../../../components/templates/RightSidebarLayout' import Template from '../../../components/templates/RightSidebarLayout'
import Link from '../../../components/molecules/Link';


type Props = { type Props = {
query: string, query: string,
@@ -10,7 +11,22 @@ const Page: NextPage<Props> = ({
}) => { }) => {
return ( return (
<Template <Template
linkComponent={Link}
query={query} query={query}
menuLink={{
query: {
q: query,
sidebar: '',
}
}}
menuLinkLabel="Menu"
userLink={{
pathname: '/profile',
query: {
q: query,
},
}}
userLinkLabel="User"
/> />
) )
} }


Loading…
Cancel
Save