mirror of
https://github.com/acid-info/logos-press-engine.git
synced 2025-02-23 06:38:27 +00:00
resolve conflicts
This commit is contained in:
parent
c08e04ae41
commit
e679765da9
@ -37,14 +37,11 @@ export default function ArticleBody({ data }: Props) {
|
||||
return (
|
||||
<ArticleContainer>
|
||||
{resultsNumber === null && <ArticleHeader {...data.article} />}
|
||||
{resultsNumber === null && <MobileToc toc={data.article.toc} />}
|
||||
<TextContainer>
|
||||
{/*@ts-ignore*/}
|
||||
<ArticleBlocks data={{ ...data.article, blocks }} />
|
||||
{resultsNumber === 0 && (
|
||||
<Typography variant="body1">No results found</Typography>
|
||||
)}
|
||||
</TextContainer>
|
||||
{/*@ts-ignore*/}
|
||||
<ArticleBlocks data={{ ...data.article, blocks }} />
|
||||
{resultsNumber === 0 && (
|
||||
<Typography variant="body1">No results found</Typography>
|
||||
)}
|
||||
<ArticleFooter data={data} />
|
||||
</ArticleContainer>
|
||||
)
|
||||
@ -69,6 +66,5 @@ const TextContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 80px;
|
||||
`
|
||||
|
@ -33,7 +33,7 @@ export const ArticleHeading = ({
|
||||
<Headline
|
||||
variant={block.tagName as any}
|
||||
component={block.tagName as any}
|
||||
genericFontFamily="sans-serif"
|
||||
genericFontFamily="serif"
|
||||
className={extractClassFromFirstTag(block.html) || ''}
|
||||
dangerouslySetInnerHTML={{ __html: `${extractInnerHtml(block.html)}` }}
|
||||
{...(typographyProps || {})}
|
||||
@ -44,6 +44,15 @@ export const ArticleHeading = ({
|
||||
|
||||
const Headline = styled(Typography)`
|
||||
white-space: pre-wrap;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 24px;
|
||||
margin-top: 16px;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
&.title {
|
||||
font-size: var(--lsd-h3-fontSize);
|
||||
line-height: var(--lsd-h4-lineHeight);
|
||||
}
|
||||
|
||||
font-size: var(--lsd-h4-fontSize);
|
||||
line-height: var(--lsd-h4-lineHeight);
|
||||
}
|
||||
`
|
||||
|
@ -15,7 +15,7 @@ export const MobileToc = ({ toc }: Props) => {
|
||||
const { tocId } = useArticleContainerContext()
|
||||
|
||||
return toc?.length > 0 ? (
|
||||
<Collapse className={styles.mobileToc} label="Contents">
|
||||
<Collapse className={styles.mobileToc} label="Contents" initOpen={false}>
|
||||
{toc.map((toc, idx) => (
|
||||
<TocItem
|
||||
href={`${idx === 0 ? '#' : toc.href}`}
|
||||
@ -23,7 +23,9 @@ export const MobileToc = ({ toc }: Props) => {
|
||||
active={tocId ? toc.href.substring(1) === tocId : idx === 0}
|
||||
>
|
||||
<CustomTypography variant="label2" genericFontFamily="sans-serif">
|
||||
{toc.title}
|
||||
{(tocId ? toc.href.substring(1) === tocId : idx === 0)
|
||||
? `☞ ${toc.title} ☜`
|
||||
: toc.title}
|
||||
</CustomTypography>
|
||||
</TocItem>
|
||||
))}
|
||||
@ -39,6 +41,8 @@ const CustomTypography = styled(Typography)`
|
||||
|
||||
const TocItem = styled(Link)<{ active: boolean }>`
|
||||
padding: 8px 14px;
|
||||
text-decoration: none;
|
||||
|
||||
background-color: ${(p) =>
|
||||
p.active
|
||||
? 'rgb(var(--lsd-theme-primary))'
|
||||
|
@ -8,21 +8,19 @@ const ArticleStats = ({
|
||||
dateStr: string
|
||||
readingLength: number
|
||||
}) => (
|
||||
<div>
|
||||
<Row>
|
||||
<Typography variant="body3" genericFontFamily="sans-serif">
|
||||
{readingLength} minutes read
|
||||
</Typography>
|
||||
<Typography variant="body3">•</Typography>
|
||||
<Typography variant="body3" genericFontFamily="sans-serif">
|
||||
{new Date(dateStr).toLocaleString('en-GB', {
|
||||
day: 'numeric',
|
||||
month: 'long', // TODO: Should be uppercase
|
||||
year: 'numeric',
|
||||
})}
|
||||
</Typography>
|
||||
</Row>
|
||||
</div>
|
||||
<Row>
|
||||
<Typography variant="body3" genericFontFamily="sans-serif">
|
||||
{readingLength} minutes read
|
||||
</Typography>
|
||||
<Typography variant="body3">•</Typography>
|
||||
<Typography variant="body3" genericFontFamily="sans-serif">
|
||||
{new Date(dateStr).toLocaleString('en-GB', {
|
||||
day: 'numeric',
|
||||
month: 'long', // TODO: Should be uppercase
|
||||
year: 'numeric',
|
||||
})}
|
||||
</Typography>
|
||||
</Row>
|
||||
)
|
||||
|
||||
const Row = styled.div`
|
||||
@ -30,7 +28,7 @@ const Row = styled.div`
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
margin-bottom: 12px;
|
||||
`
|
||||
|
||||
export default ArticleStats
|
||||
|
@ -1,5 +1,9 @@
|
||||
/* temporary breakpoint */
|
||||
@media (min-width: 1024px) {
|
||||
.mobileToc{
|
||||
/*margin-block: 32px;*/
|
||||
margin-bottom: -2px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px){
|
||||
.mobileToc {
|
||||
display: none !important;
|
||||
}
|
||||
|
@ -31,11 +31,14 @@ const ArticleFooter = ({ data }: { data: ArticlePostData }) => {
|
||||
|
||||
const ArticleFooterContainer = styled.div`
|
||||
margin-top: 16px;
|
||||
|
||||
|
||||
& > div:not(:first-child) > div > button,
|
||||
& > div:not(:first-child) > div {
|
||||
border-top: none;
|
||||
}
|
||||
`
|
||||
|
||||
@media (max-width: 768px) {
|
||||
margin-top: 72px;
|
||||
}
|
||||
`
|
||||
export default ArticleFooter
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { GoogleDocEnhanced } from '@/lib/unbody/unbody.types'
|
||||
import { getArticleCover } from '@/utils/data.utils'
|
||||
import { useMemo } from 'react'
|
||||
import React, { useMemo } from 'react'
|
||||
import { ArticleImageBlockWrapper } from '../Article.ImageBlockWrapper'
|
||||
import { PostImageRatio } from '../../Post/Post'
|
||||
import ArticleStats from '../Article.Stats'
|
||||
import { Typography } from '@acid-info/lsd-react'
|
||||
import styled from '@emotion/styled'
|
||||
import ArticleSummary from './Article.Summary'
|
||||
import ArticleSummary, { MobileSummary } from './Article.Summary'
|
||||
import { calcReadingTime } from '@/utils/string.utils'
|
||||
import { Authors } from '@/components/Authors'
|
||||
import { Tags } from '@/components/Tags'
|
||||
@ -14,6 +14,8 @@ import { UnbodyGraphQl } from '@/lib/unbody/unbody-content.types'
|
||||
import { ArticleHeading } from '@/components/Article/Article.Heading'
|
||||
import { useArticleContainerContext } from '@/containers/ArticleContainer.Context'
|
||||
import { useIntersectionObserver } from '@/utils/ui.utils'
|
||||
import { MobileToc } from '@/components/Article/Article.MobileToc'
|
||||
import { useSearchBarContext } from '@/context/searchbar.context'
|
||||
|
||||
const ArticleHeader = ({
|
||||
title,
|
||||
@ -27,6 +29,7 @@ const ArticleHeader = ({
|
||||
}: GoogleDocEnhanced) => {
|
||||
const { setTocId, tocId } = useArticleContainerContext()
|
||||
const headingElementsRef = useIntersectionObserver(setTocId)
|
||||
const { resultsNumber } = useSearchBarContext()
|
||||
|
||||
const _thumbnail = useMemo(() => {
|
||||
const coverImage = getArticleCover(blocks)
|
||||
@ -63,6 +66,7 @@ const ArticleHeader = ({
|
||||
variant: 'h1',
|
||||
genericFontFamily: 'serif',
|
||||
component: 'h1',
|
||||
style: { marginBottom: '16px' },
|
||||
}}
|
||||
headingElementsRef={headingElementsRef}
|
||||
/>
|
||||
@ -77,14 +81,22 @@ const ArticleHeader = ({
|
||||
)}
|
||||
<Tags tags={tags} />
|
||||
<AuthorsContainer>
|
||||
<Authors mentions={mentions} email={true} />
|
||||
<Authors mentions={mentions} email={true} gap={12} />
|
||||
</AuthorsContainer>
|
||||
<MobileCollapseContainer>
|
||||
{resultsNumber === null && <MobileToc toc={toc} />}
|
||||
{resultsNumber === null && <MobileSummary summary={summary} />}
|
||||
</MobileCollapseContainer>
|
||||
{_thumbnail}
|
||||
<ArticleSummary summary={summary} />
|
||||
{/*<ArticleSummary summary={summary}/>*/}
|
||||
</header>
|
||||
)
|
||||
}
|
||||
|
||||
const MobileCollapseContainer = styled.div`
|
||||
margin-bottom: 32px;
|
||||
`
|
||||
|
||||
const CustomTypography = styled(Typography)`
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-word;
|
||||
@ -100,7 +112,9 @@ const ArticleSubtitle = styled(CustomTypography)`
|
||||
`
|
||||
|
||||
const AuthorsContainer = styled.div`
|
||||
margin-block: 24px;
|
||||
//margin-block: 24px;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 32px;
|
||||
`
|
||||
|
||||
export default ArticleHeader
|
||||
|
@ -1,16 +1,57 @@
|
||||
import { Quote } from '@acid-info/lsd-react'
|
||||
import { Typography } from '@acid-info/lsd-react'
|
||||
import styled from '@emotion/styled'
|
||||
import React from 'react'
|
||||
import { Collapse } from '@/components/Collapse'
|
||||
import useIsDarkState from '@/states/isDarkState/isDarkState'
|
||||
|
||||
export const MobileSummary = ({ summary }: { summary: string }) => {
|
||||
const isDark = useIsDarkState().get()
|
||||
return (
|
||||
<SummaryContainerMobile
|
||||
label={'Summary'}
|
||||
initOpen={false}
|
||||
style={{ background: isDark ? 'black' : 'white' }}
|
||||
>
|
||||
<SummaryParagraph variant="h6" component={'p'}>
|
||||
{summary}
|
||||
</SummaryParagraph>
|
||||
</SummaryContainerMobile>
|
||||
)
|
||||
}
|
||||
|
||||
const ArticleSummary = ({ summary }: { summary: string }) => (
|
||||
//TODO for ihor to work out the design for this
|
||||
<ArticleSummaryContainer>
|
||||
<Quote>{summary}</Quote>
|
||||
<Typography variant="body3">summary</Typography>
|
||||
<SummaryParagraph variant="h6" component={'p'}>
|
||||
{summary}
|
||||
</SummaryParagraph>
|
||||
<hr />
|
||||
</ArticleSummaryContainer>
|
||||
)
|
||||
|
||||
const ArticleSummaryContainer = styled('div')`
|
||||
padding-left: 40px;
|
||||
margin-block: 16px;
|
||||
|
||||
> span {
|
||||
margin-bottom: 16px;
|
||||
display: block;
|
||||
}
|
||||
`
|
||||
|
||||
const SummaryParagraph = styled(Typography)`
|
||||
margin-bottom: 32px;
|
||||
display: block;
|
||||
`
|
||||
|
||||
const SummaryContainerMobile = styled(Collapse)`
|
||||
@media (max-width: 770px) {
|
||||
p {
|
||||
padding: 12px 14px;
|
||||
margin-bottom: 0;
|
||||
font-size: var(--lsd-font-size-body2);
|
||||
line-height: var(--lsd-line-height-body2);
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export default ArticleSummary
|
||||
|
@ -46,7 +46,7 @@ export default function ArticleReference({
|
||||
const Container = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 8px 14px;
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid rgb(var(--lsd-border-primary));
|
||||
text-decoration: none;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { UnbodyGraphQl } from '@/lib/unbody/unbody-content.types'
|
||||
import Author from './Author'
|
||||
import styled from '@emotion/styled'
|
||||
import { Typography } from '@acid-info/lsd-react'
|
||||
|
||||
export enum AuthorsDirection {
|
||||
COLUMN = 'column',
|
||||
@ -20,9 +21,16 @@ const Authors = ({
|
||||
}) => {
|
||||
return mentions?.length > 0 ? (
|
||||
<AuthorsContainer gap={gap} flexDirection={flexDirection}>
|
||||
{mentions.map((mention) => (
|
||||
<Author gap={gap} key={mention.name} mention={mention} email={email} />
|
||||
))}
|
||||
{mentions.map((mention, index) =>
|
||||
index < mentions.length - 1 ? (
|
||||
<>
|
||||
<Author key={mention.name} mention={mention} email={email} />
|
||||
<Dot variant={'body2'}>.</Dot>
|
||||
</>
|
||||
) : (
|
||||
<Author key={mention.name} mention={mention} email={email} />
|
||||
),
|
||||
)}
|
||||
</AuthorsContainer>
|
||||
) : null
|
||||
}
|
||||
@ -46,4 +54,9 @@ const AuthorsContainer = styled.div<{
|
||||
} */
|
||||
`
|
||||
|
||||
const Dot = styled(Typography)`
|
||||
transform: translateY(1px);
|
||||
font-size: 18px;
|
||||
`
|
||||
|
||||
export default Authors
|
||||
|
@ -8,6 +8,8 @@ type Props = {
|
||||
children: React.ReactNode
|
||||
className?: string
|
||||
onClick?: () => void
|
||||
initOpen?: boolean
|
||||
style?: React.CSSProperties
|
||||
}
|
||||
|
||||
export default function Collapse({
|
||||
@ -15,9 +17,10 @@ export default function Collapse({
|
||||
children,
|
||||
className,
|
||||
onClick,
|
||||
initOpen = true,
|
||||
...props
|
||||
}: Props) {
|
||||
const [open, setOpen] = useState(true)
|
||||
const [open, setOpen] = useState(initOpen)
|
||||
|
||||
const handleClick = (e: React.MouseEvent<HTMLElement>) => {
|
||||
e.stopPropagation()
|
||||
|
@ -15,7 +15,7 @@ type Props = {
|
||||
|
||||
export default function TableOfContents({ contents, ...props }: Props) {
|
||||
const { tocId, setTocId } = useArticleContainerContext()
|
||||
const dy = uiConfigs.navbarRenderedHeight + uiConfigs.postSectionMargin
|
||||
const dy = uiConfigs.navbarRenderedHeight + 2 * uiConfigs.articleSectionMargin
|
||||
const { resultsNumber } = useSearchBarContext()
|
||||
const router = useRouter()
|
||||
|
||||
@ -46,13 +46,16 @@ export default function TableOfContents({ contents, ...props }: Props) {
|
||||
sticky ? 'sticky' : ''
|
||||
}`}
|
||||
>
|
||||
<Title variant="body3">Contents</Title>
|
||||
<Title variant="body3" component={'div'}>
|
||||
Contents
|
||||
</Title>
|
||||
<Contents height={height}>
|
||||
{contents?.map((content, index) => (
|
||||
<TocItem
|
||||
href={`${index === 0 ? '#' : content.href}`}
|
||||
key={index}
|
||||
active={tocId ? content.href.substring(1) === tocId : index === 0}
|
||||
className={`level-${content.level}`}
|
||||
>
|
||||
<Typography variant="label2" genericFontFamily="sans-serif">
|
||||
{content.title}
|
||||
@ -67,13 +70,10 @@ export default function TableOfContents({ contents, ...props }: Props) {
|
||||
const Container = styled.aside<{ dy: number; height: number }>`
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: column;
|
||||
width: 162px;
|
||||
flex-direction: row;
|
||||
box-sizing: border-box;
|
||||
/* height: ${(p) => (p.height > 0 ? `${p.height}px` : 'fit-content')}; */
|
||||
position: sticky;
|
||||
top: ${(p) => `${p.dy}px`};
|
||||
margin-left: 16px;
|
||||
padding-bottom: 72px;
|
||||
|
||||
transition: opacity 0.3s ease-in-out;
|
||||
@ -96,6 +96,7 @@ const Contents = styled.div<{ height: number }>`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
|
||||
height: calc(
|
||||
100vh -
|
||||
${uiConfigs.navbarRenderedHeight + uiConfigs.postSectionMargin + 40}px
|
||||
@ -108,7 +109,7 @@ const Contents = styled.div<{ height: number }>`
|
||||
|
||||
const TocItem = styled(Link)<{ active: boolean }>`
|
||||
display: flex;
|
||||
padding: 8px 0 8px 12px;
|
||||
padding: 4px 16px 4px 16px;
|
||||
text-decoration: none;
|
||||
border-left: ${(p) =>
|
||||
p.active
|
||||
@ -119,4 +120,12 @@ const TocItem = styled(Link)<{ active: boolean }>`
|
||||
label {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.level-1 {
|
||||
}
|
||||
&.level-2 {
|
||||
}
|
||||
&.level-3 {
|
||||
text-indent: 16px;
|
||||
}
|
||||
`
|
||||
|
@ -2,6 +2,7 @@ export const uiConfigs = {
|
||||
navbarRenderedHeight: 45,
|
||||
postSectionMargin: 108,
|
||||
postSectionMobileMargin: 78,
|
||||
articleSectionMargin: 40,
|
||||
maxContainerWidth: 1400,
|
||||
articleRenderedMT: 45 * 2,
|
||||
}
|
||||
|
@ -22,8 +22,7 @@ const ArticleContainer = (props: Props) => {
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
<Gap className={'w-1'} />
|
||||
<GridItem className={'w-2'}>
|
||||
<GridItem className={'w-3'}>
|
||||
<TableOfContents contents={data.article.toc ?? []} />
|
||||
</GridItem>
|
||||
<Gap className={'w-1'} />
|
||||
|
@ -48,6 +48,9 @@ export default function App({ Component, pageProps }: AppLayoutProps) {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
#__next {
|
||||
|
Loading…
x
Reference in New Issue
Block a user