feat: allow using pure HTML as label in navbar links (#7079)

Co-authored-by: sebastienlorber <lorber.sebastien@gmail.com>
This commit is contained in:
Alexey Pyltsyn 2022-04-07 13:33:52 +03:00 committed by GitHub
parent 529d853ab8
commit bfbc78e52a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 63 additions and 27 deletions

View file

@ -112,6 +112,13 @@ describe('themeConfig', () => {
docId: 'intro',
label: 'Introduction',
},
// Doc link with HTML as label
{
type: 'doc',
position: 'left',
docId: 'intro',
html: '<b>Introduction</b>',
},
// Regular link
{
to: '/guide/',
@ -119,6 +126,13 @@ describe('themeConfig', () => {
position: 'left',
activeBaseRegex: '/guide/',
},
// Regular link with HTML as label
{
to: '/guide/',
html: '<b>Guide</b>',
position: 'left',
activeBaseRegex: '/guide/',
},
// Regular dropdown
{
label: 'Community',
@ -136,10 +150,10 @@ describe('themeConfig', () => {
},
],
},
// Dropdown with name
// Dropdown with label as HTML
{
type: 'dropdown',
label: 'Tools',
label: 'Tools <sup>new</sup>',
position: 'left',
items: [
{

View file

@ -651,6 +651,7 @@ declare module '@theme/NavbarItem/NavbarNavLink' {
readonly activeBaseRegex?: string;
readonly exact?: boolean;
readonly label?: ReactNode;
readonly html?: string;
readonly prependBaseUrlToHref?: string;
}

View file

@ -21,6 +21,7 @@ export default function NavbarNavLink({
to,
href,
label,
html,
activeClassName = '',
prependBaseUrlToHref,
...props
@ -33,32 +34,47 @@ export default function NavbarNavLink({
const isExternalLink = label && href && !isInternalUrl(href);
const isDropdownLink = activeClassName === dropdownLinkActiveClass;
// Link content is set through html XOR label
const linkContentProps = html
? {dangerouslySetInnerHTML: {__html: html}}
: {
children: (
<>
{label}
{isExternalLink && (
<IconExternalLink
{...(isDropdownLink && {width: 12, height: 12})}
/>
)}
</>
),
};
if (href) {
return (
<Link
{...(href
? {
href: prependBaseUrlToHref ? normalizedHref : href,
href={prependBaseUrlToHref ? normalizedHref : href}
{...props}
{...linkContentProps}
/>
);
}
: {
isNavLink: true,
activeClassName: !props.className?.includes(activeClassName)
? activeClassName
: '',
to: toUrl,
...(activeBasePath || activeBaseRegex
? {
return (
<Link
to={toUrl}
isNavLink
activeClassName={
!props.className?.includes(activeClassName) ? activeClassName : ''
}
{...((activeBasePath || activeBaseRegex) && {
isActive: (_match, location) =>
activeBaseRegex
? isRegexpStringMatch(activeBaseRegex, location.pathname)
: location.pathname.startsWith(activeBaseUrl),
}
: null),
})}
{...props}>
{label}
{isExternalLink && (
<IconExternalLink {...(isDropdownLink && {width: 12, height: 12})} />
)}
</Link>
{...props}
{...linkContentProps}
/>
);
}

View file

@ -49,8 +49,10 @@ const NavbarItemPosition = Joi.string().equal('left', 'right').default('left');
const NavbarItemBaseSchema = Joi.object({
label: Joi.string(),
html: Joi.string(),
className: Joi.string(),
})
.nand('html', 'label')
// We allow any unknown attributes on the links (users may need additional
// attributes like target, aria-role, data-customAttribute...)
.unknown();

View file

@ -259,6 +259,7 @@ Accepted fields:
| --- | --- | --- | --- |
| `type` | `'default'` | Optional | Sets the type of this item to a link. |
| `label` | `string` | **Required** | The name to be shown for this item. |
| `html` | `string` | Optional | Same as `label`, but renders pure HTML instead of text content. |
| `to` | `string` | **Required** | Client-side routing, used for navigating within the website. The baseUrl will be automatically prepended to this value. |
| `href` | `string` | **Required** | A full-page navigation, used for navigating outside of the website. **Only one of `to` or `href` should be used.** |
| `prependBaseUrlToHref` | `boolean` | `false` | Prepends the baseUrl to `href` values. |
@ -288,6 +289,8 @@ module.exports = {
// Only one of "to" or "href" should be used
// href: 'https://www.facebook.com',
label: 'Introduction',
// Only one of "label" or "html" should be used
// html: '<b>Introduction</b>'
position: 'left',
activeBaseRegex: 'docs/(next|v8)',
target: '_blank',