@@ -13,7 +13,7 @@ | |||||
"pridepack" | "pridepack" | ||||
], | ], | ||||
"dependencies": { | "dependencies": { | ||||
"@tesseract-design/goofy-goober": "link:../../../goofy-goober" | |||||
"tailwindcss": "^3.3.3" | |||||
}, | }, | ||||
"devDependencies": { | "devDependencies": { | ||||
"@types/node": "^18.0.0", | "@types/node": "^18.0.0", | ||||
@@ -1,13 +1 @@ | |||||
export enum Span { | |||||
NARROW = 'narrow', | |||||
NORMAL = 'normal', | |||||
WIDE = 'wide', | |||||
} | |||||
export type LayoutArgs = { | |||||
span: Span; | |||||
mainSidebarOpen: boolean; | |||||
auxiliaryItemsShown: boolean; | |||||
} | |||||
export { setup, extractCss } from '@tesseract-design/goofy-goober'; | |||||
export type Span = 'narrow' | 'normal' | 'wide'; |
@@ -1,3 +1,2 @@ | |||||
export * as layouts from './layouts'; | |||||
export * as widgets from './widgets'; | |||||
export * from './common'; | export * from './common'; | ||||
export * as tailwind from './plugin-tailwind'; |
@@ -1,34 +0,0 @@ | |||||
import { css } from '@tesseract-design/goofy-goober'; | |||||
import {LayoutArgs, Span} from '../common'; | |||||
export const ContentBase = () => css.cx( | |||||
css` | |||||
box-sizing: border-box; | |||||
` | |||||
); | |||||
export const ContentContainer = ({ | |||||
span, | |||||
}: LayoutArgs) => css.cx( | |||||
css` | |||||
padding: 0 1rem; | |||||
box-sizing: border-box; | |||||
margin: 0 auto; | |||||
width: 100%; | |||||
`, | |||||
css.if(span === Span.NARROW)( | |||||
css` | |||||
max-width: var(--base-width); | |||||
` | |||||
), | |||||
css.if(span === Span.NORMAL)( | |||||
css` | |||||
max-width: calc(var(--base-width) * 2); | |||||
` | |||||
), | |||||
css.if(span === Span.WIDE)( | |||||
css` | |||||
max-width: calc(var(--base-width) * 3); | |||||
` | |||||
), | |||||
); |
@@ -1,90 +0,0 @@ | |||||
import { css } from '@tesseract-design/goofy-goober'; | |||||
import {LayoutArgs} from '../common'; | |||||
export const ContentBase = () => css.cx( | |||||
css` | |||||
box-sizing: border-box; | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
padding-left: calc(50% - (var(--base-width) * 0.5)); | |||||
` | |||||
), | |||||
); | |||||
export const SidebarOverflow = () => css.cx( | |||||
css` | |||||
width: 100%; | |||||
height: 100%; | |||||
overflow: auto; | |||||
// overflow: overlay; | |||||
position: relative; | |||||
z-index: 1; | |||||
scrollbar-width: none; | |||||
&::-webkit-scrollbar { | |||||
display: none; | |||||
} | |||||
` | |||||
) | |||||
export const SidebarBase = ({ | |||||
mainSidebarOpen, | |||||
}: LayoutArgs) => css.cx( | |||||
css` | |||||
box-sizing: border-box; | |||||
position: fixed; | |||||
top: 0; | |||||
left: -100%; | |||||
width: 100%; | |||||
height: 100%; | |||||
background-color: var(--color-background, white); | |||||
& > * { | |||||
display: block; | |||||
width: 100%; | |||||
height: 100%; | |||||
} | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
width: calc(50% - (var(--base-width) * 0.5)); | |||||
left: 0; | |||||
` | |||||
), | |||||
css.if(mainSidebarOpen)( | |||||
css` | |||||
left: 0; | |||||
` | |||||
), | |||||
); | |||||
export const SidebarMainContainer = () => css.cx( | |||||
css` | |||||
width: 100%; | |||||
margin: 0 auto; | |||||
padding: 0 1rem; | |||||
box-sizing: border-box; | |||||
max-width: calc(var(--base-width) * 2); | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
width: var(--base-width); | |||||
margin-right: 0; | |||||
` | |||||
), | |||||
); | |||||
export const ContentContainer = () => css.cx( | |||||
css` | |||||
padding: 0 1rem; | |||||
box-sizing: border-box; | |||||
width: 100%; | |||||
max-width: calc(var(--base-width) * 2); | |||||
margin-right: auto; | |||||
margin-left: auto; | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
margin-left: 0; | |||||
` | |||||
), | |||||
); |
@@ -1,380 +0,0 @@ | |||||
import { css } from '@tesseract-design/goofy-goober'; | |||||
import {LayoutArgs} from '../common'; | |||||
export const ContentBase = () => css.cx( | |||||
css` | |||||
box-sizing: border-box; | |||||
padding-bottom: var(--size-menu, 4rem); | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
padding-left: calc(50% - var(--base-width) * 0.5); | |||||
padding-bottom: 0; | |||||
`, | |||||
), | |||||
) | |||||
export const SidebarBase = () => css.cx( | |||||
css` | |||||
box-sizing: border-box; | |||||
overflow: hidden; | |||||
display: contents; | |||||
left: calc(var(--base-width) * -1); | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
position: fixed; | |||||
top: 0; | |||||
left: 0; | |||||
width: calc(50% - var(--base-width) * 0.5); | |||||
height: 100%; | |||||
display: block; | |||||
`, | |||||
), | |||||
) | |||||
export const SidebarMain = ({ | |||||
mainSidebarOpen, | |||||
}: LayoutArgs) => css.cx( | |||||
css` | |||||
box-sizing: border-box; | |||||
position: fixed; | |||||
top: 0; | |||||
width: 100%; | |||||
height: 100%; | |||||
padding-top: inherit; | |||||
padding-bottom: var(--size-menu, 4rem); | |||||
z-index: 2; | |||||
background-color: var(--color-background, white); | |||||
> * { | |||||
display: block; | |||||
width: 100%; | |||||
height: 100%; | |||||
background-color: var(--color-background, white); | |||||
} | |||||
`, | |||||
css.dynamic({ | |||||
right: mainSidebarOpen ? 0 : '100%', | |||||
}), | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
position: absolute; | |||||
right: 0; | |||||
width: calc(var(--base-width) - var(--size-menu, 4rem)); | |||||
margin-left: 0; | |||||
padding-bottom: 0; | |||||
`, | |||||
), | |||||
) | |||||
export const SidebarMainOverflow = () => css.cx( | |||||
css` | |||||
width: 100%; | |||||
height: 100%; | |||||
overflow: auto; /* overflow: overlay */ | |||||
scrollbar-width: none; | |||||
position: relative; | |||||
z-index: 1; | |||||
::-webkit-scrollbar { | |||||
display: none; | |||||
} | |||||
` | |||||
) | |||||
export const SidebarMenu = () => css.cx( | |||||
css` | |||||
box-sizing: border-box; | |||||
overflow: auto; /* overflow: overlay */ | |||||
scrollbar-width: none; | |||||
::-webkit-scrollbar { | |||||
display: none; | |||||
} | |||||
position: fixed; | |||||
bottom: 0; | |||||
left: 0; | |||||
width: 100%; | |||||
height: var(--size-menu, 4rem); | |||||
z-index: 1; | |||||
background-color: var(--color-background, white); | |||||
> * { | |||||
display: block; | |||||
width: 100%; | |||||
height: 100%; | |||||
background-color: var(--color-background, white); | |||||
} | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
top: 0; | |||||
margin-left: auto; | |||||
position: absolute; | |||||
height: 100%; | |||||
padding-top: inherit; | |||||
overflow: auto; | |||||
z-index: auto; | |||||
`, | |||||
), | |||||
); | |||||
export const SidebarMenuSize = () => css.cx( | |||||
css` | |||||
display: flex; | |||||
width: 100%; | |||||
height: 100%; | |||||
max-width: calc(var(--base-width) * 2); | |||||
margin: 0 auto; | |||||
position: relative; | |||||
z-index: 1; | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
max-width: none; | |||||
margin-right: 0; | |||||
flex-direction: column; | |||||
justify-content: space-between; | |||||
align-items: flex-end; | |||||
`, | |||||
), | |||||
); | |||||
export const SidebarMenuGroup = () => css.cx( | |||||
css` | |||||
display: contents; | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
width: 100%; | |||||
display: block; | |||||
`, | |||||
), | |||||
); | |||||
export const MoreItems = ({ | |||||
auxiliaryItemsShown, | |||||
}: LayoutArgs) => css.cx( | |||||
css` | |||||
position: fixed; | |||||
top: 0; | |||||
width: 100%; | |||||
height: 100%; | |||||
padding-top: var(--height-topbar, 4rem); | |||||
padding-bottom: var(--size-menu, 4rem); | |||||
z-index: -1; | |||||
box-sizing: border-box; | |||||
`, | |||||
css.dynamic({ | |||||
left: auxiliaryItemsShown ? 0 : '-100%', | |||||
}), | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
display: contents; | |||||
`, | |||||
), | |||||
); | |||||
export const MoreItemsScroll = () => css.cx( | |||||
css` | |||||
width: 100%; | |||||
height: 100%; | |||||
overflow: auto; | |||||
background-color: var(--color-background, white); | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
display: contents; | |||||
`, | |||||
), | |||||
); | |||||
export const MorePrimarySidebarMenuGroup = () => css.cx( | |||||
css` | |||||
display: contents; | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
width: 100%; | |||||
display: block; | |||||
flex: auto; | |||||
`, | |||||
), | |||||
); | |||||
export const MoreSecondarySidebarMenuGroup = () => css.cx( | |||||
css` | |||||
display: contents; | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
width: 100%; | |||||
display: block; | |||||
order: 4; | |||||
`, | |||||
), | |||||
); | |||||
export const SidebarMenuItem = () => css.cx( | |||||
css` | |||||
width: 0; | |||||
flex: auto; | |||||
height: var(--size-menu, 4rem); | |||||
> * { | |||||
height: 100%; | |||||
display: flex; | |||||
align-items: center; | |||||
text-decoration: none; | |||||
width: 100%; | |||||
} | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
width: auto !important; | |||||
flex: 0 1 auto; | |||||
> * { | |||||
height: auto; | |||||
} | |||||
` | |||||
), | |||||
); | |||||
export const MoreSidebarMenuItem = () => css.cx( | |||||
css` | |||||
height: var(--size-menu, 4rem); | |||||
display: block; | |||||
> * { | |||||
height: 100%; | |||||
display: flex; | |||||
align-items: center; | |||||
text-decoration: none; | |||||
width: 100%; | |||||
} | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
width: auto !important; | |||||
flex: 0 1 auto; | |||||
`, | |||||
), | |||||
); | |||||
export const MoreToggleSidebarMenuItem = () => css.cx( | |||||
css` | |||||
width: 0; | |||||
flex: auto; | |||||
height: var(--size-menu, 4rem); | |||||
> * { | |||||
height: 100%; | |||||
display: flex; | |||||
align-items: center; | |||||
text-decoration: none; | |||||
width: 100%; | |||||
} | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
display: none; | |||||
`, | |||||
), | |||||
); | |||||
export const SidebarMenuItemIcon = () => css.cx( | |||||
css` | |||||
display: block; | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
width: var(--size-menu, 4rem); | |||||
height: var(--size-menu, 4rem); | |||||
display: grid; | |||||
place-content: center; | |||||
`, | |||||
), | |||||
); | |||||
export const MoreSidebarMenuItemIcon = () => css.cx( | |||||
css` | |||||
margin-right: 1rem; | |||||
display: block; | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
width: var(--size-menu, 4rem); | |||||
height: var(--size-menu, 4rem); | |||||
display: grid; | |||||
place-content: center; | |||||
margin-right: 0; | |||||
`, | |||||
), | |||||
); | |||||
export const SidebarMenuContainer = () => css.cx( | |||||
css` | |||||
box-sizing: border-box; | |||||
display: grid; | |||||
place-content: center; | |||||
width: 100%; | |||||
text-align: center; | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
display: flex; | |||||
justify-content: flex-start; | |||||
align-items: center; | |||||
margin-left: auto; | |||||
padding-right: 1rem; | |||||
text-align: left; | |||||
box-sizing: border-box; | |||||
width: var(--base-width); | |||||
`, | |||||
), | |||||
) | |||||
export const MoreSidebarMenuContainer = () => css.cx( | |||||
css` | |||||
display: flex; | |||||
justify-content: flex-start; | |||||
align-items: center; | |||||
width: calc(var(--base-width) * 2); | |||||
margin: 0 auto; | |||||
padding: 0 1rem; | |||||
text-align: left; | |||||
box-sizing: border-box; | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
margin-right: 0; | |||||
width: var(--base-width); | |||||
padding-left: 0; | |||||
`, | |||||
), | |||||
); | |||||
export const ContentContainer = () => css.cx( | |||||
css` | |||||
padding: 0 1rem; | |||||
box-sizing: border-box; | |||||
width: 100%; | |||||
max-width: calc(var(--base-width) * 2); | |||||
margin-right: auto; | |||||
margin-left: auto; | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
margin-left: 0; | |||||
`, | |||||
), | |||||
); | |||||
export const SidebarMainContainer = () => css.cx( | |||||
css` | |||||
padding: 0 1rem; | |||||
box-sizing: border-box; | |||||
width: 100%; | |||||
max-width: calc(var(--base-width) * 2); | |||||
margin: 0 auto; | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
max-width: none; | |||||
`, | |||||
), | |||||
); |
@@ -1,83 +0,0 @@ | |||||
import { css } from '@tesseract-design/goofy-goober'; | |||||
export const ContentBase = () => css.cx( | |||||
css` | |||||
box-sizing: border-box; | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
padding-right: calc(50% - (var(--base-width) * 0.5)); | |||||
` | |||||
), | |||||
); | |||||
export const SidebarBase = () => css.cx( | |||||
css` | |||||
box-sizing: border-box; | |||||
background-color: var(--color-background, white); | |||||
`, | |||||
// prevent collapse of margin | |||||
css` | |||||
&::after { | |||||
content: ''; | |||||
display: block; | |||||
padding-bottom: 1px; | |||||
margin-top: -1px; | |||||
box-sizing: border-box; | |||||
} | |||||
& > * { | |||||
display: block; | |||||
width: 100%; | |||||
height: 100%; | |||||
} | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
position: absolute; | |||||
top: 0; | |||||
right: 0; | |||||
width: calc(50% - var(--base-width) * 0.5); | |||||
height: 100%; | |||||
`, | |||||
), | |||||
) | |||||
export const SidebarMainContent = () => css.cx( | |||||
css` | |||||
position: relative; | |||||
z-index: 1; | |||||
` | |||||
) | |||||
export const SidebarMainContainer = () => css.cx( | |||||
css` | |||||
padding: 0 1rem; | |||||
box-sizing: border-box; | |||||
width: 100%; | |||||
max-width: calc(var(--base-width) * 2); | |||||
margin: 0 auto; | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
margin-left: 0; | |||||
width: var(--base-width); | |||||
`, | |||||
), | |||||
) | |||||
export const ContentContainer = () => css.cx( | |||||
css` | |||||
padding: 0 1rem; | |||||
box-sizing: border-box; | |||||
width: 100%; | |||||
max-width: calc(var(--base-width) * 2); | |||||
margin: 0 auto; | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
margin-right: 0; | |||||
`, | |||||
), | |||||
) | |||||
// TODO port from original viewfinder package |
@@ -1,4 +0,0 @@ | |||||
export * as Basic from './Basic'; | |||||
export * as LeftSidebar from './LeftSidebar'; | |||||
export * as LeftSidebarWithMenu from './LeftSidebarWithMenu'; | |||||
export * as RightSidebarStatic from './RightSidebarStatic'; |
@@ -0,0 +1,138 @@ | |||||
import tailwindPlugin from 'tailwindcss/plugin'; | |||||
export interface ViewfinderPluginOptions { | |||||
baseWidth?: number; | |||||
topbarHeight?: string; | |||||
sizeMenu?: string; | |||||
colorBackground?: string; | |||||
} | |||||
export const plugin = tailwindPlugin.withOptions<ViewfinderPluginOptions>( | |||||
({ | |||||
baseWidth = 360 as const, | |||||
topbarHeight = '4rem' as const, | |||||
sizeMenu = topbarHeight, | |||||
colorBackground = '255 255 255' as const, | |||||
} = {} as ViewfinderPluginOptions) => ({ | |||||
addBase, | |||||
addComponents, | |||||
addUtilities, | |||||
}) => { | |||||
addBase({ | |||||
':root': { | |||||
'--base-width': `${baseWidth}px`, | |||||
'--height-topbar': topbarHeight, | |||||
'--size-menu': sizeMenu, | |||||
'--color-background': colorBackground, | |||||
}, | |||||
}); | |||||
addBase({ | |||||
':root': { | |||||
'background-color': 'rgb(var(--color-background))', | |||||
}, | |||||
}); | |||||
addComponents({ | |||||
'.topbar': { | |||||
height: 'var(--height-topbar, 4rem)', | |||||
'& ~ *': { | |||||
'padding-top': 'var(--height-topbar, 4rem)', | |||||
}, | |||||
'& ~ [data-viewfinder="main"] ~ *': { | |||||
'padding-top': '0', | |||||
}, | |||||
'& [data-viewfinder="menu"] > *': { | |||||
'width': '100%', | |||||
'height': '100%', | |||||
'display': 'grid', | |||||
'place-content': 'center', | |||||
}, | |||||
'& [data-viewfinder="user"] > *': { | |||||
'width': '100%', | |||||
'height': '100%', | |||||
'display': 'grid', | |||||
'place-content': 'center', | |||||
}, | |||||
[`@media (min-width: ${baseWidth * 3}px)`]: { | |||||
'& ~ [data-viewfinder="main"] ~ *': { | |||||
'padding-top': 'var(--height-topbar, 4rem)', | |||||
}, | |||||
'& [data-viewfinder="menu"] > *': { | |||||
'position': 'absolute', | |||||
'left': '-999999px', | |||||
}, | |||||
'& [data-viewfinder="menu"] > *:focus': { | |||||
'position': 'static', | |||||
}, | |||||
}, | |||||
}, | |||||
}); | |||||
addUtilities({ | |||||
'.scrollbar-hidden': { | |||||
'scrollbar-width': 'none', | |||||
'&::-webkit-scrollbar': { | |||||
'display': 'none', | |||||
}, | |||||
}, | |||||
}); | |||||
addComponents({ | |||||
'.left-sidebar-with-menu-base': { | |||||
'& [data-viewfinder="menu-item"] > *': { | |||||
'height': '100%', | |||||
'display': 'flex', | |||||
'align-items': 'center', | |||||
'text-decoration': 'none', | |||||
'width': '100%', | |||||
}, | |||||
[`@media (min-width: ${baseWidth * 3}px)`]: { | |||||
'& [data-viewfinder="menu-item"]': { | |||||
'width': 'auto !important', | |||||
}, | |||||
'& [data-viewfinder="menu-item"] > *': { | |||||
'height': 'auto', | |||||
}, | |||||
}, | |||||
}, | |||||
}); | |||||
}, | |||||
({ | |||||
baseWidth = 360 as const, | |||||
} = {} as ViewfinderPluginOptions) => ({ | |||||
theme: { | |||||
screens: { | |||||
'3xs': `${baseWidth}px`, | |||||
'2xs': `${baseWidth * 1.5}px`, | |||||
xs: `${baseWidth * 2}px`, | |||||
sm: `${baseWidth * 2.5}px`, | |||||
md: `${baseWidth * 3}px`, | |||||
lg: `${baseWidth * 4}px`, | |||||
xl: `${baseWidth * 5}px`, | |||||
'2xl': `${baseWidth * 6}px`, | |||||
'3xl': `${baseWidth * 7}px`, | |||||
}, | |||||
extend: { | |||||
colors: { | |||||
bg: 'rgb(var(--color-background))', | |||||
}, | |||||
spacing: { | |||||
topbar: 'var(--height-topbar, 4rem)', | |||||
menu: 'var(--size-menu, var(--height-topbar, 4rem))', | |||||
inherit: 'inherit', | |||||
}, | |||||
maxWidth: { | |||||
'screen-3xs': `${baseWidth}px`, | |||||
'screen-2xs': `${baseWidth * 1.5}px`, | |||||
'screen-xs': `${baseWidth * 2}px`, | |||||
'screen-sm': `${baseWidth * 2.5}px`, | |||||
'screen-md': `${baseWidth * 3}px`, | |||||
'screen-lg': `${baseWidth * 4}px`, | |||||
'screen-xl': `${baseWidth * 5}px`, | |||||
'screen-2xl': `${baseWidth * 6}px`, | |||||
'screen-3xl': `${baseWidth * 7}px`, | |||||
}, | |||||
minWidth: { | |||||
32: '8rem', | |||||
}, | |||||
}, | |||||
}, | |||||
}), | |||||
); |
@@ -1,125 +0,0 @@ | |||||
import { css } from '@tesseract-design/goofy-goober'; | |||||
import {LayoutArgs, Span} from '../common'; | |||||
export const Base = () => css.cx( | |||||
css` | |||||
position: fixed; | |||||
top: 0; | |||||
left: 0; | |||||
width: 100%; | |||||
height: var(--height-topbar, 4rem); | |||||
z-index: 3; | |||||
& > * { | |||||
display: block; | |||||
width: 100%; | |||||
height: 100%; | |||||
background-color: var(--color-background, white); | |||||
} | |||||
& ~ * { | |||||
padding-top: var(--height-topbar, 4rem); | |||||
} | |||||
~ main ~ * { | |||||
padding-top: 0; | |||||
} | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
~ main ~ * { | |||||
padding-top: var(--height-topbar, 4rem); | |||||
} | |||||
` | |||||
) | |||||
); | |||||
export const Container = ({ | |||||
span, | |||||
}: LayoutArgs) => css.cx( | |||||
css` | |||||
padding: 0 1rem; | |||||
box-sizing: border-box; | |||||
margin: 0 auto; | |||||
width: 100%; | |||||
height: 100%; | |||||
display: flex; | |||||
align-items: center; | |||||
position: relative; | |||||
z-index: 1; | |||||
`, | |||||
css.if(span === Span.NARROW)( | |||||
css` | |||||
max-width: var(--base-width); | |||||
` | |||||
), | |||||
css.if(span === Span.NORMAL)( | |||||
css` | |||||
max-width: calc(var(--base-width) * 2); | |||||
` | |||||
), | |||||
css.if(span === Span.WIDE)( | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
max-width: calc(var(--base-width) * 3); | |||||
` | |||||
) | |||||
), | |||||
); | |||||
export const CenterContainer = () => css.cx( | |||||
css` | |||||
flex: auto; | |||||
padding: 0 1rem; | |||||
box-sizing: border-box; | |||||
`, | |||||
css.nest(':first-child')( | |||||
css` | |||||
padding-left: 0; | |||||
` | |||||
) | |||||
) | |||||
export const ActionContainer = () => css.cx( | |||||
css` | |||||
display: flex; | |||||
align-items: center; | |||||
justify-content: flex-end; | |||||
height: 100%; | |||||
white-space: nowrap; | |||||
`, | |||||
css.media('(min-width: 720px)')( | |||||
css` | |||||
min-width: 8rem; | |||||
` | |||||
) | |||||
); | |||||
export const LinkContainer = () => css.cx( | |||||
css` | |||||
width: var(--height-topbar, 4rem); | |||||
height: 100%; | |||||
& > * { | |||||
width: 100%; | |||||
height: 100%; | |||||
display: inline-grid; | |||||
place-content: center; | |||||
} | |||||
` | |||||
); | |||||
export const MenuLinkContainer = () => css.cx( | |||||
css` | |||||
width: var(--height-topbar, 4rem); | |||||
height: 100%; | |||||
& > * { | |||||
width: 100%; | |||||
height: 100%; | |||||
display: inline-grid; | |||||
place-content: center; | |||||
} | |||||
`, | |||||
css.media('(min-width: 1080px)')( | |||||
css` | |||||
position: absolute; | |||||
left: -999999px; | |||||
` | |||||
) | |||||
); |
@@ -1 +0,0 @@ | |||||
export * as TopBar from './TopBar'; |
@@ -1,3 +1,6 @@ | |||||
{ | { | ||||
"extends": "next/core-web-vitals" | |||||
"extends": "next/core-web-vitals", | |||||
"rules": { | |||||
"@next/next/no-html-link-for-pages": "off" | |||||
} | |||||
} | } |
@@ -2,6 +2,9 @@ | |||||
const nextConfig = { | const nextConfig = { | ||||
reactStrictMode: true, | reactStrictMode: true, | ||||
swcMinify: true, | swcMinify: true, | ||||
experimental: { | |||||
optimizeCss: true, | |||||
}, | |||||
} | } | ||||
module.exports = nextConfig | module.exports = nextConfig |
@@ -9,8 +9,8 @@ | |||||
"lint": "next lint" | "lint": "next lint" | ||||
}, | }, | ||||
"dependencies": { | "dependencies": { | ||||
"@tesseract-design/viewfinder-react": "link:../../react", | |||||
"goober": "^2.1.12", | |||||
"@tesseract-design/viewfinder-base": "workspace:*", | |||||
"@tesseract-design/viewfinder-react": "workspace:*", | |||||
"next": "12.2.4", | "next": "12.2.4", | ||||
"react": "18.2.0", | "react": "18.2.0", | ||||
"react-dom": "18.2.0", | "react-dom": "18.2.0", | ||||
@@ -20,8 +20,12 @@ | |||||
"@types/node": "18.6.4", | "@types/node": "18.6.4", | ||||
"@types/react": "18.0.15", | "@types/react": "18.0.15", | ||||
"@types/react-dom": "18.0.6", | "@types/react-dom": "18.0.6", | ||||
"autoprefixer": "^10.4.14", | |||||
"critters": "^0.0.19", | |||||
"eslint": "8.21.0", | "eslint": "8.21.0", | ||||
"eslint-config-next": "12.2.4", | "eslint-config-next": "12.2.4", | ||||
"postcss": "^8.4.27", | |||||
"tailwindcss": "^3.3.3", | |||||
"typescript": "4.7.4" | "typescript": "4.7.4" | ||||
} | } | ||||
} | } |
@@ -0,0 +1,6 @@ | |||||
module.exports = { | |||||
plugins: { | |||||
tailwindcss: {}, | |||||
autoprefixer: {}, | |||||
}, | |||||
} |
@@ -1,9 +1,11 @@ | |||||
import type { AppProps } from 'next/app' | import type { AppProps } from 'next/app' | ||||
import { setup } from '@tesseract-design/viewfinder-react'; | |||||
import * as gooberPrefixer from 'goober/prefixer'; | |||||
// import { setup } from '@tesseract-design/viewfinder-react'; | |||||
// import * as gooberPrefixer from 'goober/prefixer'; | |||||
import * as React from 'react'; | import * as React from 'react'; | ||||
setup(React.createElement, gooberPrefixer.prefix); | |||||
import '../tailwind.css'; | |||||
// setup(React.createElement, gooberPrefixer.prefix); | |||||
const MyApp: React.FC<AppProps> = ({ Component, pageProps }) => <Component {...pageProps} /> | const MyApp: React.FC<AppProps> = ({ Component, pageProps }) => <Component {...pageProps} /> | ||||
@@ -1,89 +0,0 @@ | |||||
import NextDocument, {Html, Head as NextHead, Main, NextScript, DocumentContext} from 'next/document'; | |||||
import { extractCss } from '@tesseract-design/viewfinder-react'; | |||||
export default class Document extends NextDocument { | |||||
static async getInitialProps(ctx: DocumentContext) { | |||||
const page = await ctx.renderPage() | |||||
const style = extractCss(); | |||||
const initialProps = await NextDocument.getInitialProps(ctx) | |||||
return { | |||||
...initialProps, | |||||
...page, | |||||
style, | |||||
} | |||||
} | |||||
render() { | |||||
const { style: rawStyle } = this.props as Record<string, unknown> | |||||
const style = rawStyle as string | |||||
return ( | |||||
<Html> | |||||
<NextHead> | |||||
{ | |||||
style.length > 0 | |||||
&& ( | |||||
<style | |||||
id="_goober_ssr" | |||||
dangerouslySetInnerHTML={{ __html: style }} | |||||
/> | |||||
) | |||||
} | |||||
<style> | |||||
{` | |||||
:root { | |||||
--base-width: 360px; | |||||
--color-background: white; | |||||
} | |||||
html, | |||||
body { | |||||
padding: 0; | |||||
margin: 0; | |||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, | |||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; | |||||
line-height: 1.75; | |||||
} | |||||
a { | |||||
color: inherit; | |||||
text-decoration: none; | |||||
} | |||||
* { | |||||
box-sizing: border-box; | |||||
} | |||||
@media (prefers-color-scheme: dark) { | |||||
:root { | |||||
--color-background: black; | |||||
} | |||||
html { | |||||
color-scheme: dark; | |||||
} | |||||
body { | |||||
color: white; | |||||
background-color: var(--color-background); | |||||
} | |||||
} | |||||
#__next { | |||||
display: contents; | |||||
background-color: inherit; | |||||
} | |||||
`} | |||||
</style> | |||||
</NextHead> | |||||
<body> | |||||
<Main /> | |||||
<NextScript /> | |||||
</body> | |||||
</Html> | |||||
) | |||||
} | |||||
} |
@@ -1,13 +1,12 @@ | |||||
import type {GetServerSideProps, NextPage} from 'next'; | import type {GetServerSideProps, NextPage} from 'next'; | ||||
import ReactMarkdown from 'react-markdown'; | import ReactMarkdown from 'react-markdown'; | ||||
import { Layouts, Widgets } from '@tesseract-design/viewfinder-react'; | import { Layouts, Widgets } from '@tesseract-design/viewfinder-react'; | ||||
import {Span} from '@tesseract-design/viewfinder-base'; | |||||
import {Brand} from '../../components/Brand'; | import {Brand} from '../../components/Brand'; | ||||
import {Image} from '../../components/Image'; | import {Image} from '../../components/Image'; | ||||
import Link from 'next/link'; | import Link from 'next/link'; | ||||
type BaseLayoutPageProps = { | type BaseLayoutPageProps = { | ||||
span: Span; | |||||
span: 'narrow' | 'normal' | 'wide'; | |||||
} | } | ||||
const BasicLayoutPage: NextPage<BaseLayoutPageProps> = ({ | const BasicLayoutPage: NextPage<BaseLayoutPageProps> = ({ | ||||
@@ -20,7 +19,7 @@ const BasicLayoutPage: NextPage<BaseLayoutPageProps> = ({ | |||||
brand={ | brand={ | ||||
<Brand /> | <Brand /> | ||||
} | } | ||||
span={span as Span} | |||||
span={span} | |||||
userLink={ | userLink={ | ||||
<Link | <Link | ||||
href={{ | href={{ | ||||
@@ -36,7 +35,7 @@ const BasicLayoutPage: NextPage<BaseLayoutPageProps> = ({ | |||||
} | } | ||||
> | > | ||||
<Layouts.Basic.ContentContainer | <Layouts.Basic.ContentContainer | ||||
span={span as Span} | |||||
span={span} | |||||
> | > | ||||
<ReactMarkdown | <ReactMarkdown | ||||
components={{ | components={{ | ||||
@@ -75,7 +74,7 @@ export default BasicLayoutPage | |||||
export const getServerSideProps: GetServerSideProps = async (ctx) => { | export const getServerSideProps: GetServerSideProps = async (ctx) => { | ||||
return { | return { | ||||
props: { | props: { | ||||
span: ctx.query.span ?? Span.NORMAL, | |||||
span: ctx.query.span ?? 'normal', | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -68,7 +68,7 @@ const LeftSidebarWithMenuLayoutPage: NextPage<LeftSidebarWithMenuLayoutPageProps | |||||
<Layouts.LeftSidebarWithMenu.Root | <Layouts.LeftSidebarWithMenu.Root | ||||
sidebarBaseWidget={ | sidebarBaseWidget={ | ||||
<Widgets.LeftSidebarWithMenuBase | <Widgets.LeftSidebarWithMenuBase | ||||
span={Span.WIDE} | |||||
span="wide" | |||||
open={sidebarOpen} | open={sidebarOpen} | ||||
moreItemsOpen={moreItemsOpen} | moreItemsOpen={moreItemsOpen} | ||||
items={[ | items={[ | ||||
@@ -188,7 +188,7 @@ const LeftSidebarWithMenuLayoutPage: NextPage<LeftSidebarWithMenuLayoutPageProps | |||||
User | User | ||||
</Link> | </Link> | ||||
} | } | ||||
span={Span.WIDE} | |||||
span="wide" | |||||
/> | /> | ||||
} | } | ||||
> | > | ||||
@@ -1,6 +1,5 @@ | |||||
import type { NextPage } from 'next' | import type { NextPage } from 'next' | ||||
import { Layouts, Widgets } from '@tesseract-design/viewfinder-react'; | import { Layouts, Widgets } from '@tesseract-design/viewfinder-react'; | ||||
import {Span} from '@tesseract-design/viewfinder-base'; | |||||
import Link from 'next/link'; | import Link from 'next/link'; | ||||
import {Brand} from '../../components/Brand'; | import {Brand} from '../../components/Brand'; | ||||
import {Image} from '../../components/Image'; | import {Image} from '../../components/Image'; | ||||
@@ -20,7 +19,6 @@ const LeftSidebarLayoutPage: NextPage<LeftSidebarLayoutPageProps> = ({ | |||||
<Layouts.LeftSidebar.Root | <Layouts.LeftSidebar.Root | ||||
sidebarBaseWidget={ | sidebarBaseWidget={ | ||||
<Widgets.LeftSidebarBase | <Widgets.LeftSidebarBase | ||||
span={Span.WIDE} | |||||
open={sidebarOpen} | open={sidebarOpen} | ||||
> | > | ||||
<a | <a | ||||
@@ -74,7 +72,7 @@ const LeftSidebarLayoutPage: NextPage<LeftSidebarLayoutPageProps> = ({ | |||||
}, | }, | ||||
}} | }} | ||||
> | > | ||||
Menu | |||||
Menu | |||||
</Link> | </Link> | ||||
} | } | ||||
userLink={ | userLink={ | ||||
@@ -85,10 +83,10 @@ const LeftSidebarLayoutPage: NextPage<LeftSidebarLayoutPageProps> = ({ | |||||
}, | }, | ||||
}} | }} | ||||
> | > | ||||
User | |||||
User | |||||
</Link> | </Link> | ||||
} | } | ||||
span={Span.WIDE} | |||||
span="wide" | |||||
/> | /> | ||||
} | } | ||||
> | > | ||||
@@ -1,6 +1,5 @@ | |||||
import type { NextPage } from 'next' | import type { NextPage } from 'next' | ||||
import { Layouts, Widgets } from '@tesseract-design/viewfinder-react'; | import { Layouts, Widgets } from '@tesseract-design/viewfinder-react'; | ||||
import {Span} from '@tesseract-design/viewfinder-base'; | |||||
import Link from 'next/link'; | import Link from 'next/link'; | ||||
import {Brand} from '../../../components/Brand'; | import {Brand} from '../../../components/Brand'; | ||||
import {GetServerSideProps} from 'next'; | import {GetServerSideProps} from 'next'; | ||||
@@ -68,7 +67,7 @@ const LeftSidebarWithMenuLayoutPage: NextPage<LeftSidebarWithMenuLayoutPageProps | |||||
<Layouts.LeftSidebarWithMenu.Root | <Layouts.LeftSidebarWithMenu.Root | ||||
sidebarBaseWidget={ | sidebarBaseWidget={ | ||||
<Widgets.LeftSidebarWithMenuBase | <Widgets.LeftSidebarWithMenuBase | ||||
span={Span.WIDE} | |||||
span="wide" | |||||
open={sidebarOpen} | open={sidebarOpen} | ||||
moreItemsOpen={moreItemsOpen} | moreItemsOpen={moreItemsOpen} | ||||
items={[ | items={[ | ||||
@@ -151,7 +150,7 @@ const LeftSidebarWithMenuLayoutPage: NextPage<LeftSidebarWithMenuLayoutPageProps | |||||
User | User | ||||
</Link> | </Link> | ||||
} | } | ||||
span={Span.WIDE} | |||||
span="wide" | |||||
/> | /> | ||||
} | } | ||||
> | > | ||||
@@ -1,6 +1,5 @@ | |||||
import type { NextPage } from 'next' | import type { NextPage } from 'next' | ||||
import { Layouts, Widgets } from '@tesseract-design/viewfinder-react'; | import { Layouts, Widgets } from '@tesseract-design/viewfinder-react'; | ||||
import {Span} from '@tesseract-design/viewfinder-base'; | |||||
import {Brand} from '../../components/Brand'; | import {Brand} from '../../components/Brand'; | ||||
import {Image} from '../../components/Image'; | import {Image} from '../../components/Image'; | ||||
import ReactMarkdown from 'react-markdown'; | import ReactMarkdown from 'react-markdown'; | ||||
@@ -10,9 +9,7 @@ const RightSidebarStaticLayoutPage: NextPage = () => { | |||||
return ( | return ( | ||||
<Layouts.RightSidebarStatic.Root | <Layouts.RightSidebarStatic.Root | ||||
sidebarBaseWidget={ | sidebarBaseWidget={ | ||||
<Widgets.RightSidebarStaticBase | |||||
span={Span.WIDE} | |||||
> | |||||
<Widgets.RightSidebarStaticBase> | |||||
<a | <a | ||||
href="#foo" | href="#foo" | ||||
style={{ | style={{ | ||||
@@ -67,7 +64,7 @@ const RightSidebarStaticLayoutPage: NextPage = () => { | |||||
User | User | ||||
</Link> | </Link> | ||||
} | } | ||||
span={Span.WIDE} | |||||
span="wide" | |||||
/> | /> | ||||
} | } | ||||
> | > | ||||
@@ -0,0 +1,3 @@ | |||||
@tailwind base; | |||||
@tailwind components; | |||||
@tailwind utilities; |
@@ -0,0 +1,14 @@ | |||||
const { tailwind } = require('@tesseract-design/viewfinder-base'); | |||||
const { plugin: viewfinderPlugin } = tailwind; | |||||
/** @type {import('tailwindcss').Config} */ | |||||
module.exports = { | |||||
content: [ | |||||
'./src/components/**/*.tsx', | |||||
'./src/pages/**/*.tsx', | |||||
'./node_modules/@tesseract-design/viewfinder-react/dist/**/*.js', | |||||
], | |||||
plugins: [ | |||||
viewfinderPlugin(), | |||||
], | |||||
} |
@@ -13,7 +13,8 @@ | |||||
"pridepack" | "pridepack" | ||||
], | ], | ||||
"dependencies": { | "dependencies": { | ||||
"@tesseract-design/viewfinder-base": "link:../base" | |||||
"@tesseract-design/viewfinder-base": "workspace:*", | |||||
"clsx": "^2.0.0" | |||||
}, | }, | ||||
"devDependencies": { | "devDependencies": { | ||||
"@testing-library/jest-dom": "^5.16.4", | "@testing-library/jest-dom": "^5.16.4", | ||||
@@ -1,3 +1,2 @@ | |||||
export * as Layouts from './layouts'; | export * as Layouts from './layouts'; | ||||
export * as Widgets from './widgets'; | export * as Widgets from './widgets'; | ||||
export { setup, extractCss } from '@tesseract-design/viewfinder-base'; |
@@ -1,7 +1,8 @@ | |||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import {LayoutArgs, layouts, Span} from '@tesseract-design/viewfinder-base'; | |||||
import clsx from 'clsx'; | |||||
import { SpanValues as Span } from '@tesseract-design/viewfinder-base'; | |||||
export type RootProps = React.HTMLProps<HTMLDivElement> & { | |||||
export interface RootProps extends React.HTMLProps<HTMLDivElement> { | |||||
topBarWidget?: React.ReactNode; | topBarWidget?: React.ReactNode; | ||||
} | } | ||||
@@ -12,13 +13,14 @@ export const Root = React.forwardRef<HTMLDivElement, RootProps>(({ | |||||
}, ref) => ( | }, ref) => ( | ||||
<> | <> | ||||
{topBarWidget} | {topBarWidget} | ||||
<main | |||||
<div | |||||
{...etcProps} | {...etcProps} | ||||
className={layouts.Basic.ContentBase()} | |||||
data-viewfinder="main" | |||||
className="box-border" | |||||
ref={ref} | ref={ref} | ||||
> | > | ||||
{children} | {children} | ||||
</main> | |||||
</div> | |||||
</> | </> | ||||
)); | )); | ||||
@@ -30,22 +32,21 @@ export type ContentContainerProps = Omit<React.HTMLProps<HTMLDivElement>, 'span' | |||||
export const ContentContainer = React.forwardRef<HTMLDivElement, ContentContainerProps>(({ | export const ContentContainer = React.forwardRef<HTMLDivElement, ContentContainerProps>(({ | ||||
children, | children, | ||||
span = Span.NORMAL, | |||||
span = 'normal', | |||||
}, ref) => { | }, ref) => { | ||||
const args: LayoutArgs = { | |||||
span, | |||||
mainSidebarOpen: false, | |||||
auxiliaryItemsShown: false, | |||||
}; | |||||
return ( | return ( | ||||
<div | <div | ||||
className={layouts.Basic.ContentContainer(args)} | |||||
className={clsx( | |||||
'px-8 box-border mx-auto w-full', | |||||
span === 'narrow' && 'max-w-screen-2xs', | |||||
span === 'normal' && 'max-w-screen-xs', | |||||
span === 'wide' && 'max-w-screen-sm', | |||||
)} | |||||
ref={ref} | ref={ref} | ||||
> | > | ||||
{children} | {children} | ||||
</div> | </div> | ||||
) | |||||
); | |||||
}); | }); | ||||
ContentContainer.displayName = 'ContentContainer' | ContentContainer.displayName = 'ContentContainer' |
@@ -1,10 +1,9 @@ | |||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import {layouts} from '@tesseract-design/viewfinder-base'; | |||||
export type RootProps = React.HTMLProps<HTMLDivElement> & { | |||||
export interface RootProps extends React.HTMLProps<HTMLDivElement> { | |||||
sidebarBaseWidget?: React.ReactNode; | sidebarBaseWidget?: React.ReactNode; | ||||
topBarWidget?: React.ReactNode; | topBarWidget?: React.ReactNode; | ||||
}; | |||||
} | |||||
export const Root = React.forwardRef<HTMLDivElement, RootProps>(({ | export const Root = React.forwardRef<HTMLDivElement, RootProps>(({ | ||||
children, | children, | ||||
@@ -15,23 +14,24 @@ export const Root = React.forwardRef<HTMLDivElement, RootProps>(({ | |||||
<> | <> | ||||
{topBarWidget} | {topBarWidget} | ||||
{sidebarBaseWidget} | {sidebarBaseWidget} | ||||
<main | |||||
<div | |||||
{...etcProps} | {...etcProps} | ||||
ref={ref} | ref={ref} | ||||
className={layouts.LeftSidebar.ContentBase()} | |||||
data-viewfinder="main" | |||||
className="box-border md:pl-[calc(50%-(var(--base-width)*0.5))]" | |||||
> | > | ||||
{children} | {children} | ||||
</main> | |||||
</div> | |||||
</> | </> | ||||
)); | )); | ||||
export type ContentContainerProps = React.HTMLProps<HTMLDivElement> | |||||
export interface ContentContainerProps extends React.HTMLProps<HTMLDivElement> {} | |||||
export const MainContentContainer = React.forwardRef<HTMLDivElement, ContentContainerProps>(({ | export const MainContentContainer = React.forwardRef<HTMLDivElement, ContentContainerProps>(({ | ||||
children, | children, | ||||
}, ref) => ( | }, ref) => ( | ||||
<div | <div | ||||
className={layouts.LeftSidebar.ContentContainer()} | |||||
className="px-8 box-border w-full max-w-[calc(var(--base-width)*2)] mx-auto md:ml-0" | |||||
ref={ref} | ref={ref} | ||||
> | > | ||||
{children} | {children} | ||||
@@ -40,7 +40,7 @@ export const MainContentContainer = React.forwardRef<HTMLDivElement, ContentCont | |||||
MainContentContainer.displayName = 'MainContentContainer' | MainContentContainer.displayName = 'MainContentContainer' | ||||
export type SidebarMainContainerProps = React.HTMLProps<HTMLDivElement> | |||||
export interface SidebarMainContainerProps extends React.HTMLProps<HTMLDivElement> {} | |||||
export const SidebarContentContainer = React.forwardRef<HTMLDivElement, SidebarMainContainerProps>(({ | export const SidebarContentContainer = React.forwardRef<HTMLDivElement, SidebarMainContainerProps>(({ | ||||
children, | children, | ||||
@@ -48,7 +48,7 @@ export const SidebarContentContainer = React.forwardRef<HTMLDivElement, SidebarM | |||||
}, ref) => ( | }, ref) => ( | ||||
<div | <div | ||||
{...etcProps} | {...etcProps} | ||||
className={layouts.LeftSidebar.SidebarMainContainer()} | |||||
className="w-full mx-auto px-8 box-border max-w-[calc(var(--base-width)*2)] md:w-[var(--base-width)] md:mr-0" | |||||
ref={ref} | ref={ref} | ||||
> | > | ||||
{children} | {children} | ||||
@@ -1,7 +1,6 @@ | |||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import {layouts} from '@tesseract-design/viewfinder-base'; | |||||
export type RootProps = React.HTMLProps<HTMLDivElement> & { | |||||
export interface RootProps extends React.HTMLProps<HTMLDivElement> { | |||||
sidebarBaseWidget?: React.ReactNode; | sidebarBaseWidget?: React.ReactNode; | ||||
topBarWidget?: React.ReactNode; | topBarWidget?: React.ReactNode; | ||||
}; | }; | ||||
@@ -15,23 +14,24 @@ export const Root = React.forwardRef<HTMLDivElement, RootProps>(({ | |||||
<> | <> | ||||
{topBarWidget} | {topBarWidget} | ||||
{sidebarBaseWidget} | {sidebarBaseWidget} | ||||
<main | |||||
<div | |||||
{...etcProps} | {...etcProps} | ||||
ref={ref} | ref={ref} | ||||
className={layouts.LeftSidebarWithMenu.ContentBase()} | |||||
data-viewfinder="main" | |||||
className="box-border pb-menu md:pb-0 md:pl-[calc(50%-(var(--base-width)*0.5))]" | |||||
> | > | ||||
{children} | {children} | ||||
</main> | |||||
</div> | |||||
</> | </> | ||||
)); | )); | ||||
export type ContentContainerProps = React.HTMLProps<HTMLDivElement> | |||||
export interface ContentContainerProps extends React.HTMLProps<HTMLDivElement> {} | |||||
export const MainContentContainer = React.forwardRef<HTMLDivElement, ContentContainerProps>(({ | export const MainContentContainer = React.forwardRef<HTMLDivElement, ContentContainerProps>(({ | ||||
children, | children, | ||||
}, ref) => ( | }, ref) => ( | ||||
<div | <div | ||||
className={layouts.LeftSidebarWithMenu.ContentContainer()} | |||||
className="px-8 box-border w-full max-w-[calc(var(--base-width)*2)] mx-auto md:ml-0" | |||||
ref={ref} | ref={ref} | ||||
> | > | ||||
{children} | {children} | ||||
@@ -40,7 +40,7 @@ export const MainContentContainer = React.forwardRef<HTMLDivElement, ContentCont | |||||
MainContentContainer.displayName = 'MainContentContainer' | MainContentContainer.displayName = 'MainContentContainer' | ||||
export type SidebarMainContainerProps = React.HTMLProps<HTMLDivElement> | |||||
export interface SidebarMainContainerProps extends React.HTMLProps<HTMLDivElement> {} | |||||
export const SidebarContentContainer = React.forwardRef<HTMLDivElement, SidebarMainContainerProps>(({ | export const SidebarContentContainer = React.forwardRef<HTMLDivElement, SidebarMainContainerProps>(({ | ||||
children, | children, | ||||
@@ -48,7 +48,7 @@ export const SidebarContentContainer = React.forwardRef<HTMLDivElement, SidebarM | |||||
}, ref) => ( | }, ref) => ( | ||||
<div | <div | ||||
{...etcProps} | {...etcProps} | ||||
className={layouts.LeftSidebarWithMenu.SidebarMainContainer()} | |||||
className="px-8 box-border w-full max-w-[calc(var(--base-width)*2)] mx-auto md:max-w-none" | |||||
ref={ref} | ref={ref} | ||||
> | > | ||||
{children} | {children} | ||||
@@ -57,7 +57,7 @@ export const SidebarContentContainer = React.forwardRef<HTMLDivElement, SidebarM | |||||
SidebarContentContainer.displayName = 'SidebarMainContainer'; | SidebarContentContainer.displayName = 'SidebarMainContainer'; | ||||
export type SidebarMenuItemIconProps = React.HTMLProps<HTMLSpanElement> | |||||
export interface SidebarMenuItemIconProps extends React.HTMLProps<HTMLSpanElement> {} | |||||
export const SidebarMenuItemIcon = React.forwardRef<HTMLSpanElement, SidebarMenuItemIconProps>(({ | export const SidebarMenuItemIcon = React.forwardRef<HTMLSpanElement, SidebarMenuItemIconProps>(({ | ||||
children, | children, | ||||
@@ -65,7 +65,7 @@ export const SidebarMenuItemIcon = React.forwardRef<HTMLSpanElement, SidebarMenu | |||||
}, ref) => ( | }, ref) => ( | ||||
<span | <span | ||||
{...etcProps} | {...etcProps} | ||||
className={layouts.LeftSidebarWithMenu.SidebarMenuItemIcon()} | |||||
className="block md:w-menu md:h-menu md:flex md:justify-center md:items-center" | |||||
ref={ref} | ref={ref} | ||||
> | > | ||||
{children} | {children} | ||||
@@ -80,7 +80,7 @@ export const SidebarMenuContainer = React.forwardRef<HTMLSpanElement, SidebarMai | |||||
}, ref) => ( | }, ref) => ( | ||||
<span | <span | ||||
{...etcProps} | {...etcProps} | ||||
className={layouts.LeftSidebarWithMenu.SidebarMenuContainer()} | |||||
className="box-border flex flex-col justify-center items-center w-full text-center md:justify-start md:ml-auto md:text-left md:w-[var(--base-width)] md:flex-row" | |||||
ref={ref} | ref={ref} | ||||
> | > | ||||
{children} | {children} | ||||
@@ -96,7 +96,7 @@ export const MoreSidebarMenuItemIcon = React.forwardRef<HTMLSpanElement, Sidebar | |||||
}, ref) => ( | }, ref) => ( | ||||
<span | <span | ||||
{...etcProps} | {...etcProps} | ||||
className={layouts.LeftSidebarWithMenu.MoreSidebarMenuItemIcon()} | |||||
className="block mr-4 md:w-menu md:h-menu md:flex md:justify-center md:items-center md:mr-0" | |||||
ref={ref} | ref={ref} | ||||
> | > | ||||
{children} | {children} | ||||
@@ -111,7 +111,7 @@ export const MoreSidebarMenuContainer = React.forwardRef<HTMLSpanElement, Sideba | |||||
}, ref) => ( | }, ref) => ( | ||||
<span | <span | ||||
{...etcProps} | {...etcProps} | ||||
className={layouts.LeftSidebarWithMenu.MoreSidebarMenuContainer()} | |||||
className="flex justify-start items-center w-[calc(var(--base-width)*2)] mx-auto px-8 text-left box-border md:mr-0 md:w-[var(--base-width)] md:pl-0" | |||||
ref={ref} | ref={ref} | ||||
> | > | ||||
{children} | {children} | ||||
@@ -1,7 +1,6 @@ | |||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import {layouts} from '@tesseract-design/viewfinder-base'; | |||||
export type RootProps = React.HTMLProps<HTMLDivElement> & { | |||||
export interface RootProps extends React.HTMLProps<HTMLDivElement> { | |||||
sidebarBaseWidget?: React.ReactNode; | sidebarBaseWidget?: React.ReactNode; | ||||
topBarWidget?: React.ReactNode; | topBarWidget?: React.ReactNode; | ||||
}; | }; | ||||
@@ -14,34 +13,37 @@ export const Root = React.forwardRef<HTMLDivElement, RootProps>(({ | |||||
}, ref) => ( | }, ref) => ( | ||||
<> | <> | ||||
{topBarWidget} | {topBarWidget} | ||||
<main | |||||
<div | |||||
{...etcProps} | {...etcProps} | ||||
ref={ref} | ref={ref} | ||||
className={layouts.RightSidebarStatic.ContentBase()} | |||||
data-viewfinder="main" | |||||
className="box-border md:pr-[calc(50%-(var(--base-width)*0.5))]" | |||||
> | > | ||||
{children} | {children} | ||||
</main> | |||||
</div> | |||||
{sidebarBaseWidget} | {sidebarBaseWidget} | ||||
</> | </> | ||||
)) | )) | ||||
Root.displayName = 'Root'; | |||||
export type ContentContainerProps = React.HTMLProps<HTMLDivElement> | |||||
export interface ContentContainerProps extends React.HTMLProps<HTMLDivElement> {} | |||||
export const MainContentContainer = React.forwardRef<HTMLDivElement, ContentContainerProps>(({ | export const MainContentContainer = React.forwardRef<HTMLDivElement, ContentContainerProps>(({ | ||||
children, | children, | ||||
}, ref) => ( | }, ref) => ( | ||||
<div | <div | ||||
className={layouts.RightSidebarStatic.ContentContainer()} | |||||
className="px-8 box-border w-full max-w-[calc(var(--base-width)*2)] mx-auto md:mr-0" | |||||
ref={ref} | ref={ref} | ||||
> | > | ||||
{children} | {children} | ||||
</div> | </div> | ||||
)); | )); | ||||
MainContentContainer.displayName = 'MainContentContainer' | |||||
MainContentContainer.displayName = 'MainContentContainer'; | |||||
export type SidebarMainContainerProps = React.HTMLProps<HTMLDivElement> | |||||
export interface SidebarMainContainerProps extends React.HTMLProps<HTMLDivElement> {} | |||||
export const SidebarContentContainer = React.forwardRef<HTMLDivElement, SidebarMainContainerProps>(({ | export const SidebarContentContainer = React.forwardRef<HTMLDivElement, SidebarMainContainerProps>(({ | ||||
children, | children, | ||||
@@ -49,7 +51,7 @@ export const SidebarContentContainer = React.forwardRef<HTMLDivElement, SidebarM | |||||
}, ref) => ( | }, ref) => ( | ||||
<div | <div | ||||
{...etcProps} | {...etcProps} | ||||
className={layouts.RightSidebarStatic.SidebarMainContainer()} | |||||
className="px-8 box-border w-full max-w-[calc(var(--base-width)*2)] mx-auto md:ml-0 md:w-[var(--base-width)]" | |||||
ref={ref} | ref={ref} | ||||
> | > | ||||
{children} | {children} | ||||
@@ -1,35 +1,29 @@ | |||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import {LayoutArgs, layouts, Span} from '@tesseract-design/viewfinder-base'; | |||||
import clsx from 'clsx'; | |||||
export type LeftSidebarBaseProps = Omit<React.HTMLProps<HTMLDivElement>, 'span'> & { | |||||
span?: Span, | |||||
} | |||||
export interface LeftSidebarBaseProps extends React.HTMLProps<HTMLDivElement> {} | |||||
export const LeftSidebarBase = React.forwardRef<HTMLDivElement, LeftSidebarBaseProps>(({ | export const LeftSidebarBase = React.forwardRef<HTMLDivElement, LeftSidebarBaseProps>(({ | ||||
children, | children, | ||||
span = Span.WIDE, | |||||
open = false, | open = false, | ||||
...etcProps | ...etcProps | ||||
}, ref) => { | }, ref) => { | ||||
const args: LayoutArgs = { | |||||
span, | |||||
mainSidebarOpen: open, | |||||
auxiliaryItemsShown: false, | |||||
}; | |||||
return ( | return ( | ||||
<div | <div | ||||
className={layouts.LeftSidebar.SidebarBase(args)} | |||||
className={clsx( | |||||
'box-border fixed top-0 -left-full w-full h-full bg-bg md:left-0 md:w-[calc(50%-(var(--base-width)*0.5))] scrollbar-hidden', | |||||
open && 'left-0', | |||||
)} | |||||
{...etcProps} | {...etcProps} | ||||
ref={ref} | ref={ref} | ||||
> | > | ||||
<div | <div | ||||
className={layouts.LeftSidebar.SidebarOverflow()} | |||||
className="w-full h-full overflow-auto relative z-[1]" | |||||
> | > | ||||
{children} | {children} | ||||
</div> | </div> | ||||
</div> | </div> | ||||
) | |||||
); | |||||
}); | }); | ||||
LeftSidebarBase.displayName = 'LeftSidebarBase' | LeftSidebarBase.displayName = 'LeftSidebarBase' |
@@ -1,7 +1,8 @@ | |||||
// TODO figure out how to refactor left sidebar with menu widget | // TODO figure out how to refactor left sidebar with menu widget | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import {LayoutArgs, layouts, Span} from '@tesseract-design/viewfinder-base'; | |||||
import {SpanValues as Span} from '@tesseract-design/viewfinder-base'; | |||||
import clsx from 'clsx'; | |||||
type BaseMenuItem = { | type BaseMenuItem = { | ||||
label: React.ReactNode, | label: React.ReactNode, | ||||
@@ -26,7 +27,7 @@ export type LeftSidebarWithMenuBaseProps = Omit<React.HTMLProps<HTMLDivElement>, | |||||
export const LeftSidebarWithMenuBase = React.forwardRef<HTMLDivElement, LeftSidebarWithMenuBaseProps>(({ | export const LeftSidebarWithMenuBase = React.forwardRef<HTMLDivElement, LeftSidebarWithMenuBaseProps>(({ | ||||
children, | children, | ||||
span = Span.WIDE, | |||||
span = 'wide', | |||||
open = false, | open = false, | ||||
items: sidebarMenuItems = [], | items: sidebarMenuItems = [], | ||||
linkComponent: LinkComponent = 'a', | linkComponent: LinkComponent = 'a', | ||||
@@ -35,12 +36,6 @@ export const LeftSidebarWithMenuBase = React.forwardRef<HTMLDivElement, LeftSide | |||||
moreItemsOpen = false, | moreItemsOpen = false, | ||||
...etcProps | ...etcProps | ||||
}, ref) => { | }, ref) => { | ||||
const args: LayoutArgs = { | |||||
span, | |||||
mainSidebarOpen: open, | |||||
auxiliaryItemsShown: moreItemsOpen, | |||||
}; | |||||
const primarySidebarMenuItems = sidebarMenuItems.filter(s => !s.secondary) | const primarySidebarMenuItems = sidebarMenuItems.filter(s => !s.secondary) | ||||
const secondarySidebarMenuItems = sidebarMenuItems.filter(s => s.secondary) | const secondarySidebarMenuItems = sidebarMenuItems.filter(s => s.secondary) | ||||
@@ -63,24 +58,26 @@ export const LeftSidebarWithMenuBase = React.forwardRef<HTMLDivElement, LeftSide | |||||
return ( | return ( | ||||
<div | <div | ||||
className={layouts.LeftSidebarWithMenu.SidebarBase()} | |||||
className="left-sidebar-with-menu-base box-border overflow-hidden contents left-[calc(var(--base-width)*-1)] md:fixed md:top-0 md:left-0 md:w-[calc(50%-var(--base-width)*0.5)] md:h-full md:block" | |||||
{...etcProps} | {...etcProps} | ||||
ref={ref} | ref={ref} | ||||
> | > | ||||
<div | <div | ||||
className={layouts.LeftSidebarWithMenu.SidebarMenu()} | |||||
data-viewfinder="menu" | |||||
className="box-border scrollbar-hidden overflow-auto fixed bottom-0 left-0 w-full h-menu z-[3] bg-bg md:top-0 md:ml-auto md:absolute md:h-full md:pt-inherit md:overflow-auto md:z-auto" | |||||
> | > | ||||
<div> | |||||
<div className="w-full h-full bg-bg"> | |||||
<div | <div | ||||
className={layouts.LeftSidebarWithMenu.SidebarMenuSize()} | |||||
className="flex w-full h-full max-w-[calc(var(--base-width)*2)] mx-auto relative z-[1] md:max-w-none md:mr-0 md:flex-col md:justify-between md:items-end" | |||||
> | > | ||||
<div | <div | ||||
className={layouts.LeftSidebarWithMenu.SidebarMenuGroup()} | |||||
className="contents md:w-full md:block" | |||||
> | > | ||||
{visiblePrimarySidebarMenuItems.map(({ id, ...item }) => ( | {visiblePrimarySidebarMenuItems.map(({ id, ...item }) => ( | ||||
<span | <span | ||||
className={layouts.LeftSidebarWithMenu.SidebarMenuItem()} | |||||
key={id} | |||||
key={id} | |||||
className="w-0 flex-auto h-menu md:flex-shrink-0 md:flex-grow" | |||||
data-viewfinder="menu-item" | |||||
> | > | ||||
<LinkComponent | <LinkComponent | ||||
{...item} | {...item} | ||||
@@ -89,18 +86,22 @@ export const LeftSidebarWithMenuBase = React.forwardRef<HTMLDivElement, LeftSide | |||||
))} | ))} | ||||
</div> | </div> | ||||
<div | <div | ||||
className={layouts.LeftSidebarWithMenu.MoreItems(args)} | |||||
className={clsx( | |||||
'fixed top-0 w-full h-full pt-topbar pb-menu -z-[1] box-border md:contents', | |||||
moreItemsOpen ? 'left-0': '-left-full', | |||||
)} | |||||
> | > | ||||
<div | <div | ||||
className={layouts.LeftSidebarWithMenu.MoreItemsScroll()} | |||||
className="w-full h-full overflow-auto bg-bg md:contents" | |||||
> | > | ||||
<div | <div | ||||
className={layouts.LeftSidebarWithMenu.MorePrimarySidebarMenuGroup()} | |||||
className="contents md:w-full md:block md:flex-auto" | |||||
> | > | ||||
{morePrimarySidebarMenuItems.map(({ id, ...item }) => ( | {morePrimarySidebarMenuItems.map(({ id, ...item }) => ( | ||||
<span | <span | ||||
className={layouts.LeftSidebarWithMenu.MoreSidebarMenuItem()} | |||||
key={id} | |||||
key={id} | |||||
data-viewfinder="menu-item" | |||||
className="h-menu block md:flex-shrink-0 md:flex-grow md:flex-auto" | |||||
> | > | ||||
<MoreLinkComponent | <MoreLinkComponent | ||||
{...item} | {...item} | ||||
@@ -109,12 +110,13 @@ export const LeftSidebarWithMenuBase = React.forwardRef<HTMLDivElement, LeftSide | |||||
))} | ))} | ||||
</div> | </div> | ||||
<div | <div | ||||
className={layouts.LeftSidebarWithMenu.MoreSecondarySidebarMenuGroup()} | |||||
className="contents md:w-full md:block md:order-4" | |||||
> | > | ||||
{moreSecondarySidebarMenuItems.map(({ id, ...item }) => ( | {moreSecondarySidebarMenuItems.map(({ id, ...item }) => ( | ||||
<span | <span | ||||
className={layouts.LeftSidebarWithMenu.MoreSidebarMenuItem()} | |||||
key={id} | |||||
key={id} | |||||
data-viewfinder="menu-item" | |||||
className="h-menu block md:flex-shrink-0 md:flex-grow md:flex-auto" | |||||
> | > | ||||
<MoreLinkComponent | <MoreLinkComponent | ||||
{...item} | {...item} | ||||
@@ -126,10 +128,11 @@ export const LeftSidebarWithMenuBase = React.forwardRef<HTMLDivElement, LeftSide | |||||
</div> | </div> | ||||
{hasMoreSidebarMenuItems && ( | {hasMoreSidebarMenuItems && ( | ||||
<span | <span | ||||
className={layouts.LeftSidebarWithMenu.MoreToggleSidebarMenuItem()} | |||||
className="contents md:hidden" | |||||
> | > | ||||
<span | <span | ||||
className={layouts.LeftSidebarWithMenu.SidebarMenuItem()} | |||||
className="w-0 flex-auto h-menu md:flex-shrink-0 md:flex-grow md:flex-auto" | |||||
data-viewfinder="menu-item" | |||||
> | > | ||||
<LinkComponent | <LinkComponent | ||||
{...moreLinkItem} | {...moreLinkItem} | ||||
@@ -139,12 +142,13 @@ export const LeftSidebarWithMenuBase = React.forwardRef<HTMLDivElement, LeftSide | |||||
)} | )} | ||||
{visibleSecondarySidebarMenuItems.length > 0 && ( | {visibleSecondarySidebarMenuItems.length > 0 && ( | ||||
<div | <div | ||||
className={layouts.LeftSidebarWithMenu.SidebarMenuGroup()} | |||||
className="contents md:w-full md:block" | |||||
> | > | ||||
{visibleSecondarySidebarMenuItems.map(({ id, ...item }) => ( | {visibleSecondarySidebarMenuItems.map(({ id, ...item }) => ( | ||||
<span | <span | ||||
className={layouts.LeftSidebarWithMenu.SidebarMenuItem()} | |||||
key={id} | |||||
key={id} | |||||
className="w-0 flex-auto h-menu md:flex-shrink-0 md:flex-grow md:flex-auto" | |||||
data-viewfinder="menu-item" | |||||
> | > | ||||
<LinkComponent | <LinkComponent | ||||
{...item} | {...item} | ||||
@@ -158,10 +162,14 @@ export const LeftSidebarWithMenuBase = React.forwardRef<HTMLDivElement, LeftSide | |||||
</div> | </div> | ||||
{children && ( | {children && ( | ||||
<div | <div | ||||
className={layouts.LeftSidebarWithMenu.SidebarMain(args)} | |||||
className={clsx( | |||||
'box-border fixed top-0 w-full h-full pt-inherit pb-menu z-[2] bg-bg', | |||||
open ? 'right-0': 'right-full', | |||||
'md:absolute md:right-0 md:ml-0 md:pb-0 md:w-[calc(var(--base-width)-var(--size-menu,4rem))]' | |||||
)} | |||||
> | > | ||||
<div | <div | ||||
className={layouts.LeftSidebarWithMenu.SidebarMainOverflow()} | |||||
className="bg-bg w-full h-full overflow-auto scrollbar-hidden relative z-[1]" | |||||
> | > | ||||
{children} | {children} | ||||
</div> | </div> | ||||
@@ -1,22 +1,18 @@ | |||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import {layouts, Span} from '@tesseract-design/viewfinder-base'; | |||||
export type RightSidebarStaticBaseProps = Omit<React.HTMLProps<HTMLDivElement>, 'span'> & { | |||||
span?: Span, | |||||
} | |||||
export interface RightSidebarStaticBaseProps extends React.HTMLProps<HTMLDivElement> {} | |||||
export const RightSidebarStaticBase = React.forwardRef<HTMLDivElement, RightSidebarStaticBaseProps>(({ | export const RightSidebarStaticBase = React.forwardRef<HTMLDivElement, RightSidebarStaticBaseProps>(({ | ||||
children, | children, | ||||
span = Span.WIDE, | |||||
...etcProps | ...etcProps | ||||
}, ref) => ( | }, ref) => ( | ||||
<div | <div | ||||
className={layouts.RightSidebarStatic.SidebarBase()} | |||||
className="box-border bg-bg after:pb-[1px] after:-mt-[1px] after:box-border md:pr-[calc(50%-(var(--base-width)*0.5)] md:absolute md:top-0 md:right-0 md:h-full md:w-[calc(50%-(var(--base-width)*0.5))]" | |||||
{...etcProps} | {...etcProps} | ||||
ref={ref} | ref={ref} | ||||
> | > | ||||
<div | <div | ||||
className={layouts.RightSidebarStatic.SidebarMainContent()} | |||||
className="w-full h-full relative z-[1]" | |||||
> | > | ||||
{children} | {children} | ||||
</div> | </div> | ||||
@@ -1,7 +1,8 @@ | |||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import {LayoutArgs, Span, widgets} from '@tesseract-design/viewfinder-base'; | |||||
import clsx from 'clsx'; | |||||
import { SpanValues as Span } from '@tesseract-design/viewfinder-base'; | |||||
export type TopBarProps = Omit<React.HTMLProps<HTMLDivElement>, 'span'> & { | |||||
export interface TopBarProps extends Omit<React.HTMLProps<HTMLDivElement>, 'span'> { | |||||
span?: Span, | span?: Span, | ||||
brand?: React.ReactNode, | brand?: React.ReactNode, | ||||
menuLink?: React.ReactNode, | menuLink?: React.ReactNode, | ||||
@@ -9,26 +10,28 @@ export type TopBarProps = Omit<React.HTMLProps<HTMLDivElement>, 'span'> & { | |||||
} | } | ||||
export const TopBar = React.forwardRef<HTMLDivElement, TopBarProps>(({ | export const TopBar = React.forwardRef<HTMLDivElement, TopBarProps>(({ | ||||
span = Span.NORMAL, | |||||
span = 'normal', | |||||
brand, | brand, | ||||
menuLink, | menuLink, | ||||
userLink, | userLink, | ||||
children, | children, | ||||
...etcProps | ...etcProps | ||||
}, ref) => { | }, ref) => { | ||||
const args: LayoutArgs = { | |||||
span, | |||||
mainSidebarOpen: false, | |||||
auxiliaryItemsShown: false, | |||||
}; | |||||
return ( | return ( | ||||
<div className={widgets.TopBar.Base()}> | |||||
<div className={clsx( | |||||
'fixed top-0 left-0 w-full z-[3] topbar', | |||||
)}> | |||||
<div | <div | ||||
{...etcProps} | {...etcProps} | ||||
ref={ref} | ref={ref} | ||||
className="w-full h-full bg-bg" | |||||
> | > | ||||
<div className={widgets.TopBar.Container(args)}> | |||||
<div className={clsx( | |||||
'px-8 box-border mx-auto w-full h-full flex items-center relative z-[1]', | |||||
span === 'narrow' && 'max-w-screen-2xs', | |||||
span === 'normal' && 'max-w-screen-xs', | |||||
span === 'wide' && 'max-w-screen-md', | |||||
)}> | |||||
{ | { | ||||
Boolean(brand as unknown) | Boolean(brand as unknown) | ||||
&& ( | && ( | ||||
@@ -37,14 +40,17 @@ export const TopBar = React.forwardRef<HTMLDivElement, TopBarProps>(({ | |||||
</div> | </div> | ||||
) | ) | ||||
} | } | ||||
<div className={widgets.TopBar.CenterContainer()}> | |||||
<div className="flex-auto px-8 box-border first:pl-0"> | |||||
{children} | {children} | ||||
</div> | </div> | ||||
<div className={widgets.TopBar.ActionContainer()}> | |||||
<div className="flex items-center justify-end h-full whitespace-nowrap sm:min-w-32"> | |||||
{ | { | ||||
Boolean(menuLink as unknown) | Boolean(menuLink as unknown) | ||||
&& ( | && ( | ||||
<div className={widgets.TopBar.MenuLinkContainer()}> | |||||
<div | |||||
data-viewfinder="menu" | |||||
className="w-topbar h-full" | |||||
> | |||||
{menuLink} | {menuLink} | ||||
</div> | </div> | ||||
) | ) | ||||
@@ -52,7 +58,10 @@ export const TopBar = React.forwardRef<HTMLDivElement, TopBarProps>(({ | |||||
{ | { | ||||
Boolean(userLink as unknown) | Boolean(userLink as unknown) | ||||
&& ( | && ( | ||||
<div className={widgets.TopBar.LinkContainer()}> | |||||
<div | |||||
data-viewfinder="user" | |||||
className="w-topbar h-full" | |||||
> | |||||
{userLink} | {userLink} | ||||
</div> | </div> | ||||
) | ) | ||||
@@ -0,0 +1,2 @@ | |||||
packages: | |||||
- 'packages/**' |