@jupyterlab/apputils
Version:
JupyterLab - Application Utilities
97 lines (86 loc) • 2.11 kB
text/typescript
/*
* Copyright (c) Jupyter Development Team.
* Distributed under the terms of the Modified BSD License.
*/
import { Widget } from '@lumino/widgets';
/**
* Options when add a command to a semantic group.
*/
interface ISemanticCommand {
/**
* Command id
*/
id: string;
/**
* Whether this command is enabled for a given widget
* @param widget Widget
*/
isEnabled?(widget: Widget): boolean;
/**
* Command rank in the semantic group
*
* #### Note
* If multiple commands are enabled at the same time,
* the one with the smallest rank will be executed.
*/
rank?: number;
}
/**
* Semantic group of commands
*/
export class SemanticCommand {
/**
* Default rank for semantic command
*/
static readonly DEFAULT_RANK = 500;
/**
* The command IDs used by this semantic command.
*/
get ids(): string[] {
return this._commands.map(c => c.id);
}
/**
* Add a command to the semantic group
*
* @param command Command to add
*/
add(command: ISemanticCommand): void {
if (this._commands.map(c => c.id).includes(command.id)) {
throw Error(`Command ${command.id} is already defined.`);
}
this._commands.push({
isEnabled: () => true,
rank: SemanticCommand.DEFAULT_RANK,
...command
});
}
/**
* Get the command id of the enabled command from this group
* for the given widget.
*
* @param widget Widget
* @returns Command id
*/
getActiveCommandId(widget: Widget): string | null {
const commands = this._commands
.filter(c => c.isEnabled(widget))
.sort((a, b) => {
const rankDelta = a.rank - b.rank;
return rankDelta || (a.id < b.id ? -1 : 1);
});
const command = commands[0] ?? { id: null };
return command.id;
}
/**
* Remove a command ID.
*
* @param id Command ID to remove
*/
remove(id: string): void {
const index = this._commands.findIndex(c => c.id === id);
if (index >= 0) {
this._commands.splice(index, 1);
}
}
protected _commands = new Array<Required<ISemanticCommand>>();
}