@ssiunov/busy-button
v2.1.0
Published
Кастомный элемент, расширяющий стандартный button, предназначенный для создания кнопок c визуальной индикацией состояния занято
Readme
svs.TBusyButton — это кастомный элемент на основе Web Components, расширяющий стандартный HTML-тег <button>. Он предназначен для создания кнопок с визуальной индикацией состояния "занято", что особенно полезно при выполнении асинхронных операций (например, сохранение данных, загрузка, отправка формы).
Элемент позволяет динамически переключать иконку, блокировать интерактивность и управлять отображением текста, обеспечивая удобный пользовательский опыт.
Исходный код в репозитории https://gitverse.ru/ssiunov/svs.busy_button
Установка из npm npm install @ssiunov/busy-button
С версии 2.1.0 требуется подключение библиотеки svs-lib^2.0.1. Она включена в зависимости пакета. При использовании учитывайте это:
<link href="../bootstrap/css/bootstrap.min.css" rel="stylesheet" /><!-- bootstrap 5 -->
<link href="../svs_glyph/fonts/SVS_Glyph.css" rel="stylesheet" /><!-- глифы по-умолчанию, если требуется -->
<link href="../dist/svs-busy-button.css" rel="stylesheet" /><!-- стили самой кнопки -->
<script src="../svs-lib/svs.lib.min.js"></script><!-- svs-lib^2.1.0 -->
<script src="../dist/bsBusyButton.js"></script><!-- сама кнопка -->🎯 Назначение
Компонент решает следующие задачи:
- Отображение анимированной иконки "загрузки" при выполнении операции.
- Переключение между обычным и "занятым" состоянием.
- Визуальная блокировка кнопки (предотвращение повторных кликов).
- Гибкая настройка внешнего вида: позиция текста, тип иконки, CSS-классы.
⚙️ Конфигурация и опции
Интерфейс: IBusyButtonOptions Определяет параметры инициализации кнопки:
|Свойство|Тип|По умолчанию|Описание| |--|:--:|:--:|--| |normalCssClass|string|'svsg-diskette'|CSS-класс для обычной иконки (например, дискета)| |busyCssClass|string|'svsg-arrows-rotate'|CSS-класс для анимированной иконки "загрузки"| |glyphElementName|string|'i'|Тег элемента, используемого как иконка (, и т.д.)| |caption|string|''|Текст кнопки| |captionPosition|'beforeglyph' | 'afterglyph'|'afterglyph'|Позиция текста относительно иконки|
🏗️ Архитектура и ключевые свойства
Состояние
_busy:boolean— внутренний флаг, указывающий, находится ли кнопка в режиме "занято".Глиф (иконка)
_glyphElement:HTMLElement— DOM-элемент иконки. Автоматически создаётся или переиспользуется из разметки. Управляет сменой классов между normalCssClass и busyCssClass.Обёртка содержимого
_contentWrap:HTMLElement—<span>, в который помещается текст кнопки. Используется для корректного управления порядком: текст + иконка.Хранение настроек
options:IBusyButtonOptions— переданные при создании опции.Настройки также дублируются в dataset элемента (например, data-caption-position), что позволяет управлять ими через HTML.
🔄 Основные методы и поведение
🟢 init() Инициализирует компонент:
- Заполняет dataset значениями по умолчанию.
- Применяет пользовательские опции как свойства.
🟡 connectedCallback() Вызывается при подключении элемента к DOM:
- Инициализирует глиф и текст с небольшой задержкой (через setTimeout), чтобы гарантировать готовность DOM.
🔁 caption (геттер/сеттер) Управляет текстом кнопки:
- При изменении перестраивает порядок: текст до/после иконки.
- Добавляет CSS-классы .beforeglyph / .afterglyph для стилизации.
🔁 captionPosition Устанавливает позицию текста (beforeglyph или afterglyph), вызывая перерисовку содержимого.
🔁 busy (геттер/сеттер) Главный метод управления состоянием:
При busy = true:
- Меняет иконку на "загрузку".
- Добавляет атрибут busy.
- Блокирует кнопку.
При busy = false:
- Возвращает обычную иконку.
- Убирает атрибут busy.
🔍 glyphElement Ленивая инициализация иконки:
Если в кнопке уже есть элемент — он используется как глиф.
Иначе создаётся новый на основе data-glyph-element-name и data-normal-css-class.
🛠️ Статические методы
static plugable(element: HTMLElement, options?: IBusyButtonOptions)
Позволяет "оживить" существующий <button> как TBusyButton без использования is="svs-busy-button". Возможно, что это даже не HTMLButtonElement, подойдёт любой элемент, из которого можно сделать кнопку, будь то span, a, li, etc…
Использование:
<!-- Здесь используем обычную ссылку, которую мы хотим превратить в нашу кнопку -->
<a href="#" id="myBtn">Обычная ссылка</a>/* В результате выполнения этого кода, ссылка приобретёт вид bootstrap-кнопки с функционалом BusyButton. */
const btn = document.getElementById('myBtn');
btn && svs.TBusyButton.plugable(btn, {
className: 'btn btn-lg btn-outline-secondary',
caption: 'Сохранить',
normalCssClass: 'svsg-diskette',
busyCssClass: 'svsg-arrows-rotate'
});Полезно для интеграции в legacy-код или динамически создаваемые элементы.
💡 Примеры использования
<button is="svs-busy-button"
data-caption="Сохранить"
data-caption-position="afterglyph">
</button>const button = document.querySelector('[is="svs-busy-button"]');
// Активировать состояние "занято"
button.busy = true;
// Через 3 секунды — вернуть в обычное состояние
setTimeout(() => {
button.busy = false;
}, 3000);✅ Преимущества
- Повторное использование: легко внедрить в любое приложение.
- Гибкость: настраивается через атрибуты или JS.
- Доступность: работает как обычный
<button>. - Поддержка Web Components: не требует фреймворков.
📝 Рекомендации
- Используйте иконки из библиотеки SVS Glyphs (например, svsg-diskette, svsg-arrows-rotate).
- Управляйте состоянием busy в обработчиках событий:
button.addEventListener('click', async () => {
button.busy = true;
await saveData();
button.busy = false;
});📦 Подведение итогов
svs.TBusyButton — это удобный, самодостаточный UI-компонент, который:
- Упрощает создание "умных" кнопок.
- Инкапсулирует логику состояний.
- Поддерживает как декларативную (HTML), так и программную (JS) настройку.
- Отлично подходит для форм, модальных окон, панелей действий и других интерфейсов, где требуется обратная связь при выполнении операций.
