@vectoriox/iox-ui 4.6.0 → 4.7.1

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.
@@ -2060,10 +2060,18 @@ function renderDefaultDeclarations(type, styleProps, hasHoverState) {
2060
2060
  if (type === 'LinkedContainer' && sp['display'] === undefined) {
2061
2061
  out.push('display: block');
2062
2062
  }
2063
- // NOTE: no Icon line-height/display default here both `lineHeight` and `display` are style
2064
- // traits serialized into the icon's styleProps (self-describing node), so they come through
2065
- // compileDeclarations on both sides. The icon's line-height:1 is set at the source in the builder
2066
- // icon config (applyStyleDefaults); reapplying it here would only ever be a skipped no-op.
2063
+ // An Icon is a single FONT GLYPH, not a paragraph: its line box must hug the glyph (the universal
2064
+ // icon-font convention Phosphor/FontAwesome/Material all set line-height:1). But every node
2065
+ // serialises the Typography group's `lineHeight` default of 1.5, so icons saved before that
2066
+ // default was corrected carry `line-height: 1.5` a 24px glyph then gets a 36px line box and
2067
+ // pushes the surrounding layout around.
2068
+ //
2069
+ // This is emitted UNCONDITIONALLY (not guarded on `undefined`) and callers append render-defaults
2070
+ // AFTER the node's own compiled declarations in the SAME rule, so it overrides a stale serialised
2071
+ // 1.5 for EXISTING icons too — no re-save needed. line-height is inherited, so simply omitting it
2072
+ // is not enough: the icon would inherit 1.5 from its container instead.
2073
+ if (type === 'Icon')
2074
+ out.push('line-height: 1');
2067
2075
  return out;
2068
2076
  }
2069
2077
 
@@ -2357,6 +2365,15 @@ const DEFAULT_PAGE_TRANSITION = 'parallax-up';
2357
2365
  const FADE_OUT = [{ opacity: 1 }, { opacity: 0 }];
2358
2366
  const FADE_IN = [{ opacity: 0 }, { opacity: 1 }];
2359
2367
  const move = (from, to) => [{ transform: from }, { transform: to }];
2368
+ /** Gentle recede for the outgoing page under a mask/reveal — it stays put but drops back a little,
2369
+ * so the page underneath never looks like a frozen screenshot. */
2370
+ const RECEDE_SOFT = [
2371
+ { transform: 'scale(1)', opacity: 1 },
2372
+ { transform: 'scale(0.94)', opacity: 0.6 },
2373
+ ];
2374
+ /** Barely-there settle for the incoming page under a curtain — the panel hides most of it, so this
2375
+ * only takes the edge off the reveal. Ends at identity (required: IN frames must not persist). */
2376
+ const SETTLE_IN = [{ transform: 'scale(1.04)' }, { transform: 'scale(1)' }];
2360
2377
  // ── The preset catalog ──────────────────────────────────────────────────────
2361
2378
  // Keyed by a stable preset id persisted in pageSettings.routeAnimation.transition.
2362
2379
  const PAGE_TRANSITION_PRESETS = {
@@ -2400,24 +2417,114 @@ const PAGE_TRANSITION_PRESETS = {
2400
2417
  inKeyframes: move('translateX(-100%)', 'translateX(0)'),
2401
2418
  ontop: 'in',
2402
2419
  },
2403
- // ── Move (both pages slide; no fade — the classic Codrops "move") ──────────
2420
+ // ── Reveal (clip-path) ─────────────────────────────────────────────────────
2421
+ // The incoming page is UNMASKED over the outgoing one, which recedes gently behind. No overlay
2422
+ // panel is involved — the mask is animated directly on the incoming layer, so this needs no
2423
+ // extra DOM. (WAAPI interpolates clip-path only between the SAME shape function with the same
2424
+ // number of points — keep each pair consistent.)
2425
+ 'circle-reveal': {
2426
+ category: 'reveal', label: 'Circle reveal (iris)',
2427
+ outKeyframes: RECEDE_SOFT,
2428
+ inKeyframes: [
2429
+ { clipPath: 'circle(0% at 50% 50%)' },
2430
+ { clipPath: 'circle(75% at 50% 50%)' },
2431
+ ],
2432
+ ontop: 'in',
2433
+ },
2434
+ 'wipe-right': {
2435
+ category: 'reveal', label: 'Wipe → right',
2436
+ outKeyframes: RECEDE_SOFT,
2437
+ inKeyframes: [{ clipPath: 'inset(0 100% 0 0)' }, { clipPath: 'inset(0 0 0 0)' }],
2438
+ ontop: 'in',
2439
+ },
2440
+ 'wipe-left': {
2441
+ category: 'reveal', label: 'Wipe ← left',
2442
+ outKeyframes: RECEDE_SOFT,
2443
+ inKeyframes: [{ clipPath: 'inset(0 0 0 100%)' }, { clipPath: 'inset(0 0 0 0)' }],
2444
+ ontop: 'in',
2445
+ },
2446
+ 'wipe-down': {
2447
+ category: 'reveal', label: 'Wipe ↓ down',
2448
+ outKeyframes: RECEDE_SOFT,
2449
+ inKeyframes: [{ clipPath: 'inset(0 0 100% 0)' }, { clipPath: 'inset(0 0 0 0)' }],
2450
+ ontop: 'in',
2451
+ },
2452
+ 'wipe-up': {
2453
+ category: 'reveal', label: 'Wipe ↑ up',
2454
+ outKeyframes: RECEDE_SOFT,
2455
+ inKeyframes: [{ clipPath: 'inset(100% 0 0 0)' }, { clipPath: 'inset(0 0 0 0)' }],
2456
+ ontop: 'in',
2457
+ },
2458
+ 'diagonal-wipe': {
2459
+ category: 'reveal', label: 'Diagonal wipe',
2460
+ outKeyframes: RECEDE_SOFT,
2461
+ // 4-point polygons on both ends so WAAPI can interpolate them.
2462
+ inKeyframes: [
2463
+ { clipPath: 'polygon(0% 0%, 0% 0%, -40% 100%, -40% 100%)' },
2464
+ { clipPath: 'polygon(0% 0%, 140% 0%, 100% 100%, -40% 100%)' },
2465
+ ],
2466
+ ontop: 'in',
2467
+ },
2468
+ 'inset-reveal': {
2469
+ category: 'reveal', label: 'Box reveal (from centre)',
2470
+ outKeyframes: RECEDE_SOFT,
2471
+ inKeyframes: [{ clipPath: 'inset(50% 50% 50% 50%)' }, { clipPath: 'inset(0 0 0 0)' }],
2472
+ ontop: 'in',
2473
+ },
2474
+ // ── Curtain (overlay panel sweeps across, hiding the swap) ────────────────
2475
+ // A solid panel covers the screen, the outgoing page is dropped behind it, then the panel
2476
+ // sweeps away revealing the incoming page. Colour comes from routeAnimation.curtainColor, or
2477
+ // the incoming page's own background.
2478
+ 'curtain-up': {
2479
+ category: 'curtain', label: 'Curtain up',
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-down': {
2487
+ category: 'curtain', label: 'Curtain down',
2488
+ outKeyframes: RECEDE_SOFT, inKeyframes: SETTLE_IN, ontop: 'in',
2489
+ overlay: {
2490
+ coverKeyframes: move('translateY(-100%)', 'translateY(0)'),
2491
+ uncoverKeyframes: move('translateY(0)', 'translateY(100%)'),
2492
+ },
2493
+ },
2494
+ 'curtain-left': {
2495
+ category: 'curtain', label: 'Curtain left',
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
+ 'curtain-right': {
2503
+ category: 'curtain', label: 'Curtain right',
2504
+ outKeyframes: RECEDE_SOFT, inKeyframes: SETTLE_IN, ontop: 'in',
2505
+ overlay: {
2506
+ coverKeyframes: move('translateX(-100%)', 'translateX(0)'),
2507
+ uncoverKeyframes: move('translateX(0)', 'translateX(100%)'),
2508
+ },
2509
+ },
2510
+ // ── Move / Push (both pages travel the full distance, side by side — no overlap) ─────
2404
2511
  'move-left': {
2405
- category: 'move', label: 'Move left / from right',
2512
+ category: 'move', label: 'Push left',
2406
2513
  outKeyframes: move('translateX(0)', 'translateX(-100%)'),
2407
2514
  inKeyframes: move('translateX(100%)', 'translateX(0)'),
2408
2515
  },
2409
2516
  'move-right': {
2410
- category: 'move', label: 'Move right / from left',
2517
+ category: 'move', label: 'Push right',
2411
2518
  outKeyframes: move('translateX(0)', 'translateX(100%)'),
2412
2519
  inKeyframes: move('translateX(-100%)', 'translateX(0)'),
2413
2520
  },
2414
2521
  'move-up': {
2415
- category: 'move', label: 'Move up / from bottom',
2522
+ category: 'move', label: 'Push up',
2416
2523
  outKeyframes: move('translateY(0)', 'translateY(-100%)'),
2417
2524
  inKeyframes: move('translateY(100%)', 'translateY(0)'),
2418
2525
  },
2419
2526
  'move-down': {
2420
- category: 'move', label: 'Move down / from top',
2527
+ category: 'move', label: 'Push down',
2421
2528
  outKeyframes: move('translateY(0)', 'translateY(100%)'),
2422
2529
  inKeyframes: move('translateY(-100%)', 'translateY(0)'),
2423
2530
  },
@@ -2519,11 +2626,31 @@ const PAGE_TRANSITION_PRESETS = {
2519
2626
  outTransformOrigin: '100% 50%', inTransformOrigin: '0% 50%',
2520
2627
  },
2521
2628
  };
2629
+ const TRANSITION_FEELS = [
2630
+ { value: 'calm', label: 'Calm', duration: 1800, easing: 'cubic-bezier(0.33, 1, 0.68, 1)', description: 'Slow and unhurried — editorial, luxury' },
2631
+ { value: 'cinematic', label: 'Cinematic', duration: 1500, easing: DEFAULT_PAGE_TRANSITION_EASING, description: 'Long settle with a strong middle — the default' },
2632
+ { 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' },
2633
+ { value: 'snappy', label: 'Snappy', duration: 600, easing: 'cubic-bezier(0.16, 1, 0.3, 1)', description: 'Fast and responsive — app-like' },
2634
+ { value: 'crazy', label: 'Crazy', duration: 900, easing: 'cubic-bezier(0.68, -0.6, 0.32, 1.6)', description: 'Overshoots and springs back' },
2635
+ ];
2636
+ /** The feel matching this duration+easing exactly, else 'custom'. Drives the panel's selector. */
2637
+ function feelFor(duration, easing) {
2638
+ const d = toFiniteNumber(duration, DEFAULT_PAGE_TRANSITION_DURATION);
2639
+ const e = easing || DEFAULT_PAGE_TRANSITION_EASING;
2640
+ return TRANSITION_FEELS.find(f => f.duration === d && f.easing === e)?.value ?? 'custom';
2641
+ }
2642
+ /** The duration+easing patch for a feel id (undefined for 'custom' / unknown). */
2643
+ function applyFeel(feel) {
2644
+ const f = TRANSITION_FEELS.find(x => x.value === feel);
2645
+ return f ? { duration: f.duration, easing: f.easing } : undefined;
2646
+ }
2522
2647
  /** Built from PAGE_TRANSITION_PRESETS so the two lists can never drift apart. */
2523
2648
  const PAGE_TRANSITION_CATEGORIES = (() => {
2524
2649
  const order = [
2525
2650
  { value: 'parallax', label: 'Smooth (parallax)' },
2526
- { value: 'move', label: 'Move' },
2651
+ { value: 'reveal', label: 'Reveal (mask)' },
2652
+ { value: 'curtain', label: 'Curtain (overlay)' },
2653
+ { value: 'move', label: 'Push / slide' },
2527
2654
  { value: 'fade', label: 'Fade' },
2528
2655
  { value: 'scale', label: 'Scale' },
2529
2656
  { value: 'rotate', label: 'Rotate / 3D' },
@@ -2575,6 +2702,14 @@ function resolvePageTransition(name, opts = {}) {
2575
2702
  perspective,
2576
2703
  outTransformOrigin: preset.outTransformOrigin,
2577
2704
  inTransformOrigin: preset.inTransformOrigin,
2705
+ overlay: preset.overlay && {
2706
+ coverFrames: preset.overlay.coverKeyframes,
2707
+ uncoverFrames: preset.overlay.uncoverKeyframes,
2708
+ // Cover and uncover split the total duration; 'both' holds the panel in place between
2709
+ // the two halves so the swap is never visible through a gap.
2710
+ coverOptions: { duration: duration / 2, easing, fill: 'both' },
2711
+ uncoverOptions: { duration: duration / 2, easing, fill: 'both' },
2712
+ },
2578
2713
  };
2579
2714
  }
2580
2715
  /**
@@ -2633,5 +2768,5 @@ function effectiveTransitionId(anim) {
2633
2768
  * Generated bundle index. Do not edit.
2634
2769
  */
2635
2770
 
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 };
2771
+ 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
2772
  //# sourceMappingURL=vectoriox-iox-ui.mjs.map