@cntrl-site/components 0.1.0-alpha.3 → 0.1.0-alpha.30

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
@@ -565,15 +565,28 @@ const ControlSliderComponent = {
565
565
  },
566
566
  offset: {
567
567
  type: "object",
568
+ title: "Offset",
568
569
  display: {
569
- type: "offset-controls"
570
+ type: "group"
570
571
  },
571
572
  properties: {
572
573
  x: {
573
- type: "number"
574
+ type: "number",
575
+ label: "X",
576
+ scalingEnabled: true,
577
+ display: {
578
+ type: "numeric-input",
579
+ visible: true
580
+ }
574
581
  },
575
582
  y: {
576
- type: "number"
583
+ type: "number",
584
+ label: "Y",
585
+ scalingEnabled: true,
586
+ display: {
587
+ type: "numeric-input",
588
+ visible: true
589
+ }
577
590
  }
578
591
  }
579
592
  },
@@ -626,15 +639,28 @@ const ControlSliderComponent = {
626
639
  },
627
640
  offset: {
628
641
  type: "object",
642
+ title: "Offset",
629
643
  display: {
630
- type: "offset-controls"
644
+ type: "group"
631
645
  },
632
646
  properties: {
633
647
  x: {
634
- type: "number"
648
+ type: "number",
649
+ label: "X",
650
+ scalingEnabled: true,
651
+ display: {
652
+ type: "numeric-input",
653
+ visible: true
654
+ }
635
655
  },
636
656
  y: {
637
- type: "number"
657
+ type: "number",
658
+ label: "Y",
659
+ scalingEnabled: true,
660
+ display: {
661
+ type: "numeric-input",
662
+ visible: true
663
+ }
638
664
  }
639
665
  }
640
666
  },
@@ -690,14 +716,26 @@ const ControlSliderComponent = {
690
716
  offset: {
691
717
  type: "object",
692
718
  display: {
693
- type: "offset-controls"
719
+ type: "group"
694
720
  },
695
721
  properties: {
696
722
  x: {
697
- type: "number"
723
+ type: "number",
724
+ label: "X",
725
+ scalingEnabled: true,
726
+ display: {
727
+ type: "numeric-input",
728
+ visible: true
729
+ }
698
730
  },
699
731
  y: {
700
- type: "number"
732
+ type: "number",
733
+ label: "Y",
734
+ scalingEnabled: true,
735
+ display: {
736
+ type: "numeric-input",
737
+ visible: true
738
+ }
701
739
  }
702
740
  }
703
741
  },
@@ -1443,6 +1481,7 @@ const ControlImageRevealSliderComponent = {
1443
1481
  }
1444
1482
  }
1445
1483
  };
1484
+ const background = "Lightbox-module__background___wf1Ii";
1446
1485
  const backdropStyle = "Lightbox-module__backdropStyle___y7avj";
1447
1486
  const editor = "Lightbox-module__editor___Vh82D";
1448
1487
  const contentStyle = "Lightbox-module__contentStyle___FzFaW";
@@ -1464,15 +1503,20 @@ const thumbsAlignStart = "Lightbox-module__thumbsAlignStart___uiFIV";
1464
1503
  const thumbsAlignCenter = "Lightbox-module__thumbsAlignCenter___sbUPA";
1465
1504
  const thumbsAlignEnd = "Lightbox-module__thumbsAlignEnd___OA9N4";
1466
1505
  const thumbItem = "Lightbox-module__thumbItem___zROyu";
1467
- const thumbImage = "Lightbox-module__thumbImage___xGakV";
1468
1506
  const closeButton = "Lightbox-module__closeButton___r3Dur";
1469
1507
  const fadeIn = "Lightbox-module__fadeIn___sHwRK";
1470
1508
  const slideInLeft = "Lightbox-module__slideInLeft___P-XRo";
1471
1509
  const slideInRight = "Lightbox-module__slideInRight___ZQqFi";
1472
1510
  const slideInTop = "Lightbox-module__slideInTop___XRKCs";
1473
1511
  const slideInBottom = "Lightbox-module__slideInBottom___TYOBS";
1512
+ const fadeOut = "Lightbox-module__fadeOut___h2fpQ";
1513
+ const slideOutLeft = "Lightbox-module__slideOutLeft___J-eMU";
1514
+ const slideOutRight = "Lightbox-module__slideOutRight___iZUQz";
1515
+ const slideOutTop = "Lightbox-module__slideOutTop___3TXF9";
1516
+ const slideOutBottom = "Lightbox-module__slideOutBottom___SB5ws";
1474
1517
  const scaleSlide = "Lightbox-module__scaleSlide___wS7d4";
1475
1518
  const styles = {
1519
+ background,
1476
1520
  backdropStyle,
1477
1521
  editor,
1478
1522
  contentStyle,
@@ -1494,16 +1538,20 @@ const styles = {
1494
1538
  thumbsAlignCenter,
1495
1539
  thumbsAlignEnd,
1496
1540
  thumbItem,
1497
- thumbImage,
1498
1541
  closeButton,
1499
1542
  fadeIn,
1500
1543
  slideInLeft,
1501
1544
  slideInRight,
1502
1545
  slideInTop,
1503
1546
  slideInBottom,
1547
+ fadeOut,
1548
+ slideOutLeft,
1549
+ slideOutRight,
1550
+ slideOutTop,
1551
+ slideOutBottom,
1504
1552
  scaleSlide
1505
1553
  };
1506
- const getPositionStyles = (position, offset) => {
1554
+ const getPositionStyles = (position, offset, isEditor) => {
1507
1555
  const styles2 = {};
1508
1556
  const [vertical, horizontal] = position.split("-");
1509
1557
  if (vertical === "top") {
@@ -1527,16 +1575,41 @@ const getPositionStyles = (position, offset) => {
1527
1575
  styles2.right = "0";
1528
1576
  }
1529
1577
  if (vertical === "middle" && horizontal === "center") {
1530
- styles2.transform = `translate(calc(-50% + ${offset.x}px), calc(-50% + ${offset.y}px))`;
1578
+ styles2.transform = `translate(calc(-50% + ${scalingValue(offset.x, isEditor)}), calc(-50% + ${scalingValue(offset.y, isEditor)}))`;
1531
1579
  } else if (vertical === "middle") {
1532
- styles2.transform = `translate(${offset.x}px, calc(-50% + ${offset.y}px))`;
1580
+ styles2.transform = `translate(${scalingValue(offset.x, isEditor)}, calc(-50% + ${scalingValue(offset.y, isEditor)}))`;
1533
1581
  } else if (horizontal === "center") {
1534
- styles2.transform = `translate(calc(-50% + ${offset.x}px), ${offset.y}px)`;
1582
+ styles2.transform = `translate(calc(-50% + ${scalingValue(offset.x, isEditor)}), ${scalingValue(offset.y, isEditor)})`;
1535
1583
  } else {
1536
- styles2.transform = `translate(${offset.x}px, ${offset.y}px)`;
1584
+ styles2.transform = `translate(${scalingValue(offset.x, isEditor)}, ${scalingValue(offset.y, isEditor)})`;
1537
1585
  }
1538
1586
  return styles2;
1539
1587
  };
1588
+ function getDisplayedImageRect(img2) {
1589
+ const container = img2.getBoundingClientRect();
1590
+ const containerW = container.width;
1591
+ const containerH = container.height;
1592
+ const imgW = img2.naturalWidth;
1593
+ const imgH = img2.naturalHeight;
1594
+ const containerRatio = containerW / containerH;
1595
+ const imgRatio = imgW / imgH;
1596
+ let renderedW, renderedH;
1597
+ if (imgRatio > containerRatio) {
1598
+ renderedW = containerW;
1599
+ renderedH = containerW / imgRatio;
1600
+ } else {
1601
+ renderedH = containerH;
1602
+ renderedW = containerH * imgRatio;
1603
+ }
1604
+ const offsetX = (containerW - renderedW) / 2 + container.left;
1605
+ const offsetY = (containerH - renderedH) / 2 + container.top;
1606
+ return {
1607
+ x: offsetX,
1608
+ y: offsetY,
1609
+ width: renderedW,
1610
+ height: renderedH
1611
+ };
1612
+ }
1540
1613
  function LightboxGallery({ settings, content, styles: styles2, portalId, activeEvent, isEditor }) {
1541
1614
  const [open, setOpen] = React.useState(false);
1542
1615
  const { url } = settings.thumbnailBlock.cover;
@@ -1558,54 +1631,133 @@ function LightboxGallery({ settings, content, styles: styles2, portalId, activeE
1558
1631
  onClick: () => setOpen(true)
1559
1632
  }
1560
1633
  ),
1561
- /* @__PURE__ */ jsxRuntime.jsx(Lightbox, { isOpen: open, onClose: () => setOpen(false), content, settings, portalId, isEditor })
1634
+ /* @__PURE__ */ jsxRuntime.jsx(Lightbox, { isOpen: open, onClose: () => setOpen(false), content, settings, styles: styles2, portalId, isEditor, activeEvent })
1562
1635
  ] });
1563
1636
  }
1564
- const Lightbox = ({ isOpen, onClose, content, settings, closeOnBackdropClick = true, closeOnEsc = true, portalId, isEditor }) => {
1637
+ const Lightbox = ({ isOpen, onClose, content, styles: lightboxStyles, settings, portalId, isEditor }) => {
1638
+ const { widthSettings, fontSettings, letterSpacing, textAlign, wordSpacing, fontSizeLineHeight, textAppearance, color } = lightboxStyles.caption;
1565
1639
  const [currentIndex, setCurrentIndex] = React.useState(0);
1640
+ const [splideKey, setSplideKey] = React.useState(0);
1641
+ const [isClosing, setIsClosing] = React.useState(false);
1566
1642
  const lightboxRef = React.useRef(null);
1567
- const resizeObserverRef = React.useRef(null);
1643
+ const prevSliderTypeRef = React.useRef(null);
1644
+ const imageRef = React.useRef(null);
1645
+ const isClosingRef = React.useRef(false);
1646
+ const contentRef = React.useRef(null);
1647
+ const animationEndHandlerRef = React.useRef(null);
1648
+ const appearAnimationEndHandlerRef = React.useRef(null);
1568
1649
  const { appear, triggers, slider, thumbnail, controls, area, caption: caption2, layout } = settings.lightboxBlock;
1650
+ const appearDurationMs = appear.duration ? parseInt(appear.duration) : 300;
1651
+ React.useEffect(() => {
1652
+ window.addEventListener("ArticleEditor.Layout:change", () => {
1653
+ var _a, _b;
1654
+ (_b = (_a = lightboxRef.current) == null ? void 0 : _a.splide) == null ? void 0 : _b.refresh();
1655
+ });
1656
+ return () => {
1657
+ window.removeEventListener("ArticleEditor.Layout:change", () => {
1658
+ var _a, _b;
1659
+ (_b = (_a = lightboxRef.current) == null ? void 0 : _a.splide) == null ? void 0 : _b.refresh();
1660
+ });
1661
+ };
1662
+ }, []);
1663
+ const handleClose = React.useCallback(() => {
1664
+ const isMobile = window.matchMedia("(max-width: 768px)").matches;
1665
+ const colorAlpha = getColorAlpha(area.color);
1666
+ if (isMobile && !isEditor && colorAlpha > 0.9) {
1667
+ document.body.style.backgroundColor = "";
1668
+ }
1669
+ setIsClosing(true);
1670
+ isClosingRef.current = true;
1671
+ const handleAnimationEnd = (e) => {
1672
+ if (e.target === contentRef.current && e.animationName) {
1673
+ if (contentRef.current && animationEndHandlerRef.current) {
1674
+ contentRef.current.removeEventListener("animationend", animationEndHandlerRef.current);
1675
+ }
1676
+ animationEndHandlerRef.current = null;
1677
+ onClose();
1678
+ setIsClosing(false);
1679
+ }
1680
+ };
1681
+ if (contentRef.current) {
1682
+ animationEndHandlerRef.current = handleAnimationEnd;
1683
+ contentRef.current.addEventListener("animationend", handleAnimationEnd);
1684
+ }
1685
+ }, [onClose, appearDurationMs, area.color, isEditor]);
1569
1686
  const handleBackdropClick = (e) => {
1570
- if (!closeOnBackdropClick) return;
1571
1687
  if (e.target === e.currentTarget) {
1572
- onClose();
1688
+ handleClose();
1573
1689
  }
1574
1690
  };
1575
1691
  const handleImageWrapperClick = (e) => {
1576
- if (!closeOnBackdropClick) return;
1577
- if (e.target === e.currentTarget) {
1578
- onClose();
1579
- }
1580
- };
1581
- const onImageClick = (e) => {
1582
1692
  var _a, _b;
1583
- if (triggers.type === "click" && triggers.switch === "image") {
1584
- e.stopPropagation();
1585
- (_a = lightboxRef.current) == null ? void 0 : _a.go("+1");
1693
+ const rect = imageRef.current ? getDisplayedImageRect(imageRef.current) : null;
1694
+ if (!rect) {
1695
+ if (e.target === e.currentTarget) {
1696
+ handleClose();
1697
+ }
1698
+ return;
1699
+ }
1700
+ let clientX;
1701
+ let clientY;
1702
+ if ("changedTouches" in e && e.changedTouches.length > 0) {
1703
+ clientX = e.changedTouches[0].clientX;
1704
+ clientY = e.changedTouches[0].clientY;
1705
+ } else if ("clientX" in e) {
1706
+ clientX = e.clientX;
1707
+ clientY = e.clientY;
1708
+ } else {
1709
+ return;
1586
1710
  }
1587
- if (triggers.type === "click" && triggers.switch === "50/50") {
1588
- e.stopPropagation();
1589
- const img2 = e.currentTarget;
1590
- const rect = img2.getBoundingClientRect();
1591
- const clickX = e.clientX - rect.left;
1592
- const clickY = e.clientY - rect.top;
1593
- const imgWidth = rect.width;
1594
- const imgHeight = rect.height;
1595
- let dir;
1596
- if (slider.direction === "horiz") {
1597
- dir = clickX < imgWidth / 2 ? "-1" : "+1";
1598
- } else {
1599
- dir = clickY < imgHeight / 2 ? "-1" : "+1";
1711
+ const inside = clientX >= rect.x && clientX <= rect.x + rect.width && clientY >= rect.y && clientY <= rect.y + rect.height;
1712
+ if (inside) {
1713
+ if (triggers.type === "click" && triggers.switch === "image") {
1714
+ if (triggers.repeat === "close" && currentIndex === content.length - 1) {
1715
+ handleClose();
1716
+ } else {
1717
+ (_a = lightboxRef.current) == null ? void 0 : _a.go("+1");
1718
+ }
1719
+ } else if (triggers.type === "click" && triggers.switch === "50/50") {
1720
+ const img2 = imageRef.current;
1721
+ if (img2) {
1722
+ const imgRect = img2.getBoundingClientRect();
1723
+ const clickX = clientX - imgRect.left;
1724
+ const clickY = clientY - imgRect.top;
1725
+ const imgWidth = imgRect.width;
1726
+ const imgHeight = imgRect.height;
1727
+ let dir;
1728
+ if (slider.direction === "horiz") {
1729
+ dir = clickX < imgWidth / 2 ? "-1" : "+1";
1730
+ } else {
1731
+ dir = clickY < imgHeight / 2 ? "-1" : "+1";
1732
+ }
1733
+ (_b = lightboxRef.current) == null ? void 0 : _b.go(dir);
1734
+ }
1600
1735
  }
1601
- (_b = lightboxRef.current) == null ? void 0 : _b.go(dir);
1736
+ } else {
1737
+ handleClose();
1738
+ }
1739
+ };
1740
+ const handleContentClick = (e) => {
1741
+ const target = e.target;
1742
+ const currentTarget = e.currentTarget;
1743
+ if (target === currentTarget) {
1744
+ handleClose();
1745
+ return;
1746
+ }
1747
+ const isImg = target.tagName === "IMG" || target.closest("img");
1748
+ const isButton = target.tagName === "BUTTON" || target.closest("button");
1749
+ const isSplide = target.closest(".splide") || target.closest('[class*="splide"]');
1750
+ const isCaption = target.closest(`.${styles.caption}`);
1751
+ const isThumbnail = target.closest(`.${styles.thumbsContainer}`);
1752
+ if (!isImg && !isButton && !isSplide && !isCaption && !isThumbnail) {
1753
+ handleClose();
1602
1754
  }
1603
1755
  };
1604
1756
  React.useEffect(() => {
1605
- if (!isOpen || !closeOnEsc) return;
1757
+ if (!isOpen) return;
1606
1758
  const onKeyDown = (event) => {
1607
1759
  if (event.key === "Escape") {
1608
- onClose();
1760
+ handleClose();
1609
1761
  return;
1610
1762
  }
1611
1763
  if (event.key === "ArrowRight") {
@@ -1620,58 +1772,62 @@ const Lightbox = ({ isOpen, onClose, content, settings, closeOnBackdropClick = t
1620
1772
  return () => {
1621
1773
  window.removeEventListener("keydown", onKeyDown);
1622
1774
  };
1623
- }, [isOpen, closeOnEsc, onClose, content.length]);
1775
+ }, [isOpen, handleClose, content.length]);
1624
1776
  React.useEffect(() => {
1625
- if (isOpen) setCurrentIndex(0);
1777
+ if (isOpen) {
1778
+ setCurrentIndex(0);
1779
+ isClosingRef.current = false;
1780
+ setIsClosing(false);
1781
+ }
1782
+ return () => {
1783
+ if (contentRef.current && animationEndHandlerRef.current) {
1784
+ contentRef.current.removeEventListener("animationend", animationEndHandlerRef.current);
1785
+ animationEndHandlerRef.current = null;
1786
+ }
1787
+ };
1626
1788
  }, [isOpen]);
1627
1789
  React.useEffect(() => {
1628
- if (!isOpen) return;
1629
- if (resizeObserverRef.current) {
1630
- resizeObserverRef.current.disconnect();
1631
- resizeObserverRef.current = null;
1790
+ if (prevSliderTypeRef.current !== null && prevSliderTypeRef.current !== slider.type) {
1791
+ setSplideKey((prev) => prev + 1);
1632
1792
  }
1633
- const timeoutId = setTimeout(() => {
1634
- const activeSlide = document.querySelector(".splide__slide.is-active");
1635
- if (!activeSlide) return;
1636
- const img2 = activeSlide.querySelector("img");
1637
- const container = activeSlide.querySelector(`.${styles.imgWrapper}`);
1638
- if (!img2 || !container) return;
1639
- const updateImageSize = () => {
1640
- if (!img2.naturalWidth || !img2.naturalHeight) return;
1641
- const imageAspectRatio = img2.naturalWidth / img2.naturalHeight;
1642
- const containerWidth = container.clientWidth;
1643
- const containerHeight = container.clientHeight;
1644
- const containerAspectRatio = containerWidth / containerHeight;
1645
- if (imageAspectRatio > containerAspectRatio) {
1646
- img2.style.width = "100%";
1647
- } else {
1648
- img2.style.height = "100%";
1793
+ prevSliderTypeRef.current = slider.type;
1794
+ }, [slider.type]);
1795
+ React.useEffect(() => {
1796
+ if (!isOpen) return;
1797
+ const originalOverflow = document.body.style.overflow;
1798
+ document.body.style.overflow = "hidden";
1799
+ const isMobile = window.matchMedia("(max-width: 768px)").matches;
1800
+ const colorAlpha = getColorAlpha(area.color);
1801
+ const handleAppearAnimationEnd = (e) => {
1802
+ if (e.target === contentRef.current && !isClosingRef.current && e.animationName) {
1803
+ if (isMobile && !isEditor && colorAlpha > 0.9) {
1804
+ document.body.style.backgroundColor = area.color;
1649
1805
  }
1650
- };
1651
- if (img2.complete) {
1652
- updateImageSize();
1653
- } else {
1654
- img2.onload = updateImageSize;
1806
+ if (contentRef.current && appearAnimationEndHandlerRef.current) {
1807
+ contentRef.current.removeEventListener("animationend", appearAnimationEndHandlerRef.current);
1808
+ }
1809
+ appearAnimationEndHandlerRef.current = null;
1655
1810
  }
1656
- resizeObserverRef.current = new ResizeObserver(() => {
1657
- updateImageSize();
1658
- });
1659
- resizeObserverRef.current.observe(container);
1660
- resizeObserverRef.current.observe(img2);
1661
- }, 0);
1811
+ };
1812
+ if (contentRef.current && isMobile && !isEditor && colorAlpha > 0.9) {
1813
+ appearAnimationEndHandlerRef.current = handleAppearAnimationEnd;
1814
+ contentRef.current.addEventListener("animationend", handleAppearAnimationEnd);
1815
+ }
1816
+ const preventScroll = (e) => e.preventDefault();
1817
+ document.addEventListener("touchmove", preventScroll, { passive: false });
1662
1818
  return () => {
1663
- clearTimeout(timeoutId);
1664
- if (resizeObserverRef.current) {
1665
- resizeObserverRef.current.disconnect();
1666
- resizeObserverRef.current = null;
1819
+ document.body.style.overflow = originalOverflow;
1820
+ document.removeEventListener("touchmove", preventScroll);
1821
+ if (contentRef.current && appearAnimationEndHandlerRef.current) {
1822
+ contentRef.current.removeEventListener("animationend", appearAnimationEndHandlerRef.current);
1823
+ appearAnimationEndHandlerRef.current = null;
1667
1824
  }
1668
1825
  };
1669
- }, [isOpen, currentIndex, content]);
1826
+ }, [isOpen, area.color, isEditor]);
1670
1827
  const handleArrowClick = (dir) => {
1671
1828
  var _a;
1672
1829
  (_a = lightboxRef.current) == null ? void 0 : _a.go(dir);
1673
1830
  };
1674
- const appearDurationMs = appear.duration ? parseInt(appear.duration) : 300;
1675
1831
  const backdropDurationMs = appear.type === "fade in" || appear.type === "mix" ? Math.floor(appearDurationMs * 0.7) : appearDurationMs;
1676
1832
  const appearClass = (() => {
1677
1833
  if (appear.type === "fade in") return styles.fadeIn;
@@ -1709,247 +1865,392 @@ const Lightbox = ({ isOpen, onClose, content, settings, closeOnBackdropClick = t
1709
1865
  }
1710
1866
  return styles.fadeIn;
1711
1867
  })();
1712
- if (!isOpen) return null;
1868
+ const backdropDisappearClass = (() => {
1869
+ if (appear.type === "fade in" || appear.type === "mix") return styles.fadeOut;
1870
+ if (appear.type === "slide in") {
1871
+ switch (appear.direction) {
1872
+ case "left":
1873
+ return styles.slideOutLeft;
1874
+ case "right":
1875
+ return styles.slideOutRight;
1876
+ case "top":
1877
+ return styles.slideOutTop;
1878
+ case "bottom":
1879
+ return styles.slideOutBottom;
1880
+ default:
1881
+ return styles.slideOutRight;
1882
+ }
1883
+ }
1884
+ return styles.fadeOut;
1885
+ })();
1886
+ const disappearClass = (() => {
1887
+ if (appear.type === "fade in") return styles.fadeOut;
1888
+ if (appear.type === "slide in" || appear.type === "mix") {
1889
+ switch (appear.direction) {
1890
+ case "left":
1891
+ return styles.slideOutLeft;
1892
+ case "right":
1893
+ return styles.slideOutRight;
1894
+ case "top":
1895
+ return styles.slideOutTop;
1896
+ case "bottom":
1897
+ return styles.slideOutBottom;
1898
+ default:
1899
+ return styles.slideOutRight;
1900
+ }
1901
+ }
1902
+ return styles.fadeOut;
1903
+ })();
1904
+ React.useEffect(() => {
1905
+ if (!isOpen) return;
1906
+ const handleTouchEnd = (e) => {
1907
+ if (isClosingRef.current) {
1908
+ e.stopPropagation();
1909
+ return;
1910
+ }
1911
+ if (e.touches.length === 0 && e.changedTouches.length > 0) {
1912
+ const rect = imageRef.current ? getDisplayedImageRect(imageRef.current) : null;
1913
+ console.log("rect", rect);
1914
+ if (!rect) return;
1915
+ const touch = e.changedTouches[0];
1916
+ const inside = touch.clientX >= rect.x && touch.clientX <= rect.x + rect.width && touch.clientY >= rect.y && touch.clientY <= rect.y + rect.height;
1917
+ if (!inside) {
1918
+ e.stopPropagation();
1919
+ isClosingRef.current = true;
1920
+ const blockNextClick = (clickEvent) => {
1921
+ clickEvent.stopPropagation();
1922
+ clickEvent.preventDefault();
1923
+ document.removeEventListener("click", blockNextClick, true);
1924
+ };
1925
+ document.addEventListener("click", blockNextClick, true);
1926
+ handleClose();
1927
+ }
1928
+ }
1929
+ };
1930
+ document.addEventListener("touchend", handleTouchEnd, { passive: true });
1931
+ return () => {
1932
+ document.removeEventListener("touchend", handleTouchEnd);
1933
+ };
1934
+ }, [isOpen, handleClose, currentIndex]);
1935
+ if (!isOpen && !isClosing) return null;
1713
1936
  return reactDom.createPortal(
1714
- /* @__PURE__ */ jsxRuntime.jsx(
1715
- "div",
1716
- {
1717
- className: cn(styles.backdropStyle, backdropAppearClass, { [styles.editor]: isEditor }),
1718
- style: { backgroundColor: area.color, backdropFilter: `blur(${area.blur}px)`, animationDuration: `${backdropDurationMs}ms`, animationTimingFunction: "ease", animationFillMode: "both" },
1719
- onClick: handleBackdropClick,
1720
- children: /* @__PURE__ */ jsxRuntime.jsxs(
1721
- "div",
1722
- {
1723
- className: cn(styles.contentStyle, appearClass),
1724
- style: {
1725
- padding: `${layout.padding.top}px ${layout.padding.right}px ${layout.padding.bottom}px ${layout.padding.left}px`,
1726
- animationDuration: `${appearDurationMs}ms`,
1727
- animationTimingFunction: "ease",
1728
- animationFillMode: "both",
1729
- ...appear.type === "mix" && { animationDelay: `${backdropDurationMs}ms` },
1730
- "--splide-speed": triggers.duration || "500ms"
1731
- },
1732
- children: [
1733
- /* @__PURE__ */ jsxRuntime.jsx(
1734
- reactSplide.Splide,
1735
- {
1736
- onMove: (splide) => {
1737
- setCurrentIndex(splide.index);
1738
- },
1739
- ref: lightboxRef,
1740
- className: styles.lightboxSplide,
1741
- options: {
1742
- arrows: false,
1743
- speed: triggers.duration ? parseInt(triggers.duration) : 500,
1744
- direction: slider.direction === "horiz" || slider.type === "fade" || slider.type === "scale" ? "ltr" : "ttb",
1745
- pagination: false,
1746
- drag: triggers.type === "drag",
1747
- perPage: 1,
1748
- width: "100%",
1749
- height: "100%",
1750
- type: slider.type === "fade" || slider.type === "scale" ? "fade" : "loop",
1751
- padding: 0,
1752
- rewind: (slider.type === "scale" || slider.type === "fade") && appear.repeat !== "close"
1753
- },
1754
- style: { "--splide-speed": triggers.duration || "500ms" },
1755
- children: content.map((item, index) => {
1756
- const positionStyles = getPositionStyles(layout.position, layout.offset);
1757
- const imageStyle2 = slider.type === "scale" ? (() => {
1758
- const { transform, ...restStyles } = positionStyles;
1759
- return {
1760
- ...restStyles,
1761
- "--position-transform": transform || "none"
1762
- };
1763
- })() : positionStyles;
1764
- return /* @__PURE__ */ jsxRuntime.jsx(reactSplide.SplideSlide, { children: /* @__PURE__ */ jsxRuntime.jsx(
1765
- "div",
1766
- {
1767
- className: styles.imgWrapper,
1768
- onClick: handleImageWrapperClick,
1769
- style: {
1770
- padding: `${layout.padding.top}px ${layout.padding.right}px ${layout.padding.bottom}px ${layout.padding.left}px`
1771
- },
1772
- children: /* @__PURE__ */ jsxRuntime.jsx(
1773
- "img",
1774
- {
1775
- className: cn(styles.imageStyle, {
1776
- [styles.contain]: item.image.objectFit === "contain",
1777
- [styles.cover]: item.image.objectFit === "cover",
1778
- [styles.scaleSlide]: slider.type === "scale"
1779
- }),
1780
- src: item.image.url,
1781
- alt: item.image.name ?? "",
1782
- onClick: onImageClick,
1783
- style: imageStyle2
1784
- }
1785
- )
1786
- }
1787
- ) }, index);
1788
- })
1789
- }
1790
- ),
1791
- controls.isActive && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1937
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1938
+ /* @__PURE__ */ jsxRuntime.jsx(
1939
+ "div",
1940
+ {
1941
+ className: cn(styles.background, isClosing ? backdropDisappearClass : backdropAppearClass),
1942
+ style: {
1943
+ ...isEditor && { display: "none" },
1944
+ backgroundColor: area.color,
1945
+ backdropFilter: `blur(${area.blur}px)`,
1946
+ animationDuration: `${appearDurationMs}ms`,
1947
+ animationTimingFunction: "ease",
1948
+ animationFillMode: "both"
1949
+ }
1950
+ }
1951
+ ),
1952
+ /* @__PURE__ */ jsxRuntime.jsx(
1953
+ "div",
1954
+ {
1955
+ className: cn(styles.backdropStyle, { [styles.editor]: isEditor, [isClosing ? backdropDisappearClass : backdropAppearClass]: isEditor }),
1956
+ style: { ...isEditor && {
1957
+ backgroundColor: area.color,
1958
+ backdropFilter: `blur(${area.blur}px)`,
1959
+ animationDuration: `${appearDurationMs}ms`,
1960
+ animationTimingFunction: "ease",
1961
+ animationFillMode: "both"
1962
+ } },
1963
+ onClick: handleBackdropClick,
1964
+ onTouchEnd: handleBackdropClick,
1965
+ onTouchStart: handleBackdropClick,
1966
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
1967
+ "div",
1968
+ {
1969
+ ref: contentRef,
1970
+ className: cn(styles.contentStyle, isClosing ? disappearClass : appearClass),
1971
+ onClick: handleContentClick,
1972
+ style: {
1973
+ animationDuration: `${appearDurationMs}ms`,
1974
+ animationTimingFunction: "ease",
1975
+ animationFillMode: "both",
1976
+ ...appear.type === "mix" && !isClosing && { animationDelay: `${backdropDurationMs / 2}ms` },
1977
+ ...appear.type === "mix" && isClosing && { animationDelay: "0ms" }
1978
+ },
1979
+ children: [
1792
1980
  /* @__PURE__ */ jsxRuntime.jsx(
1981
+ reactSplide.Splide,
1982
+ {
1983
+ onMove: (splide) => {
1984
+ setCurrentIndex(splide.index);
1985
+ },
1986
+ ref: lightboxRef,
1987
+ className: styles.lightboxSplide,
1988
+ options: {
1989
+ arrows: false,
1990
+ speed: slider.duration ? parseInt(slider.duration) : 500,
1991
+ direction: slider.direction === "horiz" || slider.type === "fade" || slider.type === "scale" ? "ltr" : "ttb",
1992
+ pagination: false,
1993
+ drag: triggers.type === "drag",
1994
+ perPage: 1,
1995
+ width: "100%",
1996
+ height: "100%",
1997
+ type: slider.type === "fade" || slider.type === "scale" ? "fade" : "loop",
1998
+ padding: 0,
1999
+ rewind: (slider.type === "scale" || slider.type === "fade") && triggers.repeat === "loop"
2000
+ },
2001
+ style: { "--splide-speed": slider.duration || "500ms" },
2002
+ children: content.map((item, index) => {
2003
+ const positionStyles = getPositionStyles(layout.position, layout.offset, isEditor);
2004
+ const imageStyle2 = slider.type === "scale" ? (() => {
2005
+ const { transform, ...restStyles } = positionStyles;
2006
+ return {
2007
+ ...restStyles,
2008
+ "--position-transform": transform || "none"
2009
+ };
2010
+ })() : positionStyles;
2011
+ return /* @__PURE__ */ jsxRuntime.jsx(reactSplide.SplideSlide, { children: /* @__PURE__ */ jsxRuntime.jsx(
2012
+ "div",
2013
+ {
2014
+ className: styles.imgWrapper,
2015
+ onClick: handleImageWrapperClick,
2016
+ style: { padding: scalingValue(layout.padding.top, isEditor) + " " + scalingValue(layout.padding.right, isEditor) + " " + scalingValue(layout.padding.bottom, isEditor) + " " + scalingValue(layout.padding.left, isEditor) },
2017
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2018
+ "img",
2019
+ {
2020
+ ref: index === currentIndex ? imageRef : null,
2021
+ className: cn(styles.imageStyle, {
2022
+ [styles.contain]: item.image.objectFit === "contain",
2023
+ [styles.cover]: item.image.objectFit === "cover",
2024
+ [styles.scaleSlide]: slider.type === "scale"
2025
+ }),
2026
+ src: item.image.url,
2027
+ alt: item.image.name ?? "",
2028
+ style: {
2029
+ ...imageStyle2,
2030
+ ...item.image.objectFit === "contain" ? {
2031
+ pointerEvents: "none"
2032
+ } : {}
2033
+ }
2034
+ }
2035
+ )
2036
+ }
2037
+ ) }, index);
2038
+ })
2039
+ },
2040
+ splideKey
2041
+ ),
2042
+ controls.isActive && controls.arrowsImgUrl && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2043
+ /* @__PURE__ */ jsxRuntime.jsx(
2044
+ "div",
2045
+ {
2046
+ className: cn(styles.arrow, { [styles.arrowVertical]: slider.direction === "vert" }),
2047
+ style: { color: controls.color, ["--arrow-hover-color"]: controls.hover },
2048
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2049
+ "button",
2050
+ {
2051
+ className: styles.arrowInner,
2052
+ style: {
2053
+ transform: `translate(${scalingValue(controls.offset.x, isEditor)}, ${scalingValue(controls.offset.y * (slider.direction === "horiz" ? 1 : -1), isEditor)}) scale(${controls.scale}) rotate(${slider.direction === "horiz" ? "0deg" : "90deg"})`
2054
+ },
2055
+ onClick: (e) => {
2056
+ handleArrowClick("-1");
2057
+ },
2058
+ children: controls.arrowsImgUrl && /* @__PURE__ */ jsxRuntime.jsx(
2059
+ SvgImage,
2060
+ {
2061
+ url: controls.arrowsImgUrl,
2062
+ fill: controls.color,
2063
+ hoverFill: controls.hover,
2064
+ className: cn(styles.arrowImg, styles.mirror)
2065
+ }
2066
+ )
2067
+ }
2068
+ )
2069
+ }
2070
+ ),
2071
+ /* @__PURE__ */ jsxRuntime.jsx(
2072
+ "div",
2073
+ {
2074
+ className: cn(styles.arrow, styles.nextArrow, { [styles.arrowVertical]: slider.direction === "vert" }),
2075
+ style: { color: controls.color, ["--arrow-hover-color"]: controls.hover },
2076
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2077
+ "button",
2078
+ {
2079
+ className: styles.arrowInner,
2080
+ style: {
2081
+ transform: `translate(${scalingValue(controls.offset.x * (slider.direction === "horiz" ? -1 : 1), isEditor)}, ${scalingValue(controls.offset.y, isEditor)}) scale(${controls.scale}) rotate(${slider.direction === "horiz" ? "0deg" : "90deg"})`
2082
+ },
2083
+ onClick: (e) => {
2084
+ handleArrowClick("+1");
2085
+ },
2086
+ "aria-label": "Next",
2087
+ children: controls.arrowsImgUrl && /* @__PURE__ */ jsxRuntime.jsx(
2088
+ SvgImage,
2089
+ {
2090
+ url: controls.arrowsImgUrl,
2091
+ fill: controls.color,
2092
+ hoverFill: controls.hover,
2093
+ className: styles.arrowImg
2094
+ }
2095
+ )
2096
+ }
2097
+ )
2098
+ }
2099
+ )
2100
+ ] }),
2101
+ area.closeIconUrl && (() => {
2102
+ const positionStyles = getPositionStyles(area.closeIconAlign, area.closeIconOffset, isEditor);
2103
+ const scaleTransform = `scale(${area.closeIconScale})`;
2104
+ const combinedTransform = positionStyles.transform ? `${positionStyles.transform} ${scaleTransform}` : scaleTransform;
2105
+ return /* @__PURE__ */ jsxRuntime.jsx(
2106
+ "button",
2107
+ {
2108
+ className: styles.closeButton,
2109
+ style: {
2110
+ ...positionStyles,
2111
+ transform: combinedTransform
2112
+ },
2113
+ onClick: handleClose,
2114
+ children: /* @__PURE__ */ jsxRuntime.jsx(SvgImage, { url: area.closeIconUrl })
2115
+ }
2116
+ );
2117
+ })(),
2118
+ caption2.isActive && /* @__PURE__ */ jsxRuntime.jsx(
1793
2119
  "div",
1794
2120
  {
1795
- className: cn(styles.arrow, { [styles.arrowVertical]: slider.direction === "vert" }),
1796
- style: { color: controls.color, ["--arrow-hover-color"]: controls.hover },
2121
+ className: styles.caption,
2122
+ style: {
2123
+ ...getPositionStyles(caption2.alignment, caption2.offset, isEditor),
2124
+ fontFamily: fontSettings.fontFamily,
2125
+ fontWeight: fontSettings.fontWeight,
2126
+ fontStyle: fontSettings.fontStyle,
2127
+ width: widthSettings.sizing === "auto" ? "max-content" : scalingValue(widthSettings.width, isEditor),
2128
+ letterSpacing: scalingValue(letterSpacing, isEditor),
2129
+ wordSpacing: scalingValue(wordSpacing, isEditor),
2130
+ textAlign,
2131
+ fontSize: scalingValue(fontSizeLineHeight.fontSize, isEditor),
2132
+ lineHeight: scalingValue(fontSizeLineHeight.lineHeight, isEditor),
2133
+ textTransform: textAppearance.textTransform ?? "none",
2134
+ textDecoration: textAppearance.textDecoration ?? "none",
2135
+ fontVariant: textAppearance.fontVariant ?? "normal",
2136
+ color,
2137
+ transitionDuration: slider.duration ? `${Math.round(parseInt(slider.duration) / 2)}ms` : "500ms"
2138
+ },
2139
+ onClick: (e) => e.stopPropagation(),
1797
2140
  children: /* @__PURE__ */ jsxRuntime.jsx(
1798
- "button",
2141
+ "div",
1799
2142
  {
1800
- className: styles.arrowInner,
2143
+ "data-styles": "caption",
2144
+ className: styles.captionTextInner,
1801
2145
  style: {
1802
- transform: `translate(${scalingValue(controls.offset.x)}, ${scalingValue(controls.offset.y * (slider.direction === "horiz" ? 1 : -1))}) scale(${controls.scale}) rotate(${slider.direction === "horiz" ? "0deg" : "90deg"})`
1803
- },
1804
- onClick: (e) => {
1805
- handleArrowClick("-1");
2146
+ "--link-hover-color": caption2.hover,
2147
+ position: "relative"
1806
2148
  },
1807
- children: controls.arrowsImgUrl && /* @__PURE__ */ jsxRuntime.jsx(
1808
- SvgImage,
1809
- {
1810
- url: controls.arrowsImgUrl,
1811
- fill: controls.color,
1812
- hoverFill: controls.hover,
1813
- className: cn(styles.arrowImg, styles.mirror)
1814
- }
1815
- )
2149
+ children: /* @__PURE__ */ jsxRuntime.jsx(RichTextRenderer, { content: content[currentIndex].imageCaption })
1816
2150
  }
1817
2151
  )
1818
2152
  }
1819
2153
  ),
1820
- /* @__PURE__ */ jsxRuntime.jsx(
2154
+ thumbnail.isActive && /* @__PURE__ */ jsxRuntime.jsx(
1821
2155
  "div",
1822
2156
  {
1823
- className: cn(styles.arrow, styles.nextArrow, { [styles.arrowVertical]: slider.direction === "vert" }),
1824
- style: { color: controls.color, ["--arrow-hover-color"]: controls.hover },
1825
- children: /* @__PURE__ */ jsxRuntime.jsx(
1826
- "button",
2157
+ className: cn(
2158
+ styles.thumbsContainer,
1827
2159
  {
1828
- className: styles.arrowInner,
1829
- style: {
1830
- transform: `translate(${scalingValue(controls.offset.x * (slider.direction === "horiz" ? -1 : 1))}, ${scalingValue(controls.offset.y)}) scale(${controls.scale}) rotate(${slider.direction === "horiz" ? "0deg" : "90deg"})`
1831
- },
1832
- onClick: (e) => {
1833
- handleArrowClick("+1");
1834
- },
1835
- "aria-label": "Next",
1836
- children: controls.arrowsImgUrl && /* @__PURE__ */ jsxRuntime.jsx(
1837
- SvgImage,
1838
- {
1839
- url: controls.arrowsImgUrl,
1840
- fill: controls.color,
1841
- hoverFill: controls.hover,
1842
- className: styles.arrowImg
1843
- }
1844
- )
2160
+ [styles.thumbsContainerVertical]: slider.direction === "vert",
2161
+ [styles.thumbsAlignStart]: thumbnail.align === "start",
2162
+ [styles.thumbsAlignCenter]: thumbnail.align === "center",
2163
+ [styles.thumbsAlignEnd]: thumbnail.align === "end"
1845
2164
  }
1846
- )
1847
- }
1848
- )
1849
- ] }),
1850
- area.closeIconUrl && (() => {
1851
- const positionStyles = getPositionStyles(area.closeIconAlign, area.closeIconOffset);
1852
- const scaleTransform = `scale(${area.closeIconScale})`;
1853
- const combinedTransform = positionStyles.transform ? `${positionStyles.transform} ${scaleTransform}` : scaleTransform;
1854
- return /* @__PURE__ */ jsxRuntime.jsx(
1855
- "button",
1856
- {
1857
- className: styles.closeButton,
2165
+ ),
1858
2166
  style: {
1859
- ...positionStyles,
1860
- transform: combinedTransform
2167
+ gap: `${scalingValue(thumbnail.grid.gap, isEditor)}`,
2168
+ ...getPositionStyles(thumbnail.position, thumbnail.offset, isEditor)
1861
2169
  },
1862
- onClick: onClose,
1863
- children: /* @__PURE__ */ jsxRuntime.jsx(SvgImage, { url: area.closeIconUrl })
1864
- }
1865
- );
1866
- })(),
1867
- caption2.isActive && /* @__PURE__ */ jsxRuntime.jsx(
1868
- "div",
1869
- {
1870
- className: styles.caption,
1871
- style: {
1872
- ...getPositionStyles(caption2.alignment, caption2.offset),
1873
- ["--link-hover-color"]: caption2.hover
1874
- },
1875
- children: /* @__PURE__ */ jsxRuntime.jsx(RichTextRenderer, { content: content[currentIndex].imageCaption })
1876
- }
1877
- ),
1878
- thumbnail.isActive && /* @__PURE__ */ jsxRuntime.jsx(
1879
- "div",
1880
- {
1881
- className: cn(
1882
- styles.thumbsContainer,
1883
- {
1884
- [styles.thumbsContainerVertical]: slider.direction === "vert",
1885
- [styles.thumbsAlignStart]: thumbnail.align === "start",
1886
- [styles.thumbsAlignCenter]: thumbnail.align === "center",
1887
- [styles.thumbsAlignEnd]: thumbnail.align === "end"
1888
- }
1889
- ),
1890
- style: {
1891
- gap: `${thumbnail.grid.gap}px`,
1892
- ...slider.direction === "horiz" ? { height: `${thumbnail.grid.height}px` } : {},
1893
- ...slider.direction === "vert" ? { width: `${thumbnail.grid.width}px` } : {},
1894
- ...getPositionStyles(thumbnail.position, thumbnail.offset)
1895
- },
1896
- children: content.map((item, index) => {
1897
- const isActive = index === currentIndex;
1898
- return /* @__PURE__ */ jsxRuntime.jsx(
1899
- "button",
1900
- {
1901
- className: styles.thumbItem,
1902
- style: {
1903
- transform: `scale(${isActive ? thumbnail.activeState.scale : 1})`,
1904
- ...slider.direction === "horiz" ? { height: "100%" } : {},
1905
- ...slider.direction === "vert" ? { width: "100%" } : {},
1906
- opacity: isActive ? thumbnail.activeState.opacity : thumbnail.opacity,
1907
- ["--thumb-hover"]: thumbnail.activeState.opacity
1908
- },
1909
- onClick: (e) => {
1910
- var _a;
1911
- e.stopPropagation();
1912
- setCurrentIndex(index);
1913
- (_a = lightboxRef.current) == null ? void 0 : _a.go(index);
1914
- },
1915
- children: /* @__PURE__ */ jsxRuntime.jsx(
1916
- "img",
1917
- {
1918
- src: item.image.url,
1919
- alt: item.image.name ?? "",
1920
- className: styles.thumbImage,
1921
- style: {
1922
- objectFit: thumbnail.fit === "cover" ? "cover" : "contain",
1923
- ...slider.direction === "horiz" ? { height: "100%" } : {},
1924
- ...slider.direction === "vert" ? { width: "100%" } : {}
2170
+ children: content.map((item, index) => {
2171
+ const isActive = index === currentIndex;
2172
+ return /* @__PURE__ */ jsxRuntime.jsx(
2173
+ "button",
2174
+ {
2175
+ className: styles.thumbItem,
2176
+ style: {
2177
+ ...slider.direction === "horiz" ? { height: isActive ? `${scalingValue(thumbnail.grid.height * (isActive ? thumbnail.activeState.scale : 1), isEditor)}` : `${scalingValue(thumbnail.grid.height, isEditor)}` } : {},
2178
+ ...slider.direction === "vert" ? { width: isActive ? `${scalingValue(thumbnail.grid.width * (isActive ? thumbnail.activeState.scale : 1), isEditor)}` : `${scalingValue(thumbnail.grid.width, isEditor)}` } : {},
2179
+ ...thumbnail.fit === "cover" && slider.direction === "horiz" ? { width: isActive ? `${scalingValue(thumbnail.grid.width * (isActive ? thumbnail.activeState.scale : 1), isEditor)}` : `${scalingValue(thumbnail.grid.width, isEditor)}` } : {},
2180
+ ...thumbnail.fit === "cover" && slider.direction === "vert" ? { height: isActive ? `${scalingValue(thumbnail.grid.height * (isActive ? thumbnail.activeState.scale : 1), isEditor)}` : `${scalingValue(thumbnail.grid.height, isEditor)}` } : {},
2181
+ transition: isActive ? "all 0.2s ease" : "none",
2182
+ opacity: isActive ? thumbnail.activeState.opacity / 100 : thumbnail.opacity / 100,
2183
+ ["--thumb-hover"]: thumbnail.activeState.opacity / 100
2184
+ },
2185
+ onClick: (e) => {
2186
+ var _a;
2187
+ e.stopPropagation();
2188
+ setCurrentIndex(index);
2189
+ (_a = lightboxRef.current) == null ? void 0 : _a.go(index);
2190
+ },
2191
+ onMouseEnter: () => {
2192
+ var _a;
2193
+ if (thumbnail.triggers === "hov") {
2194
+ (_a = lightboxRef.current) == null ? void 0 : _a.go(index);
1925
2195
  }
1926
- }
1927
- )
1928
- },
1929
- `${item.image.url}-${index}`
1930
- );
1931
- })
1932
- }
1933
- )
1934
- ]
1935
- }
1936
- )
1937
- }
1938
- ),
2196
+ },
2197
+ children: /* @__PURE__ */ jsxRuntime.jsx(
2198
+ "img",
2199
+ {
2200
+ src: item.image.url,
2201
+ alt: item.image.name ?? "",
2202
+ style: {
2203
+ objectFit: thumbnail.fit === "cover" ? "cover" : "contain",
2204
+ ...thumbnail.fit === "fit" ? { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } : {},
2205
+ ...thumbnail.fit === "cover" && slider.direction === "horiz" ? { width: "100%", height: "100%" } : {}
2206
+ }
2207
+ }
2208
+ )
2209
+ },
2210
+ `${item.image.url}-${index}`
2211
+ );
2212
+ })
2213
+ }
2214
+ )
2215
+ ]
2216
+ }
2217
+ )
2218
+ }
2219
+ )
2220
+ ] }),
1939
2221
  document.getElementById(portalId)
1940
2222
  );
1941
2223
  };
2224
+ const getColorAlpha = (color) => {
2225
+ const rgbaMatch = color.match(/rgba?\(([^)]+)\)/);
2226
+ if (rgbaMatch) {
2227
+ const values = rgbaMatch[1].split(",").map((v) => parseFloat(v.trim()));
2228
+ if (values.length === 4) {
2229
+ return values[3];
2230
+ }
2231
+ return 1;
2232
+ }
2233
+ const hexMatch = color.match(/^#([0-9a-fA-F]{8})$/);
2234
+ if (hexMatch) {
2235
+ const alphaHex = hexMatch[1].substring(6, 8);
2236
+ return parseInt(alphaHex, 16) / 255;
2237
+ }
2238
+ if (color.match(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/)) {
2239
+ return 1;
2240
+ }
2241
+ return 1;
2242
+ };
1942
2243
  const LightboxComponent = {
1943
2244
  element: LightboxGallery,
1944
2245
  id: "lightbox",
1945
2246
  name: "Lightbox",
1946
2247
  preview: {
1947
2248
  type: "video",
1948
- url: "https://cdn.cntrl.site/projects/01GJ2SPDSH73MC92WW7ZA2CWBY/articles-assets/01KA24CHYZXJBZ0Q714B05A7VD.mp4"
2249
+ url: "https://cdn.cntrl.site/component-assets/lightbox.mp4"
1949
2250
  },
1950
2251
  defaultSize: {
1951
- width: 400,
1952
- height: 400
2252
+ width: 440,
2253
+ height: 550
1953
2254
  },
1954
2255
  schema: {
1955
2256
  type: "object",
@@ -1974,7 +2275,7 @@ const LightboxComponent = {
1974
2275
  url: {
1975
2276
  type: "string",
1976
2277
  display: {
1977
- type: "settings-image-input"
2278
+ type: "cover-image-input"
1978
2279
  }
1979
2280
  }
1980
2281
  }
@@ -2016,14 +2317,6 @@ const LightboxComponent = {
2016
2317
  type: "direction-control"
2017
2318
  },
2018
2319
  enum: ["top", "left", "right", "bottom"]
2019
- },
2020
- repeat: {
2021
- type: "string",
2022
- title: "Repeat",
2023
- display: {
2024
- type: "ratio-group"
2025
- },
2026
- enum: ["close", "loop"]
2027
2320
  }
2028
2321
  }
2029
2322
  },
@@ -2047,13 +2340,14 @@ const LightboxComponent = {
2047
2340
  },
2048
2341
  enum: ["image", "50/50"]
2049
2342
  },
2050
- duration: {
2343
+ repeat: {
2051
2344
  type: "string",
2052
- label: "T",
2345
+ title: "Repeat",
2053
2346
  display: {
2054
- type: "step-selector"
2347
+ visible: false,
2348
+ type: "ratio-group"
2055
2349
  },
2056
- enum: ["100ms", "250ms", "500ms", "1000ms", "1500ms", "2000ms"]
2350
+ enum: ["close", "loop"]
2057
2351
  }
2058
2352
  }
2059
2353
  },
@@ -2076,6 +2370,14 @@ const LightboxComponent = {
2076
2370
  type: "ratio-group"
2077
2371
  },
2078
2372
  enum: ["horiz", "vert"]
2373
+ },
2374
+ duration: {
2375
+ type: "string",
2376
+ label: "T",
2377
+ display: {
2378
+ type: "step-selector"
2379
+ },
2380
+ enum: ["100ms", "250ms", "500ms", "1000ms", "1500ms", "2000ms"]
2079
2381
  }
2080
2382
  }
2081
2383
  },
@@ -2133,13 +2435,16 @@ const LightboxComponent = {
2133
2435
  height: {
2134
2436
  type: "number",
2135
2437
  label: "H",
2438
+ scalingEnabled: true,
2136
2439
  display: {
2137
- type: "numeric-input"
2440
+ type: "numeric-input",
2441
+ visible: true
2138
2442
  }
2139
2443
  },
2140
2444
  width: {
2141
2445
  type: "number",
2142
2446
  label: "W",
2447
+ scalingEnabled: true,
2143
2448
  display: {
2144
2449
  type: "numeric-input",
2145
2450
  visible: false
@@ -2148,6 +2453,7 @@ const LightboxComponent = {
2148
2453
  gap: {
2149
2454
  type: "number",
2150
2455
  label: "Gap",
2456
+ scalingEnabled: true,
2151
2457
  display: {
2152
2458
  type: "numeric-input"
2153
2459
  }
@@ -2156,15 +2462,28 @@ const LightboxComponent = {
2156
2462
  },
2157
2463
  offset: {
2158
2464
  type: "object",
2465
+ title: "Offset",
2159
2466
  display: {
2160
- type: "offset-controls"
2467
+ type: "group"
2161
2468
  },
2162
2469
  properties: {
2163
2470
  x: {
2164
- type: "number"
2471
+ type: "number",
2472
+ label: "X",
2473
+ scalingEnabled: true,
2474
+ display: {
2475
+ type: "numeric-input",
2476
+ visible: true
2477
+ }
2165
2478
  },
2166
2479
  y: {
2167
- type: "number"
2480
+ type: "number",
2481
+ label: "Y",
2482
+ scalingEnabled: true,
2483
+ display: {
2484
+ type: "numeric-input",
2485
+ visible: true
2486
+ }
2168
2487
  }
2169
2488
  }
2170
2489
  },
@@ -2189,7 +2508,7 @@ const LightboxComponent = {
2189
2508
  scale: {
2190
2509
  type: "number",
2191
2510
  title: "Scale",
2192
- min: 0.5,
2511
+ min: 1,
2193
2512
  max: 5,
2194
2513
  step: 0.1,
2195
2514
  display: {
@@ -2226,15 +2545,28 @@ const LightboxComponent = {
2226
2545
  },
2227
2546
  offset: {
2228
2547
  type: "object",
2548
+ title: "Offset",
2229
2549
  display: {
2230
- type: "offset-controls"
2550
+ type: "group"
2231
2551
  },
2232
2552
  properties: {
2233
2553
  x: {
2234
- type: "number"
2554
+ type: "number",
2555
+ label: "X",
2556
+ scalingEnabled: true,
2557
+ display: {
2558
+ type: "numeric-input",
2559
+ visible: true
2560
+ }
2235
2561
  },
2236
2562
  y: {
2237
- type: "number"
2563
+ type: "number",
2564
+ label: "Y",
2565
+ scalingEnabled: true,
2566
+ display: {
2567
+ type: "numeric-input",
2568
+ visible: true
2569
+ }
2238
2570
  }
2239
2571
  }
2240
2572
  },
@@ -2246,15 +2578,23 @@ const LightboxComponent = {
2246
2578
  },
2247
2579
  properties: {
2248
2580
  top: {
2581
+ min: 0,
2582
+ step: 1,
2249
2583
  type: "number"
2250
2584
  },
2251
2585
  left: {
2586
+ min: 0,
2587
+ step: 1,
2252
2588
  type: "number"
2253
2589
  },
2254
2590
  right: {
2591
+ min: 0,
2592
+ step: 1,
2255
2593
  type: "number"
2256
2594
  },
2257
2595
  bottom: {
2596
+ min: 0,
2597
+ step: 1,
2258
2598
  type: "number"
2259
2599
  }
2260
2600
  }
@@ -2280,16 +2620,29 @@ const LightboxComponent = {
2280
2620
  }
2281
2621
  },
2282
2622
  offset: {
2623
+ title: "Offset",
2283
2624
  type: "object",
2284
2625
  display: {
2285
- type: "offset-controls"
2626
+ type: "group"
2286
2627
  },
2287
2628
  properties: {
2288
2629
  x: {
2289
- type: "number"
2630
+ type: "number",
2631
+ label: "X",
2632
+ scalingEnabled: true,
2633
+ display: {
2634
+ type: "numeric-input",
2635
+ visible: true
2636
+ }
2290
2637
  },
2291
2638
  y: {
2292
- type: "number"
2639
+ type: "number",
2640
+ label: "Y",
2641
+ scalingEnabled: true,
2642
+ display: {
2643
+ type: "numeric-input",
2644
+ visible: true
2645
+ }
2293
2646
  }
2294
2647
  }
2295
2648
  },
@@ -2368,15 +2721,28 @@ const LightboxComponent = {
2368
2721
  },
2369
2722
  closeIconOffset: {
2370
2723
  type: "object",
2724
+ title: "Offset",
2371
2725
  display: {
2372
- type: "offset-controls"
2726
+ type: "group"
2373
2727
  },
2374
2728
  properties: {
2375
2729
  x: {
2376
- type: "number"
2730
+ type: "number",
2731
+ label: "X",
2732
+ scalingEnabled: true,
2733
+ display: {
2734
+ type: "numeric-input",
2735
+ visible: true
2736
+ }
2377
2737
  },
2378
2738
  y: {
2379
- type: "number"
2739
+ type: "number",
2740
+ label: "Y",
2741
+ scalingEnabled: true,
2742
+ display: {
2743
+ type: "numeric-input",
2744
+ visible: true
2745
+ }
2380
2746
  }
2381
2747
  }
2382
2748
  }
@@ -2402,16 +2768,29 @@ const LightboxComponent = {
2402
2768
  enum: ["top-left", "top-center", "top-right", "middle-left", "middle-center", "middle-right", "bottom-left", "bottom-center", "bottom-right"]
2403
2769
  },
2404
2770
  offset: {
2771
+ title: "Offset",
2405
2772
  type: "object",
2406
2773
  display: {
2407
- type: "offset-controls"
2774
+ type: "group"
2408
2775
  },
2409
2776
  properties: {
2410
2777
  x: {
2411
- type: "number"
2778
+ type: "number",
2779
+ label: "X",
2780
+ scalingEnabled: true,
2781
+ display: {
2782
+ type: "numeric-input",
2783
+ visible: true
2784
+ }
2412
2785
  },
2413
2786
  y: {
2414
- type: "number"
2787
+ type: "number",
2788
+ label: "Y",
2789
+ scalingEnabled: true,
2790
+ display: {
2791
+ type: "numeric-input",
2792
+ visible: true
2793
+ }
2415
2794
  }
2416
2795
  }
2417
2796
  },
@@ -2431,38 +2810,38 @@ const LightboxComponent = {
2431
2810
  default: {
2432
2811
  thumbnailBlock: {
2433
2812
  cover: {
2434
- url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERMHNP08T27H1649S67NZV.png"
2813
+ url: "https://cdn.cntrl.site/component-assets/Cover.jpg"
2435
2814
  }
2436
2815
  },
2437
2816
  lightboxBlock: {
2438
2817
  appear: {
2439
- type: "slide in",
2818
+ type: "fade in",
2440
2819
  duration: "1000ms",
2441
- direction: "right",
2442
- repeat: "close"
2820
+ direction: "right"
2443
2821
  },
2444
2822
  triggers: {
2445
2823
  type: "click",
2446
- switch: "image",
2447
- duration: "2000ms"
2824
+ switch: "50/50",
2825
+ repeat: "loop"
2448
2826
  },
2449
2827
  slider: {
2450
- type: "fade",
2451
- direction: "horiz"
2828
+ type: "slide",
2829
+ direction: "horiz",
2830
+ duration: "1000ms"
2452
2831
  },
2453
2832
  thumbnail: {
2454
2833
  isActive: true,
2455
2834
  position: "bottom-center",
2456
- fit: "cover",
2835
+ fit: "fit",
2457
2836
  align: "center",
2458
2837
  triggers: "clk",
2459
2838
  grid: {
2460
- height: 60,
2461
- width: 60,
2462
- gap: 8
2839
+ height: 0.03,
2840
+ width: 0.03,
2841
+ gap: 8e-3
2463
2842
  },
2464
2843
  offset: { x: 0, y: 0 },
2465
- opacity: 100,
2844
+ opacity: 80,
2466
2845
  activeState: {
2467
2846
  scale: 1,
2468
2847
  opacity: 100
@@ -2471,7 +2850,7 @@ const LightboxComponent = {
2471
2850
  layout: {
2472
2851
  position: "middle-center",
2473
2852
  offset: { x: 0, y: 0 },
2474
- padding: { top: 0, right: 0, bottom: 0, left: 0 }
2853
+ padding: { top: 0.04, right: 0, bottom: 0.04, left: 0 }
2475
2854
  },
2476
2855
  controls: {
2477
2856
  isActive: true,
@@ -2482,7 +2861,7 @@ const LightboxComponent = {
2482
2861
  hover: "#cccccc"
2483
2862
  },
2484
2863
  area: {
2485
- color: "rgba(0,0,0,0.9)",
2864
+ color: "rgba(64,67,71,0.9)",
2486
2865
  blur: 0,
2487
2866
  closeIconUrl: null,
2488
2867
  closeIconAlign: "top-right",
@@ -2514,7 +2893,7 @@ const LightboxComponent = {
2514
2893
  value: "vert"
2515
2894
  },
2516
2895
  then: {
2517
- name: "properties.lightboxBlock.properties.thumbnail.properties.position.display.direction",
2896
+ name: "properties.lightboxBlock.properties.thumbnail.properties.align.display.direction",
2518
2897
  value: "vertical"
2519
2898
  }
2520
2899
  },
@@ -2579,44 +2958,14 @@ const LightboxComponent = {
2579
2958
  }
2580
2959
  },
2581
2960
  {
2582
- if: {
2583
- name: "lightboxBlock.triggers.type",
2584
- value: "click"
2585
- },
2586
- then: {
2587
- name: "properties.lightboxBlock.properties.triggers.properties.duration.display.visible",
2588
- value: true
2589
- }
2590
- },
2591
- {
2592
- if: {
2593
- name: "lightboxBlock.triggers.type",
2594
- value: "click"
2595
- },
2961
+ if: [
2962
+ { name: "lightboxBlock.triggers.type", value: "click" },
2963
+ { name: "lightboxBlock.triggers.switch", value: "image" }
2964
+ ],
2596
2965
  then: {
2597
- name: "properties.lightboxBlock.properties.triggers.properties.switch.display.visible",
2966
+ name: "properties.lightboxBlock.properties.triggers.properties.repeat.display.visible",
2598
2967
  value: true
2599
2968
  }
2600
- },
2601
- {
2602
- if: {
2603
- name: "lightboxBlock.triggers.type",
2604
- value: "drag"
2605
- },
2606
- then: {
2607
- name: "properties.lightboxBlock.properties.triggers.properties.duration.display.visible",
2608
- value: false
2609
- }
2610
- },
2611
- {
2612
- if: {
2613
- name: "lightboxBlock.triggers.type",
2614
- value: "drag"
2615
- },
2616
- then: {
2617
- name: "properties.lightboxBlock.properties.triggers.properties.switch.display.visible",
2618
- value: false
2619
- }
2620
2969
  }
2621
2970
  ]
2622
2971
  },
@@ -2668,7 +3017,7 @@ const LightboxComponent = {
2668
3017
  {
2669
3018
  image: {
2670
3019
  objectFit: "contain",
2671
- url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERMHNP08T27H1649S67NZV.png",
3020
+ url: "https://cdn.cntrl.site/component-assets/2.jpg",
2672
3021
  name: "Slider-1.png"
2673
3022
  },
2674
3023
  imageCaption: [
@@ -2681,7 +3030,7 @@ const LightboxComponent = {
2681
3030
  {
2682
3031
  image: {
2683
3032
  objectFit: "contain",
2684
- url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERMTZA3RYMXKF0M095D6JD.png",
3033
+ url: "https://cdn.cntrl.site/component-assets/3.jpg",
2685
3034
  name: "Slider-2.png"
2686
3035
  },
2687
3036
  imageCaption: [
@@ -2694,7 +3043,7 @@ const LightboxComponent = {
2694
3043
  {
2695
3044
  image: {
2696
3045
  objectFit: "contain",
2697
- url: "https://cdn.cntrl.site/projects/01JJKT02AWY2FGN2QJ7A173RNZ/articles-assets/01K7ERMVSCMPVJBG2WF5KJZYHZ.png",
3046
+ url: "https://cdn.cntrl.site/component-assets/4.jpg",
2698
3047
  name: "Slider-3.png"
2699
3048
  },
2700
3049
  imageCaption: [