import React, { FC, useState } from "react";
import styled, { css } from "styled-components";
import type { LayoutProps, WithThemeSchemeProp } from "../types";
import { Const } from "../const";
import { NamedColors } from "../utils/style";
import { removeCommentsAndSpacing } from "../utils/shared";
import InstantRouterIndicator from "../islands/InstantRouterIndicator";
import { PageHeader } from "./PageHeader";
import { DrawerPrimary } from "./DrawerPrimary";
const BRANDLINE_HEIGHT = 4;
const HEADER_HEIGHT = 64;
const LayoutComponent: FC<LayoutProps & WithThemeSchemeProp> = (props) => {
const {
appVersion,
children,
gitStamp,
themeScheme,
showDrawerPrimary = false,
orgSlug = "",
repoSlug = "",
currentRef = Const.DEFAULT_HEAD_REF,
path = "",
layoutCounters,
} = props;
const sharedProps = {
themeScheme,
};
const [drawerPrimaryOpen, setDrawerPrimaryOpen] =
useState<boolean>(showDrawerPrimary);
return (
<>
<style
dangerouslySetInnerHTML={{
__html: removeCommentsAndSpacing(`
html,
body {
margin: 0;
padding: 0;
font-family: sans-serif;
font-size: 16px;
background-color: ${NamedColors.BACKGROUND[themeScheme]};
}
html {
/* so anchor are not hidden behind sticky header */
scroll-padding-top: ${HEADER_HEIGHT + 16}px;
}
body {
overflow-x: hidden;
overflow-y: scroll;
}
* {
box-sizing: border-box;
}
a {
color: ${NamedColors.TEXT_LINK[themeScheme]};
font-weight: bold;
text-decoration: none;
transition: opacity 220ms linear 0s;
}
a:hover {
text-decoration: underline;
}
a:active {
opacity: 0.87;
}
a > * {
pointer-events: none;
}
form {
width: 100%;
}
`),
}}
/>
<StyledLayoutWrapper {...sharedProps}>
<div data-islandid={`${InstantRouterIndicator.name}$$0`}>
<InstantRouterIndicator />
</div>
<StyledPageWrapper>
<DrawerPrimary
commonProps={props as any}
themeScheme={themeScheme}
visible={drawerPrimaryOpen}
counters={layoutCounters}
orgSlug={orgSlug}
repoSlug={repoSlug}
currentRef={currentRef}
path={path}
/>
<StyledChildrenWrapper
{...sharedProps}
showDrawerPrimary={drawerPrimaryOpen}
>
<StyledPageHeaderWrapper {...sharedProps}>
<PageHeader
commonProps={props as any}
themeScheme={themeScheme}
forceShowLogo={showDrawerPrimary !== true}
setDrawerPrimaryOpen={setDrawerPrimaryOpen}
/>
</StyledPageHeaderWrapper>
{children}
<StyledFooterWrapper>
<p>
<a href={"https://gitfoss.dev/ethicdevs/gitfoss"}>
{Const.APP_NAME} • v{appVersion} (#
{gitStamp.slice(0, 7)}) • MIT License
</a>
</p>
</StyledFooterWrapper>
</StyledChildrenWrapper>
</StyledPageWrapper>
</StyledLayoutWrapper>
</>
);
};
export const Layout = LayoutComponent;
const StyledLayoutWrapper = styled.div<WithThemeSchemeProp>`
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: flex-start;
min-height: 100vh;
min-width: 100%;
max-width: 100%;
${({ themeScheme }) => css`
background-color: ${NamedColors.BACKGROUND[themeScheme]};
color: ${NamedColors.TEXT_DEFAULT[themeScheme]};
`};
`;
const StyledPageHeaderWrapper = styled.div<WithThemeSchemeProp>`
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: center;
width: 100%;
min-height: ${HEADER_HEIGHT}px;
height: ${HEADER_HEIGHT}px;
max-height: ${HEADER_HEIGHT}px;
position: sticky;
top: 0;
z-index: 11000;
gap: 20px;
padding: 0 20px;
backdrop-filter: blur(8px);
${({ themeScheme }) => css`
background-color: ${NamedColors.HEADER[themeScheme]};
border-bottom: 1px solid ${NamedColors.BORDER_DEFAULT[themeScheme]};
& > a > h1 {
color: ${NamedColors.TEXT_DEFAULT[themeScheme]};
margin: 0;
margin-left: 16px;
}
`};
& > a {
text-decoration: unset;
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: center;
}
`;
const StyledPageWrapper = styled.div`
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: stretch;
position: relative;
flex: 1;
width: 100%;
min-height: calc(100% - ${BRANDLINE_HEIGHT + HEADER_HEIGHT}px);
`;
const StyledChildrenWrapper = styled.div<{ showDrawerPrimary?: boolean }>`
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: flex-start;
flex: 1;
width: 100%;
${({ showDrawerPrimary = false }) =>
showDrawerPrimary &&
css`
max-width: calc(100% - 300px);
`};
@media only screen and (max-width: 768px) {
max-width: 100%;
}
`;
const StyledFooterWrapper = styled.div`
display: flex;
flex-flow: row wrap;
justify-content: center;
align-items: center;
width: 100%;
min-height: 44px;
height: 44px;
& > p {
margin: 0 0 24px 0;
opacity: 0.67;
font-size: 12px;
}
`;