v 0.2.0

@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)

ParameterTypeDescription
selectorstringCSS selector to match target elements (uses event delegation).
refstringValue of data-ref attribute to match (uses event delegation).
windowbooleanListen on the global window object.
documentbooleanListen on the global document object.

Event Configuration

ParameterTypeRequiredDescription
typestringYesEvent type (e.g., 'click', 'input', 'keydown').
optionsAddEventListenerOptionsNoStandard 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