feat(v2): allow infinitely nested sidebar (#1812)

* feat(v2): allow infinitely nested sidebar

* Update markdown-features.mdx

* Update sidebar.md

* Update sidebar.md
This commit is contained in:
Endi 2019-10-08 01:52:43 +07:00 committed by Yangshun Tay
parent 1591128cdd
commit 95f0552bad
7 changed files with 282 additions and 41 deletions

View file

@ -1,6 +1,9 @@
# Docusaurus 2 Changelog
## Unreleased
- Docs plugin is rewritten in TypeScript
- Docs sidebar can now be more than one level deep, theoretically up to infinity.
- more documentation ...
## 2.0.0-alpha.25

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2017-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
module.exports = {
docs: [
{
type: 'category',
label: 'level 1',
items: [
'a',
{
type: 'category',
label: 'level 2',
items: [
{
type: 'category',
label: 'level 3',
items: [
'c',
{
type: 'category',
label: 'level 4',
items: [
'd',
{
type: 'category',
label: 'deeper more more',
items: ['e'],
},
],
},
],
},
'f',
],
},
],
},
],
};

View file

@ -1,5 +1,62 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`loadSidebars sidebars with deep level of category 1`] = `
Object {
"docs": Array [
Object {
"items": Array [
Object {
"id": "a",
"type": "doc",
},
Object {
"items": Array [
Object {
"items": Array [
Object {
"id": "c",
"type": "doc",
},
Object {
"items": Array [
Object {
"id": "d",
"type": "doc",
},
Object {
"items": Array [
Object {
"id": "e",
"type": "doc",
},
],
"label": "deeper more more",
"type": "category",
},
],
"label": "level 4",
"type": "category",
},
],
"label": "level 3",
"type": "category",
},
Object {
"id": "f",
"type": "doc",
},
],
"label": "level 2",
"type": "category",
},
],
"label": "level 1",
"type": "category",
},
],
}
`;
exports[`loadSidebars sidebars with known sidebar item type 1`] = `
Object {
"docs": Array [

View file

@ -22,6 +22,17 @@ describe('loadSidebars', () => {
expect(result).toMatchSnapshot();
});
test('sidebars with deep level of category', async () => {
const sidebarPath = path.join(
__dirname,
'__fixtures__',
'website',
'sidebars-category.js',
);
const result = loadSidebars(sidebarPath);
expect(result).toMatchSnapshot();
});
test('sidebars with unknown sidebar item type', async () => {
const sidebarPath = path.join(
__dirname,

View file

@ -40,14 +40,6 @@ function normalizeCategory(
category: SidebarItemCategoryRaw,
level = 0,
): SidebarItemCategory {
if (level === 2) {
throw new Error(
`Can not process ${
category.label
} category. Categories can be nested only one level deep.`,
);
}
assertItem(category, ['items', 'label']);
if (!Array.isArray(category.items)) {

View file

@ -143,6 +143,19 @@ I can write **Markdown** alongside my _JSX_!
You can also import your own components defined in other files or third-party components installed via npm! Check out the [MDX docs](https://mdxjs.com/) to see what other fancy stuff you can do with MDX.
### Referencing other documents
If you want to reference another document file, you should use the name of the document you want to reference. Docusaurus will convert the file path to be the final website path (and remove the `.md`).
For example, if you are in `doc2.md` and you want to reference `doc1.md` and `folder/doc3.md`:
```md
I am referencing a [document](doc1.md).
Reference to another [document in a folder](folder/doc3.md)
```
One benefit of this approach is that the links to external files will still work if you are viewing the file on GitHub.
### Syntax highlighting
Code blocks are text blocks wrapped around by strings of 3 backticks. You may check out [this reference](https://github.com/mdx-js/specification) for specifications of MDX.

View file

@ -3,49 +3,180 @@ id: sidebar
title: Sidebar
---
To generate a sidebar to your Docusaurus site, you need to define a file that exports a JS module and pass that into the `@docusaurus/plugin-docs` plugin directly or via `@docusaurus/preset-classic`. If you are using the classic preset, you can find the `sidebars.js` under the root directory already created for you, so you may edit it directly for customization.
To generate a sidebar to your Docusaurus site, you need to define a file that exports a sidebar object and pass that into the `@docusaurus/plugin-docs` plugin directly or via `@docusaurus/preset-classic`.
<!-- TODO: change classic template to use `sidebars.js` from json -->
```bash
website # root directory of your site
├── docs
│   └── greeting.md
├── docusaurus.config.js
├── sidebars.js
.
```js
// docusaurus.config.js
module.exports = {
// ...
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
// Sidebars filepath relative to the site dir.
sidebarPath: require.resolve('./sidebars.js'),
},
...
},
],
],
};
```
To add a doc to the sidebar, add the `id` specified in the frontmatter of the doc into its category.
## Sidebar object
```diff
A sidebar object looks like the following. The key `docs` is the name of the sidebar (can be renamed to something else) and `Getting Started` is a category within the sidebar. `greeting` and `doc1` is just a [Sidebar Item](#sidebar-item).
```js
// sidebars.js
module.exports = {
docs: {
+ "Getting started": ["greeting"],
"Docusaurus": ["doc1"],
"First Category": ["doc2"],
"Second Category": ["doc3"],
'Getting started': ['greeting'],
'Docusaurus': ['doc1'],
}
};
```
The `docs` key in the exported object is just the name of that particular sidebar hierarchy, and can be renamed to something else. You can have multiple sidebars for different Markdown files by adding more top-level keys to the exported object.
If you don't want to rely on iteration order of JavaScript object keys for the category name, the following sidebar object is also equivalent of the above.
## Subcategories
```js
// sidebars.js
module.exports = {
docs: [
{
type: 'category',
label: 'Getting Started',
items: ['greeting']
},
{
type: 'category',
label: 'Docusaurus',
items: ['doc1']
},
]
};
```
To include subcategories in docs sidebar, use an object of the following shape
You can also have multiple sidebars for different Markdown files by adding more top-level keys to the exported object.
Example:
```js
// sidebars.js
module.exports = {
firstSidebar: {
'Category A': ['doc1'],
},
secondSidebar: {
'Category A': ['doc2'],
'Category B': ['doc3'],
}
};
```
## Document ID
Every document has a unique `id`. By default, a document `id` is the name of the document (without the extension) relative to the root docs directory.
For example, `greeting.md` id is `greeting` and `guide/hello.md` id is `guide/hello`.
```bash
website # root directory of your site
├── docs
   └── greeting.md
└── guide
└── hello.md
```
However, the last part of the `id` can be defined by user in the frontmatter. For example, if `guide/hello.md` content is defined as below, it's final `id` is `guide/part1`.
```md
---
id: part1
---
Lorem ipsum
```
## Sidebar item
As the name implies, `SidebarItem` is an item defined in a Sidebar. There are a few types we support:
- Doc
- Link
- Ref
- Category
### Doc
Sidebar item type that links to a doc page. Example:
```js
{
type: 'doc',
id: 'doc1', // string - document id
}
```
Using just the [Document ID](#document-id) is perfectly valid as well, the following is equivalent to the above:
```js
'doc1' // string - document id
```
Note that using this type will bind the linked doc to current sidebar, this means that if you access `doc1` page, the sidebar displayed will be the sidebar this item is on. For below case, `doc1` is bounded to `firstSidebar`.
```js
// sidebars.js
module.exports = {
firstSidebar: {
'Category A': ['doc1'],
},
secondSidebar: {
'Category A': ['doc2'],
'Category B': ['doc3'],
}
};
```
### Link
Sidebar item type that links to a non-document page. Example:
```js
{
type: 'link',
label: 'Custom Label', // string - the label that should be displayed.
href: 'https://example.com' // string - the target URL.
}
```
### Ref
Sidebar item type that links to doc without bounding it to the sidebar. Example:
```js
{
type: 'ref',
id: 'doc1', // string - document id
}
```
### Category
This is used to add hierarchies to the sidebar:
```js
{
type: 'category',
label: string, // sidebar label
items: string[], // strings of doc ids
label: string, // Sidebar label text.
items: SidebarItem[], // Array of sidebar items.
}
```
in place of a string of id. As an example, here's how we created the subcategory for "Docs" under "Guides" in this site:
As an example, here's how we created the subcategory for "Docs" under "Guides" in this site:
```jsx
```js
// sidebars.js
module.exports = {
docs: {
@ -60,13 +191,3 @@ module.exports = {
},
};
```
**Note**: Only one layer of nestedness is allowed.
**Note**: We're implementing a new sidebar!
<!--
_This section is a work in progress. [Welcoming PRs](https://github.com/facebook/docusaurus/issues/1640)._
-->