@ethlete/core 4.12.1 → 4.13.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.
- package/CHANGELOG.md +14 -0
- package/esm2022/lib/utils/scrollable.utils.mjs +7 -5
- package/esm2022/lib/utils/signal.utils.mjs +141 -12
- package/fesm2022/ethlete-core.mjs +146 -17
- package/fesm2022/ethlete-core.mjs.map +1 -1
- package/lib/directives/animated-lifecycle/animated-lifecycle.directive.d.ts +3 -3
- package/lib/props/create-prop-handlers.d.ts +3 -3
- package/lib/props/props.directive.d.ts +3 -3
- package/lib/utils/signal.utils.d.ts +24 -8
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, HostBinding, InjectionToken, assertInInjectionContext, DestroyRef, ElementRef, TemplateRef, Injectable, isSignal, signal, QueryList, Injector, runInInjectionContext, effect, afterNextRender, NgZone, isDevMode, computed,
|
|
2
|
+
import { inject, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, HostBinding, InjectionToken, assertInInjectionContext, DestroyRef, ElementRef, TemplateRef, Injectable, isSignal, signal, QueryList, Injector, runInInjectionContext, effect, afterNextRender, untracked, NgZone, isDevMode, computed, Directive, model, EventEmitter, booleanAttribute, numberAttribute, Output, ViewContainerRef, Pipe, AfterRenderPhase, input } from '@angular/core';
|
|
3
3
|
import { DomSanitizer, Meta, Title } from '@angular/platform-browser';
|
|
4
4
|
import { Subject, BehaviorSubject, takeUntil, switchMap, of, tap, map, startWith, Observable, combineLatest, timer, distinctUntilChanged, shareReplay, filter, take, fromEvent, pairwise, debounceTime, finalize, merge, skip, takeWhile } from 'rxjs';
|
|
5
5
|
import { END, HOME, PAGE_DOWN, PAGE_UP, UP_ARROW, DOWN_ARROW } from '@angular/cdk/keycodes';
|
|
@@ -1011,16 +1011,18 @@ const isElementVisible = (options) => {
|
|
|
1011
1011
|
const elementBlockStart = elementRect.top;
|
|
1012
1012
|
const containerInlineStart = containerRect.left;
|
|
1013
1013
|
const containerBlockStart = containerRect.top;
|
|
1014
|
-
const
|
|
1015
|
-
const
|
|
1014
|
+
const elWith = elementRect.width || 1;
|
|
1015
|
+
const elHeight = elementRect.height || 1;
|
|
1016
|
+
const elementInlineEnd = elementInlineStart + elWith;
|
|
1017
|
+
const elementBlockEnd = elementBlockStart + elHeight;
|
|
1016
1018
|
const containerInlineEnd = containerInlineStart + containerRect.width;
|
|
1017
1019
|
const containerBlockEnd = containerBlockStart + containerRect.height;
|
|
1018
1020
|
const isElementInlineVisible = elementInlineStart >= containerInlineStart && elementInlineEnd <= containerInlineEnd;
|
|
1019
1021
|
const isElementBlockVisible = elementBlockStart >= containerBlockStart && elementBlockEnd <= containerBlockEnd;
|
|
1020
1022
|
const inlineIntersection = Math.min(elementInlineEnd, containerInlineEnd) - Math.max(elementInlineStart, containerInlineStart);
|
|
1021
1023
|
const blockIntersection = Math.min(elementBlockEnd, containerBlockEnd) - Math.max(elementBlockStart, containerBlockStart);
|
|
1022
|
-
const inlineIntersectionPercentage = clamp((inlineIntersection /
|
|
1023
|
-
const blockIntersectionPercentage = clamp((blockIntersection /
|
|
1024
|
+
const inlineIntersectionPercentage = clamp((inlineIntersection / elWith) * 100);
|
|
1025
|
+
const blockIntersectionPercentage = clamp((blockIntersection / elHeight) * 100);
|
|
1024
1026
|
return {
|
|
1025
1027
|
inline: isElementInlineVisible,
|
|
1026
1028
|
block: isElementBlockVisible,
|
|
@@ -2347,18 +2349,78 @@ const signalIsRendered = () => {
|
|
|
2347
2349
|
};
|
|
2348
2350
|
const signalClasses = (el, classMap) => {
|
|
2349
2351
|
const elements = buildElementSignal(el);
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2352
|
+
const injector = inject(Injector);
|
|
2353
|
+
effect(() => {
|
|
2354
|
+
const { currentElements, previousElements } = elements();
|
|
2355
|
+
for (const previousEl of previousElements) {
|
|
2356
|
+
if (currentElements.includes(previousEl))
|
|
2357
|
+
continue;
|
|
2358
|
+
const tokens = Object.keys(classMap)
|
|
2359
|
+
.map((key) => key.split(' '))
|
|
2360
|
+
.flat();
|
|
2361
|
+
if (!tokens.length)
|
|
2362
|
+
continue;
|
|
2363
|
+
previousEl.classList.remove(...tokens);
|
|
2364
|
+
}
|
|
2365
|
+
for (const currentEl of currentElements) {
|
|
2366
|
+
if (previousElements.includes(currentEl))
|
|
2367
|
+
continue;
|
|
2368
|
+
for (const [tokens, condition] of Object.entries(classMap)) {
|
|
2369
|
+
untracked(() => {
|
|
2370
|
+
if (!condition())
|
|
2371
|
+
return;
|
|
2372
|
+
const tokenArray = tokens.split(' ');
|
|
2373
|
+
if (!tokenArray.length)
|
|
2374
|
+
return;
|
|
2375
|
+
currentEl.classList.add(...tokenArray);
|
|
2376
|
+
});
|
|
2358
2377
|
}
|
|
2359
|
-
}
|
|
2360
|
-
cleanupFn: ({ key }) => elements().currentElement?.classList.remove(key),
|
|
2378
|
+
}
|
|
2361
2379
|
});
|
|
2380
|
+
const effects = {};
|
|
2381
|
+
const has = (tokens) => tokens in effects;
|
|
2382
|
+
const push = (tokens, signal) => {
|
|
2383
|
+
if (has(tokens))
|
|
2384
|
+
return;
|
|
2385
|
+
runInInjectionContext(injector, () => {
|
|
2386
|
+
effects[tokens] = effect(() => {
|
|
2387
|
+
const { currentElements } = untracked(() => elements());
|
|
2388
|
+
for (const el of currentElements) {
|
|
2389
|
+
const tokenArray = tokens.split(' ');
|
|
2390
|
+
if (!tokenArray.length)
|
|
2391
|
+
continue;
|
|
2392
|
+
if (!signal()) {
|
|
2393
|
+
el.classList.remove(...tokenArray);
|
|
2394
|
+
}
|
|
2395
|
+
else {
|
|
2396
|
+
el.classList.add(...tokenArray);
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
});
|
|
2400
|
+
});
|
|
2401
|
+
};
|
|
2402
|
+
const pushMany = (map) => {
|
|
2403
|
+
for (const [tokens, signal] of Object.entries(map)) {
|
|
2404
|
+
push(tokens, signal);
|
|
2405
|
+
}
|
|
2406
|
+
};
|
|
2407
|
+
const remove = (tokens) => {
|
|
2408
|
+
effects[tokens]?.destroy();
|
|
2409
|
+
delete effects[tokens];
|
|
2410
|
+
for (const el of elements().currentElements) {
|
|
2411
|
+
const tokenArray = tokens.split(' ');
|
|
2412
|
+
if (!tokenArray.length)
|
|
2413
|
+
continue;
|
|
2414
|
+
el.classList.remove(...tokenArray);
|
|
2415
|
+
}
|
|
2416
|
+
};
|
|
2417
|
+
const removeMany = (tokens) => {
|
|
2418
|
+
for (const token of tokens) {
|
|
2419
|
+
remove(token);
|
|
2420
|
+
}
|
|
2421
|
+
};
|
|
2422
|
+
pushMany(classMap);
|
|
2423
|
+
return { remove, removeMany, has, push, pushMany };
|
|
2362
2424
|
};
|
|
2363
2425
|
const signalHostClasses = (classMap) => signalClasses(inject(ElementRef), classMap);
|
|
2364
2426
|
const ALWAYS_TRUE_ATTRIBUTE_KEYS = ['disabled', 'readonly', 'required', 'checked', 'selected', 'hidden', 'inert'];
|
|
@@ -2487,11 +2549,25 @@ const signalElementMutations = (el, options) => {
|
|
|
2487
2549
|
return elementMutationsSignal.asReadonly();
|
|
2488
2550
|
};
|
|
2489
2551
|
const signalHostElementMutations = (options) => signalElementMutations(inject(ElementRef), options);
|
|
2490
|
-
const signalElementScrollState = (el) => {
|
|
2552
|
+
const signalElementScrollState = (el, options) => {
|
|
2491
2553
|
const elements = buildElementSignal(el);
|
|
2492
2554
|
const elementDimensions = signalElementDimensions(elements);
|
|
2493
2555
|
const elementMutations = signalElementMutations(elements, { childList: true, subtree: true });
|
|
2494
2556
|
const isRendered = signalIsRendered();
|
|
2557
|
+
const initialScrollPosition = options?.initialScrollPosition;
|
|
2558
|
+
if (initialScrollPosition) {
|
|
2559
|
+
const ref = effect(() => {
|
|
2560
|
+
if (!isRendered())
|
|
2561
|
+
return;
|
|
2562
|
+
const scrollPosition = initialScrollPosition();
|
|
2563
|
+
const element = elements().currentElement;
|
|
2564
|
+
if (scrollPosition && element) {
|
|
2565
|
+
element.scrollLeft = scrollPosition.x;
|
|
2566
|
+
element.scrollTop = scrollPosition.y;
|
|
2567
|
+
ref.destroy();
|
|
2568
|
+
}
|
|
2569
|
+
});
|
|
2570
|
+
}
|
|
2495
2571
|
return computed(() => {
|
|
2496
2572
|
const element = elements().currentElement;
|
|
2497
2573
|
const dimensions = elementDimensions();
|
|
@@ -2565,6 +2641,38 @@ const signalElementIntersection = (el, options) => {
|
|
|
2565
2641
|
obs?.disconnect();
|
|
2566
2642
|
}
|
|
2567
2643
|
if (els.currentElements.length && !!enabled) {
|
|
2644
|
+
const rootEl = untracked(() => root().currentElement);
|
|
2645
|
+
// check sync for intersections since the intersection observer async and we probably want to know the initial state
|
|
2646
|
+
const entries = els.currentElements
|
|
2647
|
+
.map((el) => {
|
|
2648
|
+
const visibility = isElementVisible({
|
|
2649
|
+
container: rootEl,
|
|
2650
|
+
element: el,
|
|
2651
|
+
});
|
|
2652
|
+
if (!visibility) {
|
|
2653
|
+
console.error('No visibility data found for element.', {
|
|
2654
|
+
element: el,
|
|
2655
|
+
container: rootEl,
|
|
2656
|
+
});
|
|
2657
|
+
return null;
|
|
2658
|
+
}
|
|
2659
|
+
const inlineIntersectionRatio = visibility.inlineIntersection / 100;
|
|
2660
|
+
const blockIntersectionRatio = visibility.blockIntersection / 100;
|
|
2661
|
+
const isIntersecting = inlineIntersectionRatio > 0 && blockIntersectionRatio > 0;
|
|
2662
|
+
const intersectionRatio = Math.min(inlineIntersectionRatio, blockIntersectionRatio);
|
|
2663
|
+
const intersectionEntry = {
|
|
2664
|
+
boundingClientRect: el.getBoundingClientRect(),
|
|
2665
|
+
intersectionRatio,
|
|
2666
|
+
intersectionRect: el.getBoundingClientRect(),
|
|
2667
|
+
isIntersecting,
|
|
2668
|
+
rootBounds: root().currentElement?.getBoundingClientRect() ?? null,
|
|
2669
|
+
target: el,
|
|
2670
|
+
time: performance.now(),
|
|
2671
|
+
};
|
|
2672
|
+
return intersectionEntry;
|
|
2673
|
+
})
|
|
2674
|
+
.filter((e) => e !== null);
|
|
2675
|
+
elementIntersectionSignal.set(entries);
|
|
2568
2676
|
for (const el of els.currentElements) {
|
|
2569
2677
|
obs?.observe(el);
|
|
2570
2678
|
}
|
|
@@ -2699,6 +2807,27 @@ const injectPathParam = (key, config) => {
|
|
|
2699
2807
|
const src = computed(() => pathParams()[key] ?? null);
|
|
2700
2808
|
return transformOrReturn(src, config);
|
|
2701
2809
|
};
|
|
2810
|
+
const createIsRenderedSignal = () => {
|
|
2811
|
+
const value = signal(false);
|
|
2812
|
+
nextFrame(() => {
|
|
2813
|
+
if (!value()) {
|
|
2814
|
+
console.error('Render signal was not set to true. This can cause unexpected behavior. Make sure to .bind() the render signal at the end of the constructor.');
|
|
2815
|
+
}
|
|
2816
|
+
});
|
|
2817
|
+
return {
|
|
2818
|
+
state: value,
|
|
2819
|
+
bind: () => effect(() => value.set(true), { allowSignalWrites: true }),
|
|
2820
|
+
};
|
|
2821
|
+
};
|
|
2822
|
+
const createCanAnimateSignal = () => {
|
|
2823
|
+
const value = signal(false);
|
|
2824
|
+
nextFrame(() => {
|
|
2825
|
+
value.set(true);
|
|
2826
|
+
});
|
|
2827
|
+
return {
|
|
2828
|
+
state: value,
|
|
2829
|
+
};
|
|
2830
|
+
};
|
|
2702
2831
|
|
|
2703
2832
|
const scrollBehaviorSupported = supportsScrollBehavior();
|
|
2704
2833
|
let _uniqueIdCounter = 0;
|
|
@@ -5364,5 +5493,5 @@ const Validators = {
|
|
|
5364
5493
|
* Generated bundle index. Do not edit.
|
|
5365
5494
|
*/
|
|
5366
5495
|
|
|
5367
|
-
export { ANIMATABLE_TOKEN, ANIMATED_IF_TOKEN, ANIMATED_LIFECYCLE_TOKEN, AT_LEAST_ONE_REQUIRED, ActiveSelectionModel, AnimatableDirective, AnimatedIfDirective, AnimatedLifecycleDirective, AnimatedOverlayDirective, CURSOR_DRAG_SCROLLING_CLASS, CURSOR_DRAG_SCROLLING_PREPARED_CLASS, ClickObserverFactory, ClickObserverService, ClickOutsideDirective, ContentObserverService, CursorDragScrollDirective, DEBUG_TOKEN, DEFAULT_VIEWPORT_CONFIG, DELAYABLE_TOKEN, DebugDirective, DelayableDirective, ET_PROPERTY_REMOVED, FocusVisibleService, IS_ACTIVE_ELEMENT, IS_ARRAY_NOT_EMPTY, IS_ELEMENT, IS_EMAIL, InferMimeTypePipe, IntersectionObserverFactory, IntersectionObserverService, IsActiveElementDirective, IsArrayNotEmpty, IsElementDirective, IsEmail, KeyPressManager, LetContext, LetDirective, MUST_MATCH, Memo, MustMatch, MutationObserverFactory, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, OBSERVE_SCROLL_STATE, OBSERVE_VISIBILITY_TOKEN, ObserveContentDirective, ObserveResizeDirective, ObserveScrollStateDirective, ObserveVisibilityDirective, PropsDirective, ROOT_BOUNDARY_TOKEN, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeObserverFactory, ResizeObserverService, RootBoundaryDirective, RouterStateService, RuntimeError, SCROLL_OBSERVER_FIRST_ELEMENT_CLASS, SCROLL_OBSERVER_IGNORE_TARGET_CLASS, SCROLL_OBSERVER_LAST_ELEMENT_CLASS, SCROLL_OBSERVER_OBSERVING_FIRST_ELEMENT_CLASS, SCROLL_OBSERVER_OBSERVING_LAST_ELEMENT_CLASS, SEO_DIRECTIVE_TOKEN, ScrollObserverFirstElementDirective, ScrollObserverIgnoreTargetDirective, ScrollObserverLastElementDirective, SelectionModel, SeoDirective, SmartBlockScrollStrategy, StructuredDataComponent, ToArrayPipe, TypedQueryList, VIEWPORT_CONFIG, ValidateAtLeastOneRequired, Validators, ViewportService, bindProps, buildSignalEffects, clamp, clone, cloneFormGroup, controlValueSignal, controlValueSignalWithPrevious, createComponentId, createDependencyStash, createDestroy, createElementDictionary, createFlipAnimation, createFlipAnimationGroup, createHostProps, createMediaQueryObservable, createMutationObservable, createPropHandlers, createProps, createReactiveBindings, createResizeObservable, createSetup, debouncedControlValueSignal, deleteCookie, elementCanScroll, equal, forceReflow, formatRuntimeError, fromNextFrame, getCookie, getDomain, getElementVisibleStates, getFormGroupValue, getGroupMatchPoints, getGroupMatchScore, getIntersectionInfo, getKnockoutMatchScore, getMatchScoreSubLine, getObjectProperty, hasCookie, inferMimeType, injectFragment, injectHostElement, injectOrRunInContext, injectPathParam, injectPathParams, injectQueryParam, injectQueryParams, injectRouteData, injectRouteDataItem, injectRouteTitle, injectTemplateRef, isArray, isElementVisible, isEmptyArray, isGroupMatch, isKnockoutMatch, isObject, isObjectArray, isPrimitiveArray, mergeSeoConfig, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, previousSignalValue, provideViewportConfig, round, routerDisableScrollTop, scrollToElement, setCookie, signalAttributes, signalClasses, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, signalVisibilityChangeClasses, switchQueryListChanges, syncSignal, templateComputed, toArray, toArrayTrackByFn, transformOrReturn, unbindProps };
|
|
5496
|
+
export { ANIMATABLE_TOKEN, ANIMATED_IF_TOKEN, ANIMATED_LIFECYCLE_TOKEN, AT_LEAST_ONE_REQUIRED, ActiveSelectionModel, AnimatableDirective, AnimatedIfDirective, AnimatedLifecycleDirective, AnimatedOverlayDirective, CURSOR_DRAG_SCROLLING_CLASS, CURSOR_DRAG_SCROLLING_PREPARED_CLASS, ClickObserverFactory, ClickObserverService, ClickOutsideDirective, ContentObserverService, CursorDragScrollDirective, DEBUG_TOKEN, DEFAULT_VIEWPORT_CONFIG, DELAYABLE_TOKEN, DebugDirective, DelayableDirective, ET_PROPERTY_REMOVED, FocusVisibleService, IS_ACTIVE_ELEMENT, IS_ARRAY_NOT_EMPTY, IS_ELEMENT, IS_EMAIL, InferMimeTypePipe, IntersectionObserverFactory, IntersectionObserverService, IsActiveElementDirective, IsArrayNotEmpty, IsElementDirective, IsEmail, KeyPressManager, LetContext, LetDirective, MUST_MATCH, Memo, MustMatch, MutationObserverFactory, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, OBSERVE_SCROLL_STATE, OBSERVE_VISIBILITY_TOKEN, ObserveContentDirective, ObserveResizeDirective, ObserveScrollStateDirective, ObserveVisibilityDirective, PropsDirective, ROOT_BOUNDARY_TOKEN, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeObserverFactory, ResizeObserverService, RootBoundaryDirective, RouterStateService, RuntimeError, SCROLL_OBSERVER_FIRST_ELEMENT_CLASS, SCROLL_OBSERVER_IGNORE_TARGET_CLASS, SCROLL_OBSERVER_LAST_ELEMENT_CLASS, SCROLL_OBSERVER_OBSERVING_FIRST_ELEMENT_CLASS, SCROLL_OBSERVER_OBSERVING_LAST_ELEMENT_CLASS, SEO_DIRECTIVE_TOKEN, ScrollObserverFirstElementDirective, ScrollObserverIgnoreTargetDirective, ScrollObserverLastElementDirective, SelectionModel, SeoDirective, SmartBlockScrollStrategy, StructuredDataComponent, ToArrayPipe, TypedQueryList, VIEWPORT_CONFIG, ValidateAtLeastOneRequired, Validators, ViewportService, bindProps, buildSignalEffects, clamp, clone, cloneFormGroup, controlValueSignal, controlValueSignalWithPrevious, createCanAnimateSignal, createComponentId, createDependencyStash, createDestroy, createElementDictionary, createFlipAnimation, createFlipAnimationGroup, createHostProps, createIsRenderedSignal, createMediaQueryObservable, createMutationObservable, createPropHandlers, createProps, createReactiveBindings, createResizeObservable, createSetup, debouncedControlValueSignal, deleteCookie, elementCanScroll, equal, forceReflow, formatRuntimeError, fromNextFrame, getCookie, getDomain, getElementVisibleStates, getFormGroupValue, getGroupMatchPoints, getGroupMatchScore, getIntersectionInfo, getKnockoutMatchScore, getMatchScoreSubLine, getObjectProperty, hasCookie, inferMimeType, injectFragment, injectHostElement, injectOrRunInContext, injectPathParam, injectPathParams, injectQueryParam, injectQueryParams, injectRouteData, injectRouteDataItem, injectRouteTitle, injectTemplateRef, isArray, isElementVisible, isEmptyArray, isGroupMatch, isKnockoutMatch, isObject, isObjectArray, isPrimitiveArray, mergeSeoConfig, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, previousSignalValue, provideViewportConfig, round, routerDisableScrollTop, scrollToElement, setCookie, signalAttributes, signalClasses, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, signalVisibilityChangeClasses, switchQueryListChanges, syncSignal, templateComputed, toArray, toArrayTrackByFn, transformOrReturn, unbindProps };
|
|
5368
5497
|
//# sourceMappingURL=ethlete-core.mjs.map
|