UNPKG

@stimulus-library/controllers

Version:

A library of useful controllers for Stimulus

115 lines (114 loc) 3.52 kB
import { BaseController } from "@stimulus-library/utilities"; import { useClickOutside, useHover } from "@stimulus-library/mixins"; export class ToggleClassController extends BaseController { connect() { if (!this.hasClassValue) { throw new Error("data-toggle-class-class-value must not be empty"); } if (this.hasMouseEnterValue || this.hasMouseLeaveValue) { useHover(this, this.el, this.mouseEnter, this.mouseLeave); } if (this.hasClickAwayValue && this.clickAwayValue) { useClickOutside(this, this.el, this.clickOutside); } requestAnimationFrame(() => { if (this.hasInitialValue) { if (this.initialValue === "on") { this.toggleTargets.forEach((target) => this._elementOn(target)); } else { this.toggleTargets.forEach((target) => this._elementOff(target)); } } }); } clickOutside() { this.toggleTargets.forEach((target) => { if (this._elementWasToggled(target)) { this._elementToggleStatus(target); this._elementToggle(target); } }); } mouseEnter() { if (this.hasMouseEnterValue) { switch (this.mouseEnterValue) { case "on": this.on(); break; case "off": this.off(); break; case "toggle": this.toggle(); break; } } return {}; } mouseLeave() { if (this.hasMouseLeaveValue) { switch (this.mouseLeaveValue) { case "on": this.on(); break; case "off": this.off(); break; case "toggle": this.toggle(); break; } } return {}; } on(_event) { this.toggleTargets.forEach((target) => { this._elementToggleStatus(target); this._elementOn(target); }); } off(_event) { this.toggleTargets.forEach((target) => { this._elementToggleStatus(target); this._elementOff(target); }); } toggle(_event) { this.toggleTargets.forEach((target) => { this._elementToggleStatus(target); this._elementToggle(target); }); } _elementWasToggled(el) { return el.dataset.toggled == "true"; } _elementToggleStatus(el) { if (this._elementWasToggled(el)) { delete el.dataset.toggled; } else { el.dataset.toggled = "true"; } } _elementToggle(el) { const classes = this.classValue.split(" "); classes.forEach((klass) => el.classList.toggle(klass)); } _elementOn(el) { const classes = this.classValue.split(" "); classes.forEach((klass) => el.classList.toggle(klass, true)); } _elementOff(el) { const classes = this.classValue.split(" "); classes.forEach((klass) => el.classList.toggle(klass, false)); } } ToggleClassController.targets = ["toggle"]; ToggleClassController.values = { class: String, mouseEnter: String, mouseLeave: String, clickAway: Boolean, initial: String, };