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 styled from 'styled-components';
import TopBar from '../../widgets/TopBar';
import {UrlObject} from 'url';

const Main = styled('main')({
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 = {
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 (
<>
<TopBar
query={query}
brand={brand}
onSearch={onSearch}
searchHint={searchHint}
searchLabel={searchLabel}
searchName={searchName}
linkComponent={linkComponent}
menuLink={menuLink}
menuLinkLabel={menuLinkLabel}
userLink={userLink}
userLinkLabel={userLinkLabel}
/>
<Main>
{children}


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

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

const DisableScrolling = createGlobalStyle({
'body': {
@@ -52,11 +53,61 @@ const OpenLeftSidebar = styled(LeftSidebar)({
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,
sidebarMain,
sidebarMainOpen,
children,
onSearch,
searchLabel,
searchName,
searchHint,
brand,
linkComponent,
menuLinkLabel,
menuLink,
userLink,
userLinkLabel,
}) => {
const LeftSidebarComponent = sidebarMainOpen ? OpenLeftSidebar : LeftSidebar

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


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

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

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

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

export const SidebarMenuGroup = styled('div')({
const SidebarMenuGroup = styled('div')({
display: 'contents',
'@media (min-width: 1080px)': {
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,
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)': {
width: 'auto',
display: 'none',
},
})

export const SidebarMenuItemIcon = styled('span')({
const SidebarMenuItemIcon = styled('span')({
display: 'block',
'@media (min-width: 1080px)': {
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',
display: 'grid',
placeContent: 'center',
@@ -161,22 +242,117 @@ export const SidebarMenuContainer = styled('span')({
marginLeft: 'auto',
paddingRight: '1rem',
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,
children,
sidebarMain,
sidebarMenu,
sidebarMenuItems,
sidebarMainOpen,
brand,
onSearch,
searchLabel,
searchName,
searchHint,
linkComponent: LinkComponent = 'a',
menuLinkLabel,
menuLink,
userLink,
userLinkLabel,
moreItemsOpen,
}) => {
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 (
<>
{
sidebarMainOpen
(sidebarMainOpen || moreItemsOpen)
&& (
<DisableScrolling />
)
@@ -186,11 +362,158 @@ const LeftSidebarWithMenuLayout = ({
withMenu
query={query}
wide
brand={brand}
onSearch={onSearch}
linkComponent={LinkComponent}
searchHint={searchHint}
searchLabel={searchLabel}
searchName={searchName}
menuLink={menuLink}
menuLinkLabel={menuLinkLabel}
userLink={userLink}
userLinkLabel={userLinkLabel}
/>
<LeftSidebar>
<SidebarMenu>
<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>
</SidebarMenu>
<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 TopBar from '../../widgets/TopBar';
import {UrlObject} from 'url';

const Main = styled('main')({
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,
sidebar,
sidebarMain,
children,
brand,
linkComponent,
searchHint,
searchName,
searchLabel,
onSearch,
menuLinkLabel,
menuLink,
userLink,
userLinkLabel,
}) => {
return (
<>
<TopBar
query={query}
wide
brand={brand}
linkComponent={linkComponent}
searchHint={searchHint}
searchName={searchName}
searchLabel={searchLabel}
onSearch={onSearch}
menuLink={menuLink}
menuLinkLabel={menuLinkLabel}
userLink={userLink}
userLinkLabel={userLinkLabel}
/>
<Main>
{children}
</Main>
<RightSidebar>
{sidebar}
{sidebarMain}
</RightSidebar>
</>
)


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

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

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

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)': {
position: 'absolute',
left: -999999,
},
})


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

const TopBar: React.FC<Props> = ({
@@ -100,14 +100,25 @@ const TopBar: React.FC<Props> = ({
searchHint = 'e.g. keywords, names…',
wide,
withMenu,
brand,
linkComponent: LinkComponent = 'a',
menuLink,
menuLinkLabel = 'Menu',
userLink,
userLinkLabel = 'Guest',
}) => {
const ContainerComponent = wide ? WideContainer : Container
return (
<Base>
<ContainerComponent>
<BrandContainer>
Brand
</BrandContainer>
{
Boolean(brand)
&& (
<BrandContainer>
{brand}
</BrandContainer>
)
}
<SearchContainer
onSubmit={onSearch}
>
@@ -130,22 +141,38 @@ const TopBar: React.FC<Props> = ({
{
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
name="user"
label="Guest"
label={userLinkLabel}
/>
</UserLink>
</LinkComponent>
</UserContainer>
</ContainerComponent>
</Base>


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

@@ -1,26 +1,34 @@
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';

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 = {
query: string,
linkComponent: React.ElementType,
menuLink: UrlObject,
userLink: UrlObject,
menuLinkLabel: string,
userLinkLabel: string,
}

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


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

@@ -1,41 +1,37 @@
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 {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,
sidebarMainOpen,
linkComponent,
menuLinkLabel,
menuLink,
userLink,
userLinkLabel,
}) => {
return (
<LeftSidebarLayout
brand="Brand"
query={query}
sidebarMainOpen={sidebarMainOpen}
linkComponent={linkComponent}
menuLink={menuLink}
menuLinkLabel={menuLinkLabel}
userLink={userLink}
userLinkLabel={userLinkLabel}
sidebarMain={
<SidebarContainer>
<DummyContent />


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

@@ -1,102 +1,145 @@
import * as React from 'react'
import styled from 'styled-components';
import * as T from '@tesseract-design/react-common';
import LeftSidebarWithMenuLayout, {
SidebarMenuItemIcon,
SidebarMenuContainer,
SidebarMenuGroup,
SidebarMenuItem,
Container,
SidebarMainContainer,
} from '../../organisms/layouts/LeftSidebarWithMenu';
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,
sidebarMainOpen,
linkComponent,
menuLinkLabel,
menuLink,
userLink,
userLinkLabel,
moreItemsOpen,
}) => {
return (
<LeftSidebarWithMenuLayout
brand="Brand"
moreItemsOpen={moreItemsOpen}
query={query}
linkComponent={linkComponent}
sidebarMainOpen={sidebarMainOpen}
sidebarMain={
<SidebarMainContainer>
<DummyContent />
</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>


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

@@ -1,38 +1,35 @@
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 {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,
linkComponent,
menuLinkLabel,
menuLink,
userLink,
userLinkLabel,
}) => {
return (
<RightSidebarLayout
brand="Brand"
query={query}
sidebar={
linkComponent={linkComponent}
menuLink={menuLink}
menuLinkLabel={menuLinkLabel}
userLink={userLink}
userLinkLabel={userLinkLabel}
sidebarMain={
<SidebarContainer>
<DummyContent />
</SidebarContainer>


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

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

type Props = {
query: string,
@@ -10,7 +11,22 @@ const Page: NextPage<Props> = ({
}) => {
return (
<Template
linkComponent={Link}
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 Template from '../../../components/templates/LeftSidebarLayout'
import Link from '../../../components/molecules/Link';

type Props = {
query: string,
@@ -14,6 +15,21 @@ const Page: NextPage<Props> = ({
<Template
query={query}
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 Template from '../../../../components/templates/LeftSidebarWithMenuLayout'
import Link from '../../../../components/molecules/Link';

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

const Page: NextPage<Props> = ({
query,
sidebarMainOpen,
moreItemsOpen,
}) => {
return (
<Template
query={query}
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: {
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 Template from '../../../components/templates/RightSidebarLayout'
import Link from '../../../components/molecules/Link';

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


Loading…
Cancel
Save