mirror of
https://github.com/primer/css.git
synced 2025-01-03 11:41:59 +03:00
move outline (toc) logic out of _app.js
This commit is contained in:
parent
847726c593
commit
8907a7e95f
@ -4,6 +4,7 @@ import {MDXProvider} from '@mdx-js/tag'
|
||||
import Head from 'next/head'
|
||||
import {BaseStyles, Box, Flex, Link, theme} from '@primer/components'
|
||||
import {Header, CodeExample, PackageHeader, SideNav, IndexHero} from '../src/components'
|
||||
import getComponents from '../src/markdown'
|
||||
import {rootPage} from '../src/utils'
|
||||
import {CONTENT_MAX_WIDTH} from '../src/constants'
|
||||
|
||||
@ -27,23 +28,8 @@ export default class MyApp extends App {
|
||||
const {Component, page} = this.props
|
||||
|
||||
const node = rootPage.first(node => node.path === pathname)
|
||||
const {meta = {}, outline: getOutline = () => []} = node || {}
|
||||
|
||||
const components = {
|
||||
// render links with our component
|
||||
a: Link,
|
||||
// render the outline for <p> tags with exactly the text "{:toc}"
|
||||
p: ({children, ...rest}) => {
|
||||
if (children === '{:toc}') {
|
||||
return <TableOfContents outline={getOutline()} {...rest} />
|
||||
} else {
|
||||
return <p {...rest}>{children}</p>
|
||||
}
|
||||
},
|
||||
// render code blocks with our wrapper around mdx-live
|
||||
code: CodeExample,
|
||||
pre: props => props.children
|
||||
}
|
||||
const {meta = {}} = node || {}
|
||||
const components = getComponents(node)
|
||||
|
||||
return (
|
||||
<BaseStyles style={{fontFamily: theme.fonts.normal}}>
|
||||
@ -52,9 +38,7 @@ export default class MyApp extends App {
|
||||
<title>Primer CSS{meta.title ? ` / ${meta.title}` : null}</title>
|
||||
</Head>
|
||||
<Header />
|
||||
<Flex
|
||||
flexDirection={['column', 'column', 'column', 'row-reverse']}
|
||||
justifyContent="space-between">
|
||||
<Flex flexDirection={['column', 'column', 'column', 'row-reverse']} justifyContent="space-between">
|
||||
<Box width={['auto', 'auto', 'auto', '80%']}>
|
||||
{meta.hero ? <IndexHero /> : null}
|
||||
<Box color="gray.9" maxWidth={['auto', 'auto', 'auto', CONTENT_MAX_WIDTH]} px={6} mx="auto" my={6}>
|
||||
@ -81,31 +65,3 @@ export default class MyApp extends App {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function TableOfContents({outline, ...rest}) {
|
||||
if (outline && outline.length) {
|
||||
return (
|
||||
<Box is="details" mb={4}>
|
||||
<summary>Table of contents</summary>
|
||||
<List items={outline} {...rest} />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function List({items, ...rest}) {
|
||||
if (items && items.length) {
|
||||
return (
|
||||
<ul {...rest}>
|
||||
{items.map(item => (
|
||||
<li key={item.id}>
|
||||
<a href={`#${item.id}`}>{item.title}</a>
|
||||
<List items={item.children} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import React from 'react'
|
||||
import {withMDXLive} from 'mdx-live'
|
||||
import HTMLtoJSX from 'html-2-jsx'
|
||||
|
||||
@ -10,7 +11,7 @@ const LiveEditor = withMDXLive('pre')
|
||||
|
||||
LiveEditor.defaultProps = {
|
||||
// match ```html and ```jsx fenced code blocks, with or without "."
|
||||
match: /\blanguage\-\.?(html|jsx)\b/
|
||||
match: /\blanguage-\.?(html|jsx)\b/
|
||||
}
|
||||
|
||||
export default function CodeExample(props) {
|
||||
@ -18,9 +19,7 @@ export default function CodeExample(props) {
|
||||
// get children; we need to handle both and convert them to a single string
|
||||
// that we can sanitize
|
||||
const {unsafeInnerHTML, children, ...rest} = props
|
||||
const html = unsafeInnerHTML
|
||||
? unsafeInnerHTML.__html
|
||||
: React.Children.toArray(children).join('\n')
|
||||
const html = unsafeInnerHTML ? unsafeInnerHTML.__html : React.Children.toArray(children).join('\n')
|
||||
const jsx = converter.convert(html)
|
||||
return <LiveEditor {...rest}>{jsx}</LiveEditor>
|
||||
}
|
||||
|
29
docs/src/Outline.js
Normal file
29
docs/src/Outline.js
Normal file
@ -0,0 +1,29 @@
|
||||
import {Box} from '@primer/components'
|
||||
|
||||
export default function Outline({outline, ...rest}) {
|
||||
if (outline && outline.length) {
|
||||
return (
|
||||
<Box is="details" mb={4}>
|
||||
<summary>Table of contents</summary>
|
||||
<TOCList items={outline} {...rest} />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export function OutlineList({items, ...rest}) {
|
||||
if (items && items.length) {
|
||||
return (
|
||||
<ul {...rest}>
|
||||
{items.map(item => (
|
||||
<li key={item.id}>
|
||||
<a href={`#${item.id}`}>{item.title}</a>
|
||||
<OutlineList items={item.children} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
26
docs/src/markdown.js
Normal file
26
docs/src/markdown.js
Normal file
@ -0,0 +1,26 @@
|
||||
import {Heading, Link} from '@primer/components'
|
||||
import CodeExample from './CodeExample'
|
||||
import Outline from './Outline'
|
||||
|
||||
export const H1 = props => <Heading fontSize={6} fontWeight="light" {...props} />
|
||||
|
||||
export default function getComponents(page = {}) {
|
||||
const {outline: getOutline = () => []} = page
|
||||
|
||||
return {
|
||||
h1: H1,
|
||||
// render links with our component
|
||||
a: Link,
|
||||
// render the outline for <p> tags with exactly the text "{:toc}"
|
||||
p: ({children, ...rest}) => {
|
||||
if (children === '{:toc}') {
|
||||
return <Outline outline={getOutline()} {...rest} />
|
||||
} else {
|
||||
return <p {...rest}>{children}</p>
|
||||
}
|
||||
},
|
||||
// render code blocks with our wrapper around mdx-live
|
||||
code: CodeExample,
|
||||
pre: props => props.children
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user