75 lines
2.0 KiB
JavaScript
75 lines
2.0 KiB
JavaScript
import {Controller} from '@hotwired/stimulus'
|
|
|
|
export default class extends Controller {
|
|
static classes = ['closed', 'open', 'iconOpen']
|
|
static targets = ['content', 'icon', 'container']
|
|
static values = {
|
|
open: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
storageKey: {
|
|
type: String,
|
|
default: ''
|
|
}
|
|
}
|
|
|
|
initialize() {
|
|
this.target = this.hasContentTarget ? this.contentTarget : this.element
|
|
|
|
// Restore state from storage if storageKey is provided
|
|
if (this.hasStorageKey()) {
|
|
this.restoreState()
|
|
}
|
|
}
|
|
|
|
toggle() {
|
|
this.openValue = !this.openValue
|
|
}
|
|
|
|
close() {
|
|
this.openValue = false
|
|
}
|
|
|
|
open() {
|
|
this.openValue = true
|
|
}
|
|
|
|
openValueChanged(open) {
|
|
this.target.classList.toggle(this.closedClass, false === open)
|
|
|
|
if (this.hasIconTarget) {
|
|
let iconClass = this.hasIconOpenClass ? this.iconOpenClass : 'rotate-90'
|
|
this.iconTarget.classList.toggle(iconClass, true === open)
|
|
}
|
|
|
|
// Toggle class on container element (or controller element) if specified
|
|
if (this.hasOpenClass) {
|
|
const container = this.hasContainerTarget ? this.containerTarget : this.element
|
|
this.openClasses.forEach(cls => {
|
|
container.classList.toggle(cls, true === open)
|
|
})
|
|
}
|
|
|
|
// Save state to storage if storageKey is provided
|
|
if (this.hasStorageKey()) {
|
|
this.saveState()
|
|
}
|
|
}
|
|
|
|
hasStorageKey() {
|
|
return this.storageKeyValue && this.storageKeyValue.trim() !== ''
|
|
}
|
|
|
|
saveState() {
|
|
sessionStorage.setItem(`toggle_${this.storageKeyValue}`, this.openValue.toString())
|
|
}
|
|
|
|
restoreState() {
|
|
const savedState = sessionStorage.getItem(`toggle_${this.storageKeyValue}`)
|
|
if (savedState !== null) {
|
|
this.openValue = savedState === 'true'
|
|
}
|
|
}
|
|
}
|