@yuuvis/command-palette
TypeScript icon, indicating that this package has built-in type declarations

18.1.0 • Public • Published

@yuuvis/command-palette

Add keyboard support to your application.

The core of this project is a service that the components of your app could use to register (and unregister) commands.

By default the command palette interface will be triggered by hitting 'Control' twice. This will open an overlay with all commands listed and a search box where you can filter them.

Installation

npm i -S @yuuvis/command-palette

In your app import module and register entry component:

// app.module.ts

@NgModule({
  ...
  imports: [
    CommandPaletteModule.forRoot(),
  ],
  ...
  entryComponents: [CommandPaletteComponent]
})
export class AppModule {}

You can also configure th emodule by provideing a configuration to the forRoot function:

CommandPaletteModule.forRoot({
  // the key that opens the overlay (hit twice)
  triggerKey: 'Shift',
  // accent color to be used in the overlay
  accentColor: 'hotpink',
  // character that will enter search mode if typed at the beginning
  searchModeIndicator: '?',
  // placeholder for command paletts input field
  placeholder: 'Enter your command'
}),

Usage

Now components can register commands using CommandPaletteService and listen to them beeing triggerd.

// any of your components

constructor(private cmdService: CommandPaletteService) {

    // subscribe to any command being triggered
    this.cmdService.command$.subscribe((c: CommandPaletteCommand) => console.log('command$', c));

    // register a single command and subscribe to it
    cmdService.registerCommand(
        { id: 'id1', label: 'BPM: Create task' }
    ).subscribe((c: CommandPaletteCommand) => console.log('CREATE A TASK'));

    // register multiple commands and subscribe to them
    cmdService.registerCommands(
        { id: 'id2', label: 'Navigate: Open inbox' },
        { id: 'id3', label: 'Navigate: Open settings' }
    ).subscribe((c: CommandPaletteCommand) => {
        if(c.id === 'id2') // ... open the inbox
        if(c.id === 'id3') // ... open the settings
    });

    // register command with callback
    cmdService.registerCommand(
        { id: 'id2', label: 'Task: Do awesome stuff', callback: () => {
          // executed once the command is triggered
          alert('Great! You did it.')
        } }
    ).subscribe()
}

Updating commands

Sometimes it is necessary to update command properties. If users for example change the apps language you'll need to change the labels of the registered commands as well.

// app.component.ts

import { CommandPalettService } from "@yuuvis/command-palette";
import { TranslateService } from "@ngx-translate/core";

export class AppComponent {
  constructor(
    private translate: TranslateService,
    private cmpService: CommandPaletteService
  ) {
    this.translate.onLangChange.subscribe((_) => {
      // update commands on app language change
      this.cmpService.updateCommands(this.getCommands());
    });

    // register commands in the first place
    this.cmpService.updateCommands(this.getCommands());
  }

  private getCommands(): CommandPaletteCommand[] {
    return [
      { id: "1", label: this.translate.instant("command.first") },
      { id: "2", label: this.translate.instant("command.second") },
      { id: "3", label: this.translate.instant("command.third") },
    ];
  }
}

Styling

The library will register a couple of css variables that you could overwrite in your app:

/* Accent color */
--cmp-color-accent: hotpink;
/* Text on top of an accent colored background */
--cmp-color-accent-text: #fff;
/* Color of text that should be highlighted on accent colored background */
--cmp-color-accent-text-highlight: #000;
/* Components regular text color */
--cmp-color-text: #fff;
/* Color of text that should be highlighted */
--cmp-color-text-highlight: var(--cmp-color-accent);
/* Components base font size */
--cmp-font-size: 1em;
/* Background color if commands are hovered */
--cmp-hover-background: rgba(255, 255, 255, 0.1);
/* the backdrops background color */
--cmp-backdrop-color: rgba(0, 0, 0, 0.9);
/* Width of search and command items */
--cmp-width: 30vw;
/* Minimum width of search and command items */
--cmp-min-width: 300px;

Search mode

You could also use this library to trigger custom searches. Therefore you have to define a searchModeIndicator and register a callback function on CommandPaletteService.

Let's say you define the character ? as search mode indictator then inserting thisi character into the search fiels will trigger the search mode.

// app.module.ts

@NgModule({
  imports: [
    ...CommandPaletteModule.forRoot({
      searchModeIndicator: "?",
      searchModeExplaination: `You entered '?' so you are in search mode now and your query will find objects instaed of commands ...`,
    }),
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}
// app.component.ts
import {
  CommandPaletteService,
  CommandPaletteCommand,
} from "@yuuvis/command-palette";

export class AppComponent {
  constructor(private cmdService: CommandPaletteService) {
    // register callback
    cmdService.onSearchTerm = (term, cb) => {
      cb(this.executeSearch(term));
    };
  }

  executeSearch(term): CommandPaletteCommand[] {
    // trigger actual search
  }
}

Temporarily disable command palette

In some situations you need to disable functionality of the command palette for a while. For example if a user edits data on the site that has not yet been saved you do not want to trigger any command until the user saved his work.

CommandPaletteService offers a set of functions to disable the overlay and also provide an explaination to the user:

constructor(private cmdService: CommandPaletteService) {

  this.pendingChanges$.subscribe((hasPendingChnages: boolean) => {

    if(hasPendingChanges) {
      this.cmdService.addDisabledCause({id: 'pending', message: 'Disabled due to pending changes. Please save your changes.'});
    } else {
      this.cmdService.removeDisabledCause('pending');
    }

  })
}

You could add as many causes as you want. They will all be shown to the user as a list of reasons why the command palette is disabled right now. If you got more then one cause you could also remove all of them at once by running this.cmdService.removeAllDisabledCauses().

Readme

Keywords

none

Package Sidebar

Install

npm i @yuuvis/command-palette

Weekly Downloads

70

Version

18.1.0

License

MIT

Unpacked Size

121 kB

Total Files

25

Last publish

Collaborators

  • optimal-systems-npm
  • eo-sdk-npm