mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-30 01:17:07 +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('.', {
|
||||
|
|
|
@ -312,6 +312,7 @@ Navbar dropdown items only accept the following **"link-like" item types**:
|
|||
- [Navbar doc link](#navbar-doc-link)
|
||||
- [Navbar docs version](#navbar-docs-version)
|
||||
- [Navbar doc sidebar](#navbar-doc-sidebar)
|
||||
- [Navbar with custom HTML](#navbar-with-custom-html)
|
||||
|
||||
Note that the dropdown base item is a clickable link as well, so this item can receive any of the props of a [plain navbar link](#navbar-link).
|
||||
|
||||
|
@ -621,6 +622,39 @@ module.exports = {
|
|||
};
|
||||
```
|
||||
|
||||
#### Navbar with custom HTML {#navbar-with-custom-html}
|
||||
|
||||
You can also render your own HTML markup inside a navbar item using this navbar item type.
|
||||
|
||||
<APITable name="navbar-html">
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `type` | `'html'` | **Required** | Sets the type of this item to a HTML element. |
|
||||
| `position` | <code>'left' \| 'right'</code> | `'left'` | The side of the navbar this item should appear on. |
|
||||
| `className` | `string` | `''` | Custom CSS class for this navbar item. |
|
||||
| `value` | `string` | `''` | Custom HTML to be rendered inside this navbar item. |
|
||||
|
||||
</APITable>
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
themeConfig: {
|
||||
navbar: {
|
||||
items: [
|
||||
// highlight-start
|
||||
{
|
||||
type: 'html',
|
||||
position: 'right',
|
||||
value: '<button>Give feedback</button>',
|
||||
},
|
||||
// highlight-end
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Auto-hide sticky navbar {#auto-hide-sticky-navbar}
|
||||
|
||||
You can enable this cool UI feature that automatically hides the navbar when a user starts scrolling down the page, and show it again when the user scrolls up.
|
||||
|
|
|
@ -419,6 +419,15 @@ const config = {
|
|||
position: 'right',
|
||||
dropdownActiveClassDisabled: true,
|
||||
dropdownItemsAfter: [
|
||||
{
|
||||
type: 'html',
|
||||
value: '<hr class="dropdown-separator">',
|
||||
},
|
||||
{
|
||||
type: 'html',
|
||||
className: 'dropdown-archived-versions',
|
||||
value: '<b>Archived versions</b>',
|
||||
},
|
||||
...ArchivedVersionsDropdownItems.map(
|
||||
([versionName, versionUrl]) => ({
|
||||
label: versionName,
|
||||
|
@ -429,6 +438,10 @@ const config = {
|
|||
href: 'https://v1.docusaurus.io',
|
||||
label: '1.x.x',
|
||||
},
|
||||
{
|
||||
type: 'html',
|
||||
value: '<hr class="dropdown-separator">',
|
||||
},
|
||||
{
|
||||
to: '/versions',
|
||||
label: 'All versions',
|
||||
|
@ -439,6 +452,10 @@ const config = {
|
|||
type: 'localeDropdown',
|
||||
position: 'right',
|
||||
dropdownItemsAfter: [
|
||||
{
|
||||
type: 'html',
|
||||
value: '<hr style="margin: 0.3rem 0;">',
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/facebook/docusaurus/issues/3526',
|
||||
label: 'Help Us Translate',
|
||||
|
|
|
@ -207,3 +207,12 @@ div[class^='announcementBar_'] {
|
|||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-separator {
|
||||
margin: 0.3rem 0;
|
||||
}
|
||||
|
||||
.dropdown-archived-versions {
|
||||
font-size: 0.875rem;
|
||||
padding: 0.2rem 0.5rem;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue