diff --git a/packages/docusaurus-module-type-aliases/src/index.d.ts b/packages/docusaurus-module-type-aliases/src/index.d.ts index 176ca2ec52..5876e36484 100644 --- a/packages/docusaurus-module-type-aliases/src/index.d.ts +++ b/packages/docusaurus-module-type-aliases/src/index.d.ts @@ -122,6 +122,15 @@ declare module '@theme/Root' { export default function Root({children}: Props): ReactNode; } +declare module '@theme/ThemeProvider' { + import type {ReactNode} from 'react'; + + export interface Props { + readonly children: ReactNode; + } + export default function ThemeProvider({children}: Props): ReactNode; +} + declare module '@theme/SiteMetadata' { import type {ReactNode} from 'react'; diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index d005b05806..fd6c864980 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -1569,6 +1569,17 @@ declare module '@theme/ThemedImage' { export default function ThemedImage(props: Props): ReactNode; } +declare module '@theme/ThemeProvider/TitleFormatter' { + import type {ReactNode} from 'react'; + + export interface Props { + readonly children: ReactNode; + } + export default function ThemeProviderTitleFormatter({ + children, + }: Props): ReactNode; +} + declare module '@theme/Details' { import {Details, type DetailsProps} from '@docusaurus/theme-common/Details'; diff --git a/packages/docusaurus-theme-classic/src/theme/ThemeProvider/TitleFormatter/index.tsx b/packages/docusaurus-theme-classic/src/theme/ThemeProvider/TitleFormatter/index.tsx new file mode 100644 index 0000000000..372d0e3f25 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/ThemeProvider/TitleFormatter/index.tsx @@ -0,0 +1,27 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React, {type ComponentProps, type ReactNode} from 'react'; +import {TitleFormatterProvider} from '@docusaurus/theme-common/internal'; +import type {Props} from '@theme/ThemeProvider/TitleFormatter'; + +type FormatterProp = ComponentProps['formatter']; + +const formatter: FormatterProp = (params) => { + // Add your own title formatting logic here! + return params.defaultFormatter(params); +}; + +export default function ThemeProviderTitleFormatter({ + children, +}: Props): ReactNode { + return ( + + {children} + + ); +} diff --git a/packages/docusaurus-theme-classic/src/theme/ThemeProvider/index.tsx b/packages/docusaurus-theme-classic/src/theme/ThemeProvider/index.tsx new file mode 100644 index 0000000000..61f7faad0a --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/ThemeProvider/index.tsx @@ -0,0 +1,14 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React, {type ReactNode} from 'react'; +import TitleFormatterProvider from '@theme/ThemeProvider/TitleFormatter'; +import type {Props} from '@theme/ThemeProvider'; + +export default function ThemeProvider({children}: Props): ReactNode { + return {children}; +} diff --git a/packages/docusaurus/src/client/App.tsx b/packages/docusaurus/src/client/App.tsx index 9e860ef3c7..bf65e4b1f9 100644 --- a/packages/docusaurus/src/client/App.tsx +++ b/packages/docusaurus/src/client/App.tsx @@ -12,6 +12,7 @@ import routes from '@generated/routes'; import {useLocation} from '@docusaurus/router'; import renderRoutes from '@docusaurus/renderRoutes'; import Root from '@theme/Root'; +import ThemeProvider from '@theme/ThemeProvider'; import SiteMetadata from '@theme/SiteMetadata'; import normalizeLocation from './normalizeLocation'; import {BrowserContextProvider} from './browserContext'; @@ -43,10 +44,12 @@ export default function App(): ReactNode { - - - - + + + + + + diff --git a/packages/docusaurus/src/client/theme-fallback/ThemeProvider/index.tsx b/packages/docusaurus/src/client/theme-fallback/ThemeProvider/index.tsx new file mode 100644 index 0000000000..b1f1522549 --- /dev/null +++ b/packages/docusaurus/src/client/theme-fallback/ThemeProvider/index.tsx @@ -0,0 +1,20 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React, {type ReactNode} from 'react'; +import type {Props} from '@theme/ThemeProvider'; + +// Wrapper component expected to be implemented by a theme +// Unlike , it applies to all sites routes and never unmounts +// +// Unlike , the theme is expected to provide an implementation +// is empty and the implementation is expected to be provided by the user +// +// Tree order: Root > ThemeProvider > Layout +export default function ThemeProvider({children}: Props): ReactNode { + return <>{children}; +} diff --git a/website/src/theme/ThemeProvider/TitleFormatter/index.tsx b/website/src/theme/ThemeProvider/TitleFormatter/index.tsx new file mode 100644 index 0000000000..63bc7492b7 --- /dev/null +++ b/website/src/theme/ThemeProvider/TitleFormatter/index.tsx @@ -0,0 +1,29 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React, {type ComponentProps, type ReactNode} from 'react'; +import {TitleFormatterProvider} from '@docusaurus/theme-common/internal'; +import type {Props} from '@theme/ThemeProvider/TitleFormatter'; + +type FormatterProp = ComponentProps['formatter']; + +const formatter: FormatterProp = (params) => { + if (params.title) { + return 'my custom title'; + } + return params.defaultFormatter(params); +}; + +export default function ThemeProviderTitleFormatter({ + children, +}: Props): ReactNode { + return ( + + {children} + + ); +}