@stimulus-library/controllers
Version:
A library of useful controllers for Stimulus
115 lines (114 loc) • 3.52 kB
JavaScript
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,
};