# Компонент LanguageSwitcher - Полная документация

## Назначение компонента

`LanguageSwitcher` - компонент для переключения языков интерфейса в мультиязычном приложении. Интегрируется с глобальной системой мультиязычности, обеспечивает удобный интерфейс выбора языка и сохраняет предпочтения пользователя.

## Импорт и регистрация

```coffee
# В основном файле приложения (app/temp.coffee)
components:
    'language-switcher': require 'app/shared/LanguageSwitcher'
```

## Базовое использование

```pug
//- Минимальное использование
language-switcher

//- В навигационной панели
div(class="flex items-center space-x-4")
    language-switcher
    themetoggle
```

## Полный список props

### `size` (опциональный)
- **Тип:** `String`
- **По умолчанию:** `'md'`
- **Допустимые значения:** `'sm'`, `'md'`, `'lg'`
- **Описание:** Размер переключателя
- **Пример:**
  ```pug
  language-switcher(size="sm")
  language-switcher(size="lg")
  ```

### `variant` (опциональный)
- **Тип:** `String`
- **По умолчанию:** `'dropdown'`
- **Допустимые значения:** `'dropdown'`, `'buttons'`, `'select'`, `'flags'`
- **Описание:** Вариант отображения переключателя
- **Пример:**
  ```pug
  language-switcher(variant="buttons")
  language-switcher(variant="flags")
  ```

### `showNativeNames` (опциональный)
- **Тип:** `Boolean`
- **По умолчанию:** `true`
- **Описание:** Показывать названия на родном языке
- **Пример:**
  ```pug
  language-switcher(:showNativeNames="false")
  ```

### `showFlags` (опциональный)
- **Тип:** `Boolean`
- **По умолчанию:** `true`
- **Описание:** Показывать флаги (для соответствующих вариантов)
- **Пример:**
  ```pug
  language-switcher(:showFlags="false")
  ```

### `position` (опциональный)
- **Тип:** `String`
- **По умолчанию:** `'bottom-start'`
- **Допустимые значения:** `'top'`, `'top-start'`, `'top-end'`, `'bottom'`, `'bottom-start'`, `'bottom-end'`, `'left'`, `'right'`
- **Описание:** Позиция выпадающего списка
- **Пример:**
  ```pug
  language-switcher(position="bottom-end")
  ```

### `languages` (опциональный)
- **Тип:** `Array`
- **По умолчанию:** `[{ code: 'ru', name: 'Russian', native: 'Русский', flag: '🇷🇺' }, { code: 'en', name: 'English', native: 'English', flag: '🇺🇸' }, { code: 'tj', name: 'Tajik', native: 'Тоҷикӣ', flag: '🇹🇯' }]`
- **Описание:** Список доступных языков
- **Пример:**
  ```pug
  language-switcher(:languages="customLanguages")
  ```

### `storageKey` (опциональный)
- **Тип:** `String`
- **По умолчанию:** `'borbad-language'`
- **Описание:** Ключ для сохранения в localStorage
- **Пример:**
  ```pug
  language-switcher(storageKey="my-app-language")
  ```

### `autoClose` (опциональный)
- **Тип:** `Boolean`
- **По умолчанию:** `true`
- **Описание:** Автоматически закрывать после выбора
- **Пример:**
  ```pug
  language-switcher(:autoClose="false")
  ```

### `class` (опциональный)
- **Тип:** `String | Object | Array`
- **По умолчанию:** `''`
- **Описание:** Дополнительные CSS классы
- **Пример:**
  ```pug
  language-switcher(class="border border-gray-300 rounded-lg")
  ```

## События (Events)

### `@change`
- **Описание:** Событие смены языка
- **Payload:** `{ language: String, previousLanguage: String }`
- **Пример:**
  ```pug
  language-switcher(@change="handleLanguageChange")
  ```

### `@open`
- **Описание:** Событие открытия переключателя
- **Payload:** `None`
- **Пример:**
  ```pug
  language-switcher(@open="handleLanguageSwitcherOpen")
  ```

### `@close`
- **Описание:** Событие закрытия переключателя
- **Payload:** `None`
- **Пример:**
  ```pug
  language-switcher(@close="handleLanguageSwitcherClose")
  ```

## Слоты (Slots)

### `[button-content]`
- **Описание:** Кастомное содержимое кнопки переключателя
- **Пример:**
  ```pug
  language-switcher
      template([button-content])
          div(class="flex items-center space-x-2")
              icon(name="globe")
              span Язык
  ```

### `[language-option]`
- **Описание:** Кастомное отображение опции языка
- **Scope:** `{ language: Object, isActive: Boolean }`
- **Пример:**
  ```pug
  language-switcher
      template([language-option]="{ language, isActive }")
          div(class="flex items-center space-x-3 p-2")
              span(class="text-lg") {{ language.flag }}
              div(class="flex flex-col")
                  span(class="font-medium") {{ language.native }}
                  span(class="text-sm text-gray-500") {{ language.name }}
              span(
                  v-if="isActive"
                  class="text-green-500 ml-auto"
              ) ✓
  ```

### `[before-options]`
- **Описание:** Контент перед списком языков
- **Пример:**
  ```pug
  language-switcher
      template([before-options])
          div(class="p-3 border-b border-gray-200 dark:border-gray-700")
              h3(class="font-semibold") Выберите язык
  ```

### `[after-options]`
- **Описание:** Контент после списка языков
- **Пример:**
  ```pug
  language-switcher
      template([after-options])
          div(class="p-3 border-t border-gray-200 dark:border-gray-700")
              p(class="text-sm text-gray-500") Помогите с переводом
  ```

## Поддерживаемые языки по умолчанию

### Русский (`ru`)
- **Название:** Russian
- **Родное название:** Русский
- **Флаг:** 🇷🇺

### Английский (`en`)
- **Название:** English
- **Родное название:** English
- **Флаг:** 🇺🇸

### Таджикский (`tj`)
- **Название:** Tajik
- **Родное название:** Тоҷикӣ
- **Флаг:** 🇹🇯

## Примеры использования

### 1. Базовые варианты отображения
```pug
//- Выпадающий список (по умолчанию)
language-switcher

//- Кнопки
language-switcher(variant="buttons")

//- Select элемент
language-switcher(variant="select")

//- Флаги
language-switcher(variant="flags")

//- Разные размеры
div(class="flex space-x-2 items-center")
    language-switcher(size="sm")
    language-switcher(size="md")
    language-switcher(size="lg")
```

### 2. Кастомные языки
```pug
language-switcher(
    :languages="[
        { code: 'ru', name: 'Russian', native: 'Русский', flag: '🇷🇺' },
        { code: 'en', name: 'English', native: 'English', flag: '🇺🇸' },
        { code: 'de', name: 'German', native: 'Deutsch', flag: '🇩🇪' },
        { code: 'fr', name: 'French', native: 'Français', flag: '🇫🇷' }
    ]"
)
```

### 3. Интеграция с навигацией
```pug
header(class="bg-white dark:bg-gray-800 shadow-sm")
    div(class="container mx-auto px-4")
        div(class="flex justify-between items-center py-4")
            //- Логотип
            app-link(to="/" class="text-xl font-bold") Борбад
            
            //- Навигация с переключателями
            div(class="flex items-center space-x-4")
                nav(class="flex space-x-6")
                    app-link(to="/events") Мероприятия
                    app-link(to="/blog") Блог
                
                //- Переключатели
                language-switcher(
                    variant="flags"
                    size="sm"
                    :showNativeNames="false"
                )
                themetoggle(variant="icon-only")
```

### 4. В мобильном меню
```pug
div(class="mobile-menu bg-white dark:bg-gray-800 p-6")
    div(class="space-y-4")
        app-link(to="/" class="block py-2") Главная
        app-link(to="/events" class="block py-2") Мероприятия
        
        //- Переключатель языка
        div(class="pt-4 border-t dark:border-gray-700")
            language-switcher(
                variant="buttons"
                class="w-full"
            )
```

### 5. С кастомными слотами
```pug
language-switcher
    template([button-content])
        div(class="flex items-center space-x-2")
            icon(name="translate" class="w-4 h-4")
            span {{ _.currentLanguage.toUpperCase() }}
    
    template([before-options])
        div(class="p-3 bg-blue-50 dark:bg-blue-900")
            p(class="text-sm text-blue-700 dark:text-blue-300") Выберите язык интерфейса
    
    template([language-option]="{ language, isActive }")
        div(
            :class="[
                'flex items-center space-x-3 p-3 rounded-lg transition-colors',
                isActive ? 'bg-blue-100 dark:bg-blue-800' : 'hover:bg-gray-100 dark:hover:bg-gray-700'
            ]"
        )
            span(class="text-xl") {{ language.flag }}
            div(class="flex-1")
                div(class="font-medium") {{ language.native }}
                div(class="text-sm text-gray-500 dark:text-gray-400") {{ language.name }}
            icon(
                v-if="isActive"
                name="check"
                class="w-4 h-4 text-blue-600 dark:text-blue-400"
            )
```

### 6. С обработкой событий
```pug
language-switcher(
    @change="onLanguageChange"
    @open="onLanguageSwitcherOpen"
    @close="onLanguageSwitcherClose"
)

//- В methods компонента
methods:
    onLanguageChange: ({ language, previousLanguage }) ->
        debug.log "Язык изменен: "+previousLanguage+" -> "+language
        
        # Аналитика
        analytics.track('language_changed', {
            new_language: language,
            previous_language: previousLanguage
        })
        
        # Обновление мета-тегов
        @updateHtmlLang(language)
    
    onLanguageSwitcherOpen: ->
        debug.log "Переключатель языка открыт"
        analytics.track('language_switcher_opened')
    
    onLanguageSwitcherClose: ->
        debug.log "Переключатель языка закрыт"
```

## Программное взаимодействие

### Получение текущего языка
```coffee
# Через глобальный объект
currentLanguage = _.currentLanguage

# Через AppDB
currentLanguage = AppDB.multilingual.currentLanguage

# Через EventBus
EventBus.on 'language_changed', (language) ->
    debug.log "Текущий язык: "+language
```

### Установка языка программно
```coffee
# Через глобальный объект
_.changeLanguage('en')

# Через AppDB
AppDB.multilingual.setLanguage('tj')

# Через EventBus
EventBus.emit('set_language', 'ru')
```

### Подписка на изменения языка
```coffee
# В компоненте
beforeMount: ->
    EventBus.on 'language_changed', @handleLanguageChange

methods:
    handleLanguageChange: (language) ->
        # Перезагрузка данных на новом языке
        @loadDataForLanguage(language)
        
        # Обновление контента
        @updateContent()
```

## Методы API

### `setLanguage(languageCode)`
- **Описание:** Устанавливает указанный язык
- **Параметры:** `languageCode` - код языка ('ru', 'en', 'tj')
- **Пример:**
  ```coffee
  @$refs.languageSwitcher.setLanguage('en')
  ```

### `getCurrentLanguage()`
- **Описание:** Возвращает текущий активный язык
- **Возвращает:** `String`
- **Пример:**
  ```coffee
  currentLang = @$refs.languageSwitcher.getCurrentLanguage()
  ```

### `open()`
- **Описание:** Программно открывает переключатель
- **Пример:**
  ```coffee
  @$refs.languageSwitcher.open()
  ```

### `close()`
- **Описание:** Программно закрывает переключатель
- **Пример:**
  ```coffee
  @$refs.languageSwitcher.close()
  ```

### `getAvailableLanguages()`
- **Описание:** Возвращает список доступных языков
- **Возвращает:** `Array`
- **Пример:**
  ```coffee
  languages = @$refs.languageSwitcher.getAvailableLanguages()
  ```

## Интеграция с мультиязычной системой

### С AppDB
```coffee
# Компонент автоматически интегрируется с AppDB.multilingual
languageSwitcher.setLanguage('en')
# Эквивалентно:
AppDB.multilingual.setLanguage('en')
```

### С глобальным состоянием
```coffee
# Изменение языка через компонент обновляет глобальное состояние
_.changeLanguage('tj')
```

### С загрузкой данных
```coffee
methods:
    handleLanguageChange: (language) ->
        # Перезагрузка контента на новом языке
        promises = [
            AppDB.getBlogPosts({ language: language })
            AppDB.getEvents({ language: language })
            AppDB.getCategories({ language: language })
        ]
        
        await Promise.all(promises)
        EventBus.emit('content_updated')
```

## Стили и кастомизация

### CSS-классы компонента
```styl
.language-switcher
    // Основной контейнер
    &__container
        @apply relative inline-block
    
    // Кнопка переключателя
    &__button
        @apply flex items-center space-x-2 px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors
    
    // Выпадающий список
    &__dropdown
        @apply absolute z-50 mt-2 w-48 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 py-1
    
    // Опция языка
    &__option
        @apply flex items-center space-x-3 px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors cursor-pointer
        
        &--active
            @apply bg-blue-50 dark:bg-blue-900 text-blue-600 dark:text-blue-400
    
    // Вариант с кнопками
    &--buttons
        @apply flex space-x-1
        
        .language-switcher__button
            @apply rounded-none border-r-0
            
            &:first-child
                @apply rounded-l-lg
            
            &:last-child
                @apply rounded-r-lg border-r
    
    // Вариант с флагами
    &--flags
        .language-switcher__button
            @apply p-1
            
        .language-switcher__option
            @apply px-3 py-1
```

### Кастомные стили
```styl
// Переопределение стандартных стилей
.language-switcher--custom
    .language-switcher__button
        @apply bg-gradient-to-r from-purple-500 to-pink-500 text-white border-transparent
        
        &:hover
            @apply from-purple-600 to-pink-600
    
    .language-switcher__option
        &:hover
            @apply bg-gradient-to-r from-purple-50 to-pink-50 text-purple-700
        
        &--active
            @apply bg-gradient-to-r from-purple-100 to-pink-100 text-purple-800
```

### Темная тема
```styl
@media (prefers-color-scheme: dark)
    .language-switcher
        &__button
            @apply bg-gray-800 border-gray-600 text-gray-300
            
            &:hover
                @apply bg-gray-700
        
        &__dropdown
            @apply bg-gray-800 border-gray-700
        
        &__option
            @apply text-gray-300
            
            &:hover
                @apply bg-gray-700
            
            &--active
                @apply bg-blue-900 text-blue-400
```

## Особенности работы

### Определение языка по умолчанию
```coffee
# Приоритеты определения языка:
# 1. Сохраненный выбор пользователя (localStorage)
# 2. Язык браузера
# 3. Язык по умолчанию (ru)
```

### Синхронизация между вкладками
```coffee
# Слушает события storage для синхронизации
window.addEventListener('storage', (event) ->
    if event.key == @storageKey
        @setLanguage(event.newValue, false) # false - не сохранять снова
)
```

### Интеграция с SEO
```coffee
methods:
    updateHtmlLang: (language) ->
        # Обновление атрибута lang у html элемента
        document.documentElement.lang = language
        
        # Обновление hreflang meta-тегов
        @updateHreflangTags(language)
```

## Обработка ошибок

### Валидация языка
```coffee
# Проверка поддерживаемых языков
if !@availableLanguages.find((lang) -> lang.code == language)
    throw new Error("Неподдерживаемый язык: "+language)
```

### Fallback для localStorage
```coffee
try
    localStorage.setItem(@storageKey, language)
catch error
    # Используем cookie как fallback
    document.cookie = @storageKey+"="+language+"; path=/; max-age=31536000"
```

## Примеры интеграции

### 1. С аналитикой
```coffee
methods:
    handleLanguageChange: ({ language, previousLanguage }) ->
        # Отправка в аналитику
        gtag('event', 'language_change', {
            event_category: 'ui',
            event_label: language,
            value: 1
        })
```

### 2. С синхронизацией с сервером
```coffee
methods:
    handleLanguageChange: (language) ->
        # Сохранение на сервере (если пользователь авторизован)
        if @user
            await @api.saveUserPreferences({ language: language })
```

### 3. С динамической загрузкой переводов
```coffee
methods:
    handleLanguageChange: (language) ->
        # Загрузка файлов переводов
        try
            translations = await import('../locales/'+language+'.json')
            AppDB.multilingual.setTranslations(language, translations)
        catch error
            debug.log "Ошибка загрузки переводов: "+error
```

## Best Practices

### 1. Всегда предоставляйте понятные названия
```pug
//- Правильно - показываем родные названия
language-switcher(showNativeNames="true")

//- Неправильно - только коды
language-switcher(:showNativeNames="false")
```

### 2. Используйте флаги аккуратно
```pug
//- Флаги помогают визуальной идентификации
language-switcher(showFlags="true")

//- Но могут быть спорными для некоторых языков
```

### 3. Сохраняйте состояние пользователя
```pug
//- Автоматически сохраняет в localStorage
language-switcher
```

### 4. Обеспечивайте доступность
```pug
//- Правильные ARIA-атрибуты
language-switcher(aria-label="Переключение языка")
```

### 5. Тестируйте все варианты
```coffee
# В тестах
describe('LanguageSwitcher', ->
    it('should switch between languages', ->
        switcher.setLanguage('en')
        expect(switcher.getCurrentLanguage()).toBe('en')
        
        switcher.setLanguage('ru')
        expect(switcher.getCurrentLanguage()).toBe('ru')
    )
)
```

### 6. Учитывайте RTL языки
```coffee
methods:
    handleLanguageChange: (language) ->
        # Для RTL языков (арабский, иврит и т.д.)
        if @isRtlLanguage(language)
            document.documentElement.dir = 'rtl'
        else
            document.documentElement.dir = 'ltr'
```

Компонент LanguageSwitcher предоставляет полнофункциональное решение для управления языками в мультиязычном приложении с поддержкой доступности, сохранения состояния и интеграции с глобальной системой мультиязычности.
