@vectoriox/iox-ui 4.6.0 → 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.
@@ -2357,6 +2357,15 @@ const DEFAULT_PAGE_TRANSITION = 'parallax-up';
2357
2357
  const FADE_OUT = [{ opacity: 1 }, { opacity: 0 }];
2358
2358
  const FADE_IN = [{ opacity: 0 }, { opacity: 1 }];
2359
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)' }];
2360
2369
  // ── The preset catalog ──────────────────────────────────────────────────────
2361
2370
  // Keyed by a stable preset id persisted in pageSettings.routeAnimation.transition.
2362
2371
  const PAGE_TRANSITION_PRESETS = {
@@ -2400,24 +2409,114 @@ const PAGE_TRANSITION_PRESETS = {
2400
2409
  inKeyframes: move('translateX(-100%)', 'translateX(0)'),
2401
2410
  ontop: 'in',
2402
2411
  },
2403
- // ── Move (both pages slide; no fade — the classic Codrops "move") ──────────
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) ─────
2404
2503
  'move-left': {
2405
- category: 'move', label: 'Move left / from right',
2504
+ category: 'move', label: 'Push left',
2406
2505
  outKeyframes: move('translateX(0)', 'translateX(-100%)'),
2407
2506
  inKeyframes: move('translateX(100%)', 'translateX(0)'),
2408
2507
  },
2409
2508
  'move-right': {
2410
- category: 'move', label: 'Move right / from left',
2509
+ category: 'move', label: 'Push right',
2411
2510
  outKeyframes: move('translateX(0)', 'translateX(100%)'),
2412
2511
  inKeyframes: move('translateX(-100%)', 'translateX(0)'),
2413
2512
  },
2414
2513
  'move-up': {
2415
- category: 'move', label: 'Move up / from bottom',
2514
+ category: 'move', label: 'Push up',
2416
2515
  outKeyframes: move('translateY(0)', 'translateY(-100%)'),
2417
2516
  inKeyframes: move('translateY(100%)', 'translateY(0)'),
2418
2517
  },
2419
2518
  'move-down': {
2420
- category: 'move', label: 'Move down / from top',
2519
+ category: 'move', label: 'Push down',
2421
2520
  outKeyframes: move('translateY(0)', 'translateY(100%)'),
2422
2521
  inKeyframes: move('translateY(-100%)', 'translateY(0)'),
2423
2522
  },
@@ -2519,11 +2618,31 @@ const PAGE_TRANSITION_PRESETS = {
2519
2618
  outTransformOrigin: '100% 50%', inTransformOrigin: '0% 50%',
2520
2619
  },
2521
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
+ }
2522
2639
  /** Built from PAGE_TRANSITION_PRESETS so the two lists can never drift apart. */
2523
2640
  const PAGE_TRANSITION_CATEGORIES = (() => {
2524
2641
  const order = [
2525
2642
  { value: 'parallax', label: 'Smooth (parallax)' },
2526
- { value: 'move', label: 'Move' },
2643
+ { value: 'reveal', label: 'Reveal (mask)' },
2644
+ { value: 'curtain', label: 'Curtain (overlay)' },
2645
+ { value: 'move', label: 'Push / slide' },
2527
2646
  { value: 'fade', label: 'Fade' },
2528
2647
  { value: 'scale', label: 'Scale' },
2529
2648
  { value: 'rotate', label: 'Rotate / 3D' },
@@ -2575,6 +2694,14 @@ function resolvePageTransition(name, opts = {}) {
2575
2694
  perspective,
2576
2695
  outTransformOrigin: preset.outTransformOrigin,
2577
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
+ },
2578
2705
  };
2579
2706
  }
2580
2707
  /**
@@ -2633,5 +2760,5 @@ function effectiveTransitionId(anim) {
2633
2760
  * Generated bundle index. Do not edit.
2634
2761
  */
2635
2762
 
2636
- 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, 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 };
2637
2764
  //# sourceMappingURL=vectoriox-iox-ui.mjs.map