mobile navbar

This commit is contained in:
Hossein Mehrabi 2022-10-10 02:48:31 +03:30
parent dd7a80df1a
commit b218bd2ed5
6 changed files with 215 additions and 5 deletions

View File

@ -0,0 +1,33 @@
.root {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
width: 100%;
padding: 0 1.875rem;
& > div {
flex: 0 0 !important;
}
}
.root > div:nth-child(2) {
width: 57%;
flex-basis: 57%;
margin-left: 12px;
flex-shrink: 0;
flex-grow: 1;
flex: 1 1 57% !important;
button {
width: auto;
}
}
.root > div:last-child > button {
font-size: 0.75rem;
font-weight: bold;
color: #909091;
margin-left: 8px;
}

View File

@ -0,0 +1,28 @@
import NavbarLogo from '@theme/Navbar/Logo'
import clsx from 'clsx'
import React, { useState } from 'react'
import { useDebounce } from 'react-use'
import { SearchBar } from '../../../SearchBar/SearchBar'
import styles from './MobileSearch.module.scss'
export const MobileSearch: React.FC<{
render: boolean
onCancel: () => void
}> = ({ render, onCancel }) => {
const [renderSearchBar, setRenderSearchBar] = useState(false)
useDebounce(() => setRenderSearchBar(render), render ? 0 : 1000, [render])
return (
<div className={clsx(styles.root)}>
<div>
<NavbarLogo />
</div>
<div>{renderSearchBar && <SearchBar />}</div>
<div>
<button className={clsx('clean-btn')} onClick={onCancel}>
Cancel
</button>
</div>
</div>
)
}

View File

@ -0,0 +1 @@
export * from './MobileSearch'

View File

@ -1,5 +1,10 @@
import { useThemeConfig } from '@docusaurus/theme-common'
import { useNavbarMobileSidebar } from '@docusaurus/theme-common/internal'
import {
useNavbarMobileSidebar,
useSearchPage,
} from '@docusaurus/theme-common/internal'
import { IconSearch } from '@site/src/components/Icon'
import { IconButton } from '@site/src/components/IconButton'
import {
globalStore,
selectHiddenSidebar,
@ -12,7 +17,9 @@ import NavbarSearch from '@theme/Navbar/Search'
import NavbarItem, { Props as NavbarItemConfig } from '@theme/NavbarItem'
import SearchBar from '@theme/SearchBar'
import clsx from 'clsx'
import React from 'react'
import React, { useState } from 'react'
import { useSearch } from '../../SearchBar/hooks/useSearch'
import { MobileSearch } from './MobileSearch/MobileSearch'
import { ShareButton } from './ShareButton'
import styles from './styles.module.scss'
@ -59,8 +66,16 @@ export default function NavbarContent(): JSX.Element {
const dispatch = globalStore.useDispatch()
const hiddenDesktopSidebar = globalStore.useSelector(selectHiddenSidebar)
const [mobileSearch, setMobileSearch] = useState(false)
return (
<div className={clsx('row', styles.root)}>
<div
className={clsx(
'row',
styles.root,
mobileSearch && styles.activeMobileSearch,
)}
>
<div className="col col--2">
<SidebarToggleButton
onToggle={mobileSidebar.toggle}
@ -108,6 +123,34 @@ export default function NavbarContent(): JSX.Element {
</>
)}
</div>
<div
className={clsx(
'col',
styles.headerRightMobile,
mobileSearch && styles.shifted,
)}
>
{localeDropdown && <NavbarItem {...localeDropdown} />}
<IconButton
className={styles.searchButton}
onClick={() => setMobileSearch(true)}
>
<IconSearch />
</IconButton>
</div>
<div
className={clsx(
styles.mobileSearchContainer,
mobileSearch && styles.visible,
)}
>
<MobileSearch
render={mobileSearch}
onCancel={() => setMobileSearch(false)}
/>
</div>
</div>
)
}

View File

@ -112,6 +112,7 @@
@include utils.responsive('lg', 'down') {
.root {
padding: 0 var(--ifm-spacing-horizontal);
overflow: hidden;
}
.root > * {
@ -124,8 +125,6 @@
}
.headerMiddle {
margin-left: 20px;
.leftContainer.shifted {
transform: none;
}
@ -138,6 +137,55 @@
.headerRight {
display: none !important;
}
.searchContainer {
display: none;
}
}
.headerRightMobile {
visibility: visible;
display: flex !important;
flex: 1 1 auto !important;
align-items: center;
justify-content: flex-end;
& > div {
display: initial;
}
& > div:first-child {
border-radius: 12px;
padding: 4px 12px;
height: 2.125rem;
a {
font-size: 0.875rem;
}
svg {
margin-left: 0.75rem;
vertical-align: middle;
}
margin-right: 0.75rem;
}
.searchButton {
background-color: #eeeef1;
padding: 7px 13px;
border-radius: 12px;
}
transition: 0.7s ease-in-out;
transform: translateX(0%);
&.shifted {
transform: translateX(-100%);
opacity: 0%;
}
}
/*
@ -160,3 +208,52 @@ Hide color mode toggle in small viewports
display: none;
}
}
.root {
& > div:first-child,
.headerMiddle {
opacity: 1;
transition: 1s;
visibility: visible;
}
}
.root.activeMobileSearch {
& > div:first-child,
.headerMiddle {
opacity: 0;
visibility: hidden;
}
}
.mobileSearchContainer {
top: 0;
left: 0;
width: 100%;
height: 100%;
position: absolute;
background-color: var(--ifm-background-surface-color);
transform: translateX(100%);
opacity: 0;
transition: 0.6s ease-in-out;
visibility: hidden;
&.visible {
opacity: 1;
transform: translateX(0%);
visibility: visible;
}
}
.headerRightMobile {
display: none !important;
visibility: hidden;
}
@include utils.responsive('lg', 'down') {
.headerRightMobile {
display: flex !important;
visibility: visible;
}
}

View File

@ -1,3 +1,5 @@
@use '@site/src/css/utils';
.navbar-sidebar__brand {
--ifm-navbar-padding-horizontal: 1rem;
}
@ -13,3 +15,9 @@
:root {
}
@include utils.responsive('lg', 'down') {
.navbar {
background: var(--ifm-background-surface-color);
}
}