mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-10 23:57:22 +02:00
feat(v2): add option to toggle sidebar category open by default (#2613)
* feat: update sidebar categ to take collapsed prop * feat: add extra sidebars collapsed test * fix: only mutate item.collapsed if necessary * feat: update docs for SidebarItemCategory * fix: update snapshots * fix: update json to match new sidebar schema * fix: update last snapshot
This commit is contained in:
parent
84fa4be865
commit
1863a3c805
11 changed files with 176 additions and 3 deletions
|
@ -9,25 +9,30 @@ module.exports = {
|
||||||
docs: [
|
docs: [
|
||||||
{
|
{
|
||||||
type: 'category',
|
type: 'category',
|
||||||
|
collapsed: true,
|
||||||
label: 'level 1',
|
label: 'level 1',
|
||||||
items: [
|
items: [
|
||||||
'a',
|
'a',
|
||||||
{
|
{
|
||||||
type: 'category',
|
type: 'category',
|
||||||
|
collapsed: true,
|
||||||
label: 'level 2',
|
label: 'level 2',
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
type: 'category',
|
type: 'category',
|
||||||
|
collapsed: true,
|
||||||
label: 'level 3',
|
label: 'level 3',
|
||||||
items: [
|
items: [
|
||||||
'c',
|
'c',
|
||||||
{
|
{
|
||||||
type: 'category',
|
type: 'category',
|
||||||
|
collapsed: true,
|
||||||
label: 'level 4',
|
label: 'level 4',
|
||||||
items: [
|
items: [
|
||||||
'd',
|
'd',
|
||||||
{
|
{
|
||||||
type: 'category',
|
type: 'category',
|
||||||
|
collapsed: true,
|
||||||
label: 'deeper more more',
|
label: 'deeper more more',
|
||||||
items: ['e'],
|
items: ['e'],
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"type": "category",
|
||||||
|
"label": "Introduction",
|
||||||
|
"items": [
|
||||||
|
"doc1"
|
||||||
|
],
|
||||||
|
"collapsed": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "category",
|
||||||
|
"label": "Powering MDX",
|
||||||
|
"items": [
|
||||||
|
"doc2"
|
||||||
|
],
|
||||||
|
"collapsed": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"docs": {
|
||||||
|
"Test": [
|
||||||
|
{
|
||||||
|
"type": "category",
|
||||||
|
"label": "Introduction",
|
||||||
|
"items": ["doc1"],
|
||||||
|
"collapsed": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Reference": [
|
||||||
|
{
|
||||||
|
"type": "category",
|
||||||
|
"label": "Powering MDX",
|
||||||
|
"items": ["doc2"],
|
||||||
|
"collapsed": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ exports[`simple website content 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"docs": Array [
|
"docs": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"items": Array [
|
"items": Array [
|
||||||
|
@ -36,6 +37,7 @@ Object {
|
||||||
"type": "category",
|
"type": "category",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"href": "/docs/hello",
|
"href": "/docs/hello",
|
||||||
|
@ -200,6 +202,7 @@ exports[`versioned website content: all sidebars 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"docs": Array [
|
"docs": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"href": "/docs/next/foo/bar",
|
"href": "/docs/next/foo/bar",
|
||||||
|
@ -211,6 +214,7 @@ Object {
|
||||||
"type": "category",
|
"type": "category",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"href": "/docs/next/hello",
|
"href": "/docs/next/hello",
|
||||||
|
@ -224,6 +228,7 @@ Object {
|
||||||
],
|
],
|
||||||
"version-1.0.0/docs": Array [
|
"version-1.0.0/docs": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"href": "/docs/1.0.0/foo/bar",
|
"href": "/docs/1.0.0/foo/bar",
|
||||||
|
@ -240,6 +245,7 @@ Object {
|
||||||
"type": "category",
|
"type": "category",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"href": "/docs/1.0.0/hello",
|
"href": "/docs/1.0.0/hello",
|
||||||
|
@ -253,6 +259,7 @@ Object {
|
||||||
],
|
],
|
||||||
"version-1.0.1/docs": Array [
|
"version-1.0.1/docs": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"href": "/docs/foo/bar",
|
"href": "/docs/foo/bar",
|
||||||
|
@ -264,6 +271,7 @@ Object {
|
||||||
"type": "category",
|
"type": "category",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"href": "/docs/hello",
|
"href": "/docs/hello",
|
||||||
|
@ -283,6 +291,7 @@ Object {
|
||||||
"docsSidebars": Object {
|
"docsSidebars": Object {
|
||||||
"version-1.0.0/docs": Array [
|
"version-1.0.0/docs": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"href": "/docs/1.0.0/foo/bar",
|
"href": "/docs/1.0.0/foo/bar",
|
||||||
|
@ -299,6 +308,7 @@ Object {
|
||||||
"type": "category",
|
"type": "category",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"href": "/docs/1.0.0/hello",
|
"href": "/docs/1.0.0/hello",
|
||||||
|
@ -325,6 +335,7 @@ Object {
|
||||||
"docsSidebars": Object {
|
"docsSidebars": Object {
|
||||||
"version-1.0.1/docs": Array [
|
"version-1.0.1/docs": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"href": "/docs/foo/bar",
|
"href": "/docs/foo/bar",
|
||||||
|
@ -336,6 +347,7 @@ Object {
|
||||||
"type": "category",
|
"type": "category",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"href": "/docs/hello",
|
"href": "/docs/hello",
|
||||||
|
@ -361,6 +373,7 @@ Object {
|
||||||
"docsSidebars": Object {
|
"docsSidebars": Object {
|
||||||
"docs": Array [
|
"docs": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"href": "/docs/next/foo/bar",
|
"href": "/docs/next/foo/bar",
|
||||||
|
@ -372,6 +385,7 @@ Object {
|
||||||
"type": "category",
|
"type": "category",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"href": "/docs/next/hello",
|
"href": "/docs/next/hello",
|
||||||
|
|
|
@ -4,6 +4,7 @@ exports[`loadSidebars sidebars link 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"docs": Array [
|
"docs": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"href": "https://github.com",
|
"href": "https://github.com",
|
||||||
|
@ -18,30 +19,107 @@ Object {
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`loadSidebars sidebars with category.collapsed property 1`] = `
|
||||||
|
Object {
|
||||||
|
"docs": Array [
|
||||||
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
|
"items": Array [
|
||||||
|
Object {
|
||||||
|
"collapsed": false,
|
||||||
|
"items": Array [
|
||||||
|
Object {
|
||||||
|
"id": "doc1",
|
||||||
|
"type": "doc",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"label": "Introduction",
|
||||||
|
"type": "category",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"label": "Test",
|
||||||
|
"type": "category",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
|
"items": Array [
|
||||||
|
Object {
|
||||||
|
"collapsed": false,
|
||||||
|
"items": Array [
|
||||||
|
Object {
|
||||||
|
"id": "doc2",
|
||||||
|
"type": "doc",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"label": "Powering MDX",
|
||||||
|
"type": "category",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"label": "Reference",
|
||||||
|
"type": "category",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`loadSidebars sidebars with category.collapsed property at first level 1`] = `
|
||||||
|
Object {
|
||||||
|
"docs": Array [
|
||||||
|
Object {
|
||||||
|
"collapsed": false,
|
||||||
|
"items": Array [
|
||||||
|
Object {
|
||||||
|
"id": "doc1",
|
||||||
|
"type": "doc",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"label": "Introduction",
|
||||||
|
"type": "category",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"collapsed": false,
|
||||||
|
"items": Array [
|
||||||
|
Object {
|
||||||
|
"id": "doc2",
|
||||||
|
"type": "doc",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"label": "Powering MDX",
|
||||||
|
"type": "category",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`loadSidebars sidebars with deep level of category 1`] = `
|
exports[`loadSidebars sidebars with deep level of category 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"docs": Array [
|
"docs": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"id": "a",
|
"id": "a",
|
||||||
"type": "doc",
|
"type": "doc",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"id": "c",
|
"id": "c",
|
||||||
"type": "doc",
|
"type": "doc",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"id": "d",
|
"id": "d",
|
||||||
"type": "doc",
|
"type": "doc",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"id": "e",
|
"id": "e",
|
||||||
|
@ -100,6 +178,7 @@ exports[`loadSidebars sidebars with known sidebar item type 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"docs": Array [
|
"docs": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"id": "foo/bar",
|
"id": "foo/bar",
|
||||||
|
@ -123,6 +202,7 @@ Object {
|
||||||
"type": "category",
|
"type": "category",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"id": "hello",
|
"id": "hello",
|
||||||
|
|
|
@ -4,6 +4,7 @@ exports[`docsVersion first time versioning 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"version-1.0.0/docs": Array [
|
"version-1.0.0/docs": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"items": Array [
|
"items": Array [
|
||||||
|
@ -33,6 +34,7 @@ Object {
|
||||||
"type": "category",
|
"type": "category",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"id": "version-1.0.0/hello",
|
"id": "version-1.0.0/hello",
|
||||||
|
@ -50,6 +52,7 @@ exports[`docsVersion not the first time versioning 1`] = `
|
||||||
Object {
|
Object {
|
||||||
"version-2.0.0/docs": Array [
|
"version-2.0.0/docs": Array [
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"id": "version-2.0.0/foo/bar",
|
"id": "version-2.0.0/foo/bar",
|
||||||
|
@ -60,6 +63,7 @@ Object {
|
||||||
"type": "category",
|
"type": "category",
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
|
"collapsed": true,
|
||||||
"items": Array [
|
"items": Array [
|
||||||
Object {
|
Object {
|
||||||
"id": "version-2.0.0/hello",
|
"id": "version-2.0.0/hello",
|
||||||
|
|
|
@ -126,4 +126,19 @@ describe('loadSidebars', () => {
|
||||||
const result = loadSidebars(null);
|
const result = loadSidebars(null);
|
||||||
expect(result).toEqual({});
|
expect(result).toEqual({});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('sidebars with category.collapsed property', async () => {
|
||||||
|
const sidebarPath = path.join(fixtureDir, 'sidebars-collapsed.json');
|
||||||
|
const result = loadSidebars([sidebarPath]);
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('sidebars with category.collapsed property at first level', async () => {
|
||||||
|
const sidebarPath = path.join(
|
||||||
|
fixtureDir,
|
||||||
|
'sidebars-collapsed-first-level.json',
|
||||||
|
);
|
||||||
|
const result = loadSidebars([sidebarPath]);
|
||||||
|
expect(result).toMatchSnapshot();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,6 +33,7 @@ function normalizeCategoryShorthand(
|
||||||
): SidebarItemCategoryRaw[] {
|
): SidebarItemCategoryRaw[] {
|
||||||
return Object.entries(sidebar).map(([label, items]) => ({
|
return Object.entries(sidebar).map(([label, items]) => ({
|
||||||
type: 'category',
|
type: 'category',
|
||||||
|
collapsed: true,
|
||||||
label,
|
label,
|
||||||
items,
|
items,
|
||||||
}));
|
}));
|
||||||
|
@ -56,7 +57,7 @@ function assertItem(item: Object, keys: string[]): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
function assertIsCategory(item: any): asserts item is SidebarItemCategoryRaw {
|
function assertIsCategory(item: any): asserts item is SidebarItemCategoryRaw {
|
||||||
assertItem(item, ['items', 'label']);
|
assertItem(item, ['items', 'label', 'collapsed']);
|
||||||
if (typeof item.label !== 'string') {
|
if (typeof item.label !== 'string') {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Error loading ${JSON.stringify(item)}. "label" must be a string.`,
|
`Error loading ${JSON.stringify(item)}. "label" must be a string.`,
|
||||||
|
@ -67,6 +68,12 @@ function assertIsCategory(item: any): asserts item is SidebarItemCategoryRaw {
|
||||||
`Error loading ${JSON.stringify(item)}. "items" must be an array.`,
|
`Error loading ${JSON.stringify(item)}. "items" must be an array.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// "collapsed" is an optional property
|
||||||
|
if (item.hasOwnProperty('collapsed') && typeof item.collapsed !== 'boolean') {
|
||||||
|
throw new Error(
|
||||||
|
`Error loading ${JSON.stringify(item)}. "collapsed" must be a boolean.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function assertIsDoc(item: any): asserts item is SidebarItemDoc {
|
function assertIsDoc(item: any): asserts item is SidebarItemDoc {
|
||||||
|
|
|
@ -40,12 +40,14 @@ export interface SidebarItemCategory {
|
||||||
type: 'category';
|
type: 'category';
|
||||||
label: string;
|
label: string;
|
||||||
items: SidebarItem[];
|
items: SidebarItem[];
|
||||||
|
collapsed?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SidebarItemCategoryRaw {
|
export interface SidebarItemCategoryRaw {
|
||||||
type: 'category';
|
type: 'category';
|
||||||
label: string;
|
label: string;
|
||||||
items: SidebarItemRaw[];
|
items: SidebarItemRaw[];
|
||||||
|
collapsed?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SidebarItem =
|
export type SidebarItem =
|
||||||
|
@ -81,6 +83,7 @@ export interface DocsSidebarItemCategory {
|
||||||
type: 'category';
|
type: 'category';
|
||||||
label: string;
|
label: string;
|
||||||
items: DocsSidebarItem[];
|
items: DocsSidebarItem[];
|
||||||
|
collapsed?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DocsSidebarItem = SidebarItemLink | DocsSidebarItemCategory;
|
export type DocsSidebarItem = SidebarItemLink | DocsSidebarItemCategory;
|
||||||
|
|
|
@ -105,8 +105,11 @@ function mutateSidebarCollapsingState(item, path) {
|
||||||
items
|
items
|
||||||
.map((childItem) => mutateSidebarCollapsingState(childItem, path))
|
.map((childItem) => mutateSidebarCollapsingState(childItem, path))
|
||||||
.filter((val) => val).length > 0;
|
.filter((val) => val).length > 0;
|
||||||
// eslint-disable-next-line no-param-reassign
|
// only modify item.collapsed if there are child items active and the category collapsed is set to true
|
||||||
item.collapsed = !anyChildItemsActive;
|
if (anyChildItemsActive && item.collapsed) {
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
item.collapsed = !anyChildItemsActive;
|
||||||
|
}
|
||||||
return anyChildItemsActive;
|
return anyChildItemsActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -207,6 +207,7 @@ type SidebarItemCategory = {
|
||||||
type: 'category';
|
type: 'category';
|
||||||
label: string; // Sidebar label text.
|
label: string; // Sidebar label text.
|
||||||
items: SidebarItem[]; // Array of sidebar items.
|
items: SidebarItem[]; // Array of sidebar items.
|
||||||
|
collapsed: boolean; // Set the category to be collapsed or open by default
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue