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