Skip to content

Commit

Permalink
Merge pull request #259 from shuding/shu/8ea1
Browse files Browse the repository at this point in the history
Code refactoring for the docs theme
  • Loading branch information
shuding authored Nov 29, 2021
2 parents b8283b7 + 2789a3c commit ece0ce3
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 42 deletions.
2 changes: 1 addition & 1 deletion packages/nextra-theme-docs/src/footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Link from 'next/link'
import { useRouter } from 'next/router'
import parseGitUrl from 'parse-git-url'

import ArrowRight from './arrow-right'
import ArrowRight from './icons/arrow-right'
import renderComponent from './utils/render-component'

const NextLink = ({ route, title, isRTL }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import React from 'react'

const DiscordIcon = ({ height = 40 }) => {
return (
Expand All @@ -16,7 +16,7 @@ const DiscordIcon = ({ height = 40 }) => {
fill="currentColor"
/>
</svg>
);
};
)
}

export default DiscordIcon;
export default DiscordIcon
34 changes: 11 additions & 23 deletions packages/nextra-theme-docs/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@ import { useRouter } from 'next/router'
import 'focus-visible'
import { SkipNavContent } from '@reach/skip-nav'
import { ThemeProvider } from 'next-themes'
import innerText from 'react-innertext'
import cn from 'classnames'

import normalizePages from './utils/normalize-pages'

import Head from './head'
import Navbar from './navbar'
import Footer, { NavLinks } from './footer'
Expand All @@ -18,8 +15,9 @@ import { ActiveAnchor } from './misc/active-anchor'
import defaultConfig from './misc/default.config'
import { getFSRoute } from './utils/get-fs-route'
import { MenuContext } from './utils/menu-context'

const titleType = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']
import normalizePages from './utils/normalize-pages'
import { getHeadings } from './utils/get-headings'
import { getTitle } from './utils/get-title'

function useDirectoryInfo(pageMap) {
const { locale, defaultLocale, asPath } = useRouter()
Expand Down Expand Up @@ -58,13 +56,6 @@ function Body({ meta, config, toc, filepathWithName, navLinks, children }) {
)
}

const getHeadline = (titles, meta) => {
const titleEl = titles.find(child => child.type === 'h1')
const headline =
meta.title || (titleEl ? innerText(titleEl.props.children) : 'Untitled')
return headline
}

const Layout = ({ filename, config: _config, pageMap, meta, children }) => {
const { route, locale } = useRouter()

Expand All @@ -85,13 +76,9 @@ const Layout = ({ filename, config: _config, pageMap, meta, children }) => {
const content = children.type()
const filepath = route.slice(0, route.lastIndexOf('/') + 1)
const filepathWithName = filepath + filename
const titles =
content.props.children.filter?.(child => titleType.includes(child.type)) ||
[]
const headline = getHeadline(titles, meta)
const anchors = titles
.filter(child => child.props && (config.floatTOC || child.type === 'h2'))
.map(child => child.props.children)
const headings = getHeadings(content.props.children)
const title = meta.title || getTitle(headings) || 'Untitled'

const isRTL = useMemo(() => {
if (!config.i18n) return config.direction === 'rtl' || null
const localeConfig = config.i18n.find(l => l.locale === locale)
Expand All @@ -103,7 +90,7 @@ const Layout = ({ filename, config: _config, pageMap, meta, children }) => {
if (activeType === 'nav') {
return (
<React.Fragment>
<Head config={config} title={headline} locale={locale} meta={meta} />
<Head config={config} title={title} locale={locale} meta={meta} />
<MenuContext.Provider
value={{
menu,
Expand All @@ -130,6 +117,7 @@ const Layout = ({ filename, config: _config, pageMap, meta, children }) => {
flatDirectories={flatDirectories}
fullDirectories={directories}
mdShow={false}
headings={headings}
config={config}
/>
<Body
Expand All @@ -151,7 +139,7 @@ const Layout = ({ filename, config: _config, pageMap, meta, children }) => {
// Docs layout
return (
<React.Fragment>
<Head config={config} title={headline} locale={locale} meta={meta} />
<Head config={config} title={title} locale={locale} meta={meta} />
<MenuContext.Provider
value={{
menu,
Expand All @@ -176,14 +164,14 @@ const Layout = ({ filename, config: _config, pageMap, meta, children }) => {
directories={docsDirectories}
flatDirectories={flatDirectories}
fullDirectories={directories}
anchors={config.floatTOC ? [] : anchors}
headings={headings}
config={config}
/>
<Body
meta={meta}
config={config}
filepathWithName={filepathWithName}
toc={<ToC titles={config.floatTOC ? titles : null} />}
toc={<ToC headings={config.floatTOC ? headings : null} />}
navLinks={
<NavLinks
flatDirectories={flatDocsDirectories}
Expand Down
4 changes: 2 additions & 2 deletions packages/nextra-theme-docs/src/navbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import useMenuContext from './utils/menu-context'

import Search from './search'
import StorkSearch from './stork-search'
import GitHubIcon from './github-icon'
import DiscordIcon from './discord-icon'
import GitHubIcon from './icons/github'
import DiscordIcon from './icons/discord'
import ThemeSwitch from './theme-switch'
import LocaleSwitch from './locale-switch'

Expand Down
30 changes: 25 additions & 5 deletions packages/nextra-theme-docs/src/sidebar.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react'
import React, { useState, useEffect, useMemo } from 'react'
import cn from 'classnames'
import Slugger from 'github-slugger'
import { useRouter } from 'next/router'
Expand Down Expand Up @@ -132,12 +132,19 @@ export default function Sidebar({
directories,
flatDirectories,
fullDirectories,
anchors = [],
mdShow = true,
headings = [],
config
}) {
const { menu } = useMenuContext()
const anchors = useMemo(
() =>
headings
.filter(child => child.props && child.type === 'h2')
.map(child => child.props.children),
[headings]
)

const { menu } = useMenuContext()
useEffect(() => {
if (menu) {
document.body.classList.add('overflow-hidden')
Expand Down Expand Up @@ -170,10 +177,23 @@ export default function Sidebar({
) : null)}
</div>
<div className="hidden md:block">
<Menu directories={directories} anchors={anchors} />
<Menu
directories={directories}
anchors={
// When the viewport size is larger than `md`, hide the anchors in
// the sidebar when `floatTOC` is enabled.
config.floatTOC ? [] : anchors
}
/>
</div>
<div className="md:hidden">
<Menu directories={fullDirectories} anchors={anchors} />
<Menu
directories={fullDirectories}
anchors={
// Always show the anchor links on mobile (`md`).
anchors
}
/>
</div>
</div>
</aside>
Expand Down
14 changes: 7 additions & 7 deletions packages/nextra-theme-docs/src/toc.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,23 @@ const indent = level => {
return {}
}

export default function ToC({ titles }) {
export default function ToC({ headings }) {
const slugger = new Slugger()
const activeAnchor = useActiveAnchor()

return (
<div className="w-64 hidden xl:block text-sm pl-4">
{titles ? (
{headings ? (
<ul className="overflow-y-auto sticky max-h-[calc(100vh-4rem)] top-16 pt-8 pb-10 m-0 list-none">
{titles
.filter(item => item.type !== 'h1')
.map(item => {
const text = innerText(item.props.children) || ''
{headings
.filter(heading => heading.type !== 'h1')
.map(heading => {
const text = innerText(heading.props.children) || ''
const slug = slugger.slug(text)
const state = activeAnchor[slug]

return (
<li key={slug} style={indent(item.type)}>
<li key={slug} style={indent(heading.type)}>
<a
href={`#${slug}`}
className={cn(
Expand Down
5 changes: 5 additions & 0 deletions packages/nextra-theme-docs/src/utils/get-headings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const titleType = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']

export function getHeadings(children) {
return children.filter?.(child => titleType.includes(child.type)) || []
}
6 changes: 6 additions & 0 deletions packages/nextra-theme-docs/src/utils/get-title.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import innerText from 'react-innertext'

export function getTitle(headings) {
const titleEl = headings.find(child => child.type === 'h1')
return titleEl ? innerText(titleEl.props.children) : null
}

0 comments on commit ece0ce3

Please sign in to comment.