浏览代码

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
父节点
当前提交
96c84e8801
共有 14 个文件被更改,包括 833 次插入189 次删除
  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 查看文件

@@ -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 查看文件

@@ -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 查看文件

@@ -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 查看文件

@@ -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 查看文件

@@ -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 查看文件

@@ -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 查看文件

@@ -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 查看文件

@@ -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 查看文件

@@ -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 查看文件

@@ -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 查看文件

@@ -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 查看文件

@@ -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 查看文件

@@ -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 查看文件

@@ -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"
/>
)
}


正在加载...
取消
保存