mirror of
https://github.com/facebook/docusaurus.git
synced 2025-08-06 02:08:55 +02:00
feat(v2): move navbar config into themeConfig (#1477)
* feat(v2): move navbar config into themeConfig * misc: fix tests * fix: support external url for logo
This commit is contained in:
parent
6b75bb3270
commit
89ef4b9c44
7 changed files with 98 additions and 70 deletions
|
@ -12,46 +12,43 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||||
|
|
||||||
import SearchBar from '@theme/SearchBar';
|
import SearchBar from '@theme/SearchBar';
|
||||||
|
|
||||||
|
function NavLink(props) {
|
||||||
|
const {baseUrl, ...originalProps} = props;
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
className="navbar__link"
|
||||||
|
{...originalProps}
|
||||||
|
{...(originalProps.href
|
||||||
|
? {
|
||||||
|
target: '_blank',
|
||||||
|
rel: 'noopener noreferrer',
|
||||||
|
href: originalProps.href,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
activeClassName: 'navbar__link--active',
|
||||||
|
to: `${baseUrl}${originalProps.to}`,
|
||||||
|
})}>
|
||||||
|
{originalProps.label}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function Navbar() {
|
function Navbar() {
|
||||||
const context = useDocusaurusContext();
|
const context = useDocusaurusContext();
|
||||||
const {siteConfig = {}} = context;
|
const {siteConfig = {}} = context;
|
||||||
const {
|
const {
|
||||||
baseUrl,
|
baseUrl,
|
||||||
headerIcon,
|
themeConfig: {algolia, navbar = {}},
|
||||||
themeConfig: {algolia, headerLinks = []},
|
|
||||||
title,
|
|
||||||
disableHeaderTitle,
|
|
||||||
} = siteConfig;
|
} = siteConfig;
|
||||||
|
const {title, logo, links} = navbar;
|
||||||
|
|
||||||
// function to generate each header link
|
const getUrl = url => {
|
||||||
const makeLinks = link => {
|
const externalRegex = /^(https?:|\/\/)/;
|
||||||
if (link.url) {
|
const internalRegex = /^\/(?!\/)/;
|
||||||
// internal link
|
if (externalRegex.test(url) || internalRegex.test(url)) {
|
||||||
const targetLink = `${baseUrl}${link.url}`;
|
return url;
|
||||||
return (
|
|
||||||
<div key={targetLink} className="navbar__item">
|
|
||||||
<Link
|
|
||||||
activeClassName="navbar__link--active"
|
|
||||||
className="navbar__link"
|
|
||||||
to={targetLink}>
|
|
||||||
{link.label}
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
return baseUrl + url;
|
||||||
if (link.href) {
|
|
||||||
// Set link to specified href.
|
|
||||||
return (
|
|
||||||
<div key={link.label} className="navbar__item">
|
|
||||||
<Link to={link.href} className="navbar__link">
|
|
||||||
{link.label}
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -59,18 +56,31 @@ function Navbar() {
|
||||||
<div className="navbar__inner">
|
<div className="navbar__inner">
|
||||||
<div className="navbar__items">
|
<div className="navbar__items">
|
||||||
<Link className="navbar__brand" to={baseUrl}>
|
<Link className="navbar__brand" to={baseUrl}>
|
||||||
{headerIcon && (
|
{logo != null && (
|
||||||
<img
|
<img
|
||||||
className="navbar__logo"
|
className="navbar__logo"
|
||||||
src={baseUrl + headerIcon}
|
src={getUrl(logo.src)}
|
||||||
alt={title}
|
alt={logo.alt}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!disableHeaderTitle && <strong>{title}</strong>}
|
{title != null && <strong>{title}</strong>}
|
||||||
</Link>
|
</Link>
|
||||||
{headerLinks.map(makeLinks)}
|
{links
|
||||||
|
.filter(linkItem => linkItem.position !== 'right')
|
||||||
|
.map((linkItem, i) => (
|
||||||
|
<div className="navbar__item" key={i}>
|
||||||
|
<NavLink baseUrl={baseUrl} {...linkItem} />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="navbar__items navbar__items--right">
|
<div className="navbar__items navbar__items--right">
|
||||||
|
{links
|
||||||
|
.filter(linkItem => linkItem.position === 'right')
|
||||||
|
.map((linkItem, i) => (
|
||||||
|
<div className="navbar__item" key={i}>
|
||||||
|
<NavLink baseUrl={baseUrl} {...linkItem} />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
{algolia && (
|
{algolia && (
|
||||||
<div className="navbar__search" key="search-box">
|
<div className="navbar__search" key="search-box">
|
||||||
<SearchBar />
|
<SearchBar />
|
||||||
|
|
|
@ -7,19 +7,30 @@
|
||||||
- `docsUrl`. Use the plugin option on `docusaurus-plugin-content-docs` instead.
|
- `docsUrl`. Use the plugin option on `docusaurus-plugin-content-docs` instead.
|
||||||
- `customDocsPath`. Use the plugin option on `docusaurus-plugin-content-docs` instead.
|
- `customDocsPath`. Use the plugin option on `docusaurus-plugin-content-docs` instead.
|
||||||
- `sidebars.json` now has to be explicitly loaded by users and passed into the the plugin option on `docusaurus-plugin-content-docs`.
|
- `sidebars.json` now has to be explicitly loaded by users and passed into the the plugin option on `docusaurus-plugin-content-docs`.
|
||||||
- `headerLinks` doc, page, blog is deprecated. The syntax is now:
|
- `headerLinks` doc, page, blog is deprecated and has been to moved into `themeConfig` under the name `navbar`. The syntax is now:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
headerLinks: [
|
themeConfig: {
|
||||||
// Link to internal page (without baseUrl)
|
navbar: {
|
||||||
{ url: "help", label: "Help" },
|
title: 'Docusaurus',
|
||||||
// Links to href destination/ external page
|
logo: {
|
||||||
{ href: "https://github.com/", label: "GitHub" },
|
alt: 'Docusaurus Logo',
|
||||||
],
|
src: 'img/docusaurus.svg',
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{to: 'docs/introduction', label: 'Docs', position: 'left'},
|
||||||
|
{to: 'blog', label: 'Blog', position: 'left'},
|
||||||
|
{to: 'feedback', label: 'Feedback', position: 'left'},
|
||||||
|
{
|
||||||
|
href: 'https://github.com/facebook/docusaurus',
|
||||||
|
label: 'GitHub',
|
||||||
|
position: 'right',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `headerLinks` is now moved to themeConfig
|
|
||||||
|
|
||||||
# Additions
|
# Additions
|
||||||
|
|
||||||
### Presets
|
### Presets
|
||||||
|
|
|
@ -12,7 +12,6 @@ module.exports = {
|
||||||
projectName: 'sakura',
|
projectName: 'sakura',
|
||||||
baseUrl: '/sakura/',
|
baseUrl: '/sakura/',
|
||||||
url: 'https://docusaurus.io',
|
url: 'https://docusaurus.io',
|
||||||
headerIcon: 'img/docusaurus.svg',
|
|
||||||
favicon: 'img/docusaurus.ico',
|
favicon: 'img/docusaurus.ico',
|
||||||
plugins: [
|
plugins: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,7 +12,6 @@ module.exports = {
|
||||||
projectName: 'hello',
|
projectName: 'hello',
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
url: 'https://docusaurus.io',
|
url: 'https://docusaurus.io',
|
||||||
headerIcon: 'img/docusaurus.svg',
|
|
||||||
favicon: 'img/docusaurus.ico',
|
favicon: 'img/docusaurus.ico',
|
||||||
plugins: [
|
plugins: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,18 +18,17 @@ describe('loadConfig', () => {
|
||||||
plugins: expect.any(Array),
|
plugins: expect.any(Array),
|
||||||
},
|
},
|
||||||
`
|
`
|
||||||
Object {
|
Object {
|
||||||
"baseUrl": "/",
|
"baseUrl": "/",
|
||||||
"favicon": "img/docusaurus.ico",
|
"favicon": "img/docusaurus.ico",
|
||||||
"headerIcon": "img/docusaurus.svg",
|
"organizationName": "endiliey",
|
||||||
"organizationName": "endiliey",
|
"plugins": Any<Array>,
|
||||||
"plugins": Any<Array>,
|
"projectName": "hello",
|
||||||
"projectName": "hello",
|
"tagline": "Hello World",
|
||||||
"tagline": "Hello World",
|
"title": "Hello",
|
||||||
"title": "Hello",
|
"url": "https://docusaurus.io",
|
||||||
"url": "https://docusaurus.io",
|
}
|
||||||
}
|
`,
|
||||||
`,
|
|
||||||
);
|
);
|
||||||
expect(config).not.toEqual({});
|
expect(config).not.toEqual({});
|
||||||
});
|
});
|
||||||
|
@ -39,7 +38,7 @@ Object {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
loadConfig(siteDir);
|
loadConfig(siteDir);
|
||||||
}).toThrowErrorMatchingInlineSnapshot(
|
}).toThrowErrorMatchingInlineSnapshot(
|
||||||
`"The required field(s) 'favicon', 'headerIcon', 'organizationName', 'projectName', 'tagline', 'url' are missing from docusaurus.config.js"`,
|
`"The required field(s) 'favicon', 'organizationName', 'projectName', 'tagline', 'url' are missing from docusaurus.config.js"`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -48,7 +47,7 @@ Object {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
loadConfig(siteDir);
|
loadConfig(siteDir);
|
||||||
}).toThrowErrorMatchingInlineSnapshot(
|
}).toThrowErrorMatchingInlineSnapshot(
|
||||||
`"The required field(s) 'favicon', 'headerIcon' are missing from docusaurus.config.js"`,
|
`"The required field(s) 'favicon' are missing from docusaurus.config.js"`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -57,7 +56,7 @@ Object {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
loadConfig(siteDir);
|
loadConfig(siteDir);
|
||||||
}).toThrowErrorMatchingInlineSnapshot(
|
}).toThrowErrorMatchingInlineSnapshot(
|
||||||
`"The required field(s) 'baseUrl', 'favicon', 'headerIcon', 'organizationName', 'projectName', 'tagline', 'title', 'url' are missing from docusaurus.config.js"`,
|
`"The required field(s) 'baseUrl', 'favicon', 'organizationName', 'projectName', 'tagline', 'title', 'url' are missing from docusaurus.config.js"`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,7 +14,6 @@ const {CONFIG_FILE_NAME} = require('../../constants');
|
||||||
const REQUIRED_FIELDS = [
|
const REQUIRED_FIELDS = [
|
||||||
'baseUrl',
|
'baseUrl',
|
||||||
'favicon',
|
'favicon',
|
||||||
'headerIcon',
|
|
||||||
'organizationName',
|
'organizationName',
|
||||||
'projectName',
|
'projectName',
|
||||||
'tagline',
|
'tagline',
|
||||||
|
|
|
@ -12,7 +12,6 @@ module.exports = {
|
||||||
projectName: 'docusaurus',
|
projectName: 'docusaurus',
|
||||||
baseUrl: '/',
|
baseUrl: '/',
|
||||||
url: 'https://docusaurus-2.netlify.com',
|
url: 'https://docusaurus-2.netlify.com',
|
||||||
headerIcon: 'img/docusaurus.svg',
|
|
||||||
favicon: 'img/docusaurus.ico',
|
favicon: 'img/docusaurus.ico',
|
||||||
themeConfig: {
|
themeConfig: {
|
||||||
algolia: {
|
algolia: {
|
||||||
|
@ -20,11 +19,23 @@ module.exports = {
|
||||||
indexName: 'docusaurus-2',
|
indexName: 'docusaurus-2',
|
||||||
algoliaOptions: {},
|
algoliaOptions: {},
|
||||||
},
|
},
|
||||||
headerLinks: [
|
navbar: {
|
||||||
{url: 'docs/introduction', label: 'Docs'},
|
title: 'Docusaurus',
|
||||||
{url: 'blog', label: 'Blog'},
|
logo: {
|
||||||
{url: 'feedback/', label: 'Feedback'},
|
alt: 'Docusaurus Logo',
|
||||||
],
|
src: 'img/docusaurus.svg',
|
||||||
|
},
|
||||||
|
links: [
|
||||||
|
{to: 'docs/introduction', label: 'Docs', position: 'left'},
|
||||||
|
{to: 'blog', label: 'Blog', position: 'left'},
|
||||||
|
{to: 'feedback', label: 'Feedback', position: 'left'},
|
||||||
|
{
|
||||||
|
href: 'https://github.com/facebook/docusaurus',
|
||||||
|
label: 'GitHub',
|
||||||
|
position: 'right',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
footer: {
|
footer: {
|
||||||
style: 'dark',
|
style: 'dark',
|
||||||
links: [
|
links: [
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue