analytica-frontend-lib 1.1.53 → 1.1.54

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.
@@ -644,8 +644,54 @@ IconButton.displayName = "IconButton";
644
644
  var IconButton_default = IconButton;
645
645
 
646
646
  // src/components/Modal/Modal.tsx
647
- import { useEffect as useEffect2 } from "react";
647
+ import { useEffect as useEffect2, useId } from "react";
648
648
  import { X } from "phosphor-react";
649
+
650
+ // src/components/Modal/utils/videoUtils.ts
651
+ var isYouTubeUrl = (url) => {
652
+ const youtubeRegex = /^(https?:\/\/)?((www|m|music)\.)?(youtube\.com|youtu\.be|youtube-nocookie\.com)\/.+/i;
653
+ return youtubeRegex.test(url);
654
+ };
655
+ var isValidYouTubeHost = (host) => {
656
+ if (host === "youtu.be") return "youtu.be";
657
+ const isValidYouTubeCom = host === "youtube.com" || host.endsWith(".youtube.com") && /^(www|m|music)\.youtube\.com$/.test(host);
658
+ if (isValidYouTubeCom) return "youtube";
659
+ const isValidNoCookie = host === "youtube-nocookie.com" || host.endsWith(".youtube-nocookie.com") && /^(www|m|music)\.youtube-nocookie\.com$/.test(host);
660
+ if (isValidNoCookie) return "nocookie";
661
+ return null;
662
+ };
663
+ var extractYoutuBeId = (pathname) => {
664
+ const firstSeg = pathname.split("/").filter(Boolean)[0];
665
+ return firstSeg || null;
666
+ };
667
+ var extractYouTubeId = (pathname, searchParams) => {
668
+ const parts = pathname.split("/").filter(Boolean);
669
+ const [first, second] = parts;
670
+ if (first === "embed" && second) return second;
671
+ if (first === "shorts" && second) return second;
672
+ if (first === "live" && second) return second;
673
+ const v = searchParams.get("v");
674
+ if (v) return v;
675
+ return null;
676
+ };
677
+ var getYouTubeVideoId = (url) => {
678
+ try {
679
+ const u = new URL(url);
680
+ const hostType = isValidYouTubeHost(u.hostname.toLowerCase());
681
+ if (!hostType) return null;
682
+ if (hostType === "youtu.be") {
683
+ return extractYoutuBeId(u.pathname);
684
+ }
685
+ return extractYouTubeId(u.pathname, u.searchParams);
686
+ } catch {
687
+ return null;
688
+ }
689
+ };
690
+ var getYouTubeEmbedUrl = (videoId) => {
691
+ return `https://www.youtube-nocookie.com/embed/${videoId}?autoplay=0&rel=0&modestbranding=1`;
692
+ };
693
+
694
+ // src/components/Modal/Modal.tsx
649
695
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
650
696
  var SIZE_CLASSES2 = {
651
697
  xs: "max-w-[360px]",
@@ -661,11 +707,17 @@ var Modal = ({
661
707
  children,
662
708
  size = "md",
663
709
  className = "",
664
- closeOnBackdropClick = true,
665
710
  closeOnEscape = true,
666
711
  footer,
667
- hideCloseButton = false
712
+ hideCloseButton = false,
713
+ variant = "default",
714
+ description,
715
+ image,
716
+ imageAlt,
717
+ actionLink,
718
+ actionLabel
668
719
  }) => {
720
+ const titleId = useId();
669
721
  useEffect2(() => {
670
722
  if (!isOpen || !closeOnEscape) return;
671
723
  const handleEscape = (event) => {
@@ -687,16 +739,6 @@ var Modal = ({
687
739
  document.body.style.overflow = originalOverflow;
688
740
  };
689
741
  }, [isOpen]);
690
- const handleBackdropClick = (event) => {
691
- if (closeOnBackdropClick && event.target === event.currentTarget) {
692
- onClose();
693
- }
694
- };
695
- const handleBackdropKeyDown = (event) => {
696
- if (closeOnBackdropClick && (event.key === "Enter" || event.key === " ")) {
697
- onClose();
698
- }
699
- };
700
742
  if (!isOpen) return null;
701
743
  const sizeClasses = SIZE_CLASSES2[size];
702
744
  const baseClasses = "bg-secondary-50 rounded-3xl shadow-hard-shadow-2 border border-border-100 w-full mx-4";
@@ -707,18 +749,105 @@ var Modal = ({
707
749
  dialogResetClasses,
708
750
  className
709
751
  );
710
- return /* @__PURE__ */ jsx5(
711
- "div",
752
+ const normalizeUrl = (href) => /^https?:\/\//i.test(href) ? href : `https://${href}`;
753
+ const handleActionClick = () => {
754
+ if (actionLink) {
755
+ window.open(normalizeUrl(actionLink), "_blank", "noopener,noreferrer");
756
+ }
757
+ };
758
+ if (variant === "activity") {
759
+ return /* @__PURE__ */ jsx5("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-xs border-none p-0 m-0 w-full cursor-default", children: /* @__PURE__ */ jsxs4(
760
+ "dialog",
761
+ {
762
+ className: modalClasses,
763
+ "aria-labelledby": titleId,
764
+ "aria-modal": "true",
765
+ open: true,
766
+ children: [
767
+ /* @__PURE__ */ jsx5("div", { className: "flex justify-end p-6 pb-0", children: !hideCloseButton && /* @__PURE__ */ jsx5(
768
+ "button",
769
+ {
770
+ onClick: onClose,
771
+ className: "p-1 text-text-500 hover:text-text-700 hover:bg-background-50 rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-indicator-info focus:ring-offset-2",
772
+ "aria-label": "Fechar modal",
773
+ children: /* @__PURE__ */ jsx5(X, { size: 18 })
774
+ }
775
+ ) }),
776
+ /* @__PURE__ */ jsxs4("div", { className: "flex flex-col items-center px-6 pb-6 gap-5", children: [
777
+ image && /* @__PURE__ */ jsx5("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx5(
778
+ "img",
779
+ {
780
+ src: image,
781
+ alt: imageAlt ?? "",
782
+ className: "w-[122px] h-[122px] object-contain"
783
+ }
784
+ ) }),
785
+ /* @__PURE__ */ jsx5(
786
+ "h2",
787
+ {
788
+ id: titleId,
789
+ className: "text-lg font-semibold text-text-950 text-center",
790
+ children: title
791
+ }
792
+ ),
793
+ description && /* @__PURE__ */ jsx5("p", { className: "text-sm font-normal text-text-400 text-center max-w-md leading-[21px]", children: description }),
794
+ actionLink && /* @__PURE__ */ jsxs4("div", { className: "w-full", children: [
795
+ (() => {
796
+ const normalized = normalizeUrl(actionLink);
797
+ const isYT = isYouTubeUrl(normalized);
798
+ if (!isYT) return null;
799
+ const id = getYouTubeVideoId(normalized);
800
+ if (!id) {
801
+ return /* @__PURE__ */ jsx5(
802
+ Button_default,
803
+ {
804
+ variant: "solid",
805
+ action: "primary",
806
+ size: "large",
807
+ className: "w-full",
808
+ onClick: handleActionClick,
809
+ children: actionLabel || "Iniciar Atividade"
810
+ }
811
+ );
812
+ }
813
+ return /* @__PURE__ */ jsx5(
814
+ "iframe",
815
+ {
816
+ src: getYouTubeEmbedUrl(id),
817
+ className: "w-full aspect-video rounded-lg",
818
+ allowFullScreen: true,
819
+ allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
820
+ title: "V\xEDdeo YouTube"
821
+ }
822
+ );
823
+ })(),
824
+ !isYouTubeUrl(normalizeUrl(actionLink)) && /* @__PURE__ */ jsx5(
825
+ Button_default,
826
+ {
827
+ variant: "solid",
828
+ action: "primary",
829
+ size: "large",
830
+ className: "w-full",
831
+ onClick: handleActionClick,
832
+ children: actionLabel || "Iniciar Atividade"
833
+ }
834
+ )
835
+ ] })
836
+ ] })
837
+ ]
838
+ }
839
+ ) });
840
+ }
841
+ return /* @__PURE__ */ jsx5("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-xs border-none p-0 m-0 w-full cursor-default", children: /* @__PURE__ */ jsxs4(
842
+ "dialog",
712
843
  {
713
- className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-xs",
714
- onClick: handleBackdropClick,
715
- onKeyDown: handleBackdropKeyDown,
716
- role: "button",
717
- tabIndex: closeOnBackdropClick ? 0 : -1,
718
- "aria-label": "Fechar modal clicando no fundo",
719
- children: /* @__PURE__ */ jsxs4("dialog", { className: modalClasses, "aria-labelledby": "modal-title", open: true, children: [
844
+ className: modalClasses,
845
+ "aria-labelledby": titleId,
846
+ "aria-modal": "true",
847
+ open: true,
848
+ children: [
720
849
  /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between px-6 py-6", children: [
721
- /* @__PURE__ */ jsx5("h2", { id: "modal-title", className: "text-lg font-semibold text-text-950", children: title }),
850
+ /* @__PURE__ */ jsx5("h2", { id: titleId, className: "text-lg font-semibold text-text-950", children: title }),
722
851
  !hideCloseButton && /* @__PURE__ */ jsx5(
723
852
  "button",
724
853
  {
@@ -729,11 +858,11 @@ var Modal = ({
729
858
  }
730
859
  )
731
860
  ] }),
732
- /* @__PURE__ */ jsx5("div", { className: "px-6 pb-6", children: /* @__PURE__ */ jsx5("div", { className: "text-text-500 font-normal text-sm leading-6", children }) }),
861
+ children && /* @__PURE__ */ jsx5("div", { className: "px-6 pb-6", children: /* @__PURE__ */ jsx5("div", { className: "text-text-500 font-normal text-sm leading-6", children }) }),
733
862
  footer && /* @__PURE__ */ jsx5("div", { className: "flex justify-end gap-3 px-6 pb-6", children: footer })
734
- ] })
863
+ ]
735
864
  }
736
- );
865
+ ) });
737
866
  };
738
867
  var Modal_default = Modal;
739
868
 
@@ -1222,7 +1351,6 @@ var NotificationCenter = ({
1222
1351
  title: "Notifica\xE7\xF5es",
1223
1352
  size: "md",
1224
1353
  hideCloseButton: false,
1225
- closeOnBackdropClick: true,
1226
1354
  closeOnEscape: true,
1227
1355
  children: /* @__PURE__ */ jsxs6("div", { className: "flex flex-col h-full max-h-[80vh]", children: [
1228
1356
  /* @__PURE__ */ jsxs6("div", { className: "px-0 pb-3 border-b border-border-200", children: [