activator-oce-exporter
Version:
Extract Activator binder and convert it to valid OCE mono pacakge
120 lines (102 loc) • 3.16 kB
JavaScript
import { FusionStore } from '../services/fusion-store';
import { toggleState as toggleStateAction } from '../_actions/app';
import { FusionBase } from '../base';
const shouldAdjustState = (state, enforcedState) => {
const { currentState } = FusionStore.store.getState().app;
return currentState.includes(state) !== enforcedState;
};
const shouldToggle = (state, enforcedState) => enforcedState === null || shouldAdjustState(state, enforcedState);
export function Stateful(superClass) {
return class extends superClass {
stateChanged(state) {
const stateName = this.getStateName();
if (state.app.currentState.includes(stateName)) {
if (!this.active) {
this.enterCallback();
}
} else if (this.active) {
this.exitCallback();
}
}
get isStateful() {
return this.getStateName && this.activate;
}
getStateName() {
return `${this.state}-${this.id}`;
}
constructor() {
super();
if (!this.state) this.state = 'UI';
this.active = false;
}
firstUpdated(changedProperties) {
super.firstUpdated(changedProperties);
this.stateId = this.getAttribute('id');
if (this.stateId) this.registerState(this.state);
}
disconnectedCallback() {
this.inactivate();
this.unregisterState(this.state);
}
// recursively iterates over all child elements, skips children of stateful elements
iterateNonStatefulChildren(parent, cb) {
const childEls = [...parent.children];
childEls.forEach((el) => {
if (el instanceof FusionBase) {
cb(el);
}
if (!el.isStateful) {
this.iterateNonStatefulChildren(el, cb);
}
});
}
childCbTrigger(isEnter = false) {
this.iterateNonStatefulChildren(this,
component => component.parentStateChanged({ name: this.getStateName(), active: isEnter }));
}
enterCallback() {
this.active = true;
if (this.enter) this.enter();
this.emitCustomEvent('enter');
this.childCbTrigger(true);
}
exitCallback() {
this.active = false;
if (this.exit) this.exit();
this.emitCustomEvent('exit');
this.childCbTrigger();
}
/**
* Function for change state in app
* @todo toggleState duplicated in API. Should unify it in future
* @param state
* @param id
* @param includeId
* @param enforcedState
*/
toggleState(state, id = this.id, includeId = true, enforcedState = null) {
const stateName = includeId ? `${state}-${id}` : state;
if (shouldToggle(stateName, enforcedState)) {
FusionStore.store.dispatch(toggleStateAction(stateName));
document.body.classList.toggle(stateName);
}
}
set active(value) {
if (value) {
this.setAttribute('active', value);
} else {
this.removeAttribute('active');
}
return value;
}
get active() {
return this.getAttribute('active');
}
activate() {
this.pushState(this.state);
}
inactivate() {
this.removeState(this.state);
}
};
}