@rt-tools/core 0.0.6 → 0.2.0

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.
@@ -1,25 +1,90 @@
1
- import { Subject, Observable, take } from 'rxjs';
2
- import { filter, map } from 'rxjs/operators';
3
- import { isPlatformBrowser, DOCUMENT } from '@angular/common';
4
1
  import * as i0 from '@angular/core';
5
- import { inject, PLATFORM_ID, Injectable, InjectionToken, Input, Attribute, Optional, Directive, Pipe } from '@angular/core';
2
+ import { input, HostBinding, Directive, effect, inject, PLATFORM_ID, Injectable, InjectionToken, HostListener, DestroyRef, signal, output, Pipe, Injector, computed, Input, Attribute, Optional } from '@angular/core';
3
+ import { transformArrayInput, isNil, DASH, isString, isNumber, emptyToDash, isEmail } from '@rt-tools/utils';
4
+ import { Router, ActivatedRoute } from '@angular/router';
5
+ import { isPlatformBrowser, DOCUMENT } from '@angular/common';
6
+ import { takeUntilDestroyed, toSignal, toObservable } from '@angular/core/rxjs-interop';
7
+ import { filter, take, map, distinctUntilChanged, switchMap } from 'rxjs/operators';
8
+ import { DomSanitizer } from '@angular/platform-browser';
9
+ import { Subject, Observable, take as take$1 } from 'rxjs';
10
+ import { BreakpointObserver } from '@angular/cdk/layout';
6
11
 
7
- function isNil(entity) {
8
- return entity === null || entity === undefined;
9
- }
12
+ const OVERLAY_POSITIONS = Object.freeze([
13
+ {
14
+ originX: 'start',
15
+ originY: 'bottom',
16
+ overlayX: 'start',
17
+ overlayY: 'top',
18
+ },
19
+ {
20
+ originX: 'end',
21
+ originY: 'bottom',
22
+ overlayX: 'end',
23
+ overlayY: 'top',
24
+ },
25
+ {
26
+ originX: 'start',
27
+ originY: 'bottom',
28
+ overlayX: 'start',
29
+ overlayY: 'top',
30
+ },
31
+ {
32
+ originX: 'start',
33
+ originY: 'top',
34
+ overlayX: 'start',
35
+ overlayY: 'bottom',
36
+ },
37
+ ]);
10
38
 
11
- class MessageBus {
12
- #eventSource = new Subject();
13
- emit(event) {
14
- this.#eventSource.next(event);
39
+ class RtIconOutlinedDirective {
40
+ constructor() {
41
+ this.isOutlined = input(false, { ...(ngDevMode ? { debugName: "isOutlined" } : /* istanbul ignore next */ {}), alias: 'rtIconOutlined',
42
+ transform: (value) => {
43
+ return Boolean(value);
44
+ } });
15
45
  }
16
- onEmit() {
17
- return this.#eventSource.asObservable();
46
+ get fontVariationSettings() {
47
+ // eslint-disable-next-line quotes
48
+ return this.isOutlined() ? "'FILL' 0, 'wght' 700, 'GRAD' 0, 'opsz' 48" : "'FILL' 1, 'wght' 700, 'GRAD' 0, 'opsz' 48";
18
49
  }
19
- ofType(eventType) {
20
- return this.onEmit().pipe(filter((event) => event.type === eventType), map((event) => event));
50
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: RtIconOutlinedDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
51
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.5", type: RtIconOutlinedDirective, isStandalone: true, selector: "mat-icon[rtIconOutlined]", inputs: { isOutlined: { classPropertyName: "isOutlined", publicName: "rtIconOutlined", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.fontVariationSettings": "this.fontVariationSettings" } }, ngImport: i0 }); }
52
+ }
53
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: RtIconOutlinedDirective, decorators: [{
54
+ type: Directive,
55
+ args: [{
56
+ selector: 'mat-icon[rtIconOutlined]',
57
+ }]
58
+ }], propDecorators: { isOutlined: [{ type: i0.Input, args: [{ isSignal: true, alias: "rtIconOutlined", required: false }] }], fontVariationSettings: [{
59
+ type: HostBinding,
60
+ args: ['style.fontVariationSettings']
61
+ }] } });
62
+
63
+ class RtScrollToElementDirective {
64
+ constructor() {
65
+ this.rtScrollToElement = input.required(/* @ts-ignore */
66
+ ...(ngDevMode ? [{ debugName: "rtScrollToElement" }] : /* istanbul ignore next */ []));
67
+ this.elements = input.required({ ...(ngDevMode ? { debugName: "elements" } : /* istanbul ignore next */ {}), transform: (value) => transformArrayInput(value) });
68
+ effect(() => {
69
+ if (this.elements()?.length && this.rtScrollToElement()) {
70
+ this.#scrollToTarget();
71
+ }
72
+ });
21
73
  }
74
+ #scrollToTarget() {
75
+ const targetId = this.rtScrollToElement();
76
+ const targetElement = document.getElementById(targetId.toString());
77
+ targetElement?.scrollIntoView({ behavior: 'smooth', block: 'start' });
78
+ }
79
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: RtScrollToElementDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
80
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.5", type: RtScrollToElementDirective, isStandalone: true, selector: "[rtScrollToElement]", inputs: { rtScrollToElement: { classPropertyName: "rtScrollToElement", publicName: "rtScrollToElement", isSignal: true, isRequired: true, transformFunction: null }, elements: { classPropertyName: "elements", publicName: "elements", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
22
81
  }
82
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: RtScrollToElementDirective, decorators: [{
83
+ type: Directive,
84
+ args: [{
85
+ selector: '[rtScrollToElement]',
86
+ }]
87
+ }], ctorParameters: () => [], propDecorators: { rtScrollToElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "rtScrollToElement", required: true }] }], elements: [{ type: i0.Input, args: [{ isSignal: true, alias: "elements", required: true }] }] } });
23
88
 
24
89
  /**
25
90
  * A service for detecting the platform on which the application is running.
@@ -49,6 +114,605 @@ const WINDOW = new InjectionToken('An injection token for global window object',
49
114
  },
50
115
  });
51
116
 
117
+ class RtNavigationDirective {
118
+ constructor() {
119
+ this.#router = inject(Router);
120
+ this.#windowRef = inject(WINDOW);
121
+ this.#platformService = inject(PlatformService);
122
+ this.link = input.required({ ...(ngDevMode ? { debugName: "link" } : /* istanbul ignore next */ {}), alias: 'rtNavigationDirective' });
123
+ }
124
+ #router;
125
+ #windowRef;
126
+ #platformService;
127
+ onClick(event) {
128
+ if (this.link()) {
129
+ if (this.#platformService.isPlatformBrowser && (event.ctrlKey || event.metaKey)) {
130
+ this.#windowRef.open(this.link());
131
+ }
132
+ else {
133
+ void this.#router.navigate([this.link()]);
134
+ }
135
+ }
136
+ }
137
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: RtNavigationDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
138
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.5", type: RtNavigationDirective, isStandalone: true, selector: "[rtNavigationDirective]", inputs: { link: { classPropertyName: "link", publicName: "rtNavigationDirective", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "click": "onClick($event)" } }, providers: [PlatformService], ngImport: i0 }); }
139
+ }
140
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: RtNavigationDirective, decorators: [{
141
+ type: Directive,
142
+ args: [{
143
+ selector: '[rtNavigationDirective]',
144
+ providers: [PlatformService],
145
+ }]
146
+ }], propDecorators: { link: [{ type: i0.Input, args: [{ isSignal: true, alias: "rtNavigationDirective", required: true }] }], onClick: [{
147
+ type: HostListener,
148
+ args: ['click', ['$event']]
149
+ }] } });
150
+
151
+ class RtTabQueryParamDirective {
152
+ constructor() {
153
+ this.#router = inject(Router);
154
+ this.#route = inject(ActivatedRoute);
155
+ this.#destroyRef = inject(DestroyRef);
156
+ this.#currentTabIndex = signal(0, /* @ts-ignore */
157
+ ...(ngDevMode ? [{ debugName: "#currentTabIndex" }] : /* istanbul ignore next */ []));
158
+ this.currentTabIndex = this.#currentTabIndex.asReadonly();
159
+ }
160
+ #router;
161
+ #route;
162
+ #destroyRef;
163
+ #currentTabIndex;
164
+ ngOnInit() {
165
+ this.#route.queryParamMap
166
+ .pipe(filter((params) => params.has('tab')), take(1), map((params) => Number(params.get('tab'))), takeUntilDestroyed(this.#destroyRef))
167
+ .subscribe((tabIndex) => {
168
+ this.#setTabIndex(tabIndex);
169
+ });
170
+ }
171
+ setQueryTab(index) {
172
+ void this.#router.navigate([], {
173
+ relativeTo: this.#route,
174
+ queryParams: {
175
+ tab: index,
176
+ },
177
+ queryParamsHandling: 'merge',
178
+ });
179
+ this.#setTabIndex(index);
180
+ }
181
+ #setTabIndex(index) {
182
+ this.#currentTabIndex.set(index);
183
+ }
184
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: RtTabQueryParamDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
185
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.5", type: RtTabQueryParamDirective, isStandalone: true, ngImport: i0 }); }
186
+ }
187
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: RtTabQueryParamDirective, decorators: [{
188
+ type: Directive
189
+ }] });
190
+
191
+ class RtScrollDirective {
192
+ constructor() {
193
+ this.#windowRef = inject(WINDOW);
194
+ this.#platformService = inject(PlatformService);
195
+ this.active = input(true, /* @ts-ignore */
196
+ ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
197
+ this.multiplier = input(0.5, /* @ts-ignore */
198
+ ...(ngDevMode ? [{ debugName: "multiplier" }] : /* istanbul ignore next */ []));
199
+ this.scrollAction = output();
200
+ this.scroll = (event) => {
201
+ const target = event.target;
202
+ if (this.active() && target.offsetHeight + target.scrollTop >= target.scrollHeight * this.multiplier()) {
203
+ this.scrollAction.emit();
204
+ }
205
+ };
206
+ }
207
+ #windowRef;
208
+ #platformService;
209
+ ngOnInit() {
210
+ if (this.#platformService.isPlatformBrowser) {
211
+ this.#windowRef.addEventListener('scroll', this.scroll, true);
212
+ }
213
+ }
214
+ ngOnDestroy() {
215
+ this.#windowRef.removeEventListener('scroll', this.scroll, true);
216
+ }
217
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: RtScrollDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
218
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.5", type: RtScrollDirective, isStandalone: true, selector: "[rtScrollDirective]", inputs: { active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, multiplier: { classPropertyName: "multiplier", publicName: "multiplier", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { scrollAction: "scrollAction" }, ngImport: i0 }); }
219
+ }
220
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: RtScrollDirective, decorators: [{
221
+ type: Directive,
222
+ args: [{
223
+ selector: '[rtScrollDirective]',
224
+ }]
225
+ }], propDecorators: { active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], multiplier: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiplier", required: false }] }], scrollAction: [{ type: i0.Output, args: ["scrollAction"] }] } });
226
+
227
+ class RtEscapeKeyDirective {
228
+ constructor() {
229
+ this.escapeKeyAction = output();
230
+ }
231
+ handleKeyboardEvent(event) {
232
+ if (event.key === 'Escape') {
233
+ this.escapeKeyAction.emit();
234
+ }
235
+ }
236
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: RtEscapeKeyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
237
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.5", type: RtEscapeKeyDirective, isStandalone: true, selector: "[rtEscapeKey]", outputs: { escapeKeyAction: "escapeKeyAction" }, host: { listeners: { "document:keydown": "handleKeyboardEvent($event)" } }, ngImport: i0 }); }
238
+ }
239
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: RtEscapeKeyDirective, decorators: [{
240
+ type: Directive,
241
+ args: [{
242
+ selector: '[rtEscapeKey]',
243
+ }]
244
+ }], propDecorators: { escapeKeyAction: [{ type: i0.Output, args: ["escapeKeyAction"] }], handleKeyboardEvent: [{
245
+ type: HostListener,
246
+ args: ['document:keydown', ['$event']]
247
+ }] } });
248
+
249
+ var POSITION_ENUM;
250
+ (function (POSITION_ENUM) {
251
+ POSITION_ENUM["LEFT"] = "left";
252
+ POSITION_ENUM["RIGHT"] = "right";
253
+ POSITION_ENUM["TOP"] = "top";
254
+ POSITION_ENUM["BOTTOM"] = "bottom";
255
+ POSITION_ENUM["START"] = "start";
256
+ POSITION_ENUM["END"] = "end";
257
+ POSITION_ENUM["CENTER"] = "center";
258
+ })(POSITION_ENUM || (POSITION_ENUM = {}));
259
+
260
+ /**
261
+ * This function is a type guard that checks if a value is an instance of HTMLElement.
262
+ */
263
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
264
+ function isHTMLElement(element) {
265
+ return element instanceof HTMLElement;
266
+ }
267
+
268
+ class BreakStringPipe {
269
+ transform(value) {
270
+ if (isNil(value)) {
271
+ return DASH;
272
+ }
273
+ if (value && isString(value)) {
274
+ if (/\s/.test(value) || /^[A-Z0-9\s]+$/.test(value) || /\d/.test(value) || /[^\w\s]/.test(value)) {
275
+ return value;
276
+ }
277
+ return value.split(/(?=[A-Z])/).join(' ');
278
+ }
279
+ return value.toString();
280
+ }
281
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: BreakStringPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
282
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.5", ngImport: i0, type: BreakStringPipe, isStandalone: true, name: "breakString" }); }
283
+ }
284
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: BreakStringPipe, decorators: [{
285
+ type: Pipe,
286
+ args: [{
287
+ name: 'breakString',
288
+ }]
289
+ }] });
290
+
291
+ class SanitizePipe {
292
+ #sanitizer = inject(DomSanitizer);
293
+ transform(value) {
294
+ return this.#sanitizer.bypassSecurityTrustHtml(value);
295
+ }
296
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: SanitizePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
297
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.5", ngImport: i0, type: SanitizePipe, isStandalone: true, name: "sanitize" }); }
298
+ }
299
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: SanitizePipe, decorators: [{
300
+ type: Pipe,
301
+ args: [{
302
+ name: 'sanitize',
303
+ pure: true,
304
+ }]
305
+ }] });
306
+
307
+ class EntityToStringPipe {
308
+ transform(value) {
309
+ if (isString(value)) {
310
+ return value;
311
+ }
312
+ if (isNumber(value)) {
313
+ return value.toString();
314
+ }
315
+ return DASH;
316
+ }
317
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EntityToStringPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
318
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.5", ngImport: i0, type: EntityToStringPipe, isStandalone: true, name: "entityToString" }); }
319
+ }
320
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EntityToStringPipe, decorators: [{
321
+ type: Pipe,
322
+ args: [{
323
+ name: 'entityToString',
324
+ pure: true,
325
+ }]
326
+ }] });
327
+
328
+ class EmptyToDashPipe {
329
+ transform(value) {
330
+ return emptyToDash(value);
331
+ }
332
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EmptyToDashPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
333
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.5", ngImport: i0, type: EmptyToDashPipe, isStandalone: true, name: "emptyToDash" }); }
334
+ }
335
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EmptyToDashPipe, decorators: [{
336
+ type: Pipe,
337
+ args: [{
338
+ name: 'emptyToDash',
339
+ pure: true,
340
+ }]
341
+ }] });
342
+
343
+ /**
344
+ * @description Use to compare equality to any of items with provided value
345
+ * @example
346
+ *
347
+ * Direct usage
348
+ * ```ts
349
+ * equalPipe.transform(100, 1, 10, 100) // => true
350
+ * ```
351
+ *
352
+ * Template usage
353
+ *
354
+ * ```html
355
+ * <div *ngIf="100 | equal:1:10:100">Visible</div>
356
+ * ```
357
+ */
358
+ class EqualPipe {
359
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
360
+ transform(value, ...compares) {
361
+ return compares.reduce((equal, compare) => equal || value === compare, false);
362
+ }
363
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EqualPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
364
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.5", ngImport: i0, type: EqualPipe, isStandalone: true, name: "equal" }); }
365
+ }
366
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EqualPipe, decorators: [{
367
+ type: Pipe,
368
+ args: [{
369
+ name: 'equal',
370
+ }]
371
+ }] });
372
+
373
+ /**
374
+ * @description Use to access to the deep object state for comparison
375
+ * @example
376
+ * {a: {b: true}} | equalChain:'a':'b':true => true
377
+ */
378
+ class EqualChainPipe {
379
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
380
+ transform(obj, ...args) {
381
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
382
+ const compared = args.pop();
383
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
384
+ return Boolean(obj) && args.reduce((inner, arg) => inner[arg], obj) === compared;
385
+ }
386
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EqualChainPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
387
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.5", ngImport: i0, type: EqualChainPipe, isStandalone: true, name: "equalChain" }); }
388
+ }
389
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: EqualChainPipe, decorators: [{
390
+ type: Pipe,
391
+ args: [{
392
+ name: 'equalChain',
393
+ }]
394
+ }] });
395
+
396
+ /**
397
+ * @description Use to compare not equality to all items with provided value
398
+ * @example
399
+ *
400
+ * Direct usage
401
+ * ```ts
402
+ * notEqualPipe.transform(100, 1, 10, 100) // => false
403
+ * ```
404
+ *
405
+ * Template usage
406
+ *
407
+ * ```html
408
+ * <div *ngIf="100 | notEqual:1:10:100">Invisible</div>
409
+ * ```
410
+ */
411
+ class NotEqualPipe {
412
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
413
+ transform(value, ...compares) {
414
+ return compares.reduce((notEqual, compare) => notEqual && value !== compare, true);
415
+ }
416
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NotEqualPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
417
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.5", ngImport: i0, type: NotEqualPipe, isStandalone: true, name: "notEqual" }); }
418
+ }
419
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NotEqualPipe, decorators: [{
420
+ type: Pipe,
421
+ args: [{
422
+ name: 'notEqual',
423
+ }]
424
+ }] });
425
+
426
+ /**
427
+ * @description Use to access to the deep object state for comparison
428
+ * @example
429
+ * {a: {b: true}} | equalChain:'a':'b':false => true
430
+ */
431
+ class NotEqualChainPipe {
432
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
433
+ transform(obj, ...args) {
434
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
435
+ const compared = args.pop();
436
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
437
+ return Boolean(obj) && args.reduce((inner, arg) => inner[arg], obj) !== compared;
438
+ }
439
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NotEqualChainPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
440
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.5", ngImport: i0, type: NotEqualChainPipe, isStandalone: true, name: "notEqualChain" }); }
441
+ }
442
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NotEqualChainPipe, decorators: [{
443
+ type: Pipe,
444
+ args: [{
445
+ name: 'notEqualChain',
446
+ }]
447
+ }] });
448
+
449
+ class TernaryPipe {
450
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
451
+ transform(value, option1, option2) {
452
+ return Boolean(value) ? option1 : option2;
453
+ }
454
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: TernaryPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
455
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.5", ngImport: i0, type: TernaryPipe, isStandalone: true, name: "ternary" }); }
456
+ }
457
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: TernaryPipe, decorators: [{
458
+ type: Pipe,
459
+ args: [{
460
+ name: 'ternary',
461
+ }]
462
+ }] });
463
+
464
+ class IsEmailPipe {
465
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
466
+ transform(value) {
467
+ return isEmail(value);
468
+ }
469
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: IsEmailPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
470
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.0.5", ngImport: i0, type: IsEmailPipe, isStandalone: true, name: "isEmail" }); }
471
+ }
472
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: IsEmailPipe, decorators: [{
473
+ type: Pipe,
474
+ args: [{
475
+ name: 'isEmail',
476
+ }]
477
+ }] });
478
+
479
+ class MessageBus {
480
+ #eventSource = new Subject();
481
+ emit(event) {
482
+ this.#eventSource.next(event);
483
+ }
484
+ onEmit() {
485
+ return this.#eventSource.asObservable();
486
+ }
487
+ ofType(eventType) {
488
+ return this.onEmit().pipe(filter((event) => event.type === eventType), map((event) => event));
489
+ }
490
+ }
491
+
492
+ const NAVIGATOR = new InjectionToken('An injection token for global navigator object', {
493
+ factory: () => {
494
+ const { defaultView } = inject(DOCUMENT);
495
+ if (!defaultView || !defaultView?.navigator) {
496
+ throw new Error('Navigator is not available');
497
+ }
498
+ return defaultView.navigator;
499
+ },
500
+ });
501
+
502
+ var OSTypes;
503
+ (function (OSTypes) {
504
+ OSTypes.WINDOWS = 'Windows';
505
+ OSTypes.MAC_OS = 'Mac OS';
506
+ OSTypes.LINUX = 'Linux';
507
+ OSTypes.ANDROID = 'Android';
508
+ OSTypes.IOS = 'iOS';
509
+ OSTypes.UNKNOWN = 'Unknown';
510
+ })(OSTypes || (OSTypes = {}));
511
+ class DeviceDetectorService {
512
+ #windowRef;
513
+ #navigatorRef;
514
+ #platformService;
515
+ constructor() {
516
+ this.#windowRef = inject(WINDOW);
517
+ this.#navigatorRef = inject(NAVIGATOR);
518
+ this.#platformService = inject(PlatformService);
519
+ this.userAgent = null;
520
+ if (this.#platformService.isPlatformBrowser &&
521
+ typeof this.#windowRef !== 'undefined' &&
522
+ typeof this.#navigatorRef !== 'undefined' &&
523
+ this.#navigatorRef?.userAgent) {
524
+ this.userAgent = this.#navigatorRef.userAgent;
525
+ }
526
+ }
527
+ isMobile() {
528
+ return this.userAgent ? /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(this.userAgent) : false;
529
+ }
530
+ isTablet() {
531
+ return this.userAgent ? /iPad|Android|Tablet/i.test(this.userAgent) : false;
532
+ }
533
+ isDesktop() {
534
+ return !this.isMobile() && !this.isTablet();
535
+ }
536
+ getOS() {
537
+ let os;
538
+ if (this.userAgent && /Windows/i.test(this.userAgent)) {
539
+ os = OSTypes.WINDOWS;
540
+ }
541
+ else if (this.userAgent && /Macintosh|Mac OS/i.test(this.userAgent)) {
542
+ os = OSTypes.MAC_OS;
543
+ }
544
+ else if (this.userAgent && /Linux/i.test(this.userAgent)) {
545
+ os = OSTypes.LINUX;
546
+ }
547
+ else if (this.userAgent && /Android/i.test(this.userAgent)) {
548
+ os = OSTypes.ANDROID;
549
+ }
550
+ else if (this.userAgent && /iOS/i.test(this.userAgent)) {
551
+ os = OSTypes.IOS;
552
+ }
553
+ else {
554
+ os = OSTypes.UNKNOWN;
555
+ }
556
+ return os;
557
+ }
558
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DeviceDetectorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
559
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DeviceDetectorService }); }
560
+ }
561
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: DeviceDetectorService, decorators: [{
562
+ type: Injectable
563
+ }], ctorParameters: () => [] });
564
+
565
+ class Breakpoints {
566
+ constructor() {
567
+ this.xl = '1920px';
568
+ this.lg = '1280px';
569
+ this.md = '960px';
570
+ this.sm = '720px';
571
+ this.xs = '600px';
572
+ }
573
+ }
574
+
575
+ /**
576
+ * A service that manages responsive design breakpoints using Angular's `BreakpointObserver`.
577
+ * This service provides signals for different screen sizes and allows dynamic
578
+ * breakpoint management.
579
+ *
580
+ * @Injectable
581
+ */
582
+ class BreakpointService {
583
+ constructor() {
584
+ /**
585
+ * Private instance of BreakpointObserver used to observe screen size changes.
586
+ */
587
+ this.#breakpointObserver = inject(BreakpointObserver);
588
+ /**
589
+ * Private instance of Injector.
590
+ */
591
+ this.#injector = inject(Injector);
592
+ /**
593
+ * Instance of a lass containing the breakpoint values for different screen sizes.
594
+ */
595
+ this.#breakpoints = signal(new Breakpoints(), /* @ts-ignore */
596
+ ...(ngDevMode ? [{ debugName: "#breakpoints" }] : /* istanbul ignore next */ []));
597
+ this.#desktopQuery = computed(() => `(min-width: ${this.#breakpoints().xl})`, /* @ts-ignore */
598
+ ...(ngDevMode ? [{ debugName: "#desktopQuery" }] : /* istanbul ignore next */ []));
599
+ this.#smallDesktopQuery = computed(() => `(min-width: ${this.#breakpoints().lg})`, /* @ts-ignore */
600
+ ...(ngDevMode ? [{ debugName: "#smallDesktopQuery" }] : /* istanbul ignore next */ []));
601
+ this.#tabletQuery = computed(() => `(min-width: ${this.#breakpoints().md})`, /* @ts-ignore */
602
+ ...(ngDevMode ? [{ debugName: "#tabletQuery" }] : /* istanbul ignore next */ []));
603
+ this.#smallTabletQuery = computed(() => `(min-width: ${this.#breakpoints().sm})`, /* @ts-ignore */
604
+ ...(ngDevMode ? [{ debugName: "#smallTabletQuery" }] : /* istanbul ignore next */ []));
605
+ this.#mobileQuery = computed(() => `(max-width: ${this.decrementOnePixel(this.#breakpoints().xs)})`, /* @ts-ignore */
606
+ ...(ngDevMode ? [{ debugName: "#mobileQuery" }] : /* istanbul ignore next */ []));
607
+ this.isDesktop = toSignal(toObservable(this.#desktopQuery, { injector: this.#injector }).pipe(distinctUntilChanged(), switchMap((query) => this.#breakpointObserver.observe(query)), map(({ matches }) => matches)));
608
+ this.isSmallDesktop = toSignal(toObservable(this.#smallDesktopQuery, { injector: this.#injector }).pipe(distinctUntilChanged(), switchMap((query) => this.#breakpointObserver.observe(query)), map(({ matches }) => matches)));
609
+ this.isMobile = toSignal(toObservable(this.#mobileQuery, { injector: this.#injector }).pipe(distinctUntilChanged(), switchMap((query) => this.#breakpointObserver.observe(query)), map(({ matches }) => matches)));
610
+ this.isTablet = toSignal(toObservable(this.#tabletQuery, { injector: this.#injector }).pipe(distinctUntilChanged(), switchMap((query) => this.#breakpointObserver.observe(query)), map(({ matches }) => !matches)));
611
+ this.isSmallTablet = toSignal(toObservable(this.#smallTabletQuery, { injector: this.#injector }).pipe(distinctUntilChanged(), switchMap((query) => this.#breakpointObserver.observe(query)), map(({ matches }) => matches)));
612
+ }
613
+ /**
614
+ * Private instance of BreakpointObserver used to observe screen size changes.
615
+ */
616
+ #breakpointObserver;
617
+ /**
618
+ * Private instance of Injector.
619
+ */
620
+ #injector;
621
+ /**
622
+ * Instance of a lass containing the breakpoint values for different screen sizes.
623
+ */
624
+ #breakpoints;
625
+ #desktopQuery;
626
+ #smallDesktopQuery;
627
+ #tabletQuery;
628
+ #smallTabletQuery;
629
+ #mobileQuery;
630
+ /**
631
+ * Allows setting custom breakpoints for different screen sizes.
632
+ *
633
+ * @param breakpoints - The custom breakpoints to apply.
634
+ */
635
+ setBreakpoints(breakpoints) {
636
+ this.#breakpoints.set(breakpoints);
637
+ }
638
+ /**
639
+ * Helper function to decrement the pixel value by 1.
640
+ * Used to exclude the exact pixel value in media queries.
641
+ *
642
+ * @usageNotes
643
+ *
644
+ * This function is useful for setting correct media queries.
645
+ * E.g. for mobile devices: media query should be `(max-width: 599px)`,
646
+ * and from `(min-width: 600px)` it should be considered as a tablet.
647
+ *
648
+ * @param value - The pixel value to decrement.
649
+ * @returns The adjusted pixel value as a string.
650
+ */
651
+ decrementOnePixel(value) {
652
+ return Number(value.split('px')[0]) - 1 + 'px';
653
+ }
654
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: BreakpointService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
655
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: BreakpointService }); }
656
+ }
657
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: BreakpointService, decorators: [{
658
+ type: Injectable
659
+ }] });
660
+
661
+ function checkIsMatchingValues(sample) {
662
+ return (control) => {
663
+ return sample && control.value && control.value.localeCompare(sample) === 0 ? null : { notEquivalent: true };
664
+ };
665
+ }
666
+
667
+ function arraysNotEmptyValidator(control) {
668
+ if (control.value instanceof Object) {
669
+ const arrays = Object.values(control.value);
670
+ const allArraysEmpty = arrays.every((array) => !array.length);
671
+ return allArraysEmpty ? { allArraysEmpty: true } : null;
672
+ }
673
+ else if (Array.isArray(control.value)) {
674
+ const array = control.value;
675
+ return !array.length ? { arrayEmpty: true } : null;
676
+ }
677
+ else {
678
+ return { invalidType: true };
679
+ }
680
+ }
681
+
682
+ /**
683
+ * @description Reactive-forms validator over the framework-free `isEmail` predicate.
684
+ *
685
+ * Reports `{ email: true }` on a malformed address. An empty control passes, matching `isEmail` —
686
+ * combine it with `Validators.required` where the field is mandatory.
687
+ */
688
+ function emailValidator(control) {
689
+ return isEmail(control.value) ? null : { email: true };
690
+ }
691
+
692
+ /**
693
+ * Returns a set of dependency injection providers for utility services.
694
+ *
695
+ * @usageNotes
696
+ *
697
+ * This function provides utility services that are commonly used across
698
+ * an Angular application. Specifically, it provides the `BreakpointService`
699
+ * for managing responsive design breakpoints and the `PlatformService` for
700
+ * detecting the platform on which the application is running (e.g., browser or server).
701
+ *
702
+ * ```typescript
703
+ * bootstrapApplication(RootComponent, {
704
+ * providers: [
705
+ * provideRtUtils()
706
+ * ]
707
+ * });
708
+ * ```
709
+ *
710
+ * @publicApi
711
+ */
712
+ function provideRtUtils() {
713
+ return [BreakpointService, PlatformService];
714
+ }
715
+
52
716
  const BEM_MODULE_CONFIG = {
53
717
  separators: {
54
718
  el: '__',
@@ -589,7 +1253,7 @@ class IDBStorageService {
589
1253
  }
590
1254
  get(key) {
591
1255
  return new Observable((observer) => {
592
- this.#context.pipe(take(1)).subscribe((db) => {
1256
+ this.#context.pipe(take$1(1)).subscribe((db) => {
593
1257
  const transaction = db.transaction('idb', 'readonly');
594
1258
  const store = transaction.objectStore('idb');
595
1259
  const request = store.get(key);
@@ -600,7 +1264,7 @@ class IDBStorageService {
600
1264
  }
601
1265
  set(key, value) {
602
1266
  return new Observable((observer) => {
603
- this.#context.pipe(take(1)).subscribe((db) => {
1267
+ this.#context.pipe(take$1(1)).subscribe((db) => {
604
1268
  const transaction = db.transaction('idb', 'readwrite');
605
1269
  const store = transaction.objectStore('idb');
606
1270
  const request = store.put(value, key);
@@ -611,7 +1275,7 @@ class IDBStorageService {
611
1275
  }
612
1276
  remove(key) {
613
1277
  return new Observable((observer) => {
614
- this.#context.pipe(take(1)).subscribe((db) => {
1278
+ this.#context.pipe(take$1(1)).subscribe((db) => {
615
1279
  const transaction = db.transaction('idb', 'readwrite');
616
1280
  const store = transaction.objectStore('idb');
617
1281
  const request = store.delete(key);
@@ -674,11 +1338,11 @@ function provideRtIDBStorage() {
674
1338
  ];
675
1339
  }
676
1340
 
677
- // functions
1341
+ // constants
678
1342
 
679
1343
  /**
680
1344
  * Generated bundle index. Do not edit.
681
1345
  */
682
1346
 
683
- export { BlockDirective, CUSTOM_STORAGE, ConcatClassesPipe, ElemDirective, IDBStorageService, IDB_STORAGE_SERVICE_TOKEN, IN_MEMORY_STORAGE, InMemoryStorageService, JsonConverter, LOCAL_STORAGE, MessageBus, ModDirective, PlatformService, SESSION_STORAGE, STORAGE_TYPES_ENUM, StorageService, WINDOW, iDBStorageFactory, inMemoryStorageFactory, isNil, localStorageFactory, provideRtIDBStorage, provideRtStorage, sessionStorageFactory };
1347
+ export { BlockDirective, BreakStringPipe, BreakpointService, Breakpoints, CUSTOM_STORAGE, ConcatClassesPipe, DeviceDetectorService, ElemDirective, EmptyToDashPipe, EntityToStringPipe, EqualChainPipe, EqualPipe, IDBStorageService, IDB_STORAGE_SERVICE_TOKEN, IN_MEMORY_STORAGE, InMemoryStorageService, IsEmailPipe, JsonConverter, LOCAL_STORAGE, MessageBus, ModDirective, NAVIGATOR, NotEqualChainPipe, NotEqualPipe, OSTypes, OVERLAY_POSITIONS, POSITION_ENUM, PlatformService, RtEscapeKeyDirective, RtIconOutlinedDirective, RtNavigationDirective, RtScrollDirective, RtScrollToElementDirective, RtTabQueryParamDirective, SESSION_STORAGE, STORAGE_TYPES_ENUM, SanitizePipe, StorageService, TernaryPipe, WINDOW, arraysNotEmptyValidator, checkIsMatchingValues, emailValidator, iDBStorageFactory, inMemoryStorageFactory, isHTMLElement, localStorageFactory, provideRtIDBStorage, provideRtStorage, provideRtUtils, sessionStorageFactory };
684
1348
  //# sourceMappingURL=rt-tools-core.mjs.map