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

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

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

## git репозитарий
https://gogs.osvoj.ru/s5l.ru/borbad.s5l.ru/src/master/vue/app/shared/ImageSlider/

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

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

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

### 1. Простой слайдер с изображениями
```pug
imageslider(:slides="slides")
```

### 2. Слайдер с кастомными настройками
```pug
imageslider(
    :slides="featuredSlides"
    :autoplay="true"
    :interval="5000"
    :show-indicators="true"
    :show-controls="true"
)
```

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

### `slides` (обязательный)
- **Тип:** `Array`
- **Описание:** Массив объектов слайдов
- **Структура слайда:**
  ```coffee
  {
    _id: String
    type: 'slide'
    title: Array[String]        # Мультиязычные заголовки
    content: Array[String]      # Мультиязычный контент
    image: Array[String]        # Мультиязычные пути к изображениям
    slide_data: {
      order: Number
      active: Boolean
      button_text: Array[String]
      button_link: Array[String]
      button_style: String
      text_color: Array[String]
      text_position: Array[String]
      overlay: Array[Boolean]
      overlay_opacity: Array[Number]
    }
  }
  ```

### `autoplay` (опциональный)
- **Тип:** `Boolean`
- **По умолчанию:** `true`
- **Описание:** Автоматическая прокрутка слайдов

### `interval` (опциональный)
- **Тип:** `Number`
- **По умолчанию:** `4000`
- **Описание:** Интервал автоматической прокрутки в миллисекундах

### `showIndicators` (опциональный)
- **Тип:** `Boolean`
- **По умолчанию:** `true`
- **Описание:** Показывать индикаторы слайдов

### `showControls` (опциональный)
- **Тип:** `Boolean`
- **По умолчанию:** `true`
- **Описание:** Показывать кнопки управления (вперед/назад)

### `height` (опциональный)
- **Тип:** `String`
- **По умолчанию:** `'400px'`
- **Описание:** Высота слайдера (CSS значение)

### `transition` (опциональный)
- **Тип:** `String`
- **По умолчанию:** `'slide'`
- **Допустимые значения:** `'slide'`, `'fade'`
- **Описание:** Тип анимации перехода между слайдами

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

### `@slide-change`
- **Описание:** Событие смены слайда
- **Payload:** `{ currentSlide: Object, index: Number }`
- **Пример:**
  ```pug
  imageslider(:slides="slides" @slide-change="onSlideChange")
  ```

### `@slide-click`
- **Описание:** Событие клика по слайду
- **Payload:** `{ slide: Object, index: Number }`
- **Пример:**
  ```pug
  imageslider(:slides="slides" @slide-click="onSlideClick")
  ```

## Слоты (Slots)

### `[slide]` (кастомный контент слайда)
- **Описание:** Слот для кастомного отображения слайда
- **Props:** `{ slide: Object, index: Number, active: Boolean }`
- **Пример:**
  ```pug
  imageslider(:slides="slides")
      template([slide]="{ slide, index, active }")
          div(class="relative h-full flex items-center justify-center")
              img(:src="slide.image" :alt="slide.title" class="w-full h-full object-cover")
              div(v-if="active" class="absolute inset-0 bg-black bg-opacity-40 flex items-center justify-center")
                  h2(class="text-white text-4xl font-bold") {{ slide.title }}
  ```

### `[indicators]` (кастомные индикаторы)
- **Описание:** Слот для кастомных индикаторов
- **Props:** `{ slides: Array, currentIndex: Number, goToSlide: Function }`
- **Пример:**
  ```pug
  imageslider(:slides="slides")
      template([indicators]="{ slides, currentIndex, goToSlide }")
          div(class="flex space-x-2 absolute bottom-4 left-1/2 transform -translate-x-1/2")
              button(
                  v-for="(slide, index) in slides"
                  :key="slide._id"
                  @click="goToSlide(index)"
                  :class="currentIndex === index ? 'bg-white' : 'bg-white bg-opacity-50'"
                  class="w-3 h-3 rounded-full transition-all"
              )
  ```

### `[controls]` (кастомные кнопки управления)
- **Описание:** Слот для кастомных кнопок управления
- **Props:** `{ nextSlide: Function, prevSlide: Function }`
- **Пример:**
  ```pug
  imageslider(:slides="slides")
      template([controls]="{ nextSlide, prevSlide }")
          div(class="absolute inset-y-0 left-0 flex items-center")
              button(@click="prevSlide" class="ml-4 p-2 bg-black bg-opacity-50 text-white rounded-full")
                  icon(name="chevron-left")
          div(class="absolute inset-y-0 right-0 flex items-center")
              button(@click="nextSlide" class="mr-4 p-2 bg-black bg-opacity-50 text-white rounded-full")
                  icon(name="chevron-right")
  ```

## Методы компонента

### `nextSlide()`
- **Описание:** Переход к следующему слайду
- **Пример использования:**
  ```pug
  imageslider(ref="slider" :slides="slides")
  ```
  ```coffee
  @$refs.slider.nextSlide()
  ```

### `prevSlide()`
- **Описание:** Переход к предыдущему слайду
- **Пример использования:**
  ```coffee
  @$refs.slider.prevSlide()
  ```

### `goToSlide(index)`
- **Описание:** Переход к конкретному слайду по индексу
- **Параметры:** `index: Number`
- **Пример использования:**
  ```coffee
  @$refs.slider.goToSlide(2) # Переход к третьему слайду
  ```

### `play()`
- **Описание:** Запуск автоматической прокрутки
- **Пример использования:**
  ```coffee
  @$refs.slider.play()
  ```

### `pause()`
- **Описание:** Приостановка автоматической прокрутки
- **Пример использования:**
  ```coffee
  @$refs.slider.pause()
  ```

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

### 1. Главный слайдер на homepage
```pug
imageslider(
    :slides="_.appState.slides"
    :autoplay="true"
    :interval="5000"
    :height="'600px'"
    :show-indicators="true"
    :show-controls="true"
    @slide-change="trackSlideView"
    class="rounded-lg shadow-xl"
)
```

### 2. Слайдер мероприятий с кастомным контентом
```pug
imageslider(
    :slides="eventSlides"
    :autoplay="false"
    :show-indicators="false"
    class="event-slider"
)
    template([slide]="{ slide, index, active }")
        div(class="relative h-80 rounded-lg overflow-hidden shadow-lg")
            img(
                :src="getText(slide.image)" 
                :alt="getText(slide.title)"
                class="w-full h-full object-cover"
            )
            div(class="absolute inset-0 bg-gradient-to-t from-black via-transparent to-transparent flex items-end")
                div(class="p-6 text-white")
                    h3(class="text-xl font-bold mb-2") {{ getText(slide.title) }}
                    p(class="text-gray-200 mb-4") {{ getText(slide.content) }}
                    app-link(
                        :to="getText(slide.slide_data.button_link)"
                        class="inline-block bg-blue-600 text-white px-6 py-2 rounded-lg hover:bg-blue-700 transition-colors"
                    ) {{ getText(slide.slide_data.button_text) }}
```

### 3. Мини-слайдер товаров
```pug
imageslider(
    :slides="productSlides"
    :height="'300px'"
    :show-controls="false"
    :autoplay="true"
    :interval="3000"
    class="product-slider"
)
    template([indicators]="{ slides, currentIndex, goToSlide }")
        div(class="flex justify-center space-x-1 mt-4")
            button(
                v-for="(slide, index) in slides"
                :key="slide._id"
                @click="goToSlide(index)"
                :class="currentIndex === index ? 'w-8 bg-blue-600' : 'w-2 bg-gray-300'"
                class="h-2 rounded-full transition-all duration-300"
            )
```

### 4. Fullscreen слайдер галереи
```pug
imageslider(
    :slides="gallerySlides"
    :autoplay="false"
    :transition="'fade'"
    :height="'100vh'"
    class="gallery-slider"
)
    template([controls]="{ nextSlide, prevSlide }")
        div(class="absolute inset-0 flex items-center justify-between pointer-events-none")
            button(
                @click="prevSlide"
                class="pointer-events-auto ml-8 p-4 bg-black bg-opacity-50 text-white rounded-full hover:bg-opacity-70 transition-opacity"
            )
                icon(name="arrow-left" class="w-6 h-6")
            button(
                @click="nextSlide"
                class="pointer-events-auto mr-8 p-4 bg-black bg-opacity-50 text-white rounded-full hover:bg-opacity-70 transition-opacity"
            )
                icon(name="arrow-right" class="w-6 h-6")
```

### 5. Слайдер с текстовым оверлеем
```pug
imageslider(:slides="slidesWithOverlay")
    template([slide]="{ slide, active }")
        div(class="relative h-full")
            img(
                :src="getText(slide.image)"
                :alt="getText(slide.title)"
                class="w-full h-full object-cover"
            )
            div(
                v-if="slide.slide_data.overlay"
                :style="{
                    backgroundColor: 'rgba(0,0,0,' + (slide.slide_data.overlay_opacity || 0.4) + ')'
                }"
                class="absolute inset-0 flex items-center justify-center"
            )
                div(
                    :class="'text-' + (getText(slide.slide_data.text_position) || 'center')"
                    :style="{ color: getText(slide.slide_data.text_color) || '#ffffff' }"
                    class="max-w-2xl px-8"
                )
                    h2(class="text-4xl font-bold mb-4") {{ getText(slide.title) }}
                    p(class="text-xl mb-6") {{ getText(slide.content) }}
                    app-link(
                        v-if="getText(slide.slide_data.button_text)"
                        :to="getText(slide.slide_data.button_link)"
                        :class="getButtonStyle(slide.slide_data.button_style)"
                        class="inline-block px-8 py-3 rounded-lg font-semibold transition-colors"
                    ) {{ getText(slide.slide_data.button_text) }}
```

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

### Использование с MultilingualData
```pug
imageslider(:slides="multilingualSlides")
    template([slide]="{ slide }")
        div(class="relative h-full")
            img(
                :src="AppDB.multilingual.getText(slide.image)"
                :alt="AppDB.multilingual.getText(slide.title)"
                class="w-full h-full object-cover"
            )
            div(class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black to-transparent p-6")
                h3(class="text-white text-2xl font-bold mb-2") 
                    | {{ AppDB.multilingual.getText(slide.title) }}
                p(class="text-gray-200") 
                    | {{ AppDB.multilingual.getText(slide.content) }}
```

## Обработка событий

### Отслеживание просмотров слайдов
```coffee
methods:
    onSlideChange: (data) ->
        # data: { currentSlide: Object, index: Number }
        analytics.track('slide_view', {
            slide_id: data.currentSlide._id
            slide_index: data.index
            slide_title: AppDB.multilingual.getText(data.currentSlide.title)
        })
    
    onSlideClick: (data) ->
        # data: { slide: Object, index: Number }
        if data.slide.slide_data?.button_link
            EventBus.emit('slide_button_click', {
                slide: data.slide
                button_text: AppDB.multilingual.getText(data.slide.slide_data.button_text)
                button_link: AppDB.multilingual.getText(data.slide.slide_data.button_link)
            })
```

## Кастомизация стилей

### CSS переменные для кастомизации
```styl
.image-slider
    --slider-height: 400px
    --slider-transition-duration: 0.5s
    --indicator-size: 12px
    --indicator-active-color: #3B82F6
    --indicator-inactive-color: #9CA3AF
    --control-size: 48px
    --control-bg: rgba(0, 0, 0, 0.5)
    --control-color: #FFFFFF
```

### Кастомные темы
```styl
// Темная тема
.image-slider--dark
    --indicator-active-color: #60A5FA
    --indicator-inactive-color: #4B5563
    --control-bg: rgba(255, 255, 255, 0.1)
    --control-color: #F9FAFB

// Минималистичная тема
.image-slider--minimal
    --indicator-size: 8px
    --control-size: 40px
    --control-bg: transparent
    --control-color: #1F2937
    
    .image-slider__control
        border: 1px solid #E5E7EB
```

## Best Practices

### 1. Оптимизация изображений
```pug
imageslider(:slides="optimizedSlides")
    template([slide]="{ slide }")
        div(class="relative h-full")
            img(
                :src="getOptimizedImage(slide.image)"
                :alt="getText(slide.title)"
                loading="lazy"
                class="w-full h-full object-cover"
            )
```

### 2. Обработка ошибок загрузки
```pug
imageslider(:slides="slides")
    template([slide]="{ slide }")
        div(class="relative h-full")
            img(
                :src="getText(slide.image)"
                :alt="getText(slide.title)"
                @error="handleImageError"
                class="w-full h-full object-cover"
            )
```

### 3. Доступность (Accessibility)
```pug
imageslider(
    :slides="slides"
    aria-label="Галерея изображений"
    role="region"
)
```

### 4. Производительность
```pug
imageslider(
    :slides="lazyLoadedSlides"
    :autoplay="isVisible"
    @slide-change="preloadNextSlide"
)
```

## Отладка и разработка

### Логирование состояния
```coffee
# В родительском компоненте
mounted: ->
    EventBus.on 'slide_change', (data) ->
        debug.log "Слайд изменен: "+data.index
        
    EventBus.on 'slider_autoplay_status', (data) ->
        debug.log "Автопрокрутка: "+(data.playing ? 'включена' : 'выключена')
```

### Валидация данных слайдов
```coffee
computed:
    validatedSlides: ->
        return @slides.filter (slide) ->
            slide.image? and 
            slide.image.length > 0 and
            slide.slide_data?.active isnt false
```

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