Skip to main content
Glama
LocaleSwitcher.tsx4.55 kB
'use client'; import { Link } from '@components/Link/Link'; import { getHTMLTextDir, getLocaleName } from '@intlayer/core'; import { Container, DropDown, Input, type PanelProps, } from '@intlayer/design-system'; import { MoveVertical } from 'lucide-react'; import { useIntlayer, useLocale } from 'next-intlayer'; import { type FC, useRef } from 'react'; import { useLocaleSearch } from './useLocaleSearch'; export type LocaleSwitcherProps = { fullLocaleName?: boolean; panelProps?: Omit<PanelProps, 'identifier'>; }; const DROPDOWN_IDENTIFIER = 'locale-switcher'; export const LocaleSwitcher: FC<LocaleSwitcherProps> = ({ fullLocaleName = false, panelProps, }) => { const { switchTo, searchInput, localeSwitcherLabel, languageListLabel, defaultLocaleName, } = useIntlayer('locale-switcher'); let localeName = defaultLocaleName.value as string; const inputRef = useRef<HTMLInputElement>(null); const { locale, pathWithoutLocale, availableLocales, setLocale } = useLocale(); const { searchResults, handleSearch } = useLocaleSearch( availableLocales, locale ); if (locale) { localeName = fullLocaleName ? getLocaleName(locale) : locale.toUpperCase(); } const handleFocusInput = () => { if (inputRef.current) { inputRef.current.focus(); } }; return ( <div className="flex rounded-xl text-text transition-colors"> <DropDown identifier={DROPDOWN_IDENTIFIER}> <DropDown.Trigger identifier={DROPDOWN_IDENTIFIER} aria-label={localeSwitcherLabel.value} size="sm" className="p-0!" variant="outline" color="text" roundedSize="5xl" onClick={handleFocusInput} > <div className="flex w-full items-center justify-between"> <div className="text-nowrap px-2 text-base">{localeName}</div> <MoveVertical className="w-5 self-center" /> </div> </DropDown.Trigger> <DropDown.Panel identifier={DROPDOWN_IDENTIFIER} isOverable isFocusable align="end" {...panelProps} > <Container className="max-h-[80vh] min-w-28 border border-text/5" separator="y" roundedSize="xl" transparency="sm" > <div className="p-3"> <Input type="search" aria-label={searchInput.ariaLabel.value} placeholder={searchInput.placeholder.value} onChange={(e) => handleSearch(e.target.value)} ref={inputRef} /> </div> <ul className="divide-y divide-dashed divide-text/20 overflow-y-auto p-1" aria-label={languageListLabel.value} > {searchResults.map( ({ locale: localeItem, currentLocaleName, ownLocaleName }) => ( <li className="py-1 pr-3" key={localeItem}> <Link label={switchTo({ locale: localeItem }).value} href={pathWithoutLocale} locale={localeItem} isActive={locale === localeItem} // Add aria-current="page" for accessibility variant="hoverable" color="text" replace // Will ensure that the "go back" browser button will redirect to the previous page onClick={() => setLocale(localeItem)} > <div className="flex flex-row items-center justify-between gap-3 px-2 py-1"> <div className="flex flex-col text-nowrap"> <span dir={getHTMLTextDir(localeItem)} lang={localeItem} > {ownLocaleName} </span> <span className="text-neutral text-xs"> {currentLocaleName} </span> </div> <span className="text-nowrap text-neutral text-sm"> {localeItem.toUpperCase()} </span> </div> </Link> </li> ) )} </ul> </Container> </DropDown.Panel> </DropDown> </div> ); };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aymericzip/intlayer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server