@inappstory/slide-api 0.1.35 → 0.1.36

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/dist/index.cjs CHANGED
@@ -1009,7 +1009,9 @@ const animationApi = {
1009
1009
  removeClass(elements[i], "active");
1010
1010
  removeClass(elements[i], "animated");
1011
1011
  elements[i].style.setProperty("transform", "");
1012
- elements[i].style.setProperty("filter", "");
1012
+ if (hasClass(elements[i], "narrative-element-animation-blur")) {
1013
+ elements[i].style.setProperty("filter", "");
1014
+ }
1013
1015
  }
1014
1016
  }
1015
1017
  }
@@ -5992,6 +5994,9 @@ class SlideTimer {
5992
5994
  if (currentTime != null) {
5993
5995
  // timeLeft correction
5994
5996
  this.timeLeft = this.duration - currentTime;
5997
+ if (this.timeLeft < 0) {
5998
+ this.timeLeft = 0;
5999
+ }
5995
6000
  }
5996
6001
  this.tick();
5997
6002
  }
@@ -6008,6 +6013,9 @@ class SlideTimer {
6008
6013
  }
6009
6014
  const dtDiff = new Date().getTime() - rafStartTime;
6010
6015
  this.timeLeft -= dtDiff;
6016
+ if (this.timeLeft < 0) {
6017
+ this.timeLeft = 0;
6018
+ }
6011
6019
  let progressPercent = Math.round(((this.duration - this.timeLeft) / this.duration) * 100 * 10000) / 10000;
6012
6020
  if (progressPercent > 100) {
6013
6021
  progressPercent = 100;
@@ -6077,14 +6085,16 @@ class Slider {
6077
6085
  });
6078
6086
  this.slidesFirstRenders[i] = item;
6079
6087
  }
6080
- const slideWrapper = this.createSliderElement({
6088
+ const { sliderWrapper, safeAreaView } = this.createSliderElement({
6081
6089
  slides: config.slides,
6082
6090
  nonce: config.nonce,
6083
6091
  slideRender: config.slideRender,
6084
6092
  navbarAppearance: config.navbarAppearance,
6093
+ singleSlideTimerAppearance: config.singleSlideTimerAppearance,
6085
6094
  });
6086
- config.root.appendChild(slideWrapper);
6087
- this.slideWrapperElement = slideWrapper;
6095
+ config.root.appendChild(sliderWrapper);
6096
+ this.sliderWrapperElement = sliderWrapper;
6097
+ this.safeAreaViewElement = safeAreaView;
6088
6098
  this.timelineController = createTimelineController(TimelineController, this.slides, this.config.getLayoutDirection.bind(this));
6089
6099
  // cardMounted: (card: HTMLElement) => Promise<void>
6090
6100
  requestAnimationFrame(async () => {
@@ -6100,12 +6110,16 @@ class Slider {
6100
6110
  }
6101
6111
  slides = [];
6102
6112
  sliderTrack = null;
6103
- bulletsContainer = null;
6104
6113
  slidesFirstRenders = [];
6105
- slideWrapperElement;
6114
+ sliderWrapperElement;
6115
+ safeAreaViewElement;
6116
+ isBulletsActive = false;
6117
+ isSingleSlideTimerActive = false;
6118
+ pausedAt = null;
6106
6119
  timelineController;
6107
- assembleNavbarCssVariables(navbarAppearance) {
6120
+ assembleAppearanceCssVariables(navbarAppearance, singleSlideTimerAppearance) {
6108
6121
  let css = "";
6122
+ /** Navbar variables **/
6109
6123
  if (navbarAppearance.edge_offset != null) {
6110
6124
  css += `--navbar-edge-offset: ${navbarAppearance.edge_offset};`;
6111
6125
  }
@@ -6148,25 +6162,53 @@ class Slider {
6148
6162
  if (navbarAppearance.horizontal_padding != null) {
6149
6163
  css += `--navbar-horizontal-padding: ${navbarAppearance.horizontal_padding};`;
6150
6164
  }
6151
- return `.cards-slider {${css}`;
6165
+ /** SingleSlideTimer variables **/
6166
+ if (singleSlideTimerAppearance.edge_offset != null) {
6167
+ css += `--timer-edge-offset: ${singleSlideTimerAppearance.edge_offset};`;
6168
+ }
6169
+ if (singleSlideTimerAppearance.timeline_background_color != null) {
6170
+ css += `--timer-timeline-background-color: ${singleSlideTimerAppearance.timeline_background_color};`;
6171
+ }
6172
+ if (singleSlideTimerAppearance.timeline_fill_color != null) {
6173
+ css += `--timer-timeline-fill-color: ${singleSlideTimerAppearance.timeline_fill_color};`;
6174
+ }
6175
+ if (singleSlideTimerAppearance.timeline_height != null) {
6176
+ css += `--timer-timeline-height: ${singleSlideTimerAppearance.timeline_height};`;
6177
+ }
6178
+ if (singleSlideTimerAppearance.timeline_border_radius != null) {
6179
+ css += `--timer-timeline-border-radius: ${singleSlideTimerAppearance.timeline_border_radius};`;
6180
+ }
6181
+ if (singleSlideTimerAppearance.horizontal_margin != null) {
6182
+ css += `--timer-horizontal-margin: ${singleSlideTimerAppearance.horizontal_margin};`;
6183
+ }
6184
+ return `.cards-slider {${css}}`;
6152
6185
  }
6153
- createSliderElement = ({ slides, nonce, slideRender, navbarAppearance, }) => {
6186
+ createSliderElement = ({ slides, nonce, slideRender, navbarAppearance, singleSlideTimerAppearance, }) => {
6154
6187
  const style = document.createElement("style");
6155
6188
  if (nonce != null) {
6156
6189
  style.nonce = nonce;
6157
6190
  }
6158
- style.innerText = this.assembleNavbarCssVariables(navbarAppearance);
6191
+ style.innerText = this.assembleAppearanceCssVariables(navbarAppearance, singleSlideTimerAppearance);
6159
6192
  const slider = document.createElement("div");
6160
6193
  slider.classList.add("cards-slider");
6161
6194
  const track = document.createElement("div");
6162
6195
  track.classList.add("cards-slider__track");
6163
6196
  this.sliderTrack = track;
6164
- const [bullets, updateTimelineProgress] = this.createBulletPoints(slides.length, this.config.getLayoutDirection.bind(this), navbarAppearance.position);
6165
- this.bulletsContainer = bullets;
6197
+ const [isBulletsActive, bullets, bulletsUpdateTimelineProgress] = this.createBulletPoints(slides.length, this.config.getLayoutDirection.bind(this), navbarAppearance.position);
6198
+ this.isBulletsActive = isBulletsActive;
6199
+ const [isSingleSlideTimerActive, singleSlideTimer, singleSlideTimerUpdateTimelineProgress] = this.createSingleSlideTimer(this.config.getLayoutDirection.bind(this), singleSlideTimerAppearance.position, singleSlideTimerAppearance.timeline_direction);
6200
+ this.isSingleSlideTimerActive = isSingleSlideTimerActive;
6166
6201
  this.slides = slides.map((slide, i) => ({
6167
6202
  element: slideRender(slide, i, this.slidesFirstRenders[i].firstRenderCallPromise),
6168
6203
  timer: new SlideTimer(cb => window.requestAnimationFrame(cb), handle => window.cancelAnimationFrame(handle), progressPercent => this.timelineController.onSlideTimerUpdate(i, progressPercent), this.onSlideTimerEnd.bind(this)),
6169
- updateTimelineProgress: (progressPercent, isActive) => updateTimelineProgress(i, progressPercent, isActive),
6204
+ updateTimelineProgress: (progressPercent, isActive) => {
6205
+ if (isBulletsActive) {
6206
+ bulletsUpdateTimelineProgress(i, progressPercent, isActive);
6207
+ }
6208
+ if (isSingleSlideTimerActive) {
6209
+ singleSlideTimerUpdateTimelineProgress(progressPercent);
6210
+ }
6211
+ },
6170
6212
  }));
6171
6213
  for (let i = 0; i < this.slides.length; ++i) {
6172
6214
  const slideElement = document.createElement("div");
@@ -6181,12 +6223,14 @@ class Slider {
6181
6223
  const safeAreaRelativeZoneView = document.createElement("div");
6182
6224
  safeAreaRelativeZoneView.classList.add("safe-area-relative-zone-view");
6183
6225
  safeAreaRelativeZoneView.appendChild(bullets);
6226
+ safeAreaRelativeZoneView.appendChild(singleSlideTimer);
6184
6227
  safeAreaView.appendChild(safeAreaRelativeZoneView);
6185
6228
  slider.appendChild(safeAreaView);
6186
6229
  slider.appendChild(style);
6187
- return slider;
6230
+ return { sliderWrapper: slider, safeAreaView };
6188
6231
  };
6189
6232
  createBulletPoints(count, getLayoutDirection, position) {
6233
+ let isActive = true;
6190
6234
  const bullets = document.createElement("div");
6191
6235
  bullets.classList.add("cards-slider__navbar");
6192
6236
  // force hide bullets container for single slide
@@ -6194,6 +6238,7 @@ class Slider {
6194
6238
  position = 0;
6195
6239
  }
6196
6240
  if (position === 0) {
6241
+ isActive = false;
6197
6242
  bullets.classList.add("cards-slider__navbar--position-none");
6198
6243
  }
6199
6244
  else if (position === 1) {
@@ -6202,10 +6247,6 @@ class Slider {
6202
6247
  else if (position === 2) {
6203
6248
  bullets.classList.add("cards-slider__navbar--position-bottom");
6204
6249
  }
6205
- else {
6206
- // default
6207
- bullets.classList.add("cards-slider__navbar--position-bottom");
6208
- }
6209
6250
  bullets.dir = getLayoutDirection();
6210
6251
  // skip creating view elements for single slide
6211
6252
  if (count > 1) {
@@ -6252,7 +6293,56 @@ class Slider {
6252
6293
  }
6253
6294
  }
6254
6295
  };
6255
- return [bullets, onUpdateTimelineProgress];
6296
+ return [isActive, bullets, onUpdateTimelineProgress];
6297
+ }
6298
+ createSingleSlideTimer(getLayoutDirection, position, timelineDirection) {
6299
+ let isActive = true;
6300
+ const timer = document.createElement("div");
6301
+ timer.classList.add("cards-slider__timer");
6302
+ if (position === 0) {
6303
+ isActive = false;
6304
+ timer.classList.add("cards-slider__timer--position-none");
6305
+ }
6306
+ else if (position === 1) {
6307
+ timer.classList.add("cards-slider__timer--position-top");
6308
+ }
6309
+ else if (position === 2) {
6310
+ timer.classList.add("cards-slider__timer--position-bottom");
6311
+ }
6312
+ timer.dir = getLayoutDirection();
6313
+ if (timelineDirection === 0) {
6314
+ timer.classList.add("cards-slider__timer--straight-direction");
6315
+ }
6316
+ else if (timelineDirection === 1) {
6317
+ timer.classList.add("cards-slider__timer--reverse-direction");
6318
+ }
6319
+ const timeline = document.createElement("div");
6320
+ timeline.classList.add("cards-slider__timer_timeline", "touchable");
6321
+ const timelineFill = document.createElement("div");
6322
+ timelineFill.classList.add("cards-slider__timer_timeline-fill");
6323
+ timeline.append(timelineFill);
6324
+ timer.appendChild(timeline);
6325
+ const onUpdateTimelineProgress = (progress) => {
6326
+ if (timelineFill != null) {
6327
+ // timeline straight direction
6328
+ if (timelineDirection === 0) {
6329
+ if (this.config.getLayoutDirection() === "rtl") {
6330
+ progress = -1 * progress;
6331
+ }
6332
+ // timeline reverse direction
6333
+ }
6334
+ else if (timelineDirection === 1) {
6335
+ if (this.config.getLayoutDirection() === "ltr") {
6336
+ progress = -100 - progress;
6337
+ }
6338
+ if (this.config.getLayoutDirection() === "rtl") {
6339
+ progress = 100 + progress;
6340
+ }
6341
+ }
6342
+ timelineFill.style.setProperty("transform", `translateX(${progress}%)`);
6343
+ }
6344
+ };
6345
+ return [isActive, timer, onUpdateTimelineProgress];
6256
6346
  }
6257
6347
  async showByIndex(newIndex) {
6258
6348
  const prevIndex = this.activeIndex;
@@ -6335,6 +6425,8 @@ class Slider {
6335
6425
  }
6336
6426
  onUpdateSizeMetrics(metrics) {
6337
6427
  // this.slideTo(this.activeIndex, 0);
6428
+ // todo CSP violation
6429
+ this.safeAreaViewElement.style.fontSize = metrics.fontSize;
6338
6430
  }
6339
6431
  getSlideOffset(index) {
6340
6432
  if (!this.slides.length)
@@ -6385,8 +6477,9 @@ class Slider {
6385
6477
  }
6386
6478
  destroy() {
6387
6479
  this.activeSlide?.timer.stop();
6388
- if (this.slideWrapperElement != null && this.config.root != null) {
6389
- this.config.root.removeChild(this.slideWrapperElement);
6480
+ this.pausedAt = null;
6481
+ if (this.sliderWrapperElement != null && this.config.root != null) {
6482
+ this.config.root.removeChild(this.sliderWrapperElement);
6390
6483
  }
6391
6484
  }
6392
6485
  async updateTimeline(slideIndex, action, currentTime, duration, showLoader, showError) {
@@ -6412,10 +6505,14 @@ class Slider {
6412
6505
  resumeTimer = true;
6413
6506
  }
6414
6507
  if (currentTime === duration) {
6415
- // skip timer start for already ended layer timeline
6416
6508
  // skip timer start for already ended layer timeline
6417
6509
  resumeTimer = false;
6418
6510
  }
6511
+ // if single slide timer mode - calc diff for blur time, override currentTime
6512
+ if (this.isSingleSlideTimerActive && this.pausedAt != null) {
6513
+ currentTime += new Date().getTime() - this.pausedAt;
6514
+ // we must resume timer - for trigger done callback and hide Card (SingleSlideTimer business logic)
6515
+ }
6419
6516
  if (resumeTimer) {
6420
6517
  this.activeSlide?.timer.resume(currentTime, duration);
6421
6518
  }
@@ -6426,6 +6523,9 @@ class Slider {
6426
6523
  this.config.onSlideDataWaiting();
6427
6524
  }
6428
6525
  this.activeSlide?.timer.pause();
6526
+ if (this.isSingleSlideTimerActive) {
6527
+ this.pausedAt = new Date().getTime();
6528
+ }
6429
6529
  // console.log("TIMELINE_ACTION.PAUSE", { activeSlide: this.activeSlide, duration });
6430
6530
  break;
6431
6531
  }
@@ -6453,6 +6553,7 @@ class Slider {
6453
6553
  root: HTMLElement;
6454
6554
  nonce?: string;
6455
6555
  navbarAppearance: NavbarAppearance;
6556
+ singleSlideTimerAppearance: SingleSlideTimerAppearance;
6456
6557
  slideRender: SlideRender<T>;
6457
6558
  onSlideMounted: OnSlideMounted;
6458
6559
  onBeforeShowSlide: OnBeforeShowSlide;
@@ -6664,12 +6765,33 @@ class CardApi {
6664
6765
  return this.activeSlide.showSlide(html);
6665
6766
  }
6666
6767
  slider = null;
6667
- async showSlides(slides, cardAppearance, index = 0) {
6768
+ globalCssVariablesImported = false;
6769
+ importGlobalCssVariables(safeAreaInsetTop, safeAreaInsetBottom) {
6770
+ if (!this.globalCssVariablesImported) {
6771
+ const style = document.createElement("style");
6772
+ if (this.config.nonce != null) {
6773
+ style.nonce = this.config.nonce;
6774
+ }
6775
+ let css = "";
6776
+ if (safeAreaInsetBottom != null) {
6777
+ css += `--safe-area-inset-top: ${safeAreaInsetTop}px;`;
6778
+ }
6779
+ if (safeAreaInsetBottom != null) {
6780
+ css += `--safe-area-inset-bottom: ${safeAreaInsetBottom}px;`;
6781
+ }
6782
+ style.innerText = `:root {${css}}`;
6783
+ this.config.root.appendChild(style);
6784
+ this.globalCssVariablesImported = true;
6785
+ }
6786
+ }
6787
+ async showSlides(slides, cardAppearance, index = 0, config = {}) {
6668
6788
  this.slidesMode = 1 /* SLIDES_MODE.MULTIPLE */;
6669
6789
  if (this.cardLoadingStateController === null) {
6670
6790
  this.cardLoadingStateController = new CardLoadingStateController(this.sdkApi.onCardLoadingStateChange.bind(this.sdkApi));
6671
6791
  }
6672
6792
  this.cardLoadingStateController.onSetLoadStartState();
6793
+ // TODO mv to CardApi CTOR
6794
+ this.importGlobalCssVariables(config.safeAreaInsetTop, config.safeAreaInsetBottom);
6673
6795
  slides.forEach((content, index) => {
6674
6796
  if (this.slides[index] == null) {
6675
6797
  const item = { content, resourcesReadyPromise: null };
@@ -6835,6 +6957,7 @@ class CardApi {
6835
6957
  if (this.slider != null) {
6836
6958
  this.slider.destroy();
6837
6959
  }
6960
+ const singleSlideTimerAppearance = cardAppearance.singleSlideTimer ?? {};
6838
6961
  this.slider = new Slider({
6839
6962
  root: this.config.root,
6840
6963
  slides: this.slides.map(({ content, resourcesReadyPromise }) => ({
@@ -6843,6 +6966,7 @@ class CardApi {
6843
6966
  })),
6844
6967
  nonce: this.config.nonce,
6845
6968
  navbarAppearance: cardAppearance.navbar ?? {},
6969
+ singleSlideTimerAppearance: singleSlideTimerAppearance,
6846
6970
  slideRender,
6847
6971
  onSlideMounted,
6848
6972
  onBeforeShowSlide,
@@ -6851,7 +6975,16 @@ class CardApi {
6851
6975
  onShowSlide,
6852
6976
  onSlideLeft,
6853
6977
  getLayoutDirection: () => this.layoutDirection,
6854
- onSlideTimerEnd: () => this.activeSlide.slideTimerEnd(),
6978
+ onSlideTimerEnd: () => {
6979
+ // special for IAM with type Toast - single slide, close toast after slideTimerEnd
6980
+ // singleSlideTimerAppearance.position !== 0 (SingleSlideTimer is visible) - sign that this is Toast IAM
6981
+ if (singleSlideTimerAppearance.position !== 0) {
6982
+ this.activeSlide.slideApiDeps.closeCard("Single slide timer end");
6983
+ }
6984
+ else {
6985
+ this.activeSlide.slideTimerEnd();
6986
+ }
6987
+ },
6855
6988
  onSlideChangeActiveIndex: index => (this.activeSlide = this.slides[index].slide),
6856
6989
  onSlideStart: () => {
6857
6990
  // return Promise.resolve({currentTime: 0});
@@ -6863,6 +6996,8 @@ class CardApi {
6863
6996
  onSlideDataResume: () => this.cardLoadingStateController.onSetLoadEndState(),
6864
6997
  onSlideDataError: () => this.cardLoadingStateController.onSetLoadEndState(),
6865
6998
  });
6999
+ // to set font size at SafeAreaView inside Slider
7000
+ this.slider.onUpdateSizeMetrics(this.sizeMetrics);
6866
7001
  await this.slider.showByIndex(index);
6867
7002
  // return await onShowActiveCard;
6868
7003
  }
@@ -6975,12 +7110,14 @@ class CardApi {
6975
7110
  this._sdkClientVariables = variables;
6976
7111
  }
6977
7112
  setSlideInCacheStatus(index, status) {
6978
- if (this.slides[index] != null && this.slides[index].resourcesReadyPromisesResolver != null) {
6979
- if (status === 1 /* SLIDE_IN_CACHE_STATUS.SUCCESS */) {
6980
- this.slides[index].resourcesReadyPromisesResolver.resolve();
6981
- }
6982
- else {
6983
- this.slides[index].resourcesReadyPromisesResolver.reject();
7113
+ if (this.slides[index] != null) {
7114
+ if (this.slides[index].resourcesReadyPromisesResolver != null) {
7115
+ if (status === 1 /* SLIDE_IN_CACHE_STATUS.SUCCESS */) {
7116
+ this.slides[index].resourcesReadyPromisesResolver.resolve();
7117
+ }
7118
+ else {
7119
+ this.slides[index].resourcesReadyPromisesResolver.reject();
7120
+ }
6984
7121
  }
6985
7122
  }
6986
7123
  else {