@vectoriox/iox-ui 5.86.0 → 5.86.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.
@@ -7729,7 +7729,11 @@ declare enum ScrimLevel {
7729
7729
  declare const SCRIM_LEVELS: ReadonlyArray<ScrimLevel>;
7730
7730
  /** What each level writes on the scrim node (`backgroundColor`, token references only) — `null`: the style's own. */
7731
7731
  declare const SCRIM_BACKGROUND: Readonly<Record<ScrimLevel, string | null>>;
7732
- /** The least share of the scrim's own strength under the first line of words, at each level (the gradient's ramp). */
7732
+ /**
7733
+ * The least share of the scrim's own strength under the FIRST line of words, at each level — read from where the words
7734
+ * start in the box (its top padding) against the gradient's ramp, on a phone (the tallest box): the element style's own
7735
+ * ramp (`transparent 0%` → full at 45%) has only about a quarter of its strength there; Firm starts at three quarters.
7736
+ */
7733
7737
  declare const SCRIM_COVER: Readonly<Record<ScrimLevel, number>>;
7734
7738
  /** WCAG AA for body text — the words over a picture include a lead and a button label, never only a headline. */
7735
7739
  declare const PICTURE_TEXT_CONTRAST = 4.5;
package/index.d.ts CHANGED
@@ -776,6 +776,10 @@ declare class ClientSliderContainerComponent implements AfterViewInit, OnDestroy
776
776
  };
777
777
  private swiper;
778
778
  private slidesSeen;
779
+ /** The slides the renderer placed (it asks `childHostFor` for each, before the first change detection), so a played
780
+ * slider's runway reserves its steps in the SERVER render — the page never shifts when the slider boots. */
781
+ private slideTotal;
782
+ get runwaySteps(): number;
779
783
  private readonly instanceRegistry;
780
784
  constructor(platformId: object);
781
785
  /** Swiper draws its own arrows / dots only for a saved slider whose controls are not parts yet. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectoriox/iox-ui",
3
- "version": "5.86.0",
3
+ "version": "5.86.1",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=20.0.0",
6
6
  "@angular/core": ">=20.0.0",
@@ -351,14 +351,18 @@ export const SCRIM_LEVELS: ReadonlyArray<ScrimLevel> = [ScrimLevel.Soft, ScrimLe
351
351
  /** What each level writes on the scrim node (`backgroundColor`, token references only) — `null`: the style's own. */
352
352
  export const SCRIM_BACKGROUND: Readonly<Record<ScrimLevel, string | null>> = {
353
353
  [ScrimLevel.Soft]: null,
354
- [ScrimLevel.Firm]: 'linear-gradient(180deg, transparent 0%, var(--iox-media-scrim) 18%)',
354
+ [ScrimLevel.Firm]: 'linear-gradient(180deg, color-mix(in srgb, var(--iox-media-scrim) 75%, transparent) 0%, var(--iox-media-scrim) 35%)',
355
355
  [ScrimLevel.Full]: 'var(--iox-media-scrim)',
356
356
  };
357
357
 
358
- /** The least share of the scrim's own strength under the first line of words, at each level (the gradient's ramp). */
358
+ /**
359
+ * The least share of the scrim's own strength under the FIRST line of words, at each level — read from where the words
360
+ * start in the box (its top padding) against the gradient's ramp, on a phone (the tallest box): the element style's own
361
+ * ramp (`transparent 0%` → full at 45%) has only about a quarter of its strength there; Firm starts at three quarters.
362
+ */
359
363
  export const SCRIM_COVER: Readonly<Record<ScrimLevel, number>> = {
360
- [ScrimLevel.Soft]: 0.5,
361
- [ScrimLevel.Firm]: 0.85,
364
+ [ScrimLevel.Soft]: 0.25,
365
+ [ScrimLevel.Firm]: 0.75,
362
366
  [ScrimLevel.Full]: 1,
363
367
  };
364
368
 
@@ -131,8 +131,9 @@ export class ScrollDriver {
131
131
  private lastTime = 0;
132
132
  private readonly wakeUp = (): void => this.wake();
133
133
  private readonly onWakeEvent = (e: Event): void => {
134
+ // What arrived may be the stage itself (a played slider marks its stage when it boots): read the root again.
134
135
  const scene = [...this.scenes.values()].find(s => s.root.contains(e.target as Node));
135
- if (scene) { scene.fresh = true; this.wake(); }
136
+ if (scene) this.readScene(scene);
136
137
  };
137
138
 
138
139
  constructor(private readonly options: ScrollDriverOptions = {}) {
@@ -142,7 +142,7 @@ iox-gallery.iox-es-media[data-iox-empty] > .iox-gallery {
142
142
  --iox-image-hover-scale: 1;
143
143
  }
144
144
  .iox-es-card .iox-es-media {
145
- transition: transform var(--iox-dur-ui) var(--iox-ease-standard), scale var(--iox-dur-ui) var(--iox-ease-standard);
145
+ transition: transform var(--iox-dur-ui, 200ms) var(--iox-ease-standard), scale var(--iox-dur-ui, 200ms) var(--iox-ease-standard);
146
146
  }
147
147
  @media (hover: hover) and (pointer: fine) {
148
148
  :is(a.iox-es-card, .iox-es-card:has(> a.linked-container-root), .iox-es-card:has(.iox-card-link)):hover .iox-es-media {
@@ -157,7 +157,7 @@ iox-gallery.iox-es-media[data-iox-empty] > .iox-gallery {
157
157
  forces its own), so the pseudo sits under the card's content and its shadow outside the card's edge. */
158
158
  :is(a.iox-es-card, .iox-es-card:has(> a.linked-container-root), .iox-es-card:has(.iox-card-link)) {
159
159
  --iox-card-shadow-hover: var(--iox-card-shadow);
160
- --iox-dur-base: var(--iox-dur-ui);
160
+ --iox-dur-base: var(--iox-dur-ui, 200ms);
161
161
  translate: 0px;
162
162
  }
163
163
  :is(a.iox-es-card, .iox-es-card:has(> a.linked-container-root), .iox-es-card:has(.iox-card-link))::before {
@@ -165,11 +165,11 @@ iox-gallery.iox-es-media[data-iox-empty] > .iox-gallery {
165
165
  position: absolute;
166
166
  inset: calc(var(--iox-card-border-width, 0px) * -1);
167
167
  border-radius: inherit;
168
- box-shadow: var(--iox-card-shadow-raise);
168
+ box-shadow: var(--iox-card-shadow-raise, var(--iox-shadow-md, none));
169
169
  opacity: 0;
170
170
  pointer-events: none;
171
171
  z-index: -1;
172
- transition: opacity var(--iox-dur-ui) var(--iox-ease-standard);
172
+ transition: opacity var(--iox-dur-ui, 200ms) var(--iox-ease-standard);
173
173
  }
174
174
  @media (hover: hover) and (pointer: fine) {
175
175
  :is(a.iox-es-card, .iox-es-card:has(> a.linked-container-root), .iox-es-card:has(.iox-card-link)):hover::before {
@@ -495,12 +495,15 @@ span.iox-video__play { pointer-events: none; }
495
495
  display: inline-grid; place-items: center; width: 24px; height: 24px; margin: 0; padding: 0; border: 0; border-radius: var(--iox-radius-pill, 999px);
496
496
  background: none; opacity: 1; cursor: pointer; color: inherit;
497
497
  }
498
+ /* The dot grows into the pill by its CLIP (premium M4 — Emil 41: never an animated width): the pill is always 26px wide,
499
+ clipped to an 8px dot at rest and opened whole when current — a compositor property, the dot's round ends kept. */
498
500
  .iox-role-slider-pagination .swiper-pagination-bullet::after {
499
- content: ''; display: block; width: 8px; height: 8px; border-radius: var(--iox-radius-pill, 999px); background: var(--iox-line-strong);
500
- transition: width var(--iox-dur-fast) var(--iox-ease-standard);
501
+ content: ''; display: block; width: 26px; height: 8px; border-radius: var(--iox-radius-pill, 999px); background: var(--iox-line-strong);
502
+ clip-path: inset(0 9px round var(--iox-radius-pill, 999px));
503
+ transition: clip-path var(--iox-dur-fast) var(--iox-ease-standard), background-color var(--iox-dur-fast) var(--iox-ease-standard);
501
504
  }
502
505
  .iox-role-slider-pagination .swiper-pagination-bullet-active { width: 34px; }
503
- .iox-role-slider-pagination .swiper-pagination-bullet-active::after { width: 26px; background: currentColor; }
506
+ .iox-role-slider-pagination .swiper-pagination-bullet-active::after { clip-path: inset(0 0 round var(--iox-radius-pill, 999px)); background: currentColor; }
504
507
  .iox-role-slider-pagination .swiper-pagination-bullet:focus-visible { outline: none; box-shadow: var(--iox-focus-ring); }
505
508
 
506
509
  /* ── The date picker's sheet (premium components N8) ────────────────────────────────────────────────
@@ -545,7 +548,7 @@ span.iox-video__play { pointer-events: none; }
545
548
  block-size: 16px;
546
549
  pointer-events: none;
547
550
  opacity: 0;
548
- transition: opacity var(--iox-dur-ui) var(--iox-ease-standard);
551
+ transition: opacity var(--iox-dur-ui, 200ms) var(--iox-ease-standard);
549
552
  }
550
553
  [data-iox-header][data-iox-header-edge='fade']::after {
551
554
  background: linear-gradient(to bottom,
@@ -595,8 +598,8 @@ span.iox-video__play { pointer-events: none; }
595
598
  .iox-es-link {
596
599
  --iox-link-decoration: none;
597
600
  --iox-link-current-decoration: none;
598
- --iox-dur-fast: var(--iox-dur-hover);
599
- --iox-ease-standard: var(--iox-ease-hover);
601
+ --iox-dur-fast: var(--iox-dur-hover, 150ms);
602
+ --iox-ease-standard: var(--iox-ease-hover, ease);
600
603
  background-image: linear-gradient(currentColor, currentColor);
601
604
  background-repeat: no-repeat;
602
605
  background-position: 0% calc(100% - var(--iox-link-underline-offset, 0px));
@@ -627,14 +630,14 @@ span.iox-video__play { pointer-events: none; }
627
630
  }
628
631
  /* A chip's colour moves on the hover timing too (Emil 92 — M3's review). */
629
632
  .iox-es-chip {
630
- --iox-dur-fast: var(--iox-dur-hover);
631
- --iox-ease-standard: var(--iox-ease-hover);
633
+ --iox-dur-fast: var(--iox-dur-hover, 150ms);
634
+ --iox-ease-standard: var(--iox-ease-hover, ease);
632
635
  }
633
636
 
634
637
  /* ── Premium components M4 (Emil 55/85): a press lands faster than its release ──────────────────────────────────────
635
638
  While pressed, every pressable's transition runs on dur-press; it releases on its own (slower) dur-fast. */
636
639
  :is(.iox-es-button-primary, .iox-es-button-secondary, .iox-es-button-ghost, .iox-es-bottom-bar-item):active {
637
- transition-duration: var(--iox-dur-press);
640
+ transition-duration: var(--iox-dur-press, 100ms);
638
641
  }
639
642
 
640
643
  /* ── Premium components M4 (T3): the Slider's feel, its bar and the slider the scroll plays ─────────────────────────
@@ -664,7 +667,7 @@ span.iox-video__play { pointer-events: none; }
664
667
  }
665
668
  /* The caption follows the slide in view: it changes behind a short fade (the runtime holds it at 0 for a frame). */
666
669
  .iox-role-slider-caption {
667
- transition: opacity var(--iox-dur-hover) var(--iox-ease-hover);
670
+ transition: opacity var(--iox-dur-hover, 150ms) var(--iox-ease-hover, ease);
668
671
  }
669
672
  .iox-role-slider-caption[data-iox-swapping] {
670
673
  opacity: 0;