# Localization



CxJS supports culture-specific number, currency, and date formatting based on `Intl` helpers provided by modern browsers. It also offers translation of standard widget messages to different languages.

## Example

```tsx
import { createModel } from "cx/data";
import { ContentResolver, Controller, Culture, LabelsTopLayout } from "cx/ui";
import { Calendar, LookupField, NumberField, enableTooltips } from "cx/widgets";

enableTooltips();

interface Option {
  id: string;
  text: string;
}

interface PageModel {
  number: number;
  date: string;
  culture: Option;
  cultures: Option[];
  currency: Option;
  currencies: Option[];
}

const m = createModel<PageModel>();


class PageController extends Controller {
  onInit() {
    this.store.set(m.number, 123456.78);
    this.store.set(m.date, new Date().toISOString());

    this.store.set(m.cultures, [
      { id: "en-us", text: "English (US)" },
      { id: "de-de", text: "German" },
      { id: "es-es", text: "Spanish" },
      { id: "fr-fr", text: "French" },
    ]);
    this.store.set(m.culture, { id: "en-us", text: "English (US)" });

    this.store.set(m.currencies, [
      { id: "USD", text: "USD" },
      { id: "EUR", text: "EUR" },
      { id: "GBP", text: "GBP" },
    ]);
    this.store.set(m.currency, { id: "USD", text: "USD" });
  }
}

export default (
  <div>
    <LabelsTopLayout columns={2} controller={PageController}>
      <LookupField
        value={m.culture.id}
        options={m.cultures}
        label="Culture"
        required
      />
      <LookupField
        value={m.currency.id}
        options={m.currencies}
        label="Currency"
        required
      />
    </LabelsTopLayout>
    <ContentResolver
      params={{ culture: m.culture.id, currency: m.currency.id }}
      onResolve={async ({ culture, currency }) => {
        //console.log(culture, currency);
        Culture.setCulture(culture);
        Culture.setDefaultCurrency(currency);

        switch (culture) {
          case "de-de":
            await import("cx/locale/de-de.js");
            break;
          case "es-es":
            await import("cx/locale/es-es.js");
            break;
          case "fr-fr":
            await import("cx/locale/fr-fr.js");
            break;
          default:
            await import("cx/locale/en-us.js");
            break;
        }

        return (
          <LabelsTopLayout columns={2} controller={PageController}>
            <NumberField value={m.number} label="Number" />
            <NumberField value={m.number} label="Currency" format="currency" />
            <Calendar value={m.date} label="Date" />
          </LabelsTopLayout>
        );
      }}
    />
  </div>
);

```

## Culture

```ts
import { Culture } from 'cx/ui';
```

The `Culture` object provides methods for selecting UI cultures used for formatting.

### Setting Culture

```tsx
import "cx/locale/de-de"; // Import locale data

Culture.setCulture("de-de");
```

Available locale packages include: `de-de`, `en-us`, `es-es`, `fr-fr`, `nl-nl`, `pt-pt`, `sr-latn-ba`.

### Culture Methods

| Method                               | Description                                         |
| ------------------------------------ | --------------------------------------------------- |
| `Culture.setCulture(code)`           | Sets the current culture for all formatting.        |
| `Culture.setNumberCulture(code)`     | Sets culture for number formatting only.            |
| `Culture.setDateTimeCulture(code)`   | Sets culture for date/time formatting only.         |
| `Culture.setDefaultCurrency(code)`   | Sets the default currency (e.g., `"EUR"`, `"USD"`). |
| `Culture.setDefaultTimezone(tz)`     | Sets the default timezone.                          |
| `Culture.setDefaultDateEncoding(fn)` | Sets function for encoding dates.                   |

### Dynamic Culture Loading

Use dynamic imports for code-splitting:

```tsx
async function loadCulture(culture: string) {
  switch (culture) {
    case "de-de":
      await import("cx/locale/de-de");
      break;
    case "fr-fr":
      await import("cx/locale/fr-fr");
      break;
    default:
      await import("cx/locale/en-us");
  }
  Culture.setCulture(culture);
  store.notify(); // Force re-render
}
```

## Localization

```ts
import { Localization } from 'cx/ui';
```

The `Localization` object provides methods for translating widget messages.

### Localization Methods

| Method                                         | Description                                     |
| ---------------------------------------------- | ----------------------------------------------- |
| `Localization.localize(culture, name, values)` | Override widget properties for a given culture. |
| `Localization.override(name, values)`          | Override widget properties for all cultures.    |
| `Localization.registerPrototype(name, type)`   | Register a component type for localization.     |

### Translating Widget Messages

```tsx
Localization.localize("de", "cx/widgets/TextField", {
  validationErrorText: "Ungültige Eingabe.",
  minLengthValidationErrorText: "Mindestens {0} Zeichen erforderlich.",
  maxLengthValidationErrorText: "Maximal {0} Zeichen erlaubt.",
});
```

### Overriding Defaults

Use `override` to change defaults for all cultures:

```tsx
Localization.override("cx/widgets/DateField", {
  format: "dd.MM.yyyy",
});
```