forked from apache/apisix-website
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: apisix docs version with badge (apache#1248)
- Loading branch information
Showing
6 changed files
with
237 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
123 changes: 123 additions & 0 deletions
123
doc/src/theme/NavbarItem/DocsVersionDropdownNavbarItem.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
/** | ||
* 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. | ||
*/ | ||
|
||
/* eslint-disable import/no-extraneous-dependencies, max-len, import/no-unresolved */ | ||
import type { FC } from 'react'; | ||
import React from 'react'; | ||
import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; | ||
import DropdownNavbarItem from '@theme/NavbarItem/DropdownNavbarItem'; | ||
import type { GlobalVersion } from '@theme/hooks/useDocs'; | ||
import { useVersions, useLatestVersion, useActiveDocContext } from '@theme/hooks/useDocs'; | ||
import type { Props } from '@theme/NavbarItem/DocsVersionDropdownNavbarItem'; | ||
import { useDocsPreferredVersion } from '@docusaurus/theme-common'; | ||
import { translate } from '@docusaurus/Translate'; | ||
import type { GlobalDataVersion } from '@docusaurus/plugin-content-docs-types'; | ||
import clsx from 'clsx'; | ||
import { LTSVersions } from '../../../../config/apisix-versions'; | ||
import style from './style.module.scss'; | ||
|
||
const getVersionMainDoc = (version: GlobalDataVersion) => version.docs.find((doc) => doc.id === version.mainDocId)!; | ||
|
||
const badgeObj = { | ||
LTS: <div className={clsx(style.badge, style.LTS)}>LTS</div>, | ||
Latest: <div className={clsx(style.badge, style.Latest)}>Latest</div>, | ||
}; | ||
|
||
interface LabelWithBadgeProps { | ||
version: GlobalVersion; | ||
isApisx: boolean; | ||
} | ||
const LabelWithBadge: FC<LabelWithBadgeProps> = (props) => { | ||
const { version, isApisx } = props; | ||
return ( | ||
<div> | ||
{version.label} | ||
{(() => { | ||
if (version.isLast) return badgeObj.Latest; | ||
if (isApisx && LTSVersions.includes(version.label)) return badgeObj.LTS; | ||
return null; | ||
})()} | ||
</div> | ||
); | ||
}; | ||
|
||
const DocsVersionDropdownNavbarItem = ({ | ||
mobile, | ||
docsPluginId, | ||
dropdownActiveClassDisabled, | ||
dropdownItemsBefore, | ||
dropdownItemsAfter, | ||
...props | ||
}: Props): JSX.Element => { | ||
const activeDocContext = useActiveDocContext(docsPluginId); | ||
const versions = useVersions(docsPluginId); | ||
const latestVersion = useLatestVersion(docsPluginId); | ||
const isApisix = docsPluginId === 'docs-apisix'; | ||
|
||
const { preferredVersion, savePreferredVersionName } = useDocsPreferredVersion(docsPluginId); | ||
|
||
function getItems() { | ||
const versionLinks = versions.map((version) => { | ||
// We try to link to the same doc, in another version | ||
// When not possible, fallback to the "main doc" of the version | ||
const versionDoc = activeDocContext?.alternateDocVersions[version.name] || getVersionMainDoc(version); | ||
return { | ||
isNavLink: true, | ||
label: <LabelWithBadge version={version} isApisx={isApisix} />, | ||
to: versionDoc.path, | ||
isActive: () => version === activeDocContext?.activeVersion, | ||
onClick: () => { | ||
savePreferredVersionName(version.name); | ||
}, | ||
}; | ||
}); | ||
|
||
return [...dropdownItemsBefore, ...versionLinks, ...dropdownItemsAfter]; | ||
} | ||
|
||
const items = getItems(); | ||
|
||
const dropdownVersion = activeDocContext.activeVersion ?? preferredVersion ?? latestVersion; | ||
|
||
// Mobile dropdown is handled a bit differently | ||
const dropdownLabel = mobile && items | ||
? translate({ | ||
id: 'theme.navbar.mobileVersionsDropdown.label', | ||
message: 'Versions', | ||
description: 'The label for the navbar versions dropdown on mobile view', | ||
}) | ||
: dropdownVersion.label; | ||
const dropdownTo = mobile && items ? undefined : getVersionMainDoc(dropdownVersion).path; | ||
|
||
// We don't want to render a version dropdown with 0 or 1 item | ||
// If we build the site with a single docs version (onlyIncludeVersions: ['1.0.0']) | ||
// We'd rather render a button instead of a dropdown | ||
if (items.length <= 1) { | ||
return ( | ||
<DefaultNavbarItem | ||
{...props} | ||
mobile={mobile} | ||
label={dropdownLabel} | ||
to={dropdownTo} | ||
isActive={dropdownActiveClassDisabled ? () => false : undefined} | ||
/> | ||
); | ||
} | ||
|
||
return ( | ||
<DropdownNavbarItem | ||
{...props} | ||
mobile={mobile} | ||
label={dropdownLabel} | ||
to={dropdownTo} | ||
items={items} | ||
isActive={dropdownActiveClassDisabled ? () => false : undefined} | ||
/> | ||
); | ||
}; | ||
|
||
export default DocsVersionDropdownNavbarItem; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/** | ||
* 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. | ||
*/ | ||
|
||
/* eslint-disable max-len, @typescript-eslint/no-explicit-any */ | ||
import React from 'react'; | ||
import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem'; | ||
import type { | ||
Props as DropdownNavbarItemProps, | ||
} from '@theme/NavbarItem/DropdownNavbarItem'; | ||
import DropdownNavbarItem from '@theme/NavbarItem/DropdownNavbarItem'; | ||
import LocaleDropdownNavbarItem from '@theme/NavbarItem/LocaleDropdownNavbarItem'; | ||
import SearchNavbarItem from '@theme/NavbarItem/SearchNavbarItem'; | ||
import type { Types, Props } from '@theme/NavbarItem'; | ||
|
||
const NavbarItemComponents: { [key: Exclude<Types, undefined>]: () => (props: any) => JSX.Element } = { | ||
default: () => DefaultNavbarItem, | ||
localeDropdown: () => LocaleDropdownNavbarItem, | ||
search: () => SearchNavbarItem, | ||
dropdown: () => DropdownNavbarItem, | ||
|
||
// 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 | ||
/* eslint-disable @typescript-eslint/no-var-requires, global-require */ | ||
docsVersion: () => require('@theme/NavbarItem/DocsVersionNavbarItem').default, | ||
docsVersionDropdown: () => require('@theme/NavbarItem/DocsVersionDropdownNavbarItem').default, | ||
doc: () => require('@theme/NavbarItem/DocNavbarItem').default, | ||
/* eslint-enable @typescript-eslint/no-var-requires, global-require */ | ||
} as const; | ||
|
||
type NavbarItemComponentType = keyof typeof NavbarItemComponents; | ||
|
||
const getNavbarItemComponent = (type: NavbarItemComponentType) => { | ||
const navbarItemComponentFn = NavbarItemComponents[type]; | ||
if (!navbarItemComponentFn) { | ||
throw new Error(`No NavbarItem component found for type "${type}".`); | ||
} | ||
return navbarItemComponentFn(); | ||
}; | ||
|
||
function getComponentType(type: Types, isDropdown: boolean): NavbarItemComponentType { | ||
// Backward compatibility: navbar item with no type set | ||
// but containing dropdown items should use the type "dropdown" | ||
if (!type || type === 'default') { | ||
return isDropdown ? 'dropdown' : 'default'; | ||
} | ||
return type as NavbarItemComponentType; | ||
} | ||
|
||
export const getInfimaActiveClassName = (mobile?: boolean): string => (mobile ? 'menu__link--active' : 'navbar__link--active'); | ||
|
||
const NavbarItem = ({ type, ...props }: Props): JSX.Element => { | ||
const componentType = getComponentType( | ||
type, | ||
(props as DropdownNavbarItemProps).items !== undefined, | ||
); | ||
const NavbarItemComponent = getNavbarItemComponent(componentType); | ||
return <NavbarItemComponent {...props} />; | ||
}; | ||
|
||
export default NavbarItem; |
Oops, something went wrong.