Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
at main 3.1 kB view raw
1/* eslint-disable react-hooks/rules-of-hooks */ 2 3import React from 'react'; 4import { Head } from 'react-static'; 5import styled from 'styled-components'; 6import { useMarkdownPage } from 'react-static-plugin-md-pages'; 7import { ScrollToTop } from '../../components/scroll-to-top'; 8 9import { MDXComponents } from '../../components/mdx'; 10 11const Container = styled.main.attrs(() => ({ 12 className: 'page-content', 13}))` 14 flex: 1; 15 width: 100%; 16 display: flex; 17 flex-direction: row-reverse; 18 align-items: flex-start; 19`; 20 21const Content = styled.article.attrs(() => ({ 22 id: 'page-content', 23}))` 24 flex: 1; 25 min-height: calc(100vh - ${p => p.theme.layout.header}); 26 background: ${p => p.theme.colors.bg}; 27 padding: ${p => p.theme.spacing.md}; 28 29 @media ${p => p.theme.media.lg} { 30 padding: ${p => p.theme.spacing.lg}; 31 } 32 33 overflow-wrap: break-word; 34 word-wrap: break-word; 35 word-break: break-word; 36 hyphens: auto; 37`; 38 39const Legend = styled.aside` 40 display: none; 41 42 @media ${({ theme }) => theme.media.lg} { 43 display: block; 44 position: sticky; 45 top: ${p => p.theme.layout.header}; 46 width: 100%; 47 max-width: ${p => p.theme.layout.legend}; 48 padding: ${p => p.theme.spacing.lg} ${p => p.theme.spacing.md}; 49 margin: 0; 50 overflow: auto; 51 height: calc(100vh - ${p => p.theme.layout.header}); 52 } 53`; 54 55const LegendTitle = styled.h3` 56 font-size: ${p => p.theme.fontSizes.body}; 57 font-weight: ${p => p.theme.fontWeights.heading}; 58 margin-bottom: ${p => p.theme.spacing.sm}; 59`; 60 61const HeadingList = styled.ul` 62 list-style-type: none; 63 margin: 0; 64 padding: 0; 65`; 66 67const HeadingItem = styled.li` 68 line-height: ${p => p.theme.lineHeights.heading}; 69 margin-bottom: ${p => p.theme.spacing.xs}; 70 margin-left: ${p => (p.depth >= 3 ? p.theme.spacing.sm : 0)}; 71 72 > a { 73 font-size: ${p => p.theme.fontSizes.small}; 74 font-weight: ${p => 75 p.depth < 3 ? p.theme.fontWeights.links : p.theme.fontWeights.body}; 76 color: ${p => p.theme.colors.passive}; 77 text-decoration: none; 78 } 79`; 80 81const SectionList = () => { 82 const page = useMarkdownPage(); 83 if (!page || !page.headings) return null; 84 85 const title = (page.frontmatter && page.frontmatter.title) || null; 86 const headings = page.headings.filter(x => x.depth > 1); 87 if (headings.length === 0) return null; 88 89 return ( 90 <> 91 {title && ( 92 <Head> 93 <title>{title} | urql Documentation</title> 94 </Head> 95 )} 96 <LegendTitle>In this section</LegendTitle> 97 <HeadingList> 98 {headings.map(heading => ( 99 <HeadingItem key={heading.slug} depth={heading.depth}> 100 <a href={`#${heading.slug}`}>{heading.value}</a> 101 </HeadingItem> 102 ))} 103 </HeadingList> 104 </> 105 ); 106}; 107 108export const ArticleStyling = ({ children, SectionList }) => ( 109 <Container> 110 <Legend>{SectionList && <SectionList />}</Legend> 111 <Content>{children}</Content> 112 </Container> 113); 114 115const Article = ({ children }) => ( 116 <> 117 <ScrollToTop /> 118 <ArticleStyling SectionList={SectionList}> 119 <MDXComponents>{children}</MDXComponents> 120 </ArticleStyling> 121 </> 122); 123 124export default Article;