@atlaskit/editor-plugin-block-controls
Version:
Block controls plugin for @atlaskit/editor-core
65 lines (64 loc) • 2.31 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import { EventEmitter } from 'events';
import { useCallback, useEffect, useState } from 'react';
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
export class ActiveAnchorTracker {
constructor() {
_defineProperty(this, "lastActiveAnchor", '');
this.emitter = new EventEmitter();
}
getActiveAnchor() {
return this.lastActiveAnchor;
}
subscribe(anchorName, callback) {
if (this.emitter) {
this.emitter.on(anchorName, callback);
}
}
unsubscribe(anchorName, callback) {
if (this.emitter) {
this.emitter.removeListener(anchorName, callback);
}
}
emit(anchorName) {
if (this.lastActiveAnchor !== anchorName && this.emitter) {
this.emitter.emit(this.lastActiveAnchor, false);
this.emitter.emit(anchorName, true);
this.lastActiveAnchor = anchorName;
}
}
reset() {
if (this.emitter) {
// To prevent any potential memory leaks,
// we set the event emitter to null and then create a new event emitter.
this.emitter.removeAllListeners();
this.emitter = null;
this.emitter = new EventEmitter();
}
}
}
// TODO: ED-26959 - We should use a scoped ActiveAnchorTracker rather than the global static object.
// Move this into the plugin scope once the newApply functions becomes default apply.
export const defaultActiveAnchorTracker = new ActiveAnchorTracker();
export const useActiveAnchorTracker = (anchorName, activeAnchorTracker = defaultActiveAnchorTracker) => {
const [isActive, setIsActive] = useState(false);
const onActive = eventIsActive => {
setIsActive(eventIsActive);
};
useEffect(() => {
if (activeAnchorTracker && anchorName && editorExperiment('advanced_layouts', true)) {
activeAnchorTracker.subscribe(anchorName, onActive);
if (activeAnchorTracker.getActiveAnchor() === anchorName) {
setIsActive(true);
}
const unsubscribe = () => {
activeAnchorTracker.unsubscribe(anchorName, onActive);
};
return unsubscribe;
}
}, [activeAnchorTracker, anchorName]);
const setActive = useCallback(() => {
activeAnchorTracker.emit(anchorName);
}, [activeAnchorTracker, anchorName]);
return [isActive, setActive];
};