@ethlete/core 5.0.0-next.34 → 5.0.0-next.36
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 +70 -0
- package/fesm2022/ethlete-core.mjs +384 -35
- package/fesm2022/ethlete-core.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ethlete-core.d.ts +199 -4
|
@@ -7,7 +7,7 @@ import { SIGNAL, signalSetFn } from '@angular/core/primitives/signals';
|
|
|
7
7
|
import { coerceElement } from '@angular/cdk/coercion';
|
|
8
8
|
import { DOCUMENT as DOCUMENT$1, isPlatformBrowser } from '@angular/common';
|
|
9
9
|
import { BreakpointObserver } from '@angular/cdk/layout';
|
|
10
|
-
import { Router, NavigationEnd, NavigationSkipped } from '@angular/router';
|
|
10
|
+
import { Router, NavigationEnd, NavigationSkipped, NavigationStart } from '@angular/router';
|
|
11
11
|
import { Overlay } from '@angular/cdk/overlay';
|
|
12
12
|
import { ComponentPortal } from '@angular/cdk/portal';
|
|
13
13
|
import { autoUpdate, computePosition, offset, flip, size, shift, limitShift, arrow, hide } from '@floating-ui/dom';
|
|
@@ -1972,7 +1972,12 @@ const signalStyles = (el, styleMap) => {
|
|
|
1972
1972
|
const signalHostStyles = (styleMap) => signalStyles(inject(ElementRef), styleMap);
|
|
1973
1973
|
|
|
1974
1974
|
const elementCanScroll = (element, direction) => {
|
|
1975
|
-
|
|
1975
|
+
// Omitting the element means "the document scroller". Resolved lazily and guarded so a call on the
|
|
1976
|
+
// server answers "cannot scroll" instead of throwing on a missing `document`.
|
|
1977
|
+
const el = element || (typeof document === 'undefined' ? null : document.documentElement);
|
|
1978
|
+
if (!el) {
|
|
1979
|
+
return false;
|
|
1980
|
+
}
|
|
1976
1981
|
const { scrollHeight, clientHeight, scrollWidth, clientWidth } = el;
|
|
1977
1982
|
if (direction === 'x') {
|
|
1978
1983
|
return scrollWidth > clientWidth;
|
|
@@ -1982,17 +1987,25 @@ const elementCanScroll = (element, direction) => {
|
|
|
1982
1987
|
}
|
|
1983
1988
|
return scrollHeight > clientHeight || scrollWidth > clientWidth;
|
|
1984
1989
|
};
|
|
1985
|
-
const createViewportRect = () =>
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
width
|
|
1991
|
-
height
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1990
|
+
const createViewportRect = () => {
|
|
1991
|
+
// Collapses to a zero rect where there is no window (server). `isElementVisible` never reaches the
|
|
1992
|
+
// intersection math there anyway — `elementCanScroll` already reports the document as unscrollable
|
|
1993
|
+
// — so the rect only has to be a valid shape.
|
|
1994
|
+
const hasWindow = typeof window !== 'undefined';
|
|
1995
|
+
const width = hasWindow ? window.innerWidth : 0;
|
|
1996
|
+
const height = hasWindow ? window.innerHeight : 0;
|
|
1997
|
+
return {
|
|
1998
|
+
left: 0,
|
|
1999
|
+
top: 0,
|
|
2000
|
+
right: width,
|
|
2001
|
+
bottom: height,
|
|
2002
|
+
width,
|
|
2003
|
+
height,
|
|
2004
|
+
x: 0,
|
|
2005
|
+
y: 0,
|
|
2006
|
+
toJSON: () => ({}),
|
|
2007
|
+
};
|
|
2008
|
+
};
|
|
1996
2009
|
const isElementVisible = (options) => {
|
|
1997
2010
|
const { container, element } = options;
|
|
1998
2011
|
if (!element) {
|
|
@@ -2444,6 +2457,21 @@ const signalElementLastScrollDirection = (el) => {
|
|
|
2444
2457
|
};
|
|
2445
2458
|
const signalHostElementLastScrollDirection = () => signalElementLastScrollDirection(inject(ElementRef));
|
|
2446
2459
|
|
|
2460
|
+
/**
|
|
2461
|
+
* A signal for whether this page is the one the reader is actually looking at — `false` for a backgrounded
|
|
2462
|
+
* tab or a minimised window.
|
|
2463
|
+
*
|
|
2464
|
+
* Not the same question as whether an element is on screen: an IntersectionObserver reports a fully visible
|
|
2465
|
+
* element in a background tab, because the tab's own visibility is no part of what it measures. Anything
|
|
2466
|
+
* that moves on its own needs to ask both, and a timer is not a substitute — browsers throttle timers in a
|
|
2467
|
+
* hidden tab rather than stopping them, so work keeps piling up out of sight.
|
|
2468
|
+
*/
|
|
2469
|
+
const injectIsDocumentVisible = memoizeSignal(() => {
|
|
2470
|
+
const document = inject(DOCUMENT);
|
|
2471
|
+
const isVisible = () => document.visibilityState === 'visible';
|
|
2472
|
+
return toSignal(fromEvent(document, 'visibilitychange').pipe(map(isVisible)), { initialValue: isVisible() });
|
|
2473
|
+
});
|
|
2474
|
+
|
|
2447
2475
|
const areScrollStatesEqual = (a, b) => {
|
|
2448
2476
|
return (a.canScroll === b.canScroll &&
|
|
2449
2477
|
a.canScrollHorizontally === b.canScrollHorizontally &&
|
|
@@ -2557,6 +2585,8 @@ const writeViewportSizeToCssVariables = () => {
|
|
|
2557
2585
|
|
|
2558
2586
|
/** The deadzone in pixels after which the cursor drag scroll will take effect. */
|
|
2559
2587
|
const CURSOR_DRAG_SCROLL_DEADZONE = 5;
|
|
2588
|
+
/** `MouseEvent.button` for the primary button. A secondary click opens a menu; it does not drag. */
|
|
2589
|
+
const PRIMARY_MOUSE_BUTTON = 0;
|
|
2560
2590
|
/** The class that is added to the element when the cursor is being dragged. */
|
|
2561
2591
|
const CURSOR_DRAG_SCROLLING_CLASS = 'et-cursor-drag-scroll--scrolling';
|
|
2562
2592
|
const CURSOR_DRAG_INIT_CLASS = 'et-cursor-drag-scroll--init';
|
|
@@ -2692,15 +2722,18 @@ const useCursorDragScroll = (el, options) => {
|
|
|
2692
2722
|
dragAmount.set({ x: 0, y: 0 });
|
|
2693
2723
|
};
|
|
2694
2724
|
const setupDragging = (e) => {
|
|
2695
|
-
|
|
2725
|
+
// A context menu takes the pointer away without ever delivering a `mouseup` — so without it in here, a
|
|
2726
|
+
// right click (or a ctrl-click on a Mac, which is the primary button) leaves the drag latched on and
|
|
2727
|
+
// every later mouse move scrolls the container.
|
|
2728
|
+
const dragEnd = merge(fromEvent(document, 'mouseup'), fromEvent(document, 'contextmenu'));
|
|
2696
2729
|
const mouseMove = fromEvent(document, 'mousemove');
|
|
2697
2730
|
const el = element().currentElement;
|
|
2698
2731
|
if (!el)
|
|
2699
2732
|
return;
|
|
2700
2733
|
mouseMove
|
|
2701
|
-
.pipe(takeUntilDestroyed(destroyRef), takeUntil(
|
|
2734
|
+
.pipe(takeUntilDestroyed(destroyRef), takeUntil(dragEnd), tap((e) => updateDragging(e)))
|
|
2702
2735
|
.subscribe();
|
|
2703
|
-
|
|
2736
|
+
dragEnd
|
|
2704
2737
|
.pipe(take(1), takeUntilDestroyed(destroyRef), tap(() => updateDraggingEnd()))
|
|
2705
2738
|
.subscribe();
|
|
2706
2739
|
initialDragPosition.set({ x: e.clientX, y: e.clientY });
|
|
@@ -2708,7 +2741,7 @@ const useCursorDragScroll = (el, options) => {
|
|
|
2708
2741
|
isInitDragging.set(true);
|
|
2709
2742
|
};
|
|
2710
2743
|
toObservable(element)
|
|
2711
|
-
.pipe(map((e) => e?.currentElement), switchMap((el) => (el ? fromEvent(el, 'mousedown') : of(null))), filter((e) => !!e), filter(() => enabled()), tap((e) => setupDragging(e)), takeUntilDestroyed())
|
|
2744
|
+
.pipe(map((e) => e?.currentElement), switchMap((el) => (el ? fromEvent(el, 'mousedown') : of(null))), filter((e) => !!e), filter((e) => e.button === PRIMARY_MOUSE_BUTTON), filter(() => enabled()), tap((e) => setupDragging(e)), takeUntilDestroyed())
|
|
2712
2745
|
.subscribe();
|
|
2713
2746
|
return {
|
|
2714
2747
|
isDragging: isDragging.asReadonly(),
|
|
@@ -2941,6 +2974,31 @@ const injectPathParamChanges = memoizeSignal(() => {
|
|
|
2941
2974
|
return changes;
|
|
2942
2975
|
});
|
|
2943
2976
|
});
|
|
2977
|
+
/**
|
|
2978
|
+
* The state handed to the navigation that is currently in progress, i.e. what
|
|
2979
|
+
* `router.navigate(…, { state })` passed — typed to whatever you expect.
|
|
2980
|
+
*
|
|
2981
|
+
* Read **synchronously**, in a constructor or a resolver, and deliberately not a signal: navigation state exists
|
|
2982
|
+
* only for the duration of the navigation that carries it. By the time an effect flushed, the navigation would be
|
|
2983
|
+
* over and the answer always `null`. Returns `null` when there is no navigation in flight or it carried no state —
|
|
2984
|
+
* which is the normal case for a page arrived at by typing its URL, so always handle it.
|
|
2985
|
+
*
|
|
2986
|
+
* Use it for the things a URL should not carry: a "you were redirected because…" reason, a pre-fetched object the
|
|
2987
|
+
* previous page already had, a scroll intent. Anything the page needs to survive a reload belongs in the URL.
|
|
2988
|
+
*
|
|
2989
|
+
* @example
|
|
2990
|
+
* type CheckoutNavState = { fromCart: boolean };
|
|
2991
|
+
*
|
|
2992
|
+
* export class CheckoutComponent {
|
|
2993
|
+
* private navState = injectRouterNavigationState<CheckoutNavState>();
|
|
2994
|
+
*
|
|
2995
|
+
* protected cameFromCart = this.navState?.fromCart ?? false;
|
|
2996
|
+
* }
|
|
2997
|
+
*/
|
|
2998
|
+
const injectRouterNavigationState = () => {
|
|
2999
|
+
const router = inject(Router);
|
|
3000
|
+
return router.getCurrentNavigation()?.extras.state ?? null;
|
|
3001
|
+
};
|
|
2944
3002
|
|
|
2945
3003
|
const ET_DISABLE_SCROLL_TOP = Symbol('ET_DISABLE_SCROLL_TOP');
|
|
2946
3004
|
const ET_DISABLE_SCROLL_TOP_AS_RETURN_ROUTE = Symbol('ET_DISABLE_SCROLL_TOP_AS_RETURN_ROUTE');
|
|
@@ -2951,22 +3009,182 @@ const routerDisableScrollTop = (config = {}) => {
|
|
|
2951
3009
|
...(config.onPathParamChange ? { [ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE]: true } : {}),
|
|
2952
3010
|
};
|
|
2953
3011
|
};
|
|
3012
|
+
/**
|
|
3013
|
+
* Registry of "not settled yet" reporters. Lives in the root injector so a route component can
|
|
3014
|
+
* reach the registration created by the app level `setupScrollRestoration` call.
|
|
3015
|
+
* @internal
|
|
3016
|
+
*/
|
|
3017
|
+
const [, injectScrollRestorationHolds] = createRootProvider(() => {
|
|
3018
|
+
const holds = new Set();
|
|
3019
|
+
return {
|
|
3020
|
+
add: (isPending) => {
|
|
3021
|
+
holds.add(isPending);
|
|
3022
|
+
return () => holds.delete(isPending);
|
|
3023
|
+
},
|
|
3024
|
+
isHeld: () => {
|
|
3025
|
+
for (const isPending of holds) {
|
|
3026
|
+
if (isPending())
|
|
3027
|
+
return true;
|
|
3028
|
+
}
|
|
3029
|
+
return false;
|
|
3030
|
+
},
|
|
3031
|
+
};
|
|
3032
|
+
}, { name: 'ScrollRestorationHolds' });
|
|
3033
|
+
/**
|
|
3034
|
+
* Suspend scroll restoration while `isPending` reads `true`.
|
|
3035
|
+
*
|
|
3036
|
+
* Restoration already waits for the scroll container to grow tall enough to reach the saved offset,
|
|
3037
|
+
* so this is only needed when the content may take longer than `restore.timeout` to get there —
|
|
3038
|
+
* a slow list request, for instance. Registers for the lifetime of the current injection context.
|
|
3039
|
+
*
|
|
3040
|
+
* @example
|
|
3041
|
+
* // inside a route component
|
|
3042
|
+
* holdScrollRestoration(() => query.isLoading());
|
|
3043
|
+
*/
|
|
3044
|
+
const holdScrollRestoration = (isPending) => {
|
|
3045
|
+
const remove = injectScrollRestorationHolds().add(isPending);
|
|
3046
|
+
inject(DestroyRef).onDestroy(remove);
|
|
3047
|
+
};
|
|
3048
|
+
/** Upper bound on remembered history entries. Each entry is a single number, so this is generous. */
|
|
3049
|
+
const MAX_STORED_POSITIONS = 200;
|
|
3050
|
+
const DEFAULT_RESTORE_TIMEOUT = 1000;
|
|
3051
|
+
const DEFAULT_RESTORE_MAX_TIMEOUT = 10_000;
|
|
3052
|
+
/** Events that mean the user took over scrolling, so a pending restoration must be abandoned. */
|
|
3053
|
+
const INTERACTION_EVENTS = ['wheel', 'touchmove', 'keydown'];
|
|
2954
3054
|
const setupScrollRestoration = (config = {}) => {
|
|
2955
3055
|
if (!isPlatformBrowser(inject(PLATFORM_ID))) {
|
|
2956
3056
|
return;
|
|
2957
3057
|
}
|
|
2958
3058
|
const router = inject(Router);
|
|
2959
3059
|
const document = inject(DOCUMENT);
|
|
3060
|
+
const injector = inject(Injector);
|
|
3061
|
+
const holds = injectScrollRestorationHolds();
|
|
3062
|
+
const restoreEnabled = config.restore?.enabled === true;
|
|
3063
|
+
const restoreTimeout = config.restore?.timeout ?? DEFAULT_RESTORE_TIMEOUT;
|
|
3064
|
+
const restoreMaxTimeout = config.restore?.maxTimeout ?? DEFAULT_RESTORE_MAX_TIMEOUT;
|
|
3065
|
+
const clampOnTimeout = config.restore?.clampOnTimeout ?? true;
|
|
3066
|
+
const resolveScrollElement = () => {
|
|
3067
|
+
const el = typeof config.scrollElement === 'function' ? config.scrollElement() : config.scrollElement;
|
|
3068
|
+
return el ?? document.documentElement;
|
|
3069
|
+
};
|
|
3070
|
+
// The browser restores the offset against the still-loading (much shorter) document, which is the
|
|
3071
|
+
// exact problem we are solving — take it over completely.
|
|
3072
|
+
if (restoreEnabled && 'scrollRestoration' in history) {
|
|
3073
|
+
history.scrollRestoration = 'manual';
|
|
3074
|
+
}
|
|
3075
|
+
/** Saved offsets keyed by the router's per-history-entry `navigationId`. */
|
|
3076
|
+
const positions = new Map();
|
|
3077
|
+
// Mirrors Angular's own `RouterScroller`: the offset of the currently displayed page belongs to
|
|
3078
|
+
// the navigation that produced it, and a popstate reports the id of the entry it moves to.
|
|
3079
|
+
let lastNavigationId = 0;
|
|
3080
|
+
let restoredNavigationId = 0;
|
|
3081
|
+
let isPopstate = false;
|
|
2960
3082
|
let prev = { state: createRouterState(router), route: createRoute(router) };
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
3083
|
+
let pendingRestore = null;
|
|
3084
|
+
const cancelPendingRestore = () => {
|
|
3085
|
+
pendingRestore?.();
|
|
3086
|
+
pendingRestore = null;
|
|
3087
|
+
};
|
|
3088
|
+
const scheduleRestore = (target) => {
|
|
3089
|
+
cancelPendingRestore();
|
|
3090
|
+
let frame = 0;
|
|
3091
|
+
let started = false;
|
|
3092
|
+
let cancelled = false;
|
|
3093
|
+
// The user scrolling always wins over a restoration we have not committed yet.
|
|
3094
|
+
const abortByUser = () => cancelPendingRestore();
|
|
3095
|
+
const hardDeadline = Date.now() + Math.max(restoreTimeout, restoreMaxTimeout);
|
|
3096
|
+
let deadline = Date.now() + restoreTimeout;
|
|
3097
|
+
const step = () => {
|
|
3098
|
+
frame = 0;
|
|
3099
|
+
if (cancelled)
|
|
3100
|
+
return;
|
|
3101
|
+
const el = resolveScrollElement();
|
|
3102
|
+
const maxOffset = Math.max(0, el.scrollHeight - el.clientHeight);
|
|
3103
|
+
if (maxOffset >= target) {
|
|
3104
|
+
el.scrollTop = target;
|
|
3105
|
+
cancelPendingRestore();
|
|
3106
|
+
return;
|
|
3107
|
+
}
|
|
3108
|
+
const now = Date.now();
|
|
3109
|
+
// A registered hold means the page knows more data is coming, so the content is expected to
|
|
3110
|
+
// grow — suspend the clock instead of giving up on a still loading page.
|
|
3111
|
+
if (holds.isHeld() && now < hardDeadline) {
|
|
3112
|
+
deadline = now + restoreTimeout;
|
|
3113
|
+
}
|
|
3114
|
+
if (now < deadline && now < hardDeadline) {
|
|
3115
|
+
frame = requestAnimationFrame(step);
|
|
3116
|
+
return;
|
|
3117
|
+
}
|
|
3118
|
+
if (clampOnTimeout && maxOffset > 0) {
|
|
3119
|
+
el.scrollTop = Math.min(target, maxOffset);
|
|
3120
|
+
}
|
|
3121
|
+
cancelPendingRestore();
|
|
3122
|
+
};
|
|
3123
|
+
// Wait for the new route to actually render before reading any geometry — on `NavigationEnd` the
|
|
3124
|
+
// components exist but the DOM still shows the previous page, whose height would be measured
|
|
3125
|
+
// instead. The timeout is a safety net in case no render pass follows.
|
|
3126
|
+
const start = () => {
|
|
3127
|
+
if (started || cancelled)
|
|
3128
|
+
return;
|
|
3129
|
+
started = true;
|
|
3130
|
+
frame = requestAnimationFrame(step);
|
|
3131
|
+
};
|
|
3132
|
+
const renderRef = afterNextRender({ read: start }, { injector });
|
|
3133
|
+
const fallback = setTimeout(start);
|
|
3134
|
+
for (const eventName of INTERACTION_EVENTS) {
|
|
3135
|
+
document.addEventListener(eventName, abortByUser, { capture: true, passive: true });
|
|
3136
|
+
}
|
|
3137
|
+
pendingRestore = () => {
|
|
3138
|
+
// `cancelled` is not redundant with destroying the render hook: a superseded restoration must
|
|
3139
|
+
// not apply its (now stale) offset even if its hook had already been queued to run.
|
|
3140
|
+
cancelled = true;
|
|
3141
|
+
renderRef.destroy();
|
|
3142
|
+
if (frame)
|
|
3143
|
+
cancelAnimationFrame(frame);
|
|
3144
|
+
clearTimeout(fallback);
|
|
3145
|
+
for (const eventName of INTERACTION_EVENTS) {
|
|
3146
|
+
document.removeEventListener(eventName, abortByUser, { capture: true });
|
|
3147
|
+
}
|
|
3148
|
+
};
|
|
3149
|
+
};
|
|
3150
|
+
const onNavigationStart = (event) => {
|
|
3151
|
+
// A new navigation supersedes a restoration that has not committed yet.
|
|
3152
|
+
cancelPendingRestore();
|
|
3153
|
+
if (!restoreEnabled)
|
|
3154
|
+
return;
|
|
3155
|
+
positions.set(lastNavigationId, resolveScrollElement().scrollTop);
|
|
3156
|
+
if (positions.size > MAX_STORED_POSITIONS) {
|
|
3157
|
+
const oldest = positions.keys().next();
|
|
3158
|
+
if (!oldest.done)
|
|
3159
|
+
positions.delete(oldest.value);
|
|
3160
|
+
}
|
|
3161
|
+
isPopstate = event.navigationTrigger === 'popstate';
|
|
3162
|
+
restoredNavigationId = event.restoredState?.navigationId ?? 0;
|
|
3163
|
+
};
|
|
3164
|
+
const onNavigationEnd = (event) => {
|
|
2964
3165
|
const curr = { state: createRouterState(router), route: createRoute(router) };
|
|
2965
3166
|
const prevState = prev.state;
|
|
2966
3167
|
const currState = curr.state;
|
|
2967
3168
|
const sameUrlNavigation = prev.route === curr.route;
|
|
2968
3169
|
const didFragmentChange = prevState.fragment !== currState.fragment;
|
|
2969
3170
|
prev = curr;
|
|
3171
|
+
if (event instanceof NavigationEnd) {
|
|
3172
|
+
lastNavigationId = event.id;
|
|
3173
|
+
}
|
|
3174
|
+
else {
|
|
3175
|
+
// A skipped same url navigation is not a history move, so there is nothing to restore.
|
|
3176
|
+
isPopstate = false;
|
|
3177
|
+
restoredNavigationId = 0;
|
|
3178
|
+
}
|
|
3179
|
+
if (restoreEnabled && isPopstate) {
|
|
3180
|
+
const target = positions.get(restoredNavigationId);
|
|
3181
|
+
// The saved offset wins over both scroll to top and fragment scrolling: the user may well have
|
|
3182
|
+
// scrolled away from the anchor before leaving the page.
|
|
3183
|
+
if (target !== undefined) {
|
|
3184
|
+
scheduleRestore(target);
|
|
3185
|
+
return;
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
2970
3188
|
if (sameUrlNavigation) {
|
|
2971
3189
|
const allQueryParams = [
|
|
2972
3190
|
...new Set(Object.keys(prevState.queryParams).concat(Object.keys(currState.queryParams))),
|
|
@@ -2978,7 +3196,7 @@ const setupScrollRestoration = (config = {}) => {
|
|
|
2978
3196
|
const caseQueryParams = changedQueryParams.some((key) => config.queryParamTriggerList?.includes(key));
|
|
2979
3197
|
const caseFragment = didFragmentChange && config.fragment?.enabled;
|
|
2980
3198
|
if (caseQueryParams) {
|
|
2981
|
-
(
|
|
3199
|
+
resolveScrollElement().scrollTop = 0;
|
|
2982
3200
|
}
|
|
2983
3201
|
else if (caseFragment) {
|
|
2984
3202
|
const fragmentElement = document.getElementById(currState.fragment ?? '');
|
|
@@ -2994,9 +3212,17 @@ const setupScrollRestoration = (config = {}) => {
|
|
|
2994
3212
|
if (viaReturnRoute || explicitly || pathParamsChange) {
|
|
2995
3213
|
return;
|
|
2996
3214
|
}
|
|
2997
|
-
|
|
2998
|
-
el.scrollTop = 0;
|
|
3215
|
+
resolveScrollElement().scrollTop = 0;
|
|
2999
3216
|
}
|
|
3217
|
+
};
|
|
3218
|
+
router.events
|
|
3219
|
+
.pipe(filter((e) => e instanceof NavigationStart || e instanceof NavigationEnd || e instanceof NavigationSkipped), takeUntilDestroyed())
|
|
3220
|
+
.subscribe((event) => {
|
|
3221
|
+
if (event instanceof NavigationStart) {
|
|
3222
|
+
onNavigationStart(event);
|
|
3223
|
+
return;
|
|
3224
|
+
}
|
|
3225
|
+
onNavigationEnd(event);
|
|
3000
3226
|
});
|
|
3001
3227
|
};
|
|
3002
3228
|
|
|
@@ -3575,6 +3801,8 @@ const getClientXY = (event) => {
|
|
|
3575
3801
|
}
|
|
3576
3802
|
return { clientX: event.clientX, clientY: event.clientY };
|
|
3577
3803
|
};
|
|
3804
|
+
/** Trailing window over which {@link SwipeTracker.end} measures the release velocity. */
|
|
3805
|
+
const SWIPE_VELOCITY_WINDOW_MS = 100;
|
|
3578
3806
|
const createSwipeTracker = (startEvent) => {
|
|
3579
3807
|
const { clientX: originClientX, clientY: originClientY } = getClientXY(startEvent);
|
|
3580
3808
|
const startTime = Date.now();
|
|
@@ -3582,10 +3810,25 @@ const createSwipeTracker = (startEvent) => {
|
|
|
3582
3810
|
let movementY = 0;
|
|
3583
3811
|
let isSwiping = false;
|
|
3584
3812
|
let isScrolling = false;
|
|
3813
|
+
/**
|
|
3814
|
+
* Recent positions, oldest first, used to derive the release velocity. Trimmed to the trailing
|
|
3815
|
+
* window plus the one sample just before it, which serves as that window's baseline.
|
|
3816
|
+
*/
|
|
3817
|
+
let samples = [{ t: startTime, movementX: 0, movementY: 0 }];
|
|
3585
3818
|
const update = (event) => {
|
|
3586
3819
|
const { clientX, clientY } = getClientXY(event);
|
|
3587
3820
|
movementX = clientX - originClientX;
|
|
3588
3821
|
movementY = clientY - originClientY;
|
|
3822
|
+
const now = Date.now();
|
|
3823
|
+
samples.push({ t: now, movementX, movementY });
|
|
3824
|
+
// Trim against the newest sample rather than `now + window`: `end()` measures from its own
|
|
3825
|
+
// timestamp, which is never earlier, so this always keeps a superset of what it needs.
|
|
3826
|
+
const cutoff = now - SWIPE_VELOCITY_WINDOW_MS;
|
|
3827
|
+
let dropCount = 0;
|
|
3828
|
+
while (dropCount + 1 < samples.length && samples[dropCount + 1].t < cutoff)
|
|
3829
|
+
dropCount++;
|
|
3830
|
+
if (dropCount)
|
|
3831
|
+
samples = samples.slice(dropCount);
|
|
3589
3832
|
const positiveMovementX = Math.abs(movementX);
|
|
3590
3833
|
const positiveMovementY = Math.abs(movementY);
|
|
3591
3834
|
if (!isSwiping && !isScrolling) {
|
|
@@ -3608,12 +3851,31 @@ const createSwipeTracker = (startEvent) => {
|
|
|
3608
3851
|
isSwiping,
|
|
3609
3852
|
};
|
|
3610
3853
|
};
|
|
3854
|
+
const measureReleaseVelocity = (endTime) => {
|
|
3855
|
+
const windowStart = endTime - SWIPE_VELOCITY_WINDOW_MS;
|
|
3856
|
+
const firstInWindow = samples.findIndex((sample) => sample.t >= windowStart);
|
|
3857
|
+
// Nothing moved during the window: the pointer was held still before release, so the gesture
|
|
3858
|
+
// carries no momentum no matter how fast it started out.
|
|
3859
|
+
if (firstInWindow === -1)
|
|
3860
|
+
return { x: 0, y: 0 };
|
|
3861
|
+
const newest = samples[samples.length - 1];
|
|
3862
|
+
// Measure across the window when it holds a span of its own. With a single sample in it — a
|
|
3863
|
+
// pointer emitting moves slower than the window — reach back one sample for a baseline instead
|
|
3864
|
+
// of reporting nothing.
|
|
3865
|
+
const hasSpanInWindow = samples.length - firstInWindow >= 2;
|
|
3866
|
+
const baseline = samples[hasSpanInWindow ? firstInWindow : Math.max(0, firstInWindow - 1)];
|
|
3867
|
+
const elapsed = newest.t - baseline.t;
|
|
3868
|
+
if (elapsed <= 0)
|
|
3869
|
+
return { x: 0, y: 0 };
|
|
3870
|
+
return {
|
|
3871
|
+
x: ((newest.movementX - baseline.movementX) / elapsed) * 1000,
|
|
3872
|
+
y: ((newest.movementY - baseline.movementY) / elapsed) * 1000,
|
|
3873
|
+
};
|
|
3874
|
+
};
|
|
3611
3875
|
const end = () => {
|
|
3612
|
-
const swipeTime = Math.max(1, Date.now() - startTime);
|
|
3613
3876
|
const positiveMovementX = Math.abs(movementX);
|
|
3614
3877
|
const positiveMovementY = Math.abs(movementY);
|
|
3615
|
-
const pixelPerSecondX = (
|
|
3616
|
-
const pixelPerSecondY = (movementY / swipeTime) * 1000;
|
|
3878
|
+
const { x: pixelPerSecondX, y: pixelPerSecondY } = measureReleaseVelocity(Date.now());
|
|
3617
3879
|
return {
|
|
3618
3880
|
movementX,
|
|
3619
3881
|
movementY,
|
|
@@ -3630,6 +3892,7 @@ const createSwipeTracker = (startEvent) => {
|
|
|
3630
3892
|
const cancel = () => {
|
|
3631
3893
|
movementX = 0;
|
|
3632
3894
|
movementY = 0;
|
|
3895
|
+
samples = [{ t: Date.now(), movementX: 0, movementY: 0 }];
|
|
3633
3896
|
};
|
|
3634
3897
|
return { update, end, cancel };
|
|
3635
3898
|
};
|
|
@@ -3717,6 +3980,56 @@ const [provideLocale, injectLocale] = createRootProvider(() => {
|
|
|
3717
3980
|
name: 'Locale',
|
|
3718
3981
|
});
|
|
3719
3982
|
|
|
3983
|
+
const resolveSource = (source, locale) => typeof source === 'function' ? source(locale) : source;
|
|
3984
|
+
/**
|
|
3985
|
+
* The one mechanism for the strings a component renders or announces itself. Every domain in the UI
|
|
3986
|
+
* library that has such strings exposes exactly this pair — `provide<Domain>Labels` to localize a
|
|
3987
|
+
* subtree, `inject<Domain>Labels()` to read the result — so localizing an app is the same move
|
|
3988
|
+
* repeated per domain rather than a different one each time.
|
|
3989
|
+
*
|
|
3990
|
+
* `defaults` may itself be locale-derived, for a domain that ships more than one language (the
|
|
3991
|
+
* `@ethlete/query` error tables, say). Overrides are partial and layer on top of whatever the locale
|
|
3992
|
+
* resolved to, so translating into a third language while keeping a shipped one as the base is the
|
|
3993
|
+
* same call.
|
|
3994
|
+
*
|
|
3995
|
+
* The injector returns a **signal**, because both halves can change at runtime — read it in a
|
|
3996
|
+
* template or computed, never destructure it once.
|
|
3997
|
+
*
|
|
3998
|
+
* @example
|
|
3999
|
+
* export type BreadcrumbLabels = { navigation: string; overflow: string };
|
|
4000
|
+
*
|
|
4001
|
+
* export const DEFAULT_BREADCRUMB_LABELS: BreadcrumbLabels = {
|
|
4002
|
+
* navigation: 'Breadcrumb',
|
|
4003
|
+
* overflow: 'Show hidden levels',
|
|
4004
|
+
* };
|
|
4005
|
+
*
|
|
4006
|
+
* export const [provideBreadcrumbLabels, injectBreadcrumbLabels, BREADCRUMB_LABELS] =
|
|
4007
|
+
* createLabels<BreadcrumbLabels>('BREADCRUMB_LABELS', DEFAULT_BREADCRUMB_LABELS);
|
|
4008
|
+
*
|
|
4009
|
+
* @example
|
|
4010
|
+
* // consumer, fixed wording
|
|
4011
|
+
* provideBreadcrumbLabels({ navigation: 'Brotkrumen' });
|
|
4012
|
+
*
|
|
4013
|
+
* // consumer, driven by the app's i18n and re-resolved on a locale change
|
|
4014
|
+
* provideBreadcrumbLabels((locale) => ({ navigation: translate('breadcrumb.nav', locale) }));
|
|
4015
|
+
*/
|
|
4016
|
+
const createLabels = (name, defaults) => {
|
|
4017
|
+
const token = new InjectionToken(name, {
|
|
4018
|
+
providedIn: 'root',
|
|
4019
|
+
factory: () => ({}),
|
|
4020
|
+
});
|
|
4021
|
+
const provide = (labels) => ({ provide: token, useValue: labels });
|
|
4022
|
+
const injectFn = () => {
|
|
4023
|
+
const source = inject(token);
|
|
4024
|
+
const { currentLocale } = injectLocale();
|
|
4025
|
+
return computed(() => {
|
|
4026
|
+
const locale = currentLocale();
|
|
4027
|
+
return { ...resolveSource(defaults, locale), ...resolveSource(source, locale) };
|
|
4028
|
+
});
|
|
4029
|
+
};
|
|
4030
|
+
return [provide, injectFn, token];
|
|
4031
|
+
};
|
|
4032
|
+
|
|
3720
4033
|
const [provideStyleManager, injectStyleManager] = createRootProvider(() => {
|
|
3721
4034
|
const appRef = inject(ApplicationRef);
|
|
3722
4035
|
const destroyRef = inject(DestroyRef);
|
|
@@ -3799,8 +4112,23 @@ const fromNextFrame = () => {
|
|
|
3799
4112
|
});
|
|
3800
4113
|
});
|
|
3801
4114
|
};
|
|
3802
|
-
const forceReflow = (element
|
|
3803
|
-
|
|
4115
|
+
const forceReflow = (element) => {
|
|
4116
|
+
// The `document.body` fallback is resolved lazily and guarded: there is nothing to reflow on the
|
|
4117
|
+
// server, so this becomes a no-op instead of throwing on a missing `document`.
|
|
4118
|
+
const el = element ?? (typeof document === 'undefined' ? null : document.body);
|
|
4119
|
+
return el?.offsetHeight ?? 0;
|
|
4120
|
+
};
|
|
4121
|
+
/**
|
|
4122
|
+
* Whether the user asked for reduced motion, read straight from `matchMedia`.
|
|
4123
|
+
*
|
|
4124
|
+
* Inside a component, prefer the reactive `injectPrefersReducedMotion()`. This is for the animation
|
|
4125
|
+
* helpers that run from effects, event handlers and imperative APIs, where there is no injection
|
|
4126
|
+
* context. Pass the element being animated so the query resolves against its own window — otherwise
|
|
4127
|
+
* an animation inside an iframe would read the top-level document's preference.
|
|
4128
|
+
*/
|
|
4129
|
+
const matchesReducedMotion = (element) => {
|
|
4130
|
+
const view = element?.ownerDocument.defaultView ?? (typeof window === 'undefined' ? null : window);
|
|
4131
|
+
return view?.matchMedia('(prefers-reduced-motion: reduce)').matches ?? false;
|
|
3804
4132
|
};
|
|
3805
4133
|
|
|
3806
4134
|
const ANIMATED_LIFECYCLE_TOKEN = new InjectionToken('ANIMATED_LIFECYCLE_DIRECTIVE_TOKEN');
|
|
@@ -4489,11 +4817,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
4489
4817
|
}], ctorParameters: () => [], propDecorators: { placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], fallbackPlacements: [{ type: i0.Input, args: [{ isSignal: true, alias: "fallbackPlacements", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], arrowPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "arrowPadding", required: false }] }], viewportPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewportPadding", required: false }] }], autoResize: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoResize", required: false }] }], shift: [{ type: i0.Input, args: [{ isSignal: true, alias: "shift", required: false }] }], autoHide: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoHide", required: false }] }], autoCloseIfReferenceHidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCloseIfReferenceHidden", required: false }] }], referenceElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "referenceElement", required: false }] }], mirrorWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "mirrorWidth", required: false }] }] } });
|
|
4490
4818
|
|
|
4491
4819
|
const createFlipAnimationGroup = (config) => {
|
|
4492
|
-
const { elements, duration = 250, easing = 'cubic-bezier(0.4, 0, 0.2, 1)' } = config;
|
|
4820
|
+
const { elements, duration = 250, easing = 'cubic-bezier(0.4, 0, 0.2, 1)', ignoreReducedMotion } = config;
|
|
4493
4821
|
const flips = elements.map((el) => {
|
|
4494
4822
|
const element = 'element' in el ? el.element : el;
|
|
4495
4823
|
const originElement = 'originElement' in el ? el.originElement : undefined;
|
|
4496
|
-
return createFlipAnimation({ element, originElement, duration, easing });
|
|
4824
|
+
return createFlipAnimation({ element, originElement, duration, easing, ignoreReducedMotion });
|
|
4497
4825
|
});
|
|
4498
4826
|
const onStart$ = combineLatest(flips.map((animation) => animation.onStart$));
|
|
4499
4827
|
const onFinish$ = combineLatest(flips.map((animation) => animation.onFinish$));
|
|
@@ -4517,7 +4845,7 @@ const createFlipAnimationGroup = (config) => {
|
|
|
4517
4845
|
};
|
|
4518
4846
|
};
|
|
4519
4847
|
const createFlipAnimation = (config) => {
|
|
4520
|
-
const { element: el, originElement = el, duration = 250, easing = 'cubic-bezier(0.4, 0, 0.2, 1)' } = config;
|
|
4848
|
+
const { element: el, originElement = el, duration = 250, easing = 'cubic-bezier(0.4, 0, 0.2, 1)', ignoreReducedMotion = false, } = config;
|
|
4521
4849
|
let initialRect = originElement.getBoundingClientRect();
|
|
4522
4850
|
let animation = null;
|
|
4523
4851
|
const onStart$ = new Subject();
|
|
@@ -4549,6 +4877,10 @@ const createFlipAnimation = (config) => {
|
|
|
4549
4877
|
scaleX: initialRect.width / lastRect.width,
|
|
4550
4878
|
scaleY: initialRect.height / lastRect.height,
|
|
4551
4879
|
};
|
|
4880
|
+
// Under reduced motion the element jumps straight to its final position. Collapsing the duration
|
|
4881
|
+
// instead of bailing out keeps the `Animation` lifecycle intact, so callers that wait on
|
|
4882
|
+
// `onFinish$` to clean up still get their event.
|
|
4883
|
+
const effectiveDuration = !ignoreReducedMotion && matchesReducedMotion(el) ? 0 : duration;
|
|
4552
4884
|
animation = el.animate([
|
|
4553
4885
|
{
|
|
4554
4886
|
transformOrigin: 'top left',
|
|
@@ -4562,7 +4894,7 @@ const createFlipAnimation = (config) => {
|
|
|
4562
4894
|
transform: 'none',
|
|
4563
4895
|
},
|
|
4564
4896
|
], {
|
|
4565
|
-
duration,
|
|
4897
|
+
duration: effectiveDuration,
|
|
4566
4898
|
easing,
|
|
4567
4899
|
fill: 'both',
|
|
4568
4900
|
});
|
|
@@ -4776,6 +5108,20 @@ const setupDragObservable = (startEvent, el, commitThreshold) => {
|
|
|
4776
5108
|
}), takeUntil(end$));
|
|
4777
5109
|
return concat(moves$, defer(() => of(committed ? { type: 'end' } : { type: 'tapped' })));
|
|
4778
5110
|
};
|
|
5111
|
+
/**
|
|
5112
|
+
* Observe one drag gesture, starting from a `pointerdown` on `element`.
|
|
5113
|
+
*
|
|
5114
|
+
* Emits `start` once the pointer has travelled `commitThreshold` px (so a click is not a drag),
|
|
5115
|
+
* immediately followed by a catch-up `move`, then a `move` per pointer move, and finally `end`. A
|
|
5116
|
+
* pointer released before crossing the threshold emits a single `tapped` instead. The stream
|
|
5117
|
+
* completes with the gesture, so there is nothing to unsubscribe on the happy path.
|
|
5118
|
+
*
|
|
5119
|
+
* This is the primitive behind {@link DragHandleDirective}. Prefer the directive; reach for this when
|
|
5120
|
+
* the draggable element belongs to someone else's template (e.g. a table feature attaching a drag to
|
|
5121
|
+
* header cells the table itself renders) and you can only work from a delegated `pointerdown`.
|
|
5122
|
+
*/
|
|
5123
|
+
const dragGestureFrom = (event, element, options) => setupDragObservable(event, element, options?.commitThreshold ?? 8);
|
|
5124
|
+
|
|
4779
5125
|
class DragHandleDirective {
|
|
4780
5126
|
constructor() {
|
|
4781
5127
|
this.el = inject(ElementRef);
|
|
@@ -4783,7 +5129,7 @@ class DragHandleDirective {
|
|
|
4783
5129
|
...(ngDevMode ? [{ debugName: "commitThreshold" }] : /* istanbul ignore next */ []));
|
|
4784
5130
|
this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
4785
5131
|
this.gestureStart$ = new Subject();
|
|
4786
|
-
this.gesture$ = this.gestureStart$.pipe(exhaustMap((event) =>
|
|
5132
|
+
this.gesture$ = this.gestureStart$.pipe(exhaustMap((event) => dragGestureFrom(event, this.el.nativeElement, { commitThreshold: this.commitThreshold() })), takeUntilDestroyed(), share());
|
|
4787
5133
|
this.dragTapped = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'tapped'), map(() => undefined)));
|
|
4788
5134
|
this.dragStarted = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'start'), map((e) => e.data)));
|
|
4789
5135
|
this.dragMoved = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'move'), map((e) => e.data)));
|
|
@@ -5016,7 +5362,10 @@ const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, render
|
|
|
5016
5362
|
if (arrowElement) {
|
|
5017
5363
|
middleware.push(arrow({
|
|
5018
5364
|
element: arrowElement,
|
|
5019
|
-
|
|
5365
|
+
// keeps the arrow off a rounded pane corner by default: 12px covers the radius of the
|
|
5366
|
+
// built-in boxed panes (--et-overlay-radius). Panes with a larger radius have to pass their
|
|
5367
|
+
// own — an arrow whose base sits on the corner arc looks detached from the pane.
|
|
5368
|
+
padding: strategy.arrowPadding ?? 12,
|
|
5020
5369
|
}));
|
|
5021
5370
|
}
|
|
5022
5371
|
if (strategy.autoHide || strategy.autoCloseIfReferenceHidden) {
|
|
@@ -8257,5 +8606,5 @@ const createUnsavedChangesGuard = (config) => {
|
|
|
8257
8606
|
* Generated bundle index. Do not edit.
|
|
8258
8607
|
*/
|
|
8259
8608
|
|
|
8260
|
-
export { ANIMATABLE_TOKEN, ANIMATED_IF_TOKEN, ANIMATED_LIFECYCLE_TOKEN, ANIMATION_DEBUG_STORAGE_KEY, AT_LEAST_ONE_REQUIRED, AnimatableDirective, AnimatedIfDirective, AnimatedLifecycleDirective, AnimatedOverlayDirective, AutoSurfaceDirective, BOUNDARY_ELEMENT_TOKEN, BREAKPOINT_INSTANCE_TOKEN, BREAKPOINT_ORDER, COLOR_PROVIDER, ClickOutsideDirective, ColorInteractiveContainerDirective, ColorInteractiveDirective, ColorInteractiveExcludeDirective, ColorInteractiveHasFocusDirective, DEFAULT_MULTI_INSTANCE_RELS, DEFAULT_MULTI_INSTANCE_TAGS, DEFAULT_VIEWPORT_CONFIG, DISABLE_LOGGER_PARAM, DragHandleDirective, ET_DISABLE_SCROLL_TOP, ET_DISABLE_SCROLL_TOP_AS_RETURN_ROUTE, ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE, ET_PROPERTY_REMOVED, FOCUSABLE_SELECTOR, FOCUS_VISIBLE_TRACKER_TOKEN, HtmlToMarkdownPipe, IS_ARRAY_NOT_EMPTY, IS_EMAIL, InferMimeTypePipe, InitialsPipe, IsArrayNotEmpty, IsEmail, jsonLd as JsonLD, KeyPressManager, MUST_MATCH, MarkdownToHtmlPipe, MustMatch, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, PropsDirective, ProvideColorDirective, ProvideSurfaceDirective, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeHandlesComponent, RuntimeError, SEO_DIRECTIVE_TOKEN, SURFACE_PROVIDER, SURFACE_TYPE, ScrollObserverDirective, ScrollObserverEndDirective, ScrollObserverStartDirective, SeoDirective, SlugifyPipe, StructuredDataComponent, SurfaceInteractiveDirective, ToArrayPipe, TypedQueryList, ValidateAtLeastOneRequired, Validators, animationDebugLog, applyAlternateBinding, applyAlternateLanguagesBindings, applyArticleBindings, applyAuthorBinding, applyCanonicalBinding, applyCenteredPosition, applyDescriptionBinding, applyGlobalPosition, applyHeadBinding, applyHeadTitleBinding, applyHostListener, applyHostListeners, applyInitialFocus, applyKeywordsBinding, applyLinkBinding, applyMetaBinding, applyNextBinding, applyOgBinding, applyOpenGraphBindings, applyPrevBinding, applyResourceHintsBindings, applyRobotsBinding, applySocialMediaBindings, applyStructuredDataBinding, applyTwitterCardBindings, areScrollStatesEqual, bindProps, boolBreakpointTransform, booleanBreakpointAttribute, boundingClientRectToElementRect, breakpointTransformBase, buildElementSignal, buildSignalEffects, canUseSessionMemory, clamp, clone, cloneFormGroup, computedTillFalsy, computedTillTruthy, controlValueSignal, controlValueSignalWithPrevious, copyToClipboard, createAnchoredPositionCleanup, createArrayPropertyBinding, createAutoSessionMemoryKey, createBulkPropertyBinding, createCanAnimateSignal, createComponentId, createCssColorThemeName, createCssSurfaceName, createDependencyStash, createDestroy, createDocumentElementSignal, createElementDictionary, createElementDimensions, createEmptyElementSignal, createFlipAnimation, createFlipAnimationGroup, createHostProps, createIsRenderedSignal, createLogger, createOverlayRuntimeRef, createPropHandlers, createPropertyBinding, createProps, createProvider, createRootProvider, createRootThemeCss, createRoute, createRouterState, createRxHostListener, createSessionMemory, createSetup, createStaticProvider, createStaticRootProvider, createSwatchCss, createSwipeTracker, createTailwindColorThemes, createTailwindCssVar, createTailwindRgbVar, createThemeStyle, createUnsavedChangesGuard, createUnsavedChangesTracker, createUserConsentProvider, deferredSignal, deleteCookie, easeElastic, easeIn, easeInOut, easeLinear, easeOut, easeOutBack, easeOutBackStrong, elementCanScroll, equal, firstElementSignal, focusElement, forceReflow, formatRuntimeError, fromNextFrame, getCookie, getDomain, getElementScrollCoordinates, getFocusableElements, getFormGroupValue, getGroupMatchPoints, getGroupMatchScore, getHeadingElement, getKnockoutMatchScore, getMatchScoreSubLine, getObjectProperty, getScrollContainerTarget, getScrollItemTarget, getScrollSnapTarget, hasCookie, htmlToMarkdown, inferMimeType, initials, injectAngularRootElement, injectAnimatedBlockSize, injectBoundaryElement, injectBreakpointInput, injectBreakpointIsMatched, injectBreakpointObserver, injectCanHover, injectColorThemes, injectColorThemesPrefix, injectCurrentBreakpoint, injectDeviceInputType, injectDisplayOrientation, injectErrorTheme, injectFocusVisibleTracker, injectFragment, injectHasPrecisionInput, injectHasTouchInput, injectHostElement, injectIs2Xl, injectIsLandscape, injectIsLg, injectIsMd, injectIsPortrait, injectIsRouterInitialized, injectIsSm, injectIsXl, injectIsXs, injectLinkStore, injectLinkStoreConfig, injectLocale, injectMediaQueryIsMatched, injectMetaConfig, injectMetaStore, injectObserveBreakpoint, injectObserveMediaQuery, injectOverlayRuntime, injectPathParam, injectPathParamChanges, injectPathParams, injectPrefersReducedMotion, injectQueryParam, injectQueryParamChanges, injectQueryParams, injectRenderer, injectRoute, injectRouteData, injectRouteDataItem, injectRouteTitle, injectRouterEvent, injectRouterState, injectScrollbarDimensions, injectStructuredDataConfig, injectStructuredDataStore, injectStyleManager, injectSuccessTheme, injectSurfaceContextTracker, injectSurfaceThemes, injectSurfaceThemesPrefix, injectTemplateRef, injectTitleConfig, injectTitleStore, injectUrl, injectViewportConfig, injectViewportDimensions, injectViewportSize, injectWarningTheme, isAnimationDebugEnabled, isArray, isElementSignal, isElementVisible, isFocusable, isGroupMatch, isHTMLElement, isKnockoutMatch, isObject, markdownToHtml, maybeSignalValue, memoizeSignal, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, normalizeUnsavedChangesSource, numberBreakpointAttribute, numberBreakpointTransform, previousSignalValue, provideBoundaryElement, provideBreakpointInstance, provideBreakpointObserver, provideColorThemes, provideColorThemesWithTailwind4, provideFocusVisibleTracker, provideLinkStore, provideLinkStoreConfig, provideLocale, provideMetaConfig, provideMetaStore, provideOverlayRuntime, provideRenderer, provideStructuredDataConfig, provideStructuredDataStore, provideStyleManager, provideSurfaceContextTracker, provideSurfaceThemesWithTailwind4, provideTitleConfig, provideTitleStore, provideViewportConfig, randomId, readFromClipboard, resetPositioningStyles, resolveAppRootColorProvider, resolveSurfaceByElevation, round, routerDisableScrollTop, scrollToElement, setBackdropStyles, setBaseElementStyles, setCookie, setInputSignal, setupFocusTrap, setupPositioning, setupScrollRestoration, signalAnimatedNumber, signalAttributes, signalClasses, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementLastScrollDirection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementLastScrollDirection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, slugify, switchQueryListChanges, syncSignal, templateComputed, toArray, toArrayTrackByFn, toStringBinding, transformOrReturn, typedBreakpointTransform, unbindProps, useCursorDragScroll, writeScrollbarSizeToCssVariables, writeViewportSizeToCssVariables, ɵProvideColorThemes, ɵProvideColorThemesPrefix, ɵProvideSurfaceThemes, ɵProvideSurfaceThemesPrefix };
|
|
8609
|
+
export { ANIMATABLE_TOKEN, ANIMATED_IF_TOKEN, ANIMATED_LIFECYCLE_TOKEN, ANIMATION_DEBUG_STORAGE_KEY, AT_LEAST_ONE_REQUIRED, AnimatableDirective, AnimatedIfDirective, AnimatedLifecycleDirective, AnimatedOverlayDirective, AutoSurfaceDirective, BOUNDARY_ELEMENT_TOKEN, BREAKPOINT_INSTANCE_TOKEN, BREAKPOINT_ORDER, COLOR_PROVIDER, ClickOutsideDirective, ColorInteractiveContainerDirective, ColorInteractiveDirective, ColorInteractiveExcludeDirective, ColorInteractiveHasFocusDirective, DEFAULT_MULTI_INSTANCE_RELS, DEFAULT_MULTI_INSTANCE_TAGS, DEFAULT_VIEWPORT_CONFIG, DISABLE_LOGGER_PARAM, DragHandleDirective, ET_DISABLE_SCROLL_TOP, ET_DISABLE_SCROLL_TOP_AS_RETURN_ROUTE, ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE, ET_PROPERTY_REMOVED, FOCUSABLE_SELECTOR, FOCUS_VISIBLE_TRACKER_TOKEN, HtmlToMarkdownPipe, IS_ARRAY_NOT_EMPTY, IS_EMAIL, InferMimeTypePipe, InitialsPipe, IsArrayNotEmpty, IsEmail, jsonLd as JsonLD, KeyPressManager, MUST_MATCH, MarkdownToHtmlPipe, MustMatch, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, PropsDirective, ProvideColorDirective, ProvideSurfaceDirective, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeHandlesComponent, RuntimeError, SEO_DIRECTIVE_TOKEN, SURFACE_PROVIDER, SURFACE_TYPE, SWIPE_VELOCITY_WINDOW_MS, ScrollObserverDirective, ScrollObserverEndDirective, ScrollObserverStartDirective, SeoDirective, SlugifyPipe, StructuredDataComponent, SurfaceInteractiveDirective, ToArrayPipe, TypedQueryList, ValidateAtLeastOneRequired, Validators, animationDebugLog, applyAlternateBinding, applyAlternateLanguagesBindings, applyArticleBindings, applyAuthorBinding, applyCanonicalBinding, applyCenteredPosition, applyDescriptionBinding, applyGlobalPosition, applyHeadBinding, applyHeadTitleBinding, applyHostListener, applyHostListeners, applyInitialFocus, applyKeywordsBinding, applyLinkBinding, applyMetaBinding, applyNextBinding, applyOgBinding, applyOpenGraphBindings, applyPrevBinding, applyResourceHintsBindings, applyRobotsBinding, applySocialMediaBindings, applyStructuredDataBinding, applyTwitterCardBindings, areScrollStatesEqual, bindProps, boolBreakpointTransform, booleanBreakpointAttribute, boundingClientRectToElementRect, breakpointTransformBase, buildElementSignal, buildSignalEffects, canUseSessionMemory, clamp, clone, cloneFormGroup, computedTillFalsy, computedTillTruthy, controlValueSignal, controlValueSignalWithPrevious, copyToClipboard, createAnchoredPositionCleanup, createArrayPropertyBinding, createAutoSessionMemoryKey, createBulkPropertyBinding, createCanAnimateSignal, createComponentId, createCssColorThemeName, createCssSurfaceName, createDependencyStash, createDestroy, createDocumentElementSignal, createElementDictionary, createElementDimensions, createEmptyElementSignal, createFlipAnimation, createFlipAnimationGroup, createHostProps, createIsRenderedSignal, createLabels, createLogger, createOverlayRuntimeRef, createPropHandlers, createPropertyBinding, createProps, createProvider, createRootProvider, createRootThemeCss, createRoute, createRouterState, createRxHostListener, createSessionMemory, createSetup, createStaticProvider, createStaticRootProvider, createSwatchCss, createSwipeTracker, createTailwindColorThemes, createTailwindCssVar, createTailwindRgbVar, createThemeStyle, createUnsavedChangesGuard, createUnsavedChangesTracker, createUserConsentProvider, deferredSignal, deleteCookie, dragGestureFrom, easeElastic, easeIn, easeInOut, easeLinear, easeOut, easeOutBack, easeOutBackStrong, elementCanScroll, equal, firstElementSignal, focusElement, forceReflow, formatRuntimeError, fromNextFrame, getCookie, getDomain, getElementScrollCoordinates, getFocusableElements, getFormGroupValue, getGroupMatchPoints, getGroupMatchScore, getHeadingElement, getKnockoutMatchScore, getMatchScoreSubLine, getObjectProperty, getScrollContainerTarget, getScrollItemTarget, getScrollSnapTarget, hasCookie, holdScrollRestoration, htmlToMarkdown, inferMimeType, initials, injectAngularRootElement, injectAnimatedBlockSize, injectBoundaryElement, injectBreakpointInput, injectBreakpointIsMatched, injectBreakpointObserver, injectCanHover, injectColorThemes, injectColorThemesPrefix, injectCurrentBreakpoint, injectDeviceInputType, injectDisplayOrientation, injectErrorTheme, injectFocusVisibleTracker, injectFragment, injectHasPrecisionInput, injectHasTouchInput, injectHostElement, injectIs2Xl, injectIsDocumentVisible, injectIsLandscape, injectIsLg, injectIsMd, injectIsPortrait, injectIsRouterInitialized, injectIsSm, injectIsXl, injectIsXs, injectLinkStore, injectLinkStoreConfig, injectLocale, injectMediaQueryIsMatched, injectMetaConfig, injectMetaStore, injectObserveBreakpoint, injectObserveMediaQuery, injectOverlayRuntime, injectPathParam, injectPathParamChanges, injectPathParams, injectPrefersReducedMotion, injectQueryParam, injectQueryParamChanges, injectQueryParams, injectRenderer, injectRoute, injectRouteData, injectRouteDataItem, injectRouteTitle, injectRouterEvent, injectRouterNavigationState, injectRouterState, injectScrollbarDimensions, injectStructuredDataConfig, injectStructuredDataStore, injectStyleManager, injectSuccessTheme, injectSurfaceContextTracker, injectSurfaceThemes, injectSurfaceThemesPrefix, injectTemplateRef, injectTitleConfig, injectTitleStore, injectUrl, injectViewportConfig, injectViewportDimensions, injectViewportSize, injectWarningTheme, isAnimationDebugEnabled, isArray, isElementSignal, isElementVisible, isFocusable, isGroupMatch, isHTMLElement, isKnockoutMatch, isObject, markdownToHtml, matchesReducedMotion, maybeSignalValue, memoizeSignal, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, normalizeUnsavedChangesSource, numberBreakpointAttribute, numberBreakpointTransform, previousSignalValue, provideBoundaryElement, provideBreakpointInstance, provideBreakpointObserver, provideColorThemes, provideColorThemesWithTailwind4, provideFocusVisibleTracker, provideLinkStore, provideLinkStoreConfig, provideLocale, provideMetaConfig, provideMetaStore, provideOverlayRuntime, provideRenderer, provideStructuredDataConfig, provideStructuredDataStore, provideStyleManager, provideSurfaceContextTracker, provideSurfaceThemesWithTailwind4, provideTitleConfig, provideTitleStore, provideViewportConfig, randomId, readFromClipboard, resetPositioningStyles, resolveAppRootColorProvider, resolveSurfaceByElevation, round, routerDisableScrollTop, scrollToElement, setBackdropStyles, setBaseElementStyles, setCookie, setInputSignal, setupFocusTrap, setupPositioning, setupScrollRestoration, signalAnimatedNumber, signalAttributes, signalClasses, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementLastScrollDirection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementLastScrollDirection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, slugify, switchQueryListChanges, syncSignal, templateComputed, toArray, toArrayTrackByFn, toStringBinding, transformOrReturn, typedBreakpointTransform, unbindProps, useCursorDragScroll, writeScrollbarSizeToCssVariables, writeViewportSizeToCssVariables, ɵProvideColorThemes, ɵProvideColorThemesPrefix, ɵProvideSurfaceThemes, ɵProvideSurfaceThemesPrefix };
|
|
8261
8610
|
//# sourceMappingURL=ethlete-core.mjs.map
|