Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/m-thompson-code/event-listener-types-output-target

Stencil output target to generate event listener types
https://github.com/m-thompson-code/event-listener-types-output-target

angular custom-elements ember event-listeners ionic output react stencil typescript vue web-components

Last synced: about 2 months ago
JSON representation

Stencil output target to generate event listener types

Awesome Lists containing this project

README

        

# event-listener-types-output-target

[Stencil](https://github.com/ionic-team/stencil) [output target](https://stenciljs.com/docs/output-targets) to generate event listener types

## Summary

Stencil components currently don't generate event listener types which can make consuming Stencil components difficult when wanting to add an event listener in a TypeScript project:

```ts
const myComponent = document.createElement('my-component');

myComponent.addEventListener('my-event', event => {
// TypeError: Property 'detail' does not exist on type 'Event'
event.detail;
});
```

This target output generates additional types to make events type safe:

```ts
const myComponent = document.createElement('my-component');

myComponent.addEventListener('my-event', event => {
// event is now of type MyComponentCustomEvent, and detail will
// have the proper type
event.detail;
});
```

This will also allow components to have proper Output binding types in Angular projects:

```ts
@Component({
selector: 'app-root',
template: ``,
})
export class AppComponent {
handleMyEvent(event: MyComponentCustomEvent) {
// event is properly typed now and can be consumed without
// needing to type `event` as Event or any then use type assertion
// to its proper type
event.detail;
}
}
```

## How to use

To export event listener types:

1. [Install `event-listener-types-output-target`](#install-event-listener-types-output-target)
2. [Update Stencil config to include `eventListenerTypesOutputTarget`](#update-stencil-config)
3. [Add `component-event-listeners.d.ts` to index file](#add-types-to-indexts)

### Install event-listener-types-output-target

```bash
npm i -D event-listener-types-output-target
```

### Update Stencil config

By default your Stencil config should be located at `stencil.config.ts`.
Update your Stencil config to use this output target:

```ts
import { Config } from '@stencil/core';
import { eventListenerTypesOutputTarget } from 'event-listener-types-output-target';

export const config: Config = {
// ...
outputTargets: [
// ...
eventListenerTypesOutputTarget(),
],
};
```

Now when you build, `component-event-listeners.d.ts` will be generated next to your `components.d.ts` file found at `src/component-event-listeners.d.ts`.

This is where `components.d.ts` is generated by default, but you can override where the `component-event-listeners.d.ts` files are generated by setting `outputPaths`:

```ts
import { Config } from '@stencil/core';
import { eventListenerTypesOutputTarget } from 'event-listener-types-output-target';

export const config: Config = {
// ...
outputTargets: [
// ...
eventListenerTypesOutputTarget({
outputPaths: ['some/custom/path/component-event-listeners.d.ts'],
}),
],
};
```

### Add types to `index.ts`

To include `component-event-listeners.d.ts` in your `dist`, you can add the generated types to your `index.ts` found at `src/index.ts`:

```ts
export * from './components';
export * from './component-event-listeners'; // <-- add this line
// ...
```

You'll get a type error if `component-event-listeners.d.ts` doesn't already exist, so be sure to generate one or add a placeholder like this one:

```ts
/** src/component-event-listeners */
// Doesn't matter what you export, but this file will need to export/import something something
export type Placeholder = 'This should be replaced automatically';
```

### Output target options

For more custom behavior such as changing the `outputPaths` to customize where the generated types files are saved, there are two other options:

1. `outputPaths` - Paths where generated event listener types will be stored. Path should include filename. Default if not defined is:
```ts
['src/component-event-listeners.d.ts'];
```
2. `importPath` - The generated event listener types depend on types from `components.d.ts`. Setting this will define the path where those types will be imported from. Default if not defined is:
```ts
'./components';
```
3. `excludeComponents` - List of components to not generate event listener types. Values should be the tag name of the component.

## Development

For development, code changes are lint/formatted on commit. New features should come with new tests.

```bash
npm i # Install dependencies
npm run test # Run unit tests
npm run test.watch # Run unit tests in watch mode
```