Skip to content

Commit

Permalink
feat(text editor): conditionally allow commands
Browse files Browse the repository at this point in the history
  • Loading branch information
john-traas committed Feb 21, 2025
1 parent 6418d3c commit dd11d8a
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,43 @@ import { EditorMenuTypes } from '../menu/types';

export const actionBarPluginKey = new PluginKey('actionBarPlugin');

export type ActiveMenuItems = Record<EditorMenuTypes, boolean>;
export interface MenuItemStates {
active: Record<EditorMenuTypes, boolean>;
visible: Record<EditorMenuTypes, boolean>;
}

export type UpdateMenuItemsCallBack = (activeTypes: ActiveMenuItems) => void;
export type UpdateMenuItemsCallBack = (
activeTypes: Record<EditorMenuTypes, boolean>,
allowedTypes: Record<EditorMenuTypes, boolean>,
) => void;

const getMenuItemStates = (
menuTypes: EditorMenuTypes[],
menuCommandFactory: MenuCommandFactory,
view: EditorView,
): ActiveMenuItems => {
const activeTypes: ActiveMenuItems = {};
): MenuItemStates => {
const activeTypes: Record<EditorMenuTypes, boolean> = {};
const allowedTypes: Record<EditorMenuTypes, boolean> = {};

menuTypes.forEach((type) => {
const command: CommandWithActive = menuCommandFactory.getCommand(type);
activeTypes[type] =
command && command.active && command.active(view.state);
activeTypes[type] = command?.active?.(view.state) || false;
allowedTypes[type] = command?.isAllowed?.(view.state) ?? true;
});

return activeTypes;
return { active: activeTypes, visible: allowedTypes };
};

export const createMenuStateTrackingPlugin = (
menuTypes: EditorMenuTypes[],
menuCommandFactory: MenuCommandFactory,
updateCallback: UpdateMenuItemsCallBack,
) => {
return new Plugin<ActiveMenuItems>({
return new Plugin<MenuItemStates>({
key: actionBarPluginKey,
state: {
init: () => {
return {};
return { active: {}, visible: {} };
},
apply: (tr, menuStates) => {
const newMenuStates = tr.getMeta(actionBarPluginKey);
Expand All @@ -58,7 +65,10 @@ export const createMenuStateTrackingPlugin = (
menuItemStates,
);
view.dispatch(tr);
updateCallback(menuItemStates);
updateCallback(
menuItemStates.active,
menuItemStates.visible,
);
}
},
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,19 +370,23 @@ export class ProsemirrorAdapter {

private updateActiveActionBarItems = (
activeTypes: Record<EditorMenuTypes, boolean>,
allowedTypes: Record<EditorMenuTypes, boolean>,
) => {
const newItems = getTextEditorMenuItems().map((item) => {
if (isItem(item)) {
return {
...item,
selected: activeTypes[item.value],
allowed: allowedTypes[item.value],
};
}

return item;
});

this.actionBarItems = newItems;
this.actionBarItems = newItems.filter((item) =>
isItem(item) ? item.allowed : true,
);
};

private async updateView(content: string) {
Expand Down

0 comments on commit dd11d8a

Please sign in to comment.