@onEvent
The @onEvent decorator provides a declarative way to subscribe to DOM events on elements within or outside your custom element. It automatically handles event subscription and unsubscription, ensuring no memory leaks when your component is removed from the DOM.
Usage
import { RadiantElement, customElement, onEvent } from '@ecopages/radiant';
@customElement('click-counter')
export class ClickCounter extends RadiantElement {
private count = 0;
@onEvent({ selector: 'button', type: 'click' })
handleClick(event: MouseEvent) {
this.count++;
console.log(`Clicked ${this.count} times`);
}
}
Parameters
The decorator accepts a configuration object. You must provide a target and an event type.
Target Selection (Choose one)
| Parameter | Type | Description |
|---|---|---|
selector | string | CSS selector to match target elements (uses event delegation). |
ref | string | Value of data-ref attribute to match (uses event delegation). |
window | boolean | Listen on the global window object. |
document | boolean | Listen on the global document object. |
Event Configuration
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Event type (e.g., 'click', 'input', 'keydown'). |
options | AddEventListenerOptions | No | Standard options like { passive: true, once: true }. |
Common Use Cases
Using data-ref
This is the recommended approach for referencing elements within your component's structure.
@onEvent({ ref: 'submit-btn', type: 'click' })
handleSubmit(event: MouseEvent) {
event.preventDefault();
console.log('Form submitted');
}
HTML:
<form-component>
<button data-ref="submit-btn" type="submit">Submit</button>
</form-component>
Window and Document Events
@onEvent({ window: true, type: 'scroll', options: { passive: true } })
handleScroll() {
console.log(`Scrolled to: ${window.scrollY}px`);
}
@onEvent({ document: true, type: 'keydown' })
handleKeyDown(event: KeyboardEvent) {
if (event.key === 'Escape') this.close();
}
Event Delegation for Non-Bubbling Events
Since selector and ref use event delegation, they rely on event bubbling. For events that don't bubble (like focus), use their bubbling alternatives (like focusin).
// ✅ Works: focusin bubbles
@onEvent({ selector: 'input', type: 'focusin' })
handleFocus() { /* ... */ }
Learn More
- Best Practices - Learn more about component design and events.
- @query - Query elements to use with events.
- @debounce - Debounce frequent event handlers.