@ogs-gmbh/ngx-utils
Version:
A lightweight collection of utility functions and helpers for Angular applications
69 lines • 7.04 kB
JavaScript
import { Directive, ElementRef, EventEmitter, inject, input, Output } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { fromEvent, throttleTime } from 'rxjs';
import * as i0 from "@angular/core";
/**
* Throttles click events on an HTML element.
*
* @remarks
* Prevents rapid repeated clicks by allowing only one `(throttleClick)` event
* to fire within the configured interval. Works with any clickable element.
*
* @example **Template (HTML)**
* ```html
* <button
* (throttleClick)="onCounterClick($event)"
* [throttleTimeMs]="300">
* Counter
* </button>
* ```
*
* @example **Component (TypeScript)**
* ```ts
* @Component({
* standalone: true,
* selector: 'app-foo',
* imports: [ThrottleClickDirective]
* })
* export class FooComponent {
* onCounterClick(mouseEvent: MouseEvent): void {
* // ...
* }
* }
* ```
*/
export class ThrottleClickDirective {
_element = inject(ElementRef);
/**
* Whether the first click is emitted - default is true
*/
leading = input(true);
/**
* Whether the last click is emitted - default is true
*/
trailing = input(true);
throttleTimeMs = input(800);
throttleClick = new EventEmitter();
constructor() {
fromEvent(this._element.nativeElement, "click")
.pipe(throttleTime(this.throttleTimeMs(), undefined, {
leading: this.leading(),
trailing: this.trailing()
}), takeUntilDestroyed())
.subscribe((mouseEvent) => {
this.throttleClick.emit(mouseEvent);
});
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ThrottleClickDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.14", type: ThrottleClickDirective, isStandalone: true, selector: "[throttleClick]", inputs: { leading: { classPropertyName: "leading", publicName: "leading", isSignal: true, isRequired: false, transformFunction: null }, trailing: { classPropertyName: "trailing", publicName: "trailing", isSignal: true, isRequired: false, transformFunction: null }, throttleTimeMs: { classPropertyName: "throttleTimeMs", publicName: "throttleTimeMs", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { throttleClick: "throttleClick" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ThrottleClickDirective, decorators: [{
type: Directive,
args: [{
selector: '[throttleClick]',
standalone: true
}]
}], ctorParameters: () => [], propDecorators: { throttleClick: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhyb3R0bGUtY2xpY2suZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2RpcmVjdGl2ZXMvdGhyb3R0bGUtY2xpY2suZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFlLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4RyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQzs7QUFFL0M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNkJHO0FBS0gsTUFBTSxPQUFPLHNCQUFzQjtJQUNoQixRQUFRLEdBQTRCLE1BQU0sQ0FBMEIsVUFBVSxDQUFDLENBQUM7SUFFakc7O09BRUc7SUFDSSxPQUFPLEdBQXlCLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVuRDs7T0FFRztJQUNJLFFBQVEsR0FBeUIsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRTdDLGNBQWMsR0FBd0IsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRTlCLGFBQWEsR0FBNkIsSUFBSSxZQUFZLEVBQWMsQ0FBQztJQUVuRztRQUNFLFNBQVMsQ0FBYSxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsRUFBRSxPQUFPLENBQUM7YUFDeEQsSUFBSSxDQUNILFlBQVksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUUsU0FBUyxFQUFFO1lBQzdDLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ3ZCLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFO1NBQzFCLENBQUMsRUFDRixrQkFBa0IsRUFBRSxDQUNyQjthQUNBLFNBQVMsQ0FBQyxDQUFDLFVBQXNCLEVBQUUsRUFBRTtZQUNwQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN0QyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7d0dBN0JVLHNCQUFzQjs0RkFBdEIsc0JBQXNCOzs0RkFBdEIsc0JBQXNCO2tCQUpsQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxpQkFBaUI7b0JBQzNCLFVBQVUsRUFBRSxJQUFJO2lCQUNqQjt3REFnQjJCLGFBQWE7c0JBQXRDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgaW5qZWN0LCBpbnB1dCwgSW5wdXRTaWduYWwsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgZnJvbUV2ZW50LCB0aHJvdHRsZVRpbWUgfSBmcm9tICdyeGpzJztcblxuLyoqXG4gKiBUaHJvdHRsZXMgY2xpY2sgZXZlbnRzIG9uIGFuIEhUTUwgZWxlbWVudC5cbiAqXG4gKiBAcmVtYXJrc1xuICogUHJldmVudHMgcmFwaWQgcmVwZWF0ZWQgY2xpY2tzIGJ5IGFsbG93aW5nIG9ubHkgb25lIGAodGhyb3R0bGVDbGljaylgIGV2ZW50XG4gKiB0byBmaXJlIHdpdGhpbiB0aGUgY29uZmlndXJlZCBpbnRlcnZhbC4gV29ya3Mgd2l0aCBhbnkgY2xpY2thYmxlIGVsZW1lbnQuXG4gKlxuICogQGV4YW1wbGUgKipUZW1wbGF0ZSAoSFRNTCkqKlxuICogYGBgaHRtbFxuICogPGJ1dHRvblxuICogICAodGhyb3R0bGVDbGljayk9XCJvbkNvdW50ZXJDbGljaygkZXZlbnQpXCJcbiAqICAgW3Rocm90dGxlVGltZU1zXT1cIjMwMFwiPlxuICogIENvdW50ZXJcbiAqIDwvYnV0dG9uPlxuICogYGBgXG4gKlxuICogQGV4YW1wbGUgKipDb21wb25lbnQgKFR5cGVTY3JpcHQpKipcbiAqIGBgYHRzXG4gKiBAQ29tcG9uZW50KHtcbiAqICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAqICAgc2VsZWN0b3I6ICdhcHAtZm9vJyxcbiAqICAgaW1wb3J0czogW1Rocm90dGxlQ2xpY2tEaXJlY3RpdmVdXG4gKiB9KVxuICogZXhwb3J0IGNsYXNzIEZvb0NvbXBvbmVudCB7XG4gKiAgIG9uQ291bnRlckNsaWNrKG1vdXNlRXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAqICAgICAvLyAuLi5cbiAqICAgfVxuICogfVxuICogYGBgXG4gKi9cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1t0aHJvdHRsZUNsaWNrXScsXG4gIHN0YW5kYWxvbmU6IHRydWVcbn0pXG5leHBvcnQgY2xhc3MgVGhyb3R0bGVDbGlja0RpcmVjdGl2ZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2VsZW1lbnQ6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+ID0gaW5qZWN0PEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+PihFbGVtZW50UmVmKTtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgZmlyc3QgY2xpY2sgaXMgZW1pdHRlZCAtIGRlZmF1bHQgaXMgdHJ1ZVxuICAgKi9cbiAgcHVibGljIGxlYWRpbmc6IElucHV0U2lnbmFsPGJvb2xlYW4+ID0gaW5wdXQodHJ1ZSk7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGxhc3QgY2xpY2sgaXMgZW1pdHRlZCAtIGRlZmF1bHQgaXMgdHJ1ZVxuICAgKi9cbiAgcHVibGljIHRyYWlsaW5nOiBJbnB1dFNpZ25hbDxib29sZWFuPiA9IGlucHV0KHRydWUpO1xuXG4gIHB1YmxpYyB0aHJvdHRsZVRpbWVNczogSW5wdXRTaWduYWw8bnVtYmVyPiA9IGlucHV0KDgwMCk7XG5cbiAgQE91dHB1dCgpIHB1YmxpYyByZWFkb25seSB0aHJvdHRsZUNsaWNrOiBFdmVudEVtaXR0ZXI8TW91c2VFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPE1vdXNlRXZlbnQ+KCk7XG5cbiAgY29uc3RydWN0b3IgKCkge1xuICAgIGZyb21FdmVudDxNb3VzZUV2ZW50Pih0aGlzLl9lbGVtZW50Lm5hdGl2ZUVsZW1lbnQsIFwiY2xpY2tcIilcbiAgICAgIC5waXBlKFxuICAgICAgICB0aHJvdHRsZVRpbWUodGhpcy50aHJvdHRsZVRpbWVNcygpLCB1bmRlZmluZWQsIHtcbiAgICAgICAgICBsZWFkaW5nOiB0aGlzLmxlYWRpbmcoKSxcbiAgICAgICAgICB0cmFpbGluZzogdGhpcy50cmFpbGluZygpXG4gICAgICAgIH0pLFxuICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQoKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgobW91c2VFdmVudDogTW91c2VFdmVudCkgPT4ge1xuICAgICAgICB0aGlzLnRocm90dGxlQ2xpY2suZW1pdChtb3VzZUV2ZW50KTtcbiAgICAgIH0pO1xuICB9XG59XG4iXX0=