mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-05 13:17:23 +02:00
fix: change subcategory format (#1026)
* fix: change subcategory format * Fix sidebars * Refactor * Fix implementation * Change format
This commit is contained in:
parent
c277f46a60
commit
fe500dea82
19 changed files with 493 additions and 15047 deletions
|
@ -22,11 +22,9 @@ For example, creating an empty file such as `docs/getting-started.md` will enabl
|
||||||
Suppose you add this to your document:
|
Suppose you add this to your document:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
|
||||||
id: intro
|
id: intro
|
||||||
title: Getting Started
|
title: Getting Started
|
||||||
---
|
---
|
||||||
|
|
||||||
My new content here..
|
My new content here..
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -94,27 +92,50 @@ You should provide `directory/id` instead of `id` in `sidebars.json`.
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Adding Sub Categories
|
### Adding Subcategories
|
||||||
|
|
||||||
It is possibile to add sub categories to a sidebar. Instead of passing an array to the category like the previous examples you can pass an object where
|
It is possible to add subcategories to a sidebar. Instead of using IDs as the contents of the category array like the previous examples, you can pass an object where the keys will be the subcategory name and the value an array of IDs for that subcategory.
|
||||||
the keys will be the sub category name. You can then pass an array of document ids to the sub category.
|
|
||||||
|
|
||||||
```js
|
```js
|
||||||
{
|
{
|
||||||
"examples-sidebar" : {
|
"docs": {
|
||||||
"My Example Category" : {
|
"My Example Category": [
|
||||||
"My Example Sub Category" : [
|
"examples",
|
||||||
"my-examples",
|
{
|
||||||
...
|
"type": "subcategory",
|
||||||
],
|
"label": "My Example Subcategory",
|
||||||
"My Next Sub Category" : [
|
"ids": [
|
||||||
"some-other-examples"
|
"my-examples",
|
||||||
]
|
...
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "subcategory",
|
||||||
|
"label": "My Next Subcategory",
|
||||||
|
"ids": [
|
||||||
|
"some-other-examples"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"even-more-examples",
|
||||||
...
|
...
|
||||||
},
|
],
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The above will generate:
|
||||||
|
|
||||||
|
- My Example Category
|
||||||
|
- examples
|
||||||
|
- My Example Subcategory
|
||||||
|
- my-examples
|
||||||
|
...
|
||||||
|
- My Next Subcategory
|
||||||
|
- some-other-examples
|
||||||
|
- even-more-examples
|
||||||
|
...
|
||||||
|
*/
|
||||||
```
|
```
|
||||||
|
|
||||||
### Adding New Sidebars
|
### Adding New Sidebars
|
||||||
|
@ -234,8 +255,8 @@ The links in the top navigation bar get `siteNavItemActive` and `siteNavGroupAct
|
||||||
|
|
||||||
The `siteNavGroupActive` class will be added to these links:
|
The `siteNavGroupActive` class will be added to these links:
|
||||||
|
|
||||||
* `doc` links that belong to the same sidebar as the currently displayed document
|
- `doc` links that belong to the same sidebar as the currently displayed document
|
||||||
* The blog link when a blog post, or the blog listing page is being displayed
|
- The blog link when a blog post, or the blog listing page is being displayed
|
||||||
|
|
||||||
These are two separate class names so you can have the active styles applied to either exact matches only or a bit more broadly for docs that belong together. If you don't want to make this distinction you can add both classes to the same CSS rule.
|
These are two separate class names so you can have the active styles applied to either exact matches only or a bit more broadly for docs that belong together. If you don't want to make this distinction you can add both classes to the same CSS rule.
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,12 @@ class BlogSidebar extends React.Component {
|
||||||
|
|
||||||
const contents = [
|
const contents = [
|
||||||
{
|
{
|
||||||
name: blogSidebarTitle,
|
type: 'CATEGORY',
|
||||||
links: MetadataBlog.slice(0, blogSidebarCount),
|
title: blogSidebarTitle,
|
||||||
|
children: MetadataBlog.slice(0, blogSidebarCount).map(item => ({
|
||||||
|
type: 'LINK',
|
||||||
|
item,
|
||||||
|
})),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const title = this.props.current && this.props.current.title;
|
const title = this.props.current && this.props.current.title;
|
||||||
|
|
|
@ -53,7 +53,6 @@ class DocsLayout extends React.Component {
|
||||||
const title =
|
const title =
|
||||||
idx(i18n, ['localized-strings', 'docs', id, 'title']) || defaultTitle;
|
idx(i18n, ['localized-strings', 'docs', id, 'title']) || defaultTitle;
|
||||||
const hasOnPageNav = this.props.config.onPageNav === 'separate';
|
const hasOnPageNav = this.props.config.onPageNav === 'separate';
|
||||||
|
|
||||||
const previousTitle =
|
const previousTitle =
|
||||||
idx(i18n, ['localized-strings', metadata.previous_id]) ||
|
idx(i18n, ['localized-strings', metadata.previous_id]) ||
|
||||||
idx(i18n, ['localized-strings', 'previous']) ||
|
idx(i18n, ['localized-strings', 'previous']) ||
|
||||||
|
|
|
@ -28,12 +28,13 @@ if (fs.existsSync(`../server/languages.js`)) {
|
||||||
|
|
||||||
class DocsSidebar extends React.Component {
|
class DocsSidebar extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const sidebar = this.props.metadata.sidebar;
|
const {category, sidebar} = this.props.metadata;
|
||||||
const docsCategories = readCategories(sidebar, Metadata, languages);
|
const docsCategories = readCategories(sidebar, Metadata, languages);
|
||||||
const categoryName = this.props.metadata.category;
|
|
||||||
if (!categoryName) {
|
if (!category) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container className="docsNavContainer" id="docsNav" wrapper={false}>
|
<Container className="docsNavContainer" id="docsNav" wrapper={false}>
|
||||||
<SideNav
|
<SideNav
|
||||||
|
|
|
@ -61,44 +61,48 @@ class SideNav extends React.Component {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCategory(category) {
|
renderCategory = categoryItem => (
|
||||||
return (
|
<div className="navGroup" key={categoryItem.title}>
|
||||||
<div className="navGroup" key={category.name}>
|
<h3 className="navGroupCategoryTitle">
|
||||||
<h3 className="navGroupCategoryTitle">
|
{this.getLocalizedCategoryString(categoryItem.title)}
|
||||||
{this.getLocalizedCategoryString(category.name)}
|
</h3>
|
||||||
</h3>
|
<ul>
|
||||||
<ul>
|
{categoryItem.children.map(item => {
|
||||||
{category.links.map(this.renderItemLink, this)}
|
switch (item.type) {
|
||||||
{category.sub_categories &&
|
case 'LINK':
|
||||||
category.sub_categories.map(this.renderSubCategory, this)}
|
return this.renderItemLink(item);
|
||||||
</ul>
|
case 'SUBCATEGORY':
|
||||||
</div>
|
return this.renderSubcategory(item);
|
||||||
);
|
default:
|
||||||
}
|
return null;
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
renderSubCategory(subCategory) {
|
renderSubcategory = subcategoryItem => (
|
||||||
return (
|
<div className="navGroup subNavGroup" key={subcategoryItem.title}>
|
||||||
<div className="navGroup subNavGroup" key={subCategory.name}>
|
<h4 className="navGroupSubcategoryTitle">
|
||||||
<h4 className="navGroupSubCategoryTitle">
|
{this.getLocalizedCategoryString(subcategoryItem.title)}
|
||||||
{this.getLocalizedCategoryString(subCategory.name)}
|
</h4>
|
||||||
</h4>
|
<ul>{subcategoryItem.children.map(this.renderItemLink)}</ul>
|
||||||
<ul>{subCategory.links.map(this.renderItemLink, this)}</ul>
|
</div>
|
||||||
</div>
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderItemLink(link) {
|
renderItemLink = linkItem => {
|
||||||
|
const linkMetadata = linkItem.item;
|
||||||
const itemClasses = classNames('navListItem', {
|
const itemClasses = classNames('navListItem', {
|
||||||
navListItemActive: link.id === this.props.current.id,
|
navListItemActive: linkMetadata.id === this.props.current.id,
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<li className={itemClasses} key={link.id}>
|
<li className={itemClasses} key={linkMetadata.id}>
|
||||||
<a className="navItem" href={this.getLink(link)}>
|
<a className="navItem" href={this.getLink(linkMetadata)}>
|
||||||
{this.getLocalizedString(link)}
|
{this.getLocalizedString(linkMetadata)}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
@ -122,7 +126,7 @@ class SideNav extends React.Component {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="navGroups">
|
<div className="navGroups">
|
||||||
{this.props.contents.map(this.renderCategory, this)}
|
{this.props.contents.map(this.renderCategory)}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -12,7 +12,7 @@ module.exports = {
|
||||||
next_id: 'doc2',
|
next_id: 'doc2',
|
||||||
next: 'en-doc2',
|
next: 'en-doc2',
|
||||||
next_title: 'Document 2',
|
next_title: 'Document 2',
|
||||||
sub_category: 'Sub Cat 1',
|
subcategory: 'Sub Cat 1',
|
||||||
sort: 1,
|
sort: 1,
|
||||||
},
|
},
|
||||||
'en-doc2': {
|
'en-doc2': {
|
||||||
|
@ -28,7 +28,7 @@ module.exports = {
|
||||||
previous_id: 'doc1',
|
previous_id: 'doc1',
|
||||||
previous: 'en-doc1',
|
previous: 'en-doc1',
|
||||||
previous_title: 'Document 1',
|
previous_title: 'Document 1',
|
||||||
sub_category: 'Sub Cat 1',
|
subcategory: 'Sub Cat 1',
|
||||||
sort: 2,
|
sort: 2,
|
||||||
},
|
},
|
||||||
'en-doc3': {
|
'en-doc3': {
|
||||||
|
@ -44,7 +44,7 @@ module.exports = {
|
||||||
previous_id: 'doc2',
|
previous_id: 'doc2',
|
||||||
previous: 'en-doc2',
|
previous: 'en-doc2',
|
||||||
previous_title: 'Document 2',
|
previous_title: 'Document 2',
|
||||||
sub_category: 'Sub Cat 2',
|
subcategory: 'Sub Cat 2',
|
||||||
sort: 3,
|
sort: 3,
|
||||||
},
|
},
|
||||||
'en-doc4': {
|
'en-doc4': {
|
||||||
|
|
|
@ -1,11 +1,26 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
docs: {
|
docs: {
|
||||||
'First Category': {
|
'First Category': ['doc1', 'doc2'],
|
||||||
'Sub Cat One': ['doc2', 'doc1'],
|
'Second Category': [
|
||||||
'Sub Cat Two': ['doc3', 'doc5'],
|
'doc3',
|
||||||
},
|
{
|
||||||
'Second Category': {
|
type: 'subcategory',
|
||||||
Hello: ['doc4'],
|
label: 'First Subcategory',
|
||||||
},
|
ids: ['doc4'],
|
||||||
|
},
|
||||||
|
'doc5',
|
||||||
|
],
|
||||||
|
'Third Category': [
|
||||||
|
{
|
||||||
|
type: 'subcategory',
|
||||||
|
label: 'Second Subcategory',
|
||||||
|
ids: ['doc6', 'doc7'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'subcategory',
|
||||||
|
label: 'Third Subcategory',
|
||||||
|
ids: ['doc8'],
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,176 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`readCategories should return proper categories and their pages 1`] = `
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"children": Array [
|
||||||
|
Object {
|
||||||
|
"item": Object {
|
||||||
|
"category": "Test",
|
||||||
|
"id": "en-doc1",
|
||||||
|
"language": "en",
|
||||||
|
"localized_id": "doc1",
|
||||||
|
"next": "en-doc2",
|
||||||
|
"next_id": "doc2",
|
||||||
|
"next_title": "Document 2",
|
||||||
|
"permalink": "docs/en/next/doc1.html",
|
||||||
|
"sidebar": "docs",
|
||||||
|
"sort": 1,
|
||||||
|
"source": "doc1.md",
|
||||||
|
"title": "Document 1",
|
||||||
|
"version": "next",
|
||||||
|
},
|
||||||
|
"type": "LINK",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"item": Object {
|
||||||
|
"category": "Test",
|
||||||
|
"id": "en-doc2",
|
||||||
|
"language": "en",
|
||||||
|
"localized_id": "doc2",
|
||||||
|
"permalink": "docs/en/next/doc2.html",
|
||||||
|
"previous": "en-doc1",
|
||||||
|
"previous_id": "doc1",
|
||||||
|
"previous_title": "Document 1",
|
||||||
|
"sidebar": "docs",
|
||||||
|
"sort": 2,
|
||||||
|
"source": "doc2.md",
|
||||||
|
"title": "Document 2",
|
||||||
|
"version": "next",
|
||||||
|
},
|
||||||
|
"type": "LINK",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"title": "Test",
|
||||||
|
"type": "CATEGORY",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"children": Array [
|
||||||
|
Object {
|
||||||
|
"item": Object {
|
||||||
|
"category": "Test 2",
|
||||||
|
"id": "en-doc3",
|
||||||
|
"language": "en",
|
||||||
|
"localized_id": "doc3",
|
||||||
|
"permalink": "docs/en/next/doc3.html",
|
||||||
|
"previous": "en-doc2",
|
||||||
|
"previous_id": "doc2",
|
||||||
|
"previous_title": "Document 2",
|
||||||
|
"sidebar": "docs",
|
||||||
|
"sort": 3,
|
||||||
|
"source": "doc3.md",
|
||||||
|
"title": "Document 3",
|
||||||
|
"version": "next",
|
||||||
|
},
|
||||||
|
"type": "LINK",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"title": "Test 2",
|
||||||
|
"type": "CATEGORY",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`readCategories should return proper data with categories and sub categories 1`] = `
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"children": Array [
|
||||||
|
Object {
|
||||||
|
"children": Array [
|
||||||
|
Object {
|
||||||
|
"item": Object {
|
||||||
|
"category": "Test",
|
||||||
|
"id": "en-doc1",
|
||||||
|
"language": "en",
|
||||||
|
"localized_id": "doc1",
|
||||||
|
"next": "en-doc2",
|
||||||
|
"next_id": "doc2",
|
||||||
|
"next_title": "Document 2",
|
||||||
|
"permalink": "docs/en/next/doc1.html",
|
||||||
|
"sidebar": "docs",
|
||||||
|
"sort": 1,
|
||||||
|
"source": "doc1.md",
|
||||||
|
"subcategory": "Sub Cat 1",
|
||||||
|
"title": "Document 1",
|
||||||
|
"version": "next",
|
||||||
|
},
|
||||||
|
"type": "LINK",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"item": Object {
|
||||||
|
"category": "Test",
|
||||||
|
"id": "en-doc2",
|
||||||
|
"language": "en",
|
||||||
|
"localized_id": "doc2",
|
||||||
|
"permalink": "docs/en/next/doc2.html",
|
||||||
|
"previous": "en-doc1",
|
||||||
|
"previous_id": "doc1",
|
||||||
|
"previous_title": "Document 1",
|
||||||
|
"sidebar": "docs",
|
||||||
|
"sort": 2,
|
||||||
|
"source": "doc2.md",
|
||||||
|
"subcategory": "Sub Cat 1",
|
||||||
|
"title": "Document 2",
|
||||||
|
"version": "next",
|
||||||
|
},
|
||||||
|
"type": "LINK",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"title": "Sub Cat 1",
|
||||||
|
"type": "SUBCATEGORY",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"children": Array [
|
||||||
|
Object {
|
||||||
|
"item": Object {
|
||||||
|
"category": "Test",
|
||||||
|
"id": "en-doc3",
|
||||||
|
"language": "en",
|
||||||
|
"localized_id": "doc3",
|
||||||
|
"permalink": "docs/en/next/doc3.html",
|
||||||
|
"previous": "en-doc2",
|
||||||
|
"previous_id": "doc2",
|
||||||
|
"previous_title": "Document 2",
|
||||||
|
"sidebar": "docs",
|
||||||
|
"sort": 3,
|
||||||
|
"source": "doc3.md",
|
||||||
|
"subcategory": "Sub Cat 2",
|
||||||
|
"title": "Document 3",
|
||||||
|
"version": "next",
|
||||||
|
},
|
||||||
|
"type": "LINK",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"title": "Sub Cat 2",
|
||||||
|
"type": "SUBCATEGORY",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"title": "Test",
|
||||||
|
"type": "CATEGORY",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"children": Array [
|
||||||
|
Object {
|
||||||
|
"item": Object {
|
||||||
|
"category": "Test 2",
|
||||||
|
"id": "en-doc4",
|
||||||
|
"language": "en",
|
||||||
|
"localized_id": "doc4",
|
||||||
|
"permalink": "docs/en/next/doc4.html",
|
||||||
|
"previous": "en-doc3",
|
||||||
|
"previous_id": "doc3",
|
||||||
|
"previous_title": "Document 3",
|
||||||
|
"sidebar": "docs",
|
||||||
|
"sort": 4,
|
||||||
|
"source": "doc4.md",
|
||||||
|
"title": "Document 4",
|
||||||
|
"version": "next",
|
||||||
|
},
|
||||||
|
"type": "LINK",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"title": "Test 2",
|
||||||
|
"type": "CATEGORY",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
`;
|
|
@ -0,0 +1,70 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`readMetadata readSidebar should verify sub category data and verify order 1`] = `
|
||||||
|
Object {
|
||||||
|
"doc1": Object {
|
||||||
|
"category": "First Category",
|
||||||
|
"next": "doc2",
|
||||||
|
"order": 1,
|
||||||
|
"previous": null,
|
||||||
|
"sidebar": "docs",
|
||||||
|
"subcategory": null,
|
||||||
|
},
|
||||||
|
"doc2": Object {
|
||||||
|
"category": "First Category",
|
||||||
|
"next": "doc3",
|
||||||
|
"order": 2,
|
||||||
|
"previous": "doc1",
|
||||||
|
"sidebar": "docs",
|
||||||
|
"subcategory": null,
|
||||||
|
},
|
||||||
|
"doc3": Object {
|
||||||
|
"category": "Second Category",
|
||||||
|
"next": "doc4",
|
||||||
|
"order": 3,
|
||||||
|
"previous": "doc2",
|
||||||
|
"sidebar": "docs",
|
||||||
|
"subcategory": null,
|
||||||
|
},
|
||||||
|
"doc4": Object {
|
||||||
|
"category": "Second Category",
|
||||||
|
"next": "doc5",
|
||||||
|
"order": 4,
|
||||||
|
"previous": "doc3",
|
||||||
|
"sidebar": "docs",
|
||||||
|
"subcategory": "First Subcategory",
|
||||||
|
},
|
||||||
|
"doc5": Object {
|
||||||
|
"category": "Second Category",
|
||||||
|
"next": "doc6",
|
||||||
|
"order": 5,
|
||||||
|
"previous": "doc4",
|
||||||
|
"sidebar": "docs",
|
||||||
|
"subcategory": null,
|
||||||
|
},
|
||||||
|
"doc6": Object {
|
||||||
|
"category": "Third Category",
|
||||||
|
"next": "doc7",
|
||||||
|
"order": 6,
|
||||||
|
"previous": "doc5",
|
||||||
|
"sidebar": "docs",
|
||||||
|
"subcategory": "Second Subcategory",
|
||||||
|
},
|
||||||
|
"doc7": Object {
|
||||||
|
"category": "Third Category",
|
||||||
|
"next": "doc8",
|
||||||
|
"order": 7,
|
||||||
|
"previous": "doc6",
|
||||||
|
"sidebar": "docs",
|
||||||
|
"subcategory": "Second Subcategory",
|
||||||
|
},
|
||||||
|
"doc8": Object {
|
||||||
|
"category": "Third Category",
|
||||||
|
"next": null,
|
||||||
|
"order": 8,
|
||||||
|
"previous": "doc7",
|
||||||
|
"sidebar": "docs",
|
||||||
|
"subcategory": "Third Subcategory",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
|
@ -41,15 +41,7 @@ describe('readCategories', () => {
|
||||||
|
|
||||||
expect(categories.en).toBeDefined();
|
expect(categories.en).toBeDefined();
|
||||||
expect(categories.en.length).toBe(2);
|
expect(categories.en.length).toBe(2);
|
||||||
|
expect(categories.en).toMatchSnapshot();
|
||||||
expect(categories.en[0].name).toBe('Test');
|
|
||||||
expect(categories.en[0].links.length).toBe(2);
|
|
||||||
expect(categories.en[0].links[0].id).toBe('en-doc1');
|
|
||||||
expect(categories.en[0].links[1].id).toBe('en-doc2');
|
|
||||||
|
|
||||||
expect(categories.en[1].name).toBe('Test 2');
|
|
||||||
expect(categories.en[1].links.length).toBe(1);
|
|
||||||
expect(categories.en[1].links[0].id).toBe('en-doc3');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should return proper data with categories and sub categories', () => {
|
test('should return proper data with categories and sub categories', () => {
|
||||||
|
@ -58,24 +50,7 @@ describe('readCategories', () => {
|
||||||
expect(categories.en).toBeDefined();
|
expect(categories.en).toBeDefined();
|
||||||
expect(categories.ko).toBeDefined();
|
expect(categories.ko).toBeDefined();
|
||||||
expect(categories.en.length).toBe(2);
|
expect(categories.en.length).toBe(2);
|
||||||
|
expect(categories.en).toMatchSnapshot();
|
||||||
expect(categories.en[0].name).toBe('Test');
|
|
||||||
expect(categories.en[0].links.length).toBe(0);
|
|
||||||
expect(categories.en[0].sub_categories.length).toBe(2);
|
|
||||||
|
|
||||||
expect(categories.en[0].sub_categories[0].name).toBe('Sub Cat 1');
|
|
||||||
expect(categories.en[0].sub_categories[0].links.length).toBe(2);
|
|
||||||
expect(categories.en[0].sub_categories[0].links[0].id).toBe('en-doc1');
|
|
||||||
expect(categories.en[0].sub_categories[0].links[1].id).toBe('en-doc2');
|
|
||||||
|
|
||||||
expect(categories.en[0].sub_categories[1].name).toBe('Sub Cat 2');
|
|
||||||
expect(categories.en[0].sub_categories[1].links.length).toBe(1);
|
|
||||||
expect(categories.en[0].sub_categories[1].links[0].id).toBe('en-doc3');
|
|
||||||
|
|
||||||
expect(categories.en[1].name).toBe('Test 2');
|
|
||||||
expect(categories.en[1].links.length).toBe(1);
|
|
||||||
expect(categories.en[1].links[0].id).toBe('en-doc4');
|
|
||||||
expect(categories.en[1].sub_categories).not.toBeDefined();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should return proper languages when not enabled', () => {
|
test('should return proper languages when not enabled', () => {
|
||||||
|
|
|
@ -6,8 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const {readSidebar} = require('../readMetadata');
|
const {readSidebar} = require('../readMetadata');
|
||||||
const sidebar = require('./__fixtures__/sidebar');
|
const sidebarSubcategories = require('./__fixtures__/sidebar-subcategories');
|
||||||
const sidebarSubCategories = require('./__fixtures__/sidebar-subcategories');
|
|
||||||
|
|
||||||
jest.mock('../env', () => ({
|
jest.mock('../env', () => ({
|
||||||
translation: {
|
translation: {
|
||||||
|
@ -36,42 +35,9 @@ jest.mock(`${process.cwd()}/sidebar.json`, () => true, {virtual: true});
|
||||||
|
|
||||||
describe('readMetadata', () => {
|
describe('readMetadata', () => {
|
||||||
describe('readSidebar', () => {
|
describe('readSidebar', () => {
|
||||||
it('should verify regular category data and verify sort', () => {
|
test('should verify sub category data and verify order', () => {
|
||||||
const order = readSidebar(sidebar);
|
const items = readSidebar(sidebarSubcategories);
|
||||||
|
expect(items).toMatchSnapshot();
|
||||||
// Put in this order to verify sort
|
|
||||||
['doc1', 'doc2', 'doc4', 'doc3'].forEach((id, index) => {
|
|
||||||
expect(order[id]).toBeDefined();
|
|
||||||
expect(order[id].sort).toBe(index + 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(order.doc1.previous).toBeUndefined();
|
|
||||||
expect(order.doc2.previous).toBe('doc1');
|
|
||||||
|
|
||||||
expect(order.doc1.next).toBe('doc2');
|
|
||||||
expect(order.doc2.next).toBe('doc4');
|
|
||||||
|
|
||||||
expect(order.doc1.sub_category).toBeFalsy();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should verify sub category data and verify sort', () => {
|
|
||||||
const order = readSidebar(sidebarSubCategories);
|
|
||||||
|
|
||||||
// Put in this order to verify sort
|
|
||||||
['doc2', 'doc1', 'doc3', 'doc5', 'doc4'].forEach((id, index) => {
|
|
||||||
expect(order[id]).toBeDefined();
|
|
||||||
expect(order[id].sort).toBe(index + 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(order.doc2.sidebar).toBe('docs');
|
|
||||||
expect(order.doc2.category).toBe('First Category');
|
|
||||||
expect(order.doc2.sub_category).toBe('Sub Cat One');
|
|
||||||
|
|
||||||
expect(order.doc1.category).toBe('First Category');
|
|
||||||
expect(order.doc1.sub_category).toBe('Sub Cat One');
|
|
||||||
|
|
||||||
expect(order.doc3.category).toBe('First Category');
|
|
||||||
expect(order.doc3.sub_category).toBe('Sub Cat Two');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -88,63 +88,4 @@ describe('server utils', () => {
|
||||||
expect(utils.getSubDir(docE, docsDir)).toBeNull();
|
expect(utils.getSubDir(docE, docsDir)).toBeNull();
|
||||||
expect(utils.getSubDir(docE, translatedDir)).toEqual('lol/lah');
|
expect(utils.getSubDir(docE, translatedDir)).toEqual('lol/lah');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('validateSidebar', () => {
|
|
||||||
test('should throw an error for invalid sidebarMetadatas', () => {
|
|
||||||
const metadata = {
|
|
||||||
id: 'doc1',
|
|
||||||
sidebar: 'docs',
|
|
||||||
next_id: 'doc2',
|
|
||||||
next: 'doc2',
|
|
||||||
};
|
|
||||||
|
|
||||||
const sidebarMetadatas = {
|
|
||||||
doc1: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(() => {
|
|
||||||
utils.validateSidebar(metadata, sidebarMetadatas);
|
|
||||||
}).toThrow(
|
|
||||||
`Improper sidebars.json file, document with id 'doc2' not found. Make sure that documents with the ids specified in sidebars.json exist and that no ids are repeated.`,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should throw an error for invalid version sidebarMetadatas', () => {
|
|
||||||
const metadata = {
|
|
||||||
id: 'doc1',
|
|
||||||
version: 'foo',
|
|
||||||
sidebar: 'docs',
|
|
||||||
next_id: 'doc2',
|
|
||||||
next: 'doc2',
|
|
||||||
};
|
|
||||||
|
|
||||||
const sidebarMetadatas = {
|
|
||||||
doc1: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(() => {
|
|
||||||
utils.validateSidebar(metadata, sidebarMetadatas);
|
|
||||||
}).toThrow(
|
|
||||||
`Improper sidebars file for version foo, document with id 'doc2' not found. Make sure that all documents with ids specified in this version's sidebar file exist and that no ids are repeated.`,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should pass validate', () => {
|
|
||||||
const metadata = {
|
|
||||||
id: 'doc1',
|
|
||||||
sidebar: 'docs',
|
|
||||||
next_id: 'doc2',
|
|
||||||
next: 'doc2',
|
|
||||||
};
|
|
||||||
|
|
||||||
const sidebarMetadatas = {
|
|
||||||
doc1: {},
|
|
||||||
doc2: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(() => {
|
|
||||||
utils.validateSidebar(metadata, sidebarMetadatas);
|
|
||||||
}).not.toThrow();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,115 +5,82 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const {validateSidebar} = require('./utils');
|
const _ = require('lodash');
|
||||||
|
|
||||||
// returns data broken up into categories for a sidebar
|
// returns data broken up into categories for a sidebar
|
||||||
function readCategories(sidebar, allMetadata, languages) {
|
function readCategories(sidebar, allMetadata, languages) {
|
||||||
const enabledLanguages = languages
|
|
||||||
.filter(lang => lang.enabled)
|
|
||||||
.map(lang => lang.tag);
|
|
||||||
|
|
||||||
const allCategories = {};
|
const allCategories = {};
|
||||||
|
|
||||||
// Go through each language that might be defined
|
// Go through each language that might be defined.
|
||||||
for (let k = 0; k < enabledLanguages.length; ++k) {
|
languages
|
||||||
const language = enabledLanguages[k];
|
.filter(lang => lang.enabled)
|
||||||
const metadatas = [];
|
.map(lang => lang.tag)
|
||||||
const categories = [];
|
.forEach(language => {
|
||||||
const sidebarMetadatas = {};
|
// Get all related metadata for the current sidebar and specific to the language.
|
||||||
|
const metadatas = Object.values(allMetadata)
|
||||||
|
.filter(
|
||||||
|
metadata =>
|
||||||
|
metadata.sidebar === sidebar && metadata.language === language,
|
||||||
|
)
|
||||||
|
.sort((a, b) => a.order - b.order);
|
||||||
|
|
||||||
// Get all related metadata for the current sidebar
|
// Define the correct order of categories.
|
||||||
Object.keys(allMetadata).forEach(id => {
|
const sortedCategories = _.uniq(
|
||||||
const metadata = allMetadata[id];
|
metadatas.map(metadata => metadata.category),
|
||||||
if (metadata.sidebar === sidebar && metadata.language === language) {
|
);
|
||||||
metadatas.push(metadata);
|
|
||||||
sidebarMetadatas[metadata.id] = metadata;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Sort the metadata
|
const metadatasGroupedByCategory = _.chain(metadatas)
|
||||||
metadatas.sort((a, b) => a.sort - b.sort);
|
.groupBy(metadata => metadata.category)
|
||||||
|
.mapValues(categoryItems => {
|
||||||
|
// Process subcategories.
|
||||||
|
const metadatasGroupedBySubcategory = _.groupBy(
|
||||||
|
categoryItems,
|
||||||
|
item => item.subcategory,
|
||||||
|
);
|
||||||
|
const result = [];
|
||||||
|
const seenSubcategories = new Set();
|
||||||
|
// categoryItems can be links or subcategories. Handle separately.
|
||||||
|
categoryItems.forEach(item => {
|
||||||
|
// Has no subcategory.
|
||||||
|
if (item.subcategory == null) {
|
||||||
|
result.push({
|
||||||
|
type: 'LINK',
|
||||||
|
item,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Store the correct sort of categories and sub categories for later
|
const {subcategory} = item;
|
||||||
const sortedCategories = [];
|
// Subcategory has been processed, we can skip it.
|
||||||
const sortedSubCategories = [];
|
if (seenSubcategories.has(subcategory)) {
|
||||||
for (let i = 0; i < metadatas.length; ++i) {
|
return;
|
||||||
const metadata = metadatas[i];
|
}
|
||||||
const category = metadata.category;
|
|
||||||
const subCategory = metadata.sub_category;
|
|
||||||
|
|
||||||
if (!sortedCategories.includes(category)) {
|
seenSubcategories.add(subcategory);
|
||||||
sortedCategories.push(category);
|
const subcategoryLinks = metadatasGroupedBySubcategory[
|
||||||
}
|
subcategory
|
||||||
|
].map(subcategoryItem => ({
|
||||||
if (subCategory && !sortedSubCategories.includes(subCategory)) {
|
type: 'LINK',
|
||||||
sortedSubCategories.push(subCategory);
|
item: subcategoryItem,
|
||||||
}
|
}));
|
||||||
}
|
result.push({
|
||||||
|
type: 'SUBCATEGORY',
|
||||||
// Index categories and sub categories with all of their documents
|
title: subcategory,
|
||||||
const indexedCategories = {};
|
children: subcategoryLinks,
|
||||||
const indexedSubCategories = {};
|
});
|
||||||
for (let i = 0; i < metadatas.length; i++) {
|
|
||||||
const metadata = metadatas[i];
|
|
||||||
const category = metadata.category;
|
|
||||||
const subCategory = metadata.sub_category;
|
|
||||||
|
|
||||||
// Validate sidebarMetadatas in the sidebar
|
|
||||||
validateSidebar(metadata, sidebarMetadatas);
|
|
||||||
|
|
||||||
if (!indexedCategories[category]) {
|
|
||||||
indexedCategories[category] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!subCategory) {
|
|
||||||
indexedCategories[category].push(metadata);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subCategory) {
|
|
||||||
if (!indexedSubCategories[category]) {
|
|
||||||
indexedSubCategories[category] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!indexedSubCategories[category][subCategory]) {
|
|
||||||
indexedSubCategories[category][subCategory] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
indexedSubCategories[category][subCategory].push(metadata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate data for each category and sub categories
|
|
||||||
for (let i = 0; i < sortedCategories.length; i++) {
|
|
||||||
const category = sortedCategories[i];
|
|
||||||
const currentCategory = {
|
|
||||||
name: category,
|
|
||||||
links: indexedCategories[category],
|
|
||||||
};
|
|
||||||
|
|
||||||
for (let ii = 0; ii < sortedSubCategories.length; ii++) {
|
|
||||||
const subCategory = sortedSubCategories[ii];
|
|
||||||
|
|
||||||
if (
|
|
||||||
indexedSubCategories[category] &&
|
|
||||||
indexedSubCategories[category][subCategory]
|
|
||||||
) {
|
|
||||||
if (!currentCategory.sub_categories) {
|
|
||||||
currentCategory.sub_categories = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
currentCategory.sub_categories.push({
|
|
||||||
name: subCategory,
|
|
||||||
links: indexedSubCategories[category][subCategory],
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
categories.push(currentCategory);
|
return result;
|
||||||
}
|
})
|
||||||
|
.value();
|
||||||
|
|
||||||
allCategories[language] = categories;
|
const categories = sortedCategories.map(category => ({
|
||||||
}
|
type: 'CATEGORY',
|
||||||
|
title: category,
|
||||||
|
children: metadatasGroupedByCategory[category],
|
||||||
|
}));
|
||||||
|
allCategories[language] = categories;
|
||||||
|
});
|
||||||
|
|
||||||
return allCategories;
|
return allCategories;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,55 +54,67 @@ function getDocsPath() {
|
||||||
function readSidebar(sidebars = {}) {
|
function readSidebar(sidebars = {}) {
|
||||||
Object.assign(sidebars, versionFallback.sidebarData());
|
Object.assign(sidebars, versionFallback.sidebarData());
|
||||||
|
|
||||||
const order = {};
|
const items = {};
|
||||||
|
|
||||||
Object.keys(sidebars).forEach(sidebar => {
|
Object.keys(sidebars).forEach(sidebar => {
|
||||||
const categories = sidebars[sidebar];
|
const categories = sidebars[sidebar];
|
||||||
|
const sidebarItems = [];
|
||||||
|
|
||||||
let ids = [];
|
|
||||||
const categoryOrder = [];
|
|
||||||
const subCategoryOrder = [];
|
|
||||||
Object.keys(categories).forEach(category => {
|
Object.keys(categories).forEach(category => {
|
||||||
if (Array.isArray(categories[category])) {
|
const categoryItems = categories[category];
|
||||||
ids = ids.concat(categories[category]);
|
categoryItems.forEach(categoryItem => {
|
||||||
|
if (typeof categoryItem === 'object') {
|
||||||
for (let i = 0; i < categories[category].length; i++) {
|
switch (categoryItem.type) {
|
||||||
categoryOrder.push(category);
|
case 'subcategory':
|
||||||
subCategoryOrder.push(undefined);
|
categoryItem.ids.forEach(subcategoryItem => {
|
||||||
}
|
sidebarItems.push({
|
||||||
} else {
|
id: subcategoryItem,
|
||||||
Object.keys(categories[category]).forEach(subCategory => {
|
category,
|
||||||
ids = ids.concat(categories[category][subCategory]);
|
subcategory: categoryItem.label,
|
||||||
|
order: sidebarItems.length + 1,
|
||||||
for (let i = 0; i < categories[category][subCategory].length; i++) {
|
});
|
||||||
categoryOrder.push(category);
|
});
|
||||||
subCategoryOrder.push(subCategory);
|
return;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is a regular id value.
|
||||||
|
sidebarItems.push({
|
||||||
|
id: categoryItem,
|
||||||
|
category,
|
||||||
|
subcategory: null,
|
||||||
|
order: sidebarItems.length + 1,
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
for (let i = 0; i < ids.length; i++) {
|
for (let i = 0; i < sidebarItems.length; i++) {
|
||||||
const id = ids[i];
|
const item = sidebarItems[i];
|
||||||
let previous;
|
let previous = null;
|
||||||
let next;
|
let next = null;
|
||||||
|
|
||||||
if (i > 0) previous = ids[i - 1];
|
if (i > 0) {
|
||||||
|
previous = sidebarItems[i - 1].id;
|
||||||
|
}
|
||||||
|
|
||||||
if (i < ids.length - 1) next = ids[i + 1];
|
if (i < sidebarItems.length - 1) {
|
||||||
|
next = sidebarItems[i + 1].id;
|
||||||
|
}
|
||||||
|
|
||||||
order[id] = {
|
items[item.id] = {
|
||||||
previous,
|
previous,
|
||||||
next,
|
next,
|
||||||
sidebar,
|
sidebar,
|
||||||
category: categoryOrder[i],
|
category: item.category,
|
||||||
sub_category: subCategoryOrder[i],
|
subcategory: item.subcategory,
|
||||||
sort: i + 1,
|
order: item.order,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return order;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
// process the metadata for a document found in either 'docs' or 'translated_docs'
|
// process the metadata for a document found in either 'docs' or 'translated_docs'
|
||||||
|
@ -161,24 +173,24 @@ function processMetadata(file, refDir) {
|
||||||
metadata.id = (env.translation.enabled ? `${language}-` : '') + metadata.id;
|
metadata.id = (env.translation.enabled ? `${language}-` : '') + metadata.id;
|
||||||
metadata.language = env.translation.enabled ? language : 'en';
|
metadata.language = env.translation.enabled ? language : 'en';
|
||||||
|
|
||||||
const order = readSidebar(allSidebars);
|
const items = readSidebar(allSidebars);
|
||||||
const id = metadata.localized_id;
|
const id = metadata.localized_id;
|
||||||
|
const item = items[id];
|
||||||
|
if (item) {
|
||||||
|
metadata.sidebar = item.sidebar;
|
||||||
|
metadata.category = item.category;
|
||||||
|
metadata.subcategory = item.subcategory;
|
||||||
|
metadata.order = item.order;
|
||||||
|
|
||||||
if (order[id]) {
|
if (item.next) {
|
||||||
metadata.sidebar = order[id].sidebar;
|
metadata.next_id = item.next;
|
||||||
metadata.category = order[id].category;
|
|
||||||
metadata.sub_category = order[id].sub_category;
|
|
||||||
metadata.sort = order[id].sort;
|
|
||||||
|
|
||||||
if (order[id].next) {
|
|
||||||
metadata.next_id = order[id].next;
|
|
||||||
metadata.next =
|
metadata.next =
|
||||||
(env.translation.enabled ? `${language}-` : '') + order[id].next;
|
(env.translation.enabled ? `${language}-` : '') + item.next;
|
||||||
}
|
}
|
||||||
if (order[id].previous) {
|
if (item.previous) {
|
||||||
metadata.previous_id = order[id].previous;
|
metadata.previous_id = item.previous;
|
||||||
metadata.previous =
|
metadata.previous =
|
||||||
(env.translation.enabled ? `${language}-` : '') + order[id].previous;
|
(env.translation.enabled ? `${language}-` : '') + item.previous;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,8 +284,8 @@ function generateMetadataDocs() {
|
||||||
if (order[id]) {
|
if (order[id]) {
|
||||||
metadata.sidebar = order[id].sidebar;
|
metadata.sidebar = order[id].sidebar;
|
||||||
metadata.category = order[id].category;
|
metadata.category = order[id].category;
|
||||||
metadata.sub_category = order[id].sub_category;
|
metadata.subcategory = order[id].subcategory;
|
||||||
metadata.sort = order[id].sort;
|
metadata.order = order[id].order;
|
||||||
|
|
||||||
if (order[id].next) {
|
if (order[id].next) {
|
||||||
metadata.next_id = order[id].next.replace(
|
metadata.next_id = order[id].next.replace(
|
||||||
|
|
|
@ -66,30 +66,10 @@ function autoPrefixCss(cssContent) {
|
||||||
.then(result => result.css);
|
.then(result => result.css);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the docs in the sidebar are valid
|
|
||||||
function validateSidebar(metadata, sidebarMetadatas) {
|
|
||||||
if (metadata.next) {
|
|
||||||
if (!sidebarMetadatas[metadata.next]) {
|
|
||||||
throw new Error(
|
|
||||||
metadata.version
|
|
||||||
? `Improper sidebars file for version ${
|
|
||||||
metadata.version
|
|
||||||
}, document with id '${
|
|
||||||
metadata.next
|
|
||||||
}' not found. Make sure that all documents with ids specified in this version's sidebar file exist and that no ids are repeated.`
|
|
||||||
: `Improper sidebars.json file, document with id '${
|
|
||||||
metadata.next
|
|
||||||
}' not found. Make sure that documents with the ids specified in sidebars.json exist and that no ids are repeated.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getSubDir,
|
getSubDir,
|
||||||
getLanguage,
|
getLanguage,
|
||||||
isSeparateCss,
|
isSeparateCss,
|
||||||
minifyCss,
|
minifyCss,
|
||||||
autoPrefixCss,
|
autoPrefixCss,
|
||||||
validateSidebar,
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1757,11 +1757,10 @@ input::placeholder {
|
||||||
}
|
}
|
||||||
|
|
||||||
.toc .toggleNav .subNavGroup {
|
.toc .toggleNav .subNavGroup {
|
||||||
margin-top : 16px;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toc .toggleNav .navGroup .navGroupCategoryTitle,
|
.toc .toggleNav .navGroup .navGroupCategoryTitle {
|
||||||
.toc .toggleNav .navGroup .navGroupSubCategoryTitle {
|
|
||||||
color: #393939;
|
color: #393939;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
@ -1770,8 +1769,14 @@ input::placeholder {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toc .toggleNav .navGroup .navGroupSubCategoryTitle {
|
.toc .toggleNav .navGroup .navGroupSubcategoryTitle {
|
||||||
font-size: 16px;
|
color: #393939;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-top: 0;
|
||||||
|
padding: 4px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toc .toggleNav .navGroup .navListItem {
|
.toc .toggleNav .navGroup .navListItem {
|
||||||
|
|
14691
v1/package-lock.json
generated
14691
v1/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -70,6 +70,7 @@
|
||||||
"imagemin-jpegtran": "^5.0.2",
|
"imagemin-jpegtran": "^5.0.2",
|
||||||
"imagemin-optipng": "^5.2.1",
|
"imagemin-optipng": "^5.2.1",
|
||||||
"imagemin-svgo": "^6.0.0",
|
"imagemin-svgo": "^6.0.0",
|
||||||
|
"lodash": "^4.17.11",
|
||||||
"markdown-toc": "^1.2.0",
|
"markdown-toc": "^1.2.0",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"portfinder": "^1.0.17",
|
"portfinder": "^1.0.17",
|
||||||
|
|
|
@ -4800,7 +4800,7 @@ lodash.uniq@^4.5.0:
|
||||||
version "4.5.0"
|
version "4.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||||
|
|
||||||
lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@~4.17.10:
|
lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@~4.17.10:
|
||||||
version "4.17.11"
|
version "4.17.11"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue