Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/TinkoffCreditSystems/ng-event-plugins
This is an Angular library for optimizing performance sensitive events and declarative preventDefault, stopPropagation and capture phase listeners.
https://github.com/TinkoffCreditSystems/ng-event-plugins
angular angular-library capture events optimization preventdefault stoppropagation trigger-change-detection
Last synced: 3 months ago
JSON representation
This is an Angular library for optimizing performance sensitive events and declarative preventDefault, stopPropagation and capture phase listeners.
- Host: GitHub
- URL: https://github.com/TinkoffCreditSystems/ng-event-plugins
- Owner: Tinkoff
- License: apache-2.0
- Archived: true
- Created: 2020-02-05T15:11:21.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2023-05-26T03:34:56.000Z (over 1 year ago)
- Last Synced: 2024-04-10T07:09:37.327Z (7 months ago)
- Topics: angular, angular-library, capture, events, optimization, preventdefault, stoppropagation, trigger-change-detection
- Language: TypeScript
- Homepage: https://codesandbox.io/s/github/TinkoffCreditSystems/ng-event-plugins/tree/master/projects/demo
- Size: 2 MB
- Stars: 232
- Watchers: 11
- Forks: 12
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# Angular Event Plugins
[![npm version](https://img.shields.io/npm/v/@tinkoff/ng-event-plugins.svg)](https://npmjs.com/package/@tinkoff/ng-event-plugins)
[![npm bundle size](https://img.shields.io/bundlephobia/minzip/@tinkoff/ng-event-plugins)](https://bundlephobia.com/result?p=@tinkoff/ng-event-plugins)
[![Coverage Status](https://coveralls.io/repos/github/TinkoffCreditSystems/ng-event-plugins/badge.svg?branch=master)](https://coveralls.io/github/TinkoffCreditSystems/ng-event-plugins?branch=master)
[![angular-open-source-starter](https://img.shields.io/badge/made%20with-angular--open--source--starter-d81676?logo=angular)](https://github.com/TinkoffCreditSystems/angular-open-source-starter)
[![telegram chat](https://img.shields.io/badge/support-Contact%20us-blue)](https://t.me/taiga_ui)**@tinkoff/ng-event-plugins** is a tiny (1KB gzip) library for optimizing change detection cycles for performance
sensitive events (such as _touchmove_, _scroll_, _drag_ etc.) and declarative _preventDefault()_ and
_stopPropagation()_.## How to use
1. Add `EventPluginsModule` to your app module:
```typescript
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {EventPluginsModule} from '@tinkoff/ng-event-plugins'; // <-- THIS@NgModule({
bootstrap: [
/*...*/
],
imports: [
/*...*/
BrowserModule,
EventPluginsModule, // <-- GOES HERE
],
declarations: [
/*...*/
],
})
export class AppModule {}
```> `BrowserModule` or `BrowserAnimationsModule` must go first. You will see a warning if you mess the order.
2. Use new modifiers for events in templates and in `@HostListener`:
- `.stop` to call stopPropagation() on event
- `.prevent` to call preventDefault() on event
- `.self` to skip bubbled events
- `.silent` to call event handler outside Angular's `NgZone`
- `.capture` to listen to events in
[capture phase](https://developer.mozilla.org/en-US/docs/Web/API/Event/eventPhase)
- `.passive` to add
[passive event listener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#improving_scrolling_performance_with_passive_listeners)
- `.once` to remove event listener after first callbackFor example:
```html
Clicking on this DIV will not move focus
``````html
Clicks on this DIV will not bubble up
``````html
Callbacks to mousemove will not trigger change detection
``````html
Clicks will be stopped before reaching this DIV
```3. You can also re-enter `NgZone` and trigger change detection, using `@shouldCall` decorator that takes a predicate
function as argument:```html
Scrolling this DIV will only trigger change detection and onScroll callback if it is scrolled to bottom
``````typescript
import {shouldCall} from '@tinkoff/ng-event-plugins';export function scrollFilter({
scrollTop, scrollHeight, clientHeight
}: HTMLElement): boolean {
return scrollTop === scrollHeight - clientHeight;
}// ...
@shouldCall(scrollFilter)
onScroll(_element: HTMLElement): void {
this.someService.requestMoreData();
}
```> All examples above work the same when used with `@HostListener` and `CustomEvent`
### Important notes
- Predicate is called with the same arguments as the decorated method and in the context of class instance (has access
to `this`)- Decorated method will be called and change detection triggered if predicate returns `true`.
- Predicates must be exported named function for AOT, arrow functions will trigger build error.
- `.silent` modifier will not work with built-in keyboard pseudo-events, such as `keydown.enter` or `keydown.arrowDown`
since Angular re-enters `NgZone` inside internal handlers.## Observable host bindings
In this library there's also a plugin that enables observable host bindings. Sounds weird to do host binding with event
plugin, but the code is actually pretty simple. You can read more about it in
[this article](https://indepth.dev/posts/1429/making-hostbinding-work-with-observables).To use it you need to couple `@HostListener` and `@HostBinding` on the same `Observable` property with following syntax:
```ts
@HostBinding('$.disabled')
@HostListener('$.disabled')
readonly disabled$ = asCallable(this.service.loading$)
```This supports all the native Angular syntax, such as `class.class-name` or `style.width.px`.
**IMPORTANT NOTES:**
- Until [this issue](https://github.com/angular/angular/issues/12045) is resolved you would have to use
`NO_ERRORS_SCHEMA` in your module in order to bind to arbitrary properties
- `asCallable` is a utility function from this library that simply adds `Function` to the type so Angular thinks it
could be a host listener
- To bind attributes you need to add `.attr` modifier in the end, not the beginning like in basic Angular binding. This
is due to Angular using regexp to match for `attr.` string in `@HostBinding` decorator:```ts
@HostBinding('$.aria-label.attr')
@HostListener('$.aria-label.attr')
readonly label$ = asCallable(this.translations.get$('label'));
```## Demo
You can try this
[interactive demo](https://codesandbox.io/s/github/TinkoffCreditSystems/ng-event-plugins/tree/master/projects/demo)You can also read this [detailed article](https://indepth.dev/supercharge-event-management-in-your-angular-application/)
explaining how this library works## Maintained
**@tinkoff/ng-event-plugins** is a part of [Taiga UI](https://github.com/Tinkoff/taiga-ui) libraries family which is backed and used by a
large enterprise. This means you can rely on timely support and continuous development.## License
🆓 Feel free to use our library in your commercial and private applications
All **@tinkoff/ng-event-plugins** packages are covered by [Apache 2.0](/LICENSE)
Read more about this license [here](https://choosealicense.com/licenses/apache-2.0/)
## Open-source
Do you also want to open-source something, but hate the collateral work? Check out this
[Angular Open-source Library Starter](https://github.com/TinkoffCreditSystems/angular-open-source-starter) we’ve created
for our projects. It got you covered on continuous integration, pre-commit checks, linting, versioning + changelog, code
coverage and all that jazz.