diff --git a/v2/.eslintrc.js b/v2/.eslintrc.js
index f46f89afb2..2d8ce0fadb 100644
--- a/v2/.eslintrc.js
+++ b/v2/.eslintrc.js
@@ -9,7 +9,7 @@ module.exports = {
jest: true,
node: true,
},
- extends: ['airbnb', 'prettier'],
+ extends: ['airbnb', 'prettier', 'prettier/react'],
rules: {
'no-console': OFF,
'func-names': OFF,
diff --git a/v2/lib/load/docs/metadata.js b/v2/lib/load/docs/metadata.js
index 4f147743c5..54df3a99d2 100644
--- a/v2/lib/load/docs/metadata.js
+++ b/v2/lib/load/docs/metadata.js
@@ -151,6 +151,7 @@ module.exports = async function processMetadata(
if (order[id]) {
metadata.sidebar = order[id].sidebar;
metadata.category = order[id].category;
+ metadata.subCategory = order[id].subCategory;
if (order[id].next) {
metadata.next_id = order[id].next;
metadata.next = (language ? `${language}-` : '') + order[id].next;
diff --git a/v2/lib/load/docs/order.js b/v2/lib/load/docs/order.js
index 52c8ca9a7e..ddf5757da1 100644
--- a/v2/lib/load/docs/order.js
+++ b/v2/lib/load/docs/order.js
@@ -9,11 +9,26 @@ module.exports = function createOrder(allSidebars = {}) {
let ids = [];
const categoryOrder = [];
+ const subCategoryOrder = [];
Object.keys(categories).forEach(category => {
- ids = ids.concat(categories[category]);
- // eslint-disable-next-line
- for (let i = 0; i < categories[category].length; i++) {
- categoryOrder.push(category);
+ if (Array.isArray(categories[category])) {
+ ids = ids.concat(categories[category]);
+
+ // eslint-disable-next-line
+ for (let i = 0; i < categories[category].length; i++) {
+ categoryOrder.push(category);
+ subCategoryOrder.push(undefined);
+ }
+ } else {
+ Object.keys(categories[category]).forEach(subCategory => {
+ ids = ids.concat(categories[category][subCategory]);
+
+ // eslint-disable-next-line
+ for (let i = 0; i < categories[category][subCategory].length; i++) {
+ categoryOrder.push(category);
+ subCategoryOrder.push(subCategory);
+ }
+ });
}
});
@@ -29,6 +44,7 @@ module.exports = function createOrder(allSidebars = {}) {
next,
sidebar,
category: categoryOrder[i],
+ subCategory: subCategoryOrder[i],
};
}
});
diff --git a/v2/lib/theme/Sidebar/index.js b/v2/lib/theme/Sidebar/index.js
index 30aa6c09f5..8a78166ef3 100644
--- a/v2/lib/theme/Sidebar/index.js
+++ b/v2/lib/theme/Sidebar/index.js
@@ -12,37 +12,56 @@ function Sidebar(props) {
return null;
}
const thisSidebar = docsSidebars[sidebar];
+
+ const renderItemLink = rawLinkID => {
+ const linkID = (language ? `${language}-` : '') + rawLinkID;
+ const linkMetadata = docsMetadatas[linkID];
+ if (!linkMetadata) {
+ throw new Error(
+ `Improper sidebars.json file, document with id '${linkID}' not found.`,
+ );
+ }
+ const activeItem = linkID === thisID;
+ return (
+
+
+ {linkMetadata.sidebar_label || linkMetadata.title}
+
+
+ );
+ };
+
+ const renderCategory = categoryName => {
+ const category = thisSidebar[categoryName];
+ return (
+
+
{categoryName}
+
+ {Array.isArray(category)
+ ? category.map(renderItemLink)
+ : Object.keys(category).map(subCategoryName => (
+
+
+ {subCategoryName}
+
+
+ {category[subCategoryName].map(renderItemLink)}
+
+
+ ))}
+
+
+ );
+ };
+
return (
thisSidebar && (
- {Object.keys(thisSidebar).map(categoryName => (
-
-
{categoryName}
-
- {thisSidebar[categoryName].map(rawLinkID => {
- const linkID = (language ? `${language}-` : '') + rawLinkID;
- const linkMetadata = docsMetadatas[linkID];
- if (!linkMetadata) {
- throw new Error(
- `Improper sidebars.json file, document with id '${linkID}' not found.`,
- );
- }
- const activeItem = linkID === thisID;
- return (
- -
-
- {linkMetadata.sidebar_label || linkMetadata.title}
-
-
- );
- })}
-
-
- ))}
+ {Object.keys(thisSidebar).map(renderCategory)}
)
);
diff --git a/v2/lib/theme/Sidebar/styles.css b/v2/lib/theme/Sidebar/styles.css
index 804e7636b9..36fc0f129a 100644
--- a/v2/lib/theme/Sidebar/styles.css
+++ b/v2/lib/theme/Sidebar/styles.css
@@ -7,7 +7,18 @@
margin-bottom: 20px;
}
+.sidebarSubGroup {
+ margin-top: 10px;
+ margin-left: 10px;
+}
+
+.sidebarSubGroupTitle {
+ font-size: 16px;
+ margin: 0;
+}
+
.sidebarGroupTitle {
+ font-size: 18px;
margin: 0;
}
diff --git a/v2/package.json b/v2/package.json
index a0aefaaad1..9beb3c5fea 100644
--- a/v2/package.json
+++ b/v2/package.json
@@ -38,7 +38,7 @@
"eslint-config-prettier": "^2.9.0",
"eslint-plugin-import": "^2.12.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
- "eslint-plugin-react": "^7.9.1",
+ "eslint-plugin-react": "^7.11.1",
"jest": "^23.4.2",
"prettier": "^1.13.7"
},
diff --git a/v2/test/load/docs/order.test.js b/v2/test/load/docs/order.test.js
index f37b93684b..dd9cd8982f 100644
--- a/v2/test/load/docs/order.test.js
+++ b/v2/test/load/docs/order.test.js
@@ -1,7 +1,58 @@
import createOrder from '@lib/load/docs/order';
describe('createOrder', () => {
- test('should populate docs index from multiple sidebars', () => {
+ test('multiple sidebars with subcategory', () => {
+ const result = createOrder({
+ docs: {
+ Category1: {
+ 'Subcategory 1': ['doc1'],
+ 'Subcategory 2': ['doc2'],
+ },
+ Category2: ['doc3', 'doc4'],
+ },
+ otherDocs: {
+ Category1: ['doc5'],
+ },
+ });
+ expect(result).toEqual({
+ doc1: {
+ category: 'Category1',
+ subCategory: 'Subcategory 1',
+ next: 'doc2',
+ previous: undefined,
+ sidebar: 'docs',
+ },
+ doc2: {
+ category: 'Category1',
+ subCategory: 'Subcategory 2',
+ next: 'doc3',
+ previous: 'doc1',
+ sidebar: 'docs',
+ },
+ doc3: {
+ category: 'Category2',
+ subCategory: undefined,
+ next: 'doc4',
+ previous: 'doc2',
+ sidebar: 'docs',
+ },
+ doc4: {
+ category: 'Category2',
+ subCategory: undefined,
+ next: undefined,
+ previous: 'doc3',
+ sidebar: 'docs',
+ },
+ doc5: {
+ category: 'Category1',
+ subCategory: undefined,
+ next: undefined,
+ previous: undefined,
+ sidebar: 'otherDocs',
+ },
+ });
+ });
+ test('multiple sidebars without subcategory', () => {
const result = createOrder({
docs: {
Category1: ['doc1', 'doc2'],
@@ -14,30 +65,35 @@ describe('createOrder', () => {
expect(result).toEqual({
doc1: {
category: 'Category1',
+ subCategory: undefined,
next: 'doc2',
previous: undefined,
sidebar: 'docs',
},
doc2: {
category: 'Category1',
+ subCategory: undefined,
next: 'doc3',
previous: 'doc1',
sidebar: 'docs',
},
doc3: {
category: 'Category2',
+ subCategory: undefined,
next: 'doc4',
previous: 'doc2',
sidebar: 'docs',
},
doc4: {
category: 'Category2',
+ subCategory: undefined,
next: undefined,
previous: 'doc3',
sidebar: 'docs',
},
doc5: {
category: 'Category1',
+ subCategory: undefined,
next: undefined,
previous: undefined,
sidebar: 'otherDocs',
@@ -45,7 +101,7 @@ describe('createOrder', () => {
});
});
- test('should resolve docs from older versions', () => {
+ test('versioned sidebars', () => {
const result = createOrder({
docs: {
Category1: ['doc1'],
@@ -58,18 +114,21 @@ describe('createOrder', () => {
expect(result).toEqual({
doc1: {
category: 'Category1',
+ subCategory: undefined,
next: undefined,
previous: undefined,
sidebar: 'docs',
},
'version-1.2.3-doc1': {
category: 'Category2',
+ subCategory: undefined,
next: undefined,
previous: 'version-1.2.3-doc2',
sidebar: 'version-1.2.3-docs',
},
'version-1.2.3-doc2': {
category: 'Category1',
+ subCategory: undefined,
next: 'version-1.2.3-doc1',
previous: undefined,
sidebar: 'version-1.2.3-docs',
diff --git a/v2/website/sidebars.json b/v2/website/sidebars.json
index 0c61221124..2c19635528 100644
--- a/v2/website/sidebars.json
+++ b/v2/website/sidebars.json
@@ -1,9 +1,9 @@
{
"docs": {
- "Foo": [
- "foo/bar",
- "foo/baz"
- ],
+ "Foo": {
+ "bar": ["foo/bar"],
+ "baz": ["foo/baz"]
+ },
"Endi": [
"docusaurus",
"highlight",
diff --git a/v2/yarn.lock b/v2/yarn.lock
index 5130af4c03..fba0b194f5 100644
--- a/v2/yarn.lock
+++ b/v2/yarn.lock
@@ -2527,10 +2527,11 @@ eslint-plugin-jsx-a11y@^6.0.3:
has "^1.0.3"
jsx-ast-utils "^2.0.1"
-eslint-plugin-react@^7.9.1:
- version "7.10.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.10.0.tgz#af5c1fef31c4704db02098f9be18202993828b50"
+eslint-plugin-react@^7.11.1:
+ version "7.11.1"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz#c01a7af6f17519457d6116aa94fc6d2ccad5443c"
dependencies:
+ array-includes "^3.0.3"
doctrine "^2.1.0"
has "^1.0.3"
jsx-ast-utils "^2.0.1"