Классы для состояний элементов

Stimulus — это JavaScript-фреймворк, ориентированный на управление поведением HTML-элементов через контроллеры. Один из ключевых инструментов для динамического изменения внешнего вида и состояния элементов — использование классов CSS, управляемых непосредственно из контроллера. Это позволяет отделять логику поведения от стилей, сохраняя код чистым и предсказуемым.

Работа с классами через classList

Каждый элемент DOM имеет свойство classList, предоставляющее методы для управления классами: add, remove, toggle и contains. В Stimulus эти методы используются внутри контроллеров для отражения состояния интерфейса.

Пример контроллера, управляющего активным состоянием кнопки:

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  static targets = ["button"]

  toggleActive() {
    this.buttonTarget.classList.toggle("active");
  }
}
  • toggleActive переключает класс "active" на целевом элементе.
  • Такой подход позволяет визуально обозначать состояние кнопки без прямого вмешательства в стили.

Использование data-attributes для динамических классов

Stimulus тесно интегрируется с HTML через data-* атрибуты. Для управления состояниями удобно создавать отдельные атрибуты, указывающие на классы CSS, которые должны применяться.

Пример:

<button data-controller="toggle"
        data-toggle-class="highlighted"
        data-action="click->toggle#switch">
  Нажми меня
</button>

Контроллер:

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  static values = { class: String }

  switch() {
    this.element.classList.toggle(this.classValue);
  }
}
  • classValue считывает значение атрибута data-toggle-class.
  • Такой подход делает контроллер универсальным для любых элементов с разными классами.

Управление несколькими состояниями одновременно

Иногда необходимо управлять не одним, а несколькими классами одновременно, например для отображения разных режимов интерфейса (например, "loading", "error", "success"). Stimulus позволяет хранить массив классов и управлять ими программно.

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  static targets = ["status"]

  setLoading() {
    this._clearStatusClasses();
    this.statusTarget.classList.add("loading");
  }

  setError() {
    this._clearStatusClasses();
    this.statusTarget.classList.add("error");
  }

  setSuccess() {
    this._clearStatusClasses();
    this.statusTarget.classList.add("success");
  }

  _clearStatusClasses() {
    this.statusTarget.classList.remove("loading", "error", "success");
  }
}
  • _clearStatusClasses обеспечивает, что элемент всегда имеет только один активный статус.
  • Такой подход предотвращает конфликт состояний и облегчает поддержку кода.

Динамическое добавление и удаление классов через значения контроллера

Stimulus поддерживает определение values, что позволяет задавать динамические данные прямо в HTML. Это расширяет возможности управления состояниями через CSS.

Пример с цветовой схемой:

<div data-controller="theme"
     data-theme-active-class-value="dark-mode">
  Контент
</div>

Контроллер:

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  static values = { activeClass: String }

  enableTheme() {
    this.element.classList.add(this.activeClassValue);
  }

  disableTheme() {
    this.element.classList.remove(this.activeClassValue);
  }
}
  • Применение классов через значения позволяет легко менять конфигурацию без изменения JavaScript-кода.
  • Можно использовать один контроллер для нескольких элементов с разными классами.

Использование классов для анимаций и переходов

Для плавных эффектов часто используют CSS-переходы, а классы включают или отключают нужные стили. Stimulus удобно интегрируется с анимациями через классы:

showElement() {
  this.element.classList.add("visible");
  this.element.classList.remove("hidden");
}

hideElement() {
  this.element.classList.add("hidden");
  this.element.classList.remove("visible");
}

В CSS:

.hidden {
  opacity: 0;
  transition: opacity 0.3s ease;
}

.visible {
  opacity: 1;
  transition: opacity 0.3s ease;
}
  • Классы управляют не только видимостью, но и эффектами переходов.
  • Такой подход отделяет визуальное оформление от логики состояния, делая код более предсказуемым и легко тестируемым.

Практические рекомендации

  1. Минимизировать прямое изменение стилей через JavaScript. Использование классов поддерживает консистентность и упрощает поддержку.
  2. Создавать универсальные контроллеры с параметрами через data-values. Это позволяет переиспользовать один и тот же код для разных элементов.
  3. Очистка классов перед применением нового состояния предотвращает наложение стилей и неожиданные эффекты.
  4. Сохранять семантику: имена классов должны отражать смысл состояния (active, loading, error), а не конкретные стили (red-bg, big-font).

Stimulus делает управление состояниями элементов через классы максимально прозрачным и структурированным. Использование методов classList, значений и data-attributes позволяет создавать мощные и универсальные контроллеры, поддерживающие чистый и расширяемый код интерфейса.