Skip to main content

Events

Define Events​

You can define events on your component next to its properties by using the event function.

note

Event names must start with on and follow camelCase convention.

class TaskListItem extends Component("task-list-item", {
text: prop<string>(""),
completed: prop<boolean>(false),
onCompletedChange: event<{ completed: boolean }>(),
}) {
// …
}

By default a CustomEvent will be created for dispatch. You can also specify a different event constructor, either your own or another native event constructor. Sinho expects the first constructor argument to be the event name and the second argument to be the event details that is passed to the event emitter:

class CompletedChangeEvent extends Event {
detail: { completed: boolean };

constructor(name: string, completed: boolean) {
super(name);

this.detail.completed = completed;
}
}

class TaskListItem extends Component("task-list-item", {
text: prop<string>(""),
completed: prop<boolean>(false),
onCompletedChange: event(CompletedChangeEvent),
}) {
// …
}

Dispatch Events​

To emit an event you can call the corresponding method in this.events:

class TaskListItem extends Component("task-list-item", {
text: prop<string>(""),
completed: prop<boolean>(false),
onCompletedChange: event<{ completed: boolean }>(),
}) {
render() {
return (
<>
<input
type="checkbox"
checked={this.props.completed}
onchange={(evt) => {
this.events.onCompletedChange({
details: {
completed: !evt.currentTarget.checked,
},
});
}}
/>
{/* … */}
</>
);
}
}

When a different event constructor is used, the event details are passed as second constructor argument:

class CompletedChangeEvent extends Event {
completed: boolean;

constructor(name: string, completed: boolean) {
super(name);

this.completed = completed;
}
}

class TaskListItem extends Component("task-list-item", {
text: prop<string>(""),
completed: prop<boolean>(false),
onCompletedChange: event(CompletedChangeEvent),
}) {
render() {
return (
<>
<input
type="checkbox"
checked={this.props.completed}
onchange={(evt) => {
this.events.onCompletedChange(!evt.currentTarget.checked);
}}
/>
{/* … */}
</>
);
}
}

The emitter function this.events.onCompletedChange will return false if the event is cancelable and at least one of the event listeners called evt.preventDefault(), otherwise true.

Listen to Events​

In JS​

Events can be listened to on the outside by using the addEventListener method:

const el = new TaskListItem();

el.addEventListener("completed-change", (evt) => {
console.log(evt.detail.completed);
});

Note that the native event name is the kebab-case version without the on prefix of the name defined in the component, e.g. onCompletedChange will be assigned to completed-change.

In JSX​

In JSX templates, you can specify event listeners as attributes:

<TaskListItem
onCompletedChange={(evt) => {
console.log(evt.detail.completed);
}}
/>