# `PhoenixKitWeb.Components.LanguageSwitcher`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.164/lib/phoenix_kit_web/components/language_switcher.ex#L1)

Shared language switcher component for PhoenixKit.

A configurable row of language options that works across all contexts:
admin form tabs, publishing editors, public page navigation, etc.

## Display modes

- `:auto` (default) — shows full names when ≤ `auto_threshold` languages,
  short codes when more
- `:full` — always show full names (e.g., "English", "French")
- `:compact` — always show short codes (e.g., "EN", "FR")

## Visual variants

- `:inline` (default) — pipe-separated items: `EN | FR | ES`
- `:tabs` — pill-shaped buttons on a rounded background bar
- `:pills` — individual pill-shaped chips, each with its own background

## Interaction modes

- **Button** — set `on_click` (event name) or `on_click_js` (fn returning `%JS{}`)
- **Link** — each language map has a `:url` key, renders `<.link navigate={url}>`
- **Display-only** — no click handler and no URL, renders a `<span>`

## Status dots

When `show_status` is true, a colored dot appears before each language code.
The dot color is resolved in priority order:

1. `dot_color` — explicit daisyUI color class (e.g., `"success"`, `"warning"`)
2. `status` — mapped automatically: `"published"` → green, `"draft"` → yellow,
   `"archived"` → gray
3. `exists` — `true` → green dot, `false` → dim dot

This makes the dots work for any use case: publishing post status, form content
indicators ("has translations"), or custom per-module states.

## Examples

    <%!-- Admin form: tabs with primary star, skeleton switching --%>
    <.language_switcher
      languages={@language_tabs}
      current_language={@current_lang}
      on_click_js={&switch_lang_js(&1, @current_lang)}
      show_primary={true}
      primary_divider={true}
      variant={:tabs}
    />

    <%!-- Publishing editor: compact codes with status dots --%>
    <.language_switcher
      languages={@editor_languages}
      current_language={@current_language}
      on_click_js={&switch_lang_js(&1, @current_language)}
      show_status={true}
      show_add={true}
      primary_divider={true}
    />

    <%!-- Public page: navigation links, no dots --%>
    <.language_switcher
      languages={@translations}
      current_language={@current_language}
    />

    <%!-- Post overview: pills with status dots and "Primary" label --%>
    <.language_switcher
      languages={@post_languages}
      current_language={@current_language}
      show_status={true}
      show_primary_label={true}
      variant={:pills}
      prefix_urls={true}
    />

    <%!-- Form with content indicators --%>
    <.language_switcher
      languages={Enum.map(@language_tabs, &Map.put(&1, :exists, has_content?(&1.code)))}
      current_language={@current_lang}
      on_click_js={&switch_lang_js(&1, @current_lang)}
      show_status={true}
      variant={:tabs}
    />

# `language_switcher`

Renders a language switcher.

## Language map structure

Each item in `:languages` should be a map with:

- `code` (required) — language code (e.g., "en-US", "fr")
- `name` — full display name (e.g., "English"). Falls back to uppercased code.
- `short_code` — short display code (e.g., "EN"). Auto-derived from code if absent.
- `flag` — flag emoji (e.g., "🇺🇸")
- `url` — navigation URL (enables link mode)
- `is_primary` — boolean, marks the primary language
- `status` — "published", "draft", "archived", or nil (for dot color)
- `exists` — boolean, whether content exists (inferred from status if absent)
- `dot_color` — explicit daisyUI color class override. Valid values:
  `"success"`, `"warning"`, `"error"`, `"info"`, `"primary"`, `"secondary"`,
  `"accent"`, `"neutral"`, `"base-content/20"`, `"base-content/40"`.
  Invalid values are silently ignored (falls back to status/exists color).
- `enabled` — boolean, whether this language is enabled in the system (default: true)
- `known` — boolean, whether this language code is recognized (default: true)
- `uuid` — optional ID, forwarded as `phx-value-uuid` in button mode

## Attributes

- `languages` — list of language maps (required)
- `current_language` — currently active language code
- `display` — `:auto`, `:full`, or `:compact`. Default: `:auto`
- `auto_threshold` — show full names when language count ≤ this. Default: 3
- `show_status` — show status indicator dots. Default: false
- `show_flags` — show flag emojis. Default: false
- `show_primary` — show star icon on primary language. Default: false
- `show_primary_label` — show "Primary" text label on primary language. Default: false
- `show_add` — style missing languages as addable (green). Default: false
- `exclude_primary` — exclude the primary language from the list. Default: false
- `primary_divider` — show a vertical divider after the primary language. Default: false
- `on_click` — event name for button click. Default: nil
- `on_click_js` — `fn(lang_code) -> %JS{}` for custom click. Default: nil
- `phx_target` — target for phx-click. Default: nil
- `variant` — `:inline`, `:tabs`, or `:pills`. Default: `:inline`
- `size` — `:xs`, `:sm`, or `:md`. Default: `:sm`
- `prefix_urls` — when true, URLs in language maps are passed through
  `PhoenixKit.Utils.Routes.path/1` for prefix-aware routing. Default: false
- `id` — optional HTML id for the container element. Default: nil
- `class` — additional CSS classes. Default: ""

## Notes

- `auto_threshold` is evaluated against the *displayed* language count
  (after filtering and `exclude_primary`), so excluding the primary
  language may change the display mode.
- `on_click_js` must be a pure function returning `%Phoenix.LiveView.JS{}`
  — it is called during render.

## Attributes

* `languages` (`:list`) (required)
* `current_language` (`:string`) - Defaults to `nil`.
* `display` (`:atom`) - Defaults to `:auto`. Must be one of `:auto`, `:full`, or `:compact`.
* `auto_threshold` (`:integer`) - Defaults to `3`.
* `show_status` (`:boolean`) - Defaults to `false`.
* `show_flags` (`:boolean`) - Defaults to `false`.
* `show_primary` (`:boolean`) - Defaults to `false`.
* `show_primary_label` (`:boolean`) - Defaults to `false`.
* `show_add` (`:boolean`) - Defaults to `false`.
* `exclude_primary` (`:boolean`) - Defaults to `false`.
* `primary_divider` (`:boolean`) - Defaults to `false`.
* `on_click` (`:string`) - Defaults to `nil`.
* `on_click_js` (`:any`) - Defaults to `nil`.
* `phx_target` (`:any`) - Defaults to `nil`.
* `variant` (`:atom`) - Defaults to `:inline`. Must be one of `:inline`, `:tabs`, or `:pills`.
* `size` (`:atom`) - Defaults to `:sm`. Must be one of `:xs`, `:sm`, or `:md`.
* `prefix_urls` (`:boolean`) - Defaults to `false`.
* `id` (`:string`) - Defaults to `nil`.
* `class` (`:string`) - Defaults to `""`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
