Skip to content

Commit

Permalink
feat: support multi version menu in nav (#206)
Browse files Browse the repository at this point in the history
  • Loading branch information
sanyuan0704 authored Oct 19, 2023
1 parent 6b8f55e commit 887b0cb
Show file tree
Hide file tree
Showing 12 changed files with 268 additions and 167 deletions.
6 changes: 6 additions & 0 deletions .changeset/cold-pianos-think.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@rspress/shared': patch
'@rspress/core': patch
---

feat: support multi version menu in nav
15 changes: 1 addition & 14 deletions packages/core/src/theme-default/components/Nav/NavMenuGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
withoutBase,
} from '@rspress/shared';
import { Link } from '../Link';
import Translator from '../../assets/translator.svg';
import Down from '../../assets/down.svg';
import { Tag } from '../Tag';
import { NavMenuSingleItem } from './NavMenuSingleItem';
Expand All @@ -25,8 +24,6 @@ export interface NavMenuGroupItem {
base?: string;
// Locales
langs?: string[];
// When the item is transition, we need to give a react element instead of a string.
isTranslation?: boolean;
}

function ActiveGroupItem({ item }: { item: NavItemWithLink }) {
Expand Down Expand Up @@ -67,7 +64,6 @@ function NormalGroupItem({ item }: { item: NavItemWithLink }) {
export function NavMenuGroup(item: NavMenuGroupItem) {
const {
activeValue,
isTranslation,
items: groupItems,
base = '',
link = '',
Expand Down Expand Up @@ -120,16 +116,7 @@ export function NavMenuGroup(item: NavMenuGroupItem) {
}}
>
<Tag tag={item.tag} />
{isTranslation ? (
<Translator
style={{
with: '18px',
height: '18px',
}}
/>
) : (
item.text
)}
{item.text}
</span>
<Down />
</>
Expand Down
16 changes: 16 additions & 0 deletions packages/core/src/theme-default/components/Nav/NavTranslations.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { NavMenuGroup } from './NavMenuGroup';
import styles from './index.module.scss';
import { useTranslationMenuData } from './menuDataHooks';

export function NavTranslations() {
const translationMenuData = useTranslationMenuData();
return (
<div
className={`translation ${styles.menuItem} flex text-sm font-bold items-center px-3 py-2`}
>
<div>
<NavMenuGroup {...translationMenuData} />
</div>
</div>
);
}
16 changes: 16 additions & 0 deletions packages/core/src/theme-default/components/Nav/NavVersions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { NavMenuGroup } from './NavMenuGroup';
import styles from './index.module.scss';
import { useVersionMenuData } from './menuDataHooks';

export function NavVersions() {
const versionsMenuData = useVersionMenuData();
return (
<div
className={`translation ${styles.menuItem} flex text-sm font-bold items-center px-3 py-2`}
>
<div>
<NavMenuGroup {...versionsMenuData} />
</div>
</div>
);
}
62 changes: 12 additions & 50 deletions packages/core/src/theme-default/components/Nav/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { NavItem, replaceLang } from '@rspress/shared';
import { NavItem } from '@rspress/shared';
import { useLocation } from 'react-router-dom';
import { Search } from '@theme';
import { useEffect, useState } from 'react';
import { isMobileDevice, useHiddenNav, useLocaleSiteData } from '../../logic';
import { NavHamburger } from '../NavHambmger';
import { SocialLinks } from '../SocialLinks';
import { SwitchAppearance } from '../SwitchAppearance';
import { NavMenuGroup, NavMenuGroupItem } from './NavMenuGroup';
import { NavMenuGroup } from './NavMenuGroup';
import { NavMenuSingleItem } from './NavMenuSingleItem';
import styles from './index.module.scss';
import { NavBarTitle } from './NavBarTitle';
import { usePageData, useVersion } from '@/runtime';
import { NavTranslations } from './NavTranslations';
import { NavVersions } from './NavVersions';
import { usePageData } from '@/runtime';

export interface NavProps {
beforeNav?: React.ReactNode;
Expand All @@ -20,62 +22,23 @@ export interface NavProps {

const DEFAULT_NAV_POSTION = 'right';

const NavTranslations = ({
translationMenuData,
}: {
translationMenuData: NavMenuGroupItem;
}) => {
return (
<div
className={`translation ${styles.menuItem} flex text-sm font-bold items-center px-3 py-2`}
>
<div>
<NavMenuGroup {...translationMenuData} isTranslation />
</div>
</div>
);
};

export function Nav(props: NavProps) {
const { beforeNavTitle, afterNavTitle, beforeNav } = props;
const { siteData, page } = usePageData();
const { siteData } = usePageData();
const { base } = siteData;
const { pathname } = useLocation();
const localeData = useLocaleSiteData();
const currentVersion = useVersion();
const [isMobile, setIsMobile] = useState(false);
const hiddenNav = useHiddenNav();
const localeLanguages = Object.values(siteData.themeConfig.locales || {});
const localeLanguages = Object.values(
siteData.locales || siteData.themeConfig.locales || {},
);
const hasMultiLanguage = localeLanguages.length > 1;
const hasMutilVersion = siteData.multiVersion.versions.length > 1;
const socialLinks = siteData.themeConfig.socialLinks || [];
const hasSocialLinks = socialLinks.length > 0;
const defaultLang = siteData.lang || '';
const defaultVersion = siteData.multiVersion.default || '';
const { lang } = page;
const langs = localeLanguages.map(item => item.lang || '') || [];

const translationMenuData = hasMultiLanguage
? {
items: localeLanguages.map(item => ({
text: item?.label,
link: replaceLang(
pathname,
{
current: lang,
target: item.lang,
default: defaultLang,
},
{
current: currentVersion,
default: defaultVersion,
},
base,
),
})),
activeValue: localeLanguages.find(item => lang === item.lang)?.label,
}
: null;

useEffect(() => {
setIsMobile(isMobileDevice());
}, []);
Expand Down Expand Up @@ -139,9 +102,8 @@ export function Nav(props: NavProps) {
)}
<NavMenu menuItems={rightMenuItems} />
<div className="flex-center flex-row">
{hasMultiLanguage && (
<NavTranslations translationMenuData={translationMenuData} />
)}
{hasMultiLanguage && <NavTranslations />}
{hasMutilVersion && <NavVersions />}
{hasAppearanceSwitch && (
<div className="mx-2">
<SwitchAppearance />
Expand Down
75 changes: 75 additions & 0 deletions packages/core/src/theme-default/components/Nav/menuDataHooks.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { replaceLang, replaceVersion } from '@rspress/shared';
import Translator from '../../assets/translator.svg';
import { useLocation, usePageData, useVersion } from '@/runtime';

export function useTranslationMenuData() {
const { siteData, page } = usePageData();
const currentVersion = useVersion();
const { pathname } = useLocation();
const defaultLang = siteData.lang || '';
const defaultVersion = siteData.multiVersion.default || '';
const localeLanguages = Object.values(
siteData.locales || siteData.themeConfig.locales || {},
);
const hasMultiLanguage = localeLanguages.length > 1;
const { lang: currentLang } = page;
const { base } = siteData;

const translationMenuData = hasMultiLanguage
? {
text: (
<Translator
style={{
width: '18px',
height: '18px',
}}
/>
),
items: localeLanguages.map(item => ({
text: item?.label,
link: replaceLang(
pathname,
{
current: currentLang,
target: item.lang,
default: defaultLang,
},
{
current: currentVersion,
default: defaultVersion,
},
base,
),
})),
activeValue: localeLanguages.find(item => currentLang === item.lang)
?.label,
}
: null;
return translationMenuData;
}

export function useVersionMenuData() {
const { siteData } = usePageData();
const currentVersion = useVersion();
const { pathname } = useLocation();
const defaultVersion = siteData.multiVersion.default || '';
const versions = siteData.multiVersion.versions || [];
const { base } = siteData;
const versionsMenuData = {
items: versions.map(version => ({
text: version,
link: replaceVersion(
pathname,
{
current: currentVersion,
target: version,
default: defaultVersion,
},
base,
),
})),
text: currentVersion,
activeValue: currentVersion,
};
return versionsMenuData;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function NavScreenMenuGroup(item: NavScreenMenuGroupItem) {

function ActiveGroupItem({ item }: { item: NavItemWithLink }) {
return (
<div className="p-1">
<div className="p-1 text-center">
<span className="text-brand">{item.text}</span>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,45 @@
.socialAndAppearance {
padding: 8px 0 7px;
}

.navScreenMenuGroup {
height: 39px;
overflow: hidden;
transition: border-color 0.5s;
}
.navScreenMenuGroup.open {
padding-bottom: 10px;
height: auto;
}
.button {
display: flex;
justify-content: center;
align-items: center;
padding: 8px 0 7px 0;
width: 100%;
line-height: 24px;
font-size: 14px;
font-weight: 500;
color: var(--rp-c-text-1);
transition: color 0.25s;
}

.buttonSpan {
display: flex;
align-items: center;
height: 24px;
padding-right: 4px;
}
.navScreenMenuGroup .items {
visibility: hidden;
}

.navScreenMenuGroup.open .items {
visibility: visible;
}
.down {
transition: all 0.5s;
}
.open.down {
transform: rotate(180deg);
}
Loading

0 comments on commit 887b0cb

Please sign in to comment.