@event

The @event decorator creates an EventEmitter that provides a type-safe way to dispatch custom events from your component. Custom events are the primary way for components to communicate with their parents or other parts of the application.

Import the @event(...) decorator from @ecopages/radiant, but import the EventEmitter type from @ecopages/radiant/tools/event-emitter because it is a lower-level helper type.

Usage

import type { EventEmitter } from '@ecopages/radiant/tools/event-emitter';
import { RadiantElement, customElement, event, onEvent } from '@ecopages/radiant';
 
@customElement('counter-button')
export class CounterButton extends RadiantElement {
	@event({ name: 'count-changed', bubbles: true })
	countChanged!: EventEmitter<{ count: number }>;
	
	private count = 0;
	
	@onEvent({ selector: 'button', type: 'click' })
	handleClick() {
		this.count++;
		this.countChanged.emit({ count: this.count });
	}
}

The field type is an EventEmitter: see Typing Decorated Fields. @event works on RadiantElement only.

Parameters

The decorator accepts a configuration object:

ParameterTypeRequiredDescription
namestringYesThe event name (e.g., 'value-changed', 'item-selected').
bubblesbooleanNoWhether the event bubbles up the DOM. Omitted, it is false, the CustomEvent default.
composedbooleanNoWhether the event crosses shadow DOM boundaries. Omitted, it is false.
cancelablebooleanNoWhether the event can be cancelled. Omitted, it is false.

Set bubbles: true for a parent to hear the event through @onEvent or any delegated listener: both rely on bubbling.

Type Safety

You can define interfaces for your event details to ensure type safety when emitting events:

interface UserSelectedDetail {
	userId: string;
	userName: string;
}
 
@customElement('user-list')
export class UserList extends RadiantElement {
	@event({ name: 'user-selected', bubbles: true })
	userSelected!: EventEmitter<UserSelectedDetail>;
	
	selectUser(user: User) {
		this.userSelected.emit({
			userId: user.id,
			userName: user.name,
		});
	}
}

Listening to Events

Components can listen to custom events from their children using the @onEvent decorator:

@customElement('parent-component')
export class ParentComponent extends RadiantElement {
	@onEvent({ selector: 'counter-button', type: 'count-changed' })
	handleCount(event: CustomEvent<{ count: number }>) {
		console.log('Count is now:', event.detail.count);
	}
}

Learn More