# LanguageSelector — Xertica UI

A dropdown component for switching the interface language. It reads the current language from `LanguageContext` and calls `i18n.changeLanguage()` when the user selects a new option — all `useTranslation()` consumers in the app re-render immediately, and the React Query cache is invalidated so data-layer strings refresh too.

---

## Import

```tsx
import { LanguageSelector } from 'xertica-ui/brand';
// or
import { LanguageSelector } from 'xertica-ui';
```

---

## Requirements

`LanguageSelector` calls `useLanguage()` internally and **must** be rendered inside `<LanguageProvider>`. This is satisfied automatically when using `<XerticaProvider>`, which includes `LanguageProvider`.

---

## Usage

### Basic (no props needed)

```tsx
// Language is read from LanguageContext automatically
<LanguageSelector />
```

### In the Header

```tsx
import { Header } from 'xertica-ui/layout';

<Header
  showLanguageSelector={true}
  {/* ...other props */}
/>
```

The `Header` component accepts `showLanguageSelector` and renders `<LanguageSelector />` in its actions area — no manual placement needed.

### Minimal variant (short code only)

```tsx
<LanguageSelector variant="minimal" showIcon={false} />;
{
  /* Trigger displays "PT", "EN", "ES" (or the LanguageDefinition.shortLabel of custom locales) */
}
```

---

## Props

| Prop                  | Type                     | Default     | Description                                                                               |
| --------------------- | ------------------------ | ----------- | ----------------------------------------------------------------------------------------- |
| `variant`             | `'default' \| 'minimal'` | `'default'` | `minimal` shows the short label (`PT`, `EN`, …); `default` shows the full label           |
| `showIcon`            | `boolean`                | `true`      | Show the Globe icon in the trigger                                                        |
| `showLabel`           | `boolean`                | `false`     | Reserved — currently has no visual effect                                                 |
| `className`           | `string`                 | `''`        | Additional CSS classes applied to the `SelectTrigger`                                     |
| `showWhenMonolingual` | `boolean`                | `false`     | Render the selector even when only one language is configured (would otherwise auto-hide) |

> **Removed props**: `initialLanguage` and `onLanguageChange` no longer exist. The component reads from `LanguageContext` and drives language changes through `i18n.changeLanguage()` internally.

---

## Supported Languages

By default the library ships with three languages (`DEFAULT_LANGUAGES`):

| Code      | Display        | Short label |
| --------- | -------------- | ----------- |
| `'pt-BR'` | Português (BR) | PT          |
| `'en'`    | English        | EN          |
| `'es'`    | Español        | ES          |

**The list is fully runtime-configurable.** Pass `availableLanguages` on `<XerticaProvider>` to add, remove, or restrict the set of languages exposed by the selector — no source-file edits required. See [`docs/i18n.md`](../i18n.md#configuring-available-languages) for the full API.

### Adding a custom language

```tsx
import { XerticaProvider, DEFAULT_LANGUAGES } from 'xertica-ui';
import fr from './locales/fr.json';

<XerticaProvider
  availableLanguages={[
    ...DEFAULT_LANGUAGES,
    { code: 'fr', label: 'Français', shortLabel: 'FR', resources: fr },
  ]}
>
  <LanguageSelector />
  {/* French appears in the dropdown; bundle auto-registered with i18next */}
</XerticaProvider>;
```

### Monolingual app — selector auto-hides

```tsx
<XerticaProvider availableLanguages={[{ code: 'en', label: 'English' }]}>
  <LanguageSelector />
  {/* Renders nothing — there is nothing to switch to */}
</XerticaProvider>
```

To force the selector to render anyway (e.g. as a future-proof placeholder):

```tsx
<LanguageSelector showWhenMonolingual />
```

---

## Behavior

- Reads `language`, `availableLanguages`, and `isMonolingual` from `useLanguage()`
- On selection: calls `setLanguage(lang)` which:
  1. Updates `LanguageContext` state
  2. Writes the new code to `localStorage` (key: `xertica_language`)
  3. Calls `i18n.changeLanguage(lang)` — all `useTranslation()` consumers re-render
  4. Invalidates the React Query cache — mock/API responses translated via `i18n.t()` are refetched in the new language
- **Auto-hides** when `isMonolingual === true` (single-language apps). Pass `showWhenMonolingual` to override.
- The `aria-label` and label text are themselves translated via `useTranslation()` — they change with the active language. Custom language codes fall back to the `label` passed in their `LanguageDefinition`.
- `variant="minimal"` uses `LanguageDefinition.shortLabel` when present, else `code.slice(0, 2).toUpperCase()`.

---

## Placement Guidelines

- **Header actions** — right side, adjacent to `ThemeToggle` and the user avatar (use `Header showLanguageSelector`)
- **Sidebar footer** — when persistent language switching is needed outside the header
- **Login / onboarding screens** — standalone usage before the main layout is mounted

---

## Manual Language Control

If you need to change the language programmatically (e.g., from user profile settings) without rendering `LanguageSelector`:

```tsx
import { useLanguage } from 'xertica-ui/hooks';

function ProfileSettings() {
  const { language, setLanguage, availableLanguages } = useLanguage();

  // Fully data-driven — works with any number of languages
  return (
    <select value={language} onChange={e => setLanguage(e.target.value)}>
      {availableLanguages.map(lang => (
        <option key={lang.code} value={lang.code}>
          {lang.label}
        </option>
      ))}
    </select>
  );
}
```

> Avoid hardcoding the `<option>` list — using `availableLanguages` keeps your settings UI in sync with whatever the consumer configured on `<XerticaProvider>`.

---

## AI Rules

> [!IMPORTANT]
>
> - **`<LanguageProvider>` is required**: `LanguageSelector` uses `useLanguage()` — it will throw if rendered outside a `LanguageProvider`. `<XerticaProvider>` includes this automatically.
> - **Do NOT pass `onLanguageChange` or `initialLanguage`** — these props no longer exist. Language state lives in `LanguageContext`; use `useLanguage()` to read or change it.
> - **Do NOT conditionally render this component** for monolingual apps — it self-hides via `isMonolingual`. Only use `showWhenMonolingual` if you explicitly need it visible.
> - **One per layout shell**: Avoid rendering multiple `LanguageSelector` instances — they all share the same context and the UI does not need duplication.
> - **Use `Header showLanguageSelector`** in page shells instead of placing `<LanguageSelector>` manually — it handles positioning and responsive visibility.
> - **`i18next` must be initialized**: `import './i18n'` must appear in `main.tsx` before any component renders; otherwise `useTranslation()` inside `LanguageSelector` will return raw keys.
> - **To support a new language**, pass it via `availableLanguages` on `<XerticaProvider>` — do not modify `LanguageSelector.tsx` or `LanguageContext.tsx`.
> - **In settings/profile pages**, use `availableLanguages` from `useLanguage()` to build the language picker — never hardcode the `<option>` list.
