@ethlete/core 0.2.0-next.20 → 0.2.0-next.22

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,8 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, HostBinding, InjectionToken, Injectable, Inject, Optional, ElementRef, EventEmitter, Directive, Output, NgZone, Pipe, QueryList } from '@angular/core';
2
+ import { inject, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, HostBinding, InjectionToken, Injectable, ElementRef, Inject, Optional, EventEmitter, Directive, Output, NgZone, Pipe, QueryList } from '@angular/core';
3
3
  import { DomSanitizer, Meta, Title } from '@angular/platform-browser';
4
4
  import { coerceElement, coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
5
- import { fromEvent, Observable, Subject, BehaviorSubject, filter, distinctUntilChanged, map, pairwise, combineLatest, shareReplay, takeUntil, startWith, debounceTime, tap, take } from 'rxjs';
5
+ import { fromEvent, Observable, Subject, takeUntil, distinctUntilChanged, BehaviorSubject, filter, map, combineLatest, pairwise, debounceTime, shareReplay, startWith, tap, take } from 'rxjs';
6
6
  import { DOCUMENT } from '@angular/common';
7
7
  import { Router, NavigationEnd } from '@angular/router';
8
8
  import { __decorate, __metadata } from 'tslib';
@@ -348,647 +348,680 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
348
348
  args: [{ providedIn: 'root' }]
349
349
  }], ctorParameters: function () { return [{ type: ResizeObserverFactory }]; } });
350
350
 
351
- const routerDisableScrollTop = (config = {}) => {
352
- if (!config.asReturnRoute) {
353
- return {
354
- disableScrollTop: true,
355
- };
351
+ const clamp = (value, min = 0, max = 100) => {
352
+ return Math.max(min, Math.min(max, value));
353
+ };
354
+
355
+ /* eslint-disable @typescript-eslint/no-explicit-any */
356
+ /* eslint-disable no-var */
357
+ /**
358
+ * Stolen from klona to avoid adding a dependency
359
+ * https://github.com/lukeed/klona
360
+ *
361
+ * MIT License
362
+ *
363
+ * Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com)
364
+ *
365
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
366
+ *
367
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
368
+ *
369
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
370
+ */
371
+ const set = (obj, key, val) => {
372
+ if (typeof val.value === 'object')
373
+ val.value = clone(val.value);
374
+ if (!val.enumerable || val.get || val.set || !val.configurable || !val.writable || key === '__proto__') {
375
+ Object.defineProperty(obj, key, val);
356
376
  }
357
- return {
358
- disableScrollTopAsReturnRoute: true,
359
- };
377
+ else
378
+ obj[key] = val.value;
360
379
  };
361
- class RouterStateService {
362
- get route$() {
363
- return this._route$.asObservable();
380
+ const clone = (original) => {
381
+ if (typeof original !== 'object')
382
+ return original;
383
+ var _og = original;
384
+ var i = 0, k, list, tmp, str = Object.prototype.toString.call(_og);
385
+ if (str === '[object Object]') {
386
+ tmp = Object.create(_og.__proto__ || null);
364
387
  }
365
- get state$() {
366
- return this._state$.asObservable();
388
+ else if (str === '[object Array]') {
389
+ tmp = Array(_og.length);
367
390
  }
368
- constructor() {
369
- this._isScrollTopOnNavigationEnabled = false;
370
- this._router = inject(Router);
371
- this._route$ = new BehaviorSubject('/');
372
- this._state$ = new BehaviorSubject({
373
- title: undefined,
374
- data: {},
375
- pathParams: {},
376
- queryParams: {},
391
+ else if (str === '[object Set]') {
392
+ tmp = new Set();
393
+ _og.forEach(function (val) {
394
+ tmp.add(clone(val));
377
395
  });
378
- this._router.events
379
- .pipe(filter((event) => event instanceof NavigationEnd), distinctUntilChanged((a, b) => a.url === b.url), map((event) => event.url))
380
- .subscribe(this._route$);
381
- this._route$
382
- .pipe(map(() => {
383
- let route = this._router.routerState.snapshot.root;
384
- while (route.firstChild) {
385
- route = route.firstChild;
386
- }
387
- const { data, params, queryParams, title } = route;
388
- return {
389
- data,
390
- pathParams: params,
391
- queryParams,
392
- title,
393
- };
394
- }))
395
- .subscribe(this._state$);
396
396
  }
397
- enableScrollTopOnNavigation(config = {}) {
398
- if (this._isScrollTopOnNavigationEnabled) {
399
- return;
400
- }
401
- this._isScrollTopOnNavigationEnabled = true;
402
- this._state$.pipe(pairwise()).subscribe(([oldData, newData]) => {
403
- var _a;
404
- if (!(newData.data['disableScrollTopAsReturnRoute'] && oldData.data['disableScrollTop']) &&
405
- !newData.data['disableScrollTop']) {
406
- ((_a = config.scrollElement) !== null && _a !== void 0 ? _a : document.documentElement).scrollTop = 0;
407
- }
397
+ else if (str === '[object Map]') {
398
+ tmp = new Map();
399
+ _og.forEach(function (val, key) {
400
+ tmp.set(clone(key), clone(val));
408
401
  });
409
402
  }
410
- selectQueryParam(key) {
411
- return this._state$.pipe(map((state) => state.queryParams[key]));
412
- }
413
- selectPathParam(key) {
414
- return this._state$.pipe(map((state) => state.pathParams[key]));
415
- }
416
- selectData(key) {
417
- return this._state$.pipe(map((state) => state.data[key]));
418
- }
419
- }
420
- RouterStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: RouterStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
421
- RouterStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: RouterStateService, providedIn: 'root' });
422
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: RouterStateService, decorators: [{
423
- type: Injectable,
424
- args: [{
425
- providedIn: 'root',
426
- }]
427
- }], ctorParameters: function () { return []; } });
428
-
429
- class ViewportService {
430
- get isXs$() {
431
- return this._isXs$.asObservable();
432
- }
433
- get isXs() {
434
- return this._isXs$.value;
435
- }
436
- get isSm$() {
437
- return this._isSm$.asObservable();
403
+ else if (str === '[object Date]') {
404
+ tmp = new Date(+_og);
438
405
  }
439
- get isSm() {
440
- return this._isSm$.value;
406
+ else if (str === '[object RegExp]') {
407
+ tmp = new RegExp(_og.source, _og.flags);
441
408
  }
442
- get isMd$() {
443
- return this._isMd$.asObservable();
409
+ else if (str === '[object DataView]') {
410
+ tmp = new _og.constructor(clone(_og.buffer));
444
411
  }
445
- get isMd() {
446
- return this._isMd$.value;
412
+ else if (str === '[object ArrayBuffer]') {
413
+ tmp = _og.slice(0);
447
414
  }
448
- get isLg$() {
449
- return this._isLg$.asObservable();
415
+ else if (str.slice(-6) === 'Array]') {
416
+ // ArrayBuffer.isView(x)
417
+ // ~> `new` bcuz `Buffer.slice` => ref
418
+ tmp = new _og.constructor(_og);
450
419
  }
451
- get isLg() {
452
- return this._isLg$.value;
420
+ if (tmp) {
421
+ for (list = Object.getOwnPropertySymbols(_og); i < list.length; i++) {
422
+ set(tmp, list[i], Object.getOwnPropertyDescriptor(_og, list[i]));
423
+ }
424
+ for (i = 0, list = Object.getOwnPropertyNames(_og); i < list.length; i++) {
425
+ if (Object.hasOwnProperty.call(tmp, (k = list[i])) && tmp[k] === _og[k])
426
+ continue;
427
+ set(tmp, k, Object.getOwnPropertyDescriptor(_og, k));
428
+ }
453
429
  }
454
- get isXl$() {
455
- return this._isXl$.asObservable();
430
+ return tmp || _og;
431
+ };
432
+
433
+ const hasCookie = (name) => {
434
+ if (typeof document === 'undefined') {
435
+ return false;
456
436
  }
457
- get isXl() {
458
- return this._isXl$.value;
437
+ return document.cookie.split(';').some((c) => {
438
+ return c.trim().startsWith(name + '=');
439
+ });
440
+ };
441
+ const getCookie = (name) => {
442
+ var _a;
443
+ if (typeof document === 'undefined') {
444
+ return null;
459
445
  }
460
- get is2Xl$() {
461
- return this._is2Xl$.asObservable();
446
+ // From https://stackoverflow.com/questions/10730362/get-cookie-by-name
447
+ return (_a = ('; ' + document.cookie).split(`; ${name}=`).pop()) === null || _a === void 0 ? void 0 : _a.split(';')[0];
448
+ };
449
+ const setCookie = (name, data, expiresInDays = 30, domain = getDomain()) => {
450
+ if (typeof document === 'undefined') {
451
+ return;
462
452
  }
463
- get is2Xl() {
464
- return this._is2Xl$.value;
453
+ const date = new Date();
454
+ date.setTime(date.getTime() + expiresInDays * 24 * 60 * 60 * 1000);
455
+ document.cookie = `${name}=${data}; path=/; expires=${date.toUTCString()}; domain=${domain}; SameSite=Lax;`;
456
+ };
457
+ const deleteCookie = (name, path, domain = getDomain()) => {
458
+ if (hasCookie(name)) {
459
+ document.cookie =
460
+ name +
461
+ '=' +
462
+ (path ? ';path=' + path : '') +
463
+ (domain ? ';domain=' + domain : '') +
464
+ ';expires=Thu, 01 Jan 1970 00:00:01 GMT';
465
465
  }
466
- get currentViewport() {
467
- return this.getCurrentViewport([this.isXs, this.isSm, this.isMd, this.isLg, this.isXl, this.is2Xl]);
466
+ };
467
+ const getDomain = () => {
468
+ if (typeof navigator === 'undefined') {
469
+ return null;
468
470
  }
469
- constructor(_viewportConfig, _breakpointObserver) {
470
- this._breakpointObserver = _breakpointObserver;
471
- this._isXs$ = new BehaviorSubject(false);
472
- this._isSm$ = new BehaviorSubject(false);
473
- this._isMd$ = new BehaviorSubject(false);
474
- this._isLg$ = new BehaviorSubject(false);
475
- this._isXl$ = new BehaviorSubject(false);
476
- this._is2Xl$ = new BehaviorSubject(false);
477
- this.currentViewport$ = combineLatest([this.isXs$, this.isSm$, this.isMd$, this.isLg$, this.isXl$, this.is2Xl$]).pipe(map((val) => this.getCurrentViewport(val)), shareReplay());
478
- this._viewportConfig = _viewportConfig || DEFAULT_VIEWPORT_CONFIG;
479
- this._observeDefaultBreakpoints();
471
+ const hostname = window.location.hostname;
472
+ if (hostname.includes('localhost')) {
473
+ return 'localhost';
480
474
  }
481
- observe(options) {
482
- const mediaQuery = this._buildMediaQuery(options);
483
- return this._breakpointObserver.observe(mediaQuery).pipe(map((x) => x.matches), shareReplay());
475
+ const splitHost = hostname.split('.');
476
+ if (splitHost.length > 2) {
477
+ return `${splitHost[splitHost.length - 2]}.${splitHost[splitHost.length - 1]}`;
484
478
  }
485
- isMatched(options) {
486
- const mediaQuery = this._buildMediaQuery(options);
487
- return this._breakpointObserver.isMatched(mediaQuery);
479
+ return hostname;
480
+ };
481
+
482
+ /* eslint-disable @typescript-eslint/no-explicit-any */
483
+ /* eslint-disable no-var */
484
+ /**
485
+ * Stolen from dequal to avoid adding a dependency
486
+ * https://github.com/lukeed/dequal
487
+ *
488
+ * The MIT License (MIT)
489
+ *
490
+ * Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com)
491
+ *
492
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
493
+ * of this software and associated documentation files (the "Software"), to deal
494
+ * in the Software without restriction, including without limitation the rights
495
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
496
+ * copies of the Software, and to permit persons to whom the Software is
497
+ * furnished to do so, subject to the following conditions:
498
+ *
499
+ * The above copyright notice and this permission notice shall be included in
500
+ * all copies or substantial portions of the Software.
501
+ *
502
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
503
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
504
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
505
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
506
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
507
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
508
+ * THE SOFTWARE.
509
+ */
510
+ const has = Object.prototype.hasOwnProperty;
511
+ function find(iter, tar, key) {
512
+ for (key of iter.keys()) {
513
+ if (equal(key, tar))
514
+ return key;
488
515
  }
489
- _observeDefaultBreakpoints() {
490
- this.observe({ max: 'xs' }).subscribe(this._isXs$);
491
- this.observe({ min: 'sm', max: 'sm' }).subscribe(this._isSm$);
492
- this.observe({ min: 'md', max: 'md' }).subscribe(this._isMd$);
493
- this.observe({ min: 'lg', max: 'lg' }).subscribe(this._isLg$);
494
- this.observe({ min: 'xl', max: 'xl' }).subscribe(this._isXl$);
495
- this.observe({ min: '2xl' }).subscribe(this._is2Xl$);
496
- }
497
- _getViewportSize(type, option) {
498
- const index = option === 'min' ? 0 : 1;
499
- const size = this._viewportConfig.breakpoints[type][index];
500
- if (size === Infinity || size === 0) {
501
- return size;
502
- }
503
- if (option === 'min') {
504
- return size;
505
- }
506
- // Due to scaling, the actual size of the viewport may be a decimal number.
507
- // Eg. on Windows 11 with 150% scaling, the viewport size may be 1535.33px
508
- // and thus not matching any of the default breakpoints.
509
- return size + 0.9;
510
- }
511
- _buildMediaQuery(options) {
512
- if (!options.min && !options.max) {
513
- throw new Error('At least one of min or max must be defined');
516
+ }
517
+ const equal = (foo, bar) => {
518
+ var ctor, len, tmp;
519
+ if (foo === bar)
520
+ return true;
521
+ if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
522
+ if (ctor === Date)
523
+ return foo.getTime() === bar.getTime();
524
+ if (ctor === RegExp)
525
+ return foo.toString() === bar.toString();
526
+ if (ctor === Array) {
527
+ if ((len = foo.length) === bar.length) {
528
+ while (len-- && equal(foo[len], bar[len]))
529
+ ;
530
+ }
531
+ return len === -1;
514
532
  }
515
- const mediaQueryParts = [];
516
- if (options.min) {
517
- if (typeof options.min === 'number') {
518
- mediaQueryParts.push(`(min-width: ${options.min}px)`);
533
+ if (ctor === Set) {
534
+ if (foo.size !== bar.size) {
535
+ return false;
519
536
  }
520
- else {
521
- mediaQueryParts.push(`(min-width: ${this._getViewportSize(options.min, 'min')}px)`);
537
+ for (len of foo) {
538
+ tmp = len;
539
+ if (tmp && typeof tmp === 'object') {
540
+ tmp = find(bar, tmp);
541
+ if (!tmp)
542
+ return false;
543
+ }
544
+ if (!bar.has(tmp))
545
+ return false;
522
546
  }
547
+ return true;
523
548
  }
524
- if (options.min && options.max) {
525
- mediaQueryParts.push('and');
526
- }
527
- if (options.max) {
528
- if (typeof options.max === 'number') {
529
- mediaQueryParts.push(`(max-width: ${options.max}px)`);
549
+ if (ctor === Map) {
550
+ if (foo.size !== bar.size) {
551
+ return false;
530
552
  }
531
- else {
532
- mediaQueryParts.push(`(max-width: ${this._getViewportSize(options.max, 'max')}px)`);
553
+ for (len of foo) {
554
+ tmp = len[0];
555
+ if (tmp && typeof tmp === 'object') {
556
+ tmp = find(bar, tmp);
557
+ if (!tmp)
558
+ return false;
559
+ }
560
+ if (!equal(len[1], bar.get(tmp))) {
561
+ return false;
562
+ }
533
563
  }
564
+ return true;
534
565
  }
535
- return mediaQueryParts.join(' ');
536
- }
537
- getCurrentViewport([isXs, isSm, isMd, isLg, isXl, is2Xl]) {
538
- if (isXs) {
539
- return 'xs';
566
+ if (ctor === ArrayBuffer) {
567
+ foo = new Uint8Array(foo);
568
+ bar = new Uint8Array(bar);
540
569
  }
541
- else if (isSm) {
542
- return 'sm';
570
+ else if (ctor === DataView) {
571
+ if ((len = foo.byteLength) === bar.byteLength) {
572
+ while (len-- && foo.getInt8(len) === bar.getInt8(len))
573
+ ;
574
+ }
575
+ return len === -1;
543
576
  }
544
- else if (isMd) {
545
- return 'md';
577
+ if (ArrayBuffer.isView(foo)) {
578
+ if ((len = foo.byteLength) === bar.byteLength) {
579
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
580
+ //@ts-ignore
581
+ while (len-- && foo[len] === bar[len])
582
+ ;
583
+ }
584
+ return len === -1;
546
585
  }
547
- else if (isLg) {
548
- return 'lg';
586
+ if (!ctor || typeof foo === 'object') {
587
+ len = 0;
588
+ for (ctor in foo) {
589
+ if (has.call(foo, ctor) && ++len && !has.call(bar, ctor))
590
+ return false;
591
+ if (!(ctor in bar) || !equal(foo[ctor], bar[ctor]))
592
+ return false;
593
+ }
594
+ return Object.keys(bar).length === len;
549
595
  }
550
- else if (isXl) {
551
- return 'xl';
596
+ }
597
+ return foo !== foo && bar !== bar;
598
+ };
599
+
600
+ const isAttributeRenderBinding = (value) => typeof value === 'boolean';
601
+ const isAttributeValueBinding = (value) => typeof value === 'object';
602
+ const createReactiveBindings = (...values) => {
603
+ const rootElementRef = inject(ElementRef);
604
+ const destroy$ = inject(DestroyService, { host: true }).destroy$;
605
+ const subscriptions = [];
606
+ const pushedAttributes = [];
607
+ const defaults = {};
608
+ const push = (value) => {
609
+ const { attribute, observable, elementRef } = value;
610
+ const elRef = elementRef || rootElementRef;
611
+ const attributes = Array.isArray(attribute) ? attribute : [attribute];
612
+ pushedAttributes.push(attributes);
613
+ for (const attribute of attributes) {
614
+ if (!defaults[attribute]) {
615
+ defaults[attribute] = elRef.nativeElement.getAttribute(attribute) || undefined;
616
+ }
552
617
  }
553
- else if (is2Xl) {
554
- return '2xl';
618
+ const subscription = observable
619
+ .pipe(takeUntil(destroy$), distinctUntilChanged((a, b) => {
620
+ if (isAttributeRenderBinding(a) && isAttributeRenderBinding(b)) {
621
+ return a === b;
622
+ }
623
+ else if (isAttributeValueBinding(a) && isAttributeValueBinding(b)) {
624
+ return a.render === b.render && a.value === b.value;
625
+ }
626
+ return false;
627
+ }))
628
+ .subscribe((value) => {
629
+ const currentAttributes = pushedAttributes.find((s) => s.some((current) => attributes.includes(current))) || [];
630
+ for (const attribute of currentAttributes) {
631
+ const isSingleClassMutation = attribute.startsWith('class.');
632
+ const isMultipleClassMutation = attribute === 'class';
633
+ const render = isAttributeRenderBinding(value) ? value : value.render;
634
+ if (isSingleClassMutation) {
635
+ const className = attribute.replace('class.', '');
636
+ if (!className) {
637
+ continue;
638
+ }
639
+ if (!render) {
640
+ elRef.nativeElement.classList.remove(className);
641
+ }
642
+ else {
643
+ elRef.nativeElement.classList.add(className);
644
+ }
645
+ }
646
+ else if (isMultipleClassMutation) {
647
+ const classes = isAttributeRenderBinding(value) ? '' : `${value.value}`;
648
+ if (!classes) {
649
+ continue;
650
+ }
651
+ if (!render) {
652
+ elRef.nativeElement.classList.remove(...classes.split(' '));
653
+ }
654
+ else {
655
+ elRef.nativeElement.classList.add(...classes.split(' '));
656
+ }
657
+ }
658
+ else {
659
+ const attributeValue = isAttributeRenderBinding(value) ? true : `${value.value}`;
660
+ if (!attribute) {
661
+ continue;
662
+ }
663
+ if (!render) {
664
+ elRef.nativeElement.removeAttribute(attribute);
665
+ }
666
+ else {
667
+ elRef.nativeElement.setAttribute(attribute, `${attributeValue}`);
668
+ }
669
+ }
670
+ }
671
+ });
672
+ subscriptions.push({ attributes, subscription });
673
+ };
674
+ const remove = (...attributes) => {
675
+ for (const attribute of attributes) {
676
+ const sub = subscriptions.find((s) => s.attributes.includes(attribute));
677
+ const attributeStack = pushedAttributes.find((a) => a.includes(attribute));
678
+ if (sub) {
679
+ sub.attributes = sub.attributes.filter((a) => a !== attribute);
680
+ attributeStack === null || attributeStack === void 0 ? void 0 : attributeStack.splice(attributeStack.indexOf(attribute), 1);
681
+ if (sub.attributes.length === 0) {
682
+ sub.subscription.unsubscribe();
683
+ subscriptions.splice(subscriptions.indexOf(sub), 1);
684
+ }
685
+ }
555
686
  }
556
- return 'xs';
687
+ };
688
+ const reset = () => {
689
+ for (const attribute in defaults) {
690
+ if (defaults[attribute] === undefined) {
691
+ rootElementRef.nativeElement.removeAttribute(attribute);
692
+ }
693
+ else {
694
+ rootElementRef.nativeElement.setAttribute(attribute, defaults[attribute]);
695
+ }
696
+ }
697
+ };
698
+ for (const value of values) {
699
+ push(value);
557
700
  }
558
- }
559
- ViewportService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ViewportService, deps: [{ token: VIEWPORT_CONFIG, optional: true }, { token: i1.BreakpointObserver }], target: i0.ɵɵFactoryTarget.Injectable });
560
- ViewportService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ViewportService, providedIn: 'root' });
561
- __decorate([
562
- Memo(),
563
- __metadata("design:type", Function),
564
- __metadata("design:paramtypes", [String, String]),
565
- __metadata("design:returntype", void 0)
566
- ], ViewportService.prototype, "_getViewportSize", null);
567
- __decorate([
568
- Memo({
569
- resolver: (v) => {
570
- var _a, _b;
571
- return `${(_a = v.min) !== null && _a !== void 0 ? _a : ''}-${(_b = v.max) !== null && _b !== void 0 ? _b : ''}`;
572
- },
573
- }),
574
- __metadata("design:type", Function),
575
- __metadata("design:paramtypes", [Object]),
576
- __metadata("design:returntype", void 0)
577
- ], ViewportService.prototype, "_buildMediaQuery", null);
578
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ViewportService, decorators: [{
579
- type: Injectable,
580
- args: [{
581
- providedIn: 'root',
582
- }]
583
- }], ctorParameters: function () {
584
- return [{ type: undefined, decorators: [{
585
- type: Inject,
586
- args: [VIEWPORT_CONFIG]
587
- }, {
588
- type: Optional
589
- }] }, { type: i1.BreakpointObserver }];
590
- }, propDecorators: { _getViewportSize: [], _buildMediaQuery: [] } });
701
+ return {
702
+ push,
703
+ remove,
704
+ reset,
705
+ };
706
+ };
591
707
 
592
- class ClickOutsideDirective {
708
+ const elementCanScroll = (element) => {
709
+ const { scrollHeight, clientHeight, scrollWidth, clientWidth } = element;
710
+ return scrollHeight > clientHeight || scrollWidth > clientWidth;
711
+ };
712
+
713
+ const provideViewportConfig = (viewportConfig) => {
714
+ return { provide: VIEWPORT_CONFIG, useValue: viewportConfig };
715
+ };
716
+
717
+ const routerDisableScrollTop = (config = {}) => {
718
+ if (!config.asReturnRoute) {
719
+ return {
720
+ disableScrollTop: true,
721
+ };
722
+ }
723
+ return {
724
+ disableScrollTopAsReturnRoute: true,
725
+ };
726
+ };
727
+ class RouterStateService {
728
+ get route$() {
729
+ return this._route$.asObservable();
730
+ }
731
+ get state$() {
732
+ return this._state$.asObservable();
733
+ }
593
734
  constructor() {
594
- this._elementRef = inject(ElementRef);
595
- this._clickObserverService = inject(ClickObserverService);
596
- this._subscription = null;
597
- this.etClickOutside = new EventEmitter();
735
+ this._isScrollTopOnNavigationEnabled = false;
736
+ this._router = inject(Router);
737
+ this._route$ = new BehaviorSubject('/');
738
+ this._state$ = new BehaviorSubject({
739
+ title: null,
740
+ fragment: null,
741
+ data: {},
742
+ pathParams: {},
743
+ queryParams: {},
744
+ });
745
+ this._router.events
746
+ .pipe(filter((event) => event instanceof NavigationEnd), distinctUntilChanged((a, b) => a.url === b.url), map((event) => {
747
+ const { url } = event;
748
+ const urlWithoutQueryParams = url.split('?')[0];
749
+ const withoutFragment = urlWithoutQueryParams.split('#')[0];
750
+ return withoutFragment;
751
+ }))
752
+ .subscribe(this._route$);
753
+ this._route$
754
+ .pipe(map(() => {
755
+ let route = this._router.routerState.snapshot.root;
756
+ while (route.firstChild) {
757
+ route = route.firstChild;
758
+ }
759
+ const { data, params, queryParams, title, fragment } = route;
760
+ return {
761
+ data,
762
+ pathParams: params,
763
+ queryParams,
764
+ title: title !== null && title !== void 0 ? title : null,
765
+ fragment,
766
+ };
767
+ }))
768
+ .subscribe(this._state$);
598
769
  }
599
- ngOnInit() {
600
- setTimeout(() => {
601
- this._subscription = this._clickObserverService.observe(this._elementRef.nativeElement).subscribe((event) => {
602
- const activeElement = event.target;
603
- const isInside = this._elementRef.nativeElement.contains(activeElement);
604
- if (!isInside) {
605
- this.etClickOutside.emit(event);
770
+ enableScrollEnhancements(config = {}) {
771
+ if (this._isScrollTopOnNavigationEnabled) {
772
+ return;
773
+ }
774
+ this._isScrollTopOnNavigationEnabled = true;
775
+ combineLatest([this._state$.pipe(pairwise()), this._route$.pipe(pairwise())])
776
+ .pipe(debounceTime(1))
777
+ .subscribe(([[prevState, currState], [prevRoute, currRoute]]) => {
778
+ var _a, _b, _c, _d, _e, _f;
779
+ const sameUrlNavigation = prevRoute === currRoute && equal(prevState.pathParams, currState.pathParams);
780
+ const didFragmentChange = prevState.fragment !== currState.fragment;
781
+ if (sameUrlNavigation) {
782
+ const allQueryParams = [
783
+ ...new Set(Object.keys(prevState.queryParams).concat(Object.keys(currState.queryParams))),
784
+ ];
785
+ const changedQueryParams = allQueryParams.filter((key) => currState.queryParams[key] !== prevState.queryParams[key]);
786
+ if (!((_a = config.queryParamTriggerList) === null || _a === void 0 ? void 0 : _a.length) && !didFragmentChange) {
787
+ return;
606
788
  }
607
- });
789
+ const caseQueryParams = changedQueryParams.some((key) => { var _a; return (_a = config.queryParamTriggerList) === null || _a === void 0 ? void 0 : _a.includes(key); });
790
+ const caseFragment = didFragmentChange && ((_b = config.fragment) === null || _b === void 0 ? void 0 : _b.enabled);
791
+ if (caseQueryParams) {
792
+ ((_c = config.scrollElement) !== null && _c !== void 0 ? _c : document.documentElement).scrollTop = 0;
793
+ }
794
+ else if (caseFragment) {
795
+ const fragmentElement = document.getElementById((_d = currState.fragment) !== null && _d !== void 0 ? _d : '');
796
+ if (fragmentElement) {
797
+ fragmentElement.scrollIntoView({ behavior: ((_e = config.fragment) === null || _e === void 0 ? void 0 : _e.smooth) ? 'smooth' : 'auto' });
798
+ }
799
+ }
800
+ }
801
+ else {
802
+ if (!(currState.data['disableScrollTopAsReturnRoute'] && prevState.data['disableScrollTop']) &&
803
+ !currState.data['disableScrollTop']) {
804
+ ((_f = config.scrollElement) !== null && _f !== void 0 ? _f : document.documentElement).scrollTop = 0;
805
+ }
806
+ }
608
807
  });
609
808
  }
610
- ngOnDestroy() {
611
- var _a;
612
- (_a = this._subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
809
+ selectQueryParam(key) {
810
+ return this._state$.pipe(map((state) => state.queryParams[key]));
613
811
  }
614
- }
615
- ClickOutsideDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ClickOutsideDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
616
- ClickOutsideDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.4", type: ClickOutsideDirective, isStandalone: true, selector: "[etClickOutside]", outputs: { etClickOutside: "etClickOutside" }, ngImport: i0 });
617
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ClickOutsideDirective, decorators: [{
618
- type: Directive,
812
+ selectPathParam(key) {
813
+ return this._state$.pipe(map((state) => state.pathParams[key]));
814
+ }
815
+ selectData(key) {
816
+ return this._state$.pipe(map((state) => state.data[key]));
817
+ }
818
+ }
819
+ RouterStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: RouterStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
820
+ RouterStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: RouterStateService, providedIn: 'root' });
821
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: RouterStateService, decorators: [{
822
+ type: Injectable,
619
823
  args: [{
620
- selector: '[etClickOutside]',
621
- standalone: true,
824
+ providedIn: 'root',
622
825
  }]
623
- }], propDecorators: { etClickOutside: [{
624
- type: Output
625
- }] } });
626
-
627
- const clamp = (value, min = 0, max = 100) => {
628
- return Math.max(min, Math.min(max, value));
629
- };
826
+ }], ctorParameters: function () { return []; } });
630
827
 
631
- /* eslint-disable @typescript-eslint/no-explicit-any */
632
- /* eslint-disable no-var */
633
- /**
634
- * Stolen from klona to avoid adding a dependency
635
- * https://github.com/lukeed/klona
636
- *
637
- * MIT License
638
- *
639
- * Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com)
640
- *
641
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
642
- *
643
- * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
644
- *
645
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
646
- */
647
- const set = (obj, key, val) => {
648
- if (typeof val.value === 'object')
649
- val.value = clone(val.value);
650
- if (!val.enumerable || val.get || val.set || !val.configurable || !val.writable || key === '__proto__') {
651
- Object.defineProperty(obj, key, val);
652
- }
653
- else
654
- obj[key] = val.value;
655
- };
656
- const clone = (original) => {
657
- if (typeof original !== 'object')
658
- return original;
659
- var _og = original;
660
- var i = 0, k, list, tmp, str = Object.prototype.toString.call(_og);
661
- if (str === '[object Object]') {
662
- tmp = Object.create(_og.__proto__ || null);
663
- }
664
- else if (str === '[object Array]') {
665
- tmp = Array(_og.length);
828
+ class ViewportService {
829
+ get isXs$() {
830
+ return this._isXs$.asObservable();
666
831
  }
667
- else if (str === '[object Set]') {
668
- tmp = new Set();
669
- _og.forEach(function (val) {
670
- tmp.add(clone(val));
671
- });
832
+ get isXs() {
833
+ return this._isXs$.value;
672
834
  }
673
- else if (str === '[object Map]') {
674
- tmp = new Map();
675
- _og.forEach(function (val, key) {
676
- tmp.set(clone(key), clone(val));
677
- });
835
+ get isSm$() {
836
+ return this._isSm$.asObservable();
678
837
  }
679
- else if (str === '[object Date]') {
680
- tmp = new Date(+_og);
838
+ get isSm() {
839
+ return this._isSm$.value;
681
840
  }
682
- else if (str === '[object RegExp]') {
683
- tmp = new RegExp(_og.source, _og.flags);
841
+ get isMd$() {
842
+ return this._isMd$.asObservable();
684
843
  }
685
- else if (str === '[object DataView]') {
686
- tmp = new _og.constructor(clone(_og.buffer));
844
+ get isMd() {
845
+ return this._isMd$.value;
687
846
  }
688
- else if (str === '[object ArrayBuffer]') {
689
- tmp = _og.slice(0);
847
+ get isLg$() {
848
+ return this._isLg$.asObservable();
690
849
  }
691
- else if (str.slice(-6) === 'Array]') {
692
- // ArrayBuffer.isView(x)
693
- // ~> `new` bcuz `Buffer.slice` => ref
694
- tmp = new _og.constructor(_og);
850
+ get isLg() {
851
+ return this._isLg$.value;
695
852
  }
696
- if (tmp) {
697
- for (list = Object.getOwnPropertySymbols(_og); i < list.length; i++) {
698
- set(tmp, list[i], Object.getOwnPropertyDescriptor(_og, list[i]));
699
- }
700
- for (i = 0, list = Object.getOwnPropertyNames(_og); i < list.length; i++) {
701
- if (Object.hasOwnProperty.call(tmp, (k = list[i])) && tmp[k] === _og[k])
702
- continue;
703
- set(tmp, k, Object.getOwnPropertyDescriptor(_og, k));
704
- }
853
+ get isXl$() {
854
+ return this._isXl$.asObservable();
705
855
  }
706
- return tmp || _og;
707
- };
708
-
709
- const hasCookie = (name) => {
710
- if (typeof document === 'undefined') {
711
- return false;
856
+ get isXl() {
857
+ return this._isXl$.value;
712
858
  }
713
- return document.cookie.split(';').some((c) => {
714
- return c.trim().startsWith(name + '=');
715
- });
716
- };
717
- const getCookie = (name) => {
718
- var _a;
719
- if (typeof document === 'undefined') {
720
- return null;
859
+ get is2Xl$() {
860
+ return this._is2Xl$.asObservable();
721
861
  }
722
- // From https://stackoverflow.com/questions/10730362/get-cookie-by-name
723
- return (_a = ('; ' + document.cookie).split(`; ${name}=`).pop()) === null || _a === void 0 ? void 0 : _a.split(';')[0];
724
- };
725
- const setCookie = (name, data, expiresInDays = 30, domain = getDomain()) => {
726
- if (typeof document === 'undefined') {
727
- return;
862
+ get is2Xl() {
863
+ return this._is2Xl$.value;
728
864
  }
729
- const date = new Date();
730
- date.setTime(date.getTime() + expiresInDays * 24 * 60 * 60 * 1000);
731
- document.cookie = `${name}=${data}; path=/; expires=${date.toUTCString()}; domain=${domain}; SameSite=Lax;`;
732
- };
733
- const deleteCookie = (name, path, domain = getDomain()) => {
734
- if (hasCookie(name)) {
735
- document.cookie =
736
- name +
737
- '=' +
738
- (path ? ';path=' + path : '') +
739
- (domain ? ';domain=' + domain : '') +
740
- ';expires=Thu, 01 Jan 1970 00:00:01 GMT';
865
+ get currentViewport() {
866
+ return this.getCurrentViewport([this.isXs, this.isSm, this.isMd, this.isLg, this.isXl, this.is2Xl]);
741
867
  }
742
- };
743
- const getDomain = () => {
744
- if (typeof navigator === 'undefined') {
745
- return null;
868
+ constructor(_viewportConfig, _breakpointObserver) {
869
+ this._breakpointObserver = _breakpointObserver;
870
+ this._isXs$ = new BehaviorSubject(false);
871
+ this._isSm$ = new BehaviorSubject(false);
872
+ this._isMd$ = new BehaviorSubject(false);
873
+ this._isLg$ = new BehaviorSubject(false);
874
+ this._isXl$ = new BehaviorSubject(false);
875
+ this._is2Xl$ = new BehaviorSubject(false);
876
+ this.currentViewport$ = combineLatest([this.isXs$, this.isSm$, this.isMd$, this.isLg$, this.isXl$, this.is2Xl$]).pipe(map((val) => this.getCurrentViewport(val)), shareReplay());
877
+ this._viewportConfig = _viewportConfig || DEFAULT_VIEWPORT_CONFIG;
878
+ this._observeDefaultBreakpoints();
746
879
  }
747
- const hostname = window.location.hostname;
748
- if (hostname.includes('localhost')) {
749
- return 'localhost';
880
+ observe(options) {
881
+ const mediaQuery = this._buildMediaQuery(options);
882
+ return this._breakpointObserver.observe(mediaQuery).pipe(map((x) => x.matches), shareReplay());
750
883
  }
751
- const splitHost = hostname.split('.');
752
- if (splitHost.length > 2) {
753
- return `${splitHost[splitHost.length - 2]}.${splitHost[splitHost.length - 1]}`;
884
+ isMatched(options) {
885
+ const mediaQuery = this._buildMediaQuery(options);
886
+ return this._breakpointObserver.isMatched(mediaQuery);
754
887
  }
755
- return hostname;
756
- };
757
-
758
- /* eslint-disable @typescript-eslint/no-explicit-any */
759
- /* eslint-disable no-var */
760
- /**
761
- * Stolen from dequal to avoid adding a dependency
762
- * https://github.com/lukeed/dequal
763
- *
764
- * The MIT License (MIT)
765
- *
766
- * Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com)
767
- *
768
- * Permission is hereby granted, free of charge, to any person obtaining a copy
769
- * of this software and associated documentation files (the "Software"), to deal
770
- * in the Software without restriction, including without limitation the rights
771
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
772
- * copies of the Software, and to permit persons to whom the Software is
773
- * furnished to do so, subject to the following conditions:
774
- *
775
- * The above copyright notice and this permission notice shall be included in
776
- * all copies or substantial portions of the Software.
777
- *
778
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
779
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
780
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
781
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
782
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
783
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
784
- * THE SOFTWARE.
785
- */
786
- const has = Object.prototype.hasOwnProperty;
787
- function find(iter, tar, key) {
788
- for (key of iter.keys()) {
789
- if (equal(key, tar))
790
- return key;
888
+ _observeDefaultBreakpoints() {
889
+ this.observe({ max: 'xs' }).subscribe(this._isXs$);
890
+ this.observe({ min: 'sm', max: 'sm' }).subscribe(this._isSm$);
891
+ this.observe({ min: 'md', max: 'md' }).subscribe(this._isMd$);
892
+ this.observe({ min: 'lg', max: 'lg' }).subscribe(this._isLg$);
893
+ this.observe({ min: 'xl', max: 'xl' }).subscribe(this._isXl$);
894
+ this.observe({ min: '2xl' }).subscribe(this._is2Xl$);
791
895
  }
792
- }
793
- const equal = (foo, bar) => {
794
- var ctor, len, tmp;
795
- if (foo === bar)
796
- return true;
797
- if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
798
- if (ctor === Date)
799
- return foo.getTime() === bar.getTime();
800
- if (ctor === RegExp)
801
- return foo.toString() === bar.toString();
802
- if (ctor === Array) {
803
- if ((len = foo.length) === bar.length) {
804
- while (len-- && equal(foo[len], bar[len]))
805
- ;
806
- }
807
- return len === -1;
896
+ _getViewportSize(type, option) {
897
+ const index = option === 'min' ? 0 : 1;
898
+ const size = this._viewportConfig.breakpoints[type][index];
899
+ if (size === Infinity || size === 0) {
900
+ return size;
808
901
  }
809
- if (ctor === Set) {
810
- if (foo.size !== bar.size) {
811
- return false;
812
- }
813
- for (len of foo) {
814
- tmp = len;
815
- if (tmp && typeof tmp === 'object') {
816
- tmp = find(bar, tmp);
817
- if (!tmp)
818
- return false;
819
- }
820
- if (!bar.has(tmp))
821
- return false;
822
- }
823
- return true;
902
+ if (option === 'min') {
903
+ return size;
904
+ }
905
+ // Due to scaling, the actual size of the viewport may be a decimal number.
906
+ // Eg. on Windows 11 with 150% scaling, the viewport size may be 1535.33px
907
+ // and thus not matching any of the default breakpoints.
908
+ return size + 0.9;
909
+ }
910
+ _buildMediaQuery(options) {
911
+ if (!options.min && !options.max) {
912
+ throw new Error('At least one of min or max must be defined');
824
913
  }
825
- if (ctor === Map) {
826
- if (foo.size !== bar.size) {
827
- return false;
914
+ const mediaQueryParts = [];
915
+ if (options.min) {
916
+ if (typeof options.min === 'number') {
917
+ mediaQueryParts.push(`(min-width: ${options.min}px)`);
828
918
  }
829
- for (len of foo) {
830
- tmp = len[0];
831
- if (tmp && typeof tmp === 'object') {
832
- tmp = find(bar, tmp);
833
- if (!tmp)
834
- return false;
835
- }
836
- if (!equal(len[1], bar.get(tmp))) {
837
- return false;
838
- }
919
+ else {
920
+ mediaQueryParts.push(`(min-width: ${this._getViewportSize(options.min, 'min')}px)`);
839
921
  }
840
- return true;
841
- }
842
- if (ctor === ArrayBuffer) {
843
- foo = new Uint8Array(foo);
844
- bar = new Uint8Array(bar);
845
922
  }
846
- else if (ctor === DataView) {
847
- if ((len = foo.byteLength) === bar.byteLength) {
848
- while (len-- && foo.getInt8(len) === bar.getInt8(len))
849
- ;
850
- }
851
- return len === -1;
923
+ if (options.min && options.max) {
924
+ mediaQueryParts.push('and');
852
925
  }
853
- if (ArrayBuffer.isView(foo)) {
854
- if ((len = foo.byteLength) === bar.byteLength) {
855
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
856
- //@ts-ignore
857
- while (len-- && foo[len] === bar[len])
858
- ;
926
+ if (options.max) {
927
+ if (typeof options.max === 'number') {
928
+ mediaQueryParts.push(`(max-width: ${options.max}px)`);
859
929
  }
860
- return len === -1;
861
- }
862
- if (!ctor || typeof foo === 'object') {
863
- len = 0;
864
- for (ctor in foo) {
865
- if (has.call(foo, ctor) && ++len && !has.call(bar, ctor))
866
- return false;
867
- if (!(ctor in bar) || !equal(foo[ctor], bar[ctor]))
868
- return false;
930
+ else {
931
+ mediaQueryParts.push(`(max-width: ${this._getViewportSize(options.max, 'max')}px)`);
869
932
  }
870
- return Object.keys(bar).length === len;
871
933
  }
934
+ return mediaQueryParts.join(' ');
872
935
  }
873
- return foo !== foo && bar !== bar;
874
- };
875
-
876
- const isAttributeRenderBinding = (value) => typeof value === 'boolean';
877
- const isAttributeValueBinding = (value) => typeof value === 'object';
878
- const createReactiveBindings = (...values) => {
879
- const rootElementRef = inject(ElementRef);
880
- const destroy$ = inject(DestroyService, { host: true }).destroy$;
881
- const subscriptions = [];
882
- const pushedAttributes = [];
883
- const defaults = {};
884
- const push = (value) => {
885
- const { attribute, observable, elementRef } = value;
886
- const elRef = elementRef || rootElementRef;
887
- const attributes = Array.isArray(attribute) ? attribute : [attribute];
888
- pushedAttributes.push(attributes);
889
- for (const attribute of attributes) {
890
- if (!defaults[attribute]) {
891
- defaults[attribute] = elRef.nativeElement.getAttribute(attribute) || undefined;
892
- }
936
+ getCurrentViewport([isXs, isSm, isMd, isLg, isXl, is2Xl]) {
937
+ if (isXs) {
938
+ return 'xs';
893
939
  }
894
- const subscription = observable
895
- .pipe(takeUntil(destroy$), distinctUntilChanged((a, b) => {
896
- if (isAttributeRenderBinding(a) && isAttributeRenderBinding(b)) {
897
- return a === b;
898
- }
899
- else if (isAttributeValueBinding(a) && isAttributeValueBinding(b)) {
900
- return a.render === b.render && a.value === b.value;
901
- }
902
- return false;
903
- }))
904
- .subscribe((value) => {
905
- const currentAttributes = pushedAttributes.find((s) => s.some((current) => attributes.includes(current))) || [];
906
- for (const attribute of currentAttributes) {
907
- const isSingleClassMutation = attribute.startsWith('class.');
908
- const isMultipleClassMutation = attribute === 'class';
909
- const render = isAttributeRenderBinding(value) ? value : value.render;
910
- if (isSingleClassMutation) {
911
- const className = attribute.replace('class.', '');
912
- if (!className) {
913
- continue;
914
- }
915
- if (!render) {
916
- elRef.nativeElement.classList.remove(className);
917
- }
918
- else {
919
- elRef.nativeElement.classList.add(className);
920
- }
921
- }
922
- else if (isMultipleClassMutation) {
923
- const classes = isAttributeRenderBinding(value) ? '' : `${value.value}`;
924
- if (!classes) {
925
- continue;
926
- }
927
- if (!render) {
928
- elRef.nativeElement.classList.remove(...classes.split(' '));
929
- }
930
- else {
931
- elRef.nativeElement.classList.add(...classes.split(' '));
932
- }
933
- }
934
- else {
935
- const attributeValue = isAttributeRenderBinding(value) ? true : `${value.value}`;
936
- if (!attribute) {
937
- continue;
938
- }
939
- if (!render) {
940
- elRef.nativeElement.removeAttribute(attribute);
941
- }
942
- else {
943
- elRef.nativeElement.setAttribute(attribute, `${attributeValue}`);
944
- }
945
- }
946
- }
947
- });
948
- subscriptions.push({ attributes, subscription });
949
- };
950
- const remove = (...attributes) => {
951
- for (const attribute of attributes) {
952
- const sub = subscriptions.find((s) => s.attributes.includes(attribute));
953
- const attributeStack = pushedAttributes.find((a) => a.includes(attribute));
954
- if (sub) {
955
- sub.attributes = sub.attributes.filter((a) => a !== attribute);
956
- attributeStack === null || attributeStack === void 0 ? void 0 : attributeStack.splice(attributeStack.indexOf(attribute), 1);
957
- if (sub.attributes.length === 0) {
958
- sub.subscription.unsubscribe();
959
- subscriptions.splice(subscriptions.indexOf(sub), 1);
960
- }
961
- }
940
+ else if (isSm) {
941
+ return 'sm';
962
942
  }
963
- };
964
- const reset = () => {
965
- for (const attribute in defaults) {
966
- if (defaults[attribute] === undefined) {
967
- rootElementRef.nativeElement.removeAttribute(attribute);
968
- }
969
- else {
970
- rootElementRef.nativeElement.setAttribute(attribute, defaults[attribute]);
971
- }
943
+ else if (isMd) {
944
+ return 'md';
972
945
  }
973
- };
974
- for (const value of values) {
975
- push(value);
946
+ else if (isLg) {
947
+ return 'lg';
948
+ }
949
+ else if (isXl) {
950
+ return 'xl';
951
+ }
952
+ else if (is2Xl) {
953
+ return '2xl';
954
+ }
955
+ return 'xs';
976
956
  }
977
- return {
978
- push,
979
- remove,
980
- reset,
981
- };
982
- };
983
-
984
- const elementCanScroll = (element) => {
985
- const { scrollHeight, clientHeight, scrollWidth, clientWidth } = element;
986
- return scrollHeight > clientHeight || scrollWidth > clientWidth;
987
- };
957
+ }
958
+ ViewportService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ViewportService, deps: [{ token: VIEWPORT_CONFIG, optional: true }, { token: i1.BreakpointObserver }], target: i0.ɵɵFactoryTarget.Injectable });
959
+ ViewportService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ViewportService, providedIn: 'root' });
960
+ __decorate([
961
+ Memo(),
962
+ __metadata("design:type", Function),
963
+ __metadata("design:paramtypes", [String, String]),
964
+ __metadata("design:returntype", void 0)
965
+ ], ViewportService.prototype, "_getViewportSize", null);
966
+ __decorate([
967
+ Memo({
968
+ resolver: (v) => {
969
+ var _a, _b;
970
+ return `${(_a = v.min) !== null && _a !== void 0 ? _a : ''}-${(_b = v.max) !== null && _b !== void 0 ? _b : ''}`;
971
+ },
972
+ }),
973
+ __metadata("design:type", Function),
974
+ __metadata("design:paramtypes", [Object]),
975
+ __metadata("design:returntype", void 0)
976
+ ], ViewportService.prototype, "_buildMediaQuery", null);
977
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ViewportService, decorators: [{
978
+ type: Injectable,
979
+ args: [{
980
+ providedIn: 'root',
981
+ }]
982
+ }], ctorParameters: function () {
983
+ return [{ type: undefined, decorators: [{
984
+ type: Inject,
985
+ args: [VIEWPORT_CONFIG]
986
+ }, {
987
+ type: Optional
988
+ }] }, { type: i1.BreakpointObserver }];
989
+ }, propDecorators: { _getViewportSize: [], _buildMediaQuery: [] } });
988
990
 
989
- const provideViewportConfig = (viewportConfig) => {
990
- return { provide: VIEWPORT_CONFIG, useValue: viewportConfig };
991
- };
991
+ class ClickOutsideDirective {
992
+ constructor() {
993
+ this._elementRef = inject(ElementRef);
994
+ this._clickObserverService = inject(ClickObserverService);
995
+ this._subscription = null;
996
+ this.etClickOutside = new EventEmitter();
997
+ }
998
+ ngOnInit() {
999
+ setTimeout(() => {
1000
+ this._subscription = this._clickObserverService.observe(this._elementRef.nativeElement).subscribe((event) => {
1001
+ const activeElement = event.target;
1002
+ const isInside = this._elementRef.nativeElement.contains(activeElement);
1003
+ if (!isInside) {
1004
+ this.etClickOutside.emit(event);
1005
+ }
1006
+ });
1007
+ });
1008
+ }
1009
+ ngOnDestroy() {
1010
+ var _a;
1011
+ (_a = this._subscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
1012
+ }
1013
+ }
1014
+ ClickOutsideDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ClickOutsideDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1015
+ ClickOutsideDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.4", type: ClickOutsideDirective, isStandalone: true, selector: "[etClickOutside]", outputs: { etClickOutside: "etClickOutside" }, ngImport: i0 });
1016
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ClickOutsideDirective, decorators: [{
1017
+ type: Directive,
1018
+ args: [{
1019
+ selector: '[etClickOutside]',
1020
+ standalone: true,
1021
+ }]
1022
+ }], propDecorators: { etClickOutside: [{
1023
+ type: Output
1024
+ }] } });
992
1025
 
993
1026
  const CURSOR_DRAG_SCROLLING_CLASS = 'et-cursor-drag-scroll--scrolling';
994
1027
  const CURSOR_DRAG_SCROLLING_PREPARED_CLASS = 'et-cursor-drag-scroll--prepared';
@@ -1187,7 +1220,7 @@ class ObserveContentDirective {
1187
1220
  this._contentObserver = inject(ContentObserverService);
1188
1221
  this._elementRef = inject(ElementRef);
1189
1222
  this._ngZone = inject(NgZone);
1190
- this.event = new EventEmitter();
1223
+ this.valueChange = new EventEmitter();
1191
1224
  this._disabled = false;
1192
1225
  this._debounce = null;
1193
1226
  this._currentSubscription = null;
@@ -1218,7 +1251,7 @@ class ObserveContentDirective {
1218
1251
  this._unsubscribe();
1219
1252
  const stream = this._contentObserver.observe(this._elementRef);
1220
1253
  this._ngZone.runOutsideAngular(() => {
1221
- this._currentSubscription = (this.debounce ? stream.pipe(debounceTime$1(this.debounce)) : stream).subscribe(this.event);
1254
+ this._currentSubscription = (this.debounce ? stream.pipe(debounceTime$1(this.debounce)) : stream).subscribe(this.valueChange);
1222
1255
  });
1223
1256
  }
1224
1257
  _unsubscribe() {
@@ -1227,7 +1260,7 @@ class ObserveContentDirective {
1227
1260
  }
1228
1261
  }
1229
1262
  ObserveContentDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ObserveContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1230
- ObserveContentDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.4", type: ObserveContentDirective, isStandalone: true, selector: "[etObserveContent]", inputs: { disabled: ["etObserveContentDisabled", "disabled"], debounce: ["etObserveContentDebounce", "debounce"] }, outputs: { event: "etObserveContent" }, exportAs: ["etObserveContent"], ngImport: i0 });
1263
+ ObserveContentDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.4", type: ObserveContentDirective, isStandalone: true, selector: "[etObserveContent]", inputs: { disabled: ["etObserveContentDisabled", "disabled"], debounce: ["etObserveContentDebounce", "debounce"] }, outputs: { valueChange: "etObserveContent" }, exportAs: ["etObserveContent"], ngImport: i0 });
1231
1264
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ObserveContentDirective, decorators: [{
1232
1265
  type: Directive,
1233
1266
  args: [{
@@ -1235,7 +1268,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1235
1268
  exportAs: 'etObserveContent',
1236
1269
  standalone: true,
1237
1270
  }]
1238
- }], propDecorators: { event: [{
1271
+ }], propDecorators: { valueChange: [{
1239
1272
  type: Output,
1240
1273
  args: ['etObserveContent']
1241
1274
  }], disabled: [{
@@ -1251,7 +1284,7 @@ class ObserveResizeDirective {
1251
1284
  this._resizeObserver = inject(ResizeObserverService);
1252
1285
  this._elementRef = inject(ElementRef);
1253
1286
  this._ngZone = inject(NgZone);
1254
- this.event = new EventEmitter();
1287
+ this.valueChange = new EventEmitter();
1255
1288
  this._disabled = false;
1256
1289
  this._debounce = null;
1257
1290
  this._currentSubscription = null;
@@ -1282,7 +1315,7 @@ class ObserveResizeDirective {
1282
1315
  this._unsubscribe();
1283
1316
  const stream = this._resizeObserver.observe(this._elementRef);
1284
1317
  this._ngZone.runOutsideAngular(() => {
1285
- this._currentSubscription = (this.debounce ? stream.pipe(debounceTime(this.debounce)) : stream).subscribe(this.event);
1318
+ this._currentSubscription = (this.debounce ? stream.pipe(debounceTime(this.debounce)) : stream).subscribe(this.valueChange);
1286
1319
  });
1287
1320
  }
1288
1321
  _unsubscribe() {
@@ -1291,7 +1324,7 @@ class ObserveResizeDirective {
1291
1324
  }
1292
1325
  }
1293
1326
  ObserveResizeDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ObserveResizeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1294
- ObserveResizeDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.4", type: ObserveResizeDirective, isStandalone: true, selector: "[etObserveResize]", inputs: { disabled: ["etObserveResizeDisabled", "disabled"], debounce: ["etObserveResizeDebounce", "debounce"] }, outputs: { event: "etObserveResize" }, exportAs: ["etObserveResize"], ngImport: i0 });
1327
+ ObserveResizeDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.4", type: ObserveResizeDirective, isStandalone: true, selector: "[etObserveResize]", inputs: { disabled: ["etObserveResizeDisabled", "disabled"], debounce: ["etObserveResizeDebounce", "debounce"] }, outputs: { valueChange: "etObserveResize" }, exportAs: ["etObserveResize"], ngImport: i0 });
1295
1328
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ObserveResizeDirective, decorators: [{
1296
1329
  type: Directive,
1297
1330
  args: [{
@@ -1299,7 +1332,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1299
1332
  exportAs: 'etObserveResize',
1300
1333
  standalone: true,
1301
1334
  }]
1302
- }], propDecorators: { event: [{
1335
+ }], propDecorators: { valueChange: [{
1303
1336
  type: Output,
1304
1337
  args: ['etObserveResize']
1305
1338
  }], disabled: [{
@@ -1400,7 +1433,7 @@ class ObserveScrollStateDirective {
1400
1433
  this._rootMargin = 0;
1401
1434
  this._threshold = 1;
1402
1435
  this._intersectionObserver = null;
1403
- this.etObserveScrollState = new EventEmitter();
1436
+ this.valueChange = new EventEmitter();
1404
1437
  }
1405
1438
  get _firstCurrentChild() {
1406
1439
  const explicitFirstElement = this._elementRef.nativeElement.querySelector(`.${SCROLL_OBSERVER_FIRST_ELEMENT_CLASS}`);
@@ -1457,7 +1490,7 @@ class ObserveScrollStateDirective {
1457
1490
  !elementCanScroll(this._elementRef.nativeElement)) {
1458
1491
  this._unobserveChild('first');
1459
1492
  this._unobserveChild('last');
1460
- this.etObserveScrollState.emit({
1493
+ this.valueChange.emit({
1461
1494
  isAtStart: true,
1462
1495
  isAtEnd: true,
1463
1496
  canScroll: false,
@@ -1475,7 +1508,7 @@ class ObserveScrollStateDirective {
1475
1508
  const { first, last } = this._observedChildren;
1476
1509
  const isAtStart = (_b = (_a = entries.find((entry) => entry.target === first)) === null || _a === void 0 ? void 0 : _a.isIntersecting) !== null && _b !== void 0 ? _b : false;
1477
1510
  const isAtEnd = (_d = (_c = entries.find((entry) => entry.target === last)) === null || _c === void 0 ? void 0 : _c.isIntersecting) !== null && _d !== void 0 ? _d : false;
1478
- this.etObserveScrollState.emit({
1511
+ this.valueChange.emit({
1479
1512
  isAtStart,
1480
1513
  isAtEnd,
1481
1514
  canScroll: !isAtStart || !isAtEnd,
@@ -1523,7 +1556,7 @@ class ObserveScrollStateDirective {
1523
1556
  }
1524
1557
  }
1525
1558
  ObserveScrollStateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: ObserveScrollStateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1526
- ObserveScrollStateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.4", type: ObserveScrollStateDirective, isStandalone: true, selector: "[etObserveScrollState]", inputs: { observerRootMargin: "observerRootMargin", observerThreshold: "observerThreshold" }, outputs: { etObserveScrollState: "etObserveScrollState" }, providers: [
1559
+ ObserveScrollStateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.4", type: ObserveScrollStateDirective, isStandalone: true, selector: "[etObserveScrollState]", inputs: { observerRootMargin: "observerRootMargin", observerThreshold: "observerThreshold" }, outputs: { valueChange: "etObserveScrollState" }, providers: [
1527
1560
  {
1528
1561
  provide: OBSERVE_SCROLL_STATE,
1529
1562
  useExisting: ObserveScrollStateDirective,
@@ -1548,8 +1581,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
1548
1581
  type: Input
1549
1582
  }], observerThreshold: [{
1550
1583
  type: Input
1551
- }], etObserveScrollState: [{
1552
- type: Output
1584
+ }], valueChange: [{
1585
+ type: Output,
1586
+ args: ['etObserveScrollState']
1553
1587
  }] } });
1554
1588
 
1555
1589
  class RepeatDirective {