Trigger plugins
The five built-in triggers (hover, click, focus, viewport, idle) cover most cases. For everything else, mountly ships a small trigger plugin API and four ready-made plugins.
import { registerTriggerPlugin, unregisterTriggerPlugin, getTriggerPlugin, getAllTriggerPlugins, createPluginTrigger, registerBuiltInPlugins, // Built-ins: createSwipeTrigger, createLongPressTrigger, createKeyboardTrigger, createUrlChangeTrigger,} from "mountly";Built-in plugins
Section titled “Built-in plugins”createSwipeTrigger(element, callback, options?)
Section titled “createSwipeTrigger(element, callback, options?)”Touch swipe gesture detection. Returns a cleanup function.
const cleanup = createSwipeTrigger( panelElement, () => panelFeature.activate(), { direction: "left", threshold: 60 });| Option | Type | Default | Notes |
|---|---|---|---|
direction | "up" · "down" · "left" · "right" | "left" | Required swipe direction. |
threshold | number px | 40 | Minimum distance for a swipe. |
velocity | number px/ms | 0.3 | Minimum velocity. |
createLongPressTrigger(element, callback, options?)
Section titled “createLongPressTrigger(element, callback, options?)”Mouse / touch long-press. Cancels on movement past tolerance px.
const cleanup = createLongPressTrigger( contextMenuTarget, () => menuFeature.activate(), { duration: 600, tolerance: 8 });| Option | Type | Default | Notes |
|---|---|---|---|
duration | number ms | 500 | Hold time before firing. |
tolerance | number px | 10 | Cancel if pointer moves further than this. |
createKeyboardTrigger(callback, options)
Section titled “createKeyboardTrigger(callback, options)”Single key or chord shortcut. Listens at the document level.
const cleanup = createKeyboardTrigger( () => commandPaletteFeature.activate(), { key: "k", meta: true } // Cmd+K / Ctrl+K);| Option | Type | Default | Notes |
|---|---|---|---|
key | string | required | Matches event.key. |
meta | boolean | false | Require Meta on macOS, Ctrl on others. |
shift | boolean | false | Require Shift. |
alt | boolean | false | Require Alt. |
preventDefault | boolean | true | Call event.preventDefault() on match. |
createUrlChangeTrigger(element, callback, options?)
Section titled “createUrlChangeTrigger(element, callback, options?)”Listens for URL changes and fires when one matches.
const cleanup = createUrlChangeTrigger( pageContainer, () => billingFeature.activate(), { events: ["popstate", "pushstate"] });| Option | Type | Default | Notes |
|---|---|---|---|
events | ("popstate" | "hashchange" | "pushstate" | "replacestate")[] | all four | Which URL events to listen for. |
The plugin API
Section titled “The plugin API”A trigger plugin is an object that knows how to wire and unwire itself for an element.
interface TriggerPlugin { name: string; setup( element: HTMLElement, onTrigger: (ctx: TriggerContext) => void, options?: Record<string, unknown> ): () => void;}Register with registerTriggerPlugin:
registerTriggerPlugin({ name: "double-tap", setup(element, onTrigger, options) { let lastTap = 0; const handler = () => { const now = Date.now(); if (now - lastTap < (options?.window ?? 300)) onTrigger({ element, triggerType: "programmatic" }); lastTap = now; }; element.addEventListener("pointerup", handler); return () => element.removeEventListener("pointerup", handler); },});Then wire it via createPluginTrigger:
const cleanup = createPluginTrigger("double-tap", element, () => feature.activate(), { window: 250,});Discovery
Section titled “Discovery”getTriggerPlugin("double-tap"); // → TriggerPlugin | undefinedgetAllTriggerPlugins(); // → TriggerPlugin[]unregisterTriggerPlugin("double-tap");registerBuiltInPlugins()
Section titled “registerBuiltInPlugins()”Convenience to register the four shipped plugins under a known set of names. Call once if you want them discoverable via getTriggerPlugin. The standalone createSwipeTrigger etc. work without it.
Related
Section titled “Related”- Triggers — the conceptual overview, including the built-in five.