Command palette polyfill sampler (single page)

Virtual id: i-cmd-p Spec source: /home/chrome/md-store/cmd-p.md Polyfill file: command-palette-polyfill.js

Runtime mode

Mode: checking... Native API availability: checking...

Green means true, red means false. This page can prefer native when available. Otherwise it uses the JS polyfill.

Try it

  1. Press Cmd+P (macOS) or Ctrl+P (Linux/Windows).
  2. Type add photo and press Enter to drop a new image into the gallery below.
  3. Repeat a few times to fill the grid.
  4. Type shuffle, Enter to re-randomize all photo URLs.
  5. Type remove last, Enter to pop the most recent photo.
  6. Type clear, Enter to empty the gallery.
  7. Type theme, Enter to toggle light/dark stage.
  8. Type confetti, Enter for a visual burst.
  9. Type print to fall through to the built-in browser Print command.
  10. Inside the palette you can also click rows with the mouse, not just Enter.
  11. Cmd/Ctrl+K also opens the palette as a helper shortcut.

Demo stage: image gallery

Gallery is empty Press Ctrl+P to begin.

Options

Note: the native palette is a real browser UI surface (like the Print dialog). It intentionally cannot be styled with page CSS. The page only contributes the list of commands. The polyfill fallback is page-rendered and cannot mimic the native look exactly.

Loading command set...

Activity log

Styling / theming

The native command palette is a real browser-process UI surface, the same category as the Chrome Print dialog or Find bar. It intentionally cannot be styled from page CSS (no selectors, no CSS custom properties, no ::part). Pages only contribute the command list. The polyfill fallback, when used, is page-rendered and not styling-compatible with the native surface.

JavaScript API documentation

This sampler uses manager from CommandPalettePolyfill.install(...). If native navigator.commandPalette exists and preferNative is true, manager is the native object.

API Type Description
manager.open boolean True when palette UI is open.
manager.show(options) Promise<void> Opens palette. Optional options.query pre-fills search, options.source defaults to "api", and options.includeBrowserCommands controls built-in commands when supported.
manager.close(reason) void Closes palette. Optional reason defaults to "dismissed".
manager.register(definition) object Registers command. Returns an object with id and unregister().
manager.unregister(id) void Removes one command by id.
manager.clear() void Removes all registered page commands.
manager.clearRecentUsage() void Resets recent usage ranking memory (polyfill method).
manager.setIncludeBrowserCommands(enabled) void Toggles built-in browser commands like Print at runtime (polyfill method).
manager.commandCount number Number of page commands currently registered (polyfill property).
manager.onopen, manager.onclose, manager.oncommand function|null Event handler properties for open, close, and command events.
manager.addEventListener(...) EventTarget Use event listeners for open, close, and command.

Command definition fields supported by this sampler/polyfill:

{
  id: "new-note",                  // required unique string
  title: "Create note",            // required label
  subtitle: "Optional details",
  keywords: ["new", "note"],
  icon: "optional-icon-token",
  group: "General",                // default: "General"
  enabled: true,                    // default: true
  pinned: false,                    // pinned commands rank higher
  supportsBackground: false,        // allows Cmd/Ctrl+Enter path
  handler: (context) => {
    // optional; command event still dispatches after handler
  }
}

Handler context and command event payload:

{
  commandId: "new-note",
  query: "note",
  source: "keyboard" | "api",
  background: false
}

Polyfill instructions

Use the standalone file from this folder:

<script src="./command-palette-polyfill.js"></script>

Or load it directly from this static host:

<script src="https://static.januschka.com/i-cmd-p/command-palette-polyfill.js"></script>

Install once after page load. This keeps native first, fallback second:

const installResult = CommandPalettePolyfill.install({
  preferNative: true,
  includeBrowserCommandsProvider: () => true
});

const cp = installResult.manager;

cp.register({
  id: "new-note",
  title: "Create note",
  keywords: ["new", "note"],
  handler: () => {
    console.log("new note");
  }
});

window.addEventListener("keydown", (event) => {
  const key = String(event.key || "").toLowerCase();
  const accel = (event.metaKey || event.ctrlKey) && key === "p" && !event.shiftKey && !event.altKey;
  if (!accel) return;
  event.preventDefault();
  cp.show({ source: "keyboard" });
});

Install options:

{
  preferNative: true,                    // default true
  includeBrowserCommandsProvider: () => true,
  includeBrowserCommandsByDefault: true  // optional fallback default
}

Show options:

cp.show({
  query: "note",                        // optional search text
  source: "api" | "keyboard",         // optional source marker
  includeBrowserCommands: true           // when supported
});

Installation return shape:

{
  manager,               // native or polyfill manager
  usingNative,           // boolean
  nativeAvailable,       // boolean
  mode,                  // "native" or "polyfill"
  installedOnNavigator   // boolean, polyfill only
}

Direct file link: command-palette-polyfill.js