Skip to content

Commit

Permalink
chore(nextra/blog/docs): improve loaders types
Browse files Browse the repository at this point in the history
  • Loading branch information
dimaMachina committed Jul 24, 2022
1 parent 97e6141 commit 153aee6
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 100 deletions.
7 changes: 7 additions & 0 deletions .changeset/strange-fishes-marry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'nextra': patch
'nextra-theme-blog': patch
'nextra-theme-docs': patch
---

chore(nextra/blog/docs): provide types for PageOpts in loader
7 changes: 7 additions & 0 deletions packages/nextra-theme-blog/src/constants.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react'
import { NextraBlogTheme } from './types'

export const DEFAULT_CONFIG: NextraBlogTheme = {
readMore: 'Read More →',
footer: <small className="block mt-32">CC BY-NC 4.0 2022 © Shu Ding.</small>
}
25 changes: 8 additions & 17 deletions packages/nextra-theme-blog/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import MDXTheme, { HeadingContext } from './mdx-theme'
import traverse from './utils/traverse'
import getTags from './utils/get-tags'
import sortDate from './utils/sort-date'
import type { PageMapItem, PageOpt } from 'nextra'
import type { PageMapItem, PageOpts } from 'nextra'
import type { NextraBlogTheme } from './types'
import { DEFAULT_CONFIG } from './constants'

// comments
const Cusdis = dynamic(
() => import('react-cusdis').then(mod => mod.ReactCusdis),
Expand All @@ -23,7 +25,7 @@ const Cusdis = dynamic(
interface LayoutProps {
config: NextraBlogTheme
contentNodes: React.ReactNode
opts: PageOpt
opts: PageOpts
}

const BlogLayout = ({
Expand Down Expand Up @@ -178,26 +180,15 @@ const BlogLayout = ({
)
}

const createLayout = (opts: PageOpt, _config: NextraBlogTheme) => {
const config: NextraBlogTheme = Object.assign(
{
readMore: 'Read More →',
footer: (
<small className="block mt-32">CC BY-NC 4.0 2022 © Shu Ding.</small>
),
titleSuffix: null,
postFooter: null
},
_config
)
const createLayout = (opts: PageOpts, config: NextraBlogTheme) => {
const extendedConfig = { ...DEFAULT_CONFIG, ...config }

const Page = ({ children }: { children: React.ReactChildren }) => children
const Layout = (page: React.ReactChildren) => (
Page.getLayout = (page: React.ReactChildren) => (
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
<BlogLayout config={config} contentNodes={page} opts={opts} />
<BlogLayout config={extendedConfig} contentNodes={page} opts={opts} />
</ThemeProvider>
)
Page.getLayout = Layout
return Page
}

Expand Down
12 changes: 7 additions & 5 deletions packages/nextra-theme-docs/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { PageOpt } from 'nextra'
import React from 'react'
import { PageOpts } from 'nextra'
import { createContext, useContext } from 'react'
import { DocsThemeConfig } from './types'

interface Config extends DocsThemeConfig {
unstable_flexsearch?: PageOpt['unstable_flexsearch']
unstable_flexsearch?: PageOpts['unstable_flexsearch']
}
export const ThemeConfigContext = React.createContext<Config>({})
export const useConfig = () => React.useContext(ThemeConfigContext)

export const ThemeConfigContext = createContext<Config>({})
export const useConfig = () => useContext(ThemeConfigContext)
38 changes: 15 additions & 23 deletions packages/nextra-theme-docs/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { useMemo, useState } from 'react'
import React, { ReactElement, ReactNode, useMemo, useState } from 'react'
import { useRouter } from 'next/router'
import 'focus-visible'
import { SkipNavContent } from '@reach/skip-nav'
import { ThemeProvider } from 'next-themes'
import { Heading, PageMapItem, PageOpt } from 'nextra'
import { PageMapItem, PageOpts } from 'nextra'
import cn from 'classnames'
import Head from './head'
import Navbar from './navbar'
Expand All @@ -17,7 +17,7 @@ import defaultConfig from './misc/default.config'
import { getFSRoute } from './utils/get-fs-route'
import { MenuContext } from './utils/menu-context'
import normalizePages from './utils/normalize-pages'
import { DocsThemeConfig, Meta, PageTheme } from './types'
import { DocsThemeConfig, PageTheme } from './types'
import './polyfill'
import Breadcrumb from './breadcrumb'
import renderComponent from './utils/render-component'
Expand Down Expand Up @@ -56,7 +56,7 @@ const Body: React.FC<BodyProps> = ({
const date = timestamp ? new Date(timestamp) : null

return (
<React.Fragment>
<>
<SkipNavContent />
{themeContext.layout === 'full' ? (
<article className="nextra-body full relative justify-center overflow-x-hidden pl-[max(env(safe-area-inset-left),1.5rem)] pr-[max(env(safe-area-inset-right),1.5rem)]">
Expand Down Expand Up @@ -119,27 +119,19 @@ const Body: React.FC<BodyProps> = ({
</main>
</article>
)}
</React.Fragment>
</>
)
}
interface LayoutProps {
filename: string
pageMap: PageMapItem[]
meta: Meta
titleText: string | null
headings?: Heading[]
timestamp?: number
}

const Content: React.FC<LayoutProps> = ({
const Content = ({
filename,
pageMap,
meta,
titleText,
headings,
timestamp,
children
}) => {
}: PageOpts & { children: ReactNode }): ReactElement => {
const { route, locale } = useRouter()
const config = useConfig()

Expand Down Expand Up @@ -170,8 +162,6 @@ const Content: React.FC<LayoutProps> = ({

const hideSidebar = !themeContext.sidebar || themeContext.layout === 'raw'
const hideToc = !themeContext.toc || themeContext.layout === 'raw'

const headingArr = headings ?? []
return (
<MenuContext.Provider
value={{
Expand Down Expand Up @@ -215,7 +205,7 @@ const Content: React.FC<LayoutProps> = ({
)
) : (
<ToC
headings={config.floatTOC ? headingArr : null}
headings={config.floatTOC ? headings : null}
filepathWithName={filepathWithName}
/>
)}
Expand Down Expand Up @@ -249,11 +239,13 @@ const Content: React.FC<LayoutProps> = ({
</MenuContext.Provider>
)
}
interface DocsLayoutProps extends PageOpt {
meta: Meta
}
const createLayout = (opts: DocsLayoutProps, config: DocsThemeConfig) => {
const extendedConfig = Object.assign({}, defaultConfig, config, opts)

const createLayout = (opts: PageOpts, config: DocsThemeConfig) => {
const extendedConfig = {
...defaultConfig,
...config,
unstable_flexsearch: opts.unstable_flexsearch
}
const nextThemes = extendedConfig.nextThemes || {}
const Page = ({ children }: { children: React.ReactChildren }) => children

Expand Down
12 changes: 4 additions & 8 deletions packages/nextra/src/compile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@ import remarkGfm from 'remark-gfm'
import rehypePrettyCode from 'rehype-pretty-code'
import { rehypeMdxTitle } from 'rehype-mdx-title';
import { remarkStaticImage } from './mdx-plugins/static-image'
import { remarkHeadings, HeadingMeta } from './mdx-plugins/remark'
import { LoaderOptions } from './types'
import { remarkHeadings } from './mdx-plugins/remark'
import { LoaderOptions, PageOpts } from './types'
import structurize from './mdx-plugins/structurize'
import { parseMeta, attachMeta } from './mdx-plugins/rehype-handler'

// @ts-ignore
import theme from './theme.json'

const createCompiler = (mdxOptions: ProcessorOptions) => {
const compiler = createProcessor(mdxOptions)
compiler.data('headingMeta', {
headings: []
})
compiler.data('headings', [])
return compiler
}

Expand Down Expand Up @@ -82,7 +78,7 @@ export async function compileMdx(
const result = await compiler.process(source)
return {
result: String(result),
...(compiler.data('headingMeta') as HeadingMeta),
headings: compiler.data('headings') as PageOpts['headings'],
structurizedData
}
} catch (err) {
Expand Down
10 changes: 5 additions & 5 deletions packages/nextra/src/content-dump.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ try {
function initFromCache(filename: string) {
if (!cached.has(filename)) {
try {
const content = fs.readFileSync(path.join(assetDir, filename)).toString()
const content = fs.readFileSync(path.join(assetDir, filename), 'utf8')
cached.set(filename, true)
return JSON.parse(content)
} catch (err) {
} catch {
cached.set(filename, false)
}
}
Expand All @@ -40,20 +40,20 @@ export function addPage({
fileLocale,
route,
title,
data,
meta,
structurizedData
}: {
fileLocale: string
route: string
title: string
data: any
meta: Record<string, any>
structurizedData: any
}): void {
const dataFilename = `nextra-data-${fileLocale}.json`

asset[fileLocale] ||= initFromCache(dataFilename)
asset[fileLocale][route] = {
title: title || data.title,
title: title || meta.title,
data: structurizedData
}

Expand Down
28 changes: 14 additions & 14 deletions packages/nextra/src/loader.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { LoaderOptions } from './types'
import type { LoaderOptions, PageOpts } from './types'

import path from 'path'
import grayMatter from 'gray-matter'
Expand Down Expand Up @@ -99,7 +99,7 @@ async function loader(
}

// Extract frontMatter information if it exists
const { data, content } = grayMatter(source)
const { data: meta, content } = grayMatter(source)

let layout = theme
let layoutConfig = themeConfig || null
Expand Down Expand Up @@ -128,12 +128,12 @@ async function loader(

if (unstable_flexsearch) {
// We only add .MD and .MDX contents
if (MARKDOWN_EXTENSION_REGEX.test(filename) && data.searchable !== false) {
if (MARKDOWN_EXTENSION_REGEX.test(filename) && meta.searchable !== false) {
addPage({
fileLocale: fileLocale || DEFAULT_LOCALE,
route,
title,
data,
meta,
structurizedData
})
}
Expand Down Expand Up @@ -171,6 +171,15 @@ async function loader(
? `import __nextra_layoutConfig__ from '${layoutConfig}'`
: ''

const pageOpts: Omit<PageOpts, 'pageMap' | 'titleText'> = {
filename: slash(filename),
route: slash(route),
meta,
headings,
timestamp,
unstable_flexsearch,
}

return `
import __nextra_withLayout__ from '${layout}'
import { withSSG as __nextra_withSSG__ } from 'nextra/ssg'
Expand All @@ -185,18 +194,9 @@ globalThis.__nextra_internal__ = {
}
const NextraLayout = __nextra_withSSG__(__nextra_withLayout__({
filename: "${slash(filename)}",
route: "${slash(route)}",
meta: ${JSON.stringify(data)},
pageMap: __nextra_pageMap__,
titleText: typeof titleText === 'string' ? titleText : undefined,
headings: ${JSON.stringify(headings)},
${timestamp ? `timestamp: ${timestamp},\n` : ''}
${
unstable_flexsearch
? `unstable_flexsearch: ${JSON.stringify(unstable_flexsearch)}`
: ''
}
...${JSON.stringify(pageOpts)}
}, ${layoutConfig ? '__nextra_layoutConfig__' : 'null'}))
function NextraPage(props) {
Expand Down
8 changes: 2 additions & 6 deletions packages/nextra/src/mdx-plugins/rehype-handler.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import Slugger from 'github-slugger'

import { getFlattenedValue } from './remark'

function visit(node, tagNames, handler) {
if (tagNames.includes(node.tagName)) {
handler(node)
return
}
if (node.children) {
node.children.forEach(n => visit(n, tagNames, handler))
}
node.children?.forEach(n => visit(n, tagNames, handler))
}

export function parseMeta() {
Expand Down Expand Up @@ -50,8 +47,7 @@ export function attachMeta() {
}
} else {
// Attach slug
node.properties.id =
node.properties.id || slugger.slug(getFlattenedValue(node))
node.properties.id ||= slugger.slug(getFlattenedValue(node))
}
})
}
Expand Down
13 changes: 4 additions & 9 deletions packages/nextra/src/mdx-plugins/remark.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { Processor } from '@mdx-js/mdx/lib/core'
import { Root, Heading, Parent } from 'mdast'

export interface HeadingMeta {
headings: Heading[]
}
import { PageOpts } from '../types'

function visit(
node: any,
Expand All @@ -13,9 +10,7 @@ function visit(
if (tester(node)) {
handler(node)
}
if (node.children) {
node.children.forEach((n: any) => visit(n, tester, handler))
}
node.children?.forEach((n: any) => visit(n, tester, handler))
}

export function getFlattenedValue(node: Parent): string {
Expand All @@ -31,7 +26,7 @@ export function getFlattenedValue(node: Parent): string {
}

export function remarkHeadings(this: Processor) {
const data = this.data() as any
const data = this.data() as Pick<PageOpts, 'headings'>
return (tree: Root, _file: any, done: () => void) => {
visit(
tree,
Expand All @@ -49,7 +44,7 @@ export function remarkHeadings(this: Processor) {
...(node as Heading),
value: getFlattenedValue(node)
}
data.headingMeta.headings.push(heading)
data.headings.push(heading)
} else if (node.name === 'summary' || node.name === 'details') {
// Replace the <summary> and <details> with customized components.
if (node.data) {
Expand Down

0 comments on commit 153aee6

Please sign in to comment.