mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-01 11:18:24 +02:00
docs(v2): add doc for wrapping theme components with @theme-original and @theme-init (#3502)
* add doc for wrapping theme components * fix tests * Minor improvements Co-authored-by: Alexey Pyltsyn <lex61rus@gmail.com>
This commit is contained in:
parent
9cbca49ecf
commit
dc31dad1de
5 changed files with 58 additions and 8 deletions
|
@ -83,8 +83,6 @@ What this means to the user is that if you wish to use the `CompLibrary` module,
|
|||
|
||||
If you wish to use your own components inside the website directory, use `process.cwd()` which will refer to the `website` directory to construct require paths. For example, if you add a component to `website/core/mycomponent.js`, you can use the require path, `'process.cwd() + /core/mycomponent.js'`.
|
||||
|
||||
There is a special import for custom items `@theme-original`. The `theme-original` alias (just like using `theme` alias) will not get the theme component from the plugin's code. While the `init-theme` alias refers to the proper (theme) component (from the theme itself, where it is first defined). Therefore the `theme-original` is for the user and `theme-initial` is for the plugins.
|
||||
|
||||
## Provided Components
|
||||
|
||||
Docusaurus provides the following components in `CompLibrary`:
|
||||
|
|
|
@ -13,7 +13,7 @@ describe('themeAlias', () => {
|
|||
test('valid themePath 1 with components', () => {
|
||||
const fixtures = path.join(__dirname, '__fixtures__');
|
||||
const themePath = path.join(fixtures, 'theme-1');
|
||||
const alias = themeAlias(themePath);
|
||||
const alias = themeAlias(themePath, true);
|
||||
expect(alias).toEqual({
|
||||
'@theme/Footer': path.join(themePath, 'Footer/index.js'),
|
||||
'@theme-original/Footer': path.join(themePath, 'Footer/index.js'),
|
||||
|
@ -37,7 +37,7 @@ describe('themeAlias', () => {
|
|||
test('valid themePath 2 with components', () => {
|
||||
const fixtures = path.join(__dirname, '__fixtures__');
|
||||
const themePath = path.join(fixtures, 'theme-2');
|
||||
const alias = themeAlias(themePath);
|
||||
const alias = themeAlias(themePath, true);
|
||||
expect(alias).toEqual({
|
||||
'@theme/Navbar': path.join(themePath, 'Navbar.js'),
|
||||
'@theme-original/Navbar': path.join(themePath, 'Navbar.js'),
|
||||
|
@ -62,7 +62,7 @@ describe('themeAlias', () => {
|
|||
const fixtures = path.join(__dirname, '__fixtures__');
|
||||
const themePath = path.join(fixtures, 'empty-theme');
|
||||
fs.ensureDirSync(themePath);
|
||||
const alias = themeAlias(themePath);
|
||||
const alias = themeAlias(themePath, true);
|
||||
expect(alias).toEqual({});
|
||||
});
|
||||
|
||||
|
@ -77,7 +77,7 @@ describe('themeAlias', () => {
|
|||
test('invalid themePath that does not exist', () => {
|
||||
const fixtures = path.join(__dirname, '__fixtures__');
|
||||
const themePath = path.join(fixtures, '__noExist__');
|
||||
const alias = themeAlias(themePath);
|
||||
const alias = themeAlias(themePath, true);
|
||||
expect(alias).toEqual({});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -13,7 +13,7 @@ import {ThemeAlias} from '@docusaurus/types';
|
|||
|
||||
export default function themeAlias(
|
||||
themePath: string,
|
||||
addOriginalAlias: boolean = true,
|
||||
addOriginalAlias: boolean,
|
||||
): ThemeAlias {
|
||||
if (!fs.pathExistsSync(themePath)) {
|
||||
return {};
|
||||
|
|
|
@ -31,7 +31,7 @@ export default function loadThemeAlias(
|
|||
let aliases = {};
|
||||
|
||||
themePaths.forEach((themePath) => {
|
||||
const themeAliases = themeAlias(themePath);
|
||||
const themeAliases = themeAlias(themePath, true);
|
||||
aliases = {...aliases, ...buildThemeAliases(themeAliases, aliases)};
|
||||
});
|
||||
|
||||
|
|
|
@ -101,6 +101,58 @@ npm run swizzle @docusaurus/theme-classic
|
|||
|
||||
**Note**: You need to restart your webpack dev server in order for Docusaurus to know about the new component.
|
||||
|
||||
## Wrapping theme components
|
||||
|
||||
Sometimes, you just want to wrap an existing theme component with additional logic, and it can be a pain to have to maintain an almost duplicate copy of the original theme component.
|
||||
|
||||
In such case, you should swizzle the component you want to wrap, but import the original theme component in your customized version to wrap it.
|
||||
|
||||
### For site owners
|
||||
|
||||
The `@theme-original` alias allows you to import the original theme component.
|
||||
|
||||
Here is an example to display some text just above the footer, with minimal code duplication.
|
||||
|
||||
```js title="src/theme/Footer.js"
|
||||
// Note: importing from "@theme/Footer" would fail due to the file importing itself
|
||||
import OriginalFooter from '@theme-original/Footer';
|
||||
|
||||
export default function Footer(props) {
|
||||
return (
|
||||
<>
|
||||
<div>Before footer</div>
|
||||
<OriginalFooter {...props} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### For plugin authors
|
||||
|
||||
One theme can wrap a component from another theme, by importing the component from the initial theme, using the `@theme-init` import.
|
||||
|
||||
Here's an example of using this feature to enhance the default theme `CodeBlock` component with a `react-live` playground feature.
|
||||
|
||||
```js
|
||||
import InitialCodeBlock from '@theme-init/CodeBlock';
|
||||
|
||||
export default function CodeBlock(props) {
|
||||
return props.live ? (
|
||||
<ReactLivePlayground {...props} />
|
||||
) : (
|
||||
<InitialCodeBlock {...props} />
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Check the code of `docusaurus-theme-live-codeblock` for details.
|
||||
|
||||
:::caution
|
||||
|
||||
Unless you want publish to npm a "theme enhancer" (like `docusaurus-theme-live-codeblock`), you likely don't need `@theme-init`.
|
||||
|
||||
:::
|
||||
|
||||
## Official themes by Docusaurus
|
||||
|
||||
### `@docusaurus/theme-classic`
|
||||
|
|
Loading…
Add table
Reference in a new issue