Hikari i18n System

Overview

The Hikari i18n system provides internationalization support for Hikari UI applications. It uses TOML files for language definitions and integrates seamlessly with Tairitsu components.

Features

Supported Languages

LanguageCodeEnum VariantDirection
Englishen-USLanguage::EnglishLTR
Simplified Chinesezh-CHSLanguage::ChineseSimplifiedLTR
Traditional Chinesezh-CHTLanguage::ChineseTraditionalLTR
Frenchfr-FRLanguage::FrenchLTR
Russianru-RULanguage::RussianLTR
Spanishes-ESLanguage::SpanishLTR
Arabicar-SALanguage::ArabicRTL
Japaneseja-JPLanguage::JapaneseLTR
Koreanko-KRLanguage::KoreanLTR

Quick Start

1. Define TOML Content

Create TOML files for each language:

toml
1
2
3
4
5
6
7
8
# en-US.toml
[common.button]
submit = "Submit"
cancel = "Cancel"

[common.navigation]
home = "Home"
about = "About"
toml
1
2
3
4
5
6
7
8
# ar-SA.toml (RTL language)
[common.button]
submit = "إرسال"
cancel = "إلغاء"

[common.navigation]
home = "الرئيسية"
about = "حول"

2. Wrap App with I18nProvider

rust
1
2
3
4
5
6
7
8
9
10
11
use tairitsu_web::i18n::{I18nProvider, context::Language};

fn App() -> Element {
    rsx! {
        I18nProvider {
            language: Language::English,
            toml_content: EN_US_TOML,
            YourApp {}
        }
    }
}

3. Use i18n in Components

rust
1
2
3
4
5
6
7
8
9
10
use tairitsu_web::i18n::use_i18n;

fn MyComponent() -> Element {
    let i18n = use_i18n();

    rsx! {
        button { "{i18n.keys.common.button.submit}" }
        a { href: "/about", "{i18n.keys.common.navigation.about}" }
    }
}

Language Switcher

The LanguageSwitcher component provides a ready-to-use UI for switching languages:

rust
1
2
3
4
5
6
7
8
9
10
11
12
use tairitsu_web::i18n::{LanguageSwitcher, context::Language};

fn App() -> Element {
    let mut language = use_signal(|| Language::English);

    rsx! {
        LanguageSwitcher {
            current_language: language(),
            on_language_change: move |lang| language.set(lang),
        }
    }
}

RTL (Right-to-Left) Support

Hikari provides full RTL support for languages like Arabic:

Automatic Direction Detection

The I18nProvider automatically sets the dir attribute based on the language:

rust
1
2
3
4
5
6
7
8
9
fn App() -> Element {
    rsx! {
        I18nProvider {
            language: Language::Arabic,  // Automatically sets dir="rtl"
            toml_content: AR_SA_TOML,
            YourApp {}
        }
    }
}

ThemeProvider with Direction

The ThemeProvider also supports direction configuration:

rust
1
2
3
4
5
6
7
8
9
10
11
12
use theme::ThemeProvider;

fn App() -> Element {
    rsx! {
        ThemeProvider {
            initial_palette: "hikari",
            language: "ar-SA",
            direction: "rtl",
            YourApp {}
        }
    }
}

Layout Components and RTL

All layout components automatically adapt to RTL:

rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use hikari_components::layout::{FlexBox, Direction, Aside};

fn MyLayout() -> Element {
    rsx! {
        // Row direction is automatically reversed in RTL
        FlexBox {
            direction: Direction::Row,
            // In RTL: becomes row-reverse
        }

        // Sidebar position is automatically adjusted
        Aside {
            // In RTL: slides from right instead of left
        }
    }
}

Manual RTL Override

You can override RTL behavior per component:

rust
1
2
3
4
FlexBox {
    direction: Direction::Row,
    rtl: false,  // Force LTR regardless of theme direction
}

CSS Logical Properties

Use CSS logical properties for RTL-compatible styles:

css
1
2
3
4
5
6
7
/* Instead of: */
margin-left: 10px;
text-align: left;

/* Use: */
margin-inline-start: 10px;
text-align: start;

Language Utilities

Check if Language is RTL

rust
1
2
3
4
5
6
use tairitsu_web::i18n::context::Language;

let lang = Language::Arabic;
if lang.is_rtl() {
    // Apply RTL-specific logic
}

Get Language Direction

rust
1
2
let direction = Language::Arabic.direction();
// Returns TextDirection::Rtl

Get Language Native Name

rust
1
2
let name = Language::Japanese.native_name();
// Returns "日本語"

Dynamic Language Loading

To load different languages dynamically:

rust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
fn App() -> Element {
    let mut language = use_signal(|| Language::English);

    let toml_content = match language() {
        Language::English => EN_US_TOML,
        Language::ChineseSimplified => ZH_CHS_TOML,
        Language::ChineseTraditional => ZH_CHT_TOML,
        Language::French => FR_FR_TOML,
        Language::Russian => RU_RU_TOML,
        Language::Spanish => ES_ES_TOML,
        Language::Arabic => AR_SA_TOML,
        Language::Japanese => JA_JP_TOML,
        Language::Korean => KO_KR_TOML,
    };

    rsx! {
        I18nProvider {
            language: language(),
            toml_content,
            YourApp {}
        }
    }
}

Complete Example

See /examples/website/src/components/i18n_demo.rs for a complete working example.

API Reference

Components

Hooks

Types

Theme Types

Architecture

text
1
2
3
4
5
6
7
8
9
10
11
12
13
14
I18nProvider (root)
    ↓
use_context_provider
    ↓
I18nContext (accessible via use_i18n)
    ├── language: Language
    ├── keys: I18nKeys
    └── automatic dir="rtl" for RTL languages
    ↓
ThemeProvider
    └── direction: LayoutDirection
        ↓
    Layout Components
        └── Automatic RTL adaptation

Best Practices

  1. 1
    Keep TOML files organized - Use nested structures for related keys
  2. 2
    Use descriptive key names - e.g., common.button.submit instead of btn1
  3. 3
    Provide all translations - Ensure all keys exist in all language files
  4. 4
    Test language switching - Verify all components update correctly
  5. 5
    Test RTL layouts - Verify Arabic layout renders correctly
  6. 6
    Use logical CSS properties - Prefer margin-inline-start over margin-left

Future Enhancements