@lumea-labs/locale
v0.1.1
Published
Locale & language selector UI — 3 selector variants (tabs / switch / dropdown), inline SVG round flags, zero external assets.
Readme
@lumea/locale
Tier 1 pure-UI locale and language selector for React. Three selector variants (tabs, switch, dropdown) with inline SVG round flags for the top 30 languages -- all adapter-driven with zero i18n framework, router, or external asset dependencies.
Quick start
import {
LocaleProvider,
LocaleBrowser,
type LocaleAdapter,
} from "@lumea/locale";
const adapter: LocaleAdapter = {
getLocale: async () => ({
current: "en",
options: [
{ code: "en", label: "English" },
{ code: "it", label: "Italiano", englishLabel: "Italian" },
{ code: "de", label: "Deutsch", englishLabel: "German" },
],
}),
setLocale: async (code) => {
// Persist the locale change (cookie, API call, URL rewrite, etc.)
console.log("Locale changed to:", code);
},
};
export default function SettingsPage() {
return (
<LocaleProvider adapter={adapter} initialLocale="en">
<LocaleBrowser variant="tabs" />
</LocaleProvider>
);
}Capabilities
Every adapter method is optional. The UI auto-hides controls when a capability is missing -- no broken buttons, no consumer-side guards.
| Capability | Adapter method | UI gated |
|--------------|----------------|-------------------------------------|
| canBrowse | getLocale | Auto-load locale options on mount |
| canChange | setLocale | Interactive selectors (tabs/switch/dropdown) |
When canChange is false, all selectors render in read-only mode
(current locale displayed, no interactive controls). When canBrowse
is false, the provider relies on initialLocale and initialOptions
props passed directly.
Selector variants
| Component | Best for |
|------------------------|---------------------------------|
| LocaleSelectTabs | Settings pages with 2-6 options |
| LocaleSelectSwitch | Binary locale toggles (EN/IT) |
| LocaleSelectDropdown | Nav bars, dense UIs, many locales |
Labels
All user-facing strings are overridable via the labels prop on
<LocaleProvider>. Spread defaultLocaleLabels and override what you need:
import { defaultLocaleLabels } from "@lumea/locale";
<LocaleProvider
adapter={adapter}
labels={{ ...defaultLocaleLabels, title: "Lingua" }}
>Flags
Inline SVG round flags for 30 locales. No external assets, no CDN, no CORS. Each flag is a simplified geometric SVG (2-4 shapes max).
SSR-safe
Pass initialLocale and initialOptions to avoid flash on server-rendered
pages. The adapter's getLocale call on mount confirms or updates the state.
