@vectoriox/iox-ui 4.5.2 → 4.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -2341,33 +2341,182 @@ function dataSourcePlanToRequest(plan, endpoints) {
|
|
|
2341
2341
|
*/
|
|
2342
2342
|
/** Perspective (px) applied to the transition container unless a preset overrides it. */
|
|
2343
2343
|
const DEFAULT_PAGE_TRANSITION_PERSPECTIVE = 1200;
|
|
2344
|
-
/**
|
|
2345
|
-
|
|
2344
|
+
/**
|
|
2345
|
+
* Default transition duration (ms). Deliberately long — a slow, settled transition is most of what
|
|
2346
|
+
* makes a page change read as "premium"; the same motion at ~400ms feels like a snap.
|
|
2347
|
+
*/
|
|
2348
|
+
const DEFAULT_PAGE_TRANSITION_DURATION = 1500;
|
|
2349
|
+
/**
|
|
2350
|
+
* Default easing: a strong symmetric in-out. Paired with the long duration this is the "smoothness"
|
|
2351
|
+
* — slow to leave, quick through the middle, gentle to settle.
|
|
2352
|
+
*/
|
|
2353
|
+
const DEFAULT_PAGE_TRANSITION_EASING = 'cubic-bezier(0.76, 0, 0.24, 1)';
|
|
2354
|
+
/** Default preset used when a page has no transition configured at all. */
|
|
2355
|
+
const DEFAULT_PAGE_TRANSITION = 'parallax-up';
|
|
2346
2356
|
// ── Keyframe helpers ────────────────────────────────────────────────────────
|
|
2347
2357
|
const FADE_OUT = [{ opacity: 1 }, { opacity: 0 }];
|
|
2348
2358
|
const FADE_IN = [{ opacity: 0 }, { opacity: 1 }];
|
|
2349
2359
|
const move = (from, to) => [{ transform: from }, { transform: to }];
|
|
2360
|
+
/** Gentle recede for the outgoing page under a mask/reveal — it stays put but drops back a little,
|
|
2361
|
+
* so the page underneath never looks like a frozen screenshot. */
|
|
2362
|
+
const RECEDE_SOFT = [
|
|
2363
|
+
{ transform: 'scale(1)', opacity: 1 },
|
|
2364
|
+
{ transform: 'scale(0.94)', opacity: 0.6 },
|
|
2365
|
+
];
|
|
2366
|
+
/** Barely-there settle for the incoming page under a curtain — the panel hides most of it, so this
|
|
2367
|
+
* only takes the edge off the reveal. Ends at identity (required: IN frames must not persist). */
|
|
2368
|
+
const SETTLE_IN = [{ transform: 'scale(1.04)' }, { transform: 'scale(1)' }];
|
|
2350
2369
|
// ── The preset catalog ──────────────────────────────────────────────────────
|
|
2351
2370
|
// Keyed by a stable preset id persisted in pageSettings.routeAnimation.transition.
|
|
2352
2371
|
const PAGE_TRANSITION_PRESETS = {
|
|
2353
|
-
// ──
|
|
2372
|
+
// ── Parallax (the default family) ──────────────────────────────────────────
|
|
2373
|
+
// The outgoing page travels only HALF the distance while shrinking and dimming, so it recedes
|
|
2374
|
+
// *behind* the incoming page rather than sliding away. That travel difference (50% vs 100%) is
|
|
2375
|
+
// what reads as depth — there is no 3D here at all. Pair with the long default duration.
|
|
2376
|
+
'parallax-up': {
|
|
2377
|
+
category: 'parallax', label: 'Parallax up (recommended)',
|
|
2378
|
+
outKeyframes: [
|
|
2379
|
+
{ transform: 'translateY(0) scale(1)', opacity: 1 },
|
|
2380
|
+
{ transform: 'translateY(-50%) scale(0.8)', opacity: 0.4 },
|
|
2381
|
+
],
|
|
2382
|
+
inKeyframes: move('translateY(100%)', 'translateY(0)'),
|
|
2383
|
+
ontop: 'in',
|
|
2384
|
+
},
|
|
2385
|
+
'parallax-down': {
|
|
2386
|
+
category: 'parallax', label: 'Parallax down',
|
|
2387
|
+
outKeyframes: [
|
|
2388
|
+
{ transform: 'translateY(0) scale(1)', opacity: 1 },
|
|
2389
|
+
{ transform: 'translateY(50%) scale(0.8)', opacity: 0.4 },
|
|
2390
|
+
],
|
|
2391
|
+
inKeyframes: move('translateY(-100%)', 'translateY(0)'),
|
|
2392
|
+
ontop: 'in',
|
|
2393
|
+
},
|
|
2394
|
+
'parallax-left': {
|
|
2395
|
+
category: 'parallax', label: 'Parallax left',
|
|
2396
|
+
outKeyframes: [
|
|
2397
|
+
{ transform: 'translateX(0) scale(1)', opacity: 1 },
|
|
2398
|
+
{ transform: 'translateX(-50%) scale(0.8)', opacity: 0.4 },
|
|
2399
|
+
],
|
|
2400
|
+
inKeyframes: move('translateX(100%)', 'translateX(0)'),
|
|
2401
|
+
ontop: 'in',
|
|
2402
|
+
},
|
|
2403
|
+
'parallax-right': {
|
|
2404
|
+
category: 'parallax', label: 'Parallax right',
|
|
2405
|
+
outKeyframes: [
|
|
2406
|
+
{ transform: 'translateX(0) scale(1)', opacity: 1 },
|
|
2407
|
+
{ transform: 'translateX(50%) scale(0.8)', opacity: 0.4 },
|
|
2408
|
+
],
|
|
2409
|
+
inKeyframes: move('translateX(-100%)', 'translateX(0)'),
|
|
2410
|
+
ontop: 'in',
|
|
2411
|
+
},
|
|
2412
|
+
// ── Reveal (clip-path) ─────────────────────────────────────────────────────
|
|
2413
|
+
// The incoming page is UNMASKED over the outgoing one, which recedes gently behind. No overlay
|
|
2414
|
+
// panel is involved — the mask is animated directly on the incoming layer, so this needs no
|
|
2415
|
+
// extra DOM. (WAAPI interpolates clip-path only between the SAME shape function with the same
|
|
2416
|
+
// number of points — keep each pair consistent.)
|
|
2417
|
+
'circle-reveal': {
|
|
2418
|
+
category: 'reveal', label: 'Circle reveal (iris)',
|
|
2419
|
+
outKeyframes: RECEDE_SOFT,
|
|
2420
|
+
inKeyframes: [
|
|
2421
|
+
{ clipPath: 'circle(0% at 50% 50%)' },
|
|
2422
|
+
{ clipPath: 'circle(75% at 50% 50%)' },
|
|
2423
|
+
],
|
|
2424
|
+
ontop: 'in',
|
|
2425
|
+
},
|
|
2426
|
+
'wipe-right': {
|
|
2427
|
+
category: 'reveal', label: 'Wipe → right',
|
|
2428
|
+
outKeyframes: RECEDE_SOFT,
|
|
2429
|
+
inKeyframes: [{ clipPath: 'inset(0 100% 0 0)' }, { clipPath: 'inset(0 0 0 0)' }],
|
|
2430
|
+
ontop: 'in',
|
|
2431
|
+
},
|
|
2432
|
+
'wipe-left': {
|
|
2433
|
+
category: 'reveal', label: 'Wipe ← left',
|
|
2434
|
+
outKeyframes: RECEDE_SOFT,
|
|
2435
|
+
inKeyframes: [{ clipPath: 'inset(0 0 0 100%)' }, { clipPath: 'inset(0 0 0 0)' }],
|
|
2436
|
+
ontop: 'in',
|
|
2437
|
+
},
|
|
2438
|
+
'wipe-down': {
|
|
2439
|
+
category: 'reveal', label: 'Wipe ↓ down',
|
|
2440
|
+
outKeyframes: RECEDE_SOFT,
|
|
2441
|
+
inKeyframes: [{ clipPath: 'inset(0 0 100% 0)' }, { clipPath: 'inset(0 0 0 0)' }],
|
|
2442
|
+
ontop: 'in',
|
|
2443
|
+
},
|
|
2444
|
+
'wipe-up': {
|
|
2445
|
+
category: 'reveal', label: 'Wipe ↑ up',
|
|
2446
|
+
outKeyframes: RECEDE_SOFT,
|
|
2447
|
+
inKeyframes: [{ clipPath: 'inset(100% 0 0 0)' }, { clipPath: 'inset(0 0 0 0)' }],
|
|
2448
|
+
ontop: 'in',
|
|
2449
|
+
},
|
|
2450
|
+
'diagonal-wipe': {
|
|
2451
|
+
category: 'reveal', label: 'Diagonal wipe',
|
|
2452
|
+
outKeyframes: RECEDE_SOFT,
|
|
2453
|
+
// 4-point polygons on both ends so WAAPI can interpolate them.
|
|
2454
|
+
inKeyframes: [
|
|
2455
|
+
{ clipPath: 'polygon(0% 0%, 0% 0%, -40% 100%, -40% 100%)' },
|
|
2456
|
+
{ clipPath: 'polygon(0% 0%, 140% 0%, 100% 100%, -40% 100%)' },
|
|
2457
|
+
],
|
|
2458
|
+
ontop: 'in',
|
|
2459
|
+
},
|
|
2460
|
+
'inset-reveal': {
|
|
2461
|
+
category: 'reveal', label: 'Box reveal (from centre)',
|
|
2462
|
+
outKeyframes: RECEDE_SOFT,
|
|
2463
|
+
inKeyframes: [{ clipPath: 'inset(50% 50% 50% 50%)' }, { clipPath: 'inset(0 0 0 0)' }],
|
|
2464
|
+
ontop: 'in',
|
|
2465
|
+
},
|
|
2466
|
+
// ── Curtain (overlay panel sweeps across, hiding the swap) ────────────────
|
|
2467
|
+
// A solid panel covers the screen, the outgoing page is dropped behind it, then the panel
|
|
2468
|
+
// sweeps away revealing the incoming page. Colour comes from routeAnimation.curtainColor, or
|
|
2469
|
+
// the incoming page's own background.
|
|
2470
|
+
'curtain-up': {
|
|
2471
|
+
category: 'curtain', label: 'Curtain up',
|
|
2472
|
+
outKeyframes: RECEDE_SOFT, inKeyframes: SETTLE_IN, ontop: 'in',
|
|
2473
|
+
overlay: {
|
|
2474
|
+
coverKeyframes: move('translateY(100%)', 'translateY(0)'),
|
|
2475
|
+
uncoverKeyframes: move('translateY(0)', 'translateY(-100%)'),
|
|
2476
|
+
},
|
|
2477
|
+
},
|
|
2478
|
+
'curtain-down': {
|
|
2479
|
+
category: 'curtain', label: 'Curtain down',
|
|
2480
|
+
outKeyframes: RECEDE_SOFT, inKeyframes: SETTLE_IN, ontop: 'in',
|
|
2481
|
+
overlay: {
|
|
2482
|
+
coverKeyframes: move('translateY(-100%)', 'translateY(0)'),
|
|
2483
|
+
uncoverKeyframes: move('translateY(0)', 'translateY(100%)'),
|
|
2484
|
+
},
|
|
2485
|
+
},
|
|
2486
|
+
'curtain-left': {
|
|
2487
|
+
category: 'curtain', label: 'Curtain left',
|
|
2488
|
+
outKeyframes: RECEDE_SOFT, inKeyframes: SETTLE_IN, ontop: 'in',
|
|
2489
|
+
overlay: {
|
|
2490
|
+
coverKeyframes: move('translateX(100%)', 'translateX(0)'),
|
|
2491
|
+
uncoverKeyframes: move('translateX(0)', 'translateX(-100%)'),
|
|
2492
|
+
},
|
|
2493
|
+
},
|
|
2494
|
+
'curtain-right': {
|
|
2495
|
+
category: 'curtain', label: 'Curtain right',
|
|
2496
|
+
outKeyframes: RECEDE_SOFT, inKeyframes: SETTLE_IN, ontop: 'in',
|
|
2497
|
+
overlay: {
|
|
2498
|
+
coverKeyframes: move('translateX(-100%)', 'translateX(0)'),
|
|
2499
|
+
uncoverKeyframes: move('translateX(0)', 'translateX(100%)'),
|
|
2500
|
+
},
|
|
2501
|
+
},
|
|
2502
|
+
// ── Move / Push (both pages travel the full distance, side by side — no overlap) ─────
|
|
2354
2503
|
'move-left': {
|
|
2355
|
-
category: 'move', label: '
|
|
2504
|
+
category: 'move', label: 'Push left',
|
|
2356
2505
|
outKeyframes: move('translateX(0)', 'translateX(-100%)'),
|
|
2357
2506
|
inKeyframes: move('translateX(100%)', 'translateX(0)'),
|
|
2358
2507
|
},
|
|
2359
2508
|
'move-right': {
|
|
2360
|
-
category: 'move', label: '
|
|
2509
|
+
category: 'move', label: 'Push right',
|
|
2361
2510
|
outKeyframes: move('translateX(0)', 'translateX(100%)'),
|
|
2362
2511
|
inKeyframes: move('translateX(-100%)', 'translateX(0)'),
|
|
2363
2512
|
},
|
|
2364
2513
|
'move-up': {
|
|
2365
|
-
category: 'move', label: '
|
|
2514
|
+
category: 'move', label: 'Push up',
|
|
2366
2515
|
outKeyframes: move('translateY(0)', 'translateY(-100%)'),
|
|
2367
2516
|
inKeyframes: move('translateY(100%)', 'translateY(0)'),
|
|
2368
2517
|
},
|
|
2369
2518
|
'move-down': {
|
|
2370
|
-
category: 'move', label: '
|
|
2519
|
+
category: 'move', label: 'Push down',
|
|
2371
2520
|
outKeyframes: move('translateY(0)', 'translateY(100%)'),
|
|
2372
2521
|
inKeyframes: move('translateY(-100%)', 'translateY(0)'),
|
|
2373
2522
|
},
|
|
@@ -2469,10 +2618,31 @@ const PAGE_TRANSITION_PRESETS = {
|
|
|
2469
2618
|
outTransformOrigin: '100% 50%', inTransformOrigin: '0% 50%',
|
|
2470
2619
|
},
|
|
2471
2620
|
};
|
|
2621
|
+
const TRANSITION_FEELS = [
|
|
2622
|
+
{ value: 'calm', label: 'Calm', duration: 1800, easing: 'cubic-bezier(0.33, 1, 0.68, 1)', description: 'Slow and unhurried — editorial, luxury' },
|
|
2623
|
+
{ value: 'cinematic', label: 'Cinematic', duration: 1500, easing: DEFAULT_PAGE_TRANSITION_EASING, description: 'Long settle with a strong middle — the default' },
|
|
2624
|
+
{ value: 'smooth', label: 'Smooth', duration: 1200, easing: 'cubic-bezier(0.16, 1, 0.3, 1)', description: 'Quick out of the gate, glides to a stop' },
|
|
2625
|
+
{ value: 'snappy', label: 'Snappy', duration: 600, easing: 'cubic-bezier(0.16, 1, 0.3, 1)', description: 'Fast and responsive — app-like' },
|
|
2626
|
+
{ value: 'crazy', label: 'Crazy', duration: 900, easing: 'cubic-bezier(0.68, -0.6, 0.32, 1.6)', description: 'Overshoots and springs back' },
|
|
2627
|
+
];
|
|
2628
|
+
/** The feel matching this duration+easing exactly, else 'custom'. Drives the panel's selector. */
|
|
2629
|
+
function feelFor(duration, easing) {
|
|
2630
|
+
const d = toFiniteNumber(duration, DEFAULT_PAGE_TRANSITION_DURATION);
|
|
2631
|
+
const e = easing || DEFAULT_PAGE_TRANSITION_EASING;
|
|
2632
|
+
return TRANSITION_FEELS.find(f => f.duration === d && f.easing === e)?.value ?? 'custom';
|
|
2633
|
+
}
|
|
2634
|
+
/** The duration+easing patch for a feel id (undefined for 'custom' / unknown). */
|
|
2635
|
+
function applyFeel(feel) {
|
|
2636
|
+
const f = TRANSITION_FEELS.find(x => x.value === feel);
|
|
2637
|
+
return f ? { duration: f.duration, easing: f.easing } : undefined;
|
|
2638
|
+
}
|
|
2472
2639
|
/** Built from PAGE_TRANSITION_PRESETS so the two lists can never drift apart. */
|
|
2473
2640
|
const PAGE_TRANSITION_CATEGORIES = (() => {
|
|
2474
2641
|
const order = [
|
|
2475
|
-
{ value: '
|
|
2642
|
+
{ value: 'parallax', label: 'Smooth (parallax)' },
|
|
2643
|
+
{ value: 'reveal', label: 'Reveal (mask)' },
|
|
2644
|
+
{ value: 'curtain', label: 'Curtain (overlay)' },
|
|
2645
|
+
{ value: 'move', label: 'Push / slide' },
|
|
2476
2646
|
{ value: 'fade', label: 'Fade' },
|
|
2477
2647
|
{ value: 'scale', label: 'Scale' },
|
|
2478
2648
|
{ value: 'rotate', label: 'Rotate / 3D' },
|
|
@@ -2504,7 +2674,7 @@ function resolvePageTransition(name, opts = {}) {
|
|
|
2504
2674
|
// the single point where these values become animation options, so every consumer is protected
|
|
2505
2675
|
// and already-saved string data keeps working.
|
|
2506
2676
|
const duration = toFiniteNumber(opts.duration, DEFAULT_PAGE_TRANSITION_DURATION);
|
|
2507
|
-
const easing = opts.easing
|
|
2677
|
+
const easing = opts.easing || DEFAULT_PAGE_TRANSITION_EASING;
|
|
2508
2678
|
const perspective = toFiniteNumber(preset.perspective ?? opts.perspective, DEFAULT_PAGE_TRANSITION_PERSPECTIVE);
|
|
2509
2679
|
const clampRatio = (r) => Math.max(0, Math.min(1, r ?? 0));
|
|
2510
2680
|
const outDelay = clampRatio(preset.outDelayRatio) * duration;
|
|
@@ -2524,6 +2694,14 @@ function resolvePageTransition(name, opts = {}) {
|
|
|
2524
2694
|
perspective,
|
|
2525
2695
|
outTransformOrigin: preset.outTransformOrigin,
|
|
2526
2696
|
inTransformOrigin: preset.inTransformOrigin,
|
|
2697
|
+
overlay: preset.overlay && {
|
|
2698
|
+
coverFrames: preset.overlay.coverKeyframes,
|
|
2699
|
+
uncoverFrames: preset.overlay.uncoverKeyframes,
|
|
2700
|
+
// Cover and uncover split the total duration; 'both' holds the panel in place between
|
|
2701
|
+
// the two halves so the swap is never visible through a gap.
|
|
2702
|
+
coverOptions: { duration: duration / 2, easing, fill: 'both' },
|
|
2703
|
+
uncoverOptions: { duration: duration / 2, easing, fill: 'both' },
|
|
2704
|
+
},
|
|
2527
2705
|
};
|
|
2528
2706
|
}
|
|
2529
2707
|
/**
|
|
@@ -2558,7 +2736,8 @@ function legacyEnterToTransition(enter) {
|
|
|
2558
2736
|
case 'blurIn': return 'fade';
|
|
2559
2737
|
case 'flip': return 'flip';
|
|
2560
2738
|
case 'fade': return 'fade';
|
|
2561
|
-
default
|
|
2739
|
+
// Never configured (or an unrecognised value) → the default parallax transition.
|
|
2740
|
+
default: return DEFAULT_PAGE_TRANSITION;
|
|
2562
2741
|
}
|
|
2563
2742
|
}
|
|
2564
2743
|
/**
|
|
@@ -2567,7 +2746,7 @@ function legacyEnterToTransition(enter) {
|
|
|
2567
2746
|
*/
|
|
2568
2747
|
function effectiveTransitionId(anim) {
|
|
2569
2748
|
if (!anim)
|
|
2570
|
-
return
|
|
2749
|
+
return DEFAULT_PAGE_TRANSITION;
|
|
2571
2750
|
if (anim.transition)
|
|
2572
2751
|
return anim.transition;
|
|
2573
2752
|
return legacyEnterToTransition(anim.enter);
|
|
@@ -2581,5 +2760,5 @@ function effectiveTransitionId(anim) {
|
|
|
2581
2760
|
* Generated bundle index. Do not edit.
|
|
2582
2761
|
*/
|
|
2583
2762
|
|
|
2584
|
-
export { AOSService, AnalyticsService, BuilderButtonComponent, BuilderDividerComponent, BuilderHeadingComponent, BuilderIconComponent, BuilderImageComponent, BuilderLinkComponent, BuilderSpacerComponent, ButtonBlockComponent, CMSClientInfraModule, CardComponent, ClientListComponent, ClientListItemComponent, ClientRepeaterComponent, ClientSliderContainerComponent, ClientSliderSlideComponent, ComponentInstanceRegistryService, ConsentService, ContainerComponent, ContentService, DEFAULT_PAGE_TRANSITION_DURATION, DEFAULT_PAGE_TRANSITION_PERSPECTIVE, DEFAULT_WIDTH_BY_TYPE, ENVIRONMENT, IOX_BUILDER_EVENTS, IS_PREVIEW, IoxAnimateContainer, IoxAosDirective, IoxAosModule, IoxBuilderComponentsModule, IoxComponentRegistryService, IoxPageComponent, IoxPageModule, IoxUiModule, LinkedContainerComponent, PAGE_TRANSITION_CATEGORIES, PAGE_TRANSITION_PRESETS, PageScrollProvider, PrivacyModalComponent, PrivacyModalService, PrivacyModelEvent, SectionComponent, TextBlockComponent, VIRTUAL_TRAIT_KEYS, ViewPositionDirective, ViewPositionModule, WebSettingsService, buildDataSourceFilter, buildTransitionTimeline, compileDeclarations, composeVirtualTraits, dataSourcePlanToRequest, effectiveTransitionId, legacyEnterToTransition, matchRouteParams, normalizeCollectionResult, planDataSource, renderDefaultDeclarations, resolvePageTransition, resolveSingleItemId, rewriteViewportUnits, styleKeyToKebab };
|
|
2763
|
+
export { AOSService, AnalyticsService, BuilderButtonComponent, BuilderDividerComponent, BuilderHeadingComponent, BuilderIconComponent, BuilderImageComponent, BuilderLinkComponent, BuilderSpacerComponent, ButtonBlockComponent, CMSClientInfraModule, CardComponent, ClientListComponent, ClientListItemComponent, ClientRepeaterComponent, ClientSliderContainerComponent, ClientSliderSlideComponent, ComponentInstanceRegistryService, ConsentService, ContainerComponent, ContentService, DEFAULT_PAGE_TRANSITION, DEFAULT_PAGE_TRANSITION_DURATION, DEFAULT_PAGE_TRANSITION_EASING, DEFAULT_PAGE_TRANSITION_PERSPECTIVE, DEFAULT_WIDTH_BY_TYPE, ENVIRONMENT, IOX_BUILDER_EVENTS, IS_PREVIEW, IoxAnimateContainer, IoxAosDirective, IoxAosModule, IoxBuilderComponentsModule, IoxComponentRegistryService, IoxPageComponent, IoxPageModule, IoxUiModule, LinkedContainerComponent, PAGE_TRANSITION_CATEGORIES, PAGE_TRANSITION_PRESETS, PageScrollProvider, PrivacyModalComponent, PrivacyModalService, PrivacyModelEvent, SectionComponent, TRANSITION_FEELS, TextBlockComponent, VIRTUAL_TRAIT_KEYS, ViewPositionDirective, ViewPositionModule, WebSettingsService, applyFeel, buildDataSourceFilter, buildTransitionTimeline, compileDeclarations, composeVirtualTraits, dataSourcePlanToRequest, effectiveTransitionId, feelFor, legacyEnterToTransition, matchRouteParams, normalizeCollectionResult, planDataSource, renderDefaultDeclarations, resolvePageTransition, resolveSingleItemId, rewriteViewportUnits, styleKeyToKebab };
|
|
2585
2764
|
//# sourceMappingURL=vectoriox-iox-ui.mjs.map
|