import type { ReactView } from "@ethicdevs/react-monolith";
import React from "react";
import styled, { css } from "styled-components";
import type { CommonProps, Page, WithThemeSchemeProp } from "../types";
import { Layout, MarkdownToJsx, TextEllipsis } from "../components";
import { NamedColors } from "../utils/style";
export interface DocPageViewProps extends CommonProps {
page: Page;
}
const DocPageView: ReactView<DocPageViewProps> = ({ commonProps, page }) => {
const { themeScheme } = commonProps;
return (
<Layout
{...commonProps}
showSideMenu
showSideExamples={
page.metas.showExamples != null
? Boolean(page.metas.showExamples)
: false
}
>
<StyledDocPageWrapper>
{page.metas.title != null && (
<h1 style={{ width: "100%", textAlign: "center" }}>
{page.metas.title}
</h1>
)}
{page.metas.summary != null && (
<div
style={{
width: "100%",
textAlign: "center",
color: NamedColors.TEXT_MUTED[themeScheme],
}}
>
<MarkdownToJsx
themeScheme={themeScheme}
markdown={page.metas.summary}
/>
</div>
)}
<StyledDocContentRow>
<StyledDocContentCol>
<MarkdownToJsx themeScheme={themeScheme} markdown={page.content} />
</StyledDocContentCol>
{page.tableOfContent != null && page.tableOfContent.length >= 1 && (
<StyledDocTableOfContentsCol>
<h4
style={{
margin: 0,
marginBottom: 16,
color: NamedColors.TEXT_DEFAULT[themeScheme],
}}
>
Table of Contents
</h4>
{page.tableOfContent.map((entry) => (
<StyledDocTableOfContentsItem
depth={entry.depth}
href={`#${entry.targetAnchor}`}
key={entry.targetAnchor}
title={entry.title}
themeScheme={themeScheme}
>
<TextEllipsis numberOfLines={2}>{entry.title}</TextEllipsis>
</StyledDocTableOfContentsItem>
))}
</StyledDocTableOfContentsCol>
)}
</StyledDocContentRow>
{(page.metas?.prevPage != null || page.metas?.nextPage != null) && (
<StyledDocNavigationRow themeScheme={themeScheme}>
{page.metas?.prevPage != null ? (
<StyledDocNavigationLinkCol
href={page.metas.prevPage.href}
themeScheme={themeScheme}
>
<span>‹ {page.metas.prevPage.title}</span>
<span>{page.metas.prevPage?.subtitle || "Previous"}</span>
</StyledDocNavigationLinkCol>
) : (
<StyledDocNavigationLinkCol themeScheme={themeScheme} />
)}
{page.metas?.nextPage != null ? (
<StyledDocNavigationLinkCol
href={page.metas.nextPage.href}
themeScheme={themeScheme}
>
<span>{page.metas.nextPage.title} ›</span>
<span>{page.metas.nextPage?.subtitle || "Up Next"}</span>
</StyledDocNavigationLinkCol>
) : (
<StyledDocNavigationLinkCol themeScheme={themeScheme} />
)}
</StyledDocNavigationRow>
)}
</StyledDocPageWrapper>
</Layout>
);
};
const StyledDocPageWrapper = styled.div`
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: flex-start;
gap: 24px;
padding: 24px;
width: 100%;
max-width: 960px;
margin: 0 auto;
`;
const StyledDocContentRow = styled.div`
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-items: flex-start;
width: 100%;
`;
const StyledDocContentCol = styled.main`
display: flex;
flex-flow: column wrap;
justify-content: flex-start;
align-items: flex-start;
flex: 1;
`;
const StyledDocTableOfContentsCol = styled.aside`
display: flex;
flex-flow: column wrap;
justify-content: flex-start;
align-items: flex-start;
flex: 0.3;
position: sticky;
top: ${72 + 24}px;
margin-left: 24px;
`;
const StyledDocTableOfContentsItem = styled.a<
{ depth: number } & WithThemeSchemeProp
>`
dipslay: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-item: center;
width: 100%;
font-size: 14px;
font-weight: bold;
line-height: 16px;
text-decoration: none;
&:hover {
text-decoration: underline;
}
padding: 4px 10px 4px 0px;
${({ depth }) => css`
margin-left: ${Math.max(0, (depth - 2) * 8)}px;
`};
${({ themeScheme }) => css`
color: ${NamedColors.TEXT_MUTED[themeScheme]};
`};
`;
const StyledDocNavigationLinkCol = styled.a<WithThemeSchemeProp>`
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: flex-start;
${({ themeScheme }) => css`
color: ${NamedColors.TEXT_LINK[themeScheme]};
`};
font-weight: bold;
text-decoration: none;
&:hover {
text-decoration: underline;
}
& > span:first-child {
font-size: 16px;
}
& > span:last-child {
margin-top: 4px;
font-size: 14px;
font-weight: normal;
opacity: 0.87;
}
`;
const StyledDocNavigationRow = styled.div<WithThemeSchemeProp>`
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
align-items: center;
width: 100%;
margin-top: 0;
padding-top: 24px;
${({ themeScheme }) => css`
border-top: 1px solid ${NamedColors.BORDER_DEFAULT[themeScheme]};
`};
& > ${StyledDocNavigationLinkCol}:last-child {
align-items: flex-end;
}
`;
DocPageView.displayName = "DocPageView";
export default DocPageView;