mirror of
https://github.com/facebook/docusaurus.git
synced 2025-08-03 16:59:06 +02:00
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:
parent
5273a534d3
commit
84d04ed6ed
8 changed files with 135 additions and 1 deletions
|
@ -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',
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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}}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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('.', {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue