Skip to content

✨ events: deliver emitted events to host listeners - #27

Closed
cowboyd wants to merge 1 commit into
tree-focus-navigationfrom
tree-event-listener
Closed

cowboyd wants to merge 1 commit into
tree-focus-navigationfrom
tree-event-listener

Conversation

@cowboyd

@cowboyd cowboyd commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Stateful elements need to communicate outward in a way that works equally well for raw Host consumers and JSX frameworks. An input should be able to emit a semantic value change without importing React, Preact, or Solid, while adapters should be able to translate familiar properties such as onInput into the same listener mechanism. Host listeners and EmitApi provide that common outbound event path.

Listeners belong to element identity rather than a temporary attached node, so they can be registered before attachment and survive reparenting. The open HostEvents interface lets third-party element authors add strongly typed events through declaration merging, while the runtime verifies that an event’s target actually matches the node that emitted it. This is deliberately complementary to dispatch: dispatch carries external events into the tree, whereas emit carries semantic events from an element to its consumers.

import type { HostEvent } from '@clack/ui/events';
import { emit } from './emit.ts';

declare module '@clack/ui/events' {
	interface HostEvents {
		change: HostEvent<'change'> & { value: string };
	}
}

host.addEventListener(element, 'change', (event) => {
	console.log(event.value);
});

emit(element.node!, {
	type: 'change',
	value: 'next',
});

This PR adds HostEvent, the extensible HostEvents registry, EmitApi, and typed Host listener registration and removal. Listener storage is scoped by element and event type and remains stable across attachment changes. Tests cover ordering, identity, mutation during emission, type inference, target validation, and error propagation.

@cowboyd
cowboyd force-pushed the tree-event-listener branch from 60c16bc to 60c7146 Compare August 7, 2026 06:11
@cowboyd
cowboyd force-pushed the tree-event-listener branch from 60c7146 to 3e875f6 Compare August 7, 2026 06:21
@pkg-pr-new

pkg-pr-new Bot commented Aug 7, 2026 •

Copy link
Copy Markdown

commit: f8a59ba

@cowboyd
cowboyd force-pushed the tree-event-listener branch from 3e875f6 to bc70d0f Compare August 10, 2026 17:30
@cowboyd
cowboyd force-pushed the tree-event-listener branch from bc70d0f to d53a87f Compare August 10, 2026 21:14
@cowboyd
cowboyd force-pushed the tree-event-listener branch 2 times, most recently from 7dbe4ab to a643074 Compare August 11, 2026 04:27
@cowboyd
cowboyd force-pushed the tree-event-listener branch from a643074 to e639f2b Compare August 22, 2026 05:04
@cowboyd
cowboyd force-pushed the tree-event-listener branch from e639f2b to 60127ff Compare August 22, 2026 05:24
@cowboyd
cowboyd force-pushed the tree-event-listener branch from 60127ff to 51b0c3a Compare August 22, 2026 23:46
@cowboyd
cowboyd force-pushed the tree-event-listener branch from 51b0c3a to 9a699e9 Compare August 23, 2026 17:28
@cowboyd
cowboyd force-pushed the tree-event-listener branch from 9a699e9 to e1dc017 Compare September 18, 2026 21:15
@cowboyd
cowboyd force-pushed the tree-event-listener branch from e1dc017 to f8a59ba Compare September 24, 2026 14:00
@cowboyd

cowboyd commented Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

closing out in favor of a DOM based substrate. See #37

@cowboyd cowboyd closed this Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant