react-riyils 1.0.0 → 2.0.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.
package/dist/index.umd.js CHANGED
@@ -432,9 +432,6 @@
432
432
  return el[size === 'width' ? 'offsetWidth' : 'offsetHeight'] + parseFloat(window.getComputedStyle(el, null).getPropertyValue(size === 'width' ? 'margin-right' : 'margin-top')) + parseFloat(window.getComputedStyle(el, null).getPropertyValue(size === 'width' ? 'margin-left' : 'margin-bottom'));
433
433
  }
434
434
  }
435
- function makeElementsArray(el) {
436
- return (Array.isArray(el) ? el : [el]).filter(e => !!e);
437
- }
438
435
  function getRotateFix(swiper) {
439
436
  return v => {
440
437
  if (Math.abs(v) > 0 && swiper.browser && swiper.browser.need3dFix && Math.abs(v) % 90 === 0) {
@@ -5034,6 +5031,366 @@
5034
5031
  });
5035
5032
  SwiperSlide.displayName = 'SwiperSlide';
5036
5033
 
5034
+ function Virtual({
5035
+ swiper,
5036
+ extendParams,
5037
+ on,
5038
+ emit
5039
+ }) {
5040
+ extendParams({
5041
+ virtual: {
5042
+ enabled: false,
5043
+ slides: [],
5044
+ cache: true,
5045
+ slidesPerViewAutoSlideSize: 320,
5046
+ renderSlide: null,
5047
+ renderExternal: null,
5048
+ renderExternalUpdate: true,
5049
+ addSlidesBefore: 0,
5050
+ addSlidesAfter: 0
5051
+ }
5052
+ });
5053
+ let cssModeTimeout;
5054
+ const document = getDocument();
5055
+ swiper.virtual = {
5056
+ cache: {},
5057
+ from: undefined,
5058
+ to: undefined,
5059
+ slides: [],
5060
+ offset: 0,
5061
+ slidesGrid: []
5062
+ };
5063
+ const tempDOM = document.createElement('div');
5064
+ function renderSlide(slide, index) {
5065
+ const params = swiper.params.virtual;
5066
+ if (params.cache && swiper.virtual.cache[index]) {
5067
+ return swiper.virtual.cache[index];
5068
+ }
5069
+ // eslint-disable-next-line
5070
+ let slideEl;
5071
+ if (params.renderSlide) {
5072
+ slideEl = params.renderSlide.call(swiper, slide, index);
5073
+ if (typeof slideEl === 'string') {
5074
+ setInnerHTML(tempDOM, slideEl);
5075
+ slideEl = tempDOM.children[0];
5076
+ }
5077
+ } else if (swiper.isElement) {
5078
+ slideEl = createElement('swiper-slide');
5079
+ } else {
5080
+ slideEl = createElement('div', swiper.params.slideClass);
5081
+ }
5082
+ slideEl.setAttribute('data-swiper-slide-index', index);
5083
+ if (!params.renderSlide) {
5084
+ setInnerHTML(slideEl, slide);
5085
+ }
5086
+ if (params.cache) {
5087
+ swiper.virtual.cache[index] = slideEl;
5088
+ }
5089
+ return slideEl;
5090
+ }
5091
+ function update(force, beforeInit, forceActiveIndex) {
5092
+ const {
5093
+ slidesPerGroup,
5094
+ centeredSlides,
5095
+ slidesPerView,
5096
+ loop: isLoop,
5097
+ initialSlide
5098
+ } = swiper.params;
5099
+ if (beforeInit && !isLoop && initialSlide > 0) {
5100
+ return;
5101
+ }
5102
+ const {
5103
+ addSlidesBefore,
5104
+ addSlidesAfter,
5105
+ slidesPerViewAutoSlideSize
5106
+ } = swiper.params.virtual;
5107
+ const {
5108
+ from: previousFrom,
5109
+ to: previousTo,
5110
+ slides,
5111
+ slidesGrid: previousSlidesGrid,
5112
+ offset: previousOffset
5113
+ } = swiper.virtual;
5114
+ if (!swiper.params.cssMode) {
5115
+ swiper.updateActiveIndex();
5116
+ }
5117
+ const activeIndex = typeof forceActiveIndex === 'undefined' ? swiper.activeIndex || 0 : forceActiveIndex;
5118
+ let offsetProp;
5119
+ if (swiper.rtlTranslate) offsetProp = 'right';else offsetProp = swiper.isHorizontal() ? 'left' : 'top';
5120
+ let slidesPerViewNumeric;
5121
+ if (slidesPerView === 'auto') {
5122
+ if (slidesPerViewAutoSlideSize) {
5123
+ let swiperSize = swiper.size;
5124
+ if (!swiperSize) {
5125
+ swiperSize = swiper.isHorizontal() ? swiper.el.getBoundingClientRect().width : swiper.el.getBoundingClientRect().height;
5126
+ }
5127
+ slidesPerViewNumeric = Math.max(1, Math.ceil(swiperSize / slidesPerViewAutoSlideSize));
5128
+ } else {
5129
+ slidesPerViewNumeric = 1;
5130
+ }
5131
+ } else {
5132
+ slidesPerViewNumeric = slidesPerView;
5133
+ }
5134
+ let slidesAfter;
5135
+ let slidesBefore;
5136
+ if (centeredSlides) {
5137
+ slidesAfter = Math.floor(slidesPerViewNumeric / 2) + slidesPerGroup + addSlidesAfter;
5138
+ slidesBefore = Math.floor(slidesPerViewNumeric / 2) + slidesPerGroup + addSlidesBefore;
5139
+ } else {
5140
+ slidesAfter = slidesPerViewNumeric + (slidesPerGroup - 1) + addSlidesAfter;
5141
+ slidesBefore = (isLoop ? slidesPerViewNumeric : slidesPerGroup) + addSlidesBefore;
5142
+ }
5143
+ let from = activeIndex - slidesBefore;
5144
+ let to = activeIndex + slidesAfter;
5145
+ if (!isLoop) {
5146
+ from = Math.max(from, 0);
5147
+ to = Math.min(to, slides.length - 1);
5148
+ }
5149
+ let offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0);
5150
+ if (isLoop && activeIndex >= slidesBefore) {
5151
+ from -= slidesBefore;
5152
+ if (!centeredSlides) offset += swiper.slidesGrid[0];
5153
+ } else if (isLoop && activeIndex < slidesBefore) {
5154
+ from = -slidesBefore;
5155
+ if (centeredSlides) offset += swiper.slidesGrid[0];
5156
+ }
5157
+ Object.assign(swiper.virtual, {
5158
+ from,
5159
+ to,
5160
+ offset,
5161
+ slidesGrid: swiper.slidesGrid,
5162
+ slidesBefore,
5163
+ slidesAfter
5164
+ });
5165
+ function onRendered() {
5166
+ swiper.updateSlides();
5167
+ swiper.updateProgress();
5168
+ swiper.updateSlidesClasses();
5169
+ emit('virtualUpdate');
5170
+ }
5171
+ if (previousFrom === from && previousTo === to && !force) {
5172
+ if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) {
5173
+ swiper.slides.forEach(slideEl => {
5174
+ slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`;
5175
+ });
5176
+ }
5177
+ swiper.updateProgress();
5178
+ emit('virtualUpdate');
5179
+ return;
5180
+ }
5181
+ if (swiper.params.virtual.renderExternal) {
5182
+ swiper.params.virtual.renderExternal.call(swiper, {
5183
+ offset,
5184
+ from,
5185
+ to,
5186
+ slides: function getSlides() {
5187
+ const slidesToRender = [];
5188
+ for (let i = from; i <= to; i += 1) {
5189
+ slidesToRender.push(slides[i]);
5190
+ }
5191
+ return slidesToRender;
5192
+ }()
5193
+ });
5194
+ if (swiper.params.virtual.renderExternalUpdate) {
5195
+ onRendered();
5196
+ } else {
5197
+ emit('virtualUpdate');
5198
+ }
5199
+ return;
5200
+ }
5201
+ const prependIndexes = [];
5202
+ const appendIndexes = [];
5203
+ const getSlideIndex = index => {
5204
+ let slideIndex = index;
5205
+ if (index < 0) {
5206
+ slideIndex = slides.length + index;
5207
+ } else if (slideIndex >= slides.length) {
5208
+ // eslint-disable-next-line
5209
+ slideIndex = slideIndex - slides.length;
5210
+ }
5211
+ return slideIndex;
5212
+ };
5213
+ if (force) {
5214
+ swiper.slides.filter(el => el.matches(`.${swiper.params.slideClass}, swiper-slide`)).forEach(slideEl => {
5215
+ slideEl.remove();
5216
+ });
5217
+ } else {
5218
+ for (let i = previousFrom; i <= previousTo; i += 1) {
5219
+ if (i < from || i > to) {
5220
+ const slideIndex = getSlideIndex(i);
5221
+ swiper.slides.filter(el => el.matches(`.${swiper.params.slideClass}[data-swiper-slide-index="${slideIndex}"], swiper-slide[data-swiper-slide-index="${slideIndex}"]`)).forEach(slideEl => {
5222
+ slideEl.remove();
5223
+ });
5224
+ }
5225
+ }
5226
+ }
5227
+ const loopFrom = isLoop ? -slides.length : 0;
5228
+ const loopTo = isLoop ? slides.length * 2 : slides.length;
5229
+ for (let i = loopFrom; i < loopTo; i += 1) {
5230
+ if (i >= from && i <= to) {
5231
+ const slideIndex = getSlideIndex(i);
5232
+ if (typeof previousTo === 'undefined' || force) {
5233
+ appendIndexes.push(slideIndex);
5234
+ } else {
5235
+ if (i > previousTo) appendIndexes.push(slideIndex);
5236
+ if (i < previousFrom) prependIndexes.push(slideIndex);
5237
+ }
5238
+ }
5239
+ }
5240
+ appendIndexes.forEach(index => {
5241
+ swiper.slidesEl.append(renderSlide(slides[index], index));
5242
+ });
5243
+ if (isLoop) {
5244
+ for (let i = prependIndexes.length - 1; i >= 0; i -= 1) {
5245
+ const index = prependIndexes[i];
5246
+ swiper.slidesEl.prepend(renderSlide(slides[index], index));
5247
+ }
5248
+ } else {
5249
+ prependIndexes.sort((a, b) => b - a);
5250
+ prependIndexes.forEach(index => {
5251
+ swiper.slidesEl.prepend(renderSlide(slides[index], index));
5252
+ });
5253
+ }
5254
+ elementChildren(swiper.slidesEl, '.swiper-slide, swiper-slide').forEach(slideEl => {
5255
+ slideEl.style[offsetProp] = `${offset - Math.abs(swiper.cssOverflowAdjustment())}px`;
5256
+ });
5257
+ onRendered();
5258
+ }
5259
+ function appendSlide(slides) {
5260
+ if (typeof slides === 'object' && 'length' in slides) {
5261
+ for (let i = 0; i < slides.length; i += 1) {
5262
+ if (slides[i]) swiper.virtual.slides.push(slides[i]);
5263
+ }
5264
+ } else {
5265
+ swiper.virtual.slides.push(slides);
5266
+ }
5267
+ update(true);
5268
+ }
5269
+ function prependSlide(slides) {
5270
+ const activeIndex = swiper.activeIndex;
5271
+ let newActiveIndex = activeIndex + 1;
5272
+ let numberOfNewSlides = 1;
5273
+ if (Array.isArray(slides)) {
5274
+ for (let i = 0; i < slides.length; i += 1) {
5275
+ if (slides[i]) swiper.virtual.slides.unshift(slides[i]);
5276
+ }
5277
+ newActiveIndex = activeIndex + slides.length;
5278
+ numberOfNewSlides = slides.length;
5279
+ } else {
5280
+ swiper.virtual.slides.unshift(slides);
5281
+ }
5282
+ if (swiper.params.virtual.cache) {
5283
+ const cache = swiper.virtual.cache;
5284
+ const newCache = {};
5285
+ Object.keys(cache).forEach(cachedIndex => {
5286
+ const cachedEl = cache[cachedIndex];
5287
+ const cachedElIndex = cachedEl.getAttribute('data-swiper-slide-index');
5288
+ if (cachedElIndex) {
5289
+ cachedEl.setAttribute('data-swiper-slide-index', parseInt(cachedElIndex, 10) + numberOfNewSlides);
5290
+ }
5291
+ newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = cachedEl;
5292
+ });
5293
+ swiper.virtual.cache = newCache;
5294
+ }
5295
+ update(true);
5296
+ swiper.slideTo(newActiveIndex, 0);
5297
+ }
5298
+ function removeSlide(slidesIndexes) {
5299
+ if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return;
5300
+ let activeIndex = swiper.activeIndex;
5301
+ if (Array.isArray(slidesIndexes)) {
5302
+ for (let i = slidesIndexes.length - 1; i >= 0; i -= 1) {
5303
+ if (swiper.params.virtual.cache) {
5304
+ delete swiper.virtual.cache[slidesIndexes[i]];
5305
+ // shift cache indexes
5306
+ Object.keys(swiper.virtual.cache).forEach(key => {
5307
+ if (key > slidesIndexes) {
5308
+ swiper.virtual.cache[key - 1] = swiper.virtual.cache[key];
5309
+ swiper.virtual.cache[key - 1].setAttribute('data-swiper-slide-index', key - 1);
5310
+ delete swiper.virtual.cache[key];
5311
+ }
5312
+ });
5313
+ }
5314
+ swiper.virtual.slides.splice(slidesIndexes[i], 1);
5315
+ if (slidesIndexes[i] < activeIndex) activeIndex -= 1;
5316
+ activeIndex = Math.max(activeIndex, 0);
5317
+ }
5318
+ } else {
5319
+ if (swiper.params.virtual.cache) {
5320
+ delete swiper.virtual.cache[slidesIndexes];
5321
+ // shift cache indexes
5322
+ Object.keys(swiper.virtual.cache).forEach(key => {
5323
+ if (key > slidesIndexes) {
5324
+ swiper.virtual.cache[key - 1] = swiper.virtual.cache[key];
5325
+ swiper.virtual.cache[key - 1].setAttribute('data-swiper-slide-index', key - 1);
5326
+ delete swiper.virtual.cache[key];
5327
+ }
5328
+ });
5329
+ }
5330
+ swiper.virtual.slides.splice(slidesIndexes, 1);
5331
+ if (slidesIndexes < activeIndex) activeIndex -= 1;
5332
+ activeIndex = Math.max(activeIndex, 0);
5333
+ }
5334
+ update(true);
5335
+ swiper.slideTo(activeIndex, 0);
5336
+ }
5337
+ function removeAllSlides() {
5338
+ swiper.virtual.slides = [];
5339
+ if (swiper.params.virtual.cache) {
5340
+ swiper.virtual.cache = {};
5341
+ }
5342
+ update(true);
5343
+ swiper.slideTo(0, 0);
5344
+ }
5345
+ on('beforeInit', () => {
5346
+ if (!swiper.params.virtual.enabled) return;
5347
+ let domSlidesAssigned;
5348
+ if (typeof swiper.passedParams.virtual.slides === 'undefined') {
5349
+ const slides = [...swiper.slidesEl.children].filter(el => el.matches(`.${swiper.params.slideClass}, swiper-slide`));
5350
+ if (slides && slides.length) {
5351
+ swiper.virtual.slides = [...slides];
5352
+ domSlidesAssigned = true;
5353
+ slides.forEach((slideEl, slideIndex) => {
5354
+ slideEl.setAttribute('data-swiper-slide-index', slideIndex);
5355
+ swiper.virtual.cache[slideIndex] = slideEl;
5356
+ slideEl.remove();
5357
+ });
5358
+ }
5359
+ }
5360
+ if (!domSlidesAssigned) {
5361
+ swiper.virtual.slides = swiper.params.virtual.slides;
5362
+ }
5363
+ swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`);
5364
+ swiper.params.watchSlidesProgress = true;
5365
+ swiper.originalParams.watchSlidesProgress = true;
5366
+ update(false, true);
5367
+ });
5368
+ on('setTranslate', () => {
5369
+ if (!swiper.params.virtual.enabled) return;
5370
+ if (swiper.params.cssMode && !swiper._immediateVirtual) {
5371
+ clearTimeout(cssModeTimeout);
5372
+ cssModeTimeout = setTimeout(() => {
5373
+ update();
5374
+ }, 100);
5375
+ } else {
5376
+ update();
5377
+ }
5378
+ });
5379
+ on('init update resize', () => {
5380
+ if (!swiper.params.virtual.enabled) return;
5381
+ if (swiper.params.cssMode) {
5382
+ setCSSProperty(swiper.wrapperEl, '--swiper-virtual-size', `${swiper.virtualSize}px`);
5383
+ }
5384
+ });
5385
+ Object.assign(swiper.virtual, {
5386
+ appendSlide,
5387
+ prependSlide,
5388
+ removeSlide,
5389
+ removeAllSlides,
5390
+ update
5391
+ });
5392
+ }
5393
+
5037
5394
  /* eslint-disable consistent-return */
5038
5395
  function Keyboard({
5039
5396
  swiper,
@@ -5536,228 +5893,6 @@
5536
5893
  });
5537
5894
  }
5538
5895
 
5539
- function createElementIfNotDefined(swiper, originalParams, params, checkProps) {
5540
- if (swiper.params.createElements) {
5541
- Object.keys(checkProps).forEach(key => {
5542
- if (!params[key] && params.auto === true) {
5543
- let element = elementChildren(swiper.el, `.${checkProps[key]}`)[0];
5544
- if (!element) {
5545
- element = createElement('div', checkProps[key]);
5546
- element.className = checkProps[key];
5547
- swiper.el.append(element);
5548
- }
5549
- params[key] = element;
5550
- originalParams[key] = element;
5551
- }
5552
- });
5553
- }
5554
- return params;
5555
- }
5556
-
5557
- const arrowSvg = `<svg class="swiper-navigation-icon" width="11" height="20" viewBox="0 0 11 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0.38296 20.0762C0.111788 19.805 0.111788 19.3654 0.38296 19.0942L9.19758 10.2796L0.38296 1.46497C0.111788 1.19379 0.111788 0.754138 0.38296 0.482966C0.654131 0.211794 1.09379 0.211794 1.36496 0.482966L10.4341 9.55214C10.8359 9.9539 10.8359 10.6053 10.4341 11.007L1.36496 20.0762C1.09379 20.3474 0.654131 20.3474 0.38296 20.0762Z" fill="currentColor"/></svg>`;
5558
- function Navigation({
5559
- swiper,
5560
- extendParams,
5561
- on,
5562
- emit
5563
- }) {
5564
- extendParams({
5565
- navigation: {
5566
- nextEl: null,
5567
- prevEl: null,
5568
- addIcons: true,
5569
- hideOnClick: false,
5570
- disabledClass: 'swiper-button-disabled',
5571
- hiddenClass: 'swiper-button-hidden',
5572
- lockClass: 'swiper-button-lock',
5573
- navigationDisabledClass: 'swiper-navigation-disabled'
5574
- }
5575
- });
5576
- swiper.navigation = {
5577
- nextEl: null,
5578
- prevEl: null,
5579
- arrowSvg
5580
- };
5581
- function getEl(el) {
5582
- let res;
5583
- if (el && typeof el === 'string' && swiper.isElement) {
5584
- res = swiper.el.querySelector(el) || swiper.hostEl.querySelector(el);
5585
- if (res) return res;
5586
- }
5587
- if (el) {
5588
- if (typeof el === 'string') res = [...document.querySelectorAll(el)];
5589
- if (swiper.params.uniqueNavElements && typeof el === 'string' && res && res.length > 1 && swiper.el.querySelectorAll(el).length === 1) {
5590
- res = swiper.el.querySelector(el);
5591
- } else if (res && res.length === 1) {
5592
- res = res[0];
5593
- }
5594
- }
5595
- if (el && !res) return el;
5596
- // if (Array.isArray(res) && res.length === 1) res = res[0];
5597
- return res;
5598
- }
5599
- function toggleEl(el, disabled) {
5600
- const params = swiper.params.navigation;
5601
- el = makeElementsArray(el);
5602
- el.forEach(subEl => {
5603
- if (subEl) {
5604
- subEl.classList[disabled ? 'add' : 'remove'](...params.disabledClass.split(' '));
5605
- if (subEl.tagName === 'BUTTON') subEl.disabled = disabled;
5606
- if (swiper.params.watchOverflow && swiper.enabled) {
5607
- subEl.classList[swiper.isLocked ? 'add' : 'remove'](params.lockClass);
5608
- }
5609
- }
5610
- });
5611
- }
5612
- function update() {
5613
- // Update Navigation Buttons
5614
- const {
5615
- nextEl,
5616
- prevEl
5617
- } = swiper.navigation;
5618
- if (swiper.params.loop) {
5619
- toggleEl(prevEl, false);
5620
- toggleEl(nextEl, false);
5621
- return;
5622
- }
5623
- toggleEl(prevEl, swiper.isBeginning && !swiper.params.rewind);
5624
- toggleEl(nextEl, swiper.isEnd && !swiper.params.rewind);
5625
- }
5626
- function onPrevClick(e) {
5627
- e.preventDefault();
5628
- if (swiper.isBeginning && !swiper.params.loop && !swiper.params.rewind) return;
5629
- swiper.slidePrev();
5630
- emit('navigationPrev');
5631
- }
5632
- function onNextClick(e) {
5633
- e.preventDefault();
5634
- if (swiper.isEnd && !swiper.params.loop && !swiper.params.rewind) return;
5635
- swiper.slideNext();
5636
- emit('navigationNext');
5637
- }
5638
- function init() {
5639
- const params = swiper.params.navigation;
5640
- swiper.params.navigation = createElementIfNotDefined(swiper, swiper.originalParams.navigation, swiper.params.navigation, {
5641
- nextEl: 'swiper-button-next',
5642
- prevEl: 'swiper-button-prev'
5643
- });
5644
- if (!(params.nextEl || params.prevEl)) return;
5645
- let nextEl = getEl(params.nextEl);
5646
- let prevEl = getEl(params.prevEl);
5647
- Object.assign(swiper.navigation, {
5648
- nextEl,
5649
- prevEl
5650
- });
5651
- nextEl = makeElementsArray(nextEl);
5652
- prevEl = makeElementsArray(prevEl);
5653
- const initButton = (el, dir) => {
5654
- if (el) {
5655
- if (params.addIcons && el.matches('.swiper-button-next,.swiper-button-prev') && !el.querySelector('svg')) {
5656
- const tempEl = document.createElement('div');
5657
- setInnerHTML(tempEl, arrowSvg);
5658
- el.appendChild(tempEl.querySelector('svg'));
5659
- tempEl.remove();
5660
- }
5661
- el.addEventListener('click', dir === 'next' ? onNextClick : onPrevClick);
5662
- }
5663
- if (!swiper.enabled && el) {
5664
- el.classList.add(...params.lockClass.split(' '));
5665
- }
5666
- };
5667
- nextEl.forEach(el => initButton(el, 'next'));
5668
- prevEl.forEach(el => initButton(el, 'prev'));
5669
- }
5670
- function destroy() {
5671
- let {
5672
- nextEl,
5673
- prevEl
5674
- } = swiper.navigation;
5675
- nextEl = makeElementsArray(nextEl);
5676
- prevEl = makeElementsArray(prevEl);
5677
- const destroyButton = (el, dir) => {
5678
- el.removeEventListener('click', dir === 'next' ? onNextClick : onPrevClick);
5679
- el.classList.remove(...swiper.params.navigation.disabledClass.split(' '));
5680
- };
5681
- nextEl.forEach(el => destroyButton(el, 'next'));
5682
- prevEl.forEach(el => destroyButton(el, 'prev'));
5683
- }
5684
- on('init', () => {
5685
- if (swiper.params.navigation.enabled === false) {
5686
- // eslint-disable-next-line
5687
- disable();
5688
- } else {
5689
- init();
5690
- update();
5691
- }
5692
- });
5693
- on('toEdge fromEdge lock unlock', () => {
5694
- update();
5695
- });
5696
- on('destroy', () => {
5697
- destroy();
5698
- });
5699
- on('enable disable', () => {
5700
- let {
5701
- nextEl,
5702
- prevEl
5703
- } = swiper.navigation;
5704
- nextEl = makeElementsArray(nextEl);
5705
- prevEl = makeElementsArray(prevEl);
5706
- if (swiper.enabled) {
5707
- update();
5708
- return;
5709
- }
5710
- [...nextEl, ...prevEl].filter(el => !!el).forEach(el => el.classList.add(swiper.params.navigation.lockClass));
5711
- });
5712
- on('click', (_s, e) => {
5713
- let {
5714
- nextEl,
5715
- prevEl
5716
- } = swiper.navigation;
5717
- nextEl = makeElementsArray(nextEl);
5718
- prevEl = makeElementsArray(prevEl);
5719
- const targetEl = e.target;
5720
- let targetIsButton = prevEl.includes(targetEl) || nextEl.includes(targetEl);
5721
- if (swiper.isElement && !targetIsButton) {
5722
- const path = e.path || e.composedPath && e.composedPath();
5723
- if (path) {
5724
- targetIsButton = path.find(pathEl => nextEl.includes(pathEl) || prevEl.includes(pathEl));
5725
- }
5726
- }
5727
- if (swiper.params.navigation.hideOnClick && !targetIsButton) {
5728
- if (swiper.pagination && swiper.params.pagination && swiper.params.pagination.clickable && (swiper.pagination.el === targetEl || swiper.pagination.el.contains(targetEl))) return;
5729
- let isHidden;
5730
- if (nextEl.length) {
5731
- isHidden = nextEl[0].classList.contains(swiper.params.navigation.hiddenClass);
5732
- } else if (prevEl.length) {
5733
- isHidden = prevEl[0].classList.contains(swiper.params.navigation.hiddenClass);
5734
- }
5735
- if (isHidden === true) {
5736
- emit('navigationShow');
5737
- } else {
5738
- emit('navigationHide');
5739
- }
5740
- [...nextEl, ...prevEl].filter(el => !!el).forEach(el => el.classList.toggle(swiper.params.navigation.hiddenClass));
5741
- }
5742
- });
5743
- const enable = () => {
5744
- swiper.el.classList.remove(...swiper.params.navigation.navigationDisabledClass.split(' '));
5745
- init();
5746
- update();
5747
- };
5748
- const disable = () => {
5749
- swiper.el.classList.add(...swiper.params.navigation.navigationDisabledClass.split(' '));
5750
- destroy();
5751
- };
5752
- Object.assign(swiper.navigation, {
5753
- enable,
5754
- disable,
5755
- update,
5756
- init,
5757
- destroy
5758
- });
5759
- }
5760
-
5761
5896
  function effectInit(params) {
5762
5897
  const {
5763
5898
  effect,
@@ -6049,8 +6184,11 @@
6049
6184
  */
6050
6185
 
6051
6186
 
6052
- const __iconNode$4 = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
6053
- const ChevronDown = createLucideIcon("chevron-down", __iconNode$4);
6187
+ const __iconNode$8 = [
6188
+ ["path", { d: "m11 17-5-5 5-5", key: "13zhaf" }],
6189
+ ["path", { d: "m18 17-5-5 5-5", key: "h8a8et" }]
6190
+ ];
6191
+ const ChevronsLeft = createLucideIcon("chevrons-left", __iconNode$8);
6054
6192
 
6055
6193
  /**
6056
6194
  * @license lucide-react v0.562.0 - ISC
@@ -6060,7 +6198,49 @@
6060
6198
  */
6061
6199
 
6062
6200
 
6063
- const __iconNode$3 = [
6201
+ const __iconNode$7 = [
6202
+ ["path", { d: "m6 17 5-5-5-5", key: "xnjwq" }],
6203
+ ["path", { d: "m13 17 5-5-5-5", key: "17xmmf" }]
6204
+ ];
6205
+ const ChevronsRight = createLucideIcon("chevrons-right", __iconNode$7);
6206
+
6207
+ /**
6208
+ * @license lucide-react v0.562.0 - ISC
6209
+ *
6210
+ * This source code is licensed under the ISC license.
6211
+ * See the LICENSE file in the root directory of this source tree.
6212
+ */
6213
+
6214
+
6215
+ const __iconNode$6 = [
6216
+ ["path", { d: "m17 11-5-5-5 5", key: "e8nh98" }],
6217
+ ["path", { d: "m17 18-5-5-5 5", key: "2avn1x" }]
6218
+ ];
6219
+ const ChevronsUp = createLucideIcon("chevrons-up", __iconNode$6);
6220
+
6221
+ /**
6222
+ * @license lucide-react v0.562.0 - ISC
6223
+ *
6224
+ * This source code is licensed under the ISC license.
6225
+ * See the LICENSE file in the root directory of this source tree.
6226
+ */
6227
+
6228
+
6229
+ const __iconNode$5 = [
6230
+ ["rect", { x: "14", y: "3", width: "5", height: "18", rx: "1", key: "kaeet6" }],
6231
+ ["rect", { x: "5", y: "3", width: "5", height: "18", rx: "1", key: "1wsw3u" }]
6232
+ ];
6233
+ const Pause = createLucideIcon("pause", __iconNode$5);
6234
+
6235
+ /**
6236
+ * @license lucide-react v0.562.0 - ISC
6237
+ *
6238
+ * This source code is licensed under the ISC license.
6239
+ * See the LICENSE file in the root directory of this source tree.
6240
+ */
6241
+
6242
+
6243
+ const __iconNode$4 = [
6064
6244
  [
6065
6245
  "path",
6066
6246
  {
@@ -6069,7 +6249,7 @@
6069
6249
  }
6070
6250
  ]
6071
6251
  ];
6072
- const Play = createLucideIcon("play", __iconNode$3);
6252
+ const Play = createLucideIcon("play", __iconNode$4);
6073
6253
 
6074
6254
  /**
6075
6255
  * @license lucide-react v0.562.0 - ISC
@@ -6079,7 +6259,7 @@
6079
6259
  */
6080
6260
 
6081
6261
 
6082
- const __iconNode$2 = [
6262
+ const __iconNode$3 = [
6083
6263
  [
6084
6264
  "path",
6085
6265
  {
@@ -6090,7 +6270,7 @@
6090
6270
  ["path", { d: "M16 9a5 5 0 0 1 0 6", key: "1q6k2b" }],
6091
6271
  ["path", { d: "M19.364 18.364a9 9 0 0 0 0-12.728", key: "ijwkga" }]
6092
6272
  ];
6093
- const Volume2 = createLucideIcon("volume-2", __iconNode$2);
6273
+ const Volume2 = createLucideIcon("volume-2", __iconNode$3);
6094
6274
 
6095
6275
  /**
6096
6276
  * @license lucide-react v0.562.0 - ISC
@@ -6100,7 +6280,7 @@
6100
6280
  */
6101
6281
 
6102
6282
 
6103
- const __iconNode$1 = [
6283
+ const __iconNode$2 = [
6104
6284
  [
6105
6285
  "path",
6106
6286
  {
@@ -6111,7 +6291,7 @@
6111
6291
  ["line", { x1: "22", x2: "16", y1: "9", y2: "15", key: "1ewh16" }],
6112
6292
  ["line", { x1: "16", x2: "22", y1: "9", y2: "15", key: "5ykzw1" }]
6113
6293
  ];
6114
- const VolumeX = createLucideIcon("volume-x", __iconNode$1);
6294
+ const VolumeX = createLucideIcon("volume-x", __iconNode$2);
6115
6295
 
6116
6296
  /**
6117
6297
  * @license lucide-react v0.562.0 - ISC
@@ -6121,616 +6301,409 @@
6121
6301
  */
6122
6302
 
6123
6303
 
6124
- const __iconNode = [
6304
+ const __iconNode$1 = [
6125
6305
  ["path", { d: "M18 6 6 18", key: "1bl5f8" }],
6126
6306
  ["path", { d: "m6 6 12 12", key: "d8bk6v" }]
6127
6307
  ];
6128
- const X = createLucideIcon("x", __iconNode);
6308
+ const X = createLucideIcon("x", __iconNode$1);
6309
+
6310
+ /**
6311
+ * @license lucide-react v0.562.0 - ISC
6312
+ *
6313
+ * This source code is licensed under the ISC license.
6314
+ * See the LICENSE file in the root directory of this source tree.
6315
+ */
6316
+
6317
+
6318
+ const __iconNode = [
6319
+ [
6320
+ "path",
6321
+ {
6322
+ d: "M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",
6323
+ key: "1xq2db"
6324
+ }
6325
+ ]
6326
+ ];
6327
+ const Zap = createLucideIcon("zap", __iconNode);
6129
6328
 
6130
- const defaultTranslations = {
6131
- swipe: 'Swipe',
6329
+ const defaultRiyilsTranslations = {
6132
6330
  close: 'Close',
6133
- mute: 'Mute',
6134
- unmute: 'Unmute',
6135
- speedIndicator: '2x',
6136
- videoViewer: 'Video viewer',
6137
- videoInteractionArea: 'Video interaction area',
6331
+ speedIndicator: '2x Speed',
6332
+ forward: '10s Forward',
6333
+ rewind: '10s Rewind',
6138
6334
  };
6139
- function RiyilsViewer({ videos, initialIndex = 0, onClose, onVideoChange, translations = defaultTranslations, progressBarColor = '#FF0000', }) {
6335
+ const DOUBLE_TAP_DELAY = 300;
6336
+ const LONG_PRESS_DELAY = 500;
6337
+ const SEEK_TIME = 10;
6338
+ const ANIMATION_DURATION = 600;
6339
+ const SCROLL_HINT_DURATION = 1000;
6340
+ function useLockBodyScroll() {
6341
+ React.useEffect(() => {
6342
+ const body = globalThis.document.body;
6343
+ const originalStyle = globalThis.getComputedStyle(body).overflow;
6344
+ const originalOverscroll = body.style.overscrollBehavior;
6345
+ body.style.overflow = 'hidden';
6346
+ body.style.overscrollBehavior = 'none';
6347
+ return () => {
6348
+ body.style.overflow = originalStyle;
6349
+ body.style.overscrollBehavior = originalOverscroll;
6350
+ };
6351
+ }, []);
6352
+ }
6353
+ function RiyilsViewer({ videos, initialIndex = 0, onClose, onVideoChange, translations = {}, progressBarColor = '#fff', }) {
6354
+ useLockBodyScroll();
6355
+ const t = React.useMemo(() => (Object.assign(Object.assign({}, defaultRiyilsTranslations), translations)), [translations]);
6140
6356
  const [currentIndex, setCurrentIndex] = React.useState(initialIndex);
6141
- const [isPaused, setIsPaused] = React.useState(false);
6142
6357
  const [isMuted, setIsMuted] = React.useState(true);
6143
- const [videoProgress, setVideoProgress] = React.useState(0);
6144
- const [isLoading, setIsLoading] = React.useState({});
6358
+ const [progress, setProgress] = React.useState(0);
6145
6359
  const [isSpeedUp, setIsSpeedUp] = React.useState(false);
6146
- const [showSwipeTip, setShowSwipeTip] = React.useState(true);
6360
+ const [isPlaying, setIsPlaying] = React.useState(true);
6361
+ const [seekFeedback, setSeekFeedback] = React.useState(null);
6362
+ const [showPlayPauseIcon, setShowPlayPauseIcon] = React.useState(false);
6363
+ const [showScrollHint, setShowScrollHint] = React.useState(false);
6147
6364
  const swiperRef = React.useRef(null);
6148
- const videoRefs = React.useRef([]);
6149
- const lastTapRef = React.useRef(0);
6150
- const holdTimeoutRef = React.useRef(null);
6365
+ const activeVideoRef = React.useRef(null);
6366
+ const containerRef = React.useRef(null);
6367
+ const longPressTimer = React.useRef(null);
6368
+ const doubleTapTimer = React.useRef(null);
6369
+ const lastTapTime = React.useRef(0);
6370
+ const longPressTriggered = React.useRef(false);
6151
6371
  React.useEffect(() => {
6152
- const currentVideoElement = videoRefs.current[currentIndex];
6153
- if (!currentVideoElement)
6372
+ const container = containerRef.current;
6373
+ if (!container)
6154
6374
  return;
6155
- const updateProgress = () => {
6156
- const progress = (currentVideoElement.currentTime / currentVideoElement.duration) * 100;
6157
- setVideoProgress(progress || 0);
6375
+ const handleContextMenu = (e) => {
6376
+ e.preventDefault();
6377
+ e.stopPropagation();
6158
6378
  };
6159
- currentVideoElement.addEventListener('timeupdate', updateProgress, { passive: true });
6379
+ container.addEventListener('contextmenu', handleContextMenu);
6160
6380
  return () => {
6161
- currentVideoElement.removeEventListener('timeupdate', updateProgress);
6381
+ container.removeEventListener('contextmenu', handleContextMenu);
6162
6382
  };
6163
- }, [currentIndex]);
6383
+ }, []);
6164
6384
  React.useEffect(() => {
6165
- onVideoChange === null || onVideoChange === void 0 ? void 0 : onVideoChange(currentIndex);
6166
- }, [currentIndex, onVideoChange]);
6385
+ const video = activeVideoRef.current;
6386
+ if (!video)
6387
+ return;
6388
+ if (isPlaying) {
6389
+ const playPromise = video.play();
6390
+ if (playPromise !== undefined) {
6391
+ playPromise.catch(() => {
6392
+ setIsPlaying(false);
6393
+ });
6394
+ }
6395
+ }
6396
+ else {
6397
+ video.pause();
6398
+ }
6399
+ }, [currentIndex, isPlaying]);
6167
6400
  React.useEffect(() => {
6168
- setShowSwipeTip(true);
6401
+ const video = activeVideoRef.current;
6402
+ if (video) {
6403
+ video.muted = isMuted;
6404
+ video.playbackRate = isSpeedUp ? 2 : 1;
6405
+ }
6406
+ }, [isMuted, isSpeedUp, currentIndex]);
6407
+ React.useEffect(() => {
6408
+ setShowScrollHint(true);
6169
6409
  const timer = setTimeout(() => {
6170
- setShowSwipeTip(false);
6171
- }, 3000);
6410
+ setShowScrollHint(false);
6411
+ }, SCROLL_HINT_DURATION);
6172
6412
  return () => clearTimeout(timer);
6173
6413
  }, [currentIndex]);
6174
6414
  React.useEffect(() => {
6175
- videoRefs.current.forEach((video, index) => {
6176
- if (video) {
6177
- if (index === currentIndex && !isPaused) {
6178
- video.playbackRate = isSpeedUp ? 2 : 1;
6179
- video.play().catch(() => { });
6180
- }
6181
- else {
6182
- video.pause();
6183
- }
6415
+ if (swiperRef.current) {
6416
+ swiperRef.current.virtual.update(true);
6417
+ swiperRef.current.update();
6418
+ if (swiperRef.current.keyboard) {
6419
+ swiperRef.current.keyboard.enable();
6184
6420
  }
6421
+ }
6422
+ }, [videos.length]);
6423
+ const handleTimeUpdate = React.useCallback((e) => {
6424
+ const vid = e.currentTarget;
6425
+ if (vid.duration) {
6426
+ setProgress((vid.currentTime / vid.duration) * 100);
6427
+ }
6428
+ }, []);
6429
+ const handleTouchStart = React.useCallback(() => {
6430
+ longPressTriggered.current = false;
6431
+ longPressTimer.current = setTimeout(() => {
6432
+ setIsSpeedUp(true);
6433
+ longPressTriggered.current = true;
6434
+ }, LONG_PRESS_DELAY);
6435
+ }, []);
6436
+ const handleTouchEnd = React.useCallback(() => {
6437
+ if (longPressTimer.current) {
6438
+ clearTimeout(longPressTimer.current);
6439
+ }
6440
+ setIsSpeedUp(false);
6441
+ }, []);
6442
+ const handleSeek = React.useCallback((seconds) => {
6443
+ const video = activeVideoRef.current;
6444
+ if (!video)
6445
+ return;
6446
+ video.currentTime = Math.min(Math.max(video.currentTime + seconds, 0), video.duration);
6447
+ setSeekFeedback(seconds > 0 ? 'forward' : 'rewind');
6448
+ setTimeout(() => setSeekFeedback(null), ANIMATION_DURATION);
6449
+ }, []);
6450
+ const togglePlay = React.useCallback(() => {
6451
+ setIsPlaying(prev => {
6452
+ const newState = !prev;
6453
+ setShowPlayPauseIcon(true);
6454
+ setTimeout(() => setShowPlayPauseIcon(false), ANIMATION_DURATION);
6455
+ return newState;
6185
6456
  });
6186
- }, [currentIndex, isPaused, isSpeedUp]);
6457
+ }, []);
6458
+ const handleZoneClick = React.useCallback((zone, e) => {
6459
+ e.preventDefault();
6460
+ e.stopPropagation();
6461
+ if (longPressTriggered.current) {
6462
+ longPressTriggered.current = false;
6463
+ return;
6464
+ }
6465
+ const now = Date.now();
6466
+ const timeDiff = now - lastTapTime.current;
6467
+ if (timeDiff < DOUBLE_TAP_DELAY && timeDiff > 0) {
6468
+ if (doubleTapTimer.current) {
6469
+ clearTimeout(doubleTapTimer.current);
6470
+ }
6471
+ if (zone === 'right') {
6472
+ handleSeek(SEEK_TIME);
6473
+ }
6474
+ else if (zone === 'left') {
6475
+ handleSeek(-SEEK_TIME);
6476
+ }
6477
+ else {
6478
+ togglePlay();
6479
+ }
6480
+ lastTapTime.current = 0;
6481
+ }
6482
+ else {
6483
+ lastTapTime.current = now;
6484
+ doubleTapTimer.current = setTimeout(() => {
6485
+ togglePlay();
6486
+ lastTapTime.current = 0;
6487
+ }, DOUBLE_TAP_DELAY);
6488
+ }
6489
+ }, [handleSeek, togglePlay]);
6490
+ const handleMuteToggle = React.useCallback((e) => {
6491
+ e.stopPropagation();
6492
+ setIsMuted(prev => !prev);
6493
+ }, []);
6187
6494
  React.useEffect(() => {
6188
6495
  const handleKeyDown = (e) => {
6189
- switch (e.key) {
6496
+ if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) {
6497
+ return;
6498
+ }
6499
+ switch (e.code) {
6190
6500
  case 'Escape':
6191
6501
  e.preventDefault();
6192
- onClose === null || onClose === void 0 ? void 0 : onClose();
6502
+ onClose();
6193
6503
  break;
6194
- case ' ':
6504
+ case 'Space':
6195
6505
  e.preventDefault();
6196
- setIsPaused((prev) => !prev);
6506
+ togglePlay();
6197
6507
  break;
6198
- case 'm':
6199
- case 'M':
6508
+ case 'KeyM':
6200
6509
  e.preventDefault();
6201
6510
  setIsMuted((prev) => !prev);
6202
6511
  break;
6203
6512
  }
6204
6513
  };
6205
6514
  globalThis.addEventListener('keydown', handleKeyDown);
6206
- return () => globalThis.removeEventListener('keydown', handleKeyDown);
6207
- }, [onClose]);
6208
- const handleSlideChange = (swiper) => {
6209
- setCurrentIndex(swiper.activeIndex);
6210
- setVideoProgress(0);
6211
- };
6212
- const handleVideoClick = () => {
6213
- const now = Date.now();
6214
- const timeSinceLastTap = now - lastTapRef.current;
6215
- if (timeSinceLastTap < 300 && timeSinceLastTap > 0) {
6216
- setIsPaused((prev) => !prev);
6217
- lastTapRef.current = 0;
6218
- }
6219
- else {
6220
- lastTapRef.current = now;
6221
- }
6222
- };
6223
- const handleTouchStart = (e, index) => {
6224
- const touch = e.touches[0];
6225
- const target = e.currentTarget;
6226
- const rect = target.getBoundingClientRect();
6227
- const x = touch.clientX - rect.left;
6228
- const width = rect.width;
6229
- if (x > width * 0.6 && index === currentIndex) {
6230
- holdTimeoutRef.current = setTimeout(() => {
6231
- setIsSpeedUp(true);
6232
- }, 100);
6233
- }
6234
- };
6235
- const clearSpeedUp = () => {
6236
- if (holdTimeoutRef.current) {
6237
- clearTimeout(holdTimeoutRef.current);
6238
- holdTimeoutRef.current = null;
6239
- }
6240
- setIsSpeedUp(false);
6241
- };
6242
- const handleTouchEnd = clearSpeedUp;
6243
- const handleMouseDown = (e, index) => {
6244
- const target = e.currentTarget;
6245
- const rect = target.getBoundingClientRect();
6246
- const x = e.clientX - rect.left;
6247
- const width = rect.width;
6248
- if (x > width * 0.6 && index === currentIndex) {
6249
- holdTimeoutRef.current = setTimeout(() => {
6250
- setIsSpeedUp(true);
6251
- }, 100);
6252
- }
6253
- };
6254
- const handleMouseUp = clearSpeedUp;
6255
- const goToNextVideo = () => {
6256
- var _a;
6257
- if (currentIndex < videos.length - 1) {
6258
- (_a = swiperRef.current) === null || _a === void 0 ? void 0 : _a.slideNext();
6259
- }
6260
- else {
6261
- onClose === null || onClose === void 0 ? void 0 : onClose();
6515
+ return () => {
6516
+ globalThis.removeEventListener('keydown', handleKeyDown);
6517
+ };
6518
+ }, [onClose, togglePlay]);
6519
+ const handleSlideChange = React.useCallback((s) => {
6520
+ setCurrentIndex(s.activeIndex);
6521
+ setProgress(0);
6522
+ setIsPlaying(true);
6523
+ setSeekFeedback(null);
6524
+ if (onVideoChange) {
6525
+ onVideoChange(s.activeIndex);
6262
6526
  }
6263
- };
6264
- return (React.createElement("dialog", { open: true, className: "react-riyils-viewer", onContextMenu: (e) => e.preventDefault(), "aria-label": translations.videoViewer, style: {
6265
- touchAction: 'pan-y',
6266
- WebkitTapHighlightColor: 'transparent',
6267
- userSelect: 'none',
6268
- WebkitUserSelect: 'none',
6269
- overscrollBehavior: 'none',
6270
- } },
6271
- React.createElement(Swiper, { modules: [Keyboard, Mousewheel], direction: "vertical", slidesPerView: 1, speed: 500, threshold: 5, touchRatio: 1, touchAngle: 45, followFinger: true, shortSwipes: true, longSwipes: true, longSwipesRatio: 0.5, longSwipesMs: 300, preventInteractionOnTransition: false, keyboard: { enabled: true }, mousewheel: { forceToAxis: true, sensitivity: 1 }, initialSlide: initialIndex, onSwiper: (swiper) => {
6272
- swiperRef.current = swiper;
6273
- }, onSlideChange: handleSlideChange, onReachEnd: () => {
6274
- setTimeout(() => {
6275
- onClose === null || onClose === void 0 ? void 0 : onClose();
6276
- }, 300);
6277
- }, style: { width: '100%', height: '100%' } }, videos.map((video, index) => {
6278
- const isActive = index === currentIndex;
6279
- return (React.createElement(SwiperSlide, { key: video.id },
6280
- React.createElement("section", { className: "react-riyils-viewer__section", "aria-label": `Video ${index + 1} of ${videos.length}` },
6281
- React.createElement("button", { type: "button", className: "react-riyils-viewer__interaction-area", onTouchStart: (e) => handleTouchStart(e, index), onTouchEnd: handleTouchEnd, onMouseDown: (e) => handleMouseDown(e, index), onMouseUp: handleMouseUp, onMouseLeave: handleMouseUp, onContextMenu: (e) => e.preventDefault(), "aria-label": translations.videoInteractionArea }),
6282
- React.createElement("video", { ref: (el) => {
6283
- videoRefs.current[index] = el;
6284
- }, src: video.videoUrl, "aria-label": `Video ${index + 1}`, onClick: handleVideoClick, onContextMenu: (e) => e.preventDefault(), className: "react-riyils-viewer__video", playsInline: true, muted: isMuted, preload: Math.abs(index - currentIndex) <= 1 ? 'auto' : 'metadata', onLoadStart: () => {
6285
- setIsLoading(prev => (Object.assign(Object.assign({}, prev), { [index]: true })));
6286
- }, onLoadedData: () => {
6287
- setIsLoading(prev => (Object.assign(Object.assign({}, prev), { [index]: false })));
6288
- }, onWaiting: () => {
6289
- setIsLoading(prev => (Object.assign(Object.assign({}, prev), { [index]: true })));
6290
- }, onCanPlay: () => {
6291
- setIsLoading(prev => (Object.assign(Object.assign({}, prev), { [index]: false })));
6292
- }, onEnded: (e) => {
6293
- if (isActive) {
6294
- const target = e.target;
6295
- if (target.currentTime >= target.duration - 0.1) {
6296
- goToNextVideo();
6297
- }
6298
- }
6299
- }, onTimeUpdate: (e) => {
6300
- if (isActive) {
6301
- const target = e.target;
6302
- setVideoProgress((target.currentTime / target.duration) * 100);
6303
- }
6304
- } },
6305
- React.createElement("track", { kind: "captions" })),
6306
- isLoading[index] && isActive && (React.createElement("div", { className: "react-riyils-viewer__loading" },
6307
- React.createElement("div", { className: "react-riyils-viewer__loading-spinner" }))),
6308
- isPaused && isActive && (React.createElement("div", { className: "react-riyils-viewer__pause-indicator" },
6309
- React.createElement("div", { className: "react-riyils-viewer__pause-icon" },
6310
- React.createElement("div", { className: "react-riyils-viewer__pause-bars", style: { borderLeftColor: 'rgba(255, 255, 255, 0.9)', borderRightColor: 'rgba(255, 255, 255, 0.9)' } })))),
6311
- isSpeedUp && isActive && (React.createElement("div", { className: "react-riyils-viewer__speed-indicator" },
6312
- React.createElement("div", { className: "react-riyils-viewer__speed-badge" },
6313
- React.createElement("span", { className: "react-riyils-viewer__speed-text" }, translations.speedIndicator)))))));
6314
- })),
6315
- React.createElement("div", { className: "react-riyils-viewer__overlay" },
6316
- React.createElement("div", { className: "react-riyils-viewer__header" },
6317
- React.createElement("div", { className: "react-riyils-viewer__header-content" },
6318
- React.createElement("div", { className: "react-riyils-viewer__progress-wrapper" },
6319
- React.createElement("div", { className: "react-riyils-viewer__progress-track", style: { backgroundColor: `${progressBarColor}30` } },
6320
- React.createElement("div", { className: "react-riyils-viewer__progress-bar", style: { width: `${videoProgress}%`, backgroundColor: progressBarColor } }))),
6321
- React.createElement("button", { onClick: onClose, className: "react-riyils-viewer__close-button", "aria-label": translations.close },
6322
- React.createElement(X, { className: "react-riyils-viewer__close-icon" })))),
6323
- currentIndex === 0 && showSwipeTip && (React.createElement("div", { className: "react-riyils-viewer__swipe-tip" },
6324
- React.createElement("div", { className: "react-riyils-viewer__swipe-tip-content" },
6325
- React.createElement("p", { className: "react-riyils-viewer__swipe-tip-text" }, translations.swipe),
6326
- React.createElement("div", { className: "react-riyils-viewer__swipe-tip-icon-wrapper" },
6327
- React.createElement(ChevronDown, { className: "react-riyils-viewer__swipe-tip-icon react-riyils-viewer__swipe-tip-icon--1" }),
6328
- React.createElement(ChevronDown, { className: "react-riyils-viewer__swipe-tip-icon react-riyils-viewer__swipe-tip-icon--2" }),
6329
- React.createElement(ChevronDown, { className: "react-riyils-viewer__swipe-tip-icon react-riyils-viewer__swipe-tip-icon--3" }))))),
6330
- showSwipeTip && currentIndex > 0 && (React.createElement("div", { className: "react-riyils-viewer__swipe-tip" },
6331
- React.createElement("div", { className: "react-riyils-viewer__swipe-tip-content" },
6332
- React.createElement("p", { className: "react-riyils-viewer__swipe-tip-text" }, translations.swipe),
6333
- React.createElement("div", { className: "react-riyils-viewer__swipe-tip-icon-wrapper" },
6334
- React.createElement(ChevronDown, { className: "react-riyils-viewer__swipe-tip-icon react-riyils-viewer__swipe-tip-icon--1" }),
6335
- React.createElement(ChevronDown, { className: "react-riyils-viewer__swipe-tip-icon react-riyils-viewer__swipe-tip-icon--2" }),
6336
- React.createElement(ChevronDown, { className: "react-riyils-viewer__swipe-tip-icon react-riyils-viewer__swipe-tip-icon--3" }))))),
6337
- React.createElement("div", { className: "react-riyils-viewer__mute-button-wrapper" },
6338
- React.createElement("button", { onClick: () => setIsMuted(!isMuted), className: "react-riyils-viewer__mute-button", "aria-label": isMuted ? translations.unmute : translations.mute }, isMuted ? (React.createElement(VolumeX, { className: "react-riyils-viewer__mute-icon" })) : (React.createElement(Volume2, { className: "react-riyils-viewer__mute-icon" })))))));
6527
+ }, [onVideoChange]);
6528
+ const preventDefaultMenu = React.useCallback((e) => {
6529
+ e.preventDefault();
6530
+ e.stopPropagation();
6531
+ return false;
6532
+ }, []);
6533
+ return (React.createElement("div", { ref: containerRef, className: "react-riyils-viewer", style: { WebkitTouchCallout: 'none' } },
6534
+ React.createElement("div", { className: "react-riyils-viewer__gradient-top" }),
6535
+ React.createElement("div", { className: "react-riyils-viewer__close-container" },
6536
+ React.createElement("button", { type: "button", onClick: onClose, className: "react-riyils-viewer__btn react-riyils-viewer__btn-close", "aria-label": t.close },
6537
+ React.createElement(X, { size: 24, strokeWidth: 2.5 }))),
6538
+ React.createElement(Swiper, { modules: [Keyboard, Mousewheel, Virtual], direction: "vertical", initialSlide: initialIndex, onSwiper: (s) => (swiperRef.current = s), onSlideChange: handleSlideChange, className: "h-full w-full", style: { height: '100%', width: '100%' }, threshold: 10, speed: 400, keyboard: { enabled: true }, mousewheel: { enabled: true, thresholdDelta: 50 }, virtual: { enabled: true, addSlidesBefore: 1, addSlidesAfter: 2 } }, videos.map((video, index) => (React.createElement(SwiperSlide, { key: video.id, virtualIndex: index, className: "react-riyils-viewer__slide" }, index === currentIndex ? (React.createElement(React.Fragment, null,
6539
+ React.createElement("fieldset", { className: "react-riyils-viewer__gesture-grid", onContextMenu: preventDefaultMenu, tabIndex: -1, style: { border: 0, margin: 0, padding: 0 } },
6540
+ React.createElement("button", { type: "button", className: "react-riyils-viewer__gesture-zone", onClick: (e) => handleZoneClick('left', e), "aria-label": t.rewind }),
6541
+ React.createElement("button", { type: "button", className: "react-riyils-viewer__gesture-zone", onClick: (e) => handleZoneClick('center', e), "aria-label": isPlaying ? 'Pause' : 'Play' }),
6542
+ React.createElement("button", { type: "button", className: "react-riyils-viewer__gesture-zone", onClick: (e) => handleZoneClick('right', e), onTouchStart: handleTouchStart, onTouchEnd: handleTouchEnd, onMouseDown: handleTouchStart, onMouseUp: handleTouchEnd, "aria-label": t.forward })),
6543
+ React.createElement("div", { className: `react-riyils-viewer__feedback-speed ${isSpeedUp ? 'visible' : ''}` },
6544
+ React.createElement(Zap, { size: 16, fill: "currentColor", className: "text-yellow-400" }),
6545
+ React.createElement("span", null, t.speedIndicator)),
6546
+ !isPlaying && (React.createElement("div", { className: "react-riyils-viewer__feedback-center" },
6547
+ React.createElement("div", { className: "react-riyils-viewer__feedback-icon animate-in" },
6548
+ React.createElement(Play, { size: 32, fill: "white" })))),
6549
+ isPlaying && showPlayPauseIcon && (React.createElement("div", { className: "react-riyils-viewer__feedback-center" },
6550
+ React.createElement("div", { className: "react-riyils-viewer__feedback-icon animate-out" },
6551
+ React.createElement(Pause, { size: 32, fill: "white" })))),
6552
+ seekFeedback && (React.createElement("div", { className: `react-riyils-viewer__feedback-seek ${seekFeedback === 'forward' ? 'right' : 'left'}` },
6553
+ React.createElement("div", { className: "react-riyils-viewer__seek-circle" },
6554
+ seekFeedback === 'forward' ? React.createElement(ChevronsRight, { size: 32 }) : React.createElement(ChevronsLeft, { size: 32 }),
6555
+ React.createElement("span", { className: "react-riyils-viewer__seek-text" }, "10s")))),
6556
+ React.createElement("video", { ref: activeVideoRef, src: video.videoUrl, className: "react-riyils-viewer__video", playsInline: true, loop: true, muted: isMuted, autoPlay: true, poster: video.thumbnailUrl, onTimeUpdate: handleTimeUpdate, onContextMenu: preventDefaultMenu, disablePictureInPicture: true, disableRemotePlayback: true, "aria-label": `Video ${video.id}` },
6557
+ React.createElement("track", { kind: "captions", src: video.captionUrl || '', label: "English" })))) : (React.createElement("div", { className: "react-riyils-viewer__slide" },
6558
+ React.createElement("div", { className: "react-riyils-viewer__loader" }))))))),
6559
+ React.createElement("div", { className: "react-riyils-viewer__scroll-hint", style: {
6560
+ position: 'absolute',
6561
+ bottom: '80px',
6562
+ left: '50%',
6563
+ transform: 'translateX(-50%)',
6564
+ zIndex: 45,
6565
+ pointerEvents: 'none',
6566
+ opacity: showScrollHint ? 1 : 0,
6567
+ transition: 'opacity 0.5s ease-in-out',
6568
+ display: 'flex',
6569
+ flexDirection: 'column',
6570
+ alignItems: 'center',
6571
+ animation: showScrollHint ? 'rr-bounce 1s infinite' : 'none',
6572
+ } },
6573
+ React.createElement(ChevronsUp, { size: 32, color: "rgba(255, 255, 255, 0.7)" })),
6574
+ React.createElement("div", { className: "react-riyils-viewer__gradient-bottom" },
6575
+ React.createElement("div", { className: "react-riyils-viewer__controls-row" },
6576
+ React.createElement("button", { type: "button", onClick: handleMuteToggle, className: "react-riyils-viewer__btn react-riyils-viewer__btn-mute" }, isMuted ? React.createElement(VolumeX, { size: 24 }) : React.createElement(Volume2, { size: 24 }))),
6577
+ React.createElement("div", { className: "react-riyils-viewer__progress-container" },
6578
+ React.createElement("div", { className: "react-riyils-viewer__progress-fill", style: { width: `${progress}%`, background: progressBarColor } }))),
6579
+ React.createElement("style", null, `
6580
+ @keyframes rr-bounce {
6581
+ 0%, 100% { transform: translateX(-50%) translateY(0); }
6582
+ 50% { transform: translateX(-50%) translateY(-10px); }
6583
+ }
6584
+ `)));
6339
6585
  }
6340
6586
 
6341
6587
  const defaultReactRiyilsTranslations = {
6342
- watchFullVideo: 'Watch Full Video',
6343
- videoProgress: 'Video progress',
6344
- };
6345
- const VIDEO_DURATION_LIMIT = 10;
6346
- const PRELOAD_DISTANCE = 1;
6347
- const CONTAINER_HEIGHT_MOBILE = 380;
6348
- const CONTAINER_HEIGHT_DESKTOP = 500;
6349
- const PREVIEW_DURATION = 2;
6350
- const getPreloadStrategy = (index, activeIndex, preloadDist) => {
6351
- if (index <= 3)
6352
- return 'auto';
6353
- const distance = Math.abs(index - activeIndex);
6354
- if (distance <= preloadDist)
6355
- return 'auto';
6356
- if (distance <= 2)
6357
- return 'metadata';
6358
- return 'none';
6359
- };
6360
- const handleVideoPlayWithFallback = (video, hasInteracted, setHasInteracted) => {
6361
- video.play().catch((error) => {
6362
- console.warn('Video play failed:', error);
6363
- if (!hasInteracted) {
6364
- const playOnInteraction = () => {
6365
- video.play().catch(() => { });
6366
- setHasInteracted(true);
6367
- document.removeEventListener('touchstart', playOnInteraction);
6368
- document.removeEventListener('click', playOnInteraction);
6369
- };
6370
- document.addEventListener('touchstart', playOnInteraction, { once: true });
6371
- document.addEventListener('click', playOnInteraction, { once: true });
6372
- }
6373
- });
6588
+ ctaButton: 'Watch Full Video',
6589
+ carouselAriaLabel: 'Video stories',
6590
+ slideActiveAriaLabel: 'Watch full video',
6591
+ slideInactiveAriaLabel: 'Go to slide',
6374
6592
  };
6375
- const safePlayVideo = (video) => {
6376
- video.play().catch((error) => console.warn('Video preload failed:', error));
6377
- };
6378
- function ReactRiyils({ videos, currentIndex, onVideoClick, onVideoChange, translations = defaultReactRiyilsTranslations, containerHeightMobile = CONTAINER_HEIGHT_MOBILE, containerHeightDesktop = CONTAINER_HEIGHT_DESKTOP, progressBarColor = '#3B82F6', videoDurationLimit = VIDEO_DURATION_LIMIT, preloadDistance = PRELOAD_DISTANCE, previewDuration = PREVIEW_DURATION, autoPlay = true, }) {
6379
- const swiperRef = React.useRef(null);
6380
- const videoRefs = React.useRef([]);
6381
- const containerRef = React.useRef(null);
6382
- const [activeIndex, setActiveIndex] = React.useState(currentIndex);
6383
- const [isLoading, setIsLoading] = React.useState({});
6384
- const [hasInteracted, setHasInteracted] = React.useState(false);
6385
- const wheelTimeoutRef = React.useRef(null);
6386
- const isWheelScrollingRef = React.useRef(false);
6387
- const dynamicStretch = Math.round(containerHeightDesktop / 9);
6388
- const setVideoLoading = (index, loading) => {
6389
- setIsLoading(prev => (Object.assign(Object.assign({}, prev), { [index]: loading })));
6390
- };
6391
- const handleVideoLoadedData = (e, index) => {
6392
- setVideoLoading(index, false);
6393
- const videoEl = e.target;
6394
- const distance = Math.abs(index - activeIndex);
6395
- if (videoEl.readyState >= 2) {
6396
- if (index === activeIndex) {
6397
- videoEl.style.opacity = '1';
6398
- videoEl.loop = true;
6399
- videoEl.currentTime = 0;
6400
- if (autoPlay) {
6401
- handleVideoPlayWithFallback(videoEl, hasInteracted, setHasInteracted);
6402
- }
6403
- }
6404
- else if (distance <= preloadDistance) {
6405
- videoEl.style.opacity = '0.95';
6406
- videoEl.loop = false;
6407
- videoEl.currentTime = 0;
6408
- if (autoPlay) {
6409
- safePlayVideo(videoEl);
6410
- }
6411
- }
6412
- }
6413
- };
6414
- React.useEffect(() => {
6415
- if (swiperRef.current && currentIndex !== activeIndex) {
6416
- swiperRef.current.slideTo(currentIndex, 400);
6417
- }
6418
- }, [currentIndex, activeIndex]);
6593
+ const SlideItem = React.memo(({ video, isVisualActive, index, onVideoClick, t, shouldLoad }) => {
6594
+ const videoRef = React.useRef(null);
6419
6595
  React.useEffect(() => {
6420
- const handleResize = () => {
6421
- if (swiperRef.current) {
6422
- swiperRef.current.update();
6423
- swiperRef.current.slideTo(activeIndex, 0);
6596
+ const el = videoRef.current;
6597
+ if (!el)
6598
+ return;
6599
+ const handleTimeUpdate = () => {
6600
+ if (!isVisualActive) {
6601
+ if (el.currentTime >= 2) {
6602
+ el.currentTime = 0;
6603
+ el.play().catch(() => { });
6604
+ }
6424
6605
  }
6425
6606
  };
6426
- window.addEventListener('resize', handleResize);
6427
- const timer = setTimeout(() => {
6428
- if (swiperRef.current) {
6429
- swiperRef.current.update();
6430
- swiperRef.current.slideTo(currentIndex, 0);
6431
- }
6432
- }, 100);
6433
- if (containerRef.current) {
6434
- const style = containerRef.current.style;
6435
- style.touchAction = 'pan-y pan-x';
6436
- style.webkitTapHighlightColor = 'transparent';
6437
- style.userSelect = 'none';
6438
- style.webkitUserSelect = 'none';
6439
- const handleWheel = (e) => {
6440
- var _a, _b;
6441
- if (isWheelScrollingRef.current) {
6442
- e.preventDefault();
6443
- e.stopPropagation();
6444
- return;
6445
- }
6446
- if (Math.abs(e.deltaX) < 30)
6447
- return;
6448
- e.preventDefault();
6449
- e.stopPropagation();
6450
- isWheelScrollingRef.current = true;
6451
- if (e.deltaX > 0) {
6452
- (_a = swiperRef.current) === null || _a === void 0 ? void 0 : _a.slideNext();
6453
- }
6454
- else if (e.deltaX < 0) {
6455
- (_b = swiperRef.current) === null || _b === void 0 ? void 0 : _b.slidePrev();
6456
- }
6457
- if (wheelTimeoutRef.current) {
6458
- clearTimeout(wheelTimeoutRef.current);
6459
- }
6460
- wheelTimeoutRef.current = setTimeout(() => {
6461
- isWheelScrollingRef.current = false;
6462
- }, 1000);
6463
- };
6464
- containerRef.current.addEventListener('wheel', handleWheel, { passive: false });
6465
- return () => {
6466
- var _a;
6467
- window.removeEventListener('resize', handleResize);
6468
- clearTimeout(timer);
6469
- if (wheelTimeoutRef.current)
6470
- clearTimeout(wheelTimeoutRef.current);
6471
- (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('wheel', handleWheel);
6472
- };
6607
+ el.addEventListener('timeupdate', handleTimeUpdate);
6608
+ if (isVisualActive) {
6609
+ el.currentTime = 0;
6610
+ el.play().catch(() => { });
6611
+ }
6612
+ else if (shouldLoad) {
6613
+ el.muted = true;
6614
+ el.currentTime = 0;
6473
6615
  }
6474
6616
  return () => {
6475
- window.removeEventListener('resize', handleResize);
6476
- clearTimeout(timer);
6477
- };
6478
- }, []);
6479
- React.useEffect(() => {
6480
- const videos = videoRefs.current;
6481
- return () => {
6482
- videos.forEach(video => {
6483
- if (video) {
6484
- video.pause();
6485
- video.removeAttribute('src');
6486
- video.load();
6487
- }
6488
- });
6617
+ el.removeEventListener('timeupdate', handleTimeUpdate);
6489
6618
  };
6490
- }, []);
6619
+ }, [isVisualActive, shouldLoad]);
6620
+ return (React.createElement("button", { type: "button", className: "react-riyils__slide-button", onClick: () => onVideoClick(index), "aria-label": isVisualActive ? t.slideActiveAriaLabel : t.slideInactiveAriaLabel },
6621
+ React.createElement("div", { className: `react-riyils__card ${isVisualActive ? 'active' : ''}` },
6622
+ React.createElement("video", { ref: videoRef, src: shouldLoad ? video.videoUrl : undefined, muted: true, playsInline: true, loop: isVisualActive, className: "react-riyils__video", preload: shouldLoad ? "auto" : "metadata" }),
6623
+ isVisualActive && (React.createElement("div", { className: "react-riyils__cta-container" },
6624
+ React.createElement("span", { className: "react-riyils__cta-button" },
6625
+ React.createElement(Play, { size: 14, fill: "currentColor" }),
6626
+ t.ctaButton))))));
6627
+ });
6628
+ SlideItem.displayName = 'SlideItem';
6629
+ function ReactRiyils({ videos, currentIndex = 0, onVideoClick, onVideoChange, translations = {}, containerHeightMobile, containerHeightDesktop, autoPlay = true, }) {
6630
+ const swiperRef = React.useRef(null);
6631
+ const [activeIndex, setActiveIndex] = React.useState(currentIndex);
6632
+ const t = React.useMemo(() => (Object.assign(Object.assign({}, defaultReactRiyilsTranslations), translations)), [translations]);
6633
+ const containerStyle = React.useMemo(() => ({
6634
+ '--container-height-mobile': containerHeightMobile ? `${containerHeightMobile}px` : undefined,
6635
+ '--container-height-desktop': containerHeightDesktop ? `${containerHeightDesktop}px` : undefined,
6636
+ }), [containerHeightMobile, containerHeightDesktop]);
6491
6637
  React.useEffect(() => {
6492
- const timer = setTimeout(() => {
6493
- videoRefs.current.forEach((video, index) => {
6494
- if (!video)
6495
- return;
6496
- const distance = Math.abs(index - activeIndex);
6497
- if (index === activeIndex) {
6498
- video.style.opacity = '1';
6499
- video.loop = true;
6500
- if (video.readyState >= 2) {
6501
- video.currentTime = 0;
6502
- if (autoPlay) {
6503
- handleVideoPlayWithFallback(video, hasInteracted, setHasInteracted);
6504
- }
6638
+ const swiper = swiperRef.current;
6639
+ if (swiper && !swiper.destroyed) {
6640
+ if (swiper.activeIndex !== currentIndex) {
6641
+ swiper.slideTo(currentIndex, 0);
6642
+ }
6643
+ swiper.update();
6644
+ const timer = setTimeout(() => {
6645
+ if (!swiper.destroyed) {
6646
+ swiper.updateSize();
6647
+ swiper.updateSlides();
6648
+ swiper.updateProgress();
6649
+ if (swiper.virtual) {
6650
+ swiper.virtual.update(true);
6505
6651
  }
6506
- }
6507
- else if (distance <= preloadDistance) {
6508
- video.style.opacity = '0.95';
6509
- video.loop = false;
6510
- if (video.readyState >= 2) {
6511
- video.currentTime = 0;
6512
- if (autoPlay) {
6513
- safePlayVideo(video);
6514
- }
6652
+ if (swiper.activeIndex !== currentIndex) {
6653
+ swiper.slideTo(currentIndex, 0);
6515
6654
  }
6516
6655
  }
6517
- });
6518
- }, 100);
6519
- return () => clearTimeout(timer);
6520
- }, [activeIndex, hasInteracted]);
6521
- const handleSlideChange = (swiper) => {
6522
- const activeIdx = swiper.activeIndex;
6523
- setActiveIndex(activeIdx);
6524
- onVideoChange(activeIdx);
6525
- videoRefs.current.forEach((video, index) => {
6526
- if (!video)
6527
- return;
6528
- const distance = Math.abs(index - activeIdx);
6529
- if (index === activeIdx) {
6530
- video.style.opacity = '1';
6531
- video.loop = true;
6532
- if (video.readyState >= 2) {
6533
- video.currentTime = 0;
6534
- video.play().catch((error) => console.warn('Video play failed:', error));
6535
- }
6536
- }
6537
- else if (distance <= PRELOAD_DISTANCE) {
6538
- video.style.opacity = '0.95';
6539
- video.loop = false;
6540
- if (video.readyState >= 2) {
6541
- video.currentTime = 0;
6542
- video.play().catch((error) => console.warn('Video preload failed:', error));
6543
- }
6544
- }
6545
- else {
6546
- video.pause();
6547
- video.currentTime = 0;
6548
- video.loop = false;
6549
- }
6550
- });
6551
- };
6552
- const handleTimeUpdate = (e, index) => {
6553
- var _a, _b;
6554
- const target = e.currentTarget;
6555
- const isActive = ((_a = swiperRef.current) === null || _a === void 0 ? void 0 : _a.activeIndex) === index;
6556
- const distance = Math.abs(index - activeIndex);
6557
- if (isActive) {
6558
- if (target.currentTime >= videoDurationLimit) {
6559
- target.currentTime = 0;
6560
- target.pause();
6561
- (_b = swiperRef.current) === null || _b === void 0 ? void 0 : _b.slideNext();
6562
- }
6656
+ }, 100);
6657
+ return () => clearTimeout(timer);
6563
6658
  }
6564
- else if (distance <= preloadDistance && target.currentTime >= previewDuration) {
6565
- target.currentTime = 0;
6566
- target.play().catch((error) => console.warn('Preview video replay failed:', error));
6659
+ }, [currentIndex]);
6660
+ React.useEffect(() => {
6661
+ if (!swiperRef.current || swiperRef.current.destroyed)
6662
+ return;
6663
+ swiperRef.current.update();
6664
+ if (swiperRef.current.virtual) {
6665
+ swiperRef.current.virtual.update(true);
6567
6666
  }
6568
- };
6569
- return (React.createElement("section", { ref: containerRef, className: "react-riyils__container", "data-height-mobile": true, "data-height-desktop": true, "aria-label": "Video carousel", style: {
6570
- '--container-height-mobile': `${containerHeightMobile}px`,
6571
- '--container-height-desktop': `${containerHeightDesktop}px`,
6572
- } },
6573
- React.createElement(Swiper, { modules: [Navigation, Keyboard, EffectCoverflow, Mousewheel], onSwiper: (swiper) => {
6574
- swiperRef.current = swiper;
6575
- }, onSlideChange: handleSlideChange, className: "react-riyils", slidesPerView: "auto", slidesPerGroup: 1, centeredSlides: true, centerInsufficientSlides: true, spaceBetween: 0, loop: false, initialSlide: currentIndex, speed: 800, threshold: 10, touchRatio: 1, touchAngle: 45, followFinger: true, shortSwipes: true, longSwipes: true, longSwipesRatio: 0.3, longSwipesMs: 300, preventInteractionOnTransition: true, touchStartPreventDefault: false, cssMode: false, keyboard: { enabled: true }, navigation: false, mousewheel: false, effect: "coverflow", resistance: true, resistanceRatio: 0, coverflowEffect: {
6667
+ }, [videos.length]);
6668
+ const handleSlideChange = React.useCallback((swiper) => {
6669
+ requestAnimationFrame(() => {
6670
+ if (swiper.activeIndex !== currentIndex) {
6671
+ setActiveIndex(swiper.activeIndex);
6672
+ onVideoChange(swiper.activeIndex);
6673
+ }
6674
+ });
6675
+ }, [onVideoChange, currentIndex]);
6676
+ return (React.createElement("section", { className: "react-riyils__container", style: containerStyle, "aria-label": t.carouselAriaLabel },
6677
+ React.createElement(Swiper, { modules: [Keyboard, Mousewheel, EffectCoverflow, Virtual], observer: true, observeParents: true, watchSlidesProgress: true, initialSlide: currentIndex, virtual: {
6678
+ addSlidesBefore: 4,
6679
+ addSlidesAfter: 5,
6680
+ enabled: true,
6681
+ cache: false
6682
+ }, effect: "coverflow", coverflowEffect: {
6576
6683
  rotate: 0,
6577
- stretch: dynamicStretch,
6684
+ stretch: -15,
6578
6685
  depth: 100,
6579
- modifier: 1,
6580
- slideShadows: false,
6581
- }, breakpoints: {
6582
- 640: {
6583
- spaceBetween: 0,
6584
- },
6585
- 768: {
6586
- spaceBetween: 0,
6587
- },
6588
- }, style: {
6589
- height: '100%',
6590
- padding: '0',
6591
- } }, videos.map((video, index) => {
6592
- return (React.createElement(SwiperSlide, { key: video.id }, ({ isActive: slideActive }) => {
6593
- return (React.createElement("button", { type: "button", className: `react-riyils__slide-button ${slideActive ? '' : 'react-riyils__slide-button--inactive'}`, onClick: () => {
6594
- var _a;
6595
- if (slideActive) {
6596
- onVideoClick(index);
6597
- }
6598
- else {
6599
- (_a = swiperRef.current) === null || _a === void 0 ? void 0 : _a.slideTo(index);
6600
- }
6601
- }, onKeyDown: (e) => {
6602
- var _a;
6603
- if (e.key === 'Enter' || e.key === ' ') {
6604
- e.preventDefault();
6605
- if (slideActive) {
6606
- onVideoClick(index);
6607
- }
6608
- else {
6609
- (_a = swiperRef.current) === null || _a === void 0 ? void 0 : _a.slideTo(index);
6610
- }
6686
+ modifier: 2.5,
6687
+ slideShadows: true,
6688
+ }, onSwiper: (s) => {
6689
+ swiperRef.current = s;
6690
+ }, onSlideChange: handleSlideChange, slidesPerView: "auto", centeredSlides: true, grabCursor: true, keyboard: { enabled: true }, mousewheel: { forceToAxis: true }, className: "react-riyils" }, videos.map((video, index) => {
6691
+ const isSelected = index === activeIndex;
6692
+ const distance = Math.abs(index - activeIndex);
6693
+ const shouldLoad = distance < 4;
6694
+ return (React.createElement(SwiperSlide, { key: video.id, virtualIndex: index },
6695
+ React.createElement(SlideItem, { video: video, index: index, isVisualActive: isSelected, onVideoClick: isSelected ? onVideoClick : () => {
6696
+ if (swiperRef.current && !swiperRef.current.destroyed) {
6697
+ swiperRef.current.slideTo(index);
6611
6698
  }
6612
- }, onContextMenu: (e) => e.preventDefault(), "aria-label": `Video ${index + 1}` },
6613
- React.createElement("div", { className: `react-riyils__video-container ${slideActive
6614
- ? 'react-riyils__video-container--active'
6615
- : 'react-riyils__video-container--inactive'}` },
6616
- React.createElement("video", { ref: (el) => {
6617
- videoRefs.current[index] = el;
6618
- }, src: video.videoUrl, className: "react-riyils__video", muted: true, playsInline: true, onContextMenu: (e) => e.preventDefault(), preload: getPreloadStrategy(index, activeIndex, preloadDistance), "aria-label": `Video ${index + 1}`, onLoadStart: () => setVideoLoading(index, true), onLoadedData: (e) => handleVideoLoadedData(e, index), onWaiting: () => setVideoLoading(index, true), onCanPlay: () => setVideoLoading(index, false), onTimeUpdate: (e) => handleTimeUpdate(e, index) }),
6619
- isLoading[index] && slideActive && (React.createElement("div", { className: "react-riyils__loading" },
6620
- React.createElement("div", { className: "react-riyils__spinner" }))),
6621
- !slideActive && (React.createElement(React.Fragment, null,
6622
- React.createElement("div", { className: "react-riyils__overlay-gradient" }),
6623
- React.createElement("div", { className: "react-riyils__overlay-blur" }))),
6624
- slideActive && (React.createElement("div", { className: "react-riyils__cta-container" },
6625
- React.createElement("button", { onClick: (e) => {
6626
- e.stopPropagation();
6627
- onVideoClick(index);
6628
- }, "aria-label": translations.watchFullVideo, className: "react-riyils__cta-button" },
6629
- React.createElement("div", { className: "react-riyils__cta-badge" },
6630
- React.createElement(Play, { className: "react-riyils__cta-icon", fill: "currentColor", strokeWidth: 0 }),
6631
- React.createElement("span", { className: "react-riyils__cta-text" }, translations.watchFullVideo))))))));
6632
- }));
6699
+ }, t: t, shouldLoad: isSelected || shouldLoad })));
6633
6700
  }))));
6634
6701
  }
6635
- // Custom Hooks
6636
- function useVideoPreload(videoRefs, activeIndex, preloadDistance = PRELOAD_DISTANCE) {
6637
- React.useEffect(() => {
6638
- videoRefs.current.forEach((video, index) => {
6639
- if (!video)
6640
- return;
6641
- const distance = Math.abs(index - activeIndex);
6642
- if (distance <= preloadDistance) {
6643
- video.preload = 'auto';
6644
- }
6645
- else if (distance <= 2) {
6646
- video.preload = 'metadata';
6647
- }
6648
- else {
6649
- video.preload = 'none';
6650
- }
6651
- });
6652
- }, [activeIndex, preloadDistance, videoRefs]);
6653
- }
6654
- function useVideoControls(videoElement, isActive, autoPlay = true) {
6655
- const [isPlaying, setIsPlaying] = React.useState(false);
6656
- const [progress, setProgress] = React.useState(0);
6657
- React.useEffect(() => {
6658
- if (!videoElement)
6659
- return;
6660
- const handlePlay = () => setIsPlaying(true);
6661
- const handlePause = () => setIsPlaying(false);
6662
- const handleTimeUpdate = () => {
6663
- const prog = (videoElement.currentTime / videoElement.duration) * 100;
6664
- setProgress(prog || 0);
6665
- };
6666
- videoElement.addEventListener('play', handlePlay);
6667
- videoElement.addEventListener('pause', handlePause);
6668
- videoElement.addEventListener('timeupdate', handleTimeUpdate);
6669
- if (isActive && autoPlay && videoElement.paused) {
6670
- videoElement.play().catch(() => { });
6671
- }
6672
- else if (!isActive && !videoElement.paused) {
6673
- videoElement.pause();
6674
- }
6675
- return () => {
6676
- videoElement.removeEventListener('play', handlePlay);
6677
- videoElement.removeEventListener('pause', handlePause);
6678
- videoElement.removeEventListener('timeupdate', handleTimeUpdate);
6679
- };
6680
- }, [videoElement, isActive, autoPlay]);
6681
- const play = () => videoElement === null || videoElement === void 0 ? void 0 : videoElement.play().catch(() => { });
6682
- const pause = () => videoElement === null || videoElement === void 0 ? void 0 : videoElement.pause();
6683
- const togglePlay = () => (isPlaying ? pause() : play());
6684
- const seek = (time) => {
6685
- if (videoElement)
6686
- videoElement.currentTime = time;
6687
- };
6688
- return { isPlaying, progress, play, pause, togglePlay, seek };
6689
- }
6690
- function useSwiperControl(initialIndex = 0) {
6691
- const swiperRef = React.useRef(null);
6692
- const [currentIndex, setCurrentIndex] = React.useState(initialIndex);
6693
- const goToSlide = (index, speed) => {
6694
- var _a;
6695
- (_a = swiperRef.current) === null || _a === void 0 ? void 0 : _a.slideTo(index, speed);
6696
- };
6697
- const nextSlide = () => {
6698
- var _a;
6699
- (_a = swiperRef.current) === null || _a === void 0 ? void 0 : _a.slideNext();
6700
- };
6701
- const prevSlide = () => {
6702
- var _a;
6703
- (_a = swiperRef.current) === null || _a === void 0 ? void 0 : _a.slidePrev();
6704
- };
6705
- const updateSlider = () => {
6706
- var _a;
6707
- (_a = swiperRef.current) === null || _a === void 0 ? void 0 : _a.update();
6708
- };
6709
- return {
6710
- swiperRef,
6711
- currentIndex,
6712
- setCurrentIndex,
6713
- goToSlide,
6714
- nextSlide,
6715
- prevSlide,
6716
- updateSlider,
6717
- };
6718
- }
6719
6702
 
6720
- exports.CONTAINER_HEIGHT_DESKTOP = CONTAINER_HEIGHT_DESKTOP;
6721
- exports.CONTAINER_HEIGHT_MOBILE = CONTAINER_HEIGHT_MOBILE;
6722
- exports.PRELOAD_DISTANCE = PRELOAD_DISTANCE;
6723
- exports.PREVIEW_DURATION = PREVIEW_DURATION;
6724
6703
  exports.ReactRiyils = ReactRiyils;
6725
6704
  exports.RiyilsViewer = RiyilsViewer;
6726
- exports.VIDEO_DURATION_LIMIT = VIDEO_DURATION_LIMIT;
6727
6705
  exports.defaultReactRiyilsTranslations = defaultReactRiyilsTranslations;
6728
- exports.getPreloadStrategy = getPreloadStrategy;
6729
- exports.handleVideoPlayWithFallback = handleVideoPlayWithFallback;
6730
- exports.safePlayVideo = safePlayVideo;
6731
- exports.useSwiperControl = useSwiperControl;
6732
- exports.useVideoControls = useVideoControls;
6733
- exports.useVideoPreload = useVideoPreload;
6706
+ exports.defaultRiyilsTranslations = defaultRiyilsTranslations;
6734
6707
 
6735
6708
  }));
6736
6709
  //# sourceMappingURL=index.umd.js.map