@ethlete/core 5.0.0-next.64 → 5.0.0-next.66
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 +26 -0
- package/design/interactive-styles.ts +5 -0
- package/design/theme-css.js +392 -0
- package/design/theme-css.ts +547 -0
- package/fesm2022/ethlete-core.mjs +528 -383
- package/fesm2022/ethlete-core.mjs.map +1 -1
- package/generators/tailwind-4-color-theme/generator.js +4 -187
- package/generators/tailwind-4-surface-theme/generator.js +4 -234
- package/package.json +16 -10
- package/src/lib/animations/easing-tokens-styles.component.css +155 -0
- package/src/lib/providers/visually-hidden-styles.component.css +13 -0
- package/src/lib/resize-handles/resize-handles.component.css +137 -0
- package/src/lib/theming/color-interactive-styles.component.css +147 -0
- package/src/lib/theming/surface-interactive-styles.component.css +42 -0
- package/types/ethlete-core.d.ts +58 -11
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { assertInInjectionContext, inject, DestroyRef, ElementRef, TemplateRef, InjectionToken, booleanAttribute, QueryList, RendererFactory2, RendererStyleFlags2, isSignal, DOCUMENT, signal, linkedSignal, isDevMode, computed, afterNextRender, effect, untracked, ApplicationRef, runInInjectionContext, NgZone, Injector, numberAttribute, PLATFORM_ID, afterRenderEffect, EnvironmentInjector, createComponent, ViewEncapsulation, Component, Directive, model, ViewContainerRef, input, CSP_NONCE, provideEnvironmentInitializer, output, createEnvironmentInjector, Pipe, makeEnvironmentProviders, afterEveryRender } from '@angular/core';
|
|
3
3
|
import { takeUntilDestroyed, toSignal, toObservable, outputFromObservable } from '@angular/core/rxjs-interop';
|
|
4
|
-
import { Subject, fromEvent, switchMap, startWith, of, defer, from, map, catchError, timer, takeUntil, tap, pairwise, debounceTime, merge, distinctUntilChanged, EMPTY, expand, skip, take, filter, BehaviorSubject, combineLatest, Observable,
|
|
4
|
+
import { Subject, fromEvent, switchMap, startWith, of, defer, from, map, catchError, timer, takeUntil, tap, pairwise, debounceTime, merge, distinctUntilChanged, EMPTY, expand, skip, take, filter, isObservable, ignoreElements, BehaviorSubject, combineLatest, Observable, firstValueFrom, defaultIfEmpty, concatMap, concat, finalize, exhaustMap, share, shareReplay, ReplaySubject } from 'rxjs';
|
|
5
5
|
import { FormGroup, FormArray, FormControl } from '@angular/forms';
|
|
6
6
|
import { SIGNAL, signalSetFn } from '@angular/core/primitives/signals';
|
|
7
|
-
import { isPlatformBrowser, Location, DOCUMENT as DOCUMENT$1 } from '@angular/common';
|
|
8
|
-
import { Router, NavigationEnd, NavigationSkipped, NavigationStart,
|
|
7
|
+
import { isPlatformBrowser, Location, DOCUMENT as DOCUMENT$1, isPlatformServer } from '@angular/common';
|
|
8
|
+
import { Router, NavigationEnd, NavigationCancel, NavigationError, NavigationSkipped, NavigationStart, RouterLink } from '@angular/router';
|
|
9
9
|
import { Title, Meta, DomSanitizer } from '@angular/platform-browser';
|
|
10
10
|
import { platform, offset, flip, shift, limitShift, computePosition, autoUpdate, hide, arrow, size } from '@floating-ui/dom';
|
|
11
11
|
|
|
@@ -2980,16 +2980,17 @@ const injectRouterEvent = /* @__PURE__ */ memoizeSignal(() => {
|
|
|
2980
2980
|
});
|
|
2981
2981
|
/**
|
|
2982
2982
|
* Signal that indicates whether the router has been initialized.
|
|
2983
|
-
*
|
|
2984
|
-
*
|
|
2983
|
+
* It turns true once the first navigation has ended (completed, was cancelled, failed or was skipped), so a
|
|
2984
|
+
* component created while the first navigation runs still sees `false`. Injected after that point, it is `true`
|
|
2985
|
+
* right away.
|
|
2985
2986
|
*/
|
|
2986
2987
|
const injectIsRouterInitialized = /* @__PURE__ */ memoizeSignal(() => {
|
|
2987
|
-
const
|
|
2988
|
-
const
|
|
2989
|
-
return
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2988
|
+
const router = inject(Router);
|
|
2989
|
+
const firstNavigationRunning = router.currentNavigation()?.id === 1;
|
|
2990
|
+
return toSignal(router.events.pipe(filter((e) => e instanceof NavigationEnd ||
|
|
2991
|
+
e instanceof NavigationCancel ||
|
|
2992
|
+
e instanceof NavigationError ||
|
|
2993
|
+
e instanceof NavigationSkipped), map(() => true)), { initialValue: router.navigated && !firstNavigationRunning });
|
|
2993
2994
|
});
|
|
2994
2995
|
/**
|
|
2995
2996
|
* Inject the current url.
|
|
@@ -3042,12 +3043,15 @@ const createRouterState = (router) => {
|
|
|
3042
3043
|
route = route.firstChild;
|
|
3043
3044
|
}
|
|
3044
3045
|
const { data, params, queryParams, title, fragment } = route;
|
|
3046
|
+
const navigation = router.currentNavigation();
|
|
3045
3047
|
return {
|
|
3046
3048
|
data,
|
|
3047
3049
|
pathParams: params,
|
|
3048
3050
|
queryParams,
|
|
3049
3051
|
title: title ?? null,
|
|
3050
3052
|
fragment,
|
|
3053
|
+
id: navigation?.id ?? null,
|
|
3054
|
+
trigger: navigation?.trigger ?? null,
|
|
3051
3055
|
};
|
|
3052
3056
|
};
|
|
3053
3057
|
/**
|
|
@@ -3069,14 +3073,20 @@ const readUncommittedUrl = (router, location) => {
|
|
|
3069
3073
|
: window.location.pathname + window.location.search + window.location.hash;
|
|
3070
3074
|
};
|
|
3071
3075
|
/**
|
|
3072
|
-
* Inject the complete router state. This includes the current route data, path params, query params, title and fragment
|
|
3076
|
+
* Inject the complete router state. This includes the current route data, path params, query params, title and fragment,
|
|
3077
|
+
* plus the `id` and `trigger` of the current navigation (the last one once it has ended).
|
|
3073
3078
|
*/
|
|
3074
3079
|
const injectRouterState = /* @__PURE__ */ memoizeSignal(() => {
|
|
3075
3080
|
const event = injectRouterEvent();
|
|
3076
3081
|
const router = inject(Router);
|
|
3082
|
+
const lastStart = toSignal(router.events.pipe(filter((e) => e instanceof NavigationStart), map((e) => ({ id: e.id, trigger: e.navigationTrigger ?? null }))), { initialValue: null });
|
|
3077
3083
|
return computed(() => {
|
|
3078
3084
|
event();
|
|
3079
|
-
|
|
3085
|
+
const state = createRouterState(router);
|
|
3086
|
+
if (state.id !== null)
|
|
3087
|
+
return state;
|
|
3088
|
+
const start = lastStart();
|
|
3089
|
+
return { ...state, id: start?.id ?? null, trigger: start?.trigger ?? null };
|
|
3080
3090
|
}, { equal });
|
|
3081
3091
|
});
|
|
3082
3092
|
/** Inject a signal containing the current route fragment (the part after the # inside the url if present) */
|
|
@@ -3264,7 +3274,32 @@ const ET_RESTORE_SCROLL = /* @__PURE__ */ Symbol('ET_RESTORE_SCROLL');
|
|
|
3264
3274
|
const routerRestoreScroll = () => ({ [ET_RESTORE_SCROLL]: true });
|
|
3265
3275
|
const SCROLL_RESTORATION_HOLDS_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
3266
3276
|
const holds = new Set();
|
|
3277
|
+
const states = new Set();
|
|
3267
3278
|
return {
|
|
3279
|
+
addState: (state) => {
|
|
3280
|
+
states.add(state);
|
|
3281
|
+
return () => states.delete(state);
|
|
3282
|
+
},
|
|
3283
|
+
saveStates: () => {
|
|
3284
|
+
if (!states.size)
|
|
3285
|
+
return undefined;
|
|
3286
|
+
const values = {};
|
|
3287
|
+
for (const state of states) {
|
|
3288
|
+
values[state.key] = state.save();
|
|
3289
|
+
}
|
|
3290
|
+
return values;
|
|
3291
|
+
},
|
|
3292
|
+
restoreStates: (values) => {
|
|
3293
|
+
const pending = [];
|
|
3294
|
+
for (const state of states) {
|
|
3295
|
+
if (!(state.key in values))
|
|
3296
|
+
continue;
|
|
3297
|
+
const result = state.restore(values[state.key]);
|
|
3298
|
+
if (isObservable(result))
|
|
3299
|
+
pending.push(result);
|
|
3300
|
+
}
|
|
3301
|
+
return pending;
|
|
3302
|
+
},
|
|
3268
3303
|
add: (isPending) => {
|
|
3269
3304
|
holds.add(isPending);
|
|
3270
3305
|
return () => holds.delete(isPending);
|
|
@@ -3299,12 +3334,55 @@ const holdScrollRestoration = (isPending) => {
|
|
|
3299
3334
|
const remove = injectScrollRestorationHolds().add(isPending);
|
|
3300
3335
|
inject(DestroyRef).onDestroy(remove);
|
|
3301
3336
|
};
|
|
3337
|
+
/**
|
|
3338
|
+
* Remember a piece of page state with the scroll entry, and restore it before the offset is applied -
|
|
3339
|
+
* the number of loaded pages of a paged list, for instance, without which the saved offset points at
|
|
3340
|
+
* the wrong items. Registers for the lifetime of the current injection context.
|
|
3341
|
+
*
|
|
3342
|
+
* Needs `restore.enabled` on {@link setupScrollRestoration}.
|
|
3343
|
+
*
|
|
3344
|
+
* @example
|
|
3345
|
+
* // inside a route component
|
|
3346
|
+
* registerScrollRestorationState({
|
|
3347
|
+
* key: 'pages',
|
|
3348
|
+
* save: () => pageCount(),
|
|
3349
|
+
* restore: (count) => loadPages$(count),
|
|
3350
|
+
* });
|
|
3351
|
+
*/
|
|
3352
|
+
const registerScrollRestorationState = (config) => {
|
|
3353
|
+
const remove = injectScrollRestorationHolds().addState(config);
|
|
3354
|
+
inject(DestroyRef).onDestroy(remove);
|
|
3355
|
+
};
|
|
3302
3356
|
/** Upper bound on remembered history entries. Each entry is a single number, so this is generous. */
|
|
3303
3357
|
const MAX_STORED_POSITIONS = 200;
|
|
3304
3358
|
const DEFAULT_RESTORE_TIMEOUT = 1000;
|
|
3305
3359
|
const DEFAULT_RESTORE_MAX_TIMEOUT = 10_000;
|
|
3306
3360
|
/** Events that mean the user took over scrolling, so a pending restoration must be abandoned. */
|
|
3307
3361
|
const INTERACTION_EVENTS = ['wheel', 'touchmove', 'keydown'];
|
|
3362
|
+
const RELOAD_STORAGE_KEY = 'et-scroll-restoration';
|
|
3363
|
+
const readReloadEntry = () => {
|
|
3364
|
+
try {
|
|
3365
|
+
const raw = sessionStorage.getItem(RELOAD_STORAGE_KEY);
|
|
3366
|
+
sessionStorage.removeItem(RELOAD_STORAGE_KEY);
|
|
3367
|
+
const entry = raw ? JSON.parse(raw) : null;
|
|
3368
|
+
return typeof entry?.top === 'number' && typeof entry.route === 'string' ? entry : null;
|
|
3369
|
+
}
|
|
3370
|
+
catch {
|
|
3371
|
+
return null;
|
|
3372
|
+
}
|
|
3373
|
+
};
|
|
3374
|
+
const writeReloadEntry = (entry) => {
|
|
3375
|
+
try {
|
|
3376
|
+
sessionStorage.setItem(RELOAD_STORAGE_KEY, JSON.stringify(entry));
|
|
3377
|
+
}
|
|
3378
|
+
catch {
|
|
3379
|
+
// Storage may be full or blocked (private mode); a reload then simply starts at the top.
|
|
3380
|
+
}
|
|
3381
|
+
};
|
|
3382
|
+
const isFreshNavigation = () => {
|
|
3383
|
+
const entry = performance.getEntriesByType?.('navigation')[0];
|
|
3384
|
+
return entry?.type === 'navigate';
|
|
3385
|
+
};
|
|
3308
3386
|
/** Key order is navigation order, not declaration order, so two spellings of one URL compare equal. */
|
|
3309
3387
|
const serializeQueryParams = (queryParams) => Object.keys(queryParams)
|
|
3310
3388
|
.sort()
|
|
@@ -3334,6 +3412,8 @@ const setupScrollRestoration = (config = {}) => {
|
|
|
3334
3412
|
const restoreTimeout = config.restore?.timeout ?? DEFAULT_RESTORE_TIMEOUT;
|
|
3335
3413
|
const restoreMaxTimeout = config.restore?.maxTimeout ?? DEFAULT_RESTORE_MAX_TIMEOUT;
|
|
3336
3414
|
const clampOnTimeout = config.restore?.clampOnTimeout ?? true;
|
|
3415
|
+
const restoreOnReload = restoreEnabled && config.restore?.restoreOnReload === true;
|
|
3416
|
+
let reloadEntry = restoreOnReload && !isFreshNavigation() ? readReloadEntry() : null;
|
|
3337
3417
|
const resolveScrollElement = () => {
|
|
3338
3418
|
const el = typeof config.scrollElement === 'function' ? config.scrollElement() : config.scrollElement;
|
|
3339
3419
|
return el ?? document.documentElement;
|
|
@@ -3362,11 +3442,22 @@ const setupScrollRestoration = (config = {}) => {
|
|
|
3362
3442
|
pendingRestore?.();
|
|
3363
3443
|
pendingRestore = null;
|
|
3364
3444
|
};
|
|
3365
|
-
const
|
|
3445
|
+
const captureEntry = () => ({
|
|
3446
|
+
top: resolveScrollElement().scrollTop,
|
|
3447
|
+
route: prev.route,
|
|
3448
|
+
search: serializeQueryParams(prev.state.queryParams),
|
|
3449
|
+
state: holds.saveStates(),
|
|
3450
|
+
});
|
|
3451
|
+
const scheduleRestore = (entry) => {
|
|
3366
3452
|
cancelPendingRestore();
|
|
3453
|
+
const target = entry.top;
|
|
3367
3454
|
let frame = 0;
|
|
3368
3455
|
let started = false;
|
|
3369
3456
|
let cancelled = false;
|
|
3457
|
+
let renderRef = null;
|
|
3458
|
+
let fallback;
|
|
3459
|
+
let stateSubscription = null;
|
|
3460
|
+
let stateDeadline;
|
|
3370
3461
|
// The user scrolling always wins over a restoration we have not committed yet.
|
|
3371
3462
|
const abortByUser = () => cancelPendingRestore();
|
|
3372
3463
|
const hardDeadline = Date.now() + restoreMaxTimeout;
|
|
@@ -3406,8 +3497,14 @@ const setupScrollRestoration = (config = {}) => {
|
|
|
3406
3497
|
started = true;
|
|
3407
3498
|
frame = requestAnimationFrame(step);
|
|
3408
3499
|
};
|
|
3409
|
-
const
|
|
3410
|
-
|
|
3500
|
+
const waitForRender = () => {
|
|
3501
|
+
if (cancelled)
|
|
3502
|
+
return;
|
|
3503
|
+
clearTimeout(stateDeadline);
|
|
3504
|
+
renderRef = afterNextRender({ read: start }, { injector });
|
|
3505
|
+
fallback = setTimeout(start);
|
|
3506
|
+
};
|
|
3507
|
+
const pendingStates = entry.state ? holds.restoreStates(entry.state) : [];
|
|
3411
3508
|
for (const eventName of INTERACTION_EVENTS) {
|
|
3412
3509
|
document.addEventListener(eventName, abortByUser, { capture: true, passive: true });
|
|
3413
3510
|
}
|
|
@@ -3415,7 +3512,9 @@ const setupScrollRestoration = (config = {}) => {
|
|
|
3415
3512
|
// `cancelled` is not redundant with destroying the render hook: a superseded restoration must
|
|
3416
3513
|
// not apply its (now stale) offset even if its hook had already been queued to run.
|
|
3417
3514
|
cancelled = true;
|
|
3418
|
-
renderRef
|
|
3515
|
+
renderRef?.destroy();
|
|
3516
|
+
stateSubscription?.unsubscribe();
|
|
3517
|
+
clearTimeout(stateDeadline);
|
|
3419
3518
|
if (frame)
|
|
3420
3519
|
cancelAnimationFrame(frame);
|
|
3421
3520
|
clearTimeout(fallback);
|
|
@@ -3423,13 +3522,22 @@ const setupScrollRestoration = (config = {}) => {
|
|
|
3423
3522
|
document.removeEventListener(eventName, abortByUser, { capture: true });
|
|
3424
3523
|
}
|
|
3425
3524
|
};
|
|
3525
|
+
if (pendingStates.length) {
|
|
3526
|
+
stateDeadline = setTimeout(cancelPendingRestore, restoreMaxTimeout);
|
|
3527
|
+
stateSubscription = merge(...pendingStates)
|
|
3528
|
+
.pipe(ignoreElements())
|
|
3529
|
+
.subscribe({ complete: waitForRender, error: waitForRender });
|
|
3530
|
+
}
|
|
3531
|
+
else {
|
|
3532
|
+
waitForRender();
|
|
3533
|
+
}
|
|
3426
3534
|
};
|
|
3427
3535
|
/**
|
|
3428
3536
|
* The offset the most recently left entry for this page had. A target without query params means
|
|
3429
3537
|
* "that page", whichever query state it was last in - the crumb linking to an overview does not
|
|
3430
3538
|
* know, and should not have to reproduce, the filter the user left it under.
|
|
3431
3539
|
*/
|
|
3432
|
-
const
|
|
3540
|
+
const findLastVisitedEntry = (route, search) => {
|
|
3433
3541
|
const entries = [...positions.values()];
|
|
3434
3542
|
for (let i = entries.length - 1; i >= 0; i--) {
|
|
3435
3543
|
const entry = entries[i];
|
|
@@ -3437,7 +3545,7 @@ const setupScrollRestoration = (config = {}) => {
|
|
|
3437
3545
|
continue;
|
|
3438
3546
|
if (search && entry.search !== search)
|
|
3439
3547
|
continue;
|
|
3440
|
-
return entry
|
|
3548
|
+
return entry;
|
|
3441
3549
|
}
|
|
3442
3550
|
return undefined;
|
|
3443
3551
|
};
|
|
@@ -3450,11 +3558,7 @@ const setupScrollRestoration = (config = {}) => {
|
|
|
3450
3558
|
// what `findLastVisitedOffset` walks backwards and what the cap below evicts from.
|
|
3451
3559
|
if (lastNavigationId !== null) {
|
|
3452
3560
|
positions.delete(lastNavigationId);
|
|
3453
|
-
positions.set(lastNavigationId,
|
|
3454
|
-
top: resolveScrollElement().scrollTop,
|
|
3455
|
-
route: prev.route,
|
|
3456
|
-
search: serializeQueryParams(prev.state.queryParams),
|
|
3457
|
-
});
|
|
3561
|
+
positions.set(lastNavigationId, captureEntry());
|
|
3458
3562
|
}
|
|
3459
3563
|
if (positions.size > MAX_STORED_POSITIONS) {
|
|
3460
3564
|
const oldest = positions.keys().next();
|
|
@@ -3482,7 +3586,9 @@ const setupScrollRestoration = (config = {}) => {
|
|
|
3482
3586
|
const didFragmentChange = prevState.fragment !== currState.fragment;
|
|
3483
3587
|
prev = curr;
|
|
3484
3588
|
const wasMarkedAsReturn = wantsRestore;
|
|
3589
|
+
const reloaded = reloadEntry;
|
|
3485
3590
|
wantsRestore = false;
|
|
3591
|
+
reloadEntry = null;
|
|
3486
3592
|
if (event instanceof NavigationEnd) {
|
|
3487
3593
|
lastNavigationId = event.id;
|
|
3488
3594
|
}
|
|
@@ -3496,17 +3602,24 @@ const setupScrollRestoration = (config = {}) => {
|
|
|
3496
3602
|
// The saved offset wins over both scroll to top and fragment scrolling: the user may well have
|
|
3497
3603
|
// scrolled away from the anchor before leaving the page.
|
|
3498
3604
|
if (target !== undefined) {
|
|
3499
|
-
scheduleRestore(target
|
|
3605
|
+
scheduleRestore(target);
|
|
3500
3606
|
return;
|
|
3501
3607
|
}
|
|
3502
3608
|
}
|
|
3503
3609
|
if (restoreEnabled && wasMarkedAsReturn) {
|
|
3504
|
-
const target =
|
|
3610
|
+
const target = findLastVisitedEntry(curr.route, serializeQueryParams(currState.queryParams));
|
|
3505
3611
|
if (target !== undefined) {
|
|
3506
3612
|
scheduleRestore(target);
|
|
3507
3613
|
return;
|
|
3508
3614
|
}
|
|
3509
3615
|
}
|
|
3616
|
+
if (reloaded &&
|
|
3617
|
+
event instanceof NavigationEnd &&
|
|
3618
|
+
reloaded.route === curr.route &&
|
|
3619
|
+
reloaded.search === serializeQueryParams(currState.queryParams)) {
|
|
3620
|
+
scheduleRestore(reloaded);
|
|
3621
|
+
return;
|
|
3622
|
+
}
|
|
3510
3623
|
if (sameUrlNavigation) {
|
|
3511
3624
|
const allQueryParams = [
|
|
3512
3625
|
...new Set(Object.keys(prevState.queryParams).concat(Object.keys(currState.queryParams))),
|
|
@@ -3548,8 +3661,13 @@ const setupScrollRestoration = (config = {}) => {
|
|
|
3548
3661
|
onNavigationEnd(event);
|
|
3549
3662
|
}), takeUntilDestroyed())
|
|
3550
3663
|
.subscribe();
|
|
3664
|
+
const onPageHide = () => writeReloadEntry(captureEntry());
|
|
3665
|
+
if (restoreOnReload) {
|
|
3666
|
+
window.addEventListener('pagehide', onPageHide);
|
|
3667
|
+
}
|
|
3551
3668
|
destroyRef.onDestroy(() => {
|
|
3552
3669
|
cancelPendingRestore();
|
|
3670
|
+
window.removeEventListener('pagehide', onPageHide);
|
|
3553
3671
|
if (restoreEnabled && previousScrollRestoration !== null) {
|
|
3554
3672
|
history.scrollRestoration = previousScrollRestoration;
|
|
3555
3673
|
}
|
|
@@ -4549,17 +4667,15 @@ const provideFocusVisibleTracker = /* @__PURE__ */ toProvideFn(FOCUS_VISIBLE_TRA
|
|
|
4549
4667
|
const injectFocusVisibleTracker = /* @__PURE__ */ toInjectFn(FOCUS_VISIBLE_TRACKER_DEF);
|
|
4550
4668
|
const FOCUS_VISIBLE_TRACKER_TOKEN = /* @__PURE__ */ toToken(FOCUS_VISIBLE_TRACKER_DEF);
|
|
4551
4669
|
|
|
4552
|
-
const
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
return {
|
|
4556
|
-
currentLocale,
|
|
4557
|
-
};
|
|
4558
|
-
}, {
|
|
4559
|
-
name: 'Locale',
|
|
4670
|
+
const LOCALE = /* @__PURE__ */ new InjectionToken('Locale', {
|
|
4671
|
+
providedIn: 'root',
|
|
4672
|
+
factory: () => ({ currentLocale: signal('en') }),
|
|
4560
4673
|
});
|
|
4561
|
-
|
|
4562
|
-
const
|
|
4674
|
+
/** Provides the app locale, starting at `locale` (default `'en'`). Change it later with `injectLocale().currentLocale.set(...)`. */
|
|
4675
|
+
const provideLocale = (locale) => [
|
|
4676
|
+
{ provide: LOCALE, useFactory: () => ({ currentLocale: signal(locale ?? 'en') }) },
|
|
4677
|
+
];
|
|
4678
|
+
const injectLocale = () => inject(LOCALE);
|
|
4563
4679
|
|
|
4564
4680
|
const resolveSource = (source, locale) => typeof source === 'function' ? source(locale) : source;
|
|
4565
4681
|
/**
|
|
@@ -4634,7 +4750,8 @@ const STYLE_MANAGER_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
|
4634
4750
|
const nextContainer = renderer.createElement('div');
|
|
4635
4751
|
renderer.addClass(nextContainer, 'et-style-manager');
|
|
4636
4752
|
renderer.setAttribute(nextContainer, 'aria-hidden', 'true');
|
|
4637
|
-
|
|
4753
|
+
// A style attribute needs 'unsafe-inline' in a CSP's style-src-attr; a nonce does not cover it.
|
|
4754
|
+
renderer.setAttribute(nextContainer, 'hidden', '');
|
|
4638
4755
|
renderer.appendChild(getContainerParent(), nextContainer);
|
|
4639
4756
|
container = nextContainer;
|
|
4640
4757
|
return nextContainer;
|
|
@@ -8016,6 +8133,8 @@ let middlewareExtras = null;
|
|
|
8016
8133
|
const registerAnchoredPositionMiddlewareExtras = (extras) => {
|
|
8017
8134
|
middlewareExtras = extras;
|
|
8018
8135
|
};
|
|
8136
|
+
/** Whether `enableAnchoredOverlayPositionExtras()` has run, so `arrow`, `autoResize` and `autoHide` take effect. */
|
|
8137
|
+
const hasAnchoredOverlayPositionExtras = () => middlewareExtras !== null;
|
|
8019
8138
|
const requireMiddlewareExtras = (feature) => {
|
|
8020
8139
|
if (!middlewareExtras && isDevMode()) {
|
|
8021
8140
|
console.error(`An anchored overlay uses "${feature}", but the matching floating-ui middleware is not installed. Call \`enableAnchoredOverlayPositionExtras()\` from @ethlete/core once during app setup.`);
|
|
@@ -8135,11 +8254,14 @@ const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, render
|
|
|
8135
8254
|
if (strategy.minAvailableSpace !== undefined && !strategy.autoResize && isDevMode()) {
|
|
8136
8255
|
console.error('An anchored overlay sets `minAvailableSpace` without `autoResize`, so it is kept on a side it does not fit on with nothing capping it to the space there. Enable `autoResize` or drop `minAvailableSpace`.');
|
|
8137
8256
|
}
|
|
8257
|
+
// A width the pane declares through `--et-overlay-width` must survive positioning, and the pane
|
|
8258
|
+
// has to be measured at it - the variable may be set only after this runs.
|
|
8259
|
+
const declaredWidth = () => paneElement.style.getPropertyValue('--et-overlay-width') || null;
|
|
8138
8260
|
renderer.setStyle(paneElement, {
|
|
8139
8261
|
position: 'absolute',
|
|
8140
8262
|
top: '0',
|
|
8141
8263
|
left: '0',
|
|
8142
|
-
width: mirrorWidthElement ? `${mirrorWidthElement.offsetWidth}px` : 'max-content',
|
|
8264
|
+
width: mirrorWidthElement ? `${mirrorWidthElement.offsetWidth}px` : 'var(--et-overlay-width, max-content)',
|
|
8143
8265
|
});
|
|
8144
8266
|
/**
|
|
8145
8267
|
* What to do when the reference is not somewhere the pane can be positioned against: either removed
|
|
@@ -8253,7 +8375,7 @@ const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, render
|
|
|
8253
8375
|
}
|
|
8254
8376
|
renderer.setStyle(paneElement, {
|
|
8255
8377
|
transform: `translate3d(${x}px, ${y}px, 0)`,
|
|
8256
|
-
width: mirrorWidthElement ? `${mirrorWidthElement.offsetWidth}px` :
|
|
8378
|
+
width: mirrorWidthElement ? `${mirrorWidthElement.offsetWidth}px` : declaredWidth(),
|
|
8257
8379
|
visibility: null,
|
|
8258
8380
|
});
|
|
8259
8381
|
// exposed so animations can compose their transforms with the anchored position
|
|
@@ -9694,6 +9816,152 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
|
|
|
9694
9816
|
}], ctorParameters: () => [] });
|
|
9695
9817
|
|
|
9696
9818
|
const COLOR_SCHEME_TYPE = new InjectionToken('ColorSchemeType');
|
|
9819
|
+
/** True while the scheme is only known to CSS: a server render in `system` mode with a default per surface type. */
|
|
9820
|
+
const COLOR_SCHEME_UNRESOLVED = new InjectionToken('ColorSchemeUnresolved');
|
|
9821
|
+
|
|
9822
|
+
const COLOR_PROVIDER = new InjectionToken('ColorProvider');
|
|
9823
|
+
/**
|
|
9824
|
+
* The color provider attached to a bootstrapped root component (e.g. `ProvideColorDirective` in
|
|
9825
|
+
* the app component's `hostDirectives`), if any. Detached DOM such as overlay panes can't reach
|
|
9826
|
+
* it through element DI, so overlay containers fall back to this when resolving the provider to
|
|
9827
|
+
* `syncWithProvider()` - resolve at sync time, not at injection time, since root components only
|
|
9828
|
+
* register with `ApplicationRef` once bootstrap completes.
|
|
9829
|
+
*/
|
|
9830
|
+
const resolveAppRootColorProvider = (appRef) => {
|
|
9831
|
+
for (const componentRef of appRef.components) {
|
|
9832
|
+
const provider = componentRef.injector.get(COLOR_PROVIDER, null);
|
|
9833
|
+
if (provider) {
|
|
9834
|
+
return provider;
|
|
9835
|
+
}
|
|
9836
|
+
}
|
|
9837
|
+
return null;
|
|
9838
|
+
};
|
|
9839
|
+
const FORCED_COLOR_UNSET = /* @__PURE__ */ Symbol('FORCED_COLOR_UNSET');
|
|
9840
|
+
const appsWarnedAboutMissingThemes = /* @__PURE__ */ new WeakSet();
|
|
9841
|
+
class ProvideColorDirective {
|
|
9842
|
+
constructor() {
|
|
9843
|
+
this.themes = injectColorThemes({ optional: true });
|
|
9844
|
+
this.prefix = injectColorThemesPrefix({ optional: true });
|
|
9845
|
+
this.injector = inject(Injector);
|
|
9846
|
+
this.rootSurfaceTheme = injectRootSurfaceTheme();
|
|
9847
|
+
this.parentProvider = inject(COLOR_PROVIDER, { optional: true, skipSelf: true });
|
|
9848
|
+
this.appRef = inject(ApplicationRef);
|
|
9849
|
+
this.currentProviderSync = null;
|
|
9850
|
+
this.forcedColor = signal(FORCED_COLOR_UNSET, /* @ts-ignore */
|
|
9851
|
+
...(ngDevMode ? [{ debugName: "forcedColor" }] : /* istanbul ignore next */ []));
|
|
9852
|
+
this.color = input(undefined, { ...(ngDevMode ? { debugName: "color" } : /* istanbul ignore next */ {}), alias: 'etProvideColor' });
|
|
9853
|
+
this.effectiveColor = computed(() => {
|
|
9854
|
+
const forcedColor = this.forcedColor();
|
|
9855
|
+
if (forcedColor !== FORCED_COLOR_UNSET) {
|
|
9856
|
+
return forcedColor;
|
|
9857
|
+
}
|
|
9858
|
+
return this.color();
|
|
9859
|
+
}, /* @ts-ignore */
|
|
9860
|
+
...(ngDevMode ? [{ debugName: "effectiveColor" }] : /* istanbul ignore next */ []));
|
|
9861
|
+
/**
|
|
9862
|
+
* The color that actually applies at this provider's location: its own effective color, or -
|
|
9863
|
+
* when this provider is passive (no input, nothing forced) - the nearest ancestor provider's.
|
|
9864
|
+
* Mirrors the CSS cascade, which falls through a provider's `-color--inherited` scope class;
|
|
9865
|
+
* consumers that re-apply context across detached DOM (overlay panes) must use this instead
|
|
9866
|
+
* of `effectiveColor` or a passive in-between provider (e.g. a form field's) erases the theme.
|
|
9867
|
+
*/
|
|
9868
|
+
this.resolvedColor = computed(() => {
|
|
9869
|
+
const own = this.effectiveColor();
|
|
9870
|
+
const ownName = typeof own === 'object' && own !== null ? own.name : own;
|
|
9871
|
+
if (ownName) {
|
|
9872
|
+
return own;
|
|
9873
|
+
}
|
|
9874
|
+
return this.parentProvider?.resolvedColor();
|
|
9875
|
+
}, /* @ts-ignore */
|
|
9876
|
+
...(ngDevMode ? [{ debugName: "resolvedColor" }] : /* istanbul ignore next */ []));
|
|
9877
|
+
this.colorName = computed(() => {
|
|
9878
|
+
const raw = this.effectiveColor();
|
|
9879
|
+
const value = typeof raw === 'object' && raw !== null ? raw.name : raw;
|
|
9880
|
+
if (value === SURFACE_COLOR)
|
|
9881
|
+
return SURFACE_COLOR;
|
|
9882
|
+
if (!value)
|
|
9883
|
+
return;
|
|
9884
|
+
if (!this.themes) {
|
|
9885
|
+
if (isDevMode() && !appsWarnedAboutMissingThemes.has(this.appRef)) {
|
|
9886
|
+
appsWarnedAboutMissingThemes.add(this.appRef);
|
|
9887
|
+
console.warn(`etProvideColor="${value}" has no effect because no color themes are registered. Please make sure to add provideColorThemesWithTailwind4()`);
|
|
9888
|
+
}
|
|
9889
|
+
return;
|
|
9890
|
+
}
|
|
9891
|
+
if (isDevMode() && !this.themes.some((theme) => theme.name === value)) {
|
|
9892
|
+
console.error(`Theme ${value} does not exist. Please make sure to add it to provideColorThemesWithTailwind4()`);
|
|
9893
|
+
}
|
|
9894
|
+
return createCssColorThemeName(value);
|
|
9895
|
+
}, /* @ts-ignore */
|
|
9896
|
+
...(ngDevMode ? [{ debugName: "colorName" }] : /* istanbul ignore next */ []));
|
|
9897
|
+
this.paintedColorName = computed(() => {
|
|
9898
|
+
const raw = this.effectiveColor();
|
|
9899
|
+
const value = typeof raw === 'object' && raw !== null ? raw.name : raw;
|
|
9900
|
+
if (!this.colorName() || !value)
|
|
9901
|
+
return;
|
|
9902
|
+
const surface = this.injector.get(SURFACE_PROVIDER, null)?.activeTheme() ?? this.rootSurfaceTheme();
|
|
9903
|
+
const variant = resolveColorThemeVariant(surface, value, this.themes);
|
|
9904
|
+
if (variant === value)
|
|
9905
|
+
return this.colorName();
|
|
9906
|
+
if (isDevMode() && !this.themes?.some((theme) => theme.name === variant)) {
|
|
9907
|
+
console.error(`Surface theme ${surface?.name} names the color theme ${variant}, which does not exist. Please make sure to add it to provideColorThemesWithTailwind4()`);
|
|
9908
|
+
}
|
|
9909
|
+
return createCssColorThemeName(variant);
|
|
9910
|
+
}, /* @ts-ignore */
|
|
9911
|
+
...(ngDevMode ? [{ debugName: "paintedColorName" }] : /* istanbul ignore next */ []));
|
|
9912
|
+
this.themeClass = computed(() => {
|
|
9913
|
+
const prefix = this.prefix || 'et';
|
|
9914
|
+
const name = this.paintedColorName();
|
|
9915
|
+
return name ? `${prefix}-color--${name}` : `${prefix}-color--inherited`;
|
|
9916
|
+
}, /* @ts-ignore */
|
|
9917
|
+
...(ngDevMode ? [{ debugName: "themeClass" }] : /* istanbul ignore next */ []));
|
|
9918
|
+
}
|
|
9919
|
+
syncWithProvider(provider) {
|
|
9920
|
+
this.currentProviderSync?.destroy();
|
|
9921
|
+
runInInjectionContext(this.injector, () => {
|
|
9922
|
+
this.currentProviderSync = effect(() => {
|
|
9923
|
+
const provideColor = provider.resolvedColor();
|
|
9924
|
+
untracked(() => {
|
|
9925
|
+
if (provideColor === undefined) {
|
|
9926
|
+
this.clearForcedColor();
|
|
9927
|
+
return;
|
|
9928
|
+
}
|
|
9929
|
+
this.forceColor(provideColor);
|
|
9930
|
+
});
|
|
9931
|
+
}, /* @ts-ignore */
|
|
9932
|
+
...(ngDevMode ? [{ debugName: "currentProviderSync" }] : /* istanbul ignore next */ []));
|
|
9933
|
+
});
|
|
9934
|
+
}
|
|
9935
|
+
stopSyncWithProvider() {
|
|
9936
|
+
const hadProviderSync = !!this.currentProviderSync;
|
|
9937
|
+
this.currentProviderSync?.destroy();
|
|
9938
|
+
this.currentProviderSync = null;
|
|
9939
|
+
if (hadProviderSync) {
|
|
9940
|
+
this.clearForcedColor();
|
|
9941
|
+
}
|
|
9942
|
+
}
|
|
9943
|
+
forceColor(color) {
|
|
9944
|
+
this.forcedColor.set(color);
|
|
9945
|
+
}
|
|
9946
|
+
clearForcedColor() {
|
|
9947
|
+
if (this.forcedColor() === FORCED_COLOR_UNSET) {
|
|
9948
|
+
return;
|
|
9949
|
+
}
|
|
9950
|
+
this.forcedColor.set(FORCED_COLOR_UNSET);
|
|
9951
|
+
}
|
|
9952
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ProvideColorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
9953
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.6", type: ProvideColorDirective, isStandalone: true, selector: "[etProvideColor]", inputs: { color: { classPropertyName: "color", publicName: "etProvideColor", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "themeClass()" } }, providers: [{ provide: COLOR_PROVIDER, useExisting: ProvideColorDirective }], ngImport: i0 }); }
|
|
9954
|
+
}
|
|
9955
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ProvideColorDirective, decorators: [{
|
|
9956
|
+
type: Directive,
|
|
9957
|
+
args: [{
|
|
9958
|
+
selector: '[etProvideColor]',
|
|
9959
|
+
providers: [{ provide: COLOR_PROVIDER, useExisting: ProvideColorDirective }],
|
|
9960
|
+
host: {
|
|
9961
|
+
'[class]': 'themeClass()',
|
|
9962
|
+
},
|
|
9963
|
+
}]
|
|
9964
|
+
}], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "etProvideColor", required: false }] }] } });
|
|
9697
9965
|
|
|
9698
9966
|
const TOLERANCE_PX = 0.5;
|
|
9699
9967
|
const readFontSizePx = (view, element) => {
|
|
@@ -9795,348 +10063,6 @@ const injectDefaultSurfaceTheme = (type) => {
|
|
|
9795
10063
|
return defaults.length === 1 ? (defaults[0] ?? null) : null;
|
|
9796
10064
|
};
|
|
9797
10065
|
|
|
9798
|
-
const findRootSurfaceTheme = (defaults, type) => {
|
|
9799
|
-
if (defaults.length <= 1)
|
|
9800
|
-
return defaults[0] ?? null;
|
|
9801
|
-
return defaults.find((theme) => theme.type === type) ?? null;
|
|
9802
|
-
};
|
|
9803
|
-
const COLOR_SCHEME_DEF = /* @__PURE__ */ defineProvider(() => {
|
|
9804
|
-
const root = inject(DOCUMENT).documentElement;
|
|
9805
|
-
const prefix = injectSurfaceThemesPrefix({ optional: true }) || 'et';
|
|
9806
|
-
const prefersDark = injectBreakpointObserver().observeMediaQuery('(prefers-color-scheme: dark)');
|
|
9807
|
-
const mode = signal('system', /* @ts-ignore */
|
|
9808
|
-
...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
9809
|
-
const surfaceDefaults = injectSurfaceThemes({ optional: true })?.filter((theme) => theme.isDefault) ?? [];
|
|
9810
|
-
const colorThemes = injectColorThemes({ optional: true });
|
|
9811
|
-
const colorPrefix = injectColorThemesPrefix({ optional: true }) || 'et';
|
|
9812
|
-
const type = computed(() => {
|
|
9813
|
-
const current = mode();
|
|
9814
|
-
if (current !== 'system')
|
|
9815
|
-
return current;
|
|
9816
|
-
return prefersDark() ? 'dark' : 'light';
|
|
9817
|
-
}, /* @ts-ignore */
|
|
9818
|
-
...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
9819
|
-
const rootSurface = computed(() => findRootSurfaceTheme(surfaceDefaults, type()), /* @ts-ignore */
|
|
9820
|
-
...(ngDevMode ? [{ debugName: "rootSurface" }] : /* istanbul ignore next */ []));
|
|
9821
|
-
const rootColorClass = computed(() => {
|
|
9822
|
-
const chosen = colorThemes?.find((theme) => theme.isDefault)?.name;
|
|
9823
|
-
if (!chosen)
|
|
9824
|
-
return null;
|
|
9825
|
-
const variant = resolveColorThemeVariant(rootSurface(), chosen, colorThemes);
|
|
9826
|
-
return variant === chosen ? null : `${colorPrefix}-color--${createCssColorThemeName(variant)}`;
|
|
9827
|
-
}, /* @ts-ignore */
|
|
9828
|
-
...(ngDevMode ? [{ debugName: "rootColorClass" }] : /* istanbul ignore next */ []));
|
|
9829
|
-
let paintedColorClass = null;
|
|
9830
|
-
const clearColorClass = () => {
|
|
9831
|
-
if (paintedColorClass)
|
|
9832
|
-
root.classList.remove(paintedColorClass);
|
|
9833
|
-
paintedColorClass = null;
|
|
9834
|
-
};
|
|
9835
|
-
effect(() => {
|
|
9836
|
-
const next = rootColorClass();
|
|
9837
|
-
clearColorClass();
|
|
9838
|
-
if (next)
|
|
9839
|
-
root.classList.add(next);
|
|
9840
|
-
paintedColorClass = next;
|
|
9841
|
-
});
|
|
9842
|
-
const clearClasses = () => root.classList.remove(`${prefix}-scheme--light`, `${prefix}-scheme--dark`);
|
|
9843
|
-
const setMode = (next) => {
|
|
9844
|
-
clearClasses();
|
|
9845
|
-
if (next !== 'system')
|
|
9846
|
-
root.classList.add(`${prefix}-scheme--${next}`);
|
|
9847
|
-
mode.set(next);
|
|
9848
|
-
};
|
|
9849
|
-
inject(DestroyRef).onDestroy(() => {
|
|
9850
|
-
clearClasses();
|
|
9851
|
-
clearColorClass();
|
|
9852
|
-
});
|
|
9853
|
-
return { mode: mode.asReadonly(), type, rootSurface, setMode };
|
|
9854
|
-
}, { name: 'Color Scheme' });
|
|
9855
|
-
const provideColorSchemeState = /* @__PURE__ */ toProvideFn(COLOR_SCHEME_DEF);
|
|
9856
|
-
/**
|
|
9857
|
-
* Inject the app's color scheme: `mode()` is what the app asked for, `type()` the surface type the
|
|
9858
|
-
* root paints, `rootSurface()` the default surface theme of that type, and `setMode()` switches it.
|
|
9859
|
-
* Needs `provideColorScheme()`.
|
|
9860
|
-
*/
|
|
9861
|
-
const injectColorScheme = /* @__PURE__ */ toInjectFn(COLOR_SCHEME_DEF);
|
|
9862
|
-
/**
|
|
9863
|
-
* Lets the app switch between its default light and dark surface with a class on `<html>`, instead of
|
|
9864
|
-
* only following `prefers-color-scheme`. It also paints the root surface's `colorThemeVariants` entry for the
|
|
9865
|
-
* default accent on `<html>`. Add it to the application config, next to
|
|
9866
|
-
* `provideSurfaceThemesWithTailwind4()`.
|
|
9867
|
-
*/
|
|
9868
|
-
const provideColorScheme = (config) => makeEnvironmentProviders([
|
|
9869
|
-
provideColorSchemeState(),
|
|
9870
|
-
{ provide: COLOR_SCHEME_TYPE, useFactory: () => injectColorScheme().type },
|
|
9871
|
-
provideEnvironmentInitializer(() => injectColorScheme().setMode(config?.mode ?? 'system')),
|
|
9872
|
-
]);
|
|
9873
|
-
/**
|
|
9874
|
-
* Inject a signal of the default surface theme the root paints where nothing scopes one. If the app
|
|
9875
|
-
* registers a default for both surface types, it follows `injectColorScheme()`, and is `null` without
|
|
9876
|
-
* `provideColorScheme()`.
|
|
9877
|
-
*/
|
|
9878
|
-
const injectRootSurfaceTheme = () => {
|
|
9879
|
-
const defaults = injectSurfaceThemes({ optional: true })?.filter((theme) => theme.isDefault) ?? [];
|
|
9880
|
-
const colorSchemeType = inject(COLOR_SCHEME_TYPE, { optional: true });
|
|
9881
|
-
return computed(() => findRootSurfaceTheme(defaults, colorSchemeType?.()));
|
|
9882
|
-
};
|
|
9883
|
-
|
|
9884
|
-
/**
|
|
9885
|
-
* Reserved color name. Resolves the color tokens from the ambient surface's neutral swatch
|
|
9886
|
-
* (`SurfaceTheme['interactionColor']`) instead of a registered accent, so a secondary action can
|
|
9887
|
-
* read as chrome without the app registering a neutral color theme. Apps must not register a color
|
|
9888
|
-
* theme under this name.
|
|
9889
|
-
*/
|
|
9890
|
-
const SURFACE_COLOR = 'surface';
|
|
9891
|
-
const createCssColorThemeName = (name) => name.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
9892
|
-
const COLOR_THEMES_DEF = /* @__PURE__ */ defineStaticProvider(undefined, {
|
|
9893
|
-
name: 'Color Themes',
|
|
9894
|
-
});
|
|
9895
|
-
const ɵProvideColorThemes = /* @__PURE__ */ toProvideFn(COLOR_THEMES_DEF);
|
|
9896
|
-
const injectColorThemes = /* @__PURE__ */ toInjectFn(COLOR_THEMES_DEF);
|
|
9897
|
-
const COLOR_THEMES_PREFIX_DEF = /* @__PURE__ */ defineStaticProvider('et', {
|
|
9898
|
-
name: 'Themes Prefix',
|
|
9899
|
-
});
|
|
9900
|
-
const ɵProvideColorThemesPrefix = /* @__PURE__ */ toProvideFn(COLOR_THEMES_PREFIX_DEF);
|
|
9901
|
-
const injectColorThemesPrefix = /* @__PURE__ */ toInjectFn(COLOR_THEMES_PREFIX_DEF);
|
|
9902
|
-
const provideColorThemesWithTailwind4 = (themes, prefix = 'et') => {
|
|
9903
|
-
if (isDevMode() && themes.some((theme) => theme.name === SURFACE_COLOR)) {
|
|
9904
|
-
console.error(`[provideColorThemesWithTailwind4] "${SURFACE_COLOR}" is a reserved color name that resolves to the ambient surface's neutral swatch. Rename your theme.`);
|
|
9905
|
-
}
|
|
9906
|
-
return [ɵProvideColorThemes(themes), ɵProvideColorThemesPrefix(prefix)];
|
|
9907
|
-
};
|
|
9908
|
-
const findColorThemeByType = (themes, type, caller) => {
|
|
9909
|
-
if (!themes) {
|
|
9910
|
-
throw new Error(`[${caller}] No color themes provided. Call provideColorThemesWithTailwind4() in your app config.`);
|
|
9911
|
-
}
|
|
9912
|
-
const theme = themes.find((t) => t.type === type);
|
|
9913
|
-
if (!theme) {
|
|
9914
|
-
throw new Error(`[${caller}] No color theme with type "${type}" found. Add a theme with type: "${type}" to provideColorThemesWithTailwind4().`);
|
|
9915
|
-
}
|
|
9916
|
-
if (isDevMode()) {
|
|
9917
|
-
const duplicates = themes.filter((t) => t.type === type);
|
|
9918
|
-
if (duplicates.length > 1) {
|
|
9919
|
-
console.error(`[${caller}] Multiple themes with type "${type}" found: ${duplicates.map((t) => t.name).join(', ')}. Only the first one will be used.`);
|
|
9920
|
-
}
|
|
9921
|
-
}
|
|
9922
|
-
return theme;
|
|
9923
|
-
};
|
|
9924
|
-
const injectColorThemeByType = (type) => findColorThemeByType(injectColorThemes({ optional: true }), type, 'injectColorThemeByType');
|
|
9925
|
-
/**
|
|
9926
|
-
* The color theme name that draws `chosenName` on `surface`: the surface's `colorThemeVariants` entry for it,
|
|
9927
|
-
* else `chosenName` itself. Always pass the chosen accent, never an already swapped one.
|
|
9928
|
-
*/
|
|
9929
|
-
const resolveColorThemeVariant = (surface, chosenName, themes) => {
|
|
9930
|
-
if (!surface || chosenName === SURFACE_COLOR)
|
|
9931
|
-
return chosenName;
|
|
9932
|
-
const variants = surface.colorThemeVariants;
|
|
9933
|
-
const variant = variants?.[chosenName];
|
|
9934
|
-
if (variant)
|
|
9935
|
-
return variant;
|
|
9936
|
-
const chosen = themes?.find((t) => t.name === chosenName);
|
|
9937
|
-
const semantic = chosen?.type ? surface.semanticColorThemes?.[chosen.type] : undefined;
|
|
9938
|
-
if (semantic)
|
|
9939
|
-
return semantic;
|
|
9940
|
-
if (surface.colorTheme && chosen?.isDefault)
|
|
9941
|
-
return surface.colorTheme;
|
|
9942
|
-
return chosenName;
|
|
9943
|
-
};
|
|
9944
|
-
/**
|
|
9945
|
-
* A signal of the color theme for `type` on the surface this element renders on: the first registered theme
|
|
9946
|
-
* of that `type`, swapped for the nearest surface's `colorThemeVariants` entry. Reading it throws when the app
|
|
9947
|
-
* registered no theme of that `type`, so read it only for a state that renders.
|
|
9948
|
-
*
|
|
9949
|
-
* @example
|
|
9950
|
-
* protected successTheme = injectSemanticColorTheme('success');
|
|
9951
|
-
* // <span [etProvideColor]="successTheme()">+12%</span>
|
|
9952
|
-
*/
|
|
9953
|
-
const injectSemanticColorTheme = (type) => {
|
|
9954
|
-
const themes = injectColorThemes({ optional: true });
|
|
9955
|
-
const surfaceProvider = inject(SURFACE_PROVIDER, { optional: true });
|
|
9956
|
-
const rootSurface = injectRootSurfaceTheme();
|
|
9957
|
-
return computed(() => {
|
|
9958
|
-
const chosen = findColorThemeByType(themes, type, 'injectSemanticColorTheme');
|
|
9959
|
-
const surface = surfaceProvider?.activeTheme() ?? rootSurface();
|
|
9960
|
-
const variantName = resolveColorThemeVariant(surface, chosen.name, themes);
|
|
9961
|
-
if (variantName === chosen.name)
|
|
9962
|
-
return chosen;
|
|
9963
|
-
const variant = themes?.find((t) => t.name === variantName);
|
|
9964
|
-
if (variant)
|
|
9965
|
-
return variant;
|
|
9966
|
-
if (isDevMode()) {
|
|
9967
|
-
console.error(`[injectSemanticColorTheme] Surface theme "${surface?.name}" maps "${type}" to the color theme "${variantName}", which is not registered. Add it to provideColorThemesWithTailwind4().`);
|
|
9968
|
-
}
|
|
9969
|
-
return chosen;
|
|
9970
|
-
});
|
|
9971
|
-
};
|
|
9972
|
-
/** @deprecated Use `injectSemanticColorTheme('error')`, which follows the surface the element renders on. */
|
|
9973
|
-
const injectErrorTheme = () => injectColorThemeByType('error');
|
|
9974
|
-
/** @deprecated Use `injectSemanticColorTheme('warning')`, which follows the surface the element renders on. */
|
|
9975
|
-
const injectWarningTheme = () => injectColorThemeByType('warning');
|
|
9976
|
-
/** @deprecated Use `injectSemanticColorTheme('success')`, which follows the surface the element renders on. */
|
|
9977
|
-
const injectSuccessTheme = () => injectColorThemeByType('success');
|
|
9978
|
-
const injectDefaultColorTheme = () => {
|
|
9979
|
-
const themes = injectColorThemes({ optional: true });
|
|
9980
|
-
if (!themes) {
|
|
9981
|
-
throw new Error(`[injectDefaultColorTheme] No color themes provided. Call provideColorThemesWithTailwind4() in your app config.`);
|
|
9982
|
-
}
|
|
9983
|
-
const theme = themes.find((t) => t.isDefault);
|
|
9984
|
-
if (!theme) {
|
|
9985
|
-
throw new Error(`[injectDefaultColorTheme] No color theme with isDefault: true found. Mark one theme as the default in provideColorThemesWithTailwind4().`);
|
|
9986
|
-
}
|
|
9987
|
-
if (isDevMode()) {
|
|
9988
|
-
const duplicates = themes.filter((t) => t.isDefault);
|
|
9989
|
-
if (duplicates.length > 1) {
|
|
9990
|
-
console.error(`[injectDefaultColorTheme] Multiple themes with isDefault: true found: ${duplicates.map((t) => t.name).join(', ')}. Only the first one will be used.`);
|
|
9991
|
-
}
|
|
9992
|
-
}
|
|
9993
|
-
return theme;
|
|
9994
|
-
};
|
|
9995
|
-
|
|
9996
|
-
const COLOR_PROVIDER = new InjectionToken('ColorProvider');
|
|
9997
|
-
/**
|
|
9998
|
-
* The color provider attached to a bootstrapped root component (e.g. `ProvideColorDirective` in
|
|
9999
|
-
* the app component's `hostDirectives`), if any. Detached DOM such as overlay panes can't reach
|
|
10000
|
-
* it through element DI, so overlay containers fall back to this when resolving the provider to
|
|
10001
|
-
* `syncWithProvider()` - resolve at sync time, not at injection time, since root components only
|
|
10002
|
-
* register with `ApplicationRef` once bootstrap completes.
|
|
10003
|
-
*/
|
|
10004
|
-
const resolveAppRootColorProvider = (appRef) => {
|
|
10005
|
-
for (const componentRef of appRef.components) {
|
|
10006
|
-
const provider = componentRef.injector.get(COLOR_PROVIDER, null);
|
|
10007
|
-
if (provider) {
|
|
10008
|
-
return provider;
|
|
10009
|
-
}
|
|
10010
|
-
}
|
|
10011
|
-
return null;
|
|
10012
|
-
};
|
|
10013
|
-
const FORCED_COLOR_UNSET = /* @__PURE__ */ Symbol('FORCED_COLOR_UNSET');
|
|
10014
|
-
const appsWarnedAboutMissingThemes = /* @__PURE__ */ new WeakSet();
|
|
10015
|
-
class ProvideColorDirective {
|
|
10016
|
-
constructor() {
|
|
10017
|
-
this.themes = injectColorThemes({ optional: true });
|
|
10018
|
-
this.prefix = injectColorThemesPrefix({ optional: true });
|
|
10019
|
-
this.injector = inject(Injector);
|
|
10020
|
-
this.rootSurfaceTheme = injectRootSurfaceTheme();
|
|
10021
|
-
this.parentProvider = inject(COLOR_PROVIDER, { optional: true, skipSelf: true });
|
|
10022
|
-
this.appRef = inject(ApplicationRef);
|
|
10023
|
-
this.currentProviderSync = null;
|
|
10024
|
-
this.forcedColor = signal(FORCED_COLOR_UNSET, /* @ts-ignore */
|
|
10025
|
-
...(ngDevMode ? [{ debugName: "forcedColor" }] : /* istanbul ignore next */ []));
|
|
10026
|
-
this.color = input(undefined, { ...(ngDevMode ? { debugName: "color" } : /* istanbul ignore next */ {}), alias: 'etProvideColor' });
|
|
10027
|
-
this.effectiveColor = computed(() => {
|
|
10028
|
-
const forcedColor = this.forcedColor();
|
|
10029
|
-
if (forcedColor !== FORCED_COLOR_UNSET) {
|
|
10030
|
-
return forcedColor;
|
|
10031
|
-
}
|
|
10032
|
-
return this.color();
|
|
10033
|
-
}, /* @ts-ignore */
|
|
10034
|
-
...(ngDevMode ? [{ debugName: "effectiveColor" }] : /* istanbul ignore next */ []));
|
|
10035
|
-
/**
|
|
10036
|
-
* The color that actually applies at this provider's location: its own effective color, or -
|
|
10037
|
-
* when this provider is passive (no input, nothing forced) - the nearest ancestor provider's.
|
|
10038
|
-
* Mirrors the CSS cascade, which falls through a provider's `-color--inherited` scope class;
|
|
10039
|
-
* consumers that re-apply context across detached DOM (overlay panes) must use this instead
|
|
10040
|
-
* of `effectiveColor` or a passive in-between provider (e.g. a form field's) erases the theme.
|
|
10041
|
-
*/
|
|
10042
|
-
this.resolvedColor = computed(() => {
|
|
10043
|
-
const own = this.effectiveColor();
|
|
10044
|
-
const ownName = typeof own === 'object' && own !== null ? own.name : own;
|
|
10045
|
-
if (ownName) {
|
|
10046
|
-
return own;
|
|
10047
|
-
}
|
|
10048
|
-
return this.parentProvider?.resolvedColor();
|
|
10049
|
-
}, /* @ts-ignore */
|
|
10050
|
-
...(ngDevMode ? [{ debugName: "resolvedColor" }] : /* istanbul ignore next */ []));
|
|
10051
|
-
this.colorName = computed(() => {
|
|
10052
|
-
const raw = this.effectiveColor();
|
|
10053
|
-
const value = typeof raw === 'object' && raw !== null ? raw.name : raw;
|
|
10054
|
-
if (value === SURFACE_COLOR)
|
|
10055
|
-
return SURFACE_COLOR;
|
|
10056
|
-
if (!value)
|
|
10057
|
-
return;
|
|
10058
|
-
if (!this.themes) {
|
|
10059
|
-
if (isDevMode() && !appsWarnedAboutMissingThemes.has(this.appRef)) {
|
|
10060
|
-
appsWarnedAboutMissingThemes.add(this.appRef);
|
|
10061
|
-
console.warn(`etProvideColor="${value}" has no effect because no color themes are registered. Please make sure to add provideColorThemesWithTailwind4()`);
|
|
10062
|
-
}
|
|
10063
|
-
return;
|
|
10064
|
-
}
|
|
10065
|
-
if (isDevMode() && !this.themes.some((theme) => theme.name === value)) {
|
|
10066
|
-
console.error(`Theme ${value} does not exist. Please make sure to add it to provideColorThemesWithTailwind4()`);
|
|
10067
|
-
}
|
|
10068
|
-
return createCssColorThemeName(value);
|
|
10069
|
-
}, /* @ts-ignore */
|
|
10070
|
-
...(ngDevMode ? [{ debugName: "colorName" }] : /* istanbul ignore next */ []));
|
|
10071
|
-
this.paintedColorName = computed(() => {
|
|
10072
|
-
const raw = this.effectiveColor();
|
|
10073
|
-
const value = typeof raw === 'object' && raw !== null ? raw.name : raw;
|
|
10074
|
-
if (!this.colorName() || !value)
|
|
10075
|
-
return;
|
|
10076
|
-
const surface = this.injector.get(SURFACE_PROVIDER, null)?.activeTheme() ?? this.rootSurfaceTheme();
|
|
10077
|
-
const variant = resolveColorThemeVariant(surface, value, this.themes);
|
|
10078
|
-
if (variant === value)
|
|
10079
|
-
return this.colorName();
|
|
10080
|
-
if (isDevMode() && !this.themes?.some((theme) => theme.name === variant)) {
|
|
10081
|
-
console.error(`Surface theme ${surface?.name} names the color theme ${variant}, which does not exist. Please make sure to add it to provideColorThemesWithTailwind4()`);
|
|
10082
|
-
}
|
|
10083
|
-
return createCssColorThemeName(variant);
|
|
10084
|
-
}, /* @ts-ignore */
|
|
10085
|
-
...(ngDevMode ? [{ debugName: "paintedColorName" }] : /* istanbul ignore next */ []));
|
|
10086
|
-
this.themeClass = computed(() => {
|
|
10087
|
-
const prefix = this.prefix || 'et';
|
|
10088
|
-
const name = this.paintedColorName();
|
|
10089
|
-
return name ? `${prefix}-color--${name}` : `${prefix}-color--inherited`;
|
|
10090
|
-
}, /* @ts-ignore */
|
|
10091
|
-
...(ngDevMode ? [{ debugName: "themeClass" }] : /* istanbul ignore next */ []));
|
|
10092
|
-
}
|
|
10093
|
-
syncWithProvider(provider) {
|
|
10094
|
-
this.currentProviderSync?.destroy();
|
|
10095
|
-
runInInjectionContext(this.injector, () => {
|
|
10096
|
-
this.currentProviderSync = effect(() => {
|
|
10097
|
-
const provideColor = provider.resolvedColor();
|
|
10098
|
-
untracked(() => {
|
|
10099
|
-
if (provideColor === undefined) {
|
|
10100
|
-
this.clearForcedColor();
|
|
10101
|
-
return;
|
|
10102
|
-
}
|
|
10103
|
-
this.forceColor(provideColor);
|
|
10104
|
-
});
|
|
10105
|
-
}, /* @ts-ignore */
|
|
10106
|
-
...(ngDevMode ? [{ debugName: "currentProviderSync" }] : /* istanbul ignore next */ []));
|
|
10107
|
-
});
|
|
10108
|
-
}
|
|
10109
|
-
stopSyncWithProvider() {
|
|
10110
|
-
const hadProviderSync = !!this.currentProviderSync;
|
|
10111
|
-
this.currentProviderSync?.destroy();
|
|
10112
|
-
this.currentProviderSync = null;
|
|
10113
|
-
if (hadProviderSync) {
|
|
10114
|
-
this.clearForcedColor();
|
|
10115
|
-
}
|
|
10116
|
-
}
|
|
10117
|
-
forceColor(color) {
|
|
10118
|
-
this.forcedColor.set(color);
|
|
10119
|
-
}
|
|
10120
|
-
clearForcedColor() {
|
|
10121
|
-
if (this.forcedColor() === FORCED_COLOR_UNSET) {
|
|
10122
|
-
return;
|
|
10123
|
-
}
|
|
10124
|
-
this.forcedColor.set(FORCED_COLOR_UNSET);
|
|
10125
|
-
}
|
|
10126
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ProvideColorDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
10127
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.6", type: ProvideColorDirective, isStandalone: true, selector: "[etProvideColor]", inputs: { color: { classPropertyName: "color", publicName: "etProvideColor", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "themeClass()" } }, providers: [{ provide: COLOR_PROVIDER, useExisting: ProvideColorDirective }], ngImport: i0 }); }
|
|
10128
|
-
}
|
|
10129
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ProvideColorDirective, decorators: [{
|
|
10130
|
-
type: Directive,
|
|
10131
|
-
args: [{
|
|
10132
|
-
selector: '[etProvideColor]',
|
|
10133
|
-
providers: [{ provide: COLOR_PROVIDER, useExisting: ProvideColorDirective }],
|
|
10134
|
-
host: {
|
|
10135
|
-
'[class]': 'themeClass()',
|
|
10136
|
-
},
|
|
10137
|
-
}]
|
|
10138
|
-
}], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "etProvideColor", required: false }] }] } });
|
|
10139
|
-
|
|
10140
10066
|
const SURFACE_PROVIDER = new InjectionToken('SurfaceProvider');
|
|
10141
10067
|
const FORCED_SURFACE_UNSET = /* @__PURE__ */ Symbol('FORCED_SURFACE_UNSET');
|
|
10142
10068
|
class ProvideSurfaceDirective {
|
|
@@ -10303,6 +10229,219 @@ const injectParentSurface = () => {
|
|
|
10303
10229
|
return computed(() => provider?.activeTheme() ?? rootTheme());
|
|
10304
10230
|
};
|
|
10305
10231
|
|
|
10232
|
+
/**
|
|
10233
|
+
* Reserved color name. Resolves the color tokens from the ambient surface's neutral swatch
|
|
10234
|
+
* (`SurfaceTheme['interactionColor']`) instead of a registered accent, so a secondary action can
|
|
10235
|
+
* read as chrome without the app registering a neutral color theme. Apps must not register a color
|
|
10236
|
+
* theme under this name.
|
|
10237
|
+
*/
|
|
10238
|
+
const SURFACE_COLOR = 'surface';
|
|
10239
|
+
const createCssColorThemeName = (name) => name.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
10240
|
+
const COLOR_THEMES_DEF = /* @__PURE__ */ defineStaticProvider(undefined, {
|
|
10241
|
+
name: 'Color Themes',
|
|
10242
|
+
});
|
|
10243
|
+
const ɵProvideColorThemes = /* @__PURE__ */ toProvideFn(COLOR_THEMES_DEF);
|
|
10244
|
+
const injectColorThemes = /* @__PURE__ */ toInjectFn(COLOR_THEMES_DEF);
|
|
10245
|
+
const COLOR_THEMES_PREFIX_DEF = /* @__PURE__ */ defineStaticProvider('et', {
|
|
10246
|
+
name: 'Themes Prefix',
|
|
10247
|
+
});
|
|
10248
|
+
const ɵProvideColorThemesPrefix = /* @__PURE__ */ toProvideFn(COLOR_THEMES_PREFIX_DEF);
|
|
10249
|
+
const injectColorThemesPrefix = /* @__PURE__ */ toInjectFn(COLOR_THEMES_PREFIX_DEF);
|
|
10250
|
+
const provideColorThemesWithTailwind4 = (themes, prefix = 'et') => {
|
|
10251
|
+
if (isDevMode() && themes.some((theme) => theme.name === SURFACE_COLOR)) {
|
|
10252
|
+
console.error(`[provideColorThemesWithTailwind4] "${SURFACE_COLOR}" is a reserved color name that resolves to the ambient surface's neutral swatch. Rename your theme.`);
|
|
10253
|
+
}
|
|
10254
|
+
return [ɵProvideColorThemes(themes), ɵProvideColorThemesPrefix(prefix)];
|
|
10255
|
+
};
|
|
10256
|
+
const findColorThemeByType = (themes, type, caller) => {
|
|
10257
|
+
if (!themes) {
|
|
10258
|
+
throw new Error(`[${caller}] No color themes provided. Call provideColorThemesWithTailwind4() in your app config.`);
|
|
10259
|
+
}
|
|
10260
|
+
const theme = themes.find((t) => t.type === type);
|
|
10261
|
+
if (!theme) {
|
|
10262
|
+
throw new Error(`[${caller}] No color theme with type "${type}" found. Add a theme with type: "${type}" to provideColorThemesWithTailwind4().`);
|
|
10263
|
+
}
|
|
10264
|
+
if (isDevMode()) {
|
|
10265
|
+
const duplicates = themes.filter((t) => t.type === type);
|
|
10266
|
+
if (duplicates.length > 1) {
|
|
10267
|
+
console.error(`[${caller}] Multiple themes with type "${type}" found: ${duplicates.map((t) => t.name).join(', ')}. Only the first one will be used.`);
|
|
10268
|
+
}
|
|
10269
|
+
}
|
|
10270
|
+
return theme;
|
|
10271
|
+
};
|
|
10272
|
+
const injectColorThemeByType = (type) => findColorThemeByType(injectColorThemes({ optional: true }), type, 'injectColorThemeByType');
|
|
10273
|
+
/**
|
|
10274
|
+
* The color theme name that draws `chosenName` on `surface`: the surface's `colorThemeVariants` entry for it,
|
|
10275
|
+
* else `chosenName` itself. Always pass the chosen accent, never an already swapped one.
|
|
10276
|
+
*/
|
|
10277
|
+
const resolveColorThemeVariant = (surface, chosenName, themes) => {
|
|
10278
|
+
if (!surface || chosenName === SURFACE_COLOR)
|
|
10279
|
+
return chosenName;
|
|
10280
|
+
const variants = surface.colorThemeVariants;
|
|
10281
|
+
const variant = variants?.[chosenName];
|
|
10282
|
+
if (variant)
|
|
10283
|
+
return variant;
|
|
10284
|
+
const chosen = themes?.find((t) => t.name === chosenName);
|
|
10285
|
+
const semantic = chosen?.type ? surface.semanticColorThemes?.[chosen.type] : undefined;
|
|
10286
|
+
if (semantic)
|
|
10287
|
+
return semantic;
|
|
10288
|
+
if (surface.colorTheme && chosen?.isDefault)
|
|
10289
|
+
return surface.colorTheme;
|
|
10290
|
+
return chosenName;
|
|
10291
|
+
};
|
|
10292
|
+
/**
|
|
10293
|
+
* A signal of the color theme for `type` on the surface this element renders on: the first registered theme
|
|
10294
|
+
* of that `type`, swapped for the nearest surface's `colorThemeVariants` entry. Reading it throws when the app
|
|
10295
|
+
* registered no theme of that `type`, so read it only for a state that renders.
|
|
10296
|
+
*
|
|
10297
|
+
* @example
|
|
10298
|
+
* protected successTheme = injectSemanticColorTheme('success');
|
|
10299
|
+
* // <span [etProvideColor]="successTheme()">+12%</span>
|
|
10300
|
+
*/
|
|
10301
|
+
const injectSemanticColorTheme = (type) => {
|
|
10302
|
+
const themes = injectColorThemes({ optional: true });
|
|
10303
|
+
const surfaceProvider = inject(SURFACE_PROVIDER, { optional: true });
|
|
10304
|
+
const rootSurface = injectRootSurfaceTheme();
|
|
10305
|
+
return computed(() => {
|
|
10306
|
+
const chosen = findColorThemeByType(themes, type, 'injectSemanticColorTheme');
|
|
10307
|
+
const surface = surfaceProvider?.activeTheme() ?? rootSurface();
|
|
10308
|
+
const variantName = resolveColorThemeVariant(surface, chosen.name, themes);
|
|
10309
|
+
if (variantName === chosen.name)
|
|
10310
|
+
return chosen;
|
|
10311
|
+
const variant = themes?.find((t) => t.name === variantName);
|
|
10312
|
+
if (variant)
|
|
10313
|
+
return variant;
|
|
10314
|
+
if (isDevMode()) {
|
|
10315
|
+
console.error(`[injectSemanticColorTheme] Surface theme "${surface?.name}" maps "${type}" to the color theme "${variantName}", which is not registered. Add it to provideColorThemesWithTailwind4().`);
|
|
10316
|
+
}
|
|
10317
|
+
return chosen;
|
|
10318
|
+
});
|
|
10319
|
+
};
|
|
10320
|
+
/** @deprecated Use `injectSemanticColorTheme('error')`, which follows the surface the element renders on. */
|
|
10321
|
+
const injectErrorTheme = () => injectColorThemeByType('error');
|
|
10322
|
+
/** @deprecated Use `injectSemanticColorTheme('warning')`, which follows the surface the element renders on. */
|
|
10323
|
+
const injectWarningTheme = () => injectColorThemeByType('warning');
|
|
10324
|
+
/** @deprecated Use `injectSemanticColorTheme('success')`, which follows the surface the element renders on. */
|
|
10325
|
+
const injectSuccessTheme = () => injectColorThemeByType('success');
|
|
10326
|
+
const injectDefaultColorTheme = () => {
|
|
10327
|
+
const themes = injectColorThemes({ optional: true });
|
|
10328
|
+
if (!themes) {
|
|
10329
|
+
throw new Error(`[injectDefaultColorTheme] No color themes provided. Call provideColorThemesWithTailwind4() in your app config.`);
|
|
10330
|
+
}
|
|
10331
|
+
const theme = themes.find((t) => t.isDefault);
|
|
10332
|
+
if (!theme) {
|
|
10333
|
+
throw new Error(`[injectDefaultColorTheme] No color theme with isDefault: true found. Mark one theme as the default in provideColorThemesWithTailwind4().`);
|
|
10334
|
+
}
|
|
10335
|
+
if (isDevMode()) {
|
|
10336
|
+
const duplicates = themes.filter((t) => t.isDefault);
|
|
10337
|
+
if (duplicates.length > 1) {
|
|
10338
|
+
console.error(`[injectDefaultColorTheme] Multiple themes with isDefault: true found: ${duplicates.map((t) => t.name).join(', ')}. Only the first one will be used.`);
|
|
10339
|
+
}
|
|
10340
|
+
}
|
|
10341
|
+
return theme;
|
|
10342
|
+
};
|
|
10343
|
+
|
|
10344
|
+
const findRootSurfaceTheme = (defaults, type) => {
|
|
10345
|
+
if (defaults.length <= 1)
|
|
10346
|
+
return defaults[0] ?? null;
|
|
10347
|
+
return defaults.find((theme) => theme.type === type) ?? null;
|
|
10348
|
+
};
|
|
10349
|
+
const COLOR_SCHEME_DEF = /* @__PURE__ */ defineProvider(() => {
|
|
10350
|
+
const root = inject(DOCUMENT).documentElement;
|
|
10351
|
+
const prefix = injectSurfaceThemesPrefix({ optional: true }) || 'et';
|
|
10352
|
+
const prefersDark = injectBreakpointObserver().observeMediaQuery('(prefers-color-scheme: dark)');
|
|
10353
|
+
const mode = signal('system', /* @ts-ignore */
|
|
10354
|
+
...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
10355
|
+
const surfaceDefaults = injectSurfaceThemes({ optional: true })?.filter((theme) => theme.isDefault) ?? [];
|
|
10356
|
+
const colorThemes = injectColorThemes({ optional: true });
|
|
10357
|
+
const colorPrefix = injectColorThemesPrefix({ optional: true }) || 'et';
|
|
10358
|
+
const type = computed(() => {
|
|
10359
|
+
const current = mode();
|
|
10360
|
+
if (current !== 'system')
|
|
10361
|
+
return current;
|
|
10362
|
+
return prefersDark() ? 'dark' : 'light';
|
|
10363
|
+
}, /* @ts-ignore */
|
|
10364
|
+
...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
10365
|
+
const rootSurface = computed(() => findRootSurfaceTheme(surfaceDefaults, type()), /* @ts-ignore */
|
|
10366
|
+
...(ngDevMode ? [{ debugName: "rootSurface" }] : /* istanbul ignore next */ []));
|
|
10367
|
+
const rootColorClass = computed(() => {
|
|
10368
|
+
const chosen = colorThemes?.find((theme) => theme.isDefault)?.name;
|
|
10369
|
+
if (!chosen)
|
|
10370
|
+
return null;
|
|
10371
|
+
const variant = resolveColorThemeVariant(rootSurface(), chosen, colorThemes);
|
|
10372
|
+
return variant === chosen ? null : `${colorPrefix}-color--${createCssColorThemeName(variant)}`;
|
|
10373
|
+
}, /* @ts-ignore */
|
|
10374
|
+
...(ngDevMode ? [{ debugName: "rootColorClass" }] : /* istanbul ignore next */ []));
|
|
10375
|
+
const defaultColor = colorThemes?.find((theme) => theme.isDefault)?.name;
|
|
10376
|
+
if (defaultColor) {
|
|
10377
|
+
for (const surface of surfaceDefaults) {
|
|
10378
|
+
const variant = resolveColorThemeVariant(surface, defaultColor, colorThemes);
|
|
10379
|
+
if (variant !== defaultColor)
|
|
10380
|
+
root.classList.remove(`${colorPrefix}-color--${createCssColorThemeName(variant)}`);
|
|
10381
|
+
}
|
|
10382
|
+
}
|
|
10383
|
+
let paintedColorClass = null;
|
|
10384
|
+
const clearColorClass = () => {
|
|
10385
|
+
if (paintedColorClass)
|
|
10386
|
+
root.classList.remove(paintedColorClass);
|
|
10387
|
+
paintedColorClass = null;
|
|
10388
|
+
};
|
|
10389
|
+
effect(() => {
|
|
10390
|
+
const next = rootColorClass();
|
|
10391
|
+
clearColorClass();
|
|
10392
|
+
if (next)
|
|
10393
|
+
root.classList.add(next);
|
|
10394
|
+
paintedColorClass = next;
|
|
10395
|
+
});
|
|
10396
|
+
const clearClasses = () => root.classList.remove(`${prefix}-scheme--light`, `${prefix}-scheme--dark`);
|
|
10397
|
+
const setMode = (next) => {
|
|
10398
|
+
clearClasses();
|
|
10399
|
+
if (next !== 'system')
|
|
10400
|
+
root.classList.add(`${prefix}-scheme--${next}`);
|
|
10401
|
+
mode.set(next);
|
|
10402
|
+
};
|
|
10403
|
+
inject(DestroyRef).onDestroy(() => {
|
|
10404
|
+
clearClasses();
|
|
10405
|
+
clearColorClass();
|
|
10406
|
+
});
|
|
10407
|
+
return { mode: mode.asReadonly(), type, rootSurface, setMode };
|
|
10408
|
+
}, { name: 'Color Scheme' });
|
|
10409
|
+
const provideColorSchemeState = /* @__PURE__ */ toProvideFn(COLOR_SCHEME_DEF);
|
|
10410
|
+
/**
|
|
10411
|
+
* Inject the app's color scheme: `mode()` is what the app asked for, `type()` the surface type the
|
|
10412
|
+
* root paints, `rootSurface()` the default surface theme of that type, and `setMode()` switches it.
|
|
10413
|
+
* Needs `provideColorScheme()`.
|
|
10414
|
+
*/
|
|
10415
|
+
const injectColorScheme = /* @__PURE__ */ toInjectFn(COLOR_SCHEME_DEF);
|
|
10416
|
+
const injectSchemeUnresolved = () => {
|
|
10417
|
+
const { mode } = injectColorScheme();
|
|
10418
|
+
const isServer = isPlatformServer(inject(PLATFORM_ID));
|
|
10419
|
+
const defaultCount = injectSurfaceThemes({ optional: true })?.filter((theme) => theme.isDefault).length ?? 0;
|
|
10420
|
+
return computed(() => isServer && defaultCount > 1 && mode() === 'system');
|
|
10421
|
+
};
|
|
10422
|
+
/**
|
|
10423
|
+
* Lets the app switch between its default light and dark surface with a class on `<html>`, instead of
|
|
10424
|
+
* only following `prefers-color-scheme`. It also paints the root surface's `colorThemeVariants` entry for the
|
|
10425
|
+
* default accent on `<html>`. Add it to the application config, next to
|
|
10426
|
+
* `provideSurfaceThemesWithTailwind4()`.
|
|
10427
|
+
*/
|
|
10428
|
+
const provideColorScheme = (config) => makeEnvironmentProviders([
|
|
10429
|
+
provideColorSchemeState(),
|
|
10430
|
+
{ provide: COLOR_SCHEME_TYPE, useFactory: () => injectColorScheme().type },
|
|
10431
|
+
{ provide: COLOR_SCHEME_UNRESOLVED, useFactory: injectSchemeUnresolved },
|
|
10432
|
+
provideEnvironmentInitializer(() => injectColorScheme().setMode(config?.mode ?? 'system')),
|
|
10433
|
+
]);
|
|
10434
|
+
/**
|
|
10435
|
+
* Inject a signal of the default surface theme the root paints where nothing scopes one. If the app
|
|
10436
|
+
* registers a default for both surface types, it follows `injectColorScheme()`, and is `null` without
|
|
10437
|
+
* `provideColorScheme()`.
|
|
10438
|
+
*/
|
|
10439
|
+
const injectRootSurfaceTheme = () => {
|
|
10440
|
+
const defaults = injectSurfaceThemes({ optional: true })?.filter((theme) => theme.isDefault) ?? [];
|
|
10441
|
+
const colorSchemeType = inject(COLOR_SCHEME_TYPE, { optional: true });
|
|
10442
|
+
return computed(() => findRootSurfaceTheme(defaults, colorSchemeType?.()));
|
|
10443
|
+
};
|
|
10444
|
+
|
|
10306
10445
|
let uniqueId = 0;
|
|
10307
10446
|
const SURFACE_CONTEXT_TRACKER_DEF = /* @__PURE__ */ defineRootProvider(() => {
|
|
10308
10447
|
const entries = signal([], /* @ts-ignore */
|
|
@@ -10350,6 +10489,8 @@ class AutoSurfaceDirective {
|
|
|
10350
10489
|
this.surfaceContextTracker = injectSurfaceContextTracker();
|
|
10351
10490
|
this.parentSurface = injectParentSurface();
|
|
10352
10491
|
this.elementRef = inject(ElementRef);
|
|
10492
|
+
this.schemeUnresolved = inject(COLOR_SCHEME_UNRESOLVED, { optional: true });
|
|
10493
|
+
this.rootTheme = injectRootSurfaceTheme();
|
|
10353
10494
|
/**
|
|
10354
10495
|
* Explicit surface provider to resolve the surface relative to. Falls back to the
|
|
10355
10496
|
* surface provider from the surrounding (trigger) context when not set.
|
|
@@ -10375,6 +10516,10 @@ class AutoSurfaceDirective {
|
|
|
10375
10516
|
const overlaySurface = this.surfaceContextTracker.surfaceForElement(this.elementRef.nativeElement);
|
|
10376
10517
|
const overlayElevation = overlaySurface?.elevation ?? null;
|
|
10377
10518
|
const overlayType = overlaySurface?.type ?? null;
|
|
10519
|
+
// A surface derived from the root would bake the server's guessed scheme into the markup; inherit, and let CSS pick it.
|
|
10520
|
+
if (this.schemeUnresolved?.() && overlayElevation === null && contextTheme === this.rootTheme()) {
|
|
10521
|
+
return null;
|
|
10522
|
+
}
|
|
10378
10523
|
// Must not re-derive from the declaration injector: it points at the trigger and would double-elevate the panel.
|
|
10379
10524
|
if (this.isOverlaySurface()) {
|
|
10380
10525
|
if (overlayElevation !== null) {
|
|
@@ -10722,11 +10867,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
|
|
|
10722
10867
|
|
|
10723
10868
|
// Generated from package.json by tools/scripts/generate-version.js - do not edit.
|
|
10724
10869
|
/** The version of `@ethlete/core` this build was cut from. */
|
|
10725
|
-
const CORE_VERSION = '5.0.0-next.
|
|
10870
|
+
const CORE_VERSION = '5.0.0-next.66';
|
|
10726
10871
|
|
|
10727
10872
|
/**
|
|
10728
10873
|
* Generated bundle index. Do not edit.
|
|
10729
10874
|
*/
|
|
10730
10875
|
|
|
10731
|
-
export { ANIMATABLE_TOKEN, ANIMATED_IF_TOKEN, ANIMATED_LIFECYCLE_TOKEN, ANIMATION_DEBUG_STORAGE_KEY, ANIMATION_ERROR_CODES, AT_LEAST_ONE_REQUIRED, AnimatableDirective, AnimatedIfDirective, AnimatedLifecycleDirective, AutoSurfaceDirective, BOUNDARY_ELEMENT_TOKEN, BREAKPOINT_INSTANCE_TOKEN, BREAKPOINT_ORDER, COLOR_PALETTE, COLOR_PROVIDER, CORE_VERSION, ClickOutsideDirective, ColorInteractiveContainerDirective, ColorInteractiveDirective, ColorInteractiveExcludeDirective, ColorInteractiveHasFocusDirective, DEFAULT_MULTI_INSTANCE_RELS, DEFAULT_MULTI_INSTANCE_TAGS, DEFAULT_OVERLAY_LAYER, 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, ET_RESTORE_SCROLL, EasingTokensStylesComponent, EthleteValidators, FOCUSABLE_SELECTOR, FOCUS_VISIBLE_TRACKER_TOKEN, HtmlToMarkdownPipe, IS_ARRAY_NOT_EMPTY, IS_EMAIL, InferMimeTypePipe, InitialsPipe, IsArrayNotEmpty, IsEmail, jsonLd as JsonLD, KeyPressManager, MARKDOWN_VERBATIM_ATTR, MUST_MATCH, MarkdownToHtmlPipe, MatchStateType, MustMatch, NOTIFICATION_CLICK_MESSAGE_TYPE, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, OVERLAY_LAYER_ATTRIBUTE, ProvideColorDirective, ProvideSurfaceDirective, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeHandlesComponent, RestoreScrollDirective, RuntimeError, SURFACE_COLOR, SURFACE_PROVIDER, SURFACE_TYPE, SWIPE_VELOCITY_WINDOW_MS, ScrollObserverDirective, ScrollObserverEndDirective, ScrollObserverStartDirective, SlugifyPipe, StructuredDataComponent, SurfaceInteractiveDirective, ToArrayPipe, TypedQueryList, UNSAVED_CHANGES_CONFIRM, UNSAVED_CHANGES_ERROR_CODES, UNSAVED_CHANGES_TITLE_MARKER, ValidateAtLeastOneRequired, VisuallyHiddenStylesComponent, anchoredOverlayPosition, animationDebugLog, applyAlternateBinding, applyAlternateLanguagesBindings, applyArticleBindings, applyAuthorBinding, applyCanonicalBinding, applyCenteredPosition, applyDescriptionBinding, applyFaviconOverlay, applyGlobalPosition, applyHeadBinding, applyHeadTitleBinding, applyHeadTitleMarker, applyHostListener, applyHostListeners, applyInitialFocus, applyKeywordsBinding, applyLinkBinding, applyMetaBinding, applyNextBinding, applyOgBinding, applyOpenGraphBindings, applyPrevBinding, applyResourceHintsBindings, applyRobotsBinding, applySocialMediaBindings, applyStructuredDataBinding, applyTwitterCardBindings, boolBreakpointTransform, boundingClientRectToElementRect, breakpointTransformBase, buildElementSignal, buildSignalEffects, canUseSessionMemory, clamp, clone, cloneFormGroup, computedTillFalsy, computedTillTruthy, controlValueSignal, controlValueSignalWithPrevious, copyToClipboard, createAnchoredPositionCleanup, createArrayPropertyBinding, createAutoSessionMemoryKey, createCanAnimateSignal, createComponentId, createCssColorThemeName, createCssSurfaceName, createDestroy, createDocumentElementSignal, createElementDimensions, createEmptyElementSignal, createFlipAnimation, createFlipAnimationGroup, createIsRenderedSignal, createLogger, createObjectUrlHandle, createPropertyBinding, createRootThemeCss, createRoute, createRouterState, createRxHostListener, createSessionMemory, createSwatchCss, createSwipeTracker, createTailwindColorThemes, createTailwindCssVar, createTailwindRgbVar, createThemeStyle, createUnsavedChangesGuard, createUnsavedChangesTabLock, createUnsavedChangesTracker, createUserConsentProvider, deferredSignal, defineLabels, defineProvider, defineRootProvider, defineStaticProvider, defineStaticRootProvider, deleteCookie, dragGestureFrom, easeElastic, easeIn, easeInOut, easeLinear, easeOut, easeOutBack, easeOutBackStrong, elementCanScroll, enableAnchoredOverlayPositionExtras, equal, fetchDeployedBuildFingerprint$, 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, injectAppUpdates, injectAppUpdatesConfig, injectBoundaryElement, injectBreakpointInput, injectBreakpointIsMatched, injectBreakpointObserver, injectCanHover, injectColorPalette, injectColorScheme, injectColorThemes, injectColorThemesPrefix, injectCurrentBreakpoint, injectDefaultColorTheme, injectDefaultSurfaceTheme, injectDeviceInputType, injectDisplayOrientation, injectErrorTheme, injectFaviconStore, injectFileDownload, injectFocusVisibleTracker, injectFragment, injectHasPrecisionInput, injectHasTouchInput, injectHostElement, injectIs2Xl, injectIsDocumentVisible, injectIsLandscape, injectIsLg, injectIsMd, injectIsPortrait, injectIsRouterInitialized, injectIsSm, injectIsXl, injectIsXs, injectLinkStore, injectLinkStoreConfig, injectLocale, injectMediaQueryIsMatched, injectMetaConfig, injectMetaStore, injectNotifications, injectObserveBreakpoint, injectObserveMediaQuery, injectOverlayRuntime, injectParentSurface, injectPathParam, injectPathParamChanges, injectPathParams, injectPrefersReducedMotion, injectQueryParam, injectQueryParamAll, injectQueryParamChanges, injectQueryParams, injectRenderer, injectRootSurfaceTheme, injectRoute, injectRouteData, injectRouteDataItem, injectRouteTitle, injectRouterEvent, injectRouterNavigationState, injectRouterState, injectScrollbarDimensions, injectSemanticColorTheme, injectStructuredDataConfig, injectStructuredDataStore, injectStyleManager, injectSuccessTheme, injectSurfaceColorPalette, injectSurfaceContextTracker, injectSurfaceThemes, injectSurfaceThemesPrefix, injectSurfaceType, injectTemplateRef, injectTitleConfig, injectTitleStore, injectUnsavedChangesCoordinator, injectUrl, injectViewportConfig, injectViewportDimensions, injectViewportSize, injectWarningTheme, isAnimationDebugEnabled, isArray, isElement, isElementSignal, isElementVisible, isFocusable, isGroupMatch, isHTMLElement, isHTMLOrSVGElement, isKnockoutMatch, isObject, isOnHigherOverlayLayer, isSafeLinkUrl, isSafeUrl, isStaleBuildError, markdownToHtml, matchesReducedMotion, maybeSignalValue, memoizeSignal, mountEasingTokens, mountVisuallyHidden, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, normalizeUnsavedChangesSource, numberBreakpointTransform, onOverlayViewportInsetsChange, optionalBooleanAttribute, overlayViewportInsets, overlayViewportInsetsFor, ownsActiveElement, previousSignalValue, provideAppUpdates, provideAppUpdatesConfig, provideAppUpdatesInstance, provideBoundaryElement, provideBreakpointInstance, provideBreakpointObserver, provideColorPalette, provideColorScheme, provideColorThemes, provideColorThemesWithTailwind4, provideFaviconStore, provideFocusVisibleTracker, provideLinkStore, provideLinkStoreConfig, provideLocale, provideMetaConfig, provideMetaStore, provideNotifications, provideOverlayRuntime, provideRenderer, provideStructuredDataConfig, provideStructuredDataStore, provideStyleManager, provideSurfaceContextTracker, provideSurfaceThemesWithTailwind4, provideTitleConfig, provideTitleStore, provideUnsavedChangesConfirm, provideUnsavedChangesCoordinator, provideViewportConfig, randomId, readBuildFingerprint, readFromClipboard, reserveOverlayViewportSpace, resolveAppRootColorProvider, resolveColorThemeVariant, resolveOverlayLayer, resolveSurfaceByElevation, round, routerDisableScrollTop, routerRestoreScroll, scrollToElement, setCookie, setInputSignal, setupFocusTrap, setupPositioning, setupScrollRestoration, signalAnimatedNumber, signalAttributes, signalClasses, signalCountdown, signalDeferredLoading, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementLastScrollDirection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementLastScrollDirection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, slugify, suppressTextSelection, switchQueryListChanges, syncSignal, toArray, toArrayTrackByFn, toInjectFn, toProvideFn, toStringBinding, toToken, transformOrReturn, typedBreakpointTransform, useCursorDragScroll, writeScrollbarSizeToCssVariables, writeViewportSizeToCssVariables, ɵProvideColorThemes, ɵProvideColorThemesPrefix, ɵProvideSurfaceThemes, ɵProvideSurfaceThemesPrefix };
|
|
10876
|
+
export { ANIMATABLE_TOKEN, ANIMATED_IF_TOKEN, ANIMATED_LIFECYCLE_TOKEN, ANIMATION_DEBUG_STORAGE_KEY, ANIMATION_ERROR_CODES, AT_LEAST_ONE_REQUIRED, AnimatableDirective, AnimatedIfDirective, AnimatedLifecycleDirective, AutoSurfaceDirective, BOUNDARY_ELEMENT_TOKEN, BREAKPOINT_INSTANCE_TOKEN, BREAKPOINT_ORDER, COLOR_PALETTE, COLOR_PROVIDER, CORE_VERSION, ClickOutsideDirective, ColorInteractiveContainerDirective, ColorInteractiveDirective, ColorInteractiveExcludeDirective, ColorInteractiveHasFocusDirective, DEFAULT_MULTI_INSTANCE_RELS, DEFAULT_MULTI_INSTANCE_TAGS, DEFAULT_OVERLAY_LAYER, 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, ET_RESTORE_SCROLL, EasingTokensStylesComponent, EthleteValidators, FOCUSABLE_SELECTOR, FOCUS_VISIBLE_TRACKER_TOKEN, HtmlToMarkdownPipe, IS_ARRAY_NOT_EMPTY, IS_EMAIL, InferMimeTypePipe, InitialsPipe, IsArrayNotEmpty, IsEmail, jsonLd as JsonLD, KeyPressManager, MARKDOWN_VERBATIM_ATTR, MUST_MATCH, MarkdownToHtmlPipe, MatchStateType, MustMatch, NOTIFICATION_CLICK_MESSAGE_TYPE, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, OVERLAY_LAYER_ATTRIBUTE, ProvideColorDirective, ProvideSurfaceDirective, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeHandlesComponent, RestoreScrollDirective, RuntimeError, SURFACE_COLOR, SURFACE_PROVIDER, SURFACE_TYPE, SWIPE_VELOCITY_WINDOW_MS, ScrollObserverDirective, ScrollObserverEndDirective, ScrollObserverStartDirective, SlugifyPipe, StructuredDataComponent, SurfaceInteractiveDirective, ToArrayPipe, TypedQueryList, UNSAVED_CHANGES_CONFIRM, UNSAVED_CHANGES_ERROR_CODES, UNSAVED_CHANGES_TITLE_MARKER, ValidateAtLeastOneRequired, VisuallyHiddenStylesComponent, anchoredOverlayPosition, animationDebugLog, applyAlternateBinding, applyAlternateLanguagesBindings, applyArticleBindings, applyAuthorBinding, applyCanonicalBinding, applyCenteredPosition, applyDescriptionBinding, applyFaviconOverlay, applyGlobalPosition, applyHeadBinding, applyHeadTitleBinding, applyHeadTitleMarker, applyHostListener, applyHostListeners, applyInitialFocus, applyKeywordsBinding, applyLinkBinding, applyMetaBinding, applyNextBinding, applyOgBinding, applyOpenGraphBindings, applyPrevBinding, applyResourceHintsBindings, applyRobotsBinding, applySocialMediaBindings, applyStructuredDataBinding, applyTwitterCardBindings, boolBreakpointTransform, boundingClientRectToElementRect, breakpointTransformBase, buildElementSignal, buildSignalEffects, canUseSessionMemory, clamp, clone, cloneFormGroup, computedTillFalsy, computedTillTruthy, controlValueSignal, controlValueSignalWithPrevious, copyToClipboard, createAnchoredPositionCleanup, createArrayPropertyBinding, createAutoSessionMemoryKey, createCanAnimateSignal, createComponentId, createCssColorThemeName, createCssSurfaceName, createDestroy, createDocumentElementSignal, createElementDimensions, createEmptyElementSignal, createFlipAnimation, createFlipAnimationGroup, createIsRenderedSignal, createLogger, createObjectUrlHandle, createPropertyBinding, createRootThemeCss, createRoute, createRouterState, createRxHostListener, createSessionMemory, createSwatchCss, createSwipeTracker, createTailwindColorThemes, createTailwindCssVar, createTailwindRgbVar, createThemeStyle, createUnsavedChangesGuard, createUnsavedChangesTabLock, createUnsavedChangesTracker, createUserConsentProvider, deferredSignal, defineLabels, defineProvider, defineRootProvider, defineStaticProvider, defineStaticRootProvider, deleteCookie, dragGestureFrom, easeElastic, easeIn, easeInOut, easeLinear, easeOut, easeOutBack, easeOutBackStrong, elementCanScroll, enableAnchoredOverlayPositionExtras, equal, fetchDeployedBuildFingerprint$, firstElementSignal, focusElement, forceReflow, formatRuntimeError, fromNextFrame, getCookie, getDomain, getElementScrollCoordinates, getFocusableElements, getFormGroupValue, getGroupMatchPoints, getGroupMatchScore, getHeadingElement, getKnockoutMatchScore, getMatchScoreSubLine, getObjectProperty, getScrollContainerTarget, getScrollItemTarget, getScrollSnapTarget, hasAnchoredOverlayPositionExtras, hasCookie, holdScrollRestoration, htmlToMarkdown, inferMimeType, initials, injectAngularRootElement, injectAnimatedBlockSize, injectAppUpdates, injectAppUpdatesConfig, injectBoundaryElement, injectBreakpointInput, injectBreakpointIsMatched, injectBreakpointObserver, injectCanHover, injectColorPalette, injectColorScheme, injectColorThemes, injectColorThemesPrefix, injectCurrentBreakpoint, injectDefaultColorTheme, injectDefaultSurfaceTheme, injectDeviceInputType, injectDisplayOrientation, injectErrorTheme, injectFaviconStore, injectFileDownload, injectFocusVisibleTracker, injectFragment, injectHasPrecisionInput, injectHasTouchInput, injectHostElement, injectIs2Xl, injectIsDocumentVisible, injectIsLandscape, injectIsLg, injectIsMd, injectIsPortrait, injectIsRouterInitialized, injectIsSm, injectIsXl, injectIsXs, injectLinkStore, injectLinkStoreConfig, injectLocale, injectMediaQueryIsMatched, injectMetaConfig, injectMetaStore, injectNotifications, injectObserveBreakpoint, injectObserveMediaQuery, injectOverlayRuntime, injectParentSurface, injectPathParam, injectPathParamChanges, injectPathParams, injectPrefersReducedMotion, injectQueryParam, injectQueryParamAll, injectQueryParamChanges, injectQueryParams, injectRenderer, injectRootSurfaceTheme, injectRoute, injectRouteData, injectRouteDataItem, injectRouteTitle, injectRouterEvent, injectRouterNavigationState, injectRouterState, injectScrollbarDimensions, injectSemanticColorTheme, injectStructuredDataConfig, injectStructuredDataStore, injectStyleManager, injectSuccessTheme, injectSurfaceColorPalette, injectSurfaceContextTracker, injectSurfaceThemes, injectSurfaceThemesPrefix, injectSurfaceType, injectTemplateRef, injectTitleConfig, injectTitleStore, injectUnsavedChangesCoordinator, injectUrl, injectViewportConfig, injectViewportDimensions, injectViewportSize, injectWarningTheme, isAnimationDebugEnabled, isArray, isElement, isElementSignal, isElementVisible, isFocusable, isGroupMatch, isHTMLElement, isHTMLOrSVGElement, isKnockoutMatch, isObject, isOnHigherOverlayLayer, isSafeLinkUrl, isSafeUrl, isStaleBuildError, markdownToHtml, matchesReducedMotion, maybeSignalValue, memoizeSignal, mountEasingTokens, mountVisuallyHidden, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, normalizeUnsavedChangesSource, numberBreakpointTransform, onOverlayViewportInsetsChange, optionalBooleanAttribute, overlayViewportInsets, overlayViewportInsetsFor, ownsActiveElement, previousSignalValue, provideAppUpdates, provideAppUpdatesConfig, provideAppUpdatesInstance, provideBoundaryElement, provideBreakpointInstance, provideBreakpointObserver, provideColorPalette, provideColorScheme, provideColorThemes, provideColorThemesWithTailwind4, provideFaviconStore, provideFocusVisibleTracker, provideLinkStore, provideLinkStoreConfig, provideLocale, provideMetaConfig, provideMetaStore, provideNotifications, provideOverlayRuntime, provideRenderer, provideStructuredDataConfig, provideStructuredDataStore, provideStyleManager, provideSurfaceContextTracker, provideSurfaceThemesWithTailwind4, provideTitleConfig, provideTitleStore, provideUnsavedChangesConfirm, provideUnsavedChangesCoordinator, provideViewportConfig, randomId, readBuildFingerprint, readFromClipboard, registerScrollRestorationState, reserveOverlayViewportSpace, resolveAppRootColorProvider, resolveColorThemeVariant, resolveOverlayLayer, resolveSurfaceByElevation, round, routerDisableScrollTop, routerRestoreScroll, scrollToElement, setCookie, setInputSignal, setupFocusTrap, setupPositioning, setupScrollRestoration, signalAnimatedNumber, signalAttributes, signalClasses, signalCountdown, signalDeferredLoading, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementLastScrollDirection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementLastScrollDirection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, slugify, suppressTextSelection, switchQueryListChanges, syncSignal, toArray, toArrayTrackByFn, toInjectFn, toProvideFn, toStringBinding, toToken, transformOrReturn, typedBreakpointTransform, useCursorDragScroll, writeScrollbarSizeToCssVariables, writeViewportSizeToCssVariables, ɵProvideColorThemes, ɵProvideColorThemesPrefix, ɵProvideSurfaceThemes, ɵProvideSurfaceThemesPrefix };
|
|
10732
10877
|
//# sourceMappingURL=ethlete-core.mjs.map
|