@atlaskit/editor-plugin-floating-toolbar
Version:
Floating toolbar plugin for @atlaskit/editor-core
65 lines (63 loc) • 1.8 kB
JavaScript
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
export const forceFocusStateKey = new PluginKey('forceFocusStatePlugin');
/**
* Used in cases where a floating toolbar button opens a submenu which destroys
* the button, but the user has pressed ESC to close the submenu and focus needs
* to move back to the button. */
export default (() => new SafePlugin({
key: forceFocusStateKey,
state: {
init: () => ({
selector: null
}),
apply: (tr, prevState) => {
const meta = tr.getMeta(forceFocusStateKey);
if (meta && 'selector' in meta) {
return {
selector: meta.selector
};
}
return prevState;
}
}
}));
/**
* The provided selector should be the floating toolbar button that needs focus.
*/
export const forceFocusSelector = selector => tr => {
return tr.setMeta(forceFocusStateKey, {
selector
});
};
/**
* If a selector is set and the element exists, focus it.
*/
export function checkShouldForceFocusAndApply(view) {
const state = view === null || view === void 0 ? void 0 : view.state;
if (state) {
const {
selector
} = forceFocusStateKey.getState(state);
if (selector) {
const focusableElement = document.querySelector(selector);
if (focusableElement) {
focusableElement.scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'nearest'
});
// Ignored via go/ees005
// eslint-disable-next-line @atlaskit/editor/no-as-casting
focusableElement.focus();
const {
state: {
tr
},
dispatch
} = view;
dispatch(forceFocusSelector(null)(tr));
}
}
}
}