# 国际化 Provider

## 使用方法

把整个应用包起来，告诉里面的组件现在用哪种语言，顺便可以塞进更多翻译目录，或者针对某种语言改几个词。子树里的组件都按这份设置取文案。没有这个 provider 时，组件就用内置的英文。

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

`messages` 和 `overrides` 都是「语言标签 → 目录」的映射，目录里的键就是原版那套 `@astryx.*`。也就是说，整门语言的 JSON 和只想改几个键的小对象是同一个写法。两层按同一个键合并：`messages` 里的目录替换这门语言的内置文案，`overrides` 再稀疏地盖在上面。覆盖是按语言存的，所以运行时换语言会自动用上对的那一份。

`dir` 只决定 Astryx 组件读到的书写方向，不会去动 DOM 的 `dir` 属性。要自己给 `<html>` 或者外层元素设上 `dir`，并且两边写一样的值。`getLocaleDirection(locale)` 可以按语言标签算出这个值。

可以嵌套：内层的 provider 管住自己那一段子树。

## 建议

| Guidance | Practices |
| --- | --- |
| Do | 目标语言有整份目录时，把整份目录交给 `messages`，形状和原版的 locale JSON 一致。 |
| Do | 只有在原版还没出这门语言，或者你在试还没翻完的文案时，才自己写一份同形状的本地目录。 |
| Do | 用真的 BCP 47 标签，例如 `fr-FR`、`pt-BR`、`ar-SA`。带地区的标签会先退回它的基础语言，最后才退回英文。 |
| Do | 自己给 `<html>`（或外层元素）设 `dir`，provider 不会帮你设。用 `getLocaleDirection(locale)` 算出这个值，provider 和 DOM 两边写一样的。 |
| Don't | 不要把自定义目录强转成 `any`；`ProviderMessagesByLocale` 和 `ProviderOverrides` 就是给本地目录用的类型。 |

## 示例

常见的用法和不同的状态。

### InternationalizationProvider — Overrides

不提供整份语言目录，只替换少数几句 Astryx 文案。

```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>
```

## 属性

| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `locale` | `string` | — | 当前语言，用 BCP 47 标签，例如 `"en"`、`"pt"`、`"pt-BR"`、`"zh-Hans"`。带地区的标签会先退回它的基础语言，最后退回内置英文。必填。 |
| `messages` | `ProviderMessagesByLocale` | — | 「语言标签 → 目录」的映射，目录的键就是原版那套 `@astryx.*`。给了就替换这门语言的内置文案。内置的 `"en"` 和 `"zh-CN"` 一直都在，不用列进来。 |
| `overrides` | `ProviderOverrides` | — | 按语言存的稀疏覆盖，盖在 `messages` 那份目录上；没有目录时就盖在内置文案上。按语言分开存，运行时换语言会自动用上对的那一份。 |
| `dir` | `'ltr' \| 'rtl'` | 按 `locale` 推导 | 显式指定书写方向。不传就按语言标签推导。它只决定 Astryx 组件读到的方向，不会去设 DOM 的 `dir` 属性；`<html>` 或外层元素的 `dir` 要自己设，并且和这里保持一致。 |

## 插槽

| 插槽 | 说明 |
| --- | --- |
| `default` | 使用这份语言、目录和方向的子树。 |

## 其它导出

| 导出 | 类型 | 说明 |
| --- | --- | --- |
| `getLocaleDirection` | `(locale: string) => 'ltr' \| 'rtl'` | 按语言标签算书写方向。运行时支持 `Intl.Locale#getTextInfo` 就用它，否则查一张从右往左的语言表。解析不了的标签按 `'ltr'` 处理。 |
| `useLocaleDirection` | `() => ComputedRef<'ltr' \| 'rtl'>` | 读最近一层 provider 的方向；没有 provider 时按最近的 locale 推导。 |
| `ProviderMessagesByLocale` | `Record<string, AstryxUpstreamCatalog>` | `messages` 的类型。目录本身是 `Record<string, string \| { defaultMessage: string }>`，键是 `@astryx.*`。 |
| `ProviderOverrides` | `ProviderMessagesByLocale` | `overrides` 的类型。 |

## 原生属性

组件本身不渲染元素，<code>class</code> 和 <code>style</code> 不会传下去。
