# Internationalization Provider

## Usage

Wraps your app to set the active locale and (optionally) merge additional translation catalogs + per-locale overrides. Astryx components inside the subtree resolve their strings against this context. If no provider is present, components fall back to the shipped English defaults.

```ts
import { InternationalizationProvider } from '@astryx-vue/core/InternationalizationProvider'
```

`messages` and `overrides` are both a map from a BCP 47 tag to a catalog keyed by the original `@astryx.*` message keys, so the same JSON shape works for a whole language and for a handful of keys. The two layers merge per key: a catalog replaces the shipped text for that locale, and the sparse overrides are laid on top. Overrides are keyed by locale, so a runtime locale swap picks up the right set.

`dir` only sets the direction Astryx reads. It does not touch the DOM `dir` attribute: set that on `<html>` or a wrapping element yourself, and pass the same value to both. `getLocaleDirection(locale)` derives the value from a tag.

Nesting works: the inner provider wins for its subtree.

## Best practices

| Guidance | Practices |
| --- | --- |
| Do | Give `messages` a whole-language catalog for your target locale, in the same shape as the Astryx locale JSON. |
| Do | Use a same-shape local catalog only when Astryx has not shipped that locale yet or you are testing in-progress translations. |
| Do | Use real BCP 47 tags such as `fr-FR`, `pt-BR`, or `ar-SA`; regional locales fall back to their base language before English. |
| Do | Set the `dir` attribute on `<html>` (or a wrapping element) yourself; the provider does not set it. Use `getLocaleDirection(locale)` to derive the value for both the provider and the DOM. |
| Don't | Cast custom catalog maps to `any`; `ProviderMessagesByLocale` and `ProviderOverrides` type a local catalog. |

## Examples

Common configurations, variations, and states.

### InternationalizationProvider — Overrides

Override a small number of Astryx strings without providing a full locale catalog.

```vue
<script setup lang="ts">
import { InternationalizationProvider } from '@astryx-vue/core/InternationalizationProvider'
import { Selector } from '@astryx-vue/core/Selector'
import { ref } from 'vue'

const selected = ref<string | null>(null)

const options = [
  { value: 'americas', label: 'Americas' },
  { value: 'emea', label: 'EMEA' },
  { value: 'apac', label: 'APAC' },
]

// Only the Selector placeholder changes; every other string stays the built-in English.
const overrides = {
  en: {
    '@astryx.selector.placeholder': 'Choose...',
  },
}
</script>

<template>
  <div class="internationalization-provider-preview">
    <InternationalizationProvider locale="en" :overrides="overrides">
      <Selector
        v-model="selected"
        label="Billing region"
        :options="options"
        :width="240"
        has-clear
      />
    </InternationalizationProvider>
  </div>
</template>
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `locale` | `string` | — | BCP 47 language tag for the active locale (e.g. `"en"`, `"pt"`, `"pt-BR"`, `"zh-Hans"`). Regional tags fall back to their base language, then to the shipped `"en"` catalog. Required. |
| `messages` | `ProviderMessagesByLocale` | — | Map of BCP 47 tag to a catalog keyed by the original `@astryx.*` message keys. A catalog replaces the shipped text for that locale. The built-in `"en"` and `"zh-CN"` catalogs are always available and do not need to be listed. |
| `overrides` | `ProviderOverrides` | — | Sparse per-locale key overrides applied on top of the `messages` catalog, or on top of the built-in text when there is none. Overrides are locale-keyed so a runtime locale swap picks up the correct set. |
| `dir` | `'ltr' \| 'rtl'` | derived from `locale` | Explicit text direction for the context. When omitted, direction is derived from the locale. It sets the direction Astryx reads, but it does NOT set the DOM `dir` attribute; set that yourself on `<html>` or a wrapping element and keep the two in sync. |

## Slots

| Slot | Description |
| --- | --- |
| `default` | The subtree that reads this locale, catalog set, and direction. |

## Exports

| Export | Type | Description |
| --- | --- | --- |
| `getLocaleDirection` | `(locale: string) => 'ltr' \| 'rtl'` | Direction for a language tag. Uses `Intl.Locale#getTextInfo` when the runtime has it, otherwise a right-to-left language list. An unparseable tag reads as `'ltr'`. |
| `useLocaleDirection` | `() => ComputedRef<'ltr' \| 'rtl'>` | The direction of the nearest provider, or one derived from the nearest locale. |
| `ProviderMessagesByLocale` | `Record<string, AstryxUpstreamCatalog>` | Type of `messages`. The catalog value is a `Record<string, string \| { defaultMessage: string }>` keyed by `@astryx.*`. |
| `ProviderOverrides` | `ProviderMessagesByLocale` | Type of `overrides`. |

## Native attributes

The component renders no element of its own, so <code>class</code> and <code>style</code> are not forwarded.
