website refactor
This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
import { ReactNode } from 'react';
|
||||
import { Box, type Spacing } from './Box';
|
||||
|
||||
export interface ContentViewportProps {
|
||||
children: ReactNode;
|
||||
padding?: 'none' | 'sm' | 'md' | 'lg';
|
||||
fullWidth?: boolean;
|
||||
}
|
||||
|
||||
export const ContentViewport = ({
|
||||
children,
|
||||
padding = 'md',
|
||||
fullWidth = false,
|
||||
}: ContentViewportProps) => {
|
||||
const paddingMap: Record<NonNullable<ContentViewportProps['padding']>, Spacing> = {
|
||||
none: 0,
|
||||
sm: 4,
|
||||
md: 8,
|
||||
lg: 12,
|
||||
};
|
||||
|
||||
const maxWidth = fullWidth ? '100%' : '80rem';
|
||||
|
||||
return (
|
||||
<Box flexGrow={1} width="full" display="flex" justifyContent="center" minWidth="0">
|
||||
<Box width="full" maxWidth={maxWidth} paddingX={4} py={paddingMap[padding]} minWidth="0">
|
||||
{children}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -6,39 +6,79 @@ export interface LayoutProps {
|
||||
header?: ReactNode;
|
||||
footer?: ReactNode;
|
||||
sidebar?: ReactNode;
|
||||
/**
|
||||
* Whether the sidebar should be fixed to the side.
|
||||
* If true, the main content will be offset by the sidebar width.
|
||||
*/
|
||||
fixedSidebar?: boolean;
|
||||
/**
|
||||
* Whether the header should be fixed to the top.
|
||||
* If true, the main content will be offset by the header height.
|
||||
*/
|
||||
fixedHeader?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Layout is the canonical app frame component.
|
||||
* It orchestrates the high-level structure: Header, Sidebar, Main Content, and Footer.
|
||||
*/
|
||||
export const Layout = ({
|
||||
children,
|
||||
header,
|
||||
footer,
|
||||
sidebar
|
||||
sidebar,
|
||||
fixedSidebar = false,
|
||||
fixedHeader = false
|
||||
}: LayoutProps) => {
|
||||
return (
|
||||
<Box display="flex" flexDirection="col" minHeight="100vh" bg="var(--ui-color-bg-base)">
|
||||
<Box display="flex" flexDirection="col" minHeight="100vh">
|
||||
{header && (
|
||||
<Box as="header" position="sticky" top="0" zIndex={50}>
|
||||
<Box
|
||||
as="header"
|
||||
position={fixedHeader ? "fixed" : "relative"}
|
||||
top={fixedHeader ? 0 : undefined}
|
||||
left={fixedHeader ? 0 : undefined}
|
||||
right={fixedHeader ? 0 : undefined}
|
||||
zIndex={50}
|
||||
>
|
||||
{header}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Box display="flex" flex={1}>
|
||||
<Box display="flex" flex={1} marginTop={fixedHeader ? 14 : undefined}>
|
||||
{sidebar && (
|
||||
<Box as="aside" width="16rem" display={{ base: 'none', lg: 'block' }}>
|
||||
<Box
|
||||
as="aside"
|
||||
width="64"
|
||||
display={{ base: 'none', lg: 'block' }}
|
||||
position={fixedSidebar ? "fixed" : "relative"}
|
||||
top={fixedSidebar ? (fixedHeader ? 14 : 0) : undefined}
|
||||
bottom={fixedSidebar ? 0 : undefined}
|
||||
left={fixedSidebar ? 0 : undefined}
|
||||
zIndex={40}
|
||||
>
|
||||
{sidebar}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Box as="main" flex={1}>
|
||||
{children}
|
||||
<Box
|
||||
as="main"
|
||||
flex={1}
|
||||
display="flex"
|
||||
flexDirection="col"
|
||||
marginLeft={fixedSidebar ? { lg: 64 } : undefined}
|
||||
>
|
||||
<Box flex={1}>
|
||||
{children}
|
||||
</Box>
|
||||
|
||||
{footer && (
|
||||
<Box as="footer">
|
||||
{footer}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
{footer && (
|
||||
<Box as="footer">
|
||||
{footer}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user