@ethlete/core 0.2.0-next.23 → 0.2.0-next.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/esm2020/lib/directives/animatable/animatable.directive.mjs +79 -0
  2. package/esm2020/lib/directives/animatable/public-api.mjs +2 -0
  3. package/esm2020/lib/directives/animated-lifecycle/animated-lifecycle.directive.mjs +113 -0
  4. package/esm2020/lib/directives/animated-lifecycle/public-api.mjs +2 -0
  5. package/esm2020/lib/directives/public-api.mjs +3 -1
  6. package/esm2020/lib/public-api.mjs +2 -1
  7. package/esm2020/lib/utils/animation.utils.mjs +9 -0
  8. package/esm2020/lib/utils/public-api.mjs +2 -1
  9. package/esm2020/lib/validators/is-array-not-empty.validator.mjs +9 -0
  10. package/esm2020/lib/validators/is-email.validator.mjs +10 -0
  11. package/esm2020/lib/validators/must-match.validator.mjs +19 -0
  12. package/esm2020/lib/validators/public-api.mjs +12 -0
  13. package/fesm2015/ethlete-core.mjs +237 -3
  14. package/fesm2015/ethlete-core.mjs.map +1 -1
  15. package/fesm2020/ethlete-core.mjs +237 -3
  16. package/fesm2020/ethlete-core.mjs.map +1 -1
  17. package/lib/directives/animatable/animatable.directive.d.ts +20 -0
  18. package/lib/directives/animatable/public-api.d.ts +1 -0
  19. package/lib/directives/animated-lifecycle/animated-lifecycle.directive.d.ts +22 -0
  20. package/lib/directives/animated-lifecycle/public-api.d.ts +1 -0
  21. package/lib/directives/public-api.d.ts +2 -0
  22. package/lib/public-api.d.ts +1 -0
  23. package/lib/utils/animation.utils.d.ts +2 -0
  24. package/lib/utils/public-api.d.ts +1 -0
  25. package/lib/validators/is-array-not-empty.validator.d.ts +3 -0
  26. package/lib/validators/is-email.validator.d.ts +3 -0
  27. package/lib/validators/must-match.validator.d.ts +3 -0
  28. package/lib/validators/public-api.d.ts +8 -0
  29. package/package.json +3 -2
@@ -1,8 +1,8 @@
1
1
  import * as i0 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';
2
+ import { inject, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, HostBinding, InjectionToken, Injectable, ElementRef, Inject, Optional, Directive, EventEmitter, Output, NgZone, Pipe, QueryList } from '@angular/core';
3
3
  import { DomSanitizer, Meta, Title } from '@angular/platform-browser';
4
+ import { fromEvent, Observable, Subject, startWith, map, takeUntil, distinctUntilChanged, BehaviorSubject, filter, combineLatest, pairwise, debounceTime, shareReplay, merge, tap, take } from 'rxjs';
4
5
  import { coerceElement, coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
5
- import { fromEvent, Observable, Subject, startWith, map, takeUntil, distinctUntilChanged, BehaviorSubject, filter, combineLatest, pairwise, debounceTime, shareReplay, 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';
@@ -346,6 +346,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
346
346
  args: [{ providedIn: 'root' }]
347
347
  }], ctorParameters: function () { return [{ type: ResizeObserverFactory }]; } });
348
348
 
349
+ const nextFrame = (cb) => {
350
+ requestAnimationFrame(() => {
351
+ requestAnimationFrame(cb);
352
+ });
353
+ };
354
+ const forceReflow = (element = document.body) => {
355
+ return element.offsetHeight;
356
+ };
357
+
349
358
  const clamp = (value, min = 0, max = 100) => {
350
359
  return Math.max(min, Math.min(max, value));
351
360
  };
@@ -998,6 +1007,187 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImpor
998
1007
  type: Optional
999
1008
  }] }, { type: i1.BreakpointObserver }]; }, propDecorators: { _getViewportSize: [], _buildMediaQuery: [] } });
1000
1009
 
1010
+ const ANIMATABLE_TOKEN = new InjectionToken('ANIMATABLE_DIRECTIVE_TOKEN');
1011
+ class AnimatableDirective {
1012
+ constructor() {
1013
+ this._didEmitStart = false;
1014
+ this._parent = inject(ANIMATABLE_TOKEN, { optional: true, skipSelf: true });
1015
+ this._destroy$ = inject(DestroyService, { host: true }).destroy$;
1016
+ this._elementRef = inject(ElementRef);
1017
+ this._animationStart$ = new Subject();
1018
+ this._animationEnd$ = new Subject();
1019
+ this.animationStart$ = this._animationStart$.asObservable().pipe(debounceTime(0));
1020
+ this.animationEnd$ = this._animationEnd$.asObservable().pipe(debounceTime(0));
1021
+ this._hostActiveAnimationCount$ = new BehaviorSubject(0);
1022
+ this._totalActiveAnimationCount$ = new BehaviorSubject(0);
1023
+ this.isAnimating$ = this._totalActiveAnimationCount$.pipe(map((count) => count > 0), debounceTime(0));
1024
+ }
1025
+ ngOnInit() {
1026
+ merge(fromEvent(this._elementRef.nativeElement, 'animationstart'), fromEvent(this._elementRef.nativeElement, 'transitionstart'))
1027
+ .pipe(tap(() => {
1028
+ const count = this._hostActiveAnimationCount$.value + 1;
1029
+ this._hostActiveAnimationCount$.next(count);
1030
+ this._totalActiveAnimationCount$.next(count);
1031
+ }), takeUntil(this._destroy$))
1032
+ .subscribe();
1033
+ merge(fromEvent(this._elementRef.nativeElement, 'animationend'), fromEvent(this._elementRef.nativeElement, 'animationcancel'), fromEvent(this._elementRef.nativeElement, 'transitionend'), fromEvent(this._elementRef.nativeElement, 'transitioncancel'))
1034
+ .pipe(tap(() => {
1035
+ const count = this._hostActiveAnimationCount$.value - 1;
1036
+ this._hostActiveAnimationCount$.next(count);
1037
+ this._totalActiveAnimationCount$.next(count);
1038
+ }), takeUntil(this._destroy$))
1039
+ .subscribe();
1040
+ this._totalActiveAnimationCount$
1041
+ .pipe(tap((count) => {
1042
+ if (count > 0 && !this._didEmitStart) {
1043
+ this._animationStart$.next();
1044
+ this._didEmitStart = true;
1045
+ }
1046
+ else if (count === 0) {
1047
+ this._animationEnd$.next();
1048
+ this._didEmitStart = false;
1049
+ }
1050
+ }), takeUntil(this._destroy$))
1051
+ .subscribe();
1052
+ if (this._parent) {
1053
+ this._parent._hostActiveAnimationCount$
1054
+ .pipe(takeUntil(this._destroy$), tap((count) => {
1055
+ this._totalActiveAnimationCount$.next(count + this._hostActiveAnimationCount$.value);
1056
+ }))
1057
+ .subscribe();
1058
+ }
1059
+ }
1060
+ }
1061
+ AnimatableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: AnimatableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1062
+ AnimatableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.4", type: AnimatableDirective, isStandalone: true, selector: "[etAnimatable]", providers: [
1063
+ {
1064
+ provide: ANIMATABLE_TOKEN,
1065
+ useExisting: AnimatableDirective,
1066
+ },
1067
+ DestroyService,
1068
+ ], exportAs: ["etAnimatable"], ngImport: i0 });
1069
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: AnimatableDirective, decorators: [{
1070
+ type: Directive,
1071
+ args: [{
1072
+ selector: '[etAnimatable]',
1073
+ exportAs: 'etAnimatable',
1074
+ standalone: true,
1075
+ providers: [
1076
+ {
1077
+ provide: ANIMATABLE_TOKEN,
1078
+ useExisting: AnimatableDirective,
1079
+ },
1080
+ DestroyService,
1081
+ ],
1082
+ }]
1083
+ }] });
1084
+
1085
+ const ANIMATED_LIFECYCLE_TOKEN = new InjectionToken('ANIMATED_LIFECYCLE_DIRECTIVE_TOKEN');
1086
+ const ANIMATION_CLASSES = {
1087
+ enterFrom: 'et-animation-enter-from',
1088
+ enterActive: 'et-animation-enter-active',
1089
+ enterTo: 'et-animation-enter-to',
1090
+ leaveFrom: 'et-animation-leave-from',
1091
+ leaveActive: 'et-animation-leave-active',
1092
+ leaveTo: 'et-animation-leave-to',
1093
+ };
1094
+ class AnimatedLifecycleDirective {
1095
+ constructor() {
1096
+ this._destroy$ = inject(DestroyService, { host: true }).destroy$;
1097
+ this._elementRef = inject(ElementRef);
1098
+ this._animatable = inject(ANIMATABLE_TOKEN);
1099
+ this._classList = this._elementRef.nativeElement.classList;
1100
+ this._state$ = new BehaviorSubject('init');
1101
+ this.state$ = this._state$.asObservable();
1102
+ }
1103
+ get state() {
1104
+ return this._state$.value;
1105
+ }
1106
+ get _opacity() {
1107
+ return this._state$.value === 'init' ? '0 !important' : '';
1108
+ }
1109
+ enter(config) {
1110
+ this._state$.next('entering');
1111
+ if (!config?.onlyTransition) {
1112
+ this._classList.add(ANIMATION_CLASSES.enterFrom);
1113
+ }
1114
+ forceReflow();
1115
+ this._classList.add(ANIMATION_CLASSES.enterActive);
1116
+ nextFrame(() => {
1117
+ if (!config?.onlyTransition) {
1118
+ this._classList.remove(ANIMATION_CLASSES.enterFrom);
1119
+ this._classList.add(ANIMATION_CLASSES.enterTo);
1120
+ }
1121
+ this._animatable.animationEnd$
1122
+ .pipe(takeUntil(this._destroy$), take(1), tap(() => {
1123
+ this._state$.next('entered');
1124
+ this._classList.remove(ANIMATION_CLASSES.enterActive);
1125
+ if (!config?.onlyTransition) {
1126
+ this._classList.remove(ANIMATION_CLASSES.enterTo);
1127
+ }
1128
+ }))
1129
+ .subscribe();
1130
+ });
1131
+ }
1132
+ leave(config) {
1133
+ if (this._classList.contains(ANIMATION_CLASSES.enterFrom) ||
1134
+ this._classList.contains(ANIMATION_CLASSES.enterActive) ||
1135
+ this._classList.contains(ANIMATION_CLASSES.enterTo)) {
1136
+ this._classList.remove(ANIMATION_CLASSES.enterFrom);
1137
+ this._classList.remove(ANIMATION_CLASSES.enterActive);
1138
+ this._classList.remove(ANIMATION_CLASSES.enterTo);
1139
+ }
1140
+ this._state$.next('leaving');
1141
+ if (!config?.onlyTransition) {
1142
+ this._classList.add(ANIMATION_CLASSES.leaveFrom);
1143
+ }
1144
+ forceReflow();
1145
+ this._classList.add(ANIMATION_CLASSES.leaveActive);
1146
+ nextFrame(() => {
1147
+ if (!config?.onlyTransition) {
1148
+ this._classList.remove(ANIMATION_CLASSES.leaveFrom);
1149
+ this._classList.add(ANIMATION_CLASSES.leaveTo);
1150
+ }
1151
+ this._animatable.animationEnd$
1152
+ .pipe(takeUntil(this._destroy$), take(1), tap(() => {
1153
+ this._state$.next('left');
1154
+ this._classList.remove(ANIMATION_CLASSES.leaveActive);
1155
+ if (!config?.onlyTransition) {
1156
+ this._classList.remove(ANIMATION_CLASSES.leaveTo);
1157
+ }
1158
+ }))
1159
+ .subscribe();
1160
+ });
1161
+ }
1162
+ }
1163
+ AnimatedLifecycleDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: AnimatedLifecycleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1164
+ AnimatedLifecycleDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.4", type: AnimatedLifecycleDirective, isStandalone: true, selector: "[etAnimatedLifecycle]", host: { properties: { "style.opacity": "this._opacity" } }, providers: [
1165
+ {
1166
+ provide: ANIMATED_LIFECYCLE_TOKEN,
1167
+ useExisting: AnimatedLifecycleDirective,
1168
+ },
1169
+ DestroyService,
1170
+ ], exportAs: ["etAnimatedLifecycle"], hostDirectives: [{ directive: AnimatableDirective }], ngImport: i0 });
1171
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.4", ngImport: i0, type: AnimatedLifecycleDirective, decorators: [{
1172
+ type: Directive,
1173
+ args: [{
1174
+ selector: '[etAnimatedLifecycle]',
1175
+ exportAs: 'etAnimatedLifecycle',
1176
+ standalone: true,
1177
+ providers: [
1178
+ {
1179
+ provide: ANIMATED_LIFECYCLE_TOKEN,
1180
+ useExisting: AnimatedLifecycleDirective,
1181
+ },
1182
+ DestroyService,
1183
+ ],
1184
+ hostDirectives: [AnimatableDirective],
1185
+ }]
1186
+ }], propDecorators: { _opacity: [{
1187
+ type: HostBinding,
1188
+ args: ['style.opacity']
1189
+ }] } });
1190
+
1001
1191
  class ClickOutsideDirective {
1002
1192
  constructor() {
1003
1193
  this._elementRef = inject(ElementRef);
@@ -2162,9 +2352,53 @@ class TypedQueryList extends QueryList {
2162
2352
  }
2163
2353
  _a = Symbol.iterator;
2164
2354
 
2355
+ const IS_ARRAY_NOT_EMPTY = 'isArrayNotEmpty';
2356
+ const IsArrayNotEmpty = (control) => {
2357
+ const value = control.value;
2358
+ if (!value) {
2359
+ return null;
2360
+ }
2361
+ return value.length > 0 ? null : { [IS_ARRAY_NOT_EMPTY]: true };
2362
+ };
2363
+
2364
+ const IS_EMAIL = 'isEmail';
2365
+ const IsEmail = (control) => {
2366
+ const value = control.value;
2367
+ if (!value) {
2368
+ return null;
2369
+ }
2370
+ const regex = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/;
2371
+ return regex.test(value) ? null : { [IS_EMAIL]: true };
2372
+ };
2373
+
2374
+ const MUST_MATCH = 'mustMatch';
2375
+ const MustMatch = (controlName, matchingControlName) => {
2376
+ return (formGroup) => {
2377
+ const control = formGroup.controls[controlName];
2378
+ const matchingControl = formGroup.controls[matchingControlName];
2379
+ // set error on matchingControl if validation fails
2380
+ if (matchingControl.errors && !matchingControl.errors[MUST_MATCH]) {
2381
+ return;
2382
+ }
2383
+ // set error on matchingControl if validation fails
2384
+ if (control.value !== matchingControl.value) {
2385
+ matchingControl.setErrors({ [MUST_MATCH]: true });
2386
+ }
2387
+ else {
2388
+ matchingControl.setErrors(null);
2389
+ }
2390
+ };
2391
+ };
2392
+
2393
+ const Validators = {
2394
+ MustMatch,
2395
+ IsEmail,
2396
+ IsArrayNotEmpty,
2397
+ };
2398
+
2165
2399
  /**
2166
2400
  * Generated bundle index. Do not edit.
2167
2401
  */
2168
2402
 
2169
- export { ClickObserverFactory, ClickObserverService, ClickOutsideDirective, ContentObserverService, CursorDragScrollDirective, DEFAULT_VIEWPORT_CONFIG, DestroyService, FocusVisibleService, LetContext, LetDirective, Memo, MutationObserverFactory, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, OBSERVE_SCROLL_STATE, ObserveContentDirective, ObserveResizeDirective, ObserveScrollStateDirective, RepeatDirective, ResizeObserverFactory, ResizeObserverService, RouterStateService, SCROLL_OBSERVER_FIRST_ELEMENT_CLASS, SCROLL_OBSERVER_IGNORE_TARGET_CLASS, SCROLL_OBSERVER_LAST_ELEMENT_CLASS, SEO_DIRECTIVE_TOKEN, ScrollObserverFirstElementDirective, ScrollObserverIgnoreTargetDirective, ScrollObserverLastElementDirective, SeoDirective, StructuredDataComponent, ToArrayPipe, TypedQueryList, VIEWPORT_CONFIG, ViewportService, clamp, clone, createMediaQueryObservable, createReactiveBindings, deleteCookie, elementCanScroll, equal, getCookie, getDomain, getGroupMatchPoints, getGroupMatchScore, getKnockoutMatchScore, getMatchScoreSubLine, hasCookie, isGroupMatch, isKnockoutMatch, mergeSeoConfig, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, provideViewportConfig, routerDisableScrollTop, setCookie, toArray, toArrayTrackByFn };
2403
+ export { ANIMATABLE_TOKEN, ANIMATED_LIFECYCLE_TOKEN, AnimatableDirective, AnimatedLifecycleDirective, ClickObserverFactory, ClickObserverService, ClickOutsideDirective, ContentObserverService, CursorDragScrollDirective, DEFAULT_VIEWPORT_CONFIG, DestroyService, FocusVisibleService, IS_ARRAY_NOT_EMPTY, IS_EMAIL, IsArrayNotEmpty, IsEmail, LetContext, LetDirective, MUST_MATCH, Memo, MustMatch, MutationObserverFactory, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, OBSERVE_SCROLL_STATE, ObserveContentDirective, ObserveResizeDirective, ObserveScrollStateDirective, RepeatDirective, ResizeObserverFactory, ResizeObserverService, RouterStateService, SCROLL_OBSERVER_FIRST_ELEMENT_CLASS, SCROLL_OBSERVER_IGNORE_TARGET_CLASS, SCROLL_OBSERVER_LAST_ELEMENT_CLASS, SEO_DIRECTIVE_TOKEN, ScrollObserverFirstElementDirective, ScrollObserverIgnoreTargetDirective, ScrollObserverLastElementDirective, SeoDirective, StructuredDataComponent, ToArrayPipe, TypedQueryList, VIEWPORT_CONFIG, Validators, ViewportService, clamp, clone, createMediaQueryObservable, createReactiveBindings, deleteCookie, elementCanScroll, equal, forceReflow, getCookie, getDomain, getGroupMatchPoints, getGroupMatchScore, getKnockoutMatchScore, getMatchScoreSubLine, hasCookie, isGroupMatch, isKnockoutMatch, mergeSeoConfig, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, provideViewportConfig, routerDisableScrollTop, setCookie, toArray, toArrayTrackByFn };
2170
2404
  //# sourceMappingURL=ethlete-core.mjs.map