diff --git a/.changeset/honest-donkeys-end.md b/.changeset/honest-donkeys-end.md new file mode 100644 index 0000000000..d90bc833b6 --- /dev/null +++ b/.changeset/honest-donkeys-end.md @@ -0,0 +1,6 @@ +--- +'nextra': patch +'nextra-theme-docs': patch +--- + +[nextra/nextra-theme-docs]: support both `experimental.newNextLinkBehavior` - `true` and `false` diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000000..88c5bfd549 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,24 @@ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + reportUnusedDisableDirectives: true, + parserOptions: { + sourceType: 'module', + ecmaVersion: 'latest' + }, + overrides: [ + { + // TODO: enable for `nextra-theme-blog` also + files: 'packages/nextra-theme-docs/**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}', + rules: { + 'no-restricted-imports': [ + 'error', + { + name: 'next/link', + message: 'Use local instead' + } + ] + } + } + ] +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6936bb63db..03310bfedf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,6 +47,9 @@ jobs: - name: Test run: pnpm test + - name: Lint ESLint + run: pnpm lint + - name: Clean run: pnpm clean diff --git a/examples/swr-site/next.config.js b/examples/swr-site/next.config.js index 1ffbece53c..21c1d68fd5 100644 --- a/examples/swr-site/next.config.js +++ b/examples/swr-site/next.config.js @@ -62,4 +62,7 @@ module.exports = withNextra({ ]; }, reactStrictMode: true, + experimental: { + newNextLinkBehavior: true, + }, }); diff --git a/examples/swr-site/pages/blog.en-US.mdx b/examples/swr-site/pages/blog.en-US.mdx index 693a4cdbd4..2d0a4c1405 100644 --- a/examples/swr-site/pages/blog.en-US.mdx +++ b/examples/swr-site/pages/blog.en-US.mdx @@ -7,18 +7,12 @@ searchable: false import { getPagesUnderRoute } from 'nextra/context' import Link from 'next/link' -{getPagesUnderRoute('/blog').map(page => { -// Alias `` to avoid it being replaced by MDX components. -const A = 'a' -return
- - -{page.meta.title || page.frontMatter?.title || page.name} - -

{page.frontMatter?.description}

-

{page.date}

- +{getPagesUnderRoute('/blog').map(page => ( +
+ + {page.meta.title || page.frontMatter?.title || page.name} + +

{page.frontMatter?.description}

+

{page.date}

-})} +))} diff --git a/examples/swr-site/pages/docs/data-fetching.en-US.mdx b/examples/swr-site/pages/docs/data-fetching.en-US.mdx index 8f474adf12..e81f4bb3c5 100644 --- a/examples/swr-site/pages/docs/data-fetching.en-US.mdx +++ b/examples/swr-site/pages/docs/data-fetching.en-US.mdx @@ -1,5 +1,4 @@ import Callout from 'nextra-theme-docs/callout' -import Link from 'next/link' # Data Fetching @@ -13,7 +12,7 @@ The returned value will be passed as `data`, and if it throws, it will be caught Note that fetcher can be omitted from the parameters if it's{' '} - provided globally. + [provided globally](/docs/global-configuration). ## Fetch diff --git a/examples/swr-site/pages/docs/data-fetching.es-ES.mdx b/examples/swr-site/pages/docs/data-fetching.es-ES.mdx index 72613ef2f8..bd2746b47a 100644 --- a/examples/swr-site/pages/docs/data-fetching.es-ES.mdx +++ b/examples/swr-site/pages/docs/data-fetching.es-ES.mdx @@ -1,5 +1,4 @@ import Callout from 'nextra-theme-docs/callout' -import Link from 'next/link' # Obtención De Datos @@ -13,8 +12,8 @@ y devuelve los datos. El valor devuelto será pasado como `data`, y si lanza, será capturado como `error`. - Tenga en cuenta que el fetcher puede ser omitido de los parámetros si se - proporciona globalmente. + Tenga en cuenta que el fetcher puede ser omitido de los parámetros si se + [proporciona globalmente](/docs/global-configuration). ## Fetch diff --git a/examples/swr-site/pages/docs/data-fetching.ja.mdx b/examples/swr-site/pages/docs/data-fetching.ja.mdx index 1b20fda01f..88ee3a547f 100644 --- a/examples/swr-site/pages/docs/data-fetching.ja.mdx +++ b/examples/swr-site/pages/docs/data-fetching.ja.mdx @@ -1,5 +1,4 @@ import Callout from 'nextra-theme-docs/callout' -import Link from 'next/link' # データフェッチ @@ -13,7 +12,7 @@ const { data, error } = useSWR(key, fetcher) fetcher が{' '} - グローバルで提供されている{' '} + [グローバルで提供されている](/docs/global-configuration){' '} 場合は、パラメーターから省略できることに注意してください。 diff --git a/examples/swr-site/pages/docs/data-fetching.ko.mdx b/examples/swr-site/pages/docs/data-fetching.ko.mdx index 50a9cbbeaa..df8e78f268 100644 --- a/examples/swr-site/pages/docs/data-fetching.ko.mdx +++ b/examples/swr-site/pages/docs/data-fetching.ko.mdx @@ -1,5 +1,4 @@ import Callout from 'nextra-theme-docs/callout' -import Link from 'next/link' # 데이터 가져오기 @@ -12,7 +11,7 @@ const { data, error } = useSWR(key, fetcher) 반환된 값은 `data`로 전달되며, 만약 throws라면 `error`로 잡힙니다. - fetcher전역으로 제공된다면 + fetcher가 [전역으로 제공](/docs/global-configuration)된다면 파라미터에서 생략할 수 있습니다. diff --git a/examples/swr-site/pages/docs/data-fetching.ru.mdx b/examples/swr-site/pages/docs/data-fetching.ru.mdx index 9501ed38bd..a3fdf2c5f3 100644 --- a/examples/swr-site/pages/docs/data-fetching.ru.mdx +++ b/examples/swr-site/pages/docs/data-fetching.ru.mdx @@ -1,5 +1,4 @@ import Callout from 'nextra-theme-docs/callout' -import Link from 'next/link' # Выборка данных @@ -13,7 +12,7 @@ const { data, error } = useSWR(key, fetcher) Обратите внимание, что fetcher можно не указывать в параметрах, если он{' '} - предоставляется глобально. + [предоставляется глобально](/docs/global-configuration). ## Выборка (Fetch) diff --git a/examples/swr-site/pages/docs/data-fetching.zh-CN.mdx b/examples/swr-site/pages/docs/data-fetching.zh-CN.mdx index c15b54bc43..e10b087b37 100644 --- a/examples/swr-site/pages/docs/data-fetching.zh-CN.mdx +++ b/examples/swr-site/pages/docs/data-fetching.zh-CN.mdx @@ -1,5 +1,4 @@ import Callout from 'nextra-theme-docs/callout' -import Link from 'next/link' # 数据请求 @@ -12,7 +11,7 @@ const { data, error } = useSWR(key, fetcher) 返回值将作为 `data` 传递,如果抛出错误,将作为 `error` 被捕获。 - 注意:如果 fetcher全局配置提供的,可以从参数中忽略。 + 注意:如果 fetcher 是[全局配置](/docs/global-configuration)提供的,可以从参数中忽略。 ## Fetch diff --git a/examples/swr-site/pages/docs/getting-started.en-US.mdx b/examples/swr-site/pages/docs/getting-started.en-US.mdx index 6a34b25a2a..f0bb15d721 100644 --- a/examples/swr-site/pages/docs/getting-started.en-US.mdx +++ b/examples/swr-site/pages/docs/getting-started.en-US.mdx @@ -1,5 +1,4 @@ import Callout from 'nextra-theme-docs/callout' -import Link from 'next/link' # Getting Started @@ -26,8 +25,8 @@ const fetcher = (...args) => fetch(...args).then(res => res.json()) ``` - If you want to use GraphQL API or libs like Axios, you can create your own fetcher function. - Check here for more examples. + If you want to use GraphQL API or libs like Axios, you can create your own fetcher function. + Check [here](/docs/data-fetching) for more examples. Then you can import `useSWR` and start using it inside any function components: diff --git a/examples/swr-site/pages/docs/getting-started.es-ES.mdx b/examples/swr-site/pages/docs/getting-started.es-ES.mdx index 629c5f833f..26f0387f89 100644 --- a/examples/swr-site/pages/docs/getting-started.es-ES.mdx +++ b/examples/swr-site/pages/docs/getting-started.es-ES.mdx @@ -1,5 +1,4 @@ import Callout from 'nextra-theme-docs/callout' -import Link from 'next/link' # Comienza @@ -28,7 +27,7 @@ const fetcher = (...args) => fetch(...args).then(res => res.json()) Si tu quieres usar API GraphQL o librerías como Axios, puedes crear tu propia función fetcher. Consulta - aqui para ver más ejemplos. + [aqui](/docs/data-fetching) para ver más ejemplos. Luego puede importar `useSWR` y empezar a usarlo dentro de cualquier componente de la función: diff --git a/examples/swr-site/pages/docs/getting-started.ja.mdx b/examples/swr-site/pages/docs/getting-started.ja.mdx index 43c4899e31..39d8faa1f2 100644 --- a/examples/swr-site/pages/docs/getting-started.ja.mdx +++ b/examples/swr-site/pages/docs/getting-started.ja.mdx @@ -1,5 +1,4 @@ import Callout from 'nextra-theme-docs/callout' -import Link from 'next/link' # はじめに @@ -27,7 +26,7 @@ const fetcher = (...args) => fetch(...args).then(res => res.json()) もし GraphQL API または Axios のようなライブラリを使いたい場合は、独自のフェッチャー関数を作ることができます。 - その他の例はこちらをご覧ください。 + その他の例は[こちら](/docs/data-fetching)をご覧ください。 そして、 `useSWR` をインポートして、任意の関数コンポーネント内で使用することができます: diff --git a/examples/swr-site/pages/docs/getting-started.ko.mdx b/examples/swr-site/pages/docs/getting-started.ko.mdx index 9553bf119e..ccb30ce758 100644 --- a/examples/swr-site/pages/docs/getting-started.ko.mdx +++ b/examples/swr-site/pages/docs/getting-started.ko.mdx @@ -1,5 +1,4 @@ import Callout from 'nextra-theme-docs/callout' -import Link from 'next/link' # 시작하기 @@ -26,8 +25,8 @@ const fetcher = (...args) => fetch(...args).then(res => res.json()) ``` - GraphQL API 또는 Axios와 같은 라이브러리를 사용하려면 여러분만의 fetcher 함수를 생성하면 됩니다. - 여기에서 더 많은 예시를 확인하세요. + GraphQL API 또는 Axios와 같은 라이브러리를 사용하려면 여러분만의 fetcher 함수를 생성하면 됩니다. + [여기](/docs/data-fetching)에서 더 많은 예시를 확인하세요. 그 다음, `useSWR`을 임포트하고 함수 컴포넌트 내에서 사용하여 시작하면 됩니다. diff --git a/examples/swr-site/pages/docs/getting-started.ru.mdx b/examples/swr-site/pages/docs/getting-started.ru.mdx index 64a34c60f1..9c64596ac9 100644 --- a/examples/swr-site/pages/docs/getting-started.ru.mdx +++ b/examples/swr-site/pages/docs/getting-started.ru.mdx @@ -1,5 +1,4 @@ import Callout from 'nextra-theme-docs/callout' -import Link from 'next/link' # Начало работы @@ -27,9 +26,9 @@ const fetcher = (...args) => fetch(...args).then(res => res.json()) ``` - Если вы хотите использовать GraphQL API или библиотеки, такие как Axios, вы можете создать свою + Если вы хотите использовать GraphQL API или библиотеки, такие как Axios, вы можете создать свою собственную fetcher-функцию. - Смотрите примеры здесь. + Смотрите примеры [здесь](/docs/data-fetching). Затем можете импортировать `useSWR` и использовать его внутри функциональных компонентов: diff --git a/examples/swr-site/pages/docs/revalidation.en-US.mdx b/examples/swr-site/pages/docs/revalidation.en-US.mdx index 94499f8249..0f69c24019 100644 --- a/examples/swr-site/pages/docs/revalidation.en-US.mdx +++ b/examples/swr-site/pages/docs/revalidation.en-US.mdx @@ -1,12 +1,11 @@ import Video from 'components/video' import Callout from 'nextra-theme-docs/callout' import Bleed from 'nextra-theme-docs/bleed' -import Link from 'next/link' # Automatic Revalidation - If you want to manually revalidate the data, check mutation. + If you want to manually revalidate the data, check [mutation](/docs/mutation). ## Revalidate on Focus diff --git a/examples/swr-site/pages/docs/revalidation.es-ES.mdx b/examples/swr-site/pages/docs/revalidation.es-ES.mdx index a3d138c0da..7da21975de 100644 --- a/examples/swr-site/pages/docs/revalidation.es-ES.mdx +++ b/examples/swr-site/pages/docs/revalidation.es-ES.mdx @@ -1,12 +1,11 @@ import Video from 'components/video' import Callout from 'nextra-theme-docs/callout' import Bleed from 'nextra-theme-docs/bleed' -import Link from 'next/link' # Revalidación Automática - Si quiere revalidar manualmente los datos, compruebe mutation. + Si quiere revalidar manualmente los datos, compruebe [mutation](/docs/mutation). ## Revalidar on focus diff --git a/examples/swr-site/pages/docs/revalidation.ja.mdx b/examples/swr-site/pages/docs/revalidation.ja.mdx index 630fa110dd..d8072fd6a1 100644 --- a/examples/swr-site/pages/docs/revalidation.ja.mdx +++ b/examples/swr-site/pages/docs/revalidation.ja.mdx @@ -1,12 +1,11 @@ import Video from 'components/video' import Callout from 'nextra-theme-docs/callout' import Bleed from 'nextra-theme-docs/bleed' -import Link from 'next/link' # 自動再検証 - データを手動で再検証する場合は、ミューテーションを確認してください。 + データを手動で再検証する場合は、[ミューテーション](/docs/mutation)を確認してください。 ## フォーカス時の再検証 diff --git a/examples/swr-site/pages/docs/revalidation.ko.mdx b/examples/swr-site/pages/docs/revalidation.ko.mdx index 01505dd6f3..0380c95271 100644 --- a/examples/swr-site/pages/docs/revalidation.ko.mdx +++ b/examples/swr-site/pages/docs/revalidation.ko.mdx @@ -1,12 +1,11 @@ import Video from 'components/video' import Callout from 'nextra-theme-docs/callout' import Bleed from 'nextra-theme-docs/bleed' -import Link from 'next/link' # 자동 갱신 - 수동으로 데이터를 갱신하려면 뮤테이션을 확인하세요. + 수동으로 데이터를 갱신하려면 [뮤테이션](/docs/mutation)을 확인하세요. ## 포커스 시에 갱신하기 diff --git a/examples/swr-site/pages/docs/revalidation.ru.mdx b/examples/swr-site/pages/docs/revalidation.ru.mdx index 5e044ed125..def74b0fa9 100644 --- a/examples/swr-site/pages/docs/revalidation.ru.mdx +++ b/examples/swr-site/pages/docs/revalidation.ru.mdx @@ -1,12 +1,11 @@ import Video from 'components/video' import Callout from 'nextra-theme-docs/callout' import Bleed from 'nextra-theme-docs/bleed' -import Link from 'next/link' # Автоматическая ревалидация - Вы можете ревалидировать данные вручную, смотрите мутацию. + Вы можете ревалидировать данные вручную, смотрите [мутацию](/docs/mutation). ## Ревалидация при фокусировке diff --git a/examples/swr-site/pages/docs/revalidation.zh-CN.mdx b/examples/swr-site/pages/docs/revalidation.zh-CN.mdx index 84f179a80f..36fd47b878 100644 --- a/examples/swr-site/pages/docs/revalidation.zh-CN.mdx +++ b/examples/swr-site/pages/docs/revalidation.zh-CN.mdx @@ -1,12 +1,11 @@ import Video from 'components/video' import Callout from 'nextra-theme-docs/callout' import Bleed from 'nextra-theme-docs/bleed' -import Link from 'next/link' # 自动重新请求 - 如果你想手动重新请求数据,请查看 mutation。 + 如果你想手动重新请求数据,请查看 [mutation](/docs/mutation)。 ## 聚焦时重新请求 diff --git a/examples/swr-site/tailwind.config.js b/examples/swr-site/tailwind.config.js index a4014acbce..2ef1626c52 100644 --- a/examples/swr-site/tailwind.config.js +++ b/examples/swr-site/tailwind.config.js @@ -1,10 +1,8 @@ module.exports = { - mode: "jit", + darkMode: "class", content: [ "./components/**/*.js", - "./pages/**/*.md", - "./pages/**/*.mdx", + "./pages/**/*.{md,mdx}", "./theme.config.js", - "./styles.css", ], }; diff --git a/package.json b/package.json index 0dcf0a5765..878bd9a1f6 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "dev": "turbo run dev", "build": "turbo run build:tailwind build --filter=./packages/*", "types:check": "turbo run types:check", + "lint": "eslint --ignore-path .gitignore .", "dev:core": "turbo run dev --filter=nextra...", "dev:theme-blog": "turbo run dev --filter=blog...", "dev:theme-docs": "turbo run dev --filter=swr-site...", @@ -18,6 +19,8 @@ "format": "turbo run format" }, "devDependencies": { + "@typescript-eslint/parser": "^5.31.0", + "eslint": "^8.20.0", "@changesets/cli": "^2.24.1", "@edge-runtime/vm": "1.1.0-beta.23", "postcss-import": "^14.1.0", diff --git a/packages/nextra-theme-docs/src/breadcrumb.tsx b/packages/nextra-theme-docs/src/breadcrumb.tsx index 5bca220b99..4954c804e9 100644 --- a/packages/nextra-theme-docs/src/breadcrumb.tsx +++ b/packages/nextra-theme-docs/src/breadcrumb.tsx @@ -1,12 +1,16 @@ -import React from 'react' -import Link from 'next/link' +import React, { ReactElement } from 'react' +import Anchor from './components/anchor' import cn from 'classnames' import { ArrowRightIcon } from 'nextra/icons' import { Item } from './utils/normalize-pages' -export default function Breadcrumb({ activePath }: { activePath: Item[] }) { +export default function Breadcrumb({ + activePath +}: { + activePath: Item[] +}): ReactElement { return (
{activePath.map((item, index) => { @@ -14,7 +18,7 @@ export default function Breadcrumb({ activePath }: { activePath: Item[] }) { const isActive = index === activePath.length - 1 return ( - + {index ? ( ) : null} @@ -30,9 +34,9 @@ export default function Breadcrumb({ activePath }: { activePath: Item[] }) { title={item.title} > {isLink && !isActive ? ( - - {item.title} - + + {item.title} + ) : ( item.title )} diff --git a/packages/nextra-theme-docs/src/components/anchor.tsx b/packages/nextra-theme-docs/src/components/anchor.tsx new file mode 100644 index 0000000000..eee70f0f77 --- /dev/null +++ b/packages/nextra-theme-docs/src/components/anchor.tsx @@ -0,0 +1,49 @@ +import React, { forwardRef, ComponentProps, ReactElement } from 'react' +// eslint-disable-next-line no-restricted-imports -- only in this file we determine either we include as child of based of `newNextLinkBehavior` value +import NextLink from 'next/link' +import { useConfig } from '../config' + +type AnchorProps = Omit, 'ref'> & { + newWindow?: boolean +} + +const Anchor = forwardRef(function ( + { href = '', children, newWindow, ...props }, + // ref is used in + forwardedRef +): ReactElement { + const config = useConfig() + + if (newWindow) { + return ( + + {children} + + ) + } + + if (config.newNextLinkBehavior) { + return ( + + {children} + + ) + } + + return ( + + + {children} + + + ) +}) + +export default Anchor diff --git a/packages/nextra-theme-docs/src/config.ts b/packages/nextra-theme-docs/src/config.ts index da77db2f00..2e999d89cb 100644 --- a/packages/nextra-theme-docs/src/config.ts +++ b/packages/nextra-theme-docs/src/config.ts @@ -4,6 +4,7 @@ import { DocsThemeConfig } from './types' interface Config extends DocsThemeConfig { unstable_flexsearch?: PageOpts['unstable_flexsearch'] + newNextLinkBehavior?: PageOpts['newNextLinkBehavior'] } export const ThemeConfigContext = createContext({}) diff --git a/packages/nextra-theme-docs/src/flexsearch.jsx b/packages/nextra-theme-docs/src/flexsearch.jsx index f196c47d68..67579125b4 100644 --- a/packages/nextra-theme-docs/src/flexsearch.jsx +++ b/packages/nextra-theme-docs/src/flexsearch.jsx @@ -8,7 +8,6 @@ import React, { } from 'react' import { useRouter } from 'next/router' import cn from 'classnames' -import Link from 'next/link' import FlexSearch from 'flexsearch' import { Transition } from '@headlessui/react' @@ -16,6 +15,7 @@ import { useConfig } from './config' import renderComponent from './utils/render-component' import useMenuContext from './utils/menu-context' import { SpinnerIcon } from 'nextra/icons' +import Anchor from './components/anchor' const Item = ({ page, @@ -34,24 +34,21 @@ const Item = ({ {page}
) : null} - - -
  • -
    - {title} + +
  • +
    {title}
    + {excerpt ? ( +
    + {excerpt}
    - {excerpt ? ( -
    - {excerpt} -
    - ) : null} -
  • -
    - + ) : null} + + ) } diff --git a/packages/nextra-theme-docs/src/footer.tsx b/packages/nextra-theme-docs/src/footer.tsx index 71b15f1956..d50092dafb 100644 --- a/packages/nextra-theme-docs/src/footer.tsx +++ b/packages/nextra-theme-docs/src/footer.tsx @@ -1,6 +1,5 @@ -import React, { PropsWithChildren } from 'react' +import React, { ReactElement } from 'react' import cn from 'classnames' -import Link from 'next/link' import { useRouter } from 'next/router' import { ArrowRightIcon } from 'nextra/icons' @@ -9,6 +8,7 @@ import { useConfig } from './config' import { Item } from './utils/normalize-pages' import LocaleSwitch from './locale-switch' import ThemeSwitch from './theme-switch' +import Anchor from './components/anchor' interface LinkProps { route: string @@ -18,47 +18,45 @@ interface LinkProps { const NextLink = ({ route, title, isRTL }: LinkProps) => { return ( - - - {title} - - - + + {title} + + ) } const PrevLink = ({ route, title, isRTL }: LinkProps) => { return ( - - - - {title} - - + + + {title} + ) } @@ -67,11 +65,12 @@ interface NavLinkProps { currentIndex: number flatDirectories: Item[] } + export const NavLinks = ({ flatDirectories, currentIndex, isRTL -}: NavLinkProps) => { +}: NavLinkProps): ReactElement | null => { const config = useConfig() const prev = config.prevLinks ? flatDirectories[currentIndex - 1] : null const next = config.nextLinks ? flatDirectories[currentIndex + 1] : null @@ -94,7 +93,7 @@ export const NavLinks = ({ ) } -const Footer: React.FC> = ({ menu }) => { +const Footer = ({ menu }: { menu?: boolean }): ReactElement => { const { locale = 'en-US' } = useRouter() const config = useConfig() @@ -103,7 +102,7 @@ const Footer: React.FC> = ({ menu }) => {
    diff --git a/packages/nextra-theme-docs/src/index.tsx b/packages/nextra-theme-docs/src/index.tsx index ac71c7b0ac..5722644914 100644 --- a/packages/nextra-theme-docs/src/index.tsx +++ b/packages/nextra-theme-docs/src/index.tsx @@ -283,7 +283,8 @@ const createLayout = (opts: PageOpts, config: DocsThemeConfig) => { const extendedConfig = { ...defaultConfig, ...config, - unstable_flexsearch: opts.unstable_flexsearch + unstable_flexsearch: opts.unstable_flexsearch, + newNextLinkBehavior: opts.newNextLinkBehavior } const nextThemes = extendedConfig.nextThemes || {} const Page = ({ children }: { children: ReactNode }): ReactNode => children diff --git a/packages/nextra-theme-docs/src/misc/theme.tsx b/packages/nextra-theme-docs/src/misc/theme.tsx index 97e7b4f534..88e053bf2a 100644 --- a/packages/nextra-theme-docs/src/misc/theme.tsx +++ b/packages/nextra-theme-docs/src/misc/theme.tsx @@ -1,4 +1,3 @@ -import Link from 'next/link' import React, { useEffect, useRef, @@ -14,6 +13,7 @@ import Collapse from '../components/collapse' import { Tabs, Tab } from '../components/tabs' import Bleed from '../bleed' import Callout from '../callout' +import Anchor from '../components/anchor' let observer: IntersectionObserver let setActiveAnchor: ( @@ -100,7 +100,7 @@ const createHeaderLink = (Tag: `h${2 | 3 | 4 | 5 | 6}`, context: { index: number useEffect(() => { if (!obRef.current) return - slugs.set(obRef.current, [id, context.index += 1]) + slugs.set(obRef.current, [id, (context.index += 1)]) if (obRef.current) observer.observe(obRef.current) return () => { @@ -122,30 +122,6 @@ const createHeaderLink = (Tag: `h${2 | 3 | 4 | 5 | 6}`, context: { index: number ) } -const A = ({ - children, - ...props -}: { - children?: React.ReactNode - href?: string -}) => { - const isExternal = props.href && props.href.startsWith('https://') - if (isExternal) { - return ( - - {children} - - ) - } - return props.href ? ( - - {children} - - ) : ( - <> - ) -} - const Table = ({ children }: { children: ReactNode }) => { return (
    @@ -239,7 +215,9 @@ export const getComponents = () => { h4: createHeaderLink('h4', context), h5: createHeaderLink('h5', context), h6: createHeaderLink('h6', context), - a: A, + a: ({ href = '', ...props }): ReactElement => ( + + ), table: Table, details: Details, summary: Summary, @@ -259,8 +237,6 @@ export const MDXTheme = ({ children: ReactNode }): ReactElement => { return ( - - {children} - + {children} ) } diff --git a/packages/nextra-theme-docs/src/navbar.tsx b/packages/nextra-theme-docs/src/navbar.tsx index e694f2260e..383fabe180 100644 --- a/packages/nextra-theme-docs/src/navbar.tsx +++ b/packages/nextra-theme-docs/src/navbar.tsx @@ -1,6 +1,5 @@ import React from 'react' import cn from 'classnames' -import Link from 'next/link' import { useRouter } from 'next/router' import { Menu, Transition } from '@headlessui/react' import { ArrowRightIcon } from 'nextra/icons' @@ -14,6 +13,7 @@ import Search from './search' import Flexsearch from './flexsearch' import { GitHubIcon, DiscordIcon, XIcon, MenuIcon } from 'nextra/icons' import { Item, PageItem, MenuItem } from './utils/normalize-pages' +import Anchor from './components/anchor' interface NavBarProps { isRTL?: boolean | null @@ -21,17 +21,6 @@ interface NavBarProps { items: (PageItem | MenuItem)[] } -const NavbarMenuLink = React.forwardRef((props: any, ref) => { - let { href, children, ...rest } = props - return ( - - - {children} - - - ) -}) - function NavbarMenu({ className, menu, @@ -62,28 +51,20 @@ function NavbarMenu({ leaveFrom="opacity-100" leaveTo="opacity-0" > - + {Object.entries(items || {}).map(([key, item]) => { const href = item.href || routes[key]?.route || menu.route + '/' + key return ( - {item.title || key} - + ) })} @@ -138,11 +119,12 @@ export default function Navbar({ flatDirectories, items }: NavBarProps) {