@redocly/theme
Version:
Shared UI components lib
126 lines (117 loc) • 3.62 kB
text/typescript
import type { ResolvedNavItem, Version } from '@redocly/config';
import type { Location } from 'react-router-dom';
import { type Locale, type TFunction } from '../types/l10n';
import { type ItemState } from '../types/sidebar';
import { MenuItemType } from '../constants/common';
import { getPathnameForLocale, withoutPathPrefix, withPathPrefix } from './urls';
const TRANSLATION_KEYS = {
version: 'mobileMenu.version',
};
export const mapNavbarItems = (
items: ResolvedNavItem[],
defaultLocale: string,
currentLocale: string,
locales: Locale[],
location: Location,
): ItemState[] => {
return items.map(
(navItem) =>
({
...navItem,
...(navItem.items && {
items: mapNavbarItems(navItem.items, defaultLocale, currentLocale, locales, location),
}),
...('link' in navItem && { link: navItem.link || '/' }),
active:
'link' in navItem &&
isItemActive(navItem, defaultLocale, currentLocale, locales, location),
hasActiveSubItem: !!navItem.items?.find((item) =>
isItemActive(item, defaultLocale, currentLocale, locales, location),
),
}) as ItemState,
);
};
export const isItemActive = (
item: ResolvedNavItem,
defaultLocale: string,
currentLocale: string,
locales: Locale[],
location: Location,
): boolean => {
const pathHash = location.pathname + location.hash;
const link = item.languageInsensitive
? item.link || ''
: getPathnameForLocale(item.link || '/', defaultLocale, currentLocale, locales);
return pathHash === withPathPrefix(link);
};
export const buildLanguagesGroup = (
locales: Locale[],
defaultLocale: string,
currentLocale: string,
): ResolvedNavItem | undefined => {
if (locales.length < 2) {
return;
}
const locale = locales.find((l) => l.code === currentLocale);
return {
type: 'group',
label: locale?.name || locale?.code,
items: locales
.filter((locale) => locale.code !== currentLocale)
.map((locale) => {
const newLangPathname = getPathnameForLocale(
withoutPathPrefix(location.pathname),
defaultLocale,
locale.code,
locales,
);
const newUrlWithLanguage = `${newLangPathname}${location.search}${location.hash}`;
return {
type: 'link',
label: locale.name || locale.code || '',
link: newUrlWithLanguage,
active: false,
hasActiveSubItem: false,
languageInsensitive: true,
};
}),
};
};
export const buildVersionSection = (
translate: TFunction,
versions: Version[],
activeVersion?: Version,
): ResolvedNavItem[] => {
return [
{
type: 'separator',
label: translate(TRANSLATION_KEYS.version, 'Version'),
},
{
type: 'group',
label: activeVersion?.label,
items: versions
.filter((version) => !version.active)
.map((version) => {
return {
type: 'link',
label: version.label,
link: version.link,
active: false,
hasActiveSubItem: false,
};
}),
},
];
};
export function getMenuItemType(item: ItemState): MenuItemType {
if (item.type === MenuItemType.Separator) {
return MenuItemType.Separator;
} else if (item.menuStyle === 'drilldown') {
return MenuItemType.DrillDown;
} else if (item.items?.length || (item.type === MenuItemType.Group && item.items?.length)) {
return MenuItemType.Group;
} else if (item.httpVerb) {
return MenuItemType.Operation;
} else return MenuItemType.Default;
}