@ethlete/core 0.2.0-next.6 → 0.2.0-next.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/esm2020/lib/directives/click-outside/click-outside.directive.mjs +3 -3
  2. package/esm2020/lib/directives/cursor-drag-scroll/cursor-drag-scroll.directive.mjs +45 -21
  3. package/esm2020/lib/directives/destroy/destroy.directive.mjs +22 -0
  4. package/esm2020/lib/directives/destroy/public-api.mjs +2 -0
  5. package/esm2020/lib/directives/let/let.directive.mjs +3 -3
  6. package/esm2020/lib/directives/observe-content/observe-content.directive.mjs +3 -3
  7. package/esm2020/lib/directives/observe-resize/observe-resize.directive.mjs +3 -3
  8. package/esm2020/lib/directives/observe-scroll-state/observe-scroll-state.directive.mjs +20 -5
  9. package/esm2020/lib/directives/public-api.mjs +9 -5
  10. package/esm2020/lib/directives/repeat/repeat.directive.mjs +3 -3
  11. package/esm2020/lib/directives/scroll-observer-first-element/index.mjs +2 -0
  12. package/esm2020/lib/directives/scroll-observer-first-element/public-api.mjs +2 -0
  13. package/esm2020/lib/directives/scroll-observer-first-element/scroll-observer-first-element.directive.mjs +31 -0
  14. package/esm2020/lib/directives/scroll-observer-ignore-target/scroll-observer-ignore-target.directive.mjs +3 -3
  15. package/esm2020/lib/directives/scroll-observer-last-element/index.mjs +2 -0
  16. package/esm2020/lib/directives/scroll-observer-last-element/public-api.mjs +2 -0
  17. package/esm2020/lib/directives/scroll-observer-last-element/scroll-observer-last-element.directive.mjs +34 -0
  18. package/esm2020/lib/directives/seo/public-api.mjs +5 -0
  19. package/esm2020/lib/directives/seo/seo.directive.constants.mjs +3 -0
  20. package/esm2020/lib/directives/seo/seo.directive.mjs +162 -0
  21. package/esm2020/lib/directives/seo/seo.directive.types.mjs +2 -0
  22. package/esm2020/lib/directives/seo/seo.directive.utils.mjs +7 -0
  23. package/esm2020/lib/pipes/to-array/to-array.pipe.mjs +3 -3
  24. package/esm2020/lib/services/click-observer.service.mjs +6 -6
  25. package/esm2020/lib/services/content-observer.service.mjs +6 -6
  26. package/esm2020/lib/services/destroy.service.mjs +6 -11
  27. package/esm2020/lib/services/focus-visible.service.mjs +3 -3
  28. package/esm2020/lib/services/public-api.mjs +6 -6
  29. package/esm2020/lib/services/resize-observer.service.mjs +6 -6
  30. package/esm2020/lib/services/viewport.service.mjs +3 -3
  31. package/fesm2015/ethlete-core.mjs +775 -499
  32. package/fesm2015/ethlete-core.mjs.map +1 -1
  33. package/fesm2020/ethlete-core.mjs +771 -496
  34. package/fesm2020/ethlete-core.mjs.map +1 -1
  35. package/lib/directives/click-outside/click-outside.directive.d.ts +1 -1
  36. package/lib/directives/cursor-drag-scroll/cursor-drag-scroll.directive.d.ts +8 -2
  37. package/lib/directives/destroy/destroy.directive.d.ts +9 -0
  38. package/lib/directives/destroy/public-api.d.ts +1 -0
  39. package/lib/directives/let/let.directive.d.ts +1 -1
  40. package/lib/directives/observe-content/observe-content.directive.d.ts +1 -1
  41. package/lib/directives/observe-resize/observe-resize.directive.d.ts +1 -1
  42. package/lib/directives/observe-scroll-state/observe-scroll-state.directive.d.ts +1 -1
  43. package/lib/directives/public-api.d.ts +8 -4
  44. package/lib/directives/repeat/repeat.directive.d.ts +1 -1
  45. package/lib/directives/scroll-observer-first-element/index.d.ts +1 -0
  46. package/lib/directives/scroll-observer-first-element/public-api.d.ts +1 -0
  47. package/lib/directives/scroll-observer-first-element/scroll-observer-first-element.directive.d.ts +10 -0
  48. package/lib/directives/scroll-observer-ignore-target/scroll-observer-ignore-target.directive.d.ts +1 -1
  49. package/lib/directives/scroll-observer-last-element/index.d.ts +1 -0
  50. package/lib/directives/scroll-observer-last-element/public-api.d.ts +1 -0
  51. package/lib/directives/scroll-observer-last-element/scroll-observer-last-element.directive.d.ts +10 -0
  52. package/lib/directives/seo/public-api.d.ts +4 -0
  53. package/lib/directives/seo/seo.directive.constants.d.ts +3 -0
  54. package/lib/directives/seo/seo.directive.d.ts +21 -0
  55. package/lib/directives/seo/seo.directive.types.d.ts +51 -0
  56. package/lib/directives/seo/seo.directive.utils.d.ts +2 -0
  57. package/lib/services/destroy.service.d.ts +1 -1
  58. package/lib/services/public-api.d.ts +5 -5
  59. package/package.json +5 -4
@@ -1,11 +1,12 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, Directive, Input, Injectable, Inject, Optional, inject, ElementRef, NgZone, EventEmitter, Output, Pipe } from '@angular/core';
3
- import { coerceNumberProperty, coerceElement, coerceBooleanProperty } from '@angular/cdk/coercion';
4
- import { BehaviorSubject, combineLatest, map, shareReplay, Observable, Subject, fromEvent, debounceTime, tap, takeUntil, take } from 'rxjs';
2
+ import { InjectionToken, Injectable, inject, Inject, Optional, ElementRef, EventEmitter, Directive, Output, Input, NgZone, HostBinding, Pipe } from '@angular/core';
3
+ import { coerceElement, coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
4
+ import { fromEvent, Observable, Subject, BehaviorSubject, combineLatest, map, shareReplay, startWith, debounceTime, tap, takeUntil, take } from 'rxjs';
5
+ import { DOCUMENT } from '@angular/common';
5
6
  import { __decorate, __metadata } from 'tslib';
6
7
  import * as i1 from '@angular/cdk/layout';
7
- import { DOCUMENT } from '@angular/common';
8
8
  import { debounceTime as debounceTime$1 } from 'rxjs/operators';
9
+ import { Meta, Title } from '@angular/platform-browser';
9
10
 
10
11
  const VIEWPORT_CONFIG = new InjectionToken('ViewportConfig');
11
12
  /**
@@ -48,131 +49,313 @@ const Memo = (config = {}) => (_, __, descriptor) => {
48
49
  return descriptor;
49
50
  };
50
51
 
51
- class LetContext {
52
- constructor() {
53
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
54
- this.$implicit = null;
55
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
56
- this.etLet = null;
52
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
53
+ class ClickObserverFactory {
54
+ create() {
55
+ return fromEvent(document, 'click');
57
56
  }
58
57
  }
59
-
60
- class LetDirective {
61
- constructor(_viewContainer, templateRef) {
62
- this._viewContainer = _viewContainer;
63
- this._context = new LetContext();
64
- this._templateRef = null;
65
- this._viewRef = null;
66
- this._templateRef = templateRef;
58
+ ClickObserverFactory.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ClickObserverFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
59
+ ClickObserverFactory.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ClickObserverFactory, providedIn: 'root' });
60
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ClickObserverFactory, decorators: [{
61
+ type: Injectable,
62
+ args: [{ providedIn: 'root' }]
63
+ }] });
64
+ class ClickObserverService {
65
+ constructor(_clickObserverFactory) {
66
+ this._clickObserverFactory = _clickObserverFactory;
67
+ this._observedElements = new Map();
67
68
  }
68
- set etLet(value) {
69
- this._context.$implicit = this._context.etLet = value;
70
- this._updateView();
69
+ ngOnDestroy() {
70
+ this._observedElements.forEach((_, element) => this._cleanupObserver(element));
71
71
  }
72
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
73
- static ngTemplateContextGuard(dir, ctx) {
74
- return true;
72
+ observe(elementOrRef) {
73
+ const element = coerceElement(elementOrRef);
74
+ return new Observable((observer) => {
75
+ const stream = this._observeElement(element);
76
+ const subscription = stream.subscribe(observer);
77
+ return () => {
78
+ subscription.unsubscribe();
79
+ this._unobserveElement(element);
80
+ };
81
+ });
75
82
  }
76
- _updateView() {
77
- if (!this._viewRef) {
78
- this._viewContainer.clear();
79
- if (this._templateRef) {
80
- this._viewRef = this._viewContainer.createEmbeddedView(this._templateRef, this._context);
83
+ _observeElement(element) {
84
+ if (!this._observedElements.has(element)) {
85
+ const stream = new Subject();
86
+ const observer = this._clickObserverFactory.create();
87
+ const sub = observer.subscribe((event) => stream.next(event));
88
+ this._observedElements.set(element, { observer: sub, stream, count: 1 });
89
+ }
90
+ else {
91
+ this._observedElements.get(element).count++;
92
+ }
93
+ return this._observedElements.get(element).stream;
94
+ }
95
+ _unobserveElement(element) {
96
+ if (this._observedElements.has(element)) {
97
+ this._observedElements.get(element).count--;
98
+ if (!this._observedElements.get(element).count) {
99
+ this._cleanupObserver(element);
100
+ }
101
+ }
102
+ }
103
+ _cleanupObserver(element) {
104
+ if (this._observedElements.has(element)) {
105
+ const { observer, stream } = this._observedElements.get(element);
106
+ if (observer) {
107
+ observer.unsubscribe();
81
108
  }
109
+ stream.complete();
110
+ this._observedElements.delete(element);
82
111
  }
83
112
  }
84
113
  }
85
- LetDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: LetDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
86
- LetDirectivedir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.9", type: LetDirective, isStandalone: true, selector: "[etLet]", inputs: { etLet: "etLet" }, ngImport: i0 });
87
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: LetDirective, decorators: [{
88
- type: Directive,
89
- args: [{
90
- selector: '[etLet]',
91
- standalone: true,
92
- }]
93
- }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.TemplateRef }]; }, propDecorators: { etLet: [{
94
- type: Input
95
- }] } });
114
+ ClickObserverService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ClickObserverService, deps: [{ token: ClickObserverFactory }], target: i0.ɵɵFactoryTarget.Injectable });
115
+ ClickObserverServiceprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ClickObserverService, providedIn: 'root' });
116
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ClickObserverService, decorators: [{
117
+ type: Injectable,
118
+ args: [{ providedIn: 'root' }]
119
+ }], ctorParameters: function () { return [{ type: ClickObserverFactory }]; } });
96
120
 
97
- class RepeatDirective {
98
- constructor(_mainTemplateRef, _viewContainerRef) {
99
- this._mainTemplateRef = _mainTemplateRef;
100
- this._viewContainerRef = _viewContainerRef;
101
- this._repeatCount = 2;
121
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
122
+ class MutationObserverFactory {
123
+ create(callback) {
124
+ return typeof MutationObserver === 'undefined' ? null : new MutationObserver(callback);
102
125
  }
103
- get repeatCount() {
104
- return this._repeatCount;
126
+ }
127
+ MutationObserverFactory.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: MutationObserverFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
128
+ MutationObserverFactory.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: MutationObserverFactory, providedIn: 'root' });
129
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: MutationObserverFactory, decorators: [{
130
+ type: Injectable,
131
+ args: [{ providedIn: 'root' }]
132
+ }] });
133
+ class ContentObserverService {
134
+ constructor(_mutationObserverFactory) {
135
+ this._mutationObserverFactory = _mutationObserverFactory;
136
+ this._observedElements = new Map();
105
137
  }
106
- set repeatCount(value) {
107
- this._repeatCount = coerceNumberProperty(value);
138
+ ngOnDestroy() {
139
+ this._observedElements.forEach((_, element) => this._cleanupObserver(element));
108
140
  }
109
- ngOnInit() {
110
- this._render();
141
+ observe(elementOrRef) {
142
+ const element = coerceElement(elementOrRef);
143
+ return new Observable((observer) => {
144
+ const stream = this._observeElement(element);
145
+ const subscription = stream.subscribe(observer);
146
+ return () => {
147
+ subscription.unsubscribe();
148
+ this._unobserveElement(element);
149
+ };
150
+ });
111
151
  }
112
- _render() {
113
- for (let i = 0; i < this.repeatCount; i++) {
114
- this._viewContainerRef.createEmbeddedView(this._mainTemplateRef);
152
+ _observeElement(element) {
153
+ if (!this._observedElements.has(element)) {
154
+ const stream = new Subject();
155
+ const observer = this._mutationObserverFactory.create((mutations) => stream.next(mutations));
156
+ if (observer) {
157
+ observer.observe(element, {
158
+ characterData: true,
159
+ childList: true,
160
+ subtree: true,
161
+ });
162
+ }
163
+ this._observedElements.set(element, { observer, stream, count: 1 });
115
164
  }
165
+ else {
166
+ this._observedElements.get(element).count++;
167
+ }
168
+ return this._observedElements.get(element).stream;
116
169
  }
117
- }
118
- RepeatDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: RepeatDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
119
- RepeatDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.9", type: RepeatDirective, isStandalone: true, selector: "[etRepeat]", inputs: { repeatCount: ["etRepeat", "repeatCount"] }, ngImport: i0 });
120
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: RepeatDirective, decorators: [{
121
- type: Directive,
122
- args: [{
123
- selector: '[etRepeat]',
124
- standalone: true,
125
- }]
126
- }], ctorParameters: function () { return [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }]; }, propDecorators: { repeatCount: [{
127
- type: Input,
128
- args: ['etRepeat']
129
- }] } });
130
-
131
- class ViewportService {
132
- constructor(_viewportConfig, _breakpointObserver) {
133
- this._breakpointObserver = _breakpointObserver;
134
- this._isXs$ = new BehaviorSubject(false);
135
- this._isSm$ = new BehaviorSubject(false);
136
- this._isMd$ = new BehaviorSubject(false);
137
- this._isLg$ = new BehaviorSubject(false);
138
- this._isXl$ = new BehaviorSubject(false);
139
- this._is2Xl$ = new BehaviorSubject(false);
140
- this.currentViewport$ = combineLatest([this.isXs$, this.isSm$, this.isMd$, this.isLg$, this.isXl$, this.is2Xl$]).pipe(map((val) => this.getCurrentViewport(val)), shareReplay());
141
- this._viewportConfig = _viewportConfig || DEFAULT_VIEWPORT_CONFIG;
142
- this._observeDefaultBreakpoints();
143
- }
144
- get isXs$() {
145
- return this._isXs$.asObservable();
170
+ _unobserveElement(element) {
171
+ if (this._observedElements.has(element)) {
172
+ this._observedElements.get(element).count--;
173
+ if (!this._observedElements.get(element).count) {
174
+ this._cleanupObserver(element);
175
+ }
176
+ }
146
177
  }
147
- get isXs() {
148
- return this._isXs$.value;
178
+ _cleanupObserver(element) {
179
+ if (this._observedElements.has(element)) {
180
+ const { observer, stream } = this._observedElements.get(element);
181
+ if (observer) {
182
+ observer.disconnect();
183
+ }
184
+ stream.complete();
185
+ this._observedElements.delete(element);
186
+ }
149
187
  }
150
- get isSm$() {
151
- return this._isSm$.asObservable();
188
+ }
189
+ ContentObserverService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ContentObserverService, deps: [{ token: MutationObserverFactory }], target: i0.ɵɵFactoryTarget.Injectable });
190
+ ContentObserverService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ContentObserverService, providedIn: 'root' });
191
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ContentObserverService, decorators: [{
192
+ type: Injectable,
193
+ args: [{ providedIn: 'root' }]
194
+ }], ctorParameters: function () { return [{ type: MutationObserverFactory }]; } });
195
+
196
+ class DestroyService {
197
+ constructor() {
198
+ this._destroy$ = new Subject();
199
+ this.destroy$ = this._destroy$.asObservable();
152
200
  }
153
- get isSm() {
154
- return this._isSm$.value;
201
+ ngOnDestroy() {
202
+ this._destroy$.next(true);
203
+ this._destroy$.unsubscribe();
155
204
  }
156
- get isMd$() {
157
- return this._isMd$.asObservable();
205
+ }
206
+ DestroyService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: DestroyService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
207
+ DestroyService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: DestroyService });
208
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: DestroyService, decorators: [{
209
+ type: Injectable
210
+ }] });
211
+
212
+ class FocusVisibleService {
213
+ constructor() {
214
+ this._document = inject(DOCUMENT);
215
+ this._hadKeyboardEvent = false;
216
+ this._document.addEventListener('keydown', this.onKeyDown.bind(this), true);
217
+ this._document.addEventListener('mousedown', this.onPointerDown.bind(this), true);
218
+ this._document.addEventListener('pointerdown', this.onPointerDown.bind(this), true);
219
+ this._document.addEventListener('touchstart', this.onPointerDown.bind(this), true);
158
220
  }
159
- get isMd() {
160
- return this._isMd$.value;
221
+ get isFocusVisible() {
222
+ return this._hadKeyboardEvent;
161
223
  }
162
- get isLg$() {
163
- return this._isLg$.asObservable();
224
+ onKeyDown(e) {
225
+ if (e.metaKey || e.altKey || e.ctrlKey) {
226
+ return;
227
+ }
228
+ this._hadKeyboardEvent = true;
164
229
  }
165
- get isLg() {
166
- return this._isLg$.value;
230
+ onPointerDown() {
231
+ this._hadKeyboardEvent = false;
167
232
  }
168
- get isXl$() {
169
- return this._isXl$.asObservable();
233
+ }
234
+ FocusVisibleService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: FocusVisibleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
235
+ FocusVisibleService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: FocusVisibleService, providedIn: 'root' });
236
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: FocusVisibleService, decorators: [{
237
+ type: Injectable,
238
+ args: [{
239
+ providedIn: 'root',
240
+ }]
241
+ }], ctorParameters: function () { return []; } });
242
+
243
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
244
+ class ResizeObserverFactory {
245
+ create(callback) {
246
+ return typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(callback);
170
247
  }
171
- get isXl() {
172
- return this._isXl$.value;
248
+ }
249
+ ResizeObserverFactory.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ResizeObserverFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
250
+ ResizeObserverFactory.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ResizeObserverFactory, providedIn: 'root' });
251
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ResizeObserverFactory, decorators: [{
252
+ type: Injectable,
253
+ args: [{ providedIn: 'root' }]
254
+ }] });
255
+ class ResizeObserverService {
256
+ constructor(_mutationObserverFactory) {
257
+ this._mutationObserverFactory = _mutationObserverFactory;
258
+ this._observedElements = new Map();
173
259
  }
174
- get is2Xl$() {
175
- return this._is2Xl$.asObservable();
260
+ ngOnDestroy() {
261
+ this._observedElements.forEach((_, element) => this._cleanupObserver(element));
262
+ }
263
+ observe(elementOrRef) {
264
+ const element = coerceElement(elementOrRef);
265
+ return new Observable((observer) => {
266
+ const stream = this._observeElement(element);
267
+ const subscription = stream.subscribe(observer);
268
+ return () => {
269
+ subscription.unsubscribe();
270
+ this._unobserveElement(element);
271
+ };
272
+ });
273
+ }
274
+ _observeElement(element) {
275
+ if (!this._observedElements.has(element)) {
276
+ const stream = new Subject();
277
+ const observer = this._mutationObserverFactory.create((resizes) => stream.next(resizes));
278
+ if (observer) {
279
+ observer.observe(element);
280
+ }
281
+ this._observedElements.set(element, { observer, stream, count: 1 });
282
+ }
283
+ else {
284
+ this._observedElements.get(element).count++;
285
+ }
286
+ return this._observedElements.get(element).stream;
287
+ }
288
+ _unobserveElement(element) {
289
+ if (this._observedElements.has(element)) {
290
+ this._observedElements.get(element).count--;
291
+ if (!this._observedElements.get(element).count) {
292
+ this._cleanupObserver(element);
293
+ }
294
+ }
295
+ }
296
+ _cleanupObserver(element) {
297
+ if (this._observedElements.has(element)) {
298
+ const { observer, stream } = this._observedElements.get(element);
299
+ if (observer) {
300
+ observer.disconnect();
301
+ }
302
+ stream.complete();
303
+ this._observedElements.delete(element);
304
+ }
305
+ }
306
+ }
307
+ ResizeObserverService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ResizeObserverService, deps: [{ token: ResizeObserverFactory }], target: i0.ɵɵFactoryTarget.Injectable });
308
+ ResizeObserverService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ResizeObserverService, providedIn: 'root' });
309
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ResizeObserverService, decorators: [{
310
+ type: Injectable,
311
+ args: [{ providedIn: 'root' }]
312
+ }], ctorParameters: function () { return [{ type: ResizeObserverFactory }]; } });
313
+
314
+ class ViewportService {
315
+ constructor(_viewportConfig, _breakpointObserver) {
316
+ this._breakpointObserver = _breakpointObserver;
317
+ this._isXs$ = new BehaviorSubject(false);
318
+ this._isSm$ = new BehaviorSubject(false);
319
+ this._isMd$ = new BehaviorSubject(false);
320
+ this._isLg$ = new BehaviorSubject(false);
321
+ this._isXl$ = new BehaviorSubject(false);
322
+ this._is2Xl$ = new BehaviorSubject(false);
323
+ this.currentViewport$ = combineLatest([this.isXs$, this.isSm$, this.isMd$, this.isLg$, this.isXl$, this.is2Xl$]).pipe(map((val) => this.getCurrentViewport(val)), shareReplay());
324
+ this._viewportConfig = _viewportConfig || DEFAULT_VIEWPORT_CONFIG;
325
+ this._observeDefaultBreakpoints();
326
+ }
327
+ get isXs$() {
328
+ return this._isXs$.asObservable();
329
+ }
330
+ get isXs() {
331
+ return this._isXs$.value;
332
+ }
333
+ get isSm$() {
334
+ return this._isSm$.asObservable();
335
+ }
336
+ get isSm() {
337
+ return this._isSm$.value;
338
+ }
339
+ get isMd$() {
340
+ return this._isMd$.asObservable();
341
+ }
342
+ get isMd() {
343
+ return this._isMd$.value;
344
+ }
345
+ get isLg$() {
346
+ return this._isLg$.asObservable();
347
+ }
348
+ get isLg() {
349
+ return this._isLg$.value;
350
+ }
351
+ get isXl$() {
352
+ return this._isXl$.asObservable();
353
+ }
354
+ get isXl() {
355
+ return this._isXl$.value;
356
+ }
357
+ get is2Xl$() {
358
+ return this._is2Xl$.asObservable();
176
359
  }
177
360
  get is2Xl() {
178
361
  return this._is2Xl$.value;
@@ -258,8 +441,8 @@ class ViewportService {
258
441
  return 'xs';
259
442
  }
260
443
  }
261
- ViewportService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ViewportService, deps: [{ token: VIEWPORT_CONFIG, optional: true }, { token: i1.BreakpointObserver }], target: i0.ɵɵFactoryTarget.Injectable });
262
- ViewportService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ViewportService, providedIn: 'root' });
444
+ ViewportService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ViewportService, deps: [{ token: VIEWPORT_CONFIG, optional: true }, { token: i1.BreakpointObserver }], target: i0.ɵɵFactoryTarget.Injectable });
445
+ ViewportService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ViewportService, providedIn: 'root' });
263
446
  __decorate([
264
447
  Memo(),
265
448
  __metadata("design:type", Function),
@@ -276,7 +459,7 @@ __decorate([
276
459
  __metadata("design:paramtypes", [Object]),
277
460
  __metadata("design:returntype", void 0)
278
461
  ], ViewportService.prototype, "_buildMediaQuery", null);
279
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ViewportService, decorators: [{
462
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ViewportService, decorators: [{
280
463
  type: Injectable,
281
464
  args: [{
282
465
  providedIn: 'root',
@@ -288,276 +471,264 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImpor
288
471
  type: Optional
289
472
  }] }, { type: i1.BreakpointObserver }]; }, propDecorators: { _getViewportSize: [], _buildMediaQuery: [] } });
290
473
 
291
- class FocusVisibleService {
474
+ class ClickOutsideDirective {
292
475
  constructor() {
293
- this._document = inject(DOCUMENT);
294
- this._hadKeyboardEvent = false;
295
- this._document.addEventListener('keydown', this.onKeyDown.bind(this), true);
296
- this._document.addEventListener('mousedown', this.onPointerDown.bind(this), true);
297
- this._document.addEventListener('pointerdown', this.onPointerDown.bind(this), true);
298
- this._document.addEventListener('touchstart', this.onPointerDown.bind(this), true);
299
- }
300
- get isFocusVisible() {
301
- return this._hadKeyboardEvent;
476
+ this._elementRef = inject(ElementRef);
477
+ this._clickObserverService = inject(ClickObserverService);
478
+ this._subscription = null;
479
+ this.etClickOutside = new EventEmitter();
302
480
  }
303
- onKeyDown(e) {
304
- if (e.metaKey || e.altKey || e.ctrlKey) {
305
- return;
306
- }
307
- this._hadKeyboardEvent = true;
481
+ ngOnInit() {
482
+ setTimeout(() => {
483
+ this._subscription = this._clickObserverService.observe(this._elementRef.nativeElement).subscribe((event) => {
484
+ const activeElement = event.target;
485
+ const isInside = this._elementRef.nativeElement.contains(activeElement);
486
+ if (!isInside) {
487
+ this.etClickOutside.emit(event);
488
+ }
489
+ });
490
+ });
308
491
  }
309
- onPointerDown() {
310
- this._hadKeyboardEvent = false;
492
+ ngOnDestroy() {
493
+ this._subscription?.unsubscribe();
311
494
  }
312
495
  }
313
- FocusVisibleService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: FocusVisibleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
314
- FocusVisibleServiceprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: FocusVisibleService, providedIn: 'root' });
315
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: FocusVisibleService, decorators: [{
316
- type: Injectable,
496
+ ClickOutsideDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ClickOutsideDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
497
+ ClickOutsideDirectivedir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: ClickOutsideDirective, isStandalone: true, selector: "[etClickOutside]", outputs: { etClickOutside: "etClickOutside" }, ngImport: i0 });
498
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ClickOutsideDirective, decorators: [{
499
+ type: Directive,
317
500
  args: [{
318
- providedIn: 'root',
501
+ selector: '[etClickOutside]',
502
+ standalone: true,
319
503
  }]
320
- }], ctorParameters: function () { return []; } });
504
+ }], propDecorators: { etClickOutside: [{
505
+ type: Output
506
+ }] } });
321
507
 
322
- /* eslint-disable @typescript-eslint/no-non-null-assertion */
323
- class ResizeObserverFactory {
324
- create(callback) {
325
- return typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(callback);
326
- }
327
- }
328
- ResizeObserverFactory.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ResizeObserverFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
329
- ResizeObserverFactory.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ResizeObserverFactory, providedIn: 'root' });
330
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ResizeObserverFactory, decorators: [{
331
- type: Injectable,
332
- args: [{ providedIn: 'root' }]
333
- }] });
334
- class ResizeObserverService {
335
- constructor(_mutationObserverFactory) {
336
- this._mutationObserverFactory = _mutationObserverFactory;
337
- this._observedElements = new Map();
338
- }
339
- ngOnDestroy() {
340
- this._observedElements.forEach((_, element) => this._cleanupObserver(element));
508
+ const provideViewportConfig = (viewportConfig) => {
509
+ return { provide: VIEWPORT_CONFIG, useValue: viewportConfig };
510
+ };
511
+
512
+ const clamp = (value, min = 0, max = 100) => {
513
+ return Math.max(min, Math.min(max, value));
514
+ };
515
+
516
+ const elementCanScroll = (element) => {
517
+ const { scrollHeight, clientHeight, scrollWidth, clientWidth } = element;
518
+ return scrollHeight > clientHeight || scrollWidth > clientWidth;
519
+ };
520
+
521
+ const CURSOR_DRAG_SCROLLING_CLASS = 'et-cursor-drag-scroll--scrolling';
522
+ const CURSOR_DRAG_SCROLLING_PREPARED_CLASS = 'et-cursor-drag-scroll--prepared';
523
+
524
+ class CursorDragScrollDirective {
525
+ constructor() {
526
+ this._subscriptions = [];
527
+ this._destroy$ = inject(DestroyService).destroy$;
528
+ this._elementRef = inject(ElementRef);
529
+ this._contentObserverService = inject(ContentObserverService);
530
+ this._resizeObserverService = inject(ResizeObserverService);
531
+ this._bufferUntilScroll = 5;
532
+ this._mouseUp$ = new Subject();
533
+ this._isScrolling = false;
534
+ this._canScroll = false;
535
+ this._currentScrollState = {
536
+ top: 0,
537
+ left: 0,
538
+ x: 0,
539
+ y: 0,
540
+ };
541
+ this._enabled = false;
341
542
  }
342
- observe(elementOrRef) {
343
- const element = coerceElement(elementOrRef);
344
- return new Observable((observer) => {
345
- const stream = this._observeElement(element);
346
- const subscription = stream.subscribe(observer);
347
- return () => {
348
- subscription.unsubscribe();
349
- this._unobserveElement(element);
350
- };
351
- });
543
+ get enabled() {
544
+ return this._enabled;
352
545
  }
353
- _observeElement(element) {
354
- if (!this._observedElements.has(element)) {
355
- const stream = new Subject();
356
- const observer = this._mutationObserverFactory.create((resizes) => stream.next(resizes));
357
- if (observer) {
358
- observer.observe(element);
359
- }
360
- this._observedElements.set(element, { observer, stream, count: 1 });
546
+ set enabled(value) {
547
+ this._enabled = coerceBooleanProperty(value);
548
+ if (this._enabled) {
549
+ this._enableCursorDragScroll();
361
550
  }
362
551
  else {
363
- this._observedElements.get(element).count++;
552
+ this._disableCursorDragScroll();
364
553
  }
365
- return this._observedElements.get(element).stream;
366
554
  }
367
- _unobserveElement(element) {
368
- if (this._observedElements.has(element)) {
369
- this._observedElements.get(element).count--;
370
- if (!this._observedElements.get(element).count) {
371
- this._cleanupObserver(element);
372
- }
555
+ ngAfterViewInit() {
556
+ if (this.enabled) {
557
+ this._enableCursorDragScroll();
373
558
  }
374
- }
375
- _cleanupObserver(element) {
376
- if (this._observedElements.has(element)) {
377
- const { observer, stream } = this._observedElements.get(element);
378
- if (observer) {
379
- observer.disconnect();
380
- }
381
- stream.complete();
382
- this._observedElements.delete(element);
559
+ else {
560
+ this._disableCursorDragScroll();
383
561
  }
384
562
  }
385
- }
386
- ResizeObserverService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ResizeObserverService, deps: [{ token: ResizeObserverFactory }], target: i0.ɵɵFactoryTarget.Injectable });
387
- ResizeObserverService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ResizeObserverService, providedIn: 'root' });
388
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ResizeObserverService, decorators: [{
389
- type: Injectable,
390
- args: [{ providedIn: 'root' }]
391
- }], ctorParameters: function () { return [{ type: ResizeObserverFactory }]; } });
392
-
393
- /* eslint-disable @typescript-eslint/no-non-null-assertion */
394
- class MutationObserverFactory {
395
- create(callback) {
396
- return typeof MutationObserver === 'undefined' ? null : new MutationObserver(callback);
397
- }
398
- }
399
- MutationObserverFactory.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: MutationObserverFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
400
- MutationObserverFactory.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: MutationObserverFactory, providedIn: 'root' });
401
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: MutationObserverFactory, decorators: [{
402
- type: Injectable,
403
- args: [{ providedIn: 'root' }]
404
- }] });
405
- class ContentObserverService {
406
- constructor(_mutationObserverFactory) {
407
- this._mutationObserverFactory = _mutationObserverFactory;
408
- this._observedElements = new Map();
563
+ _enableCursorDragScroll() {
564
+ const contentResizeSub = combineLatest([
565
+ this._contentObserverService.observe(this._elementRef.nativeElement).pipe(startWith(null)),
566
+ this._resizeObserverService.observe(this._elementRef.nativeElement).pipe(startWith(null)),
567
+ ])
568
+ .pipe(debounceTime(25), tap(() => this._updateCanScrollState()), takeUntil(this._destroy$))
569
+ .subscribe();
570
+ const mousedownSub = fromEvent(this._elementRef.nativeElement, 'mousedown')
571
+ .pipe(tap((e) => this._onMouseDown(e)), takeUntil(this._destroy$))
572
+ .subscribe();
573
+ this._subscriptions.push(contentResizeSub, mousedownSub);
574
+ this._updateCanScrollState();
409
575
  }
410
- ngOnDestroy() {
411
- this._observedElements.forEach((_, element) => this._cleanupObserver(element));
576
+ _disableCursorDragScroll() {
577
+ this._subscriptions.forEach((sub) => sub.unsubscribe());
578
+ this._subscriptions.length = 0;
579
+ this._elementRef.nativeElement.style.cursor = 'default';
412
580
  }
413
- observe(elementOrRef) {
414
- const element = coerceElement(elementOrRef);
415
- return new Observable((observer) => {
416
- const stream = this._observeElement(element);
417
- const subscription = stream.subscribe(observer);
418
- return () => {
419
- subscription.unsubscribe();
420
- this._unobserveElement(element);
421
- };
422
- });
581
+ _onMouseDown(e) {
582
+ if (!this._elementRef?.nativeElement || !this._canScroll) {
583
+ return;
584
+ }
585
+ const element = this._elementRef.nativeElement;
586
+ element.classList.add(CURSOR_DRAG_SCROLLING_PREPARED_CLASS);
587
+ this._elementRef.nativeElement.style.scrollSnapType = 'none';
588
+ this._elementRef.nativeElement.style.scrollBehavior = 'unset';
589
+ this._currentScrollState = {
590
+ left: this._elementRef.nativeElement.scrollLeft,
591
+ top: this._elementRef.nativeElement.scrollTop,
592
+ x: e.clientX,
593
+ y: e.clientY,
594
+ };
595
+ fromEvent(document, 'mousemove')
596
+ .pipe(tap((e) => this._mouseMoveHandler(e)), takeUntil(this._mouseUp$), takeUntil(this._destroy$))
597
+ .subscribe();
598
+ fromEvent(document, 'mouseup')
599
+ .pipe(tap(() => this._mouseUpHandler()), take(1), takeUntil(this._destroy$))
600
+ .subscribe();
423
601
  }
424
- _observeElement(element) {
425
- if (!this._observedElements.has(element)) {
426
- const stream = new Subject();
427
- const observer = this._mutationObserverFactory.create((mutations) => stream.next(mutations));
428
- if (observer) {
429
- observer.observe(element, {
430
- characterData: true,
431
- childList: true,
432
- subtree: true,
602
+ _mouseMoveHandler(e) {
603
+ e.preventDefault();
604
+ if (!this._elementRef?.nativeElement) {
605
+ return;
606
+ }
607
+ const dx = e.clientX - this._currentScrollState.x;
608
+ const dy = e.clientY - this._currentScrollState.y;
609
+ if (Math.abs(dx) > this._bufferUntilScroll || Math.abs(dy) > this._bufferUntilScroll) {
610
+ const element = this._elementRef.nativeElement;
611
+ if (!this._isScrolling) {
612
+ this._isScrolling = true;
613
+ element.style.cursor = 'grabbing';
614
+ element.classList.add(CURSOR_DRAG_SCROLLING_CLASS);
615
+ element.scroll({
616
+ top: this._currentScrollState.top - dy,
617
+ left: this._currentScrollState.left - dx,
618
+ behavior: 'smooth',
433
619
  });
434
620
  }
435
- this._observedElements.set(element, { observer, stream, count: 1 });
436
- }
437
- else {
438
- this._observedElements.get(element).count++;
621
+ else {
622
+ element.scrollTop = this._currentScrollState.top - dy;
623
+ element.scrollLeft = this._currentScrollState.left - dx;
624
+ }
439
625
  }
440
- return this._observedElements.get(element).stream;
441
626
  }
442
- _unobserveElement(element) {
443
- if (this._observedElements.has(element)) {
444
- this._observedElements.get(element).count--;
445
- if (!this._observedElements.get(element).count) {
446
- this._cleanupObserver(element);
447
- }
627
+ _mouseUpHandler() {
628
+ this._mouseUp$.next(true);
629
+ this._isScrolling = false;
630
+ if (!this._elementRef?.nativeElement) {
631
+ return;
448
632
  }
633
+ this._elementRef.nativeElement.style.scrollSnapType = '';
634
+ this._elementRef.nativeElement.style.scrollBehavior = '';
635
+ this._elementRef.nativeElement.style.cursor = 'grab';
636
+ this._elementRef.nativeElement.classList.remove(CURSOR_DRAG_SCROLLING_CLASS);
637
+ this._elementRef.nativeElement.classList.remove(CURSOR_DRAG_SCROLLING_PREPARED_CLASS);
449
638
  }
450
- _cleanupObserver(element) {
451
- if (this._observedElements.has(element)) {
452
- const { observer, stream } = this._observedElements.get(element);
453
- if (observer) {
454
- observer.disconnect();
455
- }
456
- stream.complete();
457
- this._observedElements.delete(element);
639
+ _updateCanScrollState() {
640
+ this._canScroll = elementCanScroll(this._elementRef.nativeElement);
641
+ if (this._canScroll) {
642
+ this._elementRef.nativeElement.style.cursor = 'grab';
643
+ }
644
+ else {
645
+ this._elementRef.nativeElement.style.cursor = 'default';
458
646
  }
459
647
  }
460
648
  }
461
- ContentObserverService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ContentObserverService, deps: [{ token: MutationObserverFactory }], target: i0.ɵɵFactoryTarget.Injectable });
462
- ContentObserverServiceprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ContentObserverService, providedIn: 'root' });
463
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ContentObserverService, decorators: [{
464
- type: Injectable,
465
- args: [{ providedIn: 'root' }]
466
- }], ctorParameters: function () { return [{ type: MutationObserverFactory }]; } });
649
+ CursorDragScrollDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: CursorDragScrollDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
650
+ CursorDragScrollDirectivedir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: CursorDragScrollDirective, isStandalone: true, selector: "[etCursorDragScroll]", inputs: { enabled: ["etCursorDragScroll", "enabled"] }, providers: [DestroyService], exportAs: ["etCursorDragScroll"], ngImport: i0 });
651
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: CursorDragScrollDirective, decorators: [{
652
+ type: Directive,
653
+ args: [{
654
+ selector: '[etCursorDragScroll]',
655
+ exportAs: 'etCursorDragScroll',
656
+ standalone: true,
657
+ providers: [DestroyService],
658
+ }]
659
+ }], propDecorators: { enabled: [{
660
+ type: Input,
661
+ args: ['etCursorDragScroll']
662
+ }] } });
467
663
 
468
- /* eslint-disable @typescript-eslint/no-non-null-assertion */
469
- class ClickObserverFactory {
470
- create() {
471
- return fromEvent(document, 'click');
472
- }
473
- }
474
- ClickObserverFactory.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ClickObserverFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
475
- ClickObserverFactory.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ClickObserverFactory, providedIn: 'root' });
476
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ClickObserverFactory, decorators: [{
477
- type: Injectable,
478
- args: [{ providedIn: 'root' }]
479
- }] });
480
- class ClickObserverService {
481
- constructor(_clickObserverFactory) {
482
- this._clickObserverFactory = _clickObserverFactory;
483
- this._observedElements = new Map();
664
+ class DestroyDirective {
665
+ constructor() {
666
+ this._destroy$ = new Subject();
667
+ this.destroy$ = this._destroy$.asObservable();
484
668
  }
485
669
  ngOnDestroy() {
486
- this._observedElements.forEach((_, element) => this._cleanupObserver(element));
487
- }
488
- observe(elementOrRef) {
489
- const element = coerceElement(elementOrRef);
490
- return new Observable((observer) => {
491
- const stream = this._observeElement(element);
492
- const subscription = stream.subscribe(observer);
493
- return () => {
494
- subscription.unsubscribe();
495
- this._unobserveElement(element);
496
- };
497
- });
498
- }
499
- _observeElement(element) {
500
- if (!this._observedElements.has(element)) {
501
- const stream = new Subject();
502
- const observer = this._clickObserverFactory.create();
503
- const sub = observer.subscribe((event) => stream.next(event));
504
- this._observedElements.set(element, { observer: sub, stream, count: 1 });
505
- }
506
- else {
507
- this._observedElements.get(element).count++;
508
- }
509
- return this._observedElements.get(element).stream;
510
- }
511
- _unobserveElement(element) {
512
- if (this._observedElements.has(element)) {
513
- this._observedElements.get(element).count--;
514
- if (!this._observedElements.get(element).count) {
515
- this._cleanupObserver(element);
516
- }
517
- }
670
+ this._destroy$.next(true);
671
+ this._destroy$.unsubscribe();
518
672
  }
519
- _cleanupObserver(element) {
520
- if (this._observedElements.has(element)) {
521
- const { observer, stream } = this._observedElements.get(element);
522
- if (observer) {
523
- observer.unsubscribe();
524
- }
525
- stream.complete();
526
- this._observedElements.delete(element);
527
- }
673
+ }
674
+ DestroyDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: DestroyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
675
+ DestroyDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: DestroyDirective, isStandalone: true, ngImport: i0 });
676
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: DestroyDirective, decorators: [{
677
+ type: Directive,
678
+ args: [{
679
+ standalone: true,
680
+ }]
681
+ }] });
682
+
683
+ class LetContext {
684
+ constructor() {
685
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
686
+ this.$implicit = null;
687
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
688
+ this.etLet = null;
528
689
  }
529
690
  }
530
- ClickObserverService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ClickObserverService, deps: [{ token: ClickObserverFactory }], target: i0.ɵɵFactoryTarget.Injectable });
531
- ClickObserverService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ClickObserverService, providedIn: 'root' });
532
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ClickObserverService, decorators: [{
533
- type: Injectable,
534
- args: [{ providedIn: 'root' }]
535
- }], ctorParameters: function () { return [{ type: ClickObserverFactory }]; } });
536
691
 
537
- class DestroyService {
538
- constructor() {
539
- this._destroy$ = new Subject();
692
+ class LetDirective {
693
+ constructor(_viewContainer, templateRef) {
694
+ this._viewContainer = _viewContainer;
695
+ this._context = new LetContext();
696
+ this._templateRef = null;
697
+ this._viewRef = null;
698
+ this._templateRef = templateRef;
540
699
  }
541
- get destroy$() {
542
- return this._destroy$.asObservable();
700
+ set etLet(value) {
701
+ this._context.$implicit = this._context.etLet = value;
702
+ this._updateView();
543
703
  }
544
- ngOnDestroy() {
545
- this._destroy$.next(true);
546
- this._destroy$.unsubscribe();
704
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
705
+ static ngTemplateContextGuard(dir, ctx) {
706
+ return true;
707
+ }
708
+ _updateView() {
709
+ if (!this._viewRef) {
710
+ this._viewContainer.clear();
711
+ if (this._templateRef) {
712
+ this._viewRef = this._viewContainer.createEmbeddedView(this._templateRef, this._context);
713
+ }
714
+ }
547
715
  }
548
716
  }
549
- DestroyService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: DestroyService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
550
- DestroyServiceprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: DestroyService, providedIn: 'any' });
551
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: DestroyService, decorators: [{
552
- type: Injectable,
717
+ LetDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: LetDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
718
+ LetDirectivedir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: LetDirective, isStandalone: true, selector: "[etLet]", inputs: { etLet: "etLet" }, ngImport: i0 });
719
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: LetDirective, decorators: [{
720
+ type: Directive,
553
721
  args: [{
554
- providedIn: 'any',
722
+ selector: '[etLet]',
723
+ standalone: true,
555
724
  }]
556
- }] });
725
+ }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.TemplateRef }]; }, propDecorators: { etLet: [{
726
+ type: Input
727
+ }] } });
557
728
 
558
- class ObserveResizeDirective {
729
+ class ObserveContentDirective {
559
730
  constructor() {
560
- this._resizeObserver = inject(ResizeObserverService);
731
+ this._contentObserver = inject(ContentObserverService);
561
732
  this._elementRef = inject(ElementRef);
562
733
  this._ngZone = inject(NgZone);
563
734
  this.event = new EventEmitter();
@@ -589,38 +760,38 @@ class ObserveResizeDirective {
589
760
  }
590
761
  _subscribe() {
591
762
  this._unsubscribe();
592
- const stream = this._resizeObserver.observe(this._elementRef);
763
+ const stream = this._contentObserver.observe(this._elementRef);
593
764
  this._ngZone.runOutsideAngular(() => {
594
- this._currentSubscription = (this.debounce ? stream.pipe(debounceTime(this.debounce)) : stream).subscribe(this.event);
765
+ this._currentSubscription = (this.debounce ? stream.pipe(debounceTime$1(this.debounce)) : stream).subscribe(this.event);
595
766
  });
596
767
  }
597
768
  _unsubscribe() {
598
769
  this._currentSubscription?.unsubscribe();
599
770
  }
600
771
  }
601
- ObserveResizeDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ObserveResizeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
602
- ObserveResizeDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.9", type: ObserveResizeDirective, isStandalone: true, selector: "[etObserveResize]", inputs: { disabled: ["etObserveResizeDisabled", "disabled"], debounce: ["etObserveResizeDebounce", "debounce"] }, outputs: { event: "etObserveResize" }, exportAs: ["etObserveResize"], ngImport: i0 });
603
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ObserveResizeDirective, decorators: [{
772
+ ObserveContentDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ObserveContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
773
+ ObserveContentDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: ObserveContentDirective, isStandalone: true, selector: "[etObserveContent]", inputs: { disabled: ["etObserveContentDisabled", "disabled"], debounce: ["etObserveContentDebounce", "debounce"] }, outputs: { event: "etObserveContent" }, exportAs: ["etObserveContent"], ngImport: i0 });
774
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ObserveContentDirective, decorators: [{
604
775
  type: Directive,
605
776
  args: [{
606
- selector: '[etObserveResize]',
607
- exportAs: 'etObserveResize',
777
+ selector: '[etObserveContent]',
778
+ exportAs: 'etObserveContent',
608
779
  standalone: true,
609
780
  }]
610
781
  }], propDecorators: { event: [{
611
782
  type: Output,
612
- args: ['etObserveResize']
783
+ args: ['etObserveContent']
613
784
  }], disabled: [{
614
785
  type: Input,
615
- args: ['etObserveResizeDisabled']
786
+ args: ['etObserveContentDisabled']
616
787
  }], debounce: [{
617
788
  type: Input,
618
- args: ['etObserveResizeDebounce']
789
+ args: ['etObserveContentDebounce']
619
790
  }] } });
620
791
 
621
- class ObserveContentDirective {
792
+ class ObserveResizeDirective {
622
793
  constructor() {
623
- this._contentObserver = inject(ContentObserverService);
794
+ this._resizeObserver = inject(ResizeObserverService);
624
795
  this._elementRef = inject(ElementRef);
625
796
  this._ngZone = inject(NgZone);
626
797
  this.event = new EventEmitter();
@@ -652,88 +823,69 @@ class ObserveContentDirective {
652
823
  }
653
824
  _subscribe() {
654
825
  this._unsubscribe();
655
- const stream = this._contentObserver.observe(this._elementRef);
826
+ const stream = this._resizeObserver.observe(this._elementRef);
656
827
  this._ngZone.runOutsideAngular(() => {
657
- this._currentSubscription = (this.debounce ? stream.pipe(debounceTime$1(this.debounce)) : stream).subscribe(this.event);
828
+ this._currentSubscription = (this.debounce ? stream.pipe(debounceTime(this.debounce)) : stream).subscribe(this.event);
658
829
  });
659
830
  }
660
831
  _unsubscribe() {
661
832
  this._currentSubscription?.unsubscribe();
662
833
  }
663
834
  }
664
- ObserveContentDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ObserveContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
665
- ObserveContentDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.9", type: ObserveContentDirective, isStandalone: true, selector: "[etObserveContent]", inputs: { disabled: ["etObserveContentDisabled", "disabled"], debounce: ["etObserveContentDebounce", "debounce"] }, outputs: { event: "etObserveContent" }, exportAs: ["etObserveContent"], ngImport: i0 });
666
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ObserveContentDirective, decorators: [{
835
+ ObserveResizeDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ObserveResizeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
836
+ ObserveResizeDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: ObserveResizeDirective, isStandalone: true, selector: "[etObserveResize]", inputs: { disabled: ["etObserveResizeDisabled", "disabled"], debounce: ["etObserveResizeDebounce", "debounce"] }, outputs: { event: "etObserveResize" }, exportAs: ["etObserveResize"], ngImport: i0 });
837
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ObserveResizeDirective, decorators: [{
667
838
  type: Directive,
668
839
  args: [{
669
- selector: '[etObserveContent]',
670
- exportAs: 'etObserveContent',
840
+ selector: '[etObserveResize]',
841
+ exportAs: 'etObserveResize',
671
842
  standalone: true,
672
843
  }]
673
844
  }], propDecorators: { event: [{
674
845
  type: Output,
675
- args: ['etObserveContent']
846
+ args: ['etObserveResize']
676
847
  }], disabled: [{
677
848
  type: Input,
678
- args: ['etObserveContentDisabled']
849
+ args: ['etObserveResizeDisabled']
679
850
  }], debounce: [{
680
851
  type: Input,
681
- args: ['etObserveContentDebounce']
852
+ args: ['etObserveResizeDebounce']
682
853
  }] } });
683
854
 
684
- class ClickOutsideDirective {
855
+ const SCROLL_OBSERVER_FIRST_ELEMENT_CLASS = 'et-scroll-observer-first-element';
856
+ class ScrollObserverFirstElementDirective {
685
857
  constructor() {
686
- this._elementRef = inject(ElementRef);
687
- this._clickObserverService = inject(ClickObserverService);
688
- this._subscription = null;
689
- this.etClickOutside = new EventEmitter();
858
+ this._isFirstElement = false;
690
859
  }
691
- ngOnInit() {
692
- setTimeout(() => {
693
- this._subscription = this._clickObserverService.observe(this._elementRef.nativeElement).subscribe((event) => {
694
- const activeElement = event.target;
695
- const isInside = this._elementRef.nativeElement.contains(activeElement);
696
- if (!isInside) {
697
- this.etClickOutside.emit(event);
698
- }
699
- });
700
- });
860
+ get isFirstElement() {
861
+ return this._isFirstElement;
701
862
  }
702
- ngOnDestroy() {
703
- this._subscription?.unsubscribe();
863
+ set isFirstElement(value) {
864
+ this._isFirstElement = coerceBooleanProperty(value);
704
865
  }
705
866
  }
706
- ClickOutsideDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ClickOutsideDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
707
- ClickOutsideDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.9", type: ClickOutsideDirective, isStandalone: true, selector: "[etClickOutside]", outputs: { etClickOutside: "etClickOutside" }, ngImport: i0 });
708
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ClickOutsideDirective, decorators: [{
867
+ ScrollObserverFirstElementDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ScrollObserverFirstElementDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
868
+ ScrollObserverFirstElementDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: ScrollObserverFirstElementDirective, isStandalone: true, selector: "[etScrollObserverFirstElement]", inputs: { isFirstElement: ["etScrollObserverFirstElement", "isFirstElement"] }, host: { properties: { "class.et-scroll-observer-first-element": "this.isFirstElement" } }, ngImport: i0 });
869
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ScrollObserverFirstElementDirective, decorators: [{
709
870
  type: Directive,
710
871
  args: [{
711
- selector: '[etClickOutside]',
872
+ selector: '[etScrollObserverFirstElement]',
712
873
  standalone: true,
713
874
  }]
714
- }], propDecorators: { etClickOutside: [{
715
- type: Output
875
+ }], propDecorators: { isFirstElement: [{
876
+ type: Input,
877
+ args: ['etScrollObserverFirstElement']
878
+ }, {
879
+ type: HostBinding,
880
+ args: [`class.${SCROLL_OBSERVER_FIRST_ELEMENT_CLASS}`]
716
881
  }] } });
717
882
 
718
- const provideViewportConfig = (viewportConfig) => {
719
- return { provide: VIEWPORT_CONFIG, useValue: viewportConfig };
720
- };
721
-
722
- const clamp = (value, min = 0, max = 100) => {
723
- return Math.max(min, Math.min(max, value));
724
- };
725
-
726
- const elementCanScroll = (element) => {
727
- const { scrollHeight, clientHeight, scrollWidth, clientWidth } = element;
728
- return scrollHeight > clientHeight || scrollWidth > clientWidth;
729
- };
730
-
731
883
  const SCROLL_OBSERVER_IGNORE_TARGET_CLASS = 'et-scroll-observer-ignore-target';
732
884
  class ScrollObserverIgnoreTargetDirective {
733
885
  }
734
- ScrollObserverIgnoreTargetDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ScrollObserverIgnoreTargetDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
735
- ScrollObserverIgnoreTargetDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.9", type: ScrollObserverIgnoreTargetDirective, isStandalone: true, selector: "[etScrollObserverIgnoreTarget]", host: { classAttribute: "et-scroll-observer-ignore-target" }, ngImport: i0 });
736
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ScrollObserverIgnoreTargetDirective, decorators: [{
886
+ ScrollObserverIgnoreTargetDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ScrollObserverIgnoreTargetDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
887
+ ScrollObserverIgnoreTargetDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: ScrollObserverIgnoreTargetDirective, isStandalone: true, selector: "[etScrollObserverIgnoreTarget]", host: { classAttribute: "et-scroll-observer-ignore-target" }, ngImport: i0 });
888
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ScrollObserverIgnoreTargetDirective, decorators: [{
737
889
  type: Directive,
738
890
  args: [{
739
891
  selector: '[etScrollObserverIgnoreTarget]',
@@ -744,6 +896,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImpor
744
896
  }]
745
897
  }] });
746
898
 
899
+ const SCROLL_OBSERVER_LAST_ELEMENT_CLASS = 'et-scroll-observer-last-element';
900
+ class ScrollObserverLastElementDirective {
901
+ constructor() {
902
+ this._isLastElement = false;
903
+ }
904
+ get isLastElement() {
905
+ return this._isLastElement;
906
+ }
907
+ set isLastElement(value) {
908
+ this._isLastElement = coerceBooleanProperty(value);
909
+ }
910
+ }
911
+ ScrollObserverLastElementDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ScrollObserverLastElementDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
912
+ ScrollObserverLastElementDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: ScrollObserverLastElementDirective, isStandalone: true, selector: "[etScrollObserverLastElement]", inputs: { isLastElement: ["etScrollObserverLastElement", "isLastElement"] }, host: { properties: { "class.et-scroll-observer-last-element": "this.isLastElement" }, classAttribute: "et-scroll-observer-last-element" }, ngImport: i0 });
913
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ScrollObserverLastElementDirective, decorators: [{
914
+ type: Directive,
915
+ args: [{
916
+ selector: '[etScrollObserverLastElement]',
917
+ standalone: true,
918
+ host: {
919
+ class: SCROLL_OBSERVER_LAST_ELEMENT_CLASS,
920
+ },
921
+ }]
922
+ }], propDecorators: { isLastElement: [{
923
+ type: Input,
924
+ args: ['etScrollObserverLastElement']
925
+ }, {
926
+ type: HostBinding,
927
+ args: [`class.${SCROLL_OBSERVER_LAST_ELEMENT_CLASS}`]
928
+ }] } });
929
+
747
930
  const OBSERVE_SCROLL_STATE = new InjectionToken('OBSERVE_SCROLL_STATE');
748
931
 
749
932
  class ObserveScrollStateDirective {
@@ -762,10 +945,18 @@ class ObserveScrollStateDirective {
762
945
  this.etObserveScrollState = new EventEmitter();
763
946
  }
764
947
  get _firstCurrentChild() {
948
+ const explicitFirstElement = this._elementRef.nativeElement.querySelector(`.${SCROLL_OBSERVER_FIRST_ELEMENT_CLASS}`);
949
+ if (explicitFirstElement) {
950
+ return explicitFirstElement;
951
+ }
765
952
  const element = this._elementRef.nativeElement.children[0];
766
953
  return this._getNonIgnoredChild(element, 'next');
767
954
  }
768
955
  get _lastCurrentChild() {
956
+ const explicitLastElement = this._elementRef.nativeElement.querySelector(`.${SCROLL_OBSERVER_LAST_ELEMENT_CLASS}`);
957
+ if (explicitLastElement) {
958
+ return explicitLastElement;
959
+ }
769
960
  const element = this._elementRef.nativeElement.children[this._elementRef.nativeElement.children.length - 1];
770
961
  return this._getNonIgnoredChild(element, 'previous');
771
962
  }
@@ -789,7 +980,8 @@ class ObserveScrollStateDirective {
789
980
  this._resizeObserverService
790
981
  .observe(this._elementRef.nativeElement)
791
982
  .pipe(debounceTime(25), tap(() => {
792
- if (!this._intersectionObserver && elementCanScroll(this._elementRef.nativeElement)) {
983
+ const canScroll = elementCanScroll(this._elementRef.nativeElement);
984
+ if ((!this._intersectionObserver && canScroll) || (this._intersectionObserver && !canScroll)) {
793
985
  this._checkChildren();
794
986
  }
795
987
  }), takeUntil(this._destroy$))
@@ -839,12 +1031,14 @@ class ObserveScrollStateDirective {
839
1031
  _observeChild(child, element) {
840
1032
  this._intersectionObserver?.observe(element);
841
1033
  this._observedChildren[child] = element;
1034
+ element.classList.add(`et-scroll-observer-observing-${child}-element`);
842
1035
  }
843
1036
  _unobserveChild(child) {
844
1037
  const observedChild = this._observedChildren[child];
845
1038
  if (!observedChild) {
846
1039
  return;
847
1040
  }
1041
+ observedChild.classList.remove('et-scroll-observer-observing-first-element', 'et-scroll-observer-observing-last-element');
848
1042
  this._intersectionObserver?.unobserve(observedChild);
849
1043
  this._observedChildren[child] = null;
850
1044
  }
@@ -866,14 +1060,15 @@ class ObserveScrollStateDirective {
866
1060
  return element;
867
1061
  }
868
1062
  }
869
- ObserveScrollStateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ObserveScrollStateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
870
- ObserveScrollStateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.9", type: ObserveScrollStateDirective, isStandalone: true, selector: "[etObserveScrollState]", inputs: { observerRootMargin: "observerRootMargin", observerThreshold: "observerThreshold" }, outputs: { etObserveScrollState: "etObserveScrollState" }, providers: [
1063
+ ObserveScrollStateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ObserveScrollStateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1064
+ ObserveScrollStateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: ObserveScrollStateDirective, isStandalone: true, selector: "[etObserveScrollState]", inputs: { observerRootMargin: "observerRootMargin", observerThreshold: "observerThreshold" }, outputs: { etObserveScrollState: "etObserveScrollState" }, providers: [
871
1065
  {
872
1066
  provide: OBSERVE_SCROLL_STATE,
873
1067
  useExisting: ObserveScrollStateDirective,
874
1068
  },
1069
+ DestroyService,
875
1070
  ], exportAs: ["etObserveScrollState"], ngImport: i0 });
876
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ObserveScrollStateDirective, decorators: [{
1071
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ObserveScrollStateDirective, decorators: [{
877
1072
  type: Directive,
878
1073
  args: [{
879
1074
  selector: '[etObserveScrollState]',
@@ -884,6 +1079,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImpor
884
1079
  provide: OBSERVE_SCROLL_STATE,
885
1080
  useExisting: ObserveScrollStateDirective,
886
1081
  },
1082
+ DestroyService,
887
1083
  ],
888
1084
  }]
889
1085
  }], propDecorators: { observerRootMargin: [{
@@ -894,123 +1090,202 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImpor
894
1090
  type: Output
895
1091
  }] } });
896
1092
 
897
- const CURSOR_DRAG_SCROLLING_CLASS = 'et-cursor-drag-scroll--scrolling';
898
- const CURSOR_DRAG_SCROLLING_PREPARED_CLASS = 'et-cursor-drag-scroll--prepared';
1093
+ class RepeatDirective {
1094
+ constructor(_mainTemplateRef, _viewContainerRef) {
1095
+ this._mainTemplateRef = _mainTemplateRef;
1096
+ this._viewContainerRef = _viewContainerRef;
1097
+ this._repeatCount = 2;
1098
+ }
1099
+ get repeatCount() {
1100
+ return this._repeatCount;
1101
+ }
1102
+ set repeatCount(value) {
1103
+ this._repeatCount = coerceNumberProperty(value);
1104
+ }
1105
+ ngOnInit() {
1106
+ this._render();
1107
+ }
1108
+ _render() {
1109
+ for (let i = 0; i < this.repeatCount; i++) {
1110
+ this._viewContainerRef.createEmbeddedView(this._mainTemplateRef);
1111
+ }
1112
+ }
1113
+ }
1114
+ RepeatDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RepeatDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
1115
+ RepeatDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: RepeatDirective, isStandalone: true, selector: "[etRepeat]", inputs: { repeatCount: ["etRepeat", "repeatCount"] }, ngImport: i0 });
1116
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: RepeatDirective, decorators: [{
1117
+ type: Directive,
1118
+ args: [{
1119
+ selector: '[etRepeat]',
1120
+ standalone: true,
1121
+ }]
1122
+ }], ctorParameters: function () { return [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }]; }, propDecorators: { repeatCount: [{
1123
+ type: Input,
1124
+ args: ['etRepeat']
1125
+ }] } });
899
1126
 
900
- class CursorDragScrollDirective {
1127
+ const SEO_DIRECTIVE_TOKEN = new InjectionToken('SEO_DIRECTIVE_TOKEN');
1128
+
1129
+ const mergeSeoConfig = (config, parentConfig) => {
1130
+ return {
1131
+ ...parentConfig,
1132
+ ...config,
1133
+ };
1134
+ };
1135
+
1136
+ class SeoDirective {
901
1137
  constructor() {
902
- this._destroy$ = inject(DestroyService).destroy$;
903
- this._elementRef = inject(ElementRef);
904
- this._contentObserverService = inject(ContentObserverService);
905
- this._resizeObserverService = inject(ResizeObserverService);
906
- this._bufferUntilScroll = 5;
907
- this._mouseUp$ = new Subject();
908
- this._isScrolling = false;
909
- this._canScroll = false;
910
- this._currentScrollState = {
911
- top: 0,
912
- left: 0,
913
- x: 0,
914
- y: 0,
915
- };
1138
+ this._metaService = inject(Meta);
1139
+ this._titleService = inject(Title);
1140
+ this._onDeactivate$ = new Subject();
1141
+ this._isDeactivated = false;
1142
+ this.parent = inject(SEO_DIRECTIVE_TOKEN, { optional: true, skipSelf: true });
1143
+ this._config = {};
916
1144
  }
917
- ngAfterViewInit() {
918
- combineLatest([
919
- this._contentObserverService.observe(this._elementRef.nativeElement),
920
- this._resizeObserverService.observe(this._elementRef.nativeElement),
921
- ])
922
- .pipe(tap(() => this._updateCanScrollState()), takeUntil(this._destroy$))
923
- .subscribe();
924
- fromEvent(this._elementRef.nativeElement, 'mousedown')
925
- .pipe(tap((e) => this._onMouseDown(e)), takeUntil(this._destroy$))
926
- .subscribe();
927
- this._updateCanScrollState();
1145
+ get config() {
1146
+ return this._config;
928
1147
  }
929
- _onMouseDown(e) {
930
- if (!this._elementRef?.nativeElement || !this._canScroll) {
931
- return;
932
- }
933
- const element = this._elementRef.nativeElement;
934
- element.classList.add(CURSOR_DRAG_SCROLLING_PREPARED_CLASS);
935
- this._elementRef.nativeElement.style.scrollSnapType = 'none';
936
- this._elementRef.nativeElement.style.scrollBehavior = 'unset';
937
- this._currentScrollState = {
938
- left: this._elementRef.nativeElement.scrollLeft,
939
- top: this._elementRef.nativeElement.scrollTop,
940
- x: e.clientX,
941
- y: e.clientY,
942
- };
943
- fromEvent(document, 'mousemove')
944
- .pipe(tap((e) => this._mouseMoveHandler(e)), takeUntil(this._mouseUp$), takeUntil(this._destroy$))
945
- .subscribe();
946
- fromEvent(document, 'mouseup')
947
- .pipe(tap(() => this._mouseUpHandler()), take(1), takeUntil(this._destroy$))
948
- .subscribe();
1148
+ ngOnInit() {
1149
+ this.parent?._deactivate();
949
1150
  }
950
- _mouseMoveHandler(e) {
951
- e.preventDefault();
952
- if (!this._elementRef?.nativeElement) {
1151
+ ngOnDestroy() {
1152
+ this._deactivate();
1153
+ this._cleanUp();
1154
+ this.parent?._activate();
1155
+ }
1156
+ updateConfig(config) {
1157
+ this._config = mergeSeoConfig(config, this.parent?.config || {});
1158
+ if (this._isDeactivated) {
953
1159
  return;
954
1160
  }
955
- const dx = e.clientX - this._currentScrollState.x;
956
- const dy = e.clientY - this._currentScrollState.y;
957
- if (Math.abs(dx) > this._bufferUntilScroll || Math.abs(dy) > this._bufferUntilScroll) {
958
- const element = this._elementRef.nativeElement;
959
- if (!this._isScrolling) {
960
- this._isScrolling = true;
961
- element.style.cursor = 'grabbing';
962
- element.classList.add(CURSOR_DRAG_SCROLLING_CLASS);
963
- element.scroll({
964
- top: this._currentScrollState.top - dy,
965
- left: this._currentScrollState.left - dx,
966
- behavior: 'smooth',
1161
+ this._deactivate();
1162
+ this._activate();
1163
+ }
1164
+ _activate() {
1165
+ this._onDeactivate$.next(false);
1166
+ this._isDeactivated = false;
1167
+ for (const [key, value] of Object.entries(this._config)) {
1168
+ if (value instanceof Observable) {
1169
+ value.pipe(takeUntil(this._onDeactivate$)).subscribe((value) => this._update(key, value));
1170
+ }
1171
+ else if (Array.isArray(value)) {
1172
+ value.forEach((value) => {
1173
+ if (value instanceof Observable) {
1174
+ value.pipe(takeUntil(this._onDeactivate$)).subscribe((value) => this._update(key, value));
1175
+ }
1176
+ else {
1177
+ this._update(key, value);
1178
+ }
967
1179
  });
968
1180
  }
1181
+ else if (typeof value === 'object' && value !== null) {
1182
+ for (const [subKey, subValue] of Object.entries(value)) {
1183
+ if (subValue instanceof Observable) {
1184
+ subValue.pipe(takeUntil(this._onDeactivate$)).subscribe((value) => this._update(`${key}:${subKey}`, value));
1185
+ }
1186
+ else {
1187
+ this._update(`${key}:${subKey}`, subValue);
1188
+ }
1189
+ }
1190
+ }
969
1191
  else {
970
- element.scrollTop = this._currentScrollState.top - dy;
971
- element.scrollLeft = this._currentScrollState.left - dx;
1192
+ this._update(key, value);
972
1193
  }
973
1194
  }
974
1195
  }
975
- _mouseUpHandler() {
976
- this._mouseUp$.next(true);
977
- this._isScrolling = false;
978
- if (!this._elementRef?.nativeElement) {
979
- return;
980
- }
981
- this._elementRef.nativeElement.style.scrollSnapType = '';
982
- this._elementRef.nativeElement.style.scrollBehavior = '';
983
- this._elementRef.nativeElement.style.cursor = 'grab';
984
- this._elementRef.nativeElement.classList.remove(CURSOR_DRAG_SCROLLING_CLASS);
985
- this._elementRef.nativeElement.classList.remove(CURSOR_DRAG_SCROLLING_PREPARED_CLASS);
1196
+ _deactivate() {
1197
+ this._onDeactivate$.next(true);
1198
+ this._isDeactivated = true;
986
1199
  }
987
- _updateCanScrollState() {
988
- this._canScroll = elementCanScroll(this._elementRef.nativeElement);
989
- if (this._canScroll) {
990
- this._elementRef.nativeElement.style.cursor = 'grab';
991
- }
992
- else {
993
- this._elementRef.nativeElement.style.cursor = 'default';
1200
+ _update(key, value) {
1201
+ switch (key) {
1202
+ case 'title':
1203
+ if (value && typeof value === 'string') {
1204
+ this._titleService.setTitle(value);
1205
+ }
1206
+ break;
1207
+ case 'canonical':
1208
+ {
1209
+ const link = document.querySelector(`link[rel="${key}"]`);
1210
+ if (link) {
1211
+ link.setAttribute('href', value);
1212
+ }
1213
+ else {
1214
+ const newLink = document.createElement('link');
1215
+ newLink.setAttribute('rel', key);
1216
+ newLink.setAttribute('href', value);
1217
+ document.head.appendChild(newLink);
1218
+ }
1219
+ }
1220
+ break;
1221
+ case 'alternate':
1222
+ {
1223
+ const link = document.querySelector(`link[rel="${key}"][hreflang="${value.hreflang}"]`);
1224
+ if (link) {
1225
+ link.setAttribute('href', value.href);
1226
+ }
1227
+ else {
1228
+ const newLink = document.createElement('link');
1229
+ newLink.setAttribute('rel', key);
1230
+ newLink.setAttribute('hreflang', value.hreflang);
1231
+ newLink.setAttribute('href', value.href);
1232
+ document.head.appendChild(newLink);
1233
+ }
1234
+ }
1235
+ break;
1236
+ default:
1237
+ if (value !== undefined && value !== null) {
1238
+ const val = Array.isArray(value) ? value.join(', ') : value;
1239
+ this._metaService.updateTag({ name: key, content: val });
1240
+ }
1241
+ else {
1242
+ this._metaService.removeTag(`name="${key}"`);
1243
+ }
1244
+ break;
994
1245
  }
995
1246
  }
996
- _checkCanScroll() {
997
- if (this._elementRef.nativeElement.scrollWidth > this._elementRef.nativeElement.clientWidth) {
998
- return true;
999
- }
1000
- if (this._elementRef.nativeElement.scrollHeight > this._elementRef.nativeElement.clientHeight) {
1001
- return true;
1247
+ _cleanUp() {
1248
+ for (const key in this._config) {
1249
+ if (key === 'alternate') {
1250
+ const links = document.querySelectorAll(`link[rel="${key}"]`);
1251
+ links.forEach((link) => {
1252
+ link.remove();
1253
+ });
1254
+ continue;
1255
+ }
1256
+ if (key === 'canonical') {
1257
+ const link = document.querySelector(`link[rel="${key}"]`);
1258
+ if (link) {
1259
+ link.remove();
1260
+ }
1261
+ continue;
1262
+ }
1263
+ if (typeof this._config[key] === 'object' &&
1264
+ this._config[key] !== null &&
1265
+ !(this._config[key] instanceof Observable)) {
1266
+ for (const subKey in this._config[key]) {
1267
+ const parentValue = this.parent?.config?.[key]?.[subKey];
1268
+ if (parentValue === undefined) {
1269
+ this._update(`${key}:${subKey}`, undefined);
1270
+ }
1271
+ }
1272
+ }
1273
+ else {
1274
+ const parentValue = this.parent?.config?.[key];
1275
+ if (parentValue === undefined) {
1276
+ this._update(key, null);
1277
+ }
1278
+ }
1002
1279
  }
1003
- return false;
1004
1280
  }
1005
1281
  }
1006
- CursorDragScrollDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: CursorDragScrollDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1007
- CursorDragScrollDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.9", type: CursorDragScrollDirective, isStandalone: true, selector: "[etCursorDragScroll]", exportAs: ["etCursorDragScroll"], ngImport: i0 });
1008
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: CursorDragScrollDirective, decorators: [{
1282
+ SeoDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: SeoDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1283
+ SeoDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: SeoDirective, isStandalone: true, providers: [{ provide: SEO_DIRECTIVE_TOKEN, useExisting: SeoDirective }], ngImport: i0 });
1284
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: SeoDirective, decorators: [{
1009
1285
  type: Directive,
1010
1286
  args: [{
1011
- selector: '[etCursorDragScroll]',
1012
- exportAs: 'etCursorDragScroll',
1013
1287
  standalone: true,
1288
+ providers: [{ provide: SEO_DIRECTIVE_TOKEN, useExisting: SeoDirective }],
1014
1289
  }]
1015
1290
  }] });
1016
1291
 
@@ -1024,9 +1299,9 @@ class ToArrayPipe {
1024
1299
  this.transform = toArray;
1025
1300
  }
1026
1301
  }
1027
- ToArrayPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ToArrayPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1028
- ToArrayPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.2.9", ngImport: i0, type: ToArrayPipe, isStandalone: true, name: "toArray" });
1029
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: ToArrayPipe, decorators: [{
1302
+ ToArrayPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ToArrayPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1303
+ ToArrayPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "15.0.0", ngImport: i0, type: ToArrayPipe, isStandalone: true, name: "toArray" });
1304
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ToArrayPipe, decorators: [{
1030
1305
  type: Pipe,
1031
1306
  args: [{ name: 'toArray', standalone: true }]
1032
1307
  }] });
@@ -1035,5 +1310,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImpor
1035
1310
  * Generated bundle index. Do not edit.
1036
1311
  */
1037
1312
 
1038
- export { ClickObserverFactory, ClickObserverService, ClickOutsideDirective, ContentObserverService, CursorDragScrollDirective, DEFAULT_VIEWPORT_CONFIG, DestroyService, FocusVisibleService, LetContext, LetDirective, Memo, MutationObserverFactory, OBSERVE_SCROLL_STATE, ObserveContentDirective, ObserveResizeDirective, ObserveScrollStateDirective, RepeatDirective, ResizeObserverFactory, ResizeObserverService, SCROLL_OBSERVER_IGNORE_TARGET_CLASS, ScrollObserverIgnoreTargetDirective, ToArrayPipe, VIEWPORT_CONFIG, ViewportService, clamp, elementCanScroll, provideViewportConfig, toArray, toArrayTrackByFn };
1313
+ export { ClickObserverFactory, ClickObserverService, ClickOutsideDirective, ContentObserverService, CursorDragScrollDirective, DEFAULT_VIEWPORT_CONFIG, DestroyDirective, DestroyService, FocusVisibleService, LetContext, LetDirective, Memo, MutationObserverFactory, OBSERVE_SCROLL_STATE, ObserveContentDirective, ObserveResizeDirective, ObserveScrollStateDirective, RepeatDirective, ResizeObserverFactory, ResizeObserverService, SCROLL_OBSERVER_FIRST_ELEMENT_CLASS, SCROLL_OBSERVER_IGNORE_TARGET_CLASS, SCROLL_OBSERVER_LAST_ELEMENT_CLASS, SEO_DIRECTIVE_TOKEN, ScrollObserverFirstElementDirective, ScrollObserverIgnoreTargetDirective, ScrollObserverLastElementDirective, SeoDirective, ToArrayPipe, VIEWPORT_CONFIG, ViewportService, clamp, elementCanScroll, mergeSeoConfig, provideViewportConfig, toArray, toArrayTrackByFn };
1039
1314
  //# sourceMappingURL=ethlete-core.mjs.map