# Localization

How the library takes the reader's locale, time zone and texts, and which texts each part has.

## The contract

The library has no translations, catalogs or keys. Text arrives already translated: through a
prop on an instance, or once per app through [Locale Provider](/components/locale-provider). Its
parts default to English, so an app without a provider renders exactly as before.

```tsx
import { LocaleProvider, type LocaleLabels } from "@zenoxai/ui/components/locale-provider"

function useUiLabels(): LocaleLabels {
  const { t, language } = useTranslation()
  return React.useMemo(
    () => ({
      common: {
        close: t("ui.actions.close"),
        tryAgain: t("ui.actions.tryAgain"),
        copied: t("ui.feedback.copied"),
        loading: t("ui.feedback.loading"),
      },
      dataTable: {
        empty: t("ui.table.empty"),
        resultCount: (total, format) =>
          t("ui.table.results", { count: format.number(total) }),
      },
    }),
    [t, language]
  )
}
```

The provider also carries the locale of every number the library formats, so "1 to 25 of
1.204" follows pt-BR before any word is translated.

## Precedence

A text comes from the first of these that has it:

1. The instance's prop: `closeLabel`, `labels`, `text`, an `aria-label`.
2. The part's group in the provider: `dialog.close`.
3. `common`, for the keys whose English default is the same text in every part: `close`,
   `tryAgain`, `copied`, `loading`.
4. The English default.

`common.loading` reaches the Spinner and the filter panel ("Loading"), not DataTable's
"Loading rows", which has its own key.

## Label functions

A text that holds a number or a name is a function. It gets the provider's formatters as its
last argument, the functions of [`lib/format`](/utilities/format) bound to the locale and the
time zone:

```tsx
dataTable: {
  pageRange: (from, to, total, format) =>
    `${format.number(from)} a ${format.number(to)} de ${format.number(total)}`,
}
```

Plurals come from the app's dictionary; `format.plural(count, { one, other })` picks the form by
the language's rules.

## Groups

A group exists in the `LocaleLabels` type once the app imports its part, so TypeScript checks
every key. Every key is optional.

| Group            | Part                                                                   | Keys                                                                                                                                                                                                                                                                                                                                                                        |
| ---------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `common`         | Several                                                                | `close`, `tryAgain`, `copied`, `loading`                                                                                                                                                                                                                                                                                                                                    |
| `dialog`         | [Dialog](/components/dialog)                                           | `close`                                                                                                                                                                                                                                                                                                                                                                     |
| `sheet`          | [Sheet](/components/sheet)                                             | `close`                                                                                                                                                                                                                                                                                                                                                                     |
| `command`        | [Command](/components/command) dialog                                  | `title`, `description`, `close`                                                                                                                                                                                                                                                                                                                                             |
| `pagination`     | [Pagination](/components/pagination)                                   | `previous`, `next`, `goToPrevious`, `goToNext`, `morePages`                                                                                                                                                                                                                                                                                                                 |
| `breadcrumb`     | [Breadcrumb](/components/breadcrumb)                                   | `more`                                                                                                                                                                                                                                                                                                                                                                      |
| `carousel`       | [Carousel](/components/carousel)                                       | `previous`, `next`                                                                                                                                                                                                                                                                                                                                                          |
| `sidebar`        | [Sidebar](/components/sidebar)                                         | `title`, `description`, `toggle`                                                                                                                                                                                                                                                                                                                                            |
| `combobox`       | [Combobox](/components/combobox)                                       | `showOptions`, `clear`, `remove`                                                                                                                                                                                                                                                                                                                                            |
| `numberInput`    | [Number Input](/components/number-input)                               | `decrease`, `increase`                                                                                                                                                                                                                                                                                                                                                      |
| `calendar`       | [Calendar](/components/calendar)                                       | `today`, `selected`; the navigation comes with `dateLocale`                                                                                                                                                                                                                                                                                                                 |
| `filterChip`     | [Filter Chip](/components/filter-chip)                                 | `remove()`                                                                                                                                                                                                                                                                                                                                                                  |
| `toaster`        | [Toaster](/components/sonner)                                          | `notifications`, `closeToast`                                                                                                                                                                                                                                                                                                                                               |
| `dataTable`      | [Data Table](/patterns/data-table), its column factories and cells     | `loading`, `empty`, `errorTitle`, `errorDescription`, `retry`, `refreshFailed`, `loadMoreFailed`, `loadMore`, `loadingMore`, `rowsPerPage`, `previousPage`, `nextPage`, `pageRange()`, `loadedCount()`, `loadedMore()`, `resultCount()`, `selectAll`, `selectPage`, `selectRow()`, `actions`, `columns`, `moreTags()`                                                       |
| `filterPanel`    | [Filter Panel](/patterns/filter-panel)                                 | `title`, `activeCount()`, `clear`, `reset`, `clearAll`, `resetAll`, `removeFilter()`, `removeValue()`, `selectedCount()`, `showMore()`, `showLess`, `search()`, `searchPlaceholder`, `noMatches`, `loading`, `countsFailed`, `retry`, `all`, `formatCount()`, `minimum`, `maximum`, `from`, `to`, `anyTime`, `anyDate`, `clearDate()`, `addValue`, `close`, `showResults()` |
| `filterValues`   | `useFilters`, the text of the chips                                    | `yes`, `no`, `more()`, `between()`, `atLeast()`, `atMost()`, `onOrAfter()`, `onOrBefore()`, `formatNumber()`, `formatDate()`                                                                                                                                                                                                                                                |
| `recordSheet`    | [Record Sheet](/patterns/record-sheet) header                          | `previous`, `next`, `copy`, `copyLink`, `copied`, `close`                                                                                                                                                                                                                                                                                                                   |
| `externalLink`   | [External Link](/patterns/external-link), Linkified Text               | `title`, `description()`, `copy`, `copied`, `open`, `close`, `newTab`                                                                                                                                                                                                                                                                                                       |
| `copyButton`     | [Copy Button](/patterns/copy-button), Value Actions                    | `copy`, `copied`, `pivot`                                                                                                                                                                                                                                                                                                                                                   |
| `codeBlock`      | [Code Block](/patterns/code-block)                                     | `name`                                                                                                                                                                                                                                                                                                                                                                      |
| `helpTooltip`    | [Help Tooltip](/patterns/help-tooltip)                                 | `moreInformation`                                                                                                                                                                                                                                                                                                                                                           |
| `emptyValue`     | [Empty Value](/patterns/empty-value), Stat Tile                        | `unknown`, `notApplicable`, `redacted`                                                                                                                                                                                                                                                                                                                                      |
| `listErrorState` | [List Error State](/patterns/list-error-state)                         | `title`, `description`, `retry`                                                                                                                                                                                                                                                                                                                                             |
| `severityBadge`  | [Severity Badge](/patterns/severity-badge)                             | `critical`, `high`, `medium`, `low`, `unknown`                                                                                                                                                                                                                                                                                                                              |
| `confirm`        | [Confirm Dialog](/patterns/confirm-dialog) host and `confirmDiscard()` | `confirm`, `cancel`, `discardTitle`, `discardDescription`, `discard`, `keepEditing`                                                                                                                                                                                                                                                                                         |

Keys with `()` are functions. The English default of every key is in the part's API reference.

## Without a provider

Every part shows its English default, and the parts that took the runtime's locale (Number
Input, Progress, Slider, the chart tooltip) still do. The `pagination` and `breadcrumb`
landmarks keep their English names in every language.

## Missing texts

In development, a part that falls back to English under a locale other than English logs one
warning per key and locale, naming the key to add: `LocaleProvider: no "dataTable.empty" label
for pt-BR`. A complete set of labels renders no English and no warning.
