mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-01 03:08:17 +02:00
fix(content-docs): render category with no subitems as a normal link (#6495)
This commit is contained in:
parent
049b2c84c6
commit
3573b5e4a9
6 changed files with 120 additions and 5 deletions
|
@ -209,6 +209,12 @@ describe('processSidebars', () => {
|
||||||
// typing error needing refactor
|
// typing error needing refactor
|
||||||
permalink: undefined,
|
permalink: undefined,
|
||||||
},
|
},
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
type: 'doc',
|
||||||
|
id: 'foo',
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -232,11 +238,73 @@ describe('processSidebars', () => {
|
||||||
slug: 'generated-cat-index-slug',
|
slug: 'generated-cat-index-slug',
|
||||||
permalink: '/docs/1.0.0/generated-cat-index-slug',
|
permalink: '/docs/1.0.0/generated-cat-index-slug',
|
||||||
},
|
},
|
||||||
items: [],
|
items: [
|
||||||
|
{
|
||||||
|
type: 'doc',
|
||||||
|
id: 'foo',
|
||||||
|
},
|
||||||
|
],
|
||||||
collapsible: true,
|
collapsible: true,
|
||||||
collapsed: true,
|
collapsed: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} as Sidebars);
|
} as Sidebars);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('transforms category without subitems', async () => {
|
||||||
|
const sidebarSlice: SidebarItem[] = [
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
label: 'Category',
|
||||||
|
link: {
|
||||||
|
type: 'generated-index',
|
||||||
|
permalink: 'generated/permalink',
|
||||||
|
},
|
||||||
|
items: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
label: 'Category 2',
|
||||||
|
link: {
|
||||||
|
type: 'doc',
|
||||||
|
id: 'doc ID',
|
||||||
|
},
|
||||||
|
items: [],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const processedSidebar = await testProcessSidebars(
|
||||||
|
{sidebar: sidebarSlice},
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(processedSidebar).toEqual({
|
||||||
|
sidebar: [
|
||||||
|
{
|
||||||
|
type: 'link',
|
||||||
|
label: 'Category',
|
||||||
|
href: 'generated/permalink',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'doc',
|
||||||
|
label: 'Category 2',
|
||||||
|
id: 'doc ID',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
} as Sidebars);
|
||||||
|
|
||||||
|
await expect(async () => {
|
||||||
|
await testProcessSidebars({
|
||||||
|
sidebar: [
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
label: 'Bad category',
|
||||||
|
items: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}).rejects.toThrowErrorMatchingInlineSnapshot(
|
||||||
|
`"Sidebar category Bad category has neither any subitem nor a link. This makes this item not able to link to anything."`,
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -117,6 +117,34 @@ async function processSidebar(
|
||||||
item: NormalizedSidebarItem,
|
item: NormalizedSidebarItem,
|
||||||
): Promise<SidebarItem[]> {
|
): Promise<SidebarItem[]> {
|
||||||
if (item.type === 'category') {
|
if (item.type === 'category') {
|
||||||
|
// If the current category doesn't have subitems, we render a normal doc link instead.
|
||||||
|
if (item.items.length === 0) {
|
||||||
|
if (!item.link) {
|
||||||
|
throw new Error(
|
||||||
|
`Sidebar category ${item.label} has neither any subitem nor a link. This makes this item not able to link to anything.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
switch (item.link.type) {
|
||||||
|
case 'doc':
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: 'doc',
|
||||||
|
label: item.label,
|
||||||
|
id: item.link.id,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
case 'generated-index':
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: 'link',
|
||||||
|
label: item.label,
|
||||||
|
href: item.link.permalink,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
default:
|
||||||
|
throw new Error('Unexpected sidebar category link type');
|
||||||
|
}
|
||||||
|
}
|
||||||
return [await processCategoryItem(item)];
|
return [await processCategoryItem(item)];
|
||||||
}
|
}
|
||||||
if (item.type === 'autogenerated') {
|
if (item.type === 'autogenerated') {
|
||||||
|
|
|
@ -39,9 +39,6 @@ export default function DocSidebarItem({
|
||||||
}: Props): JSX.Element | null {
|
}: Props): JSX.Element | null {
|
||||||
switch (item.type) {
|
switch (item.type) {
|
||||||
case 'category':
|
case 'category':
|
||||||
if (item.items.length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return <DocSidebarItemCategory item={item} {...props} />;
|
return <DocSidebarItemCategory item={item} {...props} />;
|
||||||
case 'link':
|
case 'link':
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
# No sub-docs
|
||||||
|
|
||||||
|
The only doc of this category is the index page. It should show up as a regular doc link.
|
|
@ -82,7 +82,13 @@ function generateHugeSidebarItems() {
|
||||||
|
|
||||||
function generateRecursive(maxLevel, currentLevel = 0) {
|
function generateRecursive(maxLevel, currentLevel = 0) {
|
||||||
if (currentLevel === maxLevel) {
|
if (currentLevel === maxLevel) {
|
||||||
return [];
|
return [
|
||||||
|
{
|
||||||
|
type: 'link',
|
||||||
|
href: '/',
|
||||||
|
label: `Link (level ${currentLevel + 1})`,
|
||||||
|
},
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
const linkItems = [...Array(linksCount).keys()].map((index) => ({
|
const linkItems = [...Array(linksCount).keys()].map((index) => ({
|
||||||
|
|
|
@ -194,6 +194,19 @@ Naming your introductory document `README.md` makes it show up when browsing the
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
|
||||||
|
If a folder only has one index page, it will be turned into a link instead of a category. This is useful for **asset collocation**:
|
||||||
|
|
||||||
|
```
|
||||||
|
some-doc
|
||||||
|
├── index.md
|
||||||
|
├── img1.png
|
||||||
|
└── img2.png
|
||||||
|
```
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary>Customizing category index matching</summary>
|
<summary>Customizing category index matching</summary>
|
||||||
|
|
Loading…
Add table
Reference in a new issue