Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(v2): allow to change location of search bar #4199

Merged
merged 5 commits into from
Feb 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions packages/docusaurus-theme-classic/src/theme/Navbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@ function Navbar(): JSX.Element {
navbar: {items, hideOnScroll, style},
colorMode: {disableSwitch: disableColorModeSwitch},
} = useThemeConfig();

const [sidebarShown, setSidebarShown] = useState(false);
const [isSearchBarExpanded, setIsSearchBarExpanded] = useState(false);

const {isDarkTheme, setLightTheme, setDarkTheme} = useThemeContext();
const {navbarRef, isNavbarVisible} = useHideableNavbar(hideOnScroll);

Expand All @@ -73,6 +70,7 @@ function Navbar(): JSX.Element {
}
}, [windowSize]);

const hasSearchNavbarItem = items.some((item) => item.type === 'search');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need help with proper typing this 🤷‍♂️

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just added something to fix it

export type NavbarItem = {
  type?: string | undefined;
  items?: NavbarItem[];
  label?: string;
};

it's not the ideal type but we'll improve that later, as there are many things that are not typed correctly currently

const {leftItems, rightItems} = splitNavItemsByPosition(items);

return (
Expand Down Expand Up @@ -101,9 +99,7 @@ function Navbar(): JSX.Element {
<Logo
className="navbar__brand"
imageClassName="navbar__logo"
titleClassName={clsx('navbar__title', {
[styles.hideLogoText]: isSearchBarExpanded,
})}
titleClassName={clsx('navbar__title')}
/>
{leftItems.map((item, i) => (
<NavbarItem {...item} key={i} />
Expand All @@ -121,10 +117,7 @@ function Navbar(): JSX.Element {
onChange={onToggleChange}
/>
)}
<SearchBar
handleSearchBarToggle={setIsSearchBarExpanded}
isSearchBarExpanded={isSearchBarExpanded}
Comment on lines -125 to -126
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's dead code, although it may be used by third party plugins implementing local search (not Algolia). It doesn't make sense to support it anyway.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree, and it's not documented afaik

/>
{!hasSearchNavbarItem && <SearchBar />}
</div>
</div>
<div
Expand Down Expand Up @@ -152,7 +145,12 @@ function Navbar(): JSX.Element {
<div className="menu">
<ul className="menu__list">
{items.map((item, i) => (
<NavbarItem mobile {...item} onClick={hideSidebar} key={i} />
<NavbarItem
mobile
{...(item as any)} // TODO fix typing
onClick={hideSidebar}
key={i}
/>
))}
</ul>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@
}
}

@media (max-width: 768px) {
.hideLogoText {
display: none;
}
}

.navbarHideable {
transition: transform var(--ifm-transition-fast) ease;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* 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 type {Props} from '@theme/NavbarItem/SearchNavbarItem';
import SearchBar from '@theme/SearchBar';
import styles from './styles.module.css';

export default function SearchNavbarItem({mobile}: Props): JSX.Element | null {
if (mobile) {
return null;
}

return (
<div className={styles.searchWrapper}>
<SearchBar />
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
import React from 'react';
import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem';
import LocaleDropdownNavbarItem from '@theme/NavbarItem/LocaleDropdownNavbarItem';
import SearchNavbarItem from '@theme/NavbarItem/SearchNavbarItem';
import type {Props} from '@theme/NavbarItem';

const NavbarItemComponents = {
default: () => DefaultNavbarItem,
localeDropdown: () => LocaleDropdownNavbarItem,
search: () => SearchNavbarItem,

// 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* 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.
*/

@media (max-width: 996px) {
.searchWrapper {
position: absolute;
right: var(--ifm-navbar-padding-horizontal);
}
}
4 changes: 4 additions & 0 deletions packages/docusaurus-theme-classic/src/theme/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@
* LICENSE file in the root directory of this source tree.
*/

// By default, the classic theme does not provide any SearchBar implementation
// If you swizzled this file, it is your responsibility to provide an implementation
// Tip: swizzle the SearchBar from the Algolia theme for inspiration:
// npm run swizzle @docusaurus/theme-search-algolia SearchBar
export {default} from '@docusaurus/Noop';
11 changes: 10 additions & 1 deletion packages/docusaurus-theme-classic/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,13 @@ declare module '@theme/NavbarItem/DefaultNavbarItem' {
export default DefaultNavbarItem;
}

declare module '@theme/NavbarItem/SearchNavbarItem' {
export type Props = {readonly mobile?: boolean};

const SearchNavbarItem: (props: Props) => JSX.Element;
export default SearchNavbarItem;
}

declare module '@theme/NavbarItem/LocaleDropdownNavbarItem' {
import type {Props as DefaultNavbarItemProps} from '@theme/NavbarItem/DefaultNavbarItem';
import type {NavLinkProps} from '@theme/NavbarItem/DefaultNavbarItem';
Expand Down Expand Up @@ -366,13 +373,15 @@ declare module '@theme/NavbarItem' {
import type {Props as DefaultNavbarItemProps} from '@theme/NavbarItem/DefaultNavbarItem';
import type {Props as DocsVersionDropdownNavbarItemProps} from '@theme/NavbarItem/DocsVersionDropdownNavbarItem';
import type {Props as DocsVersionNavbarItemProps} from '@theme/NavbarItem/DocsVersionNavbarItem';
import type {Props as SearchNavbarItemProps} from '@theme/NavbarItem/SearchNavbarItem';

export type Props =
| ({readonly type?: 'default' | undefined} & DefaultNavbarItemProps)
| ({
readonly type: 'docsVersionDropdown';
} & DocsVersionDropdownNavbarItemProps)
| ({readonly type: 'docsVersion'} & DocsVersionNavbarItemProps);
| ({readonly type: 'docsVersion'} & DocsVersionNavbarItemProps)
| ({readonly type: 'search'} & SearchNavbarItemProps);

const NavbarItem: (props: Props) => JSX.Element;
export default NavbarItem;
Expand Down
9 changes: 9 additions & 0 deletions packages/docusaurus-theme-classic/src/validateThemeConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ const LocaleDropdownNavbarItemSchema = Joi.object({
className: Joi.string(),
});

const SearchItemSchema = Joi.object({
type: Joi.string().equal('search').required(),
position: NavbarItemPosition,
});

// Can this be made easier? :/
const isOfType = (type) => {
let typeSchema = Joi.string().required();
Expand Down Expand Up @@ -139,6 +144,10 @@ const NavbarItemSchema = Joi.object().when({
is: isOfType('localeDropdown'),
then: LocaleDropdownNavbarItemSchema,
},
{
is: isOfType('search'),
then: SearchItemSchema,
},
{
is: isOfType(undefined),
then: Joi.forbidden().messages({
Expand Down
3 changes: 2 additions & 1 deletion packages/docusaurus-theme-common/src/utils/useThemeConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext';

export type DocsVersionPersistence = 'localStorage' | 'none';

// TODO improve
// TODO improve types, use unions
export type NavbarItem = {
type?: string | undefined;
items?: NavbarItem[];
label?: string;
};
Expand Down
24 changes: 19 additions & 5 deletions website/docs/api/themes/theme-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,12 +395,26 @@ module.exports = {
};
```

````
### Navbar search

If you use the [search](../../search.md), the search bar will be the rightmost element in the navbar.

However, with this special navbar item type, you can change the default location.

```js {5-8} title="docusaurus.config.js"
module.exports = {
themeConfig: {
navbar: {
items: [
{
type: 'localeDropdown',
position: 'left',
type: 'search',
position: 'right',
},
```
],
},
},
};
```

### Auto-hide sticky navbar

Expand All @@ -416,7 +430,7 @@ module.exports = {
// ...
},
};
````
```

### Navbar style

Expand Down