# Введиние

<figure><img src="https://pipui.ru/Themes/Default/img/logo.svg" alt="Logo not loaded"><figcaption><p>Логотип PipUI</p></figcaption></figure>

**PipUI** является кроссбраузерным фреймворком веб-интерфейсов для их быстрой и адаптивной верстки. Распространяется свободно под лицензией [MIT](https://en.wikipedia.org/wiki/MIT_License).

На сегодняшний день **PipUI** предлагает широкий набор компонентов:

1. Базовый набор
2. Стили отступов
3. Цветовые наборы
4. Стили Grid сетки
5. Панель навигации
6. Выпадающее меню
7. Постраничная навигация
8. Формы и компоненты форм
9. Кнопки
10. Полосы прогресса
11. Меню навигации
12. Модальные окна
13. Оповещения
14. Подтверждения действий
15. Вкладки
16. Хлебные крошки
17. Спойлеры
18. Таблицы
19. Панели ББ-кодов
20. ББ-коды
21. Валидаторы форм
22. Индексы полей ввода
23. Всплывающие подсказки
24. Подсвечивающиеся блоки
25. Всплывающие блоки
26. Слайдеры
27. Автозаполнения
28. Селекторы тегов
29. Блоки оповещений
30. Селекторы дат и времени
31. Якоря


# Скачать

[Скачать последнюю версию](https://github.com/pipui/pipui/releases/download/v1.6.0a/PipUI.v1.6.0.compressed.zip)&#x20;

[Скачать исходный код](https://github.com/pipui/pipui/archive/refs/tags/v1.6.0a.zip)&#x20;

Все релизы вы можете найти в нашем CDN [https://cdn.pipui.ru](https://cdn.pipui.ru/)


# Начало работы

Начиная с PipUI версии 2, фреймворк больше не использует зависимости от jQuery и jQuery Easing. В качестве иконок мы по прежнему используем [Font Awesome](https://fontawesome.com/v6/search), который является не обязательной библиотекой.

Для использования фреймворка, его необходимо подключить в HTML код на странице между тегами \<head>

{% code title="PipUI CDN" %}

```html
<link rel="stylesheet" href="https://cdn.pipui.ru/latest/dist/css/bundles/pipui.min.css" />
<link rel="stylesheet" href="https://cdn.pipui.ru/latest/dist/css/bundles/pipui-responsive.min.css" />
<script src="https://cdn.pipui.ru/latest/dist/js/bundles/pipui.min.js"></script>
```

{% endcode %}


# Базовый набор

Набор скриптов и стилей отвечающих за работу основных функций фреймворка и его компонентов

Одним из важнейших элементов в стилизации выступает класс <mark style="color:orange;">`.container`</mark>, который служит контейнером для адаптивной верстки. Именно с него и стоит начинать свою верстку страницы.

## Брейкпоинты <a href="#breakpoints" id="breakpoints"></a>

Точки изменения адаптивной верстки представлены ниже

{% code title="Responsive breakpoints" lineNumbers="true" %}

```css
@media (min-width: 320px) { ... }
@media (min-width: 480px) { ... }
@media (min-width: 768px) { ... }
@media (min-width: 900px) { ... }
@media (min-width: 1200px) { ... }
@media (min-width: 1400px) { ... }
```

{% endcode %}

## Работа с текстом <a href="#text" id="text"></a>

<mark style="color:orange;">`.text-center`</mark> - Выравнивание текста по центру

<mark style="color:orange;">`.text-left`</mark> - Выравнивание текста по левому краю

<mark style="color:orange;">`.text-right`</mark> - Выравнивание текста по правому краю

<mark style="color:orange;">`.text-justify`</mark> - Выравнивание текста по обеим краям

<mark style="color:orange;">`.text-upper`</mark> - Переведет шрифт в верхний регистр

<mark style="color:orange;">`.text-lower`</mark> - Переведет шрифт в нижний регистр

<mark style="color:orange;">`.text-capitalize`</mark> - Переводит первую букву каждого слова в верхний регистр

<mark style="color:orange;">`.text-bold`</mark> - Жирное начертание шрифта

<mark style="color:orange;">`.text-italic`</mark> - Наклонный текст

<mark style="color:orange;">`.text-overflow`</mark> - Сокращенный текст. Текст будет сокращен до максимальной ширины блока, а вконце предложения будет добавлено троеточие.

<mark style="color:orange;">`.text-strike`</mark> - Зачёркнутый текст

<mark style="color:orange;">`.text-underline`</mark> - Подчеркнутый текст

<mark style="color:orange;">`.text-overline`</mark> - Линия над текстом

{% embed url="<https://codepen.io/pipui/pen/jOpwPJE>" %}

## Управление свойством display <a href="#display" id="display"></a>

Поддерживаемые стили display: <mark style="color:orange;">`.d-none`</mark> <mark style="color:orange;">`.d-block`</mark> <mark style="color:orange;">`.d-inline`</mark> <mark style="color:orange;">`.d-inline-block`</mark> <mark style="color:orange;">`.d-grid`</mark> <mark style="color:orange;">`.d-inline-grid`</mark> <mark style="color:orange;">`.d-flex`</mark> <mark style="color:orange;">`.d-inline-flex`</mark>

## Полоса прокрутки <a href="#overflow" id="overflow"></a>

Управление полосой прокрутки с помощью заготовленных классов

<mark style="color:orange;">`.of-hidden`</mark> - перекрывающее содержимое будет скрыто без видимой полосы прокрутки

<mark style="color:orange;">`.of-visible`</mark> - всегда отображать полосу прокрутки и содержимое за пределами блока

<mark style="color:orange;">`.of-auto`</mark> - полоса прокрутки отображается по необходимости, если содержимое выходит за пределы блока

<mark style="color:orange;">`.of-auto`</mark> - полоса прокрутки отображается всегда

Все заготовленные классы выше, можно использовать с префиксами .of-x- и .of-y- для полос прокрутки по осям X и Y соответственно, например .of-x-auto

## Курсоры <a href="#cursor" id="cursor"></a>

PipUI дает возможность менять курсор элемента используя заготовленные классы.

Ниже представлены примеры работы таких классов и их список

<mark style="color:orange;">`.cursor-none .cursor-auto .cursor-default .cursor-pointer .cursor-progress .cursor-help .cursor-move .cursor-text .cursor-cell .cursor-crosshair .cursor-alias .cursor-vertical-text .cursor-no-drop .cursor-copy .cursor-all-scroll .cursor-col-resize .cursor-row-resize .cursor-nesw-resize .cursor-nwse-resize .cursor-n-resize .cursor-e-resize .cursor-nw-resize .cursor-grab .cursor-grabbing .cursor-zoom-in .cursor-zoom-out`</mark>

{% embed url="<https://codepen.io/pipui/pen/gOdLyqP>" %}
Пример работы курсоров
{% endembed %}

## Вертикальное выравнивание <a href="#vertical-alignment" id="vertical-alignment"></a>

Вертикальное выравнивание позволяет изменить положение элементов по вертикали

<mark style="color:orange;">`.v-align-top`</mark> - выравнивает **inline** элемент в блоке по верхнему краю

<mark style="color:orange;">`.v-align-bottom`</mark> - выравнивает **inline** элемент в блоке по нижнему краю

<mark style="color:orange;">`.v-align-center`</mark> - выравнивает **inline** элемент в блоке по центру

<mark style="color:orange;">`.v-align-baseline`</mark> - выравнивает базовую линию текущего элемента по базовой линии родителя

<mark style="color:orange;">`.v-align-sub`</mark> - выравнивает **inline** элемент в блоке под нижней линией

<mark style="color:orange;">`.v-align-super`</mark> - выравнивает **inline** элемент в блоке над верхней линией

<mark style="color:orange;">`.v-align-text-bottom`</mark> - нижняя граница элемента выравнивается по самому нижнему краю текущей строки

<mark style="color:orange;">`.v-align-text-top`</mark> - верхняя граница элемента выравнивается по самому высокому текстовому элементу текущей строки

## Прозрачность элементов <a href="#opacity" id="opacity"></a>

В PipUI заготовлены классы и для прозрачности элементов от <mark style="color:orange;">`.opacity-0`</mark> до <mark style="color:orange;">`.opacity-10`</mark> с шагом 1. (В стилях это **0.1**, следовательно 10 - это 1 или же 100%)

## Позиционирование <a href="#position" id="position"></a>

Позиционировать элементы можно используя классы:

<mark style="color:orange;">`.fixed`</mark> - фиксированное позиционирование, которое двигает элемент вместе с прокруткой страницы

<mark style="color:orange;">`.absolute`</mark> - абсолютное позиционирование выставляет элемент на странице не учитывая ее прокрутку

<mark style="color:orange;">`.relative`</mark> - относительное позиционирование. Блоки внутри данного, если им указано абсолютное позиционирование, будут выравниваться относительно его позиции

<mark style="color:orange;">`.static`</mark> - статичное позиционирование (по умолчанию)

Управлять позицией относительно верхнего, правого, нижнего, левого краев можно задать, воспользовавшись классами от <mark style="color:orange;">`.top-0`</mark> до <mark style="color:orange;">`.top-64`</mark>, от <mark style="color:orange;">`.right-0`</mark> до <mark style="color:orange;">`.right-64`</mark>, от <mark style="color:orange;">`.bottom-0`</mark> до <mark style="color:orange;">`.bottom-64`</mark>, от <mark style="color:orange;">`.left-0`</mark> до <mark style="color:orange;">`.left-64`</mark> соответственно. Данные классы можно использовать с шагом в 4, например <mark style="color:orange;">`.top-0`</mark> , <mark style="color:orange;">`.top-4`</mark> , <mark style="color:orange;">`.top-8`</mark> и т.д.

Помимо этого, Вы можете контролировать и позиционные индексы, относительно оси Z от <mark style="color:orange;">`.zid-0`</mark> до <mark style="color:orange;">`.zid-10`</mark>


# Отступы

Если Вам необходимо добавить отступ к элементу, то в PipUI есть набор готовых стилей для данных операций

## Внутренние отступы (padding) <a href="#padding" id="padding"></a>

Общие отступы (*padding*): От <mark style="color:orange;">`.p-0`</mark> до <mark style="color:orange;">`.p-100`</mark> с шагом 4

Отступы по верхнему и нижнему краям (*padding-top/padding-bottom*): От <mark style="color:orange;">`.py-0`</mark> до <mark style="color:orange;">`.py-100`</mark> с шагом 4

Отступы по левому и правому краям (*padding-left/padding-right*): От <mark style="color:orange;">`.px-0`</mark> до <mark style="color:orange;">`.px-100`</mark> с шагом 4

Отступы по левому и правому краям (*padding-left/padding-right*): От <mark style="color:orange;">`.px-0`</mark> до <mark style="color:orange;">`.px-100`</mark> с шагом 4

Отступы по левому краю (*padding-left*): От <mark style="color:orange;">`.pl-0`</mark> до <mark style="color:orange;">`.pl-100`</mark> с шагом 4

Отступы по правому краю (*padding-right*): От <mark style="color:orange;">`.pr-0`</mark> до <mark style="color:orange;">`.pr-100`</mark> с шагом 4

Отступы по верхнему краю (*padding-top*): От <mark style="color:orange;">`.pt-0`</mark> до <mark style="color:orange;">`.pt-100`</mark> с шагом 4

Отступы по нижнему краю (*padding-bottom*): От <mark style="color:orange;">`.pb-0`</mark> до <mark style="color:orange;">`.pb-100`</mark> с шагом 4

## Внешние отступы (margin) <a href="#margin" id="margin"></a>

Общие отступы (*margin*): От <mark style="color:orange;">`.m-0`</mark> до <mark style="color:orange;">`.m-100`</mark> с шагом 4

Отступы по верхнему и нижнему краям (*margin-top/margin-bottom*): От <mark style="color:orange;">`.my-0`</mark> до <mark style="color:orange;">`.my-100`</mark> с шагом 4

Отступы по левому и правому краям (*margin-left/margin-right*): От <mark style="color:orange;">`.mx-0`</mark> до <mark style="color:orange;">`.mx-100`</mark> с шагом 4

Отступы по левому и правому краям (*margin-left/margin-right*): От <mark style="color:orange;">`.mx-0`</mark> до <mark style="color:orange;">`.mx-100`</mark> с шагом 4

Отступы по левому краю (*margin-left*): От <mark style="color:orange;">`.ml-0`</mark> до <mark style="color:orange;">`.ml-100`</mark> с шагом 4

Отступы по правому краю (*margin-right*): От <mark style="color:orange;">`.mr-0`</mark> до <mark style="color:orange;">`.mr-100`</mark> с шагом 4

Отступы по верхнему краю (*margin-top*): От <mark style="color:orange;">`.mt-0`</mark> до <mark style="color:orange;">`.mt-100`</mark> с шагом 4

Отступы по нижнему краю (*margin-bottom*): От <mark style="color:orange;">`.mb-0`</mark> до <mark style="color:orange;">`.mb-100`</mark> с шагом 4

Автоматические отступы: <mark style="color:orange;">`.mx-auto`</mark>, <mark style="color:orange;">`.my-auto`</mark>, <mark style="color:orange;">`.m-auto`</mark>


# Палитра цветов

PipUI дает возможность менять цвет текста и фона без необходимости изменять CSS стили. Для этого в нем заготовлены специальные классы, а палитра выбрана на основе Material UI от Google.

Чтобы задать цвет фона элемента, используйте класс <mark style="color:orange;">`.bg-{COLOR}-{INTENSITY}`</mark>, где *{COLOR}* - цвет, а *{INTENCITY}* - интенсивность от 50 до 900 с шагом 100 (после 100).

Чтобы задать цвет текста, используйте класс <mark style="color:orange;">`.text-{COLOR}-{INTENSITY}`</mark>

{% hint style="info" %}
Цвета тона 500 можно использовать без суффикса -500
{% endhint %}

{% embed url="<https://codepen.io/pipui/pen/NWzvEXz>" %}
Пример работы цветовых наборов
{% endembed %}

*Вы можете менять цвет текста и фона наведения, используя те же имена классов с суффиксом -h, в случае с префиксом -i, класс будет первостепенно иметь префикс -h, а уже затем -i, например* <mark style="color:orange;">`.bg-blue-gray-h-i`</mark>


# Grid сетка

Данный компонент позволяет быстро произвести разметку блоков внутри контейнера.

Для определения grid контейнера используется класс <mark style="color:orange;">`.d-grid`</mark> или его алиас <mark style="color:orange;">`.grid`</mark>.

Количество колонок и рядов внутри grid контейнера варьируется от 1 до 12, которые используют классы от <mark style="color:orange;">`.columns-1`</mark> до <mark style="color:orange;">`.columns-12`</mark> (для колонок) и <mark style="color:orange;">`.rows-1`</mark> до <mark style="color:orange;">`.rows-12`</mark> (для рядов) соответственно.

Позиции колонок внутри контейнера определяются классами с патерном <mark style="color:orange;">`.column-{1-12}-{1-12}`</mark> при этом второй параметр может отсутствовать, если он равен первому.

{% embed url="<https://codepen.io/pipui/pen/WNyEYLY>" %}
Пример работы колонок в Grid сетке (с учетом responsive)
{% endembed %}

Отступы внутри grid сетки можно выставлять с помощью классов от <mark style="color:orange;">`.gap-0`</mark> до <mark style="color:orange;">`.gap-100`</mark> с шагом 4. Для отступов внутри сетки между рядами используйте классы от <mark style="color:orange;">`.gap-row-0`</mark> до <mark style="color:orange;">`.gap-row-100`</mark>, а для отступов между колонками от <mark style="color:orange;">`.gap-column-0`</mark> до <mark style="color:orange;">`.gap-column-100`</mark> так же с шагом 4.


# Панель навигации

## Общая информация <a href="#general-information" id="general-information"></a>

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

### Разметка <a href="#markup" id="markup"></a>

```html
<div class="navbar">
    <div class="navbar-container">
        <a class="nav-brand" href="#">Название</a>
        <a href="#" rel="nofollow" class="nav-mobile"><i class="nav-mobile-bars"></i></a>
    </div>
</div>
```

{% embed url="<https://codepen.io/pipui/pen/NWBXroJ>" %}
Пример работы кода выше
{% endembed %}

Цвет панели может быть изменен с помощью классов цвета фона из палитры (<mark style="color:purple;">.bg-{COLOR}</mark>)

Вы можете добавить клсаа <mark style="color:orange;">`.container`</mark> к объекту <mark style="color:orange;">`.navbar-container`</mark>, если хотите, чтобы контейнер был адаптивным.

Для изменения тёмной палитры текста, можно добавить класс <mark style="color:orange;">`.navbar-text-light`</mark> к блоку <mark style="color:orange;">`.navbar`</mark> в этом случае все текстовые элементы будут светлыми.

В панели навигации есть 3 секции: левая (<mark style="color:orange;">`.nav-left`</mark>), правая(<mark style="color:orange;">`.nav-right`</mark>)\
и центральная(<mark style="color:orange;">`.nav-center`</mark>). Чтобы их добавить необходимо внутрь\
блока <mark style="color:orange;">`.navbar-container`</mark> поместить необходимые секции. Именно в эти секции и следует помещать основной список меню.

```html
<div class="navbar">
    <div class="navbar-container container">
        <a class="nav-brand" href="#">Название</a>
        <a href="#" rel="nofollow" class="nav-mobile"><i class="nav-mobile-bars"></i></a>

        <div class="navbar-wrapper">
            <div class="nav-left">
                <ul class="navbar-menu">
                    <li class="nav-item active">
                        <a class="nav-link" href="#">Item #1</a>
                    </li>

                    <li class="nav-item">
                        <a class="nav-link" href="#">Item #2</a>
                    </li>
                </ul>
            </div>

            <div class="nav-center">
                <ul class="navbar-menu">
                    <li class="nav-item">
                        <a class="nav-link" href="#">Item #3</a>
                    </li>

                    <li class="nav-item">
                        <a class="nav-link" href="#">Item #4</a>
                    </li>
                </ul>
            </div>

            <div class="nav-right">
                <ul class="navbar-menu">
                    <li class="nav-item">
                        <a class="nav-link" href="#">Item #5</a>
                    </li>

                    <li class="nav-item">
                        <a class="nav-link" href="#">Item #6</a>
                    </li>
                </ul>
            </div>
        </div>
    </div>
</div>
```

{% embed url="<https://codepen.io/pipui/pen/gOjoJKr>" %}
Пример работы кода выше
{% endembed %}

### Выпадающее меню <a href="#dropdown-menu" id="dropdown-menu"></a>

Панель навигации поддерживает выпадающее меню, которое инициализируется автоматически, но при желании можно это сделать и вручную, согласно [документации](/components/dropdown#inicializaciya-vypadayushego-spiska).

```html
<div class="navbar">
    <div class="navbar-container container">
        <a class="nav-brand" href="#">Название</a>
        <a href="#" rel="nofollow" class="nav-mobile"><i class="nav-mobile-bars"></i></a>

        <div class="navbar-wrapper">
            <div class="nav-right">
                <ul class="navbar-menu">
                    <li class="nav-item active">
                        <a class="nav-link" href="#">Item #1</a>
                    </li>

                    <li class="nav-item">
                        <a class="nav-link" href="#">Item #2</a>
                    </li>

                    <li class="nav-item dropdown" data-dropdown-direction-x="left">
                        <a class="nav-link nav-sub dropdown-trigger" href="#" rel="nofollow">Администрация <i class="fa-solid fa-caret-down"></i></a>

                        <ul class="dropdown-list">
                            <li class="dropdown-item">
                                <a class="dropdown-link" rel="nofollow" href="#">Управление</a>
                            </li>

                            <li class="dropdown-item dropdown-submenu">
                                <a class="dropdown-link dropdown-submenu-trigger" href="#">Вход <i class="fa-solid fa-caret-down"></i></a>

                                <ul class="nav-submenu dropdown-list">
                                    <li class="dropdown-item">
                                        <a class="dropdown-link" href="#">Через ВК</a>
                                    </li>

                                    <li class="dropdown-item">
                                        <a class="dropdown-link" href="#">Через Facebook</a>
                                    </li>
                                </ul>
                            </li>
                        </ul>
                    </li>
                </ul>
            </div>
        </div>
    </div>
</div>
```

{% embed url="<https://codepen.io/pipui/pen/dyjJEqb>" %}
Пример работы кода выше
{% endembed %}

## Javascript

Панель навигации может работать через Javascript. В этом бывает необходимость, когда требуется управлять состоянием меню на адаптивной верстке (Открытие/закрытие меню)

По умолчанию инициализация происходить автоматически при клике на меню, но это можно сделать и самостоятельн

### Инициализация <a href="#init" id="init"></a>

Для инициализации меню вручную, необходимо создать экземпляр класса PipUI.Navbar. Конструктор данного класса поддерживает 2 параметра: HTMLElement и Object

Первый параметр - объект или строка ссылающаяся на элемент.&#x20;

Второй параметр - объект опций

```html
<div class="navbar" id="navbar">...</div>

<script>
    let navbar = new PipUI.Navbar('#navbar');
</script>
```

### Опции <a href="#options" id="options"></a>

```
// Выводить в консоль отладку
debug: false

// Функция обратного вызова по завершению отображения блока
openCallback: undefined

// Функция обратного вызова по завершению скрытия блока
closeCallback: undefined
```

### Методы <a href="#methods" id="methods"></a>

```javascript
let navbar = new PipUI.Navbar('#navbar');

navbar.getID() // Вернет уникальный идентификатор панели

navbar.setOptions(object) // Изменить опции панели

navbar.getOptions() // Получить опции панели

navbar.hide(callback) // Скрыть панель
// Параметр callback является приоритетной функцией обратного
// вызова при завершении скрытия, если она задана и через опции

navbar.show(callback) // Показать блок
// Параметр callback является приоритетной функцией обратного
// вызова при завершении отображения, если она задана и через опции

navbar.isOpen() // Текущее состояние панели
```

### События

<table><thead><tr><th width="203">Триггер</th><th width="259">Описание</th><th>Инициатор</th></tr></thead><tbody><tr><td>show-navbar-pipui</td><td>Срабатывает при открытии меню на мобильных устройствах</td><td>.navbar</td></tr><tr><td>hide-navbar-pipui</td><td>Срабатывает при закрытии меню на мобильных устройствах</td><td>.navbar</td></tr></tbody></table>


# Выпадающее меню

## Общая информация <a href="#general-information" id="general-information"></a>

Компонент выпадающего меню имеет многоуровневую систему вложенности, что позволяет определять множественные разделы и подразделы

{% embed url="<https://codepen.io/pipui/pen/WNyEPbw>" %}
Пример простейшего выпадающего меню
{% endembed %}

```html
<div class="dropdown">
      <button class="btn dropdown-trigger">Dropdown Menu ▼</button>

      <ul class="dropdown-list">
          <li class="dropdown-item">
              <a href="#" rel="nofollow" class="dropdown-link">Link #1</a>
          </li>

          <li class="dropdown-item">
              <a href="#" rel="nofollow" class="dropdown-link">Link #2</a>
          </li>
      </ul>
  </div>
```

Выпадающее меню может быть многоуровневым.

Для этого одному из элементов <mark style="color:orange;">`.dropdown-item`</mark> необходимо добавить\
класс <mark style="color:orange;">`.dropdown-submenu`</mark> и поместить внутрь него такой же код, как и в одноуровневом меню и заменить класс триггера <mark style="color:orange;">`.dropdown-trigger`</mark> на <mark style="color:orange;">`.dropdown-submenu-trigger`</mark>

```html
<div class="dropdown">
    <button class="btn dropdown-trigger">Dropdown Menu ▼</button>

    <ul class="dropdown-list">
        <li class="dropdown-item">
            <a href="#" rel="nofollow" class="dropdown-link">Link #1</a>
        </li>

        <li class="dropdown-item">
            <a href="#" rel="nofollow" class="dropdown-link">Link #1</a>
        </li>

        <li class="dropdown-item dropdown-submenu">
            <a href="#" rel="nofollow" class="dropdown-link dropdown-submenu-trigger">Dropdown ▼</a>

            <ul class="dropdown-list">
                <li class="dropdown-item">
                    <a href="#" rel="nofollow" class="dropdown-link">Link #1</a>
                </li>

                <li class="dropdown-item">
                    <a href="#" rel="nofollow" class="dropdown-link">Link #2</a>
                </li>

                <li class="dropdown-item dropdown-submenu">
                    <a href="#" rel="nofollow" class="dropdown-link dropdown-submenu-trigger">Dropdown ▼</a>

                    <ul class="dropdown-list">
                        <li class="dropdown-item">
                            <a href="#" rel="nofollow" class="dropdown-link">Link #1</a>
                        </li>

                        <li class="dropdown-item">
                            <a href="#" rel="nofollow" class="dropdown-link">Link #2</a>
                        </li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>

</div>
```

{% embed url="<https://codepen.io/pipui/pen/wvxqEZe>" %}
Пример работы кода выше
{% endembed %}

Для управления положением выпадающего меню, вы можете использовать атрибуты\ <mark style="color:orange;">`data-dropdown-direction-x`</mark> и <mark style="color:orange;">`data-dropdown-direction-y`</mark>

Атрибут <mark style="color:orange;">`data-dropdown-direction-x`</mark> принимает значения **left** или **right**

Атрибут <mark style="color:orange;">`data-dropdown-direction-y`</mark> принимает значения **up** или **down**

## Javascript

По умолчанию объекты не инициализированных выпадающих списков создаются автоматически и сохраняются компонентом **PipUI.Storage**

Вы можете создавать и управлять объектами выпадающих списков с помощью Javascript. Для этого необходимо создать объект PipUI.Dropdown и передать в него параметры

```html
<div id="dd"></div>

<script>
let dropdown = new PipUI.Dropdown('#dd', {
    name: 'Dropdown',
    list: [
        {url: 'https://pipui.ru', name: 'PipUI'},
        {url: 'https://google.com', name: 'Google'},
        {url: '#', name: 'Submenu', submenu: [
            {url: 'https://github.com', target: '_blank', name: 'GitHub'},
            {url: 'https://youtube.com', target: '_blank', name: 'YouTube'}
        ]}
    ]
    
}, true);
</script>
```

### Инициализация выпадающего списка <a href="#init" id="init"></a>

```javascript
let dropdown = new PipUI.Dropdown();
```

Объект Dropdown может содержать в себе 3 аргумента

1. HTMLElement или строка элемента на странице
2. Объект набора опций
3. Механизм обработки элемента. true - для создания нового, false - для инициализации из существующего выпадающего списка

### Опции <a href="#options" id="options"></a>

```
// Выводить в консоль отладку
debug: false

// Опции шаблонов
templates: {
	// Основной элемент выпадающего списка
	wrapper: '<div class="dropdown"></div>'
	
	// Элемент триггера, открывающего выпадающий список
	trigger: '<button type="button" class="btn dropdown-trigger"></button>'
	
	// Контейнер для списка
	list: '<ul class="dropdown-list"></ul>'
	
	Элемент списка
	item: '<li class="dropdown-item"></li>'
}

// Имя кнопки выпадающего списка
name: ''

// URL адрес кнопки
url: ''

// Массив со списком элементов
list: []

// Направление в которое будет открываться список по оси X
direction_x: 'right'

// Направление в которое будет открываться список по оси Y
direction_y: 'down'

// По какому событию будет открываться список
openEvent: 'click'

// По какому событию будет открываться подменю
submenuOpenEvent: 'hover'

// Функция обратного вызова по завершению открытия
showCallback: undefined

// Функция обратного вызова по завершению скрытия
hideCallback: undefined
```

### Методы <a href="#methods" id="methods"></a>

```javascript
let dropdown = new PipUI.Dropdown();

dropdown.getID() // Вернет уникальный идентификатор блока

dropdown.setOptions(object) // Изменить опции блока. DOM не будет изменен
// до вызова метода dropdown.update()

dropdown.getOptions() // Получить опции блока

dropdown.update() // Отрендерит список заново

dropdown.isOpen() // Открыт ли список

dropdown.hide(callback) // Скрыть список
// Параметр callback является приоритетной функцией обратного
// вызова при завершении скрытия, если она задана и через опции

dropdown.show(callback) // Отобразить список
// Параметр callback является приоритетной функцией обратного
// вызова при завершении отображения, если она задана и через опции
```

### События

| Триггер             | Описание                        | Инициатор |
| ------------------- | ------------------------------- | --------- |
| show-dropdown-pipui | Срабатывает при открытии списка | .dropdown |
| hide-dropdown-pipui | Срабатывает при закрытии списка | .dropdown |


# Постраничная навигация

## Общая информация <a href="#general-information" id="general-information"></a>

Блок постраничной навигации состоит из панели пронумерованных страниц.

Для работы стилей постраничной навигации, контейнеру списка необходимо\
задать класс <mark style="color:orange;">`.pagination`</mark> а всем его элементам, класс <mark style="color:orange;">`.pagination-page`</mark>

```html
<ul class="pagination">
    <li class="pagination-page disabled"><a href="#" rel="nofollow"><i class="fa-solid fa-angles-left"></i></a></li>
    <li class="pagination-page disabled"><a href="#" rel="nofollow"><i class="fa-solid fa-angle-left"></i></a></li>
    <li class="pagination-page"><a href="#" rel="nofollow">1</a></li>
    <li class="pagination-page"><a href="#" rel="nofollow">2</a></li>
    <li class="pagination-page page-selector"><a href="#" rel="nofollow">...</a></li>
    <li class="pagination-page"><a href="#" rel="nofollow">39</a></li>
    <li class="pagination-page active"><a href="#" rel="nofollow">40</a></li>
    <li class="pagination-page"><a href="#" rel="nofollow">41</a></li>
    <li class="pagination-page page-selector"><a href="#" rel="nofollow">...</a></li>
    <li class="pagination-page"><a href="#" rel="nofollow">99</a></li>
    <li class="pagination-page"><a href="#" rel="nofollow">100</a></li>
    <li class="pagination-page"><a href="#" rel="nofollow"><i class="fa-solid fa-angle-right"></i></a></li>
    <li class="pagination-page"><a href="#" rel="nofollow"><i class="fa-solid fa-angles-right"></i></a></li>
</ul>

<br><br>

<ul class="pagination">
    <li class="pagination-page"><a href="#">← Назад</a></li>
    <li class="pagination-page"><a href="#">Вперед →</a></li>
</ul>
```

{% embed url="<https://codepen.io/pipui/pen/QWBQxJg>" %}
Пример работы кода выше
{% endembed %}

Класс <mark style="color:orange;">`.disabled`</mark> элемента списка служит для отключения переключателя.

## Javascript

Блок постраничной навигации можно создать при помощи Javascript. В этом случае у вас откроется больше возможность без перезагрузки страницы.

Для этого вам необходимо создать экземпляр класса <mark style="color:orange;">`PipUI.Pagination`</mark> и передать в него необходимые параметры.

Данный класс имеет в себе два параметра

1. HTMLElement - элемент или строковая ссылка на элемент
2. Object - объект с набором опций

### Пример <a href="#example" id="example"></a>

```html
<div id="pagination1"></div>

<script>
    let pagination1 = new PipUI.Pagination('#pagination1', {records: 100});
</script>
```

### Опции <a href="#options" id="options"></a>

Второй параметр объекта PipUI.Pagination поддерживает следующие параметры

```
// Выводить в консоль отладку
debug: false

// Шаблон адреса URL страницы. На место {NUM} будет подставлен номер страницы 
url: '/page-{NUM}'

// Что должно произойти после нажатия на селектор
// Поддерживаемые значения:
// redirect - произойдет переход на страницу, указанную в ссылке селектора
// location - URL страницы изменится, но перехода не произойдет
// none - отсутствие действия
// Во всех случаях визуальная составляющая будет обновлена
method: 'redirect'

// Тип метода генерации шаблона постраничной навигации.
// Поддерживаемые значения по умолчанию от 1 до 4
// Вы можете передать свое значение, но перед этим необходимо создать свой метод, добавив его через опцию types
type: 1

// Кол-во записей
records: 0

// Текущий номер страницы
current: 1

// Максимальное кол-во элементо вна страницу
max: 10

// Функция обратного вызова, которая будет выполнена при изменении страницы
changePageCallback: undefined

// Функция обратного вызова, которая будет выполнена при рендере
updateCallback: undefined

// Типы методов генерации шаблона постраничной навигации
types: {...}
```

### Методы <a href="#methods" id="methods"></a>

```javascript
let pagination = new PipUI.Pagination('#pagination');

pagination.getID() // Вернет уникальный идентификатор

pagination.setOptions(object) // Изменить опции. DOM не будет изменен
// до вызова метода pagination.update()

pagination.getOptions() // Получить опции

pagination.update() // Отрендерить содержимое заново

pagination.getPages() // Вернуть общее кол-во страниц

pagination.getPrev() // Вернуть номер предыдущей страницы

pagination.getNext() // Вернуть номер следующей страницы

pagination.setPage(int) // Установить новую страницы. Содержимое будет обновлено

pagination.getType() // Получить объект типа метода генерации
```

### Новые типы генерации <a href="#custom-generation-types" id="custom-generation-types"></a>

Для создания или изменения текущего типа генерации, необходимо передать в опции параметр types со своими значениями.

{% hint style="info" %}
Объект должен содержать в себе метод render, который принимает параметр\
self - реферальная переменная от текущего экземпляра класса (this).

Данный метод должен возвращать новый список страниц в виде строки HTML
{% endhint %}

#### Пример нового типа <a href="#example-generation-type" id="example-generation-type"></a>

```
let pagination = new PipUI.Pagination('#pagination', {
    records: 100,
    types: {
        5: {
            render: function(self){
                return '<li class="pagination-page"><a data-pagination-page="1" href="#">1</a></li>';
            }
        }
    }
});
```

### События

| Триггер                 | Описание                           | Инициатор   |
| ----------------------- | ---------------------------------- | ----------- |
| change-pagination-pipui | Срабатывает при изменении страницы | .pagination |
| update-pagination-pipui | Срабатывает при обновлении списка  | .pagination |
|                         |                                    |             |


# Формы

Формы и компоненты форм

Формы в наше время являются неотъемлемой частью сайта, где есть какие-либо поля ввода. PipUI имеет в себе компонент быстрой стилизации всех существующих элементов форм и даже больше.

Для начала работы подготовленных стилей, необходимо добавить компоненту формы класс <mark style="color:orange;">`.input`</mark>

{% embed url="<https://codepen.io/pipui/pen/NWLbQKP>" %}
Простой пример формы
{% endembed %}

## Input

```html
<input type="text" class="input" placeholder=".input">

<input type="text" class="input focus" placeholder=".input.focus">

<input type="text" class="input" readonly placeholder=".input:readonly">

<input type="text" class="input" disabled placeholder=".input:disabled">
```

{% embed url="<https://codepen.io/pipui/pen/dyqOxaB>" %}
Пример работы кода выше
{% endembed %}

## Select

```html
<select class="input">
    <option value="0">Item #1</option>
    <option value="1">Item #2</option>
</select>

<select class="input focus">
    <option value="0">Item #1</option>
    <option value="1">Item #2</option>
</select>

<select class="input" disabled>
    <option value="0">Item #1</option>
    <option value="1">Item #2</option>
</select>
```

### Multiple

Класс <mark style="color:orange;">`.input`</mark> поддерживает и мультиселекторы

```html
<select class="input" multiple>
    <option value="1">Item #1</option>
    <option value="2">Item #2</option>
    <option value="3">Item #3</option>
    <option value="4" disabled>Item #4 (disabled)</option>
    <option value="5">Item #5</option>
    <option value="6">Item #6</option>
</select>
```

{% embed url="<https://codepen.io/pipui/pen/KKxNOLy>" %}
Пример работы селекторов
{% endembed %}

## Textarea

```html
<textarea class="input" placeholder=".input"></textarea>
```

### Javascript

Помимо стандартного поле ввода со стилями, textarea может быть инициализована с помощью Javascript, что даст дополнительные возможности управления данной формой. Например, количество введенных строк, их копирование и др.

Для инициализации достаточно использовать следующий скрипт

```html
<textarea class="input" id="textarea1" placeholder=".input"></textarea>

<script>new PipUI.Textarea('#textarea1');</script>
```

## File

По умолчанию селектор выбора файлов имеет стили заданные браузером и которые не поддаются на данный момент кастомизации, но это можно исправить, если поместить такой селектор в контейнер <mark style="color:orange;">`label.input-file`</mark> и кастомизировать его, а сам селектор просто скрыть, что мы и сделали.

```html
<label class="input-file btn"><input type="file">Выберите файл</label>
```

## Checkbox

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

```html
<label><input type="checkbox" class="input"> Check it!</label>
```

## Radio

```html
<input type="radio" name="radio_example1" checked class="input">
<input type="radio" name="radio_example1" class="input">
```

## Switch

По умолчанию в браузерах нет данных переключателей, но как и в случае с селекторами файлов, мы сделали это возможным. Для этого необходимо поместить checkbox с классом <mark style="color:orange;">`.input`</mark> в контейнер <mark style="color:orange;">`label.input-switch`</mark>

```html
<label class="input-switch"><input type="checkbox" class="input"></label>
```

## Input Block

Блоки помогают использовать дополнительные возможности внутри общего контейнера.

В качестве контейнера необходимо создать блок с классом <mark style="color:orange;">`.input-block`</mark> и поместить в него форму ввода.

```html
<div class="input-block">
    <input type="text" class="input" placeholder=".input">
</div>
```

### Label

Ярлыки позволяют добавить зависимое описание, при клике на которое, у формы появляется фокусировка.

```html
<div class="input-block">
    <label for="input-example-1"></label>
    <input type="text" class="input" id="input-example-1" placeholder=".input">
</div>
```

### Helper

Вспомогательные блоки служат в качестве дополнительной информации, которая появляется при наведении на контейнер. Данный блок можно использовать вместе с [ярлыками](#label).

```html
<div class="input-block">
    <label for="input-example-1"></label>
    <input type="text" class="input" id="input-example-1" placeholder=".input">
    <div class="input-helper">Block Helper Here</div>
</div>
```

## Prepend / Append

Иногда бывают ситуации, когда необходимо вывести дополнительный контент до или после поля ввода или селектора. Для этих случаев есть дополнительный контейнер\ <mark style="color:orange;">`.input-append-prepend`</mark>, который так же совместим с <mark style="color:orange;">`.input-block`</mark>.

Блок <mark style="color:orange;">`.prepend`</mark> выводит дополнительный контент перед полем ввода или селектором, а блок <mark style="color:orange;">`.append`</mark>, соответственно, после. Оба блока являются не обязательными в контейнере и могут использоваться как отдельно, так и вместе.

```html
<div class="input-block">
    <label for="input-block-example2">My Label</label>
    <div class="input-append-prepend">
        <div class="prepend">Hello</div>
        <input type="text" id="input-block-example2" placeholder=".input" class="input">
        <div class="append"><input type="checkbox" class="input"></div>
    </div>
    <div class="input-helper">Скрытая информация, появляющаяся при наведении</div>
</div>
```


# Кнопки

PipUI имеет в своем наборе компонентов множество вариаций кнопок, совместно с другими компонентами. Для их стилизации необходимо добавить элементу класс <mark style="color:orange;">`.btn`</mark>

```html
<button class="btn">Example</button>
<button class="btn active">Active</button>
<button class="btn" disabled>Disabled</button>
```

{% embed url="<https://codepen.io/pipui/pen/GRBNPXY>" %}
Примеры кнопок в разных состояниях
{% endembed %}

Кнопки можно комбинировать и с другими компонентами, например с [цветовыми наборами](/components/palette), [отступами](/components/margin) и др.

{% embed url="<https://codepen.io/pipui/pen/JjBbwwr>" %}
Пример кастомизации кнопок
{% endembed %}


# Полосы прогресса

## Общая информация <a href="#general-information" id="general-information"></a>

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

{% code title="Пример прогресс бара" lineNumbers="true" %}

```html
<div class="progress" data-progress-type="linear">
    <div class="progress-bar" style="width: 35%;"></div>
    <div class="progress-text">35%</div>
    <div class="progress-label">Label text</div>
</div>
```

{% endcode %}

{% embed url="<https://codepen.io/pipui/pen/GRBxdbY>" %}
Пример работы кода выше
{% endembed %}

{% hint style="warning" %}
Атрибут <mark style="color:orange;">`data-progress-type`</mark> является обязательным, т.к. для каждого типа прогресса своя стратегия обработки стилей и скриптов.
{% endhint %}

На данный момент поддерживаются 2 типа полос прогресса: **linear** и **radial**

Т.к. radial тип работает совершенно иначе, нежели linear. Его инициализация требуется через  canvas и javascript.

```html
<div id="progressbar" class="progress" data-progress-type="radial">
    <canvas class="progress-bar" data-progress-size="20"></canvas>
    <div class="progress-text">Text</div>
    <div class="progress-label">Label</div>
</div>

<script>
    let progress = new PipUI.Progress('#progressbar', {styles: {width: '200px', height: '20'}});
</script>
```

## Javascript

Управление полосой прогресса можно производить через Javascript, обращаясь к экземпляру класса PipUI.Progress

```html
<div id="progress"></div>

<script>let progress = new PipUI.Progress('#progress', {}, true);</script>
```

Класс PipUI.Progress поддерживает 3 параметра

1. HTMLElement или строковая ссылка на элемент
2. Объект опций
3. Стратегия создания (true/false)

В примере выше мы передали 3й параметр, который означает, что прогресс бар будет создан из опций, которые мы должны указать во втором параметре.

### Опции <a href="#options" id="options"></a>

<pre><code>// Выводить в консоль отладку
debug: false

// Текст прогресс бара
text: ''

// Дополнительный текст для прогресс бара
label: ''

// Размер прогресс бара в процентах
progress: 0

// Тип прогресс бара
type: 'linear'

// Объект настроек стилей
styles: {
    width: '100%'
    height: '28px'
    padding: 4
<strong>    barColor: '#fff'
</strong>    progressColor: '#212121'
}

// Объект настроек шаблона
templates: {
    text: '&#x3C;div class="progress-text">&#x3C;/div>'
    label: '&#x3C;div class="progress-label">&#x3C;/div>'
}

// Объект типов
types: {...}
</code></pre>

### Методы <a href="#methods" id="methods"></a>

```
let progress = new PipUI.Progress('#progress');

progress.getID() // Вернет уникальный идентификатор

progress.setOptions(object) // Изменить опции. DOM не будет изменен
// до вызова метода progress.update()

progress.getOptions() // Получить опции

progress.setProgress(float) // Изменить размер прогресс бара в процентах. DOM будет обновлен

progress.setText(string) // Изменить текст прогресс бара. DOM будет обновлен

progress.setLabel(string) // Изменить дополнительный текст. DOM будет обновлен
 
progress.update() // Обновить DOM
```

### События

<table><thead><tr><th width="268.3333333333333">Триггер</th><th>Описание</th><th>Инициатор</th></tr></thead><tbody><tr><td>change-progress-pipui</td><td>Срабатывает при изменении размера полосы прогресс бара</td><td>.progress</td></tr><tr><td>change-text-progress-pipui</td><td>Срабатывает при изменении текста внутри прогресс бара</td><td>.progress</td></tr><tr><td>change-label-progress-pipui</td><td>Срабатывает при изменении дополнительного текста прогресс бара</td><td>.progress</td></tr><tr><td>update-progress-pipui</td><td>Срабатывает при полном обновлении прогресс бара</td><td>.progress</td></tr></tbody></table>

### Типы прогресс баров <a href="#progress-bar-types" id="progress-bar-types"></a>

Для изменения типов прогресс баров, необходимо передать в объект types опций свои параметры.

{% hint style="warning" %}
Важно чтобы тип имел в себе 3 обязательных ключа: **template, create, progress**

1. template - HTML строка шаблона для .progress-bar
2. create - функция создания прогресс бара
3. progress - изменение размера прогресс бара
   {% endhint %}


# Меню навигации

## Общая информация <a href="#general-information" id="general-information"></a>

Меню навигации позволяет быстро переходить по разделам и категориям.

### Простое меню <a href="#basic-menu" id="basic-menu"></a>

```html
<ul class="nav-menu">
    <li class="nav-menu-item active"><a href="#" rel="nofollow" class="nav-menu-link">Menu #1</a></li>
    <li class="nav-menu-item"><a href="#" rel="nofollow" class="nav-menu-link">Menu #2</a></li>
    <li class="nav-menu-item"><a href="#" rel="nofollow" class="nav-menu-link">Menu #3</a></li>
</ul>
```

{% embed url="<https://codepen.io/pipui/pen/yLqQYYW>" %}
Пример работы кода выше
{% endembed %}

### Многоуровневое меню <a href="#tree-menu" id="tree-menu"></a>

Меню навигации поддерживает многоуровневое меню.

```html
<ul class="nav-menu">
    <li class="nav-menu-item active"><a href="#" rel="nofollow" class="nav-menu-link">Menu #1</a></li>
    <li class="nav-menu-item"><a href="#" rel="nofollow" class="nav-menu-link">Menu #2</a></li>
    <li class="nav-menu-item">
        <a href="#" rel="nofollow" class="nav-menu-link">Menu #3 <i class="fa-solid fa-caret-down"></i></a>
        <ul class="nav-sub-menu">
            <li class="nav-menu-item"><a href="#" rel="nofollow" class="nav-menu-link">Submenu #1</a></li>
            <li class="nav-menu-item"><a href="#" rel="nofollow" class="nav-menu-link">Submenu #2</a></li>
            <li class="nav-menu-item">
                <a href="#" rel="nofollow" class="nav-menu-link">Submenu #3 <i class="fa-solid fa-caret-down"></i></a>
                <ul class="nav-sub-menu">
                    <li class="nav-menu-item"><a href="#" rel="nofollow" class="nav-menu-link">Submenu #3.1</a></li>
                    <li class="nav-menu-item"><a href="#" rel="nofollow" class="nav-menu-link">Submenu #3.2</a></li>
                    <li class="nav-menu-item"><a href="#" rel="nofollow" class="nav-menu-link">Submenu #3.3</a></li>
                </ul>
            </li>
        </ul>
    </li>
</ul>
```

{% embed url="<https://codepen.io/pipui/pen/RwBqWOe>" %}
Пример работы кода выше
{% endembed %}

### Меню под спойлером <a href="#collapsed-menu" id="collapsed-menu"></a>

Вы так же можете использовать данное меню вместе со [спойлерами](/components/collapse).

```html
<ul class="nav-menu">
    <li class="nav-menu-item active"><a href="#" rel="nofollow" class="nav-menu-link">Menu #1</a></li>
    <li class="nav-menu-item"><a href="#" rel="nofollow" class="nav-menu-link">Menu #2</a></li>
    <li class="nav-menu-item">
        <a href="#" rel="nofollow" class="nav-menu-link" data-collapse="#navmenu-sub">Menu #3 <i class="fa-solid fa-caret-down"></i></a>
        <ul class="nav-sub-menu collapse" id="navmenu-sub">
            <li class="nav-menu-item"><a href="#" rel="nofollow" class="nav-menu-link">Submenu #1</a></li>
            <li class="nav-menu-item"><a href="#" rel="nofollow" class="nav-menu-link">Submenu #2</a></li>
            <li class="nav-menu-item">
                <a href="#" rel="nofollow" class="nav-menu-link" data-collapse="#navmenu-sub2">Menu #3 <i class="fa-solid fa-caret-down"></i></a>
                <ul class="nav-sub-menu collapse" id="navmenu-sub2">
                    <li class="nav-menu-item"><a href="#" rel="nofollow" class="nav-menu-link">Submenu #1</a></li>
                    <li class="nav-menu-item"><a href="#" rel="nofollow" class="nav-menu-link">Submenu #2</a></li>
                    <li class="nav-menu-item"><a href="#" rel="nofollow" class="nav-menu-link">Submenu #3</a></li>
                </ul>
            </li>
        </ul>
    </li>
</ul>
```

### Иконки <a href="#icons" id="icons"></a>

Если есть необходимость добавить иконки, Вы можете добавить блок <mark style="color:orange;">`.link-icon`</mark> внутрь блока <mark style="color:orange;">`.nav-menu-link`</mark> с вашей иконкой или текстом


# Модальные окна

## Общая информация <a href="#general-information" id="general-information"></a>

Когда необходимо вывести дополнительный контент, а создавать для этого отдельную страницу нет необходимости, то на помощь нам придут модальные окна.

```html
<button type="button" class="btn" id="modal-trigger1" data-modal="#modal1">Modal</button>

<div class="modal" id="modal1">
    <div class="modal-wrapper">
        <div class="modal-content">
            <div class="modal-header">Название окна</div>

            <div class="modal-body">
                Содержимое модального окна
            </div>

            <div class="modal-footer">
                <button class="btn btn-transparent" data-modal-close>Закрыть</button>
            </div>
        </div>
    </div>
</div>
```

{% embed url="<https://codepen.io/pipui/pen/xxJBGbp>" %}
Пример работы кода выше
{% endembed %}

Модальные окна работают через Javascript и объект PipUI.Modal

При использовании открытия модального окна через атрибуты, экземпляр класса PipUI.Modal создается автоматически, как показано в примере выше и хранится в PipUI.Storage

## Javascript

Инициализация и управление может быть произведено напрямую через Javascript. Для того, чтобы инициализировать модальное окно, требуется создать экземпляр класс PipUI.Modal и передать в него необходимые параметры.

Класс PipUI.Modal принимает 3 параметра

1. HTMLElement или строковая ссылка на элемент
2. Объект опций
3. Стратегия создания (true/false)

```html
<div id="mymodal"></div>

<script>
let modal = new PipUI.Modal('#mymodal', {
    header: 'My modal',
    body: 'Lorem ipsum'
}, true)
</script>
```

Если вы сформирует HTML код модального окна самостоятельно и зададите только первый параметр, то все параметры будут извлечены из HTML кода автоматически.

### Опции <a href="#options" id="options"></a>

```
// Выводить в консоль отладку
debug: false

// Заголовок модального окна. Можно использовать HTML
header: ''

// Тело модального окна. Можно использовать HTML
body: ''

// Нижняя часть модального окна. Можно использовать HTML
footer: ''

// Функция обратного вызова, срабатываемая при открытии модального окна
showCallback: undefined

// Функция обратного вызова, срабатываемая при закрытии модального окна
hideCallback: undefined

// Функция обратного вызова, срабатываемая при завершении открытия модального окна
showedCallback: undefined

// Функция обратного вызова, срабатываемая при завершении закрытия модального окна
hidedCallback: undefined

// Функция обратного вызова, срабатываемая при стратегии обновления
updateCallback: undefined

// Функция обратного вызова, срабатываемая при стратегии инициализации
initCallback: undefined

// Класс открытого модального окна
targetActiveClass: 'modal-active'

// Настройка шаблона модального окна при инициализации по стратегии создания
templates: {
        // Основной код модального окна
	modal: '<div class="modal"><div class="modal-wrapper"><div class="modal-content"></div></div></div>'
	
	// Код заголовка модального окна
	header: '<div class="modal-header"></div>'
	
	// Тело модального окна
	body: '<div class="modal-body"></div>'
	
	// Нижняя часть модального окна
	footer: '<div class="modal-footer"></div>'
	
	// Код кнопки закрытия модального окна
	close: '<a href="#" rel="nofollow" data-modal-close class="modal-close"></a>'
}
```

### Методы <a href="#methods" id="methods"></a>

```javascript
let modal = new PipUI.Modal('#mymodal');

modal.getID() // Вернет уникальный идентификатор модального окна.
// Он так же хранится в блоке .modal

modal.setOptions(object) // Изменить опции модального окна. DOM не будет изменен
// до вызова метода modal.update()

modal.getOptions() // Получить опции модального окна

modal.update() // Отрендерит модальное окно заново из текущих опций

modal.isOpen() // Открыто ли модальное окно

modal.hide(callback) // Скрыть модальное окно
// Параметр callback является приоритетной функцией обратного
// вызова при начале скрытия, если она задана и через опции

modal.show(callback) // Отобразить модальное окно
// Параметр callback является приоритетной функцией обратного
// вызова при начале отображения, если она задана и через опции
```

### События

| Триггер            | Описание                                           | Инициатор |
| ------------------ | -------------------------------------------------- | --------- |
| update-modal-pipui | Срабатывает при стратегии обновления               | .modal    |
| init-modal-pipui   | Срабатывает при стратегии инициализации            | .modal    |
| show-modal-pipui   | Срабатывает при начале открытия модального окна    | .modal    |
| hide-modal-pipui   | Срабатывает при начале закрытия модального окна    | .modal    |
| showed-modal-pipui | Срабатывает при окончании открытия модального окна | .modal    |
| hided-modal-pipui  | Срабатывает при окончании закрытия модального окна | .modal    |


# Оповещения

## Общая информация <a href="#general-information" id="general-information"></a>

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

Данный компонент спроектирован исключительно для работы через Javascript, однако при большом желании, HTML код оповещения можно сформировать и вручную.

## Создание через атрибуты <a href="#make-via-attributes" id="make-via-attributes"></a>

Для создания оповещения через атрибуты, необходимо добавить инициатору события вызова атрибут <mark style="color:orange;">`data-alert`</mark>. Опции оповещения можно задать\
через атрибуты <mark style="color:orange;">`data-alert-{NAME}`</mark>.

```html
<button class="btn" data-alert data-alert-title="Welcome" data-alert-text="Hello world!">Open Alert!</button>
```

{% embed url="<https://codepen.io/pipui/pen/rNrgbBZ>" %}
Пример работы кода выше
{% endembed %}

### Поддерживаемые атрибуты <a href="#supported-attributes" id="supported-attributes"></a>

<pre><code><strong>// Текст оповещения
</strong>data-alert-text

// Название оповещения
data-alert-title

// Местоположение появления оповещения
data-alert-placement

// Кол-во миллисекунд, через которое оповещение будет закрыто. По умолчанию 3000 (3 сек.)
data-alert-autoclose

// Будет ли отображен оверлей. Принимает значения true или false. По умолчанию false
data-alert-overlay
</code></pre>

## Создание через Javascript <a href="#make-via-javascript" id="make-via-javascript"></a>

Для создания оповещения через javascript, необходимо создать экземпляр класса PipUI.Alert и передать в него один параметр опций. Важнейшим свойством объекта опций является text и title, которые задают текст и название окна соответственно. При желании эти свойства могут быть опущены.

```javascript
new PipUI.Alert({text: 'Hello world!', title: 'Welcome'})
```

{% embed url="<https://codepen.io/pipui/pen/NWBVJZj>" %}
Пример работы кода выше
{% endembed %}

### Опции <a href="#options" id="options"></a>

```
// Выводить в консоль отладку
debug: false

// Текст оповещения
text: ''

// Название оповещения
title: ''

// Местоположение появления оповещения
placement: 'bottom-right'

// Иконка оповещения
icon: ''

// Отображать ли оверлей. Если хоть у одного открытого окна задан данный параметр,
// то оверлей будет отображаться до тех пор, пока такие оповещения открыты
overlay: false

// Автозакрытие оповещения. Если задано 0, то оповещение
// не будет закрываться автоматически
autoclose: 3000

// Отображать ли кнопку закрытия внутри оповещения
closeButton: true

// Можно закрыть при нажатии на само оповещение
closeClick: false

// Класс открытого оповещения
openedClass: 'alert-active'

// Функция обратного вызова при начале открытия оповещения
openCallback: undefined

// Функция обратного вызова при закрытияе открытия оповещения
closeCallback: undefined

// Функция обратного вызова при окончании открытия оповещения
openedCallback: undefined

// Функция обратного вызова при окончании закрытия оповещения
closedCallback: undefined

// Настройки шаблонов
templates: {
	// Шаблон окна оповещения
	alert: '...'
	
	// Шаблон кнопки закрытия внутри оповещения
	close: '<button type="button" class="btn btn-transparent" data-alert-close></button>'
}
```

### Методы <a href="#methods" id="methods"></a>

```javascript
let alert = new PipUI.Alert();

alert.getID() // Вернет уникальный идентификатор оповещения

alert.setOptions(object) // Изменить опции оповещения. DOM не будет изменен
// до вызова метода alert.update()

alert.getOptions() // Получить опции оповещения

alert.update() // Отрендерит окно заново

alert.isOpen() // Открыто ли оповещение

alert.close(callback) // Закрыть оповещение. Дальнейшая работа с ним будет невозможна
// Параметр callback является приоритетной функцией обратного
// вызова при начале закрытия, если она задана и через опции

alert.open(callback) // Отобразить оповещение
// Параметр callback является приоритетной функцией обратного
// вызова при начале отображения, если она задана и через опции
```

### События

| Триггер            | Описание                                       | Инициатор |
| ------------------ | ---------------------------------------------- | --------- |
| open-alert-pipui   | Срабатывает при начале открытия оповещения     | .modal    |
| opened-alert-pipui | Срабатывает при завершении открытия оповещения | .modal    |
| close-alert-pipui  | Срабатывает при начале закрытия оповещения     | .modal    |
| closed-alert-pipui | Срабатывает при завершении закрытия оповещения | .modal    |

## Дополнительная информация <a href="#more-info" id="more-info"></a>

Положения появления оповещения задаются в формате **{VERTICAL}-{HORIZONTAL}**

Поддерживаемые положения по вертикали: top, center, bottom

Поддерживаемые положения по горизонтали: left, center, right


# Подтверждения действий

## Общая информация <a href="#general-information" id="general-information"></a>

Как известно, стандартные методы Javascript не позволяют кастомизировать метод confirm(), по этому мы решили добавить такую возможность в наш фреймворк.

Данный компонент спроектирован исключительно для работы через Javascript, однако при большом желании, HTML код подтверждения можно сформировать и вручную.

## Создание через атрибуты <a href="#make-via-attributes" id="make-via-attributes"></a>

Для создания подтверждения через атрибуты, необходимо добавить инициатору события вызова атрибут <mark style="color:orange;">`data-confirm`</mark>. Опции подтверждения можно задать\
через атрибуты <mark style="color:orange;">`data-confirm-{NAME}`</mark>.

```html
<button class="btn" data-confirm data-confirm-title="Welcome" data-confirm-text="Hello world!" data-confirm-confirm="myCallback">Open Confirm!</button>

<script>function myCallback(){ console.log('Confirmed!'); }</script>
```

{% embed url="<https://codepen.io/pipui/pen/XWBLGxZ>" %}
Пример работы кода выше
{% endembed %}

### Поддерживаемые атрибуты <a href="#supported-attributes" id="supported-attributes"></a>

<pre><code><strong>// Текст подтверждения
</strong>data-confirm-text

// Название подтверждения
data-confirm-title

// Местоположение появления подтверждения
data-confirm-placement

// Кол-во миллисекунд, через которое оповещение будет закрыто. По умолчанию 0 (бесконечно)
data-confirm-autoclose

// Будет ли отображен оверлей. Принимает значения true или false. По умолчанию true
data-confirm-overlay

// Имя функции, вызываемой при подтверждении
data-confirm-confirm

// Имя функции, вызываемой при отмене. Данная функция не будет вызвана,
// если сработало автозакрытие.
data-confirm-cancel

// Имя кнопки подтверждения
data-confirm-confirm-btn

// Имя кнопки отмены
data-confirm-cancel-btn
</code></pre>

## Создание через Javascript <a href="#make-via-javascript" id="make-via-javascript"></a>

Для создания подтверждения через javascript, необходимо создать экземпляр класса PipUI.Confirm и передать в него один параметр опций. Важнейшим свойством объекта опций является text и title, которые задают текст и название окна соответственно. При желании эти свойства могут быть опущены.

Для обработки события нажатия на одну из кнопок, можно использовать параметры объекта опций confirm и/или cancel, передав в них функции обратного вызова.

```javascript
new PipUI.Confirm({text: 'Hello world!', title: 'Welcome', confirm: () => { console.log('Hello') }})
```

{% embed url="<https://codepen.io/pipui/pen/GRBbLOj>" %}
Пример работы кода выше
{% endembed %}

### Опции <a href="#options" id="options"></a>

```
// Выводить в консоль отладку
debug: false

// Текст подтверждения
text: ''

// Название подтверждения
title: ''

// Функция обратного вызова при нажатии на кнопку подтверждения
confirm: undefined

// Функция обратного вызова при нажатии на кнопку отмены. Не выполняется при
// срабатываении автозакрытия
cancel: undefined

// Местоположение появления подтверждения
placement: 'top-center'

// Отображать ли оверлей. Если хоть у одного открытого окна задан данный параметр,
// то оверлей будет отображаться до тех пор, пока такие подтверждения открыты
overlay: true

// Автозакрытие подтверждения. Если задано 0, то подтверждения
// не будет закрываться автоматически. По умолчанию 0.
autoclose: 0

// Класс открытого подтверждения
openedClass: 'confirm-active'

// Текст внутри кнопки подтверждения
confirmBtn: ''

// Текст внутри кнопки отмены
cancelBtn: ''

// Функция обратного вызова при начале открытия подтверждения
openCallback: undefined

// Функция обратного вызова при закрытияе открытия подтверждения
closeCallback: undefined

// Функция обратного вызова при окончании открытия подтверждения
openedCallback: undefined

// Функция обратного вызова при окончании закрытия подтверждения
closedCallback: undefined

// Настройки шаблонов
templates: {
	// Шаблон окна подтверждения
	confirm: '...'
}
```

### Методы <a href="#methods" id="methods"></a>

```javascript
let confirm = new PipUI.Confirm();

confirm.getID() // Вернет уникальный идентификатор подтверждения

confirm.setOptions(object) // Изменить опции подтверждения. DOM не будет изменен
// до вызова метода confirm.update()

confirm.getOptions() // Получить опции подтверждения

confirm.update() // Отрендерит окно заново

confirm.isOpen() // Открыто ли подтверждение

confirm.confirm() // Выполнить функцию подтверждения.
// Аналог нажатия на кнопку подтвердить

confirm.cancel() // Выполнить функцию отмены.
// Аналог нажатия на кнопку отменить.

confirm.close(callback) // Закрыть подтверждение. Дальнейшая работа с ним будет невозможна
// Параметр callback является приоритетной функцией обратного
// вызова при завершении закрытия, если она задана и через опции

confirm.open(callback) // Отобразить подтверждение
// Параметр callback является приоритетной функцией обратного
// вызова при завершении отображения, если она задана и через опции
```

| Триггер               | Описание                                          | Инициатор |
| --------------------- | ------------------------------------------------- | --------- |
| open-confirm-pipui    | Срабатывает при начале открытия подтверждения     | .modal    |
| opened-confirm-pipui  | Срабатывает при завершении открытия подтверждения | .modal    |
| close-confirm-pipui   | Срабатывает при начале закрытия подтверждения     | .modal    |
| closed-confirm-pipui  | Срабатывает при завершении закрытия подтверждения | .modal    |
| confirm-confirm-pipui | Срабатывает при подтверждающем действии           | .modal    |
| cancel-confirm-pipui  | Срабатывает при отмене                            | .modal    |

## Дополнительная информация <a href="#more-info" id="more-info"></a>

Положения появления подтверждения задаются в формате **{VERTICAL}-{HORIZONTAL}**

Поддерживаемые положения по вертикали: top, center, bottom

Поддерживаемые положения по горизонтали: left, center, right


# BB-коды

В составе фреймворка PipUI есть компонент с заготовленными стилями для BB-кодов. Всё что необходимо сделать, это выставить необходимую разметку или классы

Жирное начертание шрифта (теги <mark style="color:orange;">`[b][/b]`</mark>)

```html
<span class="bb-bold">Жирное начертание шрифта</span>
```

Наклонный текст (теги <mark style="color:orange;">`[i][/i]`</mark>)

```html
<span class="bb-italic">Наклонный текст</span>
```

Зачеркнутый текст (теги <mark style="color:orange;">`[s][/s]`</mark>)

```html
<span class="bb-strike">Зачеркнутый текст</span>
```

Подчеркнутый текст (теги <mark style="color:orange;">`[u][/u]`</mark>)

```html
<span class="bb-underline">Подчеркнутый текст</span>
```

Выравнивание по левому краю (теги <mark style="color:orange;">`[left][/left]`</mark>)

```html
<div class="bb-text-left">Выравнивание по левому краю</div> 
```

Выравнивание по правому краю (теги <mark style="color:orange;">`[right][/right]`</mark>)

```html
<div class="bb-text-right">Выравнивание по правому краю</div> 
```

Выравнивание по центру (теги <mark style="color:orange;">`[center][/center]`</mark>)

```html
<div class="bb-text-center">Выравнивание по центру</div> 
```

Горизонтальная линия (тег <mark style="color:orange;">`[line]`</mark>)

```html
<div class="bb-line"></div> 
```

Скрытый текст (теги <mark style="color:orange;">`[spoiler="Показать/Скрыть"][/spoiler]`</mark>)

```html
<div class="bb-spoiler">
    <a href="#" rel="nofollow" class="bb-spoiler-trigger" data-collapse="#collapse-trigger-1">Показать/Скрыть</a>
    <div class="bb-spoiler-text collapse" id="collapse-trigger-1">Скрытый текст!</div>
</div>
```

Изображение (теги <mark style="color:orange;">`[img]`</mark>`url`<mark style="color:orange;">`[/img]`</mark>)

```html
<img src="/Themes/Default/img/logo.svg" alt="IMG" class="bb-image" /> 
```

Цитата (теги <mark style="color:orange;">`[quote][/quote]`</mark>)

```html
<div class="bb-quote-wrapper">
    <div class="bb-quote">
        <div class="bb-quote-title">PipUI - 01.01.2019</div>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi, in.
    </div>
</div>
```

Вставка кода (теги <mark style="color:orange;">`[code][/code]`</mark>)

```html
<div class="bb-code">
    <div class="bb-code-language">Javascript</div>
    <div class="bb-code-text">alert('PipUI');</div>
</div>
```

Вставка **YouTube** проигрывателя (теги <mark style="color:orange;">`[youtube][/youtube]`</mark>)

```html
<div class="bb-youtube">
    <iframe width="510" height="287" src="https://www.youtube.com/embed/eY52Zsg-KVI" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
```


# Всплывающие подсказки

## Общая информация <a href="#general-information" id="general-information"></a>

Компонент всплывающих подсказок - это отличная альтернатива стандартным атрибутам title. Используйте атрибут <mark style="color:orange;">`data-tooltip`</mark> вместо стандартного *title*, для работы всплывающих подсказок.

Для направления отображаемой подсказки, используйте атрибут <mark style="color:orange;">`data-tooltip-direction`</mark>.\
В качестве значения можно передать одно из доступных значений: up, down, left, right.

Вы так же можете использовать альтернативный синтаксис объединив data-tooltip и\
data-tooltip-direction в один из следующих атрибутов: <mark style="color:orange;">`data-tooltip-up`</mark>,\ <mark style="color:orange;">`data-tooltip-down`</mark>, <mark style="color:orange;">`data-tooltip-left`</mark>, <mark style="color:orange;">`data-tooltip-right`</mark> соответственно.

```html
<a href="#" data-tooltip="Стандартная подсказка">По умолчанию</a> |
<a href="#" data-tooltip-left="Подсказка слева!">Слева</a> |
<a href="#" data-tooltip-up="Подсказка сверху!">Сверху</a> |
<a href="#" data-tooltip-down="Подсказка снизу!">Снизу</a> |
<a href="#" data-tooltip-right="Подсказка справа!">Справа</a> |
<a href="#" data-tooltip="Подсказка справа!" data-tooltip-direction="down">Справа</a>
```

{% embed url="<https://codepen.io/pipui/pen/gOjVQQN>" %}
Пример работы кода выше
{% endembed %}

## Javascript

По умолчанию подсказки инстализируются автоматически при наведении на соответствующий объект. Но вы можете произвести это действие и вручную, создав экземпляр класса <mark style="color:orange;">`PipUI.Tooltip`</mark>, который принимает 2 параметра:

1. Инициатор события (ссылка или объект)
2. Объект опций

### Инициализация подсказки <a href="#init" id="init"></a>

```html
<div id="tooltip-trigger">Tooltip!</div>

<script>
    let tooltip = new PipUI.Tooltip('#tooltip-trigger', {
        content: 'My tooltip message'
    })
</script>
```

### Опции <a href="#options" id="options"></a>

```
// Выводить в консоль отладку
debug: false

// Направление выводимой подсказки
direction: 'up'

// Содержимое подсказки. При инициализации через javascript можно использовать HTML
content: ''

// Шаблон подсказки
template: '<div class="tooltip"></div>'

// Класс, который присваивается подсказке при отображении и уберается при исчезании
showedClass: 'tooltip-active'

// Функция обратного вызова, которая срабатывает при появлении подсказки
showCallback: undefined

// Функция обратного вызова, которая срабатывает при исчезании подсказки
hideCallback: undefined

// Функция обратного вызова, которая срабатывает при обновлении подсказки
updateCallback: undefined

// Объект доступных направлений
directions: {...}
```

### Методы <a href="#methods" id="methods"></a>

```javascript
let tooltip = new PipUI.Dropdown();

tooltip.getID() // Вернет уникальный идентификатор подсказки

tooltip.setOptions(object) // Изменить опции подсказки. DOM не будет изменен
// до вызова метода tooltip.update()

tooltip.getOptions() // Получить опции подсказки

tooltip.update() // Отрендерит подсказку заново.
// По умолчанию производится при каждом появлении подсказки

tooltip.isOpen() // Отображена ли в текущий момент подсказка

tooltip.hide(callback) // Скрыть подсказку
// Параметр callback является приоритетной функцией обратного
// вызова при завершении скрытия, если она задана и через опции

tooltip.show(callback) // Отобразить подсказку
// Параметр callback является приоритетной функцией обратного
// вызова при завершении отображения, если она задана и через опции
```

### События

| Триггер              | Описание                                    | Инициатор |
| -------------------- | ------------------------------------------- | --------- |
| update-tooltip-pipui | Срабатывает при обновлении тултипа          | .tooltip  |
| show-tooltip-pipui   | Срабатывает при начале появления тултипа    | .tooltip  |
| hide-tooltip-pipui   | Срабатывает при начале исчезания тултипа    | .tooltip  |
| showed-tooltip-pipui | Срабатывает при окончании появления тултипа | .tooltip  |
| hided-tooltip-pipui  | Срабатывает при окончании исчезания тултипа | .tooltip  |


# Вкладки

## Общая информация <a href="#general-information" id="general-information"></a>

Компонент позволяют разделять контент на вкладки и переключаться по ним, как с помощью прямого обращения, так и через javascript. PipUI позволяет с легкостью реализовать данный подход, используя всего несколько строчек кода

```html
<div class="tabs">
    <ul class="tab-links">
        <li><a href="#" rel="nofollow" data-tabs-id="example-tab-1" class="tab-link active">Tab #1</a></li>
        <li><a href="#" rel="nofollow" data-tabs-id="example-tab-2" class="tab-link">Tab #2</a></li>
        <li><a href="#" rel="nofollow" data-tabs-id="example-tab-3" class="tab-link">Tab #3</a></li>
    </ul>

    <div class="tab-list">
        <div class="tab-id active" data-tabs-id="example-tab-1">
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam aperiam aut consectetur dicta ea eligendi esse
        </div>
        
        <div class="tab-id" data-tabs-id="example-tab-2">
            Lorem ipsum dolor sit amet, consectetur adipisicing elit.
        </div>
        
        <div class="tab-id" data-tabs-id="example-tab-3">
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Excepturi, voluptate?
        </div>
    </div>
</div>
```

{% embed url="<https://codepen.io/pipui/pen/rNZZyYa>" %}
Пример работы кода выше
{% endembed %}

Элемент с классом <mark style="color:orange;">`.tab-link`</mark> и атрибутом <mark style="color:orange;">`data-tabs-id`</mark> яаляется триггером переключения вкладки через javascript. Чтобы javascript не обрабатывал такие вкладки, достаточно убрать атрибут <mark style="color:orange;">`data-tabs-id`</mark>.

## Горизонтальные вкладки <a href="#horizontal-tabs" id="horizontal-tabs"></a>

Совместно с классом <mark style="color:orange;">`.tabs`</mark>, Вы можете использовать класс <mark style="color:orange;">`.tabs-horizontal`</mark>, который сделает вкладки и их содержимое горизонтальными.

## Javascript

Помимо HTML, Вы можете менять активность вкладок через javascript метод <mark style="color:orange;">`PipUI.Tabs.active`</mark>, принимающий 1 входящий параметр **element**, который является элементом содержимого вкладки. Данный метод возвращает true или false в зависимости от того, была ли переключена вкладка или нет.

```javascript
PipUI.Tabs.active(document.getElementById('example-tab-1'));
// Или
TabsComponent.active(document.getElementById('example-tab-1'));
```

{% hint style="info" %}
Свойство PipUI.Tabs является ссылкой на объект TabsComponent
{% endhint %}

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

```html
<div class="tabs tabs-horizontal">
    <ul class="tab-links bg-light-green-i">
        <li><a href="#" rel="nofollow" data-tabs-id="example-tab-7" class="tab-link active">Tab #1</a></li>
        <li><a href="#" rel="nofollow" data-tabs-id="example-tab-8" class="tab-link">Tab #2</a></li>
        <li><a href="#" rel="nofollow" data-tabs-id="example-tab-9" class="tab-link">Tab #3</a></li>
    </ul>

    <div class="tab-list bg-gray-200">
        <div class="tab-id active" data-tabs-id="example-tab-7">
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam aperiam aut consectetur dicta ea eligendi esse, magnam minima, odio perferendis quia saepe totam vitae. Eius facere magnam omnis provident vero.
            <div class="text-center pt-20">
                <button class="btn" onclick="PipUI.toggleClass(document.querySelector('.tabs'), 'tabs-horizontal');">Переключить расположение</button>
            </div>
        </div>
        <div class="tab-id" data-tabs-id="example-tab-8">
            Lorem ipsum dolor sit amet, consectetur adipisicing elit.
        </div>
        <div class="tab-id" data-tabs-id="example-tab-9">
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Excepturi, voluptate?
        </div>
    </div>
</div>
```

{% embed url="<https://codepen.io/pipui/pen/abaaJLN>" %}
Пример работы кода выше
{% endembed %}

### Опции <a href="#default-settings" id="default-settings"></a>

```javascript
PipUI.Tabs.debug = false; // Вывод дебага в консоль браузера
```

### Методы <a href="#animation-control" id="animation-control"></a>

```javascript
PipUI.Tabs.active(element); // Активировать вкладку
// Параметр element является элементом вкладки
```

### События

| Триггер         | Описание                         | Инициатор |
| --------------- | -------------------------------- | --------- |
| hide-tabs-pipui | Срабатывает при закрытии вкладки | .tab-id   |
| show-tabs-pipui | Срабатывает при открытии         | .tab-id   |


# Хлебные крошки

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

```html
<div class="breadcrumbs">
    <a class="bc-item" href="http://pipui.loc/">PipUI</a>
    <a class="bc-item" href="http://pipui.loc/docs/">Документация</a>
    <a class="bc-item" href="http://pipui.loc/docs/components/">Компоненты</a>
    <a class="bc-item disabled preventDefault" href="http://pipui.loc/docs/components/breadcrumbs/">Хлебные крошки</a>
</div>
```

{% embed url="<https://codepen.io/pipui/pen/QWVBZrK>" %}
Пример работы кода выше
{% endembed %}


# Спойлеры

## Общая информация <a href="#general-information" id="general-information"></a>

Вы можете скрывать содержимое с помощью спойлеров.

```html
<a href="#" rel="nofollow" data-collapse="#collapse-trigger-1">Показать/Скрыть</a>

<div class="collapse" id="collapse-trigger-1">
    Hidden text
</div>

<a href="#" class="collapse-active" rel="nofollow" data-collapse="#collapse-trigger-2">Показать/Скрыть</a>

<div class="collapse collapse-active" id="collapse-trigger-2">
    Hidden text
</div>
```

{% embed url="<https://codepen.io/pipui/pen/BaPqWYz>" %}
Пример работы кода выше
{% endembed %}

Для определения триггера, необходимо добавить атрибут <mark style="color:orange;">`data-collapse`</mark> и передать в него ссылку на элемент, который необходимо открыть или закрыть.

По умолчанию элементы являются неактивными и закрытыми, чтобы это изменить, добавьте триггеру и блоку класс <mark style="color:orange;">`.collapse-active`</mark>.

## Аккордеон <a href="#accordion" id="accordion"></a>

Для создания зависимых спойлеров, разметка отличается и является более сложной, чем обычные спойлеры.

```html
<div class="accordion">
    <div class="accordion-id active">
        <a href="#" class="accordion-trigger" data-accordion="#accordion-item-1">
            Accordeon #1
            <i class="accordion-trigger-icon"><i class="fa-solid fa-angle-down"></i></i>
        </a>
        <div class="accordion-target" id="accordion-item-1">
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci, voluptates.
        </div>
    </div>

    <div class="accordion-id">
        <a href="#" class="accordion-trigger" data-accordion="#accordion-item-2">
            Accordeon #2
            <i class="accordion-trigger-icon"><i class="fa-solid fa-angle-down"></i></i>
        </a>
        <div class="accordion-target" id="accordion-item-2">
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci, voluptates.
        </div>
    </div>

    <div class="accordion-id">
        <a href="#" class="accordion-trigger" data-accordion="#accordion-item-3">
            Accordeon #3
            <i class="accordion-trigger-icon"><i class="fa-solid fa-angle-down"></i></i>
        </a>
        <div class="accordion-target" id="accordion-item-3">
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci, voluptates.
        </div>
    </div>
</div>
```

{% embed url="<https://codepen.io/pipui/pen/ExpdmLx>" %}
Пример работы кода выше
{% endembed %}

Для триггеров аккордеона, необходимо задать атрибут <mark style="color:orange;">`data-accordion`</mark> и передать в него ссылку на элемент.

## Javascript

Вы можете управлять спойлерами и аккордеонами через javascript. По умолчанию инициализация элементов производится автоматически при клике на триггер, а экземпляры классов хранятся компонентом PipUI.Storage (collapse), но их можно инициализировать и вручную с помощью класса PipUI.Collapse.

### Инициализация <a href="#init" id="init"></a>

Для инициализации меню вручную, необходимо создать экземпляр класса PipUI.Collapse. Конструктор данного класса поддерживает 2 параметра: HTMLElement и Object.

```html
<a class="btn" href="#collapse-target1" rel="nofollow" id="collapse-trigger1">Показать/Скрыть</a>

<div class="collapse" id="collapse-target1">
    Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</div>

<script>
    let collapse1 = new PipUI.Collapse('#collapse-target1', {
        triggers: ['#collapse-trigger1']
    });
</script>
```

{% embed url="<https://codepen.io/pipui/pen/qByJjrj>" %}
Пример работы кода выше
{% endembed %}

Первый параметр - объект или строка ссылающаяся на элемент.&#x20;

Второй параметр - объект опций.

### Опции <a href="#options" id="options"></a>

```
// Выводить в консоль отладку
debug: false,

// Массив триггеров
triggers: [],

// Настройки анимаций
animation: {
	// Анимация появляения
	show: {
		// Тип анимации
		type: 'slideDown'
		
		// Скорость анимации в миллисекундах
		duration: 200
	}
	
	// Анимация исчезания
	hide: {
		// Тип анимации
		type: 'slideUp'
		
		// Скорость анимации в миллисекундах
		duration: 200
	}
}

// Спойлер является аккордеоном
accordion: false,

// Сделать видимым по умолчанию
defaultVisible: false,

// Класс открытого блока
toggleTargetClass: 'collapse-active',

// Класс активного триггера
toggleTriggerClass: 'active',

// Функция обратного вызова при начале появления
showStartCallback: undefined,

// Функция обратного вызова при начале исчезания
hideStartCallback: undefined,

// Функция обратного вызова при окончании появления
showEndCallback: undefined,

// Функция обратного вызова при окончании исчезания
hideEndCallback: undefined
```

### Методы <a href="#methods" id="methods"></a>

```javascript
let collapse = new PipUI.Collapse('#collapse');

collapse.getID() // Вернет уникальный идентификатор спойлера

collapse.setOptions(object) // Изменить опции спойлера

collapse.getOptions() // Получить опции спойлера

collapse.toggle(callback) // Скрыть или отобразить содержимое спойлера
// Параметр callback является приоритетной функцией обратного
// вызова при завершении скрытия, если она задана и через опции

collapse.hide(callback) // Скрыть содержимое спойлера
// Параметр callback является приоритетной функцией обратного
// вызова при завершении скрытия, если она задана и через опции

collapse.show(callback) // Показать содержимое спойлера
// Параметр callback является приоритетной функцией обратного
// вызова при завершении отображения, если она задана и через опции

collapse.update() // Обновить содержимое

collapse.isOpen() // Текущее состояние спойлера
```


# Галерея

## Общая информация <a href="#general-information" id="general-information"></a>

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

Для работы достаточно создать контейнер и подключить его в экземпляре класса <mark style="color:orange;">`PipUI.Gallery`</mark> , как это показано ниже

```html
<div id="gallery1"></div>

<script>let gallery1 = new PipUI.Gallery('#gallery1', {});</script>
```

Экземпляр класса PipUI.Gallery принимает 2 аргумента

1. Элемент контейнера, где будет образована галерея
2. Объект  опций

{% hint style="info" %}
Чтобы загрузить список изображений, необходимо во втором параметре передать массив **images**.
{% endhint %}

Все элементы массива должны быть переданы в виде объектов. Каждый такой объект может содержать в себе следующие ключи

1. title - Название изображения
2. text - Описание
3. thumb - Превью, выводимое в списке изображений
4. large - Основное изображение, выводимое в контейнере
5. original - Оригинал изображения, который открывается при нажатии на основное изображение

{% embed url="<https://codepen.io/pipui/pen/ZEMqVBV>" %}
Пример работы галереи
{% endembed %}

## Javascript

Так как компонент галереи может работать исключительно через Javascript, то все настройки, за исключением стилей, можно произвести только через него.

### Опции <a href="#options" id="options"></a>

```javascript
// Выводить в консоль отладку
debug: false

// Массив изображений
images: []

// Разрешить двигать меню превью
scroll: true

// Функция обратного вызова при запуске изменения изображения
changeCallback: undefined

// Функция обратного вызова при завершении изменения изображения
changedCallback: undefined

// Функция обратного вызова при обновлении
updateCallback: undefined

// Функция обратного вызова при добавлении изображения в конец
pushCallback: undefined

// Функция обратного вызова при добавлении изображения в начало
unshiftCallback: undefined

// Использовать компонент изображений
useImage: false

// Выбранное по умолчанию изображение
active: 0

// Шаблоны верстки
templates: {
    // Враппер галереи
    wrapper: '...',
    
    // Элемент изображения
    image: ''
}
```

### Методы <a href="#methods" id="methods"></a>

```javascript
let gallery = new PipUI.Gallery('#gallery');

gallery.getID() // Вернет уникальный идентификатор галереи

gallery.setOptions(object) // Изменить опции галереи

gallery.getOptions() // Получить опции галереи

gallery.updateImages() // Обновить изображения

gallery.push(object) // Добавить изображение в конец

gallery.unshift(object) // Добавить изображение в начало

gallery.updateScroll() // Обновить позицию списка превью

gallery.active(index) // Сделать выбранное изображение активным

gallery.update() // Обновить содержимое
```

### События

| Триггер                     | Описание                                        | Инициатор |
| --------------------------- | ----------------------------------------------- | --------- |
| change-gallery-pipui        | Срабатывает при начале изменения изображения    | .gallery  |
| changed-gallery-pipui       | Срабатывает по окончанию изменения изображения  | .gallery  |
| update-gallery-pipui        | Срабатывает при обновлении содержимого          | .gallery  |
| update-images-gallery-pipui | Срабатывает при обновлении списка изображений   | .gallery  |
| push-gallery-pipui          | Срабатывает при добавлении изображения в конец  | .gallery  |
| unshift-gallery-pipui       | Срабатывает при добавлении изображения в начало | .gallery  |
| update-scroll-gallery-pipui | Срабатывает при обновлении позиции скрола       | .gallery  |


# Изображения

## Общая информация <a href="#general-information" id="general-information"></a>

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

Для работы компонента достаточно задать атрибут <mark style="color:orange;">`data-image`</mark> и указать в нем путь до открываемого изображения.

```html
<img src="https://cdn.pipui.ru/media/images/image/0001-small.png" alt="PIC" data-image="https://cdn.pipui.ru/media/images/image/0001.png">
<img src="https://cdn.pipui.ru/media/images/image/0002-small.png" alt="PIC" data-image="https://cdn.pipui.ru/media/images/image/0002.png">
<img src="https://cdn.pipui.ru/media/images/image/0003-small.png" alt="PIC" data-image="https://cdn.pipui.ru/media/images/image/0003.png">
<img src="https://cdn.pipui.ru/media/images/image/0004-small.png" alt="PIC" data-image="https://cdn.pipui.ru/media/images/image/0004.png">
<img src="https://cdn.pipui.ru/media/images/image/0005-small.png" alt="PIC" data-image="https://cdn.pipui.ru/media/images/image/0005.png">
<img src="https://cdn.pipui.ru/media/images/image/0006-small.png" alt="PIC" data-image="https://cdn.pipui.ru/media/images/image/0006.png">
```

{% embed url="<https://codepen.io/pipui/pen/MWqPLeW>" %}
Пример работы кода выше
{% endembed %}

Чтобы разделить изображения на группы, необходимо определить атрибут\ <mark style="color:orange;">`data-image-group`</mark> а в качестве значения указать имя общей группы.

{% hint style="info" %}
Имя группы может быть любым для каждой из групп, но мы рекомендуем использовать осмысленные имена.
{% endhint %}

```html
<!-- group 1 -->
<img src="https://cdn.pipui.ru/media/images/image/0001-small.png" alt="PIC" data-image-group="group1" data-image="https://cdn.pipui.ru/media/images/image/0001.png">
<img src="https://cdn.pipui.ru/media/images/image/0002-small.png" alt="PIC" data-image-group="group1" data-image="https://cdn.pipui.ru/media/images/image/0002.png">
<img src="https://cdn.pipui.ru/media/images/image/0003-small.png" alt="PIC" data-image-group="group1" data-image="https://cdn.pipui.ru/media/images/image/0003.png">
<img src="https://cdn.pipui.ru/media/images/image/0004-small.png" alt="PIC" data-image-group="group1" data-image="https://cdn.pipui.ru/media/images/image/0004.png">
<img src="https://cdn.pipui.ru/media/images/image/0005-small.png" alt="PIC" data-image-group="group1" data-image="https://cdn.pipui.ru/media/images/image/0005.png">
<img src="https://cdn.pipui.ru/media/images/image/0006-small.png" alt="PIC" data-image-group="group1" data-image="https://cdn.pipui.ru/media/images/image/0006.png">

<!-- group 2 -->
<img src="https://cdn.pipui.ru/media/images/image/0007-small.png" alt="PIC" data-image-group="group2" data-image="https://cdn.pipui.ru/media/images/image/0007.png">
<img src="https://cdn.pipui.ru/media/images/image/0008-small.png" alt="PIC" data-image-group="group2" data-image="https://cdn.pipui.ru/media/images/image/0008.png">
<img src="https://cdn.pipui.ru/media/images/image/0009-small.png" alt="PIC" data-image-group="group2" data-image="https://cdn.pipui.ru/media/images/image/0009.png">
<img src="https://cdn.pipui.ru/media/images/image/0010-small.png" alt="PIC" data-image-group="group2" data-image="https://cdn.pipui.ru/media/images/image/0010.png">
```

{% embed url="<https://codepen.io/pipui/pen/zYJmeZK>" %}
Пример работы кода выше
{% endembed %}

## Javascript

Вы можете управлять изображениями с помощью класса PipUI.Image. Методы и свойства данного класса являются статическими.

### Свойства <a href="#options" id="options"></a>

```
// Выводить в консоль отладку
debug: false,

// Функция обратного вызова, срабатываемая при открытии модального окна
openCallback: undefined

// Функция обратного вызова, срабатываемая при закрытии модального окна
closeCallback: undefined

// Функция обратного вызова, срабатываемая при открытии следующего изображения
nextCallback: undefined

// Функция обратного вызова, срабатываемая при открытии предыдущего изображения
prevCallback: undefined

// Шаблоны
templates: {
        // Шаблон модального окна
        modal: ''
}
```

### Методы <a href="#methods" id="methods"></a>

```javascript
PipUI.Image.getID() // Вернет уникальный идентификатор

PipUI.Image.setOptions(object) // Изменить опции

PipUI.Image.getOptions() // Получить опции

PipUI.Image.open(url, options) // Открыть изображение с указанными опциями

PipUI.Image.close() // Закрыть открытое изображение

PipUI.Image.prev() // Переключить на предыдущее изображение

PipUI.Image.next() // Переключить на следующее изображение
```


# Таблицы

В PipUI есть готовые стили для таблиц, а так же их адаптивная версия под разные разрешения экранов.

```html
<div class="table">
    <div class="table-row">
        <div class="table-cell">1</div>
        <div class="table-cell">PipUI Alpha</div>
        <div class="table-cell">1.0.0</div>
    </div>

    <div class="table-row">
        <div class="table-cell">2</div>
        <div class="table-cell">PipUI Beta</div>
        <div class="table-cell">1.0.0RC-2</div>
    </div>
</div>
```

{% embed url="<https://codepen.io/pipui/pen/KKBamBW>" %}
Пример работы кода выше
{% endembed %}

Для адаптивной таблицы, потребуется дополнительно указать класс <mark style="color:orange;">`.table-responsive`</mark> к классу <mark style="color:orange;">`.table`</mark> и продублировать элементы названий шапки с классом <mark style="color:orange;">`.table-cell-resp`</mark>

```html
<div class="table table-responsive">
    <div class="table-header">
        <div class="table-row">
            <div class="table-cell-resp">#</div>
            <div class="table-cell">#</div>
            <div class="table-cell-resp">Наименование</div>
            <div class="table-cell">Наименование</div>
            <div class="table-cell-resp">Версия</div>
            <div class="table-cell">Версия</div>
        </div>
    </div>

    <div class="table-body">
        <div class="table-row">
            <div class="table-cell-resp">#</div>
            <div class="table-cell">1</div>
            <div class="table-cell-resp">Наименование</div>
            <div class="table-cell">PipUI Alpha</div>
            <div class="table-cell-resp">Версия</div>
            <div class="table-cell">1.0.0</div>
        </div>

        <div class="table-row">
            <div class="table-cell-resp">#</div>
            <div class="table-cell">2</div>
            <div class="table-cell-resp">Наименование</div>
            <div class="table-cell">PipUI Beta</div>
            <div class="table-cell-resp">Версия</div>
            <div class="table-cell">1.0.0RC-2</div>
        </div>
    </div>
</div>
```

Если Вам необходимо зафиксировать ширину каждого столбца, используйте класс <mark style="color:orange;">`.table-fixed`</mark> или если потребуется сделать каждый ряд подсвечиваемым при наведении, добавьте класс <mark style="color:orange;">`.table-hover`</mark> к классу <mark style="color:orange;">`.table`</mark>

```
<div class="table table-fixed table-hover">
    <div class="table-header">
        <div class="table-row">
            <div class="table-cell-resp">#</div>
            <div class="table-cell">#</div>
            <div class="table-cell-resp">Наименование</div>
            <div class="table-cell">Наименование</div>
            <div class="table-cell-resp">Версия</div>
            <div class="table-cell">Версия</div>
        </div>
    </div>

    <div class="table-row">
        <div class="table-cell">1</div>
        <div class="table-cell">PipUI Alpha</div>
        <div class="table-cell">1.0.0</div>
    </div>

    <div class="table-row">
        <div class="table-cell">2</div>
        <div class="table-cell">PipUI Beta</div>
        <div class="table-cell">1.0.0RC-2</div>
    </div>

    <div class="table-row">
        <div class="table-cell">3</div>
        <div class="table-cell">PipUI</div>
        <div class="table-cell">1.0.0</div>
    </div>

    <div class="table-row">
        <div class="table-cell">4</div>
        <div class="table-cell">PipUI</div>
        <div class="table-cell">2.0.0</div>
    </div>
</div>
```


# Панель BB-кодов

## Общая информация <a href="#general-information" id="general-information"></a>

Панель управления BB-кодов помогает производить быструю подстановку кодов в форму ввода. Инсталлизировать её можно с помощью добавления класса <mark style="color:orange;">`.bbpanel`</mark> к <mark style="color:orange;">`textarea`</mark> или напрямую через Javascript.

{% hint style="warning" %}
После инсталлизации textarea будет помещена в контейнер с классом <mark style="color:orange;">`.bbpanel`</mark>, а у формы этот класс будет заменен на <mark style="color:orange;">`.bbpanel-form`</mark>
{% endhint %}

### Разметка

```html
<textarea class="bbpanel"></textarea>
```

{% embed url="<https://codepen.io/pipui/pen/GRYgQVX>" %}
Пример работы кода выше
{% endembed %}

## Javascript

Данная панель полностью зависит от Javascript, по этому без его поддержки она работать не будет. По умолчанию инсталлизация происходит благодаря триггеру .bbpanel в форме, но вы можете произвести инсталлизацию и вручную с помощью создания экземпляра\
класса <mark style="color:orange;">`PipUI.BBPanel(...)`</mark>

### Инициализация

```html
<textarea class="input" id="myform"></textarea>

<script>
    let panel = new PipUI.BBPanel('#myform');
</script>
```

{% embed url="<https://codepen.io/pipui/pen/dygPmod>" %}
Пример работы кода выше
{% endembed %}

Конструктор данного класса поддерживает 2 параметра: HTMLElement и Object

Первый параметр - объект или строка ссылающаяся на элемент.

Второй параметр - объект опций

### Опции

```
// Выводить в консоль отладку
debug: false

// Класс, добавляемый форме ввода при выводе панели
focusClass: 'focus'

// Класс, заменяемый класс .bbpanel в форме
formClass: 'bbpanel-form'

// Настройки появляющейся панели при выделении текста
popup: {
	// Включено или выключено
	enable: true
	
	// Теги, выводимые в данной панели
	format: 'b,i,u,s,|,left,center,right,|,urlAlt'
	
	// Шаблон данной панели
	template: '<div class="popup-list"></div>'
	
	// Класс, добавляемый данной панели при выводе её на экран
	activeClass: 'popup-active'
}

// Отображать стилизованные подсказки при наведении на BB-коды в панели
tooltip: true

// Функция обратного вызова срабатываемая при отображении панели
showCallback: undefined,

// Функция обратного вызова срабатываемая при скрытии панели
hideCallback: undefined

// Функция обратного вызова срабатываемая при вызове обращения к коду
callcodeCallback: undefined

// Функция обратного вызова срабатываемая при работе функции UNDO	
undoCallback: undefined

// Функция обратного вызова срабатываемая при работе функции REDO
redoCallback: undefined

// Функция обратного вызова срабатываемая при изменении панели
changeCallback: undefined

// Теги выводимые в панели BB-кодов
format: 'undo,|,redo,|,b,i,u,s,|,left,center,right,|,size,color,|,spoiler,quote,code,|,img,youtube,|,urlAlt,line,|,hide'

// Максимальный размер истории запоминаемый при использовании Undo/Redo
maxHistory: 64

// Настройки кодов панели. Вы можете добавлять собственные коды или изменять существующие
// Каждый элемент должен быть стилизован на подобии остальных.
codes: {...}

// Настройки шаблонов панели
templates: {}
```

### Методы

```javascript
let bbpanel = new PipUI.BBPanel('#myform');

bbpanel.getID() // Вернет уникальный идентификатор панели

bbpanel.setOptions(object) // Изменить опции панели

bbpanel.getOptions() // Получить опции панели

bbpanel.hide(callback) // Скрыть панель
// Параметр callback является приоритетной функцией обратного
// вызова при завершении скрытия, если она задана и через опции

bbpanel.show(callback) // Показать блок
// Параметр callback является приоритетной функцией обратного
// вызова при завершении отображения, если она задана и через опции

bbpanel.callCode(key, callback) // Вызвать указанный код
// Параметр callback является приоритетной функцией обратного
// вызова при вызове кода, если она задана и через опции

bbpanel.change(callback) // Обновить содержимое панели
// Параметр callback является приоритетной функцией обратного
// вызова при обновлении панели, если она задана и через опции

bbpanel.undo(callback) // Вызвать функцию undo
// Параметр callback является приоритетной функцией обратного
// вызова при шаге назад, если она задана и через опции

bbpanel.redo(callback) // Вызвать функцию redo
// Параметр callback является приоритетной функцией обратного
// вызова при шаге вперёд, если она задана и через опции

bbpanel.isOpen() // Текущее состояние панели
```

### События

| Триггер                | Описание                                          | Инициатор     |
| ---------------------- | ------------------------------------------------- | ------------- |
| hide-bbpanel-pipui     | Срабатывает при скрытии панели BB-кодов           | .bbpanel-form |
| show-bbpanel-pipui     | Срабатывает при отображении панели BB-кодов       | .bbpanel-form |
| change-bbpanel-pipui   | Срабатывает при изменении панели                  | .bbpanel-form |
| callcode-bbpanel-pipui | Срабатывает при вызове какого-либо кода из панели | .bbpanel-form |
| undo-bbpanel-pipui     | Срабатывает при вызове функции шага назад         | .bbpanel-form |
| redo-bbpanel-pipui     | Срабатывает при вызове функции шага вперёд        | .bbpanel-form |


# Валидаторы форм

## Общая информация

Очень часто перед отправкой формы, требуется произвести ее проверку. Фреймворк PipUI даёт такую возможность.

Для работы компонента, необходимо задать элементам формы атрибут <mark style="color:orange;">`data-validator`</mark>. Все эти элементы должна находится внутри контейнера <mark style="color:orange;">`.input-block`</mark>, которые в свою очередь должны быть внутри <mark style="color:orange;">`form`</mark>.

### Разметка <a href="#markup" id="markup"></a>

```html
<form novalidate>
        <div class="input-block">
            <input type="text" data-validator placeholder=".input:required" required class="input">
        </div>

        <div class="input-block pt-20">
            <input type="text" data-validator placeholder=".input[pattern='^[a-z0-9]+']" pattern="^[a-z0-9]+$" class="input">
        </div>

        <div class="pt-20"><button type="submit" class="btn">Send</button></div>
</form>
```

{% embed url="<https://codepen.io/pipui/pen/MWPYBQJ>" %}
Пример работы кода выше
{% endembed %}

Вы можете управлять стилем появляющейся подсказки с помощью атрибута\ <mark style="color:orange;">`[data-validator-type]`</mark>, который может принимать любые значения.\
Атрибут <mark style="color:orange;">`[data-validator-text]`</mark> принимает в качестве значения текст, который будет выводится в оповещении в случает некорректного заполнения поля.

## Javascript

Вы можете произвести инстализацию вручную. Каждый элемент инстализируется отдельно.&#x20;

### Инициализация <a href="#init" id="init"></a>

Для этого вам необходимо создать экземпляр класса <mark style="color:orange;">`PipUI.Validator`</mark> и передать в него селектор элемента формы.

Второй параметр данного класса отвечает за объект опций.

```html
<div class="navbar" id="navbar">...</div>

<script>
    let validator = new PipUI.Validator('#navbar');
</script>
```

### Опции <a href="#options" id="options"></a>

```
// Выводить в консоль отладку
debug: false

// Текст, выводимый валидатором в случае ошибки
text: ''

// Значение атрибута data-validator-type для стилизации
type: 'default'

// Функция обратного вызова, выполняемая при обнаружении ошибки валидации формы
invalidCallback: undefined

// Шаблоны валидатора
templates: {...}
```

### Методы <a href="#methods" id="methods"></a>

```javascript
let validator = new PipUI.Validator('#myform');

validator.getID() // Вернет уникальный идентификатор панели

validator.setOptions(object) // Изменить опции панели

validator.getOptions() // Получить опции панели

validator.isValid() // Проверить валидна ли форма

// Произвести полную проверку валидности формы с учетом вывода сообщения
// Параметр callback является приоритетной функцией, если аналогичная задана через
// опцию invalidCallback
validator.validate(callback)
```

### События

| Триггер                  | Описание                               | Инициатор         |
| ------------------------ | -------------------------------------- | ----------------- |
| validate-validator-pipui | Срабатывает при полной валидации формы | \[data-validator] |


# Всплывающие блоки

## Общая информация

Если есть необходимость использовать HTML во всплывающих подсказках([tooltip](/components/tooltip)), то вам могут помочь всплывающие блоки.

### Разметка <a href="#markup" id="markup"></a>

```html
<div id="popup" class="popup">
    <div class="popup-title">Header</div>
    <div class="popup-content">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quasi, sit?</div>
</div>
<button type="button" class="btn" data-popup="#popup">Example</button>
```

{% embed url="<https://codepen.io/pipui/pen/GRYJmVd>" %}
Пример работы кода выше
{% endembed %}

## Поддерживаемые атрибуты

Атрибут <mark style="color:orange;">`data-popup`</mark> является инициатором события вызова всплывающего блока. Данный атрибут может принимать в качестве значения селектор на объект всплывающего блока.

### title & content

Вы так же можете обойтись без дополнительного блока и указать название и описание через атрибуты <mark style="color:orange;">`data-popup-title`</mark> и <mark style="color:orange;">`data-popup-content`</mark>, однако в таком случае HTML поддерживаться не будет, но и потребность в указании атрибута data-popup отпадёт.

```html
<button type="button" class="btn" data-popup data-popup-content="Простейший всплывающий блок созданный через атрибуты" data-popup-title="Заголовок">Example #1</button>
```

{% embed url="<https://codepen.io/pipui/pen/LYgVqyp>" %}
Пример работы кода выше
{% endembed %}

Значения атрибутов <mark style="color:orange;">`data-popup-title`</mark> и <mark style="color:orange;">`data-popup-content`</mark> не являются обязательными, так же как и их аналог через отдельную HTML разметку <mark style="color:orange;">`.popup-title`</mark> и <mark style="color:orange;">`.popup-content`</mark>.

### target

С помощью атрибута <mark style="color:orange;">`data-popup-target`</mark> можно указать селектор элемента к которому будет привязан всплывающий блок.

```html
<span id="target1">Target #1</span>
  
<button type="button" class="btn mt-100" data-popup data-popup-target="#target1" data-popup-content="Всплывающий блок с привязкой к другому объекту" data-popup-title="Заголовок">Example #4</button>
```

{% embed url="<https://codepen.io/pipui/pen/gOBpqzG>" %}
Пример работы кода выше
{% endembed %}

### overlay

Атрибут <mark style="color:orange;">`data-popup-overlay="true"`</mark> включает затемнение фона при появлении всплывающего блока. По умолчанию данная функция отключена.

```html
<button type="button" class="btn" data-popup data-popup-overlay="true" data-popup-content="Всплывающий блок с затемнением" data-popup-title="Заголовок">Example #5</button>
```

{% embed url="<https://codepen.io/pipui/pen/PoyqLOX>" %}
Пример работы кода выше
{% endembed %}

### autoclose

В качестве значение атрибута <mark style="color:orange;">`data-popup-autoclose`</mark> принимается целое число - кол-во миллисекунд, по истечению которых всплывающий блок будет автоматически закрыт.

По умолчанию автозакрытие имеет значение 0, что будет означать отсутствие автоматического закрытия.

```html
<button type="button" class="btn" data-popup data-popup-autoclose="3000" data-popup-content="Всплывающий блок с затемнением" data-popup-title="Заголовок">Example</button>
```

{% embed url="<https://codepen.io/pipui/pen/poxJYYb>" %}
Пример работы кода выше
{% endembed %}

### overclose

Атрибут <mark style="color:orange;">`data-popup-overclose`</mark> включает или отключает закрытие всплывающего блока при нажатии на область, которая не является самим блоком.

По умолчанию данный атрибут имеет значение true.

```html
<button type="button" class="btn" data-popup data-popup-overclose="true" data-popup-content="Всплывающий блок с закрытием" data-popup-title="Заголовок">[data-popup-overclose="true"]</button>
  
  <button type="button" class="btn" data-popup data-popup-overclose="false" data-popup-content="Всплывающий блок без закрытия" data-popup-title="Заголовок">[data-popup-overclose="false"]</button>
```

{% embed url="<https://codepen.io/pipui/pen/mdzJogv>" %}
Пример работы кода выше
{% endembed %}

### direction

По умолчанию направление вывода всплывающего блока установлено как вверх (up) и меняется в зависимости от доступности области, однако вы можете поменять значение по умолчанию на своё с помощью атрибута <mark style="color:orange;">`data-popup-direction`</mark>, однако блок по прежнему будет проверять доступность выбранного направления или искать другое.

На данный момент доступны следующие направления

* **up** - вверх (по умолчанию)
* **down** - вниз
* **left** - влево
* **right** - вправо

```html
<button type="button" class="btn" data-popup data-popup-content="Блок будет выведен сверху" data-popup-title="Вверх">[data-popup-direction="up"]</button>
    <button type="button" class="btn" data-popup data-popup-direction="down" data-popup-content="Блок будет выведен снизу" data-popup-title="Вверх">[data-popup-direction="down"]</button>
    <button type="button" class="btn" data-popup data-popup-direction="left" data-popup-content="Блок будет выведен слева" data-popup-title="Вверх">[data-popup-direction="left"]</button>
    <button type="button" class="btn" data-popup data-popup-direction="right" data-popup-content="Блок будет выведен справа" data-popup-title="Вверх">[data-popup-direction="right"]</button>
```

{% embed url="<https://codepen.io/pipui/pen/NWOqmNx>" %}
Пример работы кода выше
{% endembed %}

## Javascript

Для работы с всплывающими блоками необходимо создать экземпляр класса PipUI.Popup.\
По умолчанию инициализация происходит автоматически при клике на элемент\
с атрибутом \[data-popup].

### Инициализация

Конструктор класса PipUI.Popup принимает 2 параметра: HTMLElement и Object

Первый параметр - селектор объекта самого блока всплывающего окна. Может быть пустым.

Второй параметр - объект опций

```javascript
let popup = new PipUI.Popup('#popup-box');
```

### Опции

<pre><code>// Выводить в консоль отладку
debug: false

// Селектор или HTMLElement к которому будет привязан всплывающий блок
target: undefined

// Список триггеров, при нажатии на которые будет появляться/исчезать блок
triggers: []

<strong>// Название, выводимое в всплывающем блоке. Если не указано, то появится без названия.
</strong>title: ''

// Содержимое, выводимое в всплывающем блоке. Если не указано, то появится без содержимого.
content: ''

// Направление вывода. Поддерживаются: up, down, left, right
direction: 'up'

// Выводить ли оверлей
overlay: false

// Кол-во миллисекунд, через которое блок автоматически закроется
autoclose: 0

// Закрывать всплывающий блок при клике на область вне самого блока
overclose: true

// Класс присваиваемый всплывающему блоку при открытии
openedClass: 'popup-active'

// Класс присваиваемый оверлею при открытии
openedOverlayClass: 'overlay-active'

// Класс присваиваемый триггеру при открытии
openedTriggerClass: 'active'

// Класс элемента к которому привязан всплывающий блок
targetClass: 'popup-target'

// Класс, присваиваемый элементу к которому привязан всплывающий блок, при открытии
targetActiveClass: 'popup-target-active'

// Функция обратного вызова срабатываемая при появлении всплывающего блока
openCallback: undefined

// Функция обратного вызова срабатываемая при исчезании всплывающего блока
closeCallback: undefined

// Функция обратного вызова срабатываемая при обновлении всплывающего блока
updateCallback: undefined

// Функция обратного вызова срабатываемая при изменении позиции всплывающего блока
repositionCallback: undefined

// Шаблоны
templates: {
     // Разметка основного блока всплывающего окна
     box: '...'
     
     // Разметка блока оверлея
     overlay: '...'
}
</code></pre>

### Методы

```javascript
let popup = new PipUI.Navbar('#popup');

popup.getID() // Вернет уникальный идентификатор всплывающего блока

popup.setOptions(object) // Изменить опции блока

popup.getOptions() // Получить опции блока

popup.getPosition(name) // Получить актуальную позицию блока(служит для обновления)
// Параметр name является направлением позиции

popup.updatePosition() // Обновить позицию всплывающего блока

popup.update() // Обновить всплывающее окно

popup.hide(callback) // Скрыть панель
// Параметр callback является приоритетной функцией обратного
// вызова при завершении скрытия, если она задана и через опции

popup.show(callback) // Показать блок
// Параметр callback является приоритетной функцией обратного
// вызова при завершении отображения, если она задана и через опции

popup.isOpen() // Текущее состояние блока (открыт или закрыт)

popup.open(callback) // Отобразить блок
// Параметр callback является приоритетной функцией обратного
// вызова при завершении отображения, если она задана и через опции

popup.close(callback) // Скрыть блок
// Параметр callback является приоритетной функцией обратного
// вызова при завершении скрытия, если она задана и через опции
```

### События

<table><thead><tr><th width="281.3333333333333">Триггер</th><th>Описание</th><th>Инициатор</th></tr></thead><tbody><tr><td>open-popup-pipui</td><td>Срабатывает при открытии всплывающего блока</td><td>.popup</td></tr><tr><td>close-popup-pipui</td><td>Срабатывает при закрытии всплывающего блока</td><td>.popup</td></tr><tr><td>update-popup-pipui</td><td>Срабатывает при обновлении содержимого всплывающего блока</td><td>.popup</td></tr><tr><td>update-position-popup-pipup</td><td>Срабатывает при обновлении позиции всплывающего блока</td><td>.popup</td></tr></tbody></table>


# Слайдер

## Общая информация

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

### Разметка

```html
<div id="slider"></div>

<script>
    let someHtml = '<h3 class="pb-20">HTML Slide</h3>'
        + 'Lorem Ipsum is simply dummy text of the printing and typesetting industry.<br>'
        + 'Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.<br>'
        + 'It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.<br>'
        + 'It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.'
        + '<br><br><hr><br>'
        + '<ol class="px-20"><li>Line #1</li><li>Line #2</li><li>Line #3</li></ol>';

    let slider = new PipUI.Slider('#slider', {
        slides: [
            {img: "https://cdn.pipui.ru/media/images/slider/1.webp"},
            {img: "https://cdn.pipui.ru/media/images/slider/2.webp"},
            {img: "https://cdn.pipui.ru/media/images/slider/3.webp"},
            {img: "https://cdn.pipui.ru/media/images/slider/4.webp"},
            {content: someHtml},
            {img: "https://cdn.pipui.ru/media/images/slider/5.webp", content: someHtml}
        ]
    });
</script>
```

{% embed url="<https://codepen.io/pipui/pen/ZEqWPNz>" %}
Пример работы кода выше
{% endembed %}

## Javascript

Данный компонент управляется исключительно с помощью Javascript, по этому какие-либо настройки через атрибуты произвести не удастся.

### Инициализация <a href="#init" id="init"></a>

Для инициализации слайдера необходимо создать экземпляр класса PipUI.Slider.

Конструктор данного класса поддерживает 2 параметра: HTMLElement и Object

Первый параметр - селектор или объект контейнера слайдера.

Второй параметр - объект опций

```html
<div id="slider"></div>

<script>
    let slider = new PipUI.Slider('#slider');
</script>
```

Если произвести просто инициализацию, то слайдер будет пустым, по этому необходимо заполнить его опции, а именно параметр slides, который принимает массив слайдов.

### Опции

```
// Выводить в консоль отладку
debug: false

// Массив слайдов
// Каждый элемент слайдов может представлять собой объект, состоящий из
// параметра img или content, которые являются не обязательными.
// img - ссылка на изображение
// content - HTML содержимое
slides: []

// Функция обратного вызова, срабатываемая при обновлении слайдера
updateCallback: undefined

// Функция обратного вызова, срабатываемая при изменении слайда
changeCallback: undefined

// Функция обратного вызова, срабатываемая при паузе
pauseCallback: undefined

// Функция обратного вызова, срабатываемая при возобновлении после паузе
resumeCallback: undefined

// Функция обратного вызова, срабатываемая при старте
playCallback: undefined

// Задержка при изменении слайда на следующей.
// Если установить 0, то слайды не будут переключаться автоматически.
duration: 3000

// Анимация переключения слайда
animation: 'slide'

// Отображать ли стрелочки переключения на предыдущий и следующий слайды
arrows: true

// Отображать ли элементы переключения по имеющимся слайдам
labels: true

// Можно ли использовать паузу при наведении
pause: true

// Шаблоны слайдера
templates: {
	// Контейнер списка слайдов
	list: '...'
	
	// Блок слайда
	slide: '...'
	
	// Стрелка переключения на предыдущий слайд
	arrowLeft: '...'
	
	// Стрелка переключения на следующий слайд
	arrowRight: '...'
	
	// Элемент переключения по имеющимся слайдам
	label: '...'
}
```

### Методы

```javascript
let slider = new PipUI.Slider('#slider');

slider.getID() // Вернет уникальный идентификатор слайдера

slider.setOptions(object) // Изменить опции слайдера

slider.getOptions() // Получить опции слайдера

slider.update(callback) // Обновить слайдер
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной из объекта опций

slider.setSlide(index, callback) // Изменить слайд на указанный
// Параметр index - целое число, начиная от 0
// Параметр callback является приоритетной функцией обратного
// вызова перед функцией changeCallback из объекта опций

slider.next(callback) // Изменить слайд на следующий
// Параметр callback является приоритетной функцией обратного
// вызова перед функцией changeCallback из объекта опций

slider.prev(callback) // Изменить слайд на предыдущий
// Параметр callback является приоритетной функцией обратного
// вызова перед функцией changeCallback из объекта опций

slider.pause(callback) // Поставить слайдер на паузу
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной из объекта опций

slider.resume(callback) // Запустить слайдер после паузы
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной из объекта опций

slider.play(delay, clear, callback) // Запустить слайдер с доп. параметрами
// Параметр delay указывает задержку переключения
// Параметр clear очищает предыдущие параметры
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной из объекта опций
```

### События

<table><thead><tr><th width="201.33333333333331">Триггер</th><th width="413">Описание</th><th>Инициатор</th></tr></thead><tbody><tr><td>update-slider-pipui</td><td>Срабатывает при обновлении слайдера</td><td>.slider</td></tr><tr><td>change-slider-pipui</td><td>Срабатывает при изменении слайда</td><td>.slider</td></tr><tr><td>pause-slider-pipui</td><td>Срабатывает при выставлении паузы</td><td>.slider</td></tr><tr><td>resume-slider-pipui</td><td>Срабатывает при запуске после паузы</td><td>.slider</td></tr><tr><td>play-slider-pipui</td><td>Срабатывает при запуске слайдера(обычно после паузы с определенной задержкой)</td><td>.slider</td></tr></tbody></table>


# Автозаполнение

## Общая информация <a href="#general-information" id="general-information"></a>

Автозаполнение помогает при вводе части запроса выдавать подходящие под него результаты без необходимости вводить запрос целиком.

### Разметка <a href="#markup" id="markup"></a>

```html
<input type="text" class="input" id="autocomplete2"
           data-autocomplete
           data-autocomplete-list="Qexy,Lorem Ipsum,Lorem,Ipsum,Hello,world,welcome,Lorem ipsum dolor sit amet consectetur adipisicing elit">
```

{% embed url="<https://codepen.io/pipui/pen/mdzPNgv>" %}
Пример работы кода выше
{% endembed %}

## Атрибуты

Атрибут data-autocomplete является триггером для обработки компонента автозаполнения и срабатывает при получении фокуса на поле ввода.

Помимо него, существуют и несколько других атрибута, которые можно использовать для более углубленной настройки.

### data-autocomplete-list

Список всех доступных результатов запросов через символ "**;**". Поиск подходящих будет вычисляться с помощью javascript.

### data-autocomplete-url

Задаёт URL адрес, откуда будут загружаться подходящие под запрос предложения. Данные от обработчика необходимо возвращать в виде **JSON** и передать в нем список значений в параметре **list**.

#### Пример возвращаемых данных

```json
{
    "list": ["value 1", "value 2", "value N"]
}
```

### data-autocomplete-method

Метод отправки запроса на получение данных. По умолчанию используется GET запрос.

### data-autocomplete-key

Имя ключа, отправляемого в запросе на сервер. По умолчанию "<mark style="color:purple;">value</mark>".

Например, если мы хотим отправить значение "<mark style="color:green;">myvalue</mark>" из поля ввода методом <mark style="color:red;">GET</mark>, то запрос будет таким <mark style="color:red;">`GET`</mark>`['`<mark style="color:purple;">`value`</mark>`'] = "`<mark style="color:green;">`myvalue`</mark>`"`.&#x20;

### data-autocomplete-min

Минимальное кол-во символов, вводимых в поле ввода, для получения результатов запроса.

### data-autocomplete-max-items

Максимальное кол-во выводимых результатов

## Javascript

Для прямой работы через javascript, необходимо создать экземпляр класса PipUI.Autocomplete.

### Инициализация <a href="#init" id="init"></a>

Конструктор данного класса поддерживает 2 параметра: HTMLElement и Object

Первый параметр - объект или селектор формы ввода.

Второй параметр - объект опций

```html
<input type="text" class="input" id="autocomplete">

<script>
    let autocomplete = new PipUI.Autocomplete("#autocomplete");
</script>
```

### Опции

```
// Выводить в консоль отладку
debug: false

// Настройки источника списка. Если не указан URL, то данные будут браться из list
source: {
	// URL адрес источника, к которому будет производиться запрос на получение списка
	url: ''
	
	// Метод отправки запроса
	method: 'GET'
	
	// Ключ отправляемого параметра значения
	key: 'value'
	
	// Дополнительные параметры, отправляемые с запросом
	extra: undefined
}

// Основной список значений
list: []

// Минимальное кол-во введенных символов в форму, после которых будет обрабатываться список
min: 2

// Максимальное кол-во выводимых результатов
maxItems: 10

// Функция обратного вызова, срабатываемая при обновлении списка
updateCallback: undefined

// Функция обратного вызова, срабатываемая при переключении на следующий пункт списка
nextCallback: undefined

// Функция обратного вызова, срабатываемая при переключении на предыдущий пункт списка
prevCallback: undefined

// Функция обратного вызова, срабатываемая при обновлении позиции списка
updatePosition: undefined

// Функция обратного вызова, срабатываемая при запросе
requestCallback: undefined

// Функция обратного вызова, срабатываемая при выборе элемента списка
choiseCallback: undefined

// Шаблоны
templates: {
	// Шаблон списка
	list: '...'
	
	// Элемент списка
	item: '...'
	
	// Основной контейнер списка
	container: '...'
}
```

### Методы <a href="#methods" id="methods"></a>

```javascript
let autocomplete = new PipUI.Autocomplete('#autocomplete');

autocomplete.getID() // Вернет уникальный идентификатор автозаполнения

autocomplete.setOptions(object) // Изменить опции автозаполнения

autocomplete.getOptions() // Получить опции автозаполнения

autocomplete.request(value, callback) // Произвести запрос для получения списка
// Параметр value задает строку запроса
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной функцией указанной через опции

autocomplete.update(value, callback) // Обновление списка автозаполнения
// Параметр value задает строку запроса
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной функцией указанной через опции

autocomplete.updatePosition(callback) // Обновить позицию списка
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной функцией указанной через опции

autocomplete.isOpenedContainer() // Текущее состояние списка

autocomplete.choise(index, callback) // Выбрать элемент из списка
// Параметр index является целым числом, начиная от 0
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной функцией указанной через опции
```

### События

<table><thead><tr><th width="267">Триггер</th><th width="283.3333333333333">Описание</th><th>Инициатор</th></tr></thead><tbody><tr><td>update-autocomplete-pipui</td><td>Срабатывает при обновлении списка результатов</td><td>.autocomplete-input</td></tr><tr><td>next-autocomplete-pipui</td><td>Срабатывает при переключении на следующий пункт списка</td><td>.autocomplete-input</td></tr><tr><td>prev-autocomplete-pipui</td><td>Срабатывает при переключении на предыдущий пункт списка</td><td>.autocomplete-input</td></tr><tr><td>update-position-autocomplete-pipui</td><td>Срабатывает при обновлении позиции списка</td><td>.autocomplete-input</td></tr><tr><td>request-autocomplete-pipui</td><td>Срабатывает при получении ответа на запрос</td><td>.autocomplete-input</td></tr><tr><td>choise-autocomplete-pipui</td><td>Срабатывает при выборе пункта из списка</td><td>.autocomplete-input</td></tr></tbody></table>


# Селектор тегов

## Общая информация <a href="#general-information" id="general-information"></a>

Селектор тегов помогает осуществить выборку ключевых слов или предложений.

По умолчанию в качестве разделителей используются запятая или клавиша ENTER.

Все полученные результаты помещаются в скрытое поле ввода (по умолчанию name="tags").

### Разметка

```html
<input type="text" class="input" data-tagselector>
```

{% embed url="<https://codepen.io/pipui/pen/JjmKYWP>" %}
Пример работы кода выше
{% endembed %}

## Атрибуты

Атрибут <mark style="color:orange;">`data-tagselector`</mark> является инициатором для обработки формы при получении фокуса, однако помимо атрибутов, вы можете инициализировать обработку через javascript.

### data-tagselector-keys

Клавиши, по нажатию на которые тег будет добавляться в список. В качестве разделителя можно использовать символ "**+**".

### data-tagselector-unique

Должны ли теги быть уникальными. По умолчанию **true**.

### data-tagselector-insert

Куда будет вставлен тег. Принимаются значения **start**(вначале) и **end**(вконце).\
По умолчанию **start**.

### data-tagselector-min

Минимальное кол-во символов, которое необходимо ввести для добавления тега. По умолчанию **1**.

### data-tagselector-max

Максимальное кол-во символов, которое можно ввести для добавления тега.\
По умолчанию **32**.

### data-tagselector-max-tags

Максимальное кол-во тегов, которое можно добавить. По умолчанию **0** (без лимита).

### data-tagselector-pattern

Паттерн регулярного выражения, которому должен соответствовать тег.

## Javascript

Больше возможностей для управления тегами можно достичь благодаря Javascript.

### Инициализация

Для инициализации, необходимо создать экземпляр класса PipUI.Tagselector. Конструктор данного класса поддерживает 2 параметра: HTMLElement и Object

Первый параметр - селектор или объект формы ввода

Второй параметр - объект опций

```html
<input type="text" class="input" id="tagselector">

<script>
    let tagselector = new PipUI.Tagselector('#tagselector');
</script>
```

### Опции <a href="#options" id="options"></a>

```
// Выводить в консоль отладку
debug: false

// Минимальное кол-во символов для добавления тега.
min: 1

// Максимальное кол-во символов для добавления тегов.
max: 32

// Максимальное кол-во тегов для добавления.
maxTags: 0

// Паттерн регулярного выражения, которому должен соответствовать добавляемый тег.
pattern: undefined

// Куда будет вставлен тег вначале или вконце - start или end соответственно.
insert: 'start'

// Значения с которыми будет инициализирована форма
values: []

// Клавиши, по нажатию на которые тег будет добавлен
keys: [',', 'Enter']

// Должны ли теги быть уникальными
unique: true

// Имя скрытого поле в котором записаны все теги
hidden: 'tags'

// Функция обратного вызова, срабатываетая при добавлении тега вконец
pushCallback: undefined

// Функция обратного вызова, срабатываетая при добавлении тега вначало
unshiftCallback: undefined

// Функция обратного вызова, срабатываетая при очистке тегов
clearCallback: undefined

// Функция обратного вызова, срабатываетая при изменении тега
setCallback: undefined

// Функция обратного вызова, срабатываетая при удалении тега
removeCallback: undefined

// Функция обратного вызова, срабатываетая при обновлении списка тегов
updateCallback: undefined

// Функция обратного вызова, срабатываетая при получении ошибки
errorCallback: undefined

// Класс контейнера списка тегов
tagselectorClass: 'tagselector'

// Шаблоны селектора
templates: {
      // Основной контейнер списка тегов
      container: '...',
      
      // Элемент тега
      tag: '...'
}
```

### Методы <a href="#methods" id="methods"></a>

```javascript
let tagselector = new PipUI.Tagselector('#tagselector');

tagselector.getID() // Вернет уникальный идентификатор

tagselector.setOptions(object) // Изменить опции

tagselector.getOptions() // Получить опции

tagselector.add(string, callback) // Добавить тег в список
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной функцией указанной через опции

tagselector.push(string, callback) // Добавить тег вконец списка
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной функцией указанной через опции

tagselector.unshift(string, callback) // Добавить тег вначало списка
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной функцией указанной через опции

tagselector.set(id, string, callback) // Изменить тег
// Параметр id хранится в атрибуте data-tagselector-item-id каждого тега
// Параметр string - строка, на которую будет заменено содержимое тега
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной функцией указанной через опции

tagselector.remove(id, callback) // Удалить тег
// Параметр id хранится в атрибуте data-tagselector-item-id каждого тега
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной функцией указанной через опции

tagselector.clear(callback) // Удалить все теги
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной функцией указанной через опции

tagselector.search(string) // Поиск тега
```

### События

<table><thead><tr><th>Триггер</th><th width="351.3333333333333">Описание</th><th>Инициатор</th></tr></thead><tbody><tr><td>push-tagselector-pipui</td><td>Срабатывает при добавлении тега вконец</td><td>.tagselector-input</td></tr><tr><td>unshift-tagselector-pipui</td><td>Срабатывает при добавлении тега вначало</td><td>.tagselector-input</td></tr><tr><td>set-tagselector-pipui</td><td>Срабатывает при изменении тега</td><td>.tagselector-input</td></tr><tr><td>remove-tagselector-pipui</td><td>Срабатывает при удалении тега</td><td>.tagselector-input</td></tr><tr><td>clear-tagselector-pipui</td><td>Срабатывает при очистке</td><td>.tagselector-input</td></tr></tbody></table>

### Совместимость

Вы так же можете использовать селектор тегов совместно с [автозаполнением](/components/autocomplete)

```html
<input type="text" class="input" id="tagselector" data-autocomplete-list="test;example;lorem;ipsum">

<script>
    let tagselector1 = new PipUI.Tagselector('#tagselector');

    let autocomplete = new PipUI.Autocomplete('#tagselector', {
        choiseCallback: (self, item) => { self.input.value = ''; tagselector1.add(item.innerHTML); }
    });
</script>
```


# Селекторы даты и времени

## Общая информация

До появления HTML 5 в разметке отсутствовали поля ввода с типами для выбора даты и времени. С появлением этой спецификации, положение немного улучшилось и таковые были добавлены, но не всеми браузерами, а их поддержка оставляла желать лучшего.\
И конечно добавленные браузерами типы полей input не позволяли производить стилизацию появляющихся селекторов.

Мы решили добавить этот компонент, чтобы решить все эти проблемы

### Разметка

```html
<input type="text" class="input" data-datepicker>
```

{% embed url="<https://codepen.io/pipui/pen/JjmRYdx>" %}
Пример работы кода выше
{% endembed %}

## Атрибуты

При инициализации через атрибуты, триггером является атрибут data-datepicker.

### data-datepicker

Без указания значения включает селектор даты и времени. Может принимать в качестве значений **date** и **time**, каждое из которых включает только соответствующий селектор.

### data-datepicker-format

Формат входящей/исходящей даты. Формируется компонентом Date.

## Javascript

Для прямой работы через javascript, необходимо создать экземпляр класса PipUI.Datepicker.

### Инициализация <a href="#init" id="init"></a>

Конструктор данного класса поддерживает 2 параметра: HTMLElement и Object

Первый параметр - объект или селектор формы ввода.

Второй параметр - объект опций

```html
<input type="text" class="input" id="datepicker">

<script>
    let datepicker = new PipUI.Datepicker("#datepicker");
</script>
```

### Опции

```
// Выводить в консоль отладку
debug: false

// Класс, присваиваемый модальному окну при открытии
showedClass: 'datepicker-active'

// Разрешить выбор даты
date: true

// Разрешить выбор времени
time: true

// Разрешить выбор года
year: true

// Разрешить выбор месяца
month: true

// Разрешить выбор дня
day: true

// Разрешить выбор часа
hours: true

// Разрешить выбор минуты
minutes: true

// Разрешить выбор секунды
seconds: true

// Функция обратного вызова, срабатываемая при изменении даты
changeCallback: undefined

// Функция обратного вызова, срабатываемая при обновлении содержимого селектора
updateCallback: undefined

// Функция обратного вызова, срабатываемая при отображении селектора
showCallback: undefined

// Функция обратного вызова, срабатываемая при скрытии селектора
hideCallback: undefined

// Формат обрабатываемой даты и времени
format: 'd.m.Y H:i:s'

// Функция форматирования даты и времени
formating: (date, self) => ...,

// Функция парсинга даты и времени
parse: (str, self) => ...

// Настройки шаблонов
templates: {
	// Основной контейнер модального окна селектора
	container: '...'
	
	// Враппер модального окна
	wrapper: '...'
	
	// Контейнер вкладок модального окна
	tabs: '...'
	
	// Вкладка селектора даты
	date: {
		// Враппер селектора даты
		wrapper: '...'

		// Селектор выбора года
		year: '...'

		// Селектор выбора месяца
		month: '...'

		// Селектор выбора недели
		week: '...'

		// Селектор выбора дня
		day: '...'
	}
	
	// Вкладка селектора времени
	time: {
		// Враппер селектора времени
		wrapper: '...'
		
		// Визуальные селекторы
		visual: {
			// Часы
			hours: '...'
			
			// Минуты
			minutes: '...'
			
			// Секунды
			seconds: '...'
		}
		
		// Формы ввода
		inputs: {
			// Часы
			hours: '...'
			
			// Минуты
			minutes: '...'
			
			// Секунды
			seconds: '...'
		}
		
		// Разделитель	
		separator: '...'
	}
	
	// Подвал модального окна
	footer: {
		// Враппер подвала
		wrapper: '...'
		
		// Кнопка отмены
		cancel: '...'
		
		// Кнопка далее
		next: '...'
		
		// Кнопка предыдущего селектора
		prev: '...'
		
		// Кнопка завершения
		done: '...'
	}

}
```

### Методы <a href="#methods" id="methods"></a>

```javascript
let datepicker = new PipUI.Datepicker('#datepicker');

datepicker.getID() // Вернет уникальный идентификатор селектора

datepicker.setOptions(object) // Изменить опции селектора

datepicker.getOptions() // Получить опции селектора

datepicker.setActiveDate() // Изменить вкладку на селектор даты

datepicker.setActiveTime() // Изменить вкладку на селектор времени

datepicker.show(callback) // Открыть модальное окно селектора
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной функцией указанной через опции

datepicker.hide(callback) // Закрыть  модальное окно селектора
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной функцией указанной через опции

datepicker.updateValue(callback) // Обновить значение в форме ввода
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной функцией указанной через опции

datepicker.setDay(day) // Установить день на указанный

datepicker.setYear(year) // Установить год на указанный

datepicker.setMonth(month) // Установить месяц на указанный

datepicker.nextYear() // Переключить на следующий год

datepicker.prevYear() // Переключить на предыдущий год

datepicker.setHours(hours) // Установить час на указанный

datepicker.setMinutes(minutes) // Установить минуту на указанную

datepicker.setSeconds(seconds) // Установить секунду на указанную

datepicker.getValue() // Получить текущее значение

datepicker.update(callback) // Обновить селектор даты
// Параметр callback является приоритетной функцией обратного
// вызова перед аналогичной функцией указанной через опции
```

### События

| Триггер                 | Описание                                              | Инициатор          |
| ----------------------- | ----------------------------------------------------- | ------------------ |
| show-datepicker-pipui   | Срабатывает при отображении модального окна селектора | \[data-datepicker] |
| hide-datepicker-pipui   | Срабатывает при скрытии модального окна селектора     | \[data-datepicker] |
| change-datepicker-pipui | Срабатывает при изменении даты или времени            | \[data-datepicker] |
| update-datepicker-pipui | Срабатывает при обновлении селектора                  | \[data-datepicker] |


# Блоки оповещений

## Общая информация <a href="#general-information" id="general-information"></a>

Блок оповещений - стилизованный блок для привлечения внимания пользователей.

```html
<div class="alertblock">
    <div class="alertblock-wrapper">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit.
        A aspernatur dicta dignissimos doloremque, facere illo ipsa molestias provident quasi quis, quos rem.
        Ab, expedita hic magni quidem quisquam reprehenderit suscipit?
    </div>
</div>
```

{% embed url="<https://codepen.io/pipui/pen/dyjWVPR>" %}
Пример работы кода выше
{% endembed %}

Вы можете выставить дополнительный контент до и/или после основного текста, который будет гармонировать с основным блоком. Для этого добавьте внутрь <mark style="color:orange;">`.alertblock`</mark> блоки <mark style="color:orange;">`.before`</mark> и <mark style="color:orange;">`.after`</mark> соответственно

```html
<div class="alertblock">
    <div class="before"><i class="fa fa-exclamation-triangle"></i></div>

    <div class="alertblock-wrapper">
        Lorem ipsum dolor sit amet, consectetur adipisicing elit.
        A aspernatur dicta dignissimos doloremque, facere illo ipsa molestias provident quasi quis,
        quos rem. Ab, expedita hic magni quidem quisquam reprehenderit suscipit?
    </div>

    <div class="after"><i class="fa-regular fa-face-smile-wink"></i></div>
</div>
```

{% embed url="<https://codepen.io/pipui/pen/OJwmvdX>" %}
Пример работы кода выше
{% endembed %}

## Javascript

Управлять блоками можно с помощью Javascript. Для этого необходимо инициализировать соответствующий объект.

```javascript
let alertblock = new PipUI.Alertblock('#alertblock')
```

Класс PipUI.Alertblock принимает 3 аргумента:\
1\. Элемент (String|HTMLElement)\
2\. Опции(Object)\
3\. Метод инициализации(Boolean) - true для создания блока

### Создание блока <a href="#block-creating" id="block-creating"></a>

Вы можете полностью создать блок со всем содержимым. Чтобы это сделать, передайте в 3 параметре значение true и задайте опции во 2 параметре.

{% hint style="success" %}
Пустой элемент из первого параметра должен существовать на странице
{% endhint %}

```javascript
let create = new PipUI.Alertblock('#alertblock', {
        message: 'Hello',
        canClose: true,
        before: '<i class="fa-solid fa-cloud"></i>',
        after: '<i class="fa-solid fa-upload"></i>'
    }, true);
```

### Инициализация блока <a href="#block-init" id="block-init"></a>

Если вы уже создали блок, то вы можете его инициализировать и управлять им. Для этого просто создайте новый объект с первым параметром

```javascript
let init = new PipUI.Alertblock('#alertblock');
```

### Опции <a href="#options" id="options"></a>

Второй параметр объекта PipUI.Alertblock поддерживает следующие параметры

```
// Выводить в консоль отладку
debug: false

// Шаблон враппера
wrapperTemplate: '<div class="alertblock-wrapper"></div>'

// Шаблон кнопки закрытия
closeTemplate: '<a href="#" class="alertblock-close" rel="nofollow">&times;</a>'

// Содержимое выводимое до основного контента
before: ''

// Содержимое выводимое после основного контента
after: ''

// Набор классов через пробел, которые будут добавлены к блоку .alertblock
class: ''

// Функция обратного вызова при начале закрытия блока
closeCallback: undefined

// Функция обратного вызова при окончании закрытия блока
closedCallback: undefined

// Функция обратного вызова при начале появления блока
showCallback: undefined

// Функция обратного вызова при окончании появления блока
showedCallback: undefined

// Функция обратного вызова при начале исчезания блока
hideCallback: undefined

// Функция обратного вызова при окончании исчезания блока
hidedCallback: undefined

// Класс анимации скрытого блока
hiddenClass: 'alertblock-hidden'

// Класс анимации закрытого блока
closedClass: 'alertblock-closed'

// Класс полного скрытия блока (display: none)
noneClass: 'alertblock-none'

// Может ли блок быть закртываемым(будет отображаться кнопка закрытия)
canClose: false

// Основное сообщение, выводимое в блоке. Можно использовать HTML
message: ''
```

### Методы <a href="#methods" id="methods"></a>

```javascript
let alertblock = new PipUI.Alertblock('#alertblock');

alertblock.getID() // Вернет уникальный идентификатор блока

alertblock.setOptions(object) // Изменить опции блока. DOM не будет изменен
// до вызова метода alertblock.update()

alertblock.getOptions() // Получить опции блока

alertblock.setMessage(string) // Изменить текст основного содержимого

alertblock.hide(callback) // Скрыть блок.
// Параметр callback является приоритетной функцией обратного
// вызова при завершении скрытия, если она задана и через опции

alertblock.show(callback) // Показать блок
// Параметр callback является приоритетной функцией обратного
// вызова при завершении отображения, если она задана и через опции

alertblock.close(callback) // Закрыть блок. Он будет полностью удалён со страницы
// Параметр callback является приоритетной функцией обратного
// вызова при завершении закрытия, если она задана и через опции
```

### События

| Триггер                 | Описание                                    | Инициатор   |
| ----------------------- | ------------------------------------------- | ----------- |
| update-alertblock-pipui | Срабатывает при обновлении блока оповещения | .alertblock |
| show-alertblock-pipui   | Срабатывает при начале появления блока      | .alertblock |
| showed-alertblock-pipui | Срабатывает по окончанию появления блока    | .alertblock |
| hide-alertblock-pipui   | Срабатывает при начале скрытия блока        | .alertblock |
| hided-alertblock-pipui  | Срабатывает по окончанию скрытия блока      | .alertblock |
| close-alertblock-pipui  | Срабатывает при начале закрытия блока       | .alertblock |
| closed-alertblock-pipui | Срабатывает по окончанию закрытия блока     | .alertblock |


# Якоря

Якоря позволяют организовать переход к элементу с анимацией

Вы можете управлять ими как через HTML, так и через Javascript

## Управление через атрибуты <a href="#control-via-attributes" id="control-via-attributes"></a>

Для управления через HTML, необходимо добавить элементу атрибут <mark style="color:orange;">`data-anchor`</mark> и передать в него ссылку на элемент к которому необходимо прокрутить страницу.

Атрибут <mark style="color:orange;">`data-anchor-duration`</mark> отвечает за скорость прокрутки в миллисекундах.

Атрибут <mark style="color:orange;">`data-anchor-hash`</mark> используется для изменения ссылки при прокрутке страницы

```html
<ul class="nav-menu">
    <li class="nav-menu-item"><a href="#" data-anchor="#anchor1" class="nav-menu-link" rel="nofollow">Anchor link #1</a></li>
    <li class="nav-menu-item"><a href="#" data-anchor="#anchor2" class="nav-menu-link" rel="nofollow">Anchor link #2</a></li>
    <li class="nav-menu-item"><a href="#" data-anchor="#anchor3" class="nav-menu-link" rel="nofollow">Anchor link #3</a></li>
    <li class="nav-menu-item"><a href="#" data-anchor="#anchor4" data-anchor-duration="3000" class="nav-menu-link" rel="nofollow">Anchor with custom duration</a></li>
    <li class="nav-menu-item"><a href="#" data-anchor="#anchor5" data-anchor-hash="anchor5" class="nav-menu-link" rel="nofollow">Anchor with hash change</a></li>
</ul>

<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

<div id="anchor1">Element1</div>

<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

<div id="anchor2">Element2</div>

<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

<div id="anchor3">Element3</div>

<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

<div id="anchor4">Element4</div>

<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

<div id="anchor5">Element5</div>
```

{% embed url="<https://codepen.io/pipui/pen/abjqmLW>" %}
Пример работы кода выше
{% endembed %}

## Управление через Javascript <a href="#control-via-javascript" id="control-via-javascript"></a>

Чтобы управлять прокруткой через Javascript, необходимо обратиться к статическому методу <mark style="color:orange;">`PipUI.Anchor.scroll()`</mark> , который принимает параметры HTMLElement и options.

```javascript
PipUI.Anchor.scroll('#anchor1');
```

### Опции <a href="#options" id="options"></a>

```
// Выводить в консоль отладку
debug: false

// Скорость прокрутки по умолчанию
defaultDuration: 400

// Функция обратного вызова по умолчанию
defaultCallback: undefined
```

### Методы <a href="#methods" id="methods"></a>

```javascript
PipUI.Anchor.setOptions(object) // Изменить опции блока. DOM не будет изменен

PipUI.Anchor.getOptions() // Получить опции блока

PipUI.Anchor.scroll(string|object, object) //Прокрутить страницу до элемента
```


# Контакты

На данной страницы вы найдёте актуальную информацию о средствах связи с нами

#### Предложения и сотрудничество

E-Mail: <admin@qexy.org>

#### Социальные сети

VK: <https://vk.com/pipui>

Telegram: <https://t.me/pip_ui>


