Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions content/docs/components/inputs/phone-input.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ export function PhoneField() {
| `side` | `"top" \| "bottom"` | No | Preferred menu side; flips when there is no room (default: `"bottom"`) |
| `searchPlaceholder` | `string` | No | Placeholder for the country search (default: `"Search countries..."`) |
| `emptyMessage` | `ReactNode` | No | Shown when the search matches nothing (default: `"No countries found."`) |
| `labels` | `Partial<PhoneInputLabels>` | No | Override the built-in English UI text (see below) |
| `displayLocale` | `string` | No | Locale for country names, e.g. `"fr"` (default: English names) |
| `maxHeight` | `number \| string` | No | Max height of the scrolling country list (default: `"15rem"`) |
| `label` | `string` | No | Accessible label for the input |
| `className` | `string` | No | Classes for the root wrapper |
Expand Down Expand Up @@ -256,6 +258,50 @@ Every part takes its own classes through `classNames`, merged after the defaults
/>
```

### Translated UI text

Pass `labels` to translate the country menu's text, and `displayLocale` to show
country names in another language. Names come from the browser's
[`Intl.DisplayNames`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames),
so their exact wording can vary slightly between browsers. Searching matches the
translated name, while `onValueChange` still reports the country's English `name`.
The `searchPlaceholder` and `emptyMessage` props still work, and win over `labels`
when both are set.

```tsx
"use client";

import { PhoneInput } from "@/components/ui/phone-input";

export default function App() {
return (
<PhoneInput
defaultCountry="FR"
displayLocale="fr"
label="Numéro de téléphone"
placeholder="Numéro de téléphone"
labels={{
trigger: "Choisir un pays",
searchPlaceholder: "Rechercher un pays…",
searchLabel: "Rechercher un pays",
clearSearch: "Effacer la recherche",
emptyMessage: "Aucun pays trouvé.",
listbox: "Choisir un pays",
}}
/>
);
}
```

| Key | Default | Used for |
| ------------------- | ----------------------- | ----------------------------- |
| `trigger` | `"Select country"` | Country trigger label |
| `searchPlaceholder` | `"Search countries..."` | Search field placeholder |
| `searchLabel` | `"Search countries"` | Search field accessible label |
| `clearSearch` | `"Clear search"` | Clear button accessible label |
| `emptyMessage` | `"No countries found."` | Shown when nothing matches |
| `listbox` | `"Select country"` | Country list accessible label |

## Keyboard support

The country menu follows the WAI-ARIA combobox pattern: focus stays in the search
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ export function LocaleSwitcher() {
| `searchable` | `boolean` | No | Show the search field (default: `true`) |
| `searchPlaceholder` | `string` | No | Search placeholder (default: `"Search languages..."`) |
| `emptyMessage` | `ReactNode` | No | Shown when the search matches nothing (default: `"No languages found."`) |
| `labels` | `Partial<LanguageSwitcherLabels>` | No | Override the built-in English UI text (see below) |
| `disabled` | `boolean` | No | Disable the trigger |
| `renderOption` | `(locale, state) => ReactNode` | No | Replace each option row's content; `state` has `selected`, `active`, `label`, `flag` |
| `classNames` | `LanguageSwitcherClassNames` | No | Per-part classes: `trigger`, `content`, `search`, `list`, `item`, `empty` |
Expand Down Expand Up @@ -267,6 +268,46 @@ The switcher is styled with shadcn theme tokens, so it follows your theme. Use
/>
```

### Translated UI text

The search placeholder, empty state and accessible labels default to English. Pass
`labels` to translate them — any key you leave out keeps its English default. The
`searchPlaceholder` and `emptyMessage` props still work, and win over `labels` when
both are set.

```tsx
"use client";

import { LanguageSwitcher } from "@/components/ui/language-switcher";

export default function App() {
return (
<LanguageSwitcher
locales={[{ code: "en" }, { code: "fr" }, { code: "es" }]}
defaultValue="fr"
label="native"
labels={{
searchPlaceholder: "Rechercher une langue…",
searchLabel: "Rechercher une langue",
clearSearch: "Effacer la recherche",
emptyMessage: "Aucune langue trouvée.",
listbox: "Choisir la langue",
current: (name) => `Langue actuelle : ${name}`,
}}
/>
);
}
```

| Key | Default | Used for |
| ------------------- | --------------------------------------- | ----------------------------- |
| `searchPlaceholder` | `"Search languages..."` | Search field placeholder |
| `searchLabel` | `"Search languages"` | Search field accessible label |
| `clearSearch` | `"Clear search"` | Clear button accessible label |
| `emptyMessage` | `"No languages found."` | Shown when nothing matches |
| `listbox` | `"Select language"` | Option list accessible label |
| `current` | `(name) => "Current language: " + name` | Trigger accessible label |

## Keyboard support

The popup follows the WAI-ARIA combobox pattern: focus stays in the search field,
Expand Down
35 changes: 35 additions & 0 deletions content/docs/components/navigation/navbar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ export function SiteNav() {
| `showFlags` | `boolean` | No | Show flags in language selector (default: `true`) |
| `maxHeight` | `number \| string` | No | Max height of the scrolling language menu (default: `"15rem"`) |
| `linkComponent` | `React.ElementType` | No | Component used for internal links (default: `"a"`) |
| `labels` | `Partial<NavBarLabels>` | No | Override the built-in English UI text (see below) |
| `classNames` | `NavBarClassNames` | No | Per-part class overrides (see below) |
| `className` | `string` | No | Additional CSS classes |

Expand Down Expand Up @@ -361,6 +362,40 @@ export default function App() {
}
```

### Translated UI text

The language menu, mobile menu button and GitHub link carry English accessible
labels by default. Pass `labels` to translate them — any key you leave out keeps
its English default.

```tsx
"use client";

import { NavBar } from "@/components/ui/navbar";

export default function App() {
return (
<NavBar
logo={<span className="font-bold">MyApp</span>}
locales={[{ code: "en" }, { code: "fr" }]}
defaultValue="fr"
labels={{
listbox: "Choisir la langue",
current: (name) => `Langue actuelle : ${name}`,
toggleMenu: "Ouvrir le menu",
}}
/>
);
}
```

| Key | Default | Used for |
| ------------ | --------------------------------------- | --------------------------------- |
| `listbox` | `"Select language"` | Language menu accessible label |
| `current` | `(name) => "Current language: " + name` | Language trigger accessible label |
| `toggleMenu` | `"Toggle menu"` | Mobile menu button label |
| `github` | `"GitHub"` | GitHub icon link label |

## Keyboard support

The language menu follows the WAI-ARIA listbox pattern. With no text field in the
Expand Down
Loading
Loading