Skip to content

Commit

Permalink
feat(theme-classic): new 'html' type navbar item (#7058)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>

Co-authored-by: Sébastien Lorber <[email protected]>
Co-authored-by: Joshua Chen <[email protected]>
  • Loading branch information
3 people authored Apr 15, 2022
1 parent 5273a53 commit 84d04ed
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -181,6 +191,10 @@ describe('themeConfig', () => {
},
],
dropdownItemsAfter: [
{
type: 'html',
value: '<hr/>',
},
{
to: '/versions',
label: 'All versions',
Expand Down
14 changes: 13 additions & 1 deletion packages/docusaurus-theme-classic/src/theme-classic.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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';
Expand Down
Original file line number Diff line number Diff line change
@@ -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}}
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -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
Expand Down
14 changes: 14 additions & 0 deletions packages/docusaurus-theme-classic/src/validateThemeConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -125,6 +131,10 @@ const DropdownSubitemSchema = Joi.object({
is: itemWithType(undefined),
then: DefaultNavbarItemSchema,
},
{
is: itemWithType('html'),
then: HtmlNavbarItemSchema,
},
{
is: Joi.alternatives().try(
itemWithType('dropdown'),
Expand Down Expand Up @@ -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('.', {
Expand Down
34 changes: 34 additions & 0 deletions website/docs/api/themes/theme-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

Expand Down Expand Up @@ -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.
Expand Down
17 changes: 17 additions & 0 deletions website/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand 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,
Expand All @@ -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',
Expand All @@ -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',
Expand Down
9 changes: 9 additions & 0 deletions website/src/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

0 comments on commit 84d04ed

Please sign in to comment.