event-handler
Stitch behaviors of your app together, primarily through events.
Features
- Fire custom events Map any input event, such as clicks, or lifecycles to custom output events
- Commands
command-nameinvokes the HTML Command API — built-in verbs (show-modal) and the--verbcommands elements accept (--submit,--close) - Retarget Aim events/commands at any selector (
target-ref) — where a<button commandfor>needs an id - Global / host listening Listen to events globally or on any element. Helpful for: escape to dismiss, global shortcuts, etc.
- Keycode filter Escape to dismiss, Shift+K shortcuts — keys / modifier chords
- Listen filters Debounce, selector, and pathname gates
- Custom Event Payloads
detail-*attributes and forms convert toevent.detailJSON
In a view that already has a
<quark-sheet>, the same wiring is a rule:@on click (target: "[data-add]") { @dispatch cart-add (detail: (sku: attr("data-sku"))); }—@onoptions coverselector-filter/keycode-filter/is-debounced/host-ref, and@dispatch/@commandcoverfire-event/target-ref/form-ref/command-name. Keep<event-handler>for markup without a sheet.
Installation
This package is available in the
<script src="https://unpkg.com/@excom/kit-utils@0.3.0/dist/index.umd.min.js"></script>
<script src="https://unpkg.com/@excom/neutron@0.2.0/dist/index.umd.min.js"></script>
<script src="https://unpkg.com/@excom/event-handler@0.1.4/dist/index.umd.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/@excom/event-handler@0.1.4/dist/index.css">npm install @excom/event-handler<!-- import path to `node_modules` will depend on your build setup -->
<script type="module" src="/node_modules/@excom/event-handler"></script>
<link rel="stylesheet" href="/node_modules/@excom/event-handler">import "@excom/event-handler";@import "@excom/event-handler/index.css";Peer dependencies (0)
Packages a consumer must install alongside this one. Workspace deps are bundled.
| Package | Version |
|---|---|
|
Usage
Listen (default click), then either fire-event or command-name.
<event-handler fire-event="cart-add">
Add to cart
</event-handler><event-handler fire-event="cart-add">
Add to cart
</event-handler>Or, for example: a successful form submit re-fetches the related data by invoking the provider's --fetch command.
<event-handler listen-for="super-form-success" target-ref="#fetch-todos" command-name="--fetch">
<super-form>
<form>
<!-- form to create a new todo -->
</form>
</super-form>
</event-handler><event-handler listen-for="super-form-success" target-ref="#fetch-todos" command-name="--fetch">
<super-form>
<form>
<!-- form to create a new todo -->
</form>
</super-form>
</event-handler>In a Nucleus Stack application, this will be one of the most heavily used elements. It is the primary method of linking a functional cause and effect.
API Reference
Attributes
Role —option is configurable, state
is managed by the element (read-only), or hybrid which is both.
Provision
Thisprovision property lives on the DOM node.
Read / watch it with Quark’s prop("provision"), or listen
for the neutron-provision event from app JS.
Events
Type
command event (HTML Command API): from a
<button command commandfor>, an <event-handler
command-name>, or a CommandEvent.
Recognized Elements
Child or descendant elements are recognized by and relevant to its functionality.Styles
@custom-selector synonyms so custom elements can share
semantic styles. Element aliases match the host tag / .tag-* class; state
aliases match attributes (nested under the element alias).
event-handler
Attributes (21)
Role —option is configurable, state
is managed by the element (read-only), or hybrid which is both.
command-name
--verb commands (--submit, --close) dispatch a command event, as a <button command commandfor> would; built-in verbs (show-modal, close, toggle-popover) run through the platform.
commandName
tokenlist
<command>…nulldelay-ms
delayMs
number
nullfire-event
detail. Ignored when mutate-target is set. Pair with detail-* attributes for static detail fields.
fireEvent
tokenlist
<EventName>…nullform-ref
<form> whose fields merge into event detail, or become attributes when mutate-target is set.
formRef
string
<CSS Selector>nullhost-ref
window / document — e.g. Escape to dismiss a dialog from a global keydown. Defaults to :scope. Used with listen-for. Not compatible with listen-for-lifecycle. The selector MUST resolve when host-ref is set — it will not wait for a match to appear.
hostRef
string
<CSS Selector> | "window" | "document" | "html" | "body" | "head"nullis-debounced
delay-ms, coalesce bursts into one trailing call (debounce).
isDebounced
boolean
falsekeycode-filter
+ (AND, any order): shift+k tab → Shift+K or Tab. Modifiers: shift, alt, ctrl/control, meta/cmd. Name the space bar space / spacebar and the plus key plus (shift+space). Case-insensitive.
keycodeFilter
tokenlist
<key | mod+key>…nulllisten-for
click when unset (and no lifecycle list is set).
listenFor
tokenlist
<EventName>…nulllisten-for-lifecycle
listenForLifecycle
tokenlist
"connected" | "disconnected" | "adopted"nulllisten-once
listenOnce
boolean
falsemutate-target
attr-* on this element plus form-ref fields). Use a Quark @on <event> { … } block instead — it writes State from the event without one element mutating another. Kept for compatibility; will be removed in a future major.
mutateTarget
boolean
falsenot-bubbles
bubbles: false (default: bubble).
notBubbles
boolean
falsenot-cancelable
cancelable: false (default: cancelable).
notCancelable
boolean
falsenot-composed
composed: false (default: composed / cross shadow roots).
notComposed
boolean
falsepathname-filter
location.pathname is one of these values — route-aware behaviors without a separate router element.
pathnameFilter
tokenlist
<pathname>…nullprevent-default
preventDefault() on matched events (ignored for lifecycles).
preventDefault
boolean
falseselector-filter
event.target matches this CSS selector. Does not support :scope in the selector.
selectorFilter
string
<CSS Selector>nullstop-immediate-propagation
stopImmediatePropagation() on matched events (ignored for lifecycles).
stopImmediatePropagation
boolean
falsestop-propagation
stopPropagation() on matched events (ignored for lifecycles).
stopPropagation
boolean
falsetarget-ref
:scope for relative targeting (e.g. :scope ~ dialog).
targetRef
string
<CSS Selector>nullvibrate-ms
navigator.vibrate). Empty / 0 uses a 20ms pulse.
vibrateMs
number
"20 (when attribute is present with no value)"Provision (0)
Thisprovision property lives on the DOM node.
Read / watch it with Quark’s prop("provision"), or listen
for the neutron-provision event from app JS.
Events (0)
e.preventDefault() is not
synchronously called on the event.
Type
command event (HTML Command API): from a
<button command commandfor>, an <event-handler
command-name>, or a CommandEvent.
Recognized Elements (0)
Child or descendant elements are recognized by event-handler and relevant to its functionality.Styles (2)
.unstyledall: revert-layer.
Valence.css ships this as .unstyled and .unstyled-all for the entire tree.
@custom-selector synonyms so custom elements can share
semantic styles. Element aliases match the host tag / .tag-* class; state
aliases match attributes (nested under the element alias).
:--event-handlerevent-handler, .tag-event-handlerRelease notes (1)
0.1.1
- Ship only dist (and declared extras) in the npm tarball; drop build logs, tests and sources
Release notes
e.preventDefault() is not
synchronously called on the event.
all: revert-layer.
Valence.css ships this as .unstyled and .unstyled-all for the entire tree.
Examples
Fire a custom event
Click dispatches cart-add event with { sku: "sku-1" } in event.detail.
Open a dialog
command-name invokes the HTML Command API — here the built-in show-modal opens the sibling <dialog>. Custom commands (command-name="--close") reach any element that handles them, such as <content-drawer>, through a relative target-ref.
Close on Enter
keycode-filter gates keyboard handling — here Enter, focused in the
input, invokes the drawer's --close command (local / bubbling events only).
Escape to dismiss (global)
host-ref="window" listens for keydown on the window — Escape closes
the dialog even when focus is outside it.
Cancel a link click
prevent-default cancels the native action — here the wrapped <a> never navigates.
Use stop-propagation / stop-immediate-propagation the same way when you need to stop bubbling.
Retarget
target-ref aims the outgoing event at another element — useful when the target sits outside of the bubble path.
Debounced input / form data
Inherited delay-ms + is-debounced coalesce noisy input into one search-query event. Demo below is debounced every 200ms.
Also demonstrated is form conversion into JSON: text -> string, checkbox -> boolean, etc. Including the data structure: detail.strict -> {detail: {strict}}.