feat(theme-classic): new 'html' type navbar item (#7058)

* feat(theme-classic): allow using html in dropdown items

* Fix tests

* Introduce HTML type for navbar item

* Update packages/docusaurus-theme-classic/src/theme/NavbarItem/HtmlNavbarItem.tsx

Co-authored-by: Sébastien Lorber <slorber@users.noreply.github.com>

Co-authored-by: Sébastien Lorber <slorber@users.noreply.github.com>
Co-authored-by: Joshua Chen <sidachen2003@gmail.com>
This commit is contained in:
Alexey Pyltsyn 2022-04-15 13:58:15 +03:00 committed by GitHub
parent 5273a534d3
commit 84d04ed6ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 135 additions and 1 deletions

View file

@ -150,12 +150,22 @@ describe('themeConfig', () => {
},
],
},
// HTML-only
{
type: 'html',
position: 'right',
value: '<button>Give feedback</button>',
},
// Dropdown with label as HTML
{
type: 'dropdown',
label: 'Tools <sup>new</sup>',
position: 'left',
items: [
{
type: 'html',
value: '<b>Supported package managers</b>',
},
{
type: 'doc',
docId: 'npm',
@ -181,6 +191,10 @@ describe('themeConfig', () => {
},
],
dropdownItemsAfter: [
{
type: 'html',
value: '<hr/>',
},
{
to: '/versions',
label: 'All versions',

View file

@ -872,6 +872,16 @@ declare module '@theme/NavbarItem/DocSidebarNavbarItem' {
export default function DocSidebarNavbarItem(props: Props): JSX.Element;
}
declare module '@theme/NavbarItem/HtmlNavbarItem' {
import type {Props as DefaultNavbarItemProps} from '@theme/NavbarItem/DefaultNavbarItem';
export interface Props extends DefaultNavbarItemProps {
readonly value: string;
}
export default function HtmlNavbarItem(props: Props): JSX.Element;
}
declare module '@theme/NavbarItem' {
import type {ComponentProps} from 'react';
import type {Props as DefaultNavbarItemProps} from '@theme/NavbarItem/DefaultNavbarItem';
@ -882,12 +892,14 @@ declare module '@theme/NavbarItem' {
import type {Props as DocsVersionDropdownNavbarItemProps} from '@theme/NavbarItem/DocsVersionDropdownNavbarItem';
import type {Props as LocaleDropdownNavbarItemProps} from '@theme/NavbarItem/LocaleDropdownNavbarItem';
import type {Props as SearchNavbarItemProps} from '@theme/NavbarItem/SearchNavbarItem';
import type {Props as HtmlNavbarItemProps} from '@theme/NavbarItem/HtmlNavbarItem';
export type LinkLikeNavbarItemProps =
| ({readonly type?: 'default'} & DefaultNavbarItemProps)
| ({readonly type: 'doc'} & DocNavbarItemProps)
| ({readonly type: 'docsVersion'} & DocsVersionNavbarItemProps)
| ({readonly type: 'docSidebar'} & DocSidebarNavbarItemProps);
| ({readonly type: 'docSidebar'} & DocSidebarNavbarItemProps)
| ({readonly type: 'html'} & HtmlNavbarItemProps);
export type Props = ComponentProps<'a'> & {
readonly position?: 'left' | 'right';

View file

@ -0,0 +1,32 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React from 'react';
import clsx from 'clsx';
import type {Props} from '@theme/NavbarItem/HtmlNavbarItem';
export default function HtmlNavbarItem({
value,
className,
mobile = false,
isDropdownItem = false,
}: Props): JSX.Element {
const Comp = isDropdownItem ? 'li' : 'div';
return (
<Comp
className={clsx(
{
navbar__item: !mobile && !isDropdownItem,
'menu__list-item': mobile,
},
className,
)}
dangerouslySetInnerHTML={{__html: value}}
/>
);
}

View file

@ -12,6 +12,7 @@ import DropdownNavbarItem, {
} from '@theme/NavbarItem/DropdownNavbarItem';
import LocaleDropdownNavbarItem from '@theme/NavbarItem/LocaleDropdownNavbarItem';
import SearchNavbarItem from '@theme/NavbarItem/SearchNavbarItem';
import HtmlNavbarItem from '@theme/NavbarItem/HtmlNavbarItem';
import type {Types, Props} from '@theme/NavbarItem';
const NavbarItemComponents: {
@ -23,6 +24,7 @@ const NavbarItemComponents: {
localeDropdown: () => LocaleDropdownNavbarItem,
search: () => SearchNavbarItem,
dropdown: () => DropdownNavbarItem,
html: () => HtmlNavbarItem,
// Need to lazy load these items as we don't know for sure the docs plugin is
// loaded. See https://github.com/facebook/docusaurus/issues/3360

View file

@ -93,6 +93,12 @@ const DocSidebarItemSchema = NavbarItemBaseSchema.append({
docsPluginId: Joi.string(),
});
const HtmlNavbarItemSchema = Joi.object({
className: Joi.string(),
type: Joi.string().equal('html').required(),
value: Joi.string().required(),
});
const itemWithType = (type: string | undefined) => {
// because equal(undefined) is not supported :/
const typeSchema = type
@ -125,6 +131,10 @@ const DropdownSubitemSchema = Joi.object({
is: itemWithType(undefined),
then: DefaultNavbarItemSchema,
},
{
is: itemWithType('html'),
then: HtmlNavbarItemSchema,
},
{
is: Joi.alternatives().try(
itemWithType('dropdown'),
@ -196,6 +206,10 @@ const NavbarItemSchema = Joi.object({
is: itemWithType('search'),
then: SearchItemSchema,
},
{
is: itemWithType('html'),
then: HtmlNavbarItemSchema,
},
{
is: itemWithType(undefined),
then: Joi.object().when('.', {