@geekapps/silo-elements-nextjs 0.2.52 → 0.2.53

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.
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo, useState, useRef, useEffect, useCallback } from 'react';
2
2
  import gsap from 'gsap';
3
- import { Pause, Play, VolumeX, Volume2, Captions as Captions$1, Settings, Minimize, Maximize } from 'lucide-react';
3
+ import { Pause, Play, Captions as Captions$1, Settings, Minimize, Maximize, VolumeX, Volume2 } from 'lucide-react';
4
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
5
 
6
6
  var AUTO_QUALITY = {
@@ -104,6 +104,8 @@ function Video({
104
104
  const [audioTracks, setAudioTracks] = useState([]);
105
105
  const [selectedAudio, setSelectedAudio] = useState(0);
106
106
  const [settingsOpen, setSettingsOpen] = useState(false);
107
+ const [settingsVisible, setSettingsVisible] = useState(false);
108
+ const settingsCloseTimerRef = useRef(null);
107
109
  const [settingsTab, setSettingsTab] = useState("root");
108
110
  const [playbackRate, setPlaybackRate] = useState(1);
109
111
  const [subtitleStyle, setSubtitleStyle] = useState({
@@ -114,6 +116,8 @@ function Video({
114
116
  });
115
117
  const [subtitleMode, setSubtitleMode] = useState(initialSubtitleMode);
116
118
  const [activeCue, setActiveCue] = useState(null);
119
+ const [storyboardSheetSize, setStoryboardSheetSize] = useState(null);
120
+ const storyboardSheetUrlRef = useRef("");
117
121
  const [storyboardCues, setStoryboardCues] = useState(
118
122
  []
119
123
  );
@@ -122,6 +126,7 @@ function Video({
122
126
  const [currentTime, setCurrentTime] = useState(0);
123
127
  const [bufferedTime, setBufferedTime] = useState(0);
124
128
  const [isDragging, setIsDragging] = useState(false);
129
+ const [isHoveringProgress, setIsHoveringProgress] = useState(false);
125
130
  const dragPointerIdRef = useRef(null);
126
131
  const [isPlaying, setIsPlaying] = useState(false);
127
132
  const [hasPlayed, setHasPlayed] = useState(false);
@@ -197,6 +202,16 @@ function Video({
197
202
  }
198
203
  );
199
204
  }, []);
205
+ const openSettings = useCallback(() => {
206
+ setSettingsOpen(true);
207
+ setSettingsTab("root");
208
+ window.setTimeout(() => setSettingsVisible(true), 10);
209
+ }, []);
210
+ const closeSettings = useCallback(() => {
211
+ setSettingsVisible(false);
212
+ if (settingsCloseTimerRef.current) window.clearTimeout(settingsCloseTimerRef.current);
213
+ settingsCloseTimerRef.current = window.setTimeout(() => setSettingsOpen(false), 200);
214
+ }, []);
200
215
  useEffect(() => {
201
216
  if (sourceIndex >= parsed.sources.length) {
202
217
  setSourceIndex(initialSourceIndex);
@@ -422,7 +437,7 @@ function Video({
422
437
  setQualities([AUTO_QUALITY]);
423
438
  setAudioTracks([]);
424
439
  setSelectedAudio(0);
425
- setSettingsOpen(false);
440
+ closeSettings();
426
441
  video.pause();
427
442
  video.removeAttribute("src");
428
443
  video.load();
@@ -649,17 +664,17 @@ function Video({
649
664
  }, []);
650
665
  const changeAudio = useCallback((trackId) => {
651
666
  setSelectedAudio(trackId);
652
- setSettingsOpen(false);
667
+ closeSettings();
653
668
  if (hlsRef.current) {
654
669
  hlsRef.current.audioTrack = trackId;
655
670
  }
656
- }, []);
671
+ }, [closeSettings]);
657
672
  const changeQuality = useCallback(
658
673
  (qualityId) => {
659
674
  const option = qualities.find((quality) => quality.id === qualityId);
660
675
  if (!option) return;
661
676
  setSelectedQuality(qualityId);
662
- setSettingsOpen(false);
677
+ closeSettings();
663
678
  if (option.type === "auto") {
664
679
  if (hlsRef.current) {
665
680
  hlsRef.current.currentLevel = -1;
@@ -694,7 +709,7 @@ function Video({
694
709
  dashRef.current.setQualityFor("video", option.index);
695
710
  }
696
711
  },
697
- [qualities]
712
+ [qualities, closeSettings]
698
713
  );
699
714
  const seekFromPointer = useCallback(
700
715
  (clientX) => {
@@ -739,7 +754,11 @@ function Video({
739
754
  },
740
755
  [isDragging, seekFromPointer, updatePreview]
741
756
  );
757
+ const handleProgressPointerEnter = useCallback(() => {
758
+ setIsHoveringProgress(true);
759
+ }, []);
742
760
  const handleProgressPointerLeave = useCallback(() => {
761
+ setIsHoveringProgress(false);
743
762
  if (!isDragging) setPreview(null);
744
763
  }, [isDragging]);
745
764
  const handleProgressPointerDown = useCallback(
@@ -810,10 +829,18 @@ function Video({
810
829
  onKeyDown: handleKeyDown,
811
830
  onMouseMove: showControlsTemporarily,
812
831
  onMouseLeave: () => {
832
+ closeSettings();
813
833
  if (isPlaying && autoHideControls) {
814
834
  setControlsVisible(false);
815
835
  }
816
836
  },
837
+ onBlur: (e) => {
838
+ if (!e.currentTarget.contains(e.relatedTarget)) {
839
+ closeSettings();
840
+ }
841
+ },
842
+ onTouchStart: showControlsTemporarily,
843
+ onTouchMove: showControlsTemporarily,
817
844
  className: "relative w-full overflow-hidden rounded-[14px] bg-black shadow-[0_30px_90px_rgba(15,15,15,0.22)] outline-none ring-1 ring-black/5",
818
845
  style: fixedHeight ? {
819
846
  height: typeof fixedHeight === "number" ? `${fixedHeight}px` : fixedHeight
@@ -826,7 +853,7 @@ function Video({
826
853
  "video",
827
854
  {
828
855
  ref: videoRef,
829
- className: "h-full w-full object-contain",
856
+ className: `h-full w-full ${isFullscreen ? "object-contain" : "object-cover"}`,
830
857
  playsInline: true,
831
858
  preload: "metadata",
832
859
  crossOrigin: "anonymous",
@@ -917,7 +944,7 @@ function Video({
917
944
  "div",
918
945
  {
919
946
  className: "fixed inset-0 z-70",
920
- onClick: () => setSettingsOpen(false)
947
+ onClick: closeSettings
921
948
  }
922
949
  ),
923
950
  /* @__PURE__ */ jsxs(
@@ -929,7 +956,9 @@ function Video({
929
956
  224,
930
957
  Math.max(180, (playerWidth || 640) * 0.22)
931
958
  ) + "px",
932
- animation: "spFadeIn 0.15s ease"
959
+ opacity: settingsVisible ? 1 : 0,
960
+ transform: settingsVisible ? "translateY(0) scale(1)" : "translateY(8px) scale(0.97)",
961
+ transition: "opacity 0.18s ease, transform 0.18s ease"
933
962
  },
934
963
  children: [
935
964
  settingsTab === "root" && /* @__PURE__ */ jsx("div", { children: [
@@ -1363,8 +1392,7 @@ function Video({
1363
1392
  type: "button",
1364
1393
  onClick: () => {
1365
1394
  setPlaybackRate(speed);
1366
- setSettingsOpen(false);
1367
- setSettingsTab("root");
1395
+ closeSettings();
1368
1396
  },
1369
1397
  className: "flex w-full items-center gap-3 px-4 py-2.5 text-sm transition hover:bg-white/8",
1370
1398
  children: [
@@ -1400,37 +1428,40 @@ function Video({
1400
1428
  ] })
1401
1429
  ]
1402
1430
  }
1403
- ),
1404
- /* @__PURE__ */ jsx("style", { children: `@keyframes spFadeIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}` })
1431
+ )
1405
1432
  ] }),
1406
1433
  /* @__PURE__ */ jsxs(
1407
1434
  "div",
1408
1435
  {
1409
1436
  ref: progressRef,
1410
1437
  onPointerMove: handleProgressPointerMove,
1438
+ onPointerEnter: handleProgressPointerEnter,
1411
1439
  onPointerLeave: handleProgressPointerLeave,
1412
1440
  onPointerDown: handleProgressPointerDown,
1413
1441
  onPointerUp: handleProgressPointerUp,
1414
- className: "group relative mb-3 h-7 cursor-pointer",
1442
+ className: "relative mb-2 h-8 cursor-pointer overflow-visible",
1415
1443
  children: [
1416
1444
  /* @__PURE__ */ jsxs(
1417
1445
  "div",
1418
1446
  {
1419
- className: "absolute left-0 right-0 top-1/2 -translate-y-1/2 overflow-hidden rounded-full bg-white/22 transition-[height] duration-150",
1420
- style: { height: isDragging ? "6px" : "3px" },
1447
+ className: "absolute left-0 right-0 top-1/2 -translate-y-1/2 overflow-hidden rounded-full bg-white/18",
1448
+ style: {
1449
+ height: isDragging ? "7px" : isHoveringProgress ? "5px" : "3px",
1450
+ transition: "height 0.15s ease"
1451
+ },
1421
1452
  children: [
1422
1453
  /* @__PURE__ */ jsx(
1423
1454
  "div",
1424
1455
  {
1425
- className: "absolute inset-y-0 left-0 rounded-full bg-white/30",
1456
+ className: "absolute inset-y-0 left-0 rounded-full bg-white/28",
1426
1457
  style: { width: `${bufferedPercent}%` }
1427
1458
  }
1428
1459
  ),
1429
1460
  /* @__PURE__ */ jsx(
1430
1461
  "div",
1431
1462
  {
1432
- className: "absolute inset-y-0 left-0 rounded-full bg-white/90",
1433
- style: { width: `${progressPercent}%` }
1463
+ className: "absolute inset-y-0 left-0 rounded-full bg-white",
1464
+ style: { width: `${progressPercent}%`, transition: "width 0.05s linear" }
1434
1465
  }
1435
1466
  )
1436
1467
  ]
@@ -1439,14 +1470,90 @@ function Video({
1439
1470
  /* @__PURE__ */ jsx(
1440
1471
  "div",
1441
1472
  {
1442
- className: "pointer-events-none absolute top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-white shadow-md transition-[width,height] duration-100 group-hover:size-4",
1473
+ className: "pointer-events-none absolute rounded-full bg-white shadow-[0_1px_6px_rgba(0,0,0,0.5)]",
1443
1474
  style: {
1475
+ top: "50%",
1444
1476
  left: `${progressPercent}%`,
1445
- width: isDragging ? "16px" : "10px",
1446
- height: isDragging ? "16px" : "10px"
1477
+ transform: "translate(-50%, -50%)",
1478
+ width: isDragging ? "18px" : isHoveringProgress ? "14px" : "10px",
1479
+ height: isDragging ? "18px" : isHoveringProgress ? "14px" : "10px",
1480
+ transition: "width 0.2s cubic-bezier(0.34,1.56,0.64,1), height 0.2s cubic-bezier(0.34,1.56,0.64,1)"
1447
1481
  }
1448
1482
  }
1449
- )
1483
+ ),
1484
+ preview && (() => {
1485
+ const frameW = preview.cue.w ?? 160;
1486
+ const frameH = preview.cue.h ?? 90;
1487
+ const thumbW = 200;
1488
+ const thumbH = Math.round(thumbW * (frameH / frameW));
1489
+ const scale = thumbW / frameW;
1490
+ const isSprite = preview.cue.x != null && preview.cue.y != null;
1491
+ return /* @__PURE__ */ jsxs(
1492
+ "div",
1493
+ {
1494
+ className: "pointer-events-none absolute flex flex-col items-center gap-1",
1495
+ style: {
1496
+ bottom: "calc(100% + 6px)",
1497
+ left: preview.left,
1498
+ transform: "translateX(-50%)",
1499
+ zIndex: 80
1500
+ },
1501
+ children: [
1502
+ /* @__PURE__ */ jsx(
1503
+ "div",
1504
+ {
1505
+ className: "overflow-hidden rounded-lg shadow-2xl ring-1 ring-white/20",
1506
+ style: { width: thumbW, height: thumbH, flexShrink: 0 },
1507
+ children: isSprite ? (
1508
+ // Sprite: need full sheet dimensions to compute backgroundSize correctly.
1509
+ // Load them once from the image's natural size.
1510
+ (() => {
1511
+ const imgUrl = preview.cue.image;
1512
+ if (storyboardSheetUrlRef.current !== imgUrl) {
1513
+ storyboardSheetUrlRef.current = imgUrl;
1514
+ const img = new window.Image();
1515
+ img.onload = () => setStoryboardSheetSize({ w: img.naturalWidth, h: img.naturalHeight });
1516
+ img.src = imgUrl;
1517
+ }
1518
+ if (!storyboardSheetSize) return null;
1519
+ const bsW = storyboardSheetSize.w * scale;
1520
+ const bsH = storyboardSheetSize.h * scale;
1521
+ return /* @__PURE__ */ jsx(
1522
+ "div",
1523
+ {
1524
+ style: {
1525
+ width: thumbW,
1526
+ height: thumbH,
1527
+ backgroundImage: `url(${imgUrl})`,
1528
+ backgroundRepeat: "no-repeat",
1529
+ backgroundPosition: `-${(preview.cue.x ?? 0) * scale}px -${(preview.cue.y ?? 0) * scale}px`,
1530
+ backgroundSize: `${bsW}px ${bsH}px`
1531
+ }
1532
+ }
1533
+ );
1534
+ })()
1535
+ ) : /* @__PURE__ */ jsx(
1536
+ "img",
1537
+ {
1538
+ src: preview.cue.image,
1539
+ alt: "",
1540
+ style: { width: thumbW, height: thumbH, objectFit: "cover", objectPosition: "center", display: "block" }
1541
+ }
1542
+ )
1543
+ }
1544
+ ),
1545
+ /* @__PURE__ */ jsx(
1546
+ "span",
1547
+ {
1548
+ className: "rounded-md px-2 py-0.5 text-[11px] font-semibold tabular-nums text-white/90",
1549
+ style: { background: "rgba(0,0,0,0.55)", backdropFilter: "blur(6px)" },
1550
+ children: formatTime(preview.time)
1551
+ }
1552
+ )
1553
+ ]
1554
+ }
1555
+ );
1556
+ })()
1450
1557
  ]
1451
1558
  }
1452
1559
  ),
@@ -1469,44 +1576,29 @@ function Video({
1469
1576
  ] })
1470
1577
  ] }),
1471
1578
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5 @sm:gap-1", children: [
1472
- /* @__PURE__ */ jsxs("div", { className: "group flex items-center", children: [
1473
- /* @__PURE__ */ jsx(
1474
- "button",
1475
- {
1476
- type: "button",
1477
- onClick: () => setIsMuted((value) => !value),
1478
- className: "grid size-8 place-items-center text-white/70 transition hover:text-white @sm:size-9",
1479
- "aria-label": isMuted ? "Unmute" : "Mute",
1480
- children: isMuted || volume === 0 ? /* @__PURE__ */ jsx(VolumeX, { className: "size-4 @sm:size-5" }) : /* @__PURE__ */ jsx(Volume2, { className: "size-4 @sm:size-5" })
1481
- }
1482
- ),
1483
- /* @__PURE__ */ jsx("div", { className: "w-0 overflow-hidden transition-all duration-200 group-hover:w-16 @md:group-hover:w-20", children: /* @__PURE__ */ jsx(
1484
- "input",
1485
- {
1486
- type: "range",
1487
- min: "0",
1488
- max: "1",
1489
- step: "0.01",
1490
- value: isMuted ? 0 : volume,
1491
- onChange: (event) => {
1492
- const nextVolume = Number(event.target.value);
1493
- setVolume(nextVolume);
1494
- setIsMuted(nextVolume === 0);
1495
- },
1496
- className: "h-1 w-14 accent-white @md:w-20",
1497
- "aria-label": "Audio level"
1498
- }
1499
- ) })
1500
- ] }),
1579
+ /* @__PURE__ */ jsx(
1580
+ VolumeSlider,
1581
+ {
1582
+ volume: isMuted ? 0 : volume,
1583
+ onMuteToggle: () => setIsMuted((v) => !v),
1584
+ onVolumeChange: (v) => {
1585
+ setVolume(v);
1586
+ setIsMuted(v === 0);
1587
+ },
1588
+ isMuted
1589
+ }
1590
+ ),
1501
1591
  /* @__PURE__ */ jsx("div", { className: "mx-0.5 h-4 w-px bg-white/20 @md:mx-1" }),
1502
1592
  captions.length > 0 && /* @__PURE__ */ jsx(
1503
1593
  "button",
1504
1594
  {
1505
1595
  type: "button",
1506
- onClick: () => setSubtitleMode(
1507
- (m) => m === "off" ? captions[0]?.srclang ?? "off" : "off"
1508
- ),
1509
- className: `grid size-8 place-items-center rounded transition hover:text-white/80 @sm:size-10${subtitleMode !== "off" ? "text-white" : "text-white/60"}`,
1596
+ onClick: () => {
1597
+ const next = subtitleMode === "off" ? captions[0]?.srclang ?? "off" : "off";
1598
+ setSubtitleMode(next);
1599
+ setSubtitleStyle((st) => ({ ...st, track: next }));
1600
+ },
1601
+ className: `grid size-8 place-items-center rounded transition hover:text-white/80 @sm:size-10 ${subtitleMode !== "off" ? "text-white" : "text-white/60"}`,
1510
1602
  "aria-label": "Captions",
1511
1603
  children: /* @__PURE__ */ jsx(Captions$1, { className: "size-4 @sm:size-5" })
1512
1604
  }
@@ -1515,11 +1607,8 @@ function Video({
1515
1607
  "button",
1516
1608
  {
1517
1609
  type: "button",
1518
- onClick: () => {
1519
- setSettingsOpen((v) => !v);
1520
- setSettingsTab("root");
1521
- },
1522
- className: `grid size-8 place-items-center rounded transition hover:text-white/80 @sm:size-10${settingsOpen ? "text-white" : "text-white/60"}`,
1610
+ onClick: () => settingsOpen ? closeSettings() : openSettings(),
1611
+ className: `grid size-8 place-items-center rounded transition hover:text-white/80 @sm:size-10 ${settingsOpen ? "text-white" : "text-white/60"}`,
1523
1612
  "aria-label": "Settings",
1524
1613
  children: /* @__PURE__ */ jsx(Settings, { className: "size-4 @sm:size-5" })
1525
1614
  }
@@ -1542,65 +1631,6 @@ function Video({
1542
1631
  ]
1543
1632
  }
1544
1633
  ),
1545
- preview && (() => {
1546
- const srcW = preview.cue.w ?? 160;
1547
- const srcH = preview.cue.h ?? 90;
1548
- const thumbW = Math.max(
1549
- 140,
1550
- Math.round((playerWidth || 640) * 0.13)
1551
- );
1552
- const thumbH = Math.round(thumbW * (srcH / srcW));
1553
- const scale = thumbW / srcW;
1554
- const isSprite = preview.cue.x != null && preview.cue.y != null;
1555
- return /* @__PURE__ */ jsx(
1556
- "div",
1557
- {
1558
- className: "pointer-events-none absolute z-60 -translate-x-1/2 -translate-y-2 overflow-hidden rounded-xl shadow-2xl ring-1 ring-white/15",
1559
- style: {
1560
- bottom: controlsVisible ? "80px" : "20px",
1561
- left: preview.left,
1562
- transition: "bottom 0.2s"
1563
- },
1564
- children: isSprite ? /* @__PURE__ */ jsx(
1565
- "div",
1566
- {
1567
- style: {
1568
- width: thumbW,
1569
- height: thumbH,
1570
- overflow: "hidden"
1571
- },
1572
- children: /* @__PURE__ */ jsx(
1573
- "div",
1574
- {
1575
- style: {
1576
- width: srcW,
1577
- height: srcH,
1578
- backgroundImage: `url(${preview.cue.image})`,
1579
- backgroundPosition: `-${preview.cue.x ?? 0}px -${preview.cue.y ?? 0}px`,
1580
- backgroundSize: "auto",
1581
- backgroundRepeat: "no-repeat",
1582
- transform: `scale(${scale})`,
1583
- transformOrigin: "top left"
1584
- }
1585
- }
1586
- )
1587
- }
1588
- ) : /* @__PURE__ */ jsx(
1589
- "div",
1590
- {
1591
- style: {
1592
- width: thumbW,
1593
- height: thumbH,
1594
- backgroundImage: `url(${preview.cue.image})`,
1595
- backgroundSize: "cover",
1596
- backgroundPosition: "center",
1597
- backgroundRepeat: "no-repeat"
1598
- }
1599
- }
1600
- )
1601
- }
1602
- );
1603
- })(),
1604
1634
  activeCue && /* @__PURE__ */ jsx(
1605
1635
  "div",
1606
1636
  {
@@ -1634,6 +1664,109 @@ function Video({
1634
1664
  );
1635
1665
  }
1636
1666
  var VideoPlayer = Video;
1667
+ function VolumeSlider({
1668
+ volume,
1669
+ isMuted,
1670
+ onMuteToggle,
1671
+ onVolumeChange
1672
+ }) {
1673
+ const [hovered, setHovered] = useState(false);
1674
+ const [dragging, setDragging] = useState(false);
1675
+ const trackRef = useRef(null);
1676
+ const expanded = hovered || dragging;
1677
+ const seek = useCallback((clientX) => {
1678
+ const track = trackRef.current;
1679
+ if (!track) return;
1680
+ const rect = track.getBoundingClientRect();
1681
+ const v = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
1682
+ onVolumeChange(v);
1683
+ }, [onVolumeChange]);
1684
+ const onPointerDown = useCallback((e) => {
1685
+ e.currentTarget.setPointerCapture(e.pointerId);
1686
+ setDragging(true);
1687
+ seek(e.clientX);
1688
+ }, [seek]);
1689
+ const onPointerMove = useCallback((e) => {
1690
+ if (dragging) seek(e.clientX);
1691
+ }, [dragging, seek]);
1692
+ const onPointerUp = useCallback(() => setDragging(false), []);
1693
+ const fillPercent = volume * 100;
1694
+ return /* @__PURE__ */ jsxs(
1695
+ "div",
1696
+ {
1697
+ className: "flex items-center",
1698
+ onMouseEnter: () => setHovered(true),
1699
+ onMouseLeave: () => {
1700
+ if (!dragging) setHovered(false);
1701
+ },
1702
+ children: [
1703
+ /* @__PURE__ */ jsx(
1704
+ "button",
1705
+ {
1706
+ type: "button",
1707
+ onClick: onMuteToggle,
1708
+ className: "grid size-8 place-items-center text-white/70 transition hover:text-white @sm:size-9",
1709
+ "aria-label": isMuted ? "Unmute" : "Mute",
1710
+ children: isMuted || volume === 0 ? /* @__PURE__ */ jsx(VolumeX, { className: "size-4 @sm:size-5" }) : /* @__PURE__ */ jsx(Volume2, { className: "size-4 @sm:size-5" })
1711
+ }
1712
+ ),
1713
+ /* @__PURE__ */ jsx(
1714
+ "div",
1715
+ {
1716
+ style: {
1717
+ width: expanded ? "64px" : "0px",
1718
+ opacity: expanded ? 1 : 0,
1719
+ transition: "width 0.2s ease, opacity 0.2s ease",
1720
+ overflow: "hidden"
1721
+ },
1722
+ children: /* @__PURE__ */ jsxs(
1723
+ "div",
1724
+ {
1725
+ ref: trackRef,
1726
+ onPointerDown,
1727
+ onPointerMove,
1728
+ onPointerUp,
1729
+ className: "relative mx-1 flex h-7 cursor-pointer items-center",
1730
+ style: { width: "52px" },
1731
+ children: [
1732
+ /* @__PURE__ */ jsx(
1733
+ "div",
1734
+ {
1735
+ className: "absolute inset-x-0 rounded-full bg-white/20",
1736
+ style: {
1737
+ height: dragging ? "5px" : hovered ? "4px" : "3px",
1738
+ transition: "height 0.15s ease"
1739
+ },
1740
+ children: /* @__PURE__ */ jsx(
1741
+ "div",
1742
+ {
1743
+ className: "absolute inset-y-0 left-0 rounded-full bg-white",
1744
+ style: { width: `${fillPercent}%` }
1745
+ }
1746
+ )
1747
+ }
1748
+ ),
1749
+ /* @__PURE__ */ jsx(
1750
+ "div",
1751
+ {
1752
+ className: "pointer-events-none absolute top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-white shadow-md",
1753
+ style: {
1754
+ left: `${fillPercent}%`,
1755
+ width: dragging ? "14px" : hovered ? "11px" : "0px",
1756
+ height: dragging ? "14px" : hovered ? "11px" : "0px",
1757
+ transition: "width 0.15s ease, height 0.15s ease"
1758
+ }
1759
+ }
1760
+ )
1761
+ ]
1762
+ }
1763
+ )
1764
+ }
1765
+ )
1766
+ ]
1767
+ }
1768
+ );
1769
+ }
1637
1770
  function parseVideoChildren(children) {
1638
1771
  const parsed = {
1639
1772
  sources: []