Skip to content

Command Palette — vyuh_command_palette ​

vyuh_command_palette is the Vyuh command palette package. It provides a plugin, global launch shortcut, dialog, tabbed result list, and a pluggable search-provider contract.

dart
import 'package:vyuh_command_palette/vyuh_command_palette.dart';

CommandPalettePlugin ​

Register the plugin with the Vyuh platform, optionally passing a CommandPaletteConfig.

dart
CommandPalettePlugin(
  config: CommandPaletteConfig(
    canOpen: () => session.isSignedIn,
  ),
)

The plugin:

  • Installs a global hardware-key handler on init.
  • Opens or toggles the dialog when the launch shortcut matches.
  • Owns registered SearchProviders.
  • Dispatches searches to providers in registration order.
  • Clears providers on dispose.

The default launch shortcut is PlatformLaunchShortcut: Cmd+K on macOS and Ctrl+K elsewhere. The default tab-cycle shortcut inside the dialog is plain Tab.

Register Providers ​

Providers return one or more SearchTabs for each query. Queries are sent on every debounced keystroke, including an empty string for the idle browse state.

dart
final provider = NavigationSearchProvider(tabName: 'App')
  ..addItem(
    title: 'Areas',
    subtitle: 'Master data',
    icon: FluentIcons.building_factory_24_regular,
    searchTerms: const ['production', 'site'],
    canAccess: () => permissions.canReadAreas(),
    onSelected: (context) => context.go('/areas'),
  );

vyuh.commandPalette?.registerSearchProvider(provider);

NavigationSearchProvider is dependency-free by default: it uses simple substring matching. Apps can inject a NavigationMatcher for fuzzy matching when another package already provides that dependency.

Provider Contract ​

dart
class LotSearchProvider implements SearchProvider {
  @override
  Future<List<SearchTab>> search(String query) async {
    final lots = await api.searchLots(query);
    return [
      SearchTab(
        name: 'Lots',
        items: [
          for (final lot in lots)
            PaletteItem(
              title: lot.code,
              subtitle: lot.productName,
              icon: FluentIcons.box_24_regular,
              onSelected: (context) => context.go('/lots/${lot.id}'),
              metadata: {'lotId': lot.id},
            ),
        ],
      ),
    ];
  }
}

Provider failures should return const [] and log internally. The plugin also catches provider errors and treats that provider as empty for the query, so one failing provider does not break the palette.

Public Types ​

TypeUse
CommandPalettePluginPlugin lifecycle, provider registry, and show(context)
CommandPaletteConfigLaunch shortcut, tab-cycle shortcut, and canOpen gate
PlatformLaunchShortcutCmd+K / Ctrl+K platform activator
SearchProviderAsync provider interface
SearchTabNamed result tab returned by a provider
PaletteItemSelectable result row with title, subtitle, icon, action, metadata
NavigationSearchProviderBuilt-in provider for route/navigation entries
ShowCommandPaletteAction / ShowCommandPaletteIntentActions integration for widget-tree launchers
CommandPaletteDialogDialog widget used by the action/plugin

Open Programmatically ​

For button-triggered launch, call show(context) on the registered plugin or invoke the action directly.

dart
Button.icon(
  icon: FluentIcons.search_24_regular,
  tooltip: 'Command palette',
  onPressed: () async => vyuh.commandPalette?.show(context),
)

CommandPaletteConfig.canOpen is checked on both the global-key path and the widget-tree Actions.invoke path, so auth/session gates remain consistent.