VersionSelector.tsx
1 import React, { useState, useEffect } from 'react'; 2 import DropdownNavbarItem from '@theme/NavbarItem/DropdownNavbarItem'; 3 import BrowserOnly from '@docusaurus/BrowserOnly'; 4 import { LinkLikeNavbarItemProps } from '@theme/NavbarItem'; 5 6 interface VersionSelectorProps { 7 mobile?: boolean; 8 position?: 'left' | 'right'; 9 label?: string; 10 [key: string]: any; 11 } 12 13 function getLabel(currentVersion: string, versions: string[]): string { 14 if (currentVersion === 'latest' && versions.length > 0) { 15 // version list is sorted in descending order, so the first one is the latest 16 return `Version: ${versions[0]} (latest)`; 17 } 18 19 return `Version: ${currentVersion}`; 20 } 21 22 function VersionSelectorImpl({ mobile, label = 'Version', ...props }: VersionSelectorProps): JSX.Element { 23 const [versions, setVersions] = useState<string[]>([]); 24 const [loading, setLoading] = useState(true); 25 const versionsUrl = window.location.origin + '/docs/versions.json'; 26 27 // Determine current version from URL or default to latest 28 const docPath = window.location.pathname; 29 const currentVersion = docPath.match(/^\/docs\/([a-zA-Z0-9.]+)/)?.[1]; 30 31 const versionItems: LinkLikeNavbarItemProps[] = versions?.map((version) => ({ 32 type: 'default', 33 label: version, 34 to: window.location.origin + `/docs/${version}/`, 35 target: '_self', 36 })); 37 38 useEffect(() => { 39 const fetchVersions = async () => { 40 try { 41 const response = await fetch(versionsUrl); 42 const data = await response.json(); 43 if (data['versions'] != null) { 44 setVersions(data['versions']); 45 } 46 } catch (error) { 47 // do nothing, this can happen in dev where the versions.json file is not available 48 } finally { 49 setLoading(false); 50 } 51 }; 52 53 fetchVersions(); 54 }, [versionsUrl]); 55 56 if (loading || versions == null || versions.length === 0) { 57 return null; 58 } 59 60 return ( 61 <DropdownNavbarItem {...props} mobile={mobile} label={getLabel(currentVersion, versions)} items={versionItems} /> 62 ); 63 } 64 65 export default function VersionSelector(props: VersionSelectorProps): JSX.Element { 66 return <BrowserOnly>{() => <VersionSelectorImpl {...props} />}</BrowserOnly>; 67 }