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.
package/dist/index.mjs CHANGED
@@ -3851,8 +3851,54 @@ var Calendar = ({
3851
3851
  var Calendar_default = Calendar;
3852
3852
 
3853
3853
  // src/components/Modal/Modal.tsx
3854
- import { useEffect as useEffect6 } from "react";
3854
+ import { useEffect as useEffect6, useId as useId7 } from "react";
3855
3855
  import { X as X3 } from "phosphor-react";
3856
+
3857
+ // src/components/Modal/utils/videoUtils.ts
3858
+ var isYouTubeUrl = (url) => {
3859
+ const youtubeRegex = /^(https?:\/\/)?((www|m|music)\.)?(youtube\.com|youtu\.be|youtube-nocookie\.com)\/.+/i;
3860
+ return youtubeRegex.test(url);
3861
+ };
3862
+ var isValidYouTubeHost = (host) => {
3863
+ if (host === "youtu.be") return "youtu.be";
3864
+ const isValidYouTubeCom = host === "youtube.com" || host.endsWith(".youtube.com") && /^(www|m|music)\.youtube\.com$/.test(host);
3865
+ if (isValidYouTubeCom) return "youtube";
3866
+ const isValidNoCookie = host === "youtube-nocookie.com" || host.endsWith(".youtube-nocookie.com") && /^(www|m|music)\.youtube-nocookie\.com$/.test(host);
3867
+ if (isValidNoCookie) return "nocookie";
3868
+ return null;
3869
+ };
3870
+ var extractYoutuBeId = (pathname) => {
3871
+ const firstSeg = pathname.split("/").filter(Boolean)[0];
3872
+ return firstSeg || null;
3873
+ };
3874
+ var extractYouTubeId = (pathname, searchParams) => {
3875
+ const parts = pathname.split("/").filter(Boolean);
3876
+ const [first, second] = parts;
3877
+ if (first === "embed" && second) return second;
3878
+ if (first === "shorts" && second) return second;
3879
+ if (first === "live" && second) return second;
3880
+ const v = searchParams.get("v");
3881
+ if (v) return v;
3882
+ return null;
3883
+ };
3884
+ var getYouTubeVideoId = (url) => {
3885
+ try {
3886
+ const u = new URL(url);
3887
+ const hostType = isValidYouTubeHost(u.hostname.toLowerCase());
3888
+ if (!hostType) return null;
3889
+ if (hostType === "youtu.be") {
3890
+ return extractYoutuBeId(u.pathname);
3891
+ }
3892
+ return extractYouTubeId(u.pathname, u.searchParams);
3893
+ } catch {
3894
+ return null;
3895
+ }
3896
+ };
3897
+ var getYouTubeEmbedUrl = (videoId) => {
3898
+ return `https://www.youtube-nocookie.com/embed/${videoId}?autoplay=0&rel=0&modestbranding=1`;
3899
+ };
3900
+
3901
+ // src/components/Modal/Modal.tsx
3856
3902
  import { jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
3857
3903
  var SIZE_CLASSES10 = {
3858
3904
  xs: "max-w-[360px]",
@@ -3868,11 +3914,17 @@ var Modal = ({
3868
3914
  children,
3869
3915
  size = "md",
3870
3916
  className = "",
3871
- closeOnBackdropClick = true,
3872
3917
  closeOnEscape = true,
3873
3918
  footer,
3874
- hideCloseButton = false
3919
+ hideCloseButton = false,
3920
+ variant = "default",
3921
+ description,
3922
+ image,
3923
+ imageAlt,
3924
+ actionLink,
3925
+ actionLabel
3875
3926
  }) => {
3927
+ const titleId = useId7();
3876
3928
  useEffect6(() => {
3877
3929
  if (!isOpen || !closeOnEscape) return;
3878
3930
  const handleEscape = (event) => {
@@ -3894,16 +3946,6 @@ var Modal = ({
3894
3946
  document.body.style.overflow = originalOverflow;
3895
3947
  };
3896
3948
  }, [isOpen]);
3897
- const handleBackdropClick = (event) => {
3898
- if (closeOnBackdropClick && event.target === event.currentTarget) {
3899
- onClose();
3900
- }
3901
- };
3902
- const handleBackdropKeyDown = (event) => {
3903
- if (closeOnBackdropClick && (event.key === "Enter" || event.key === " ")) {
3904
- onClose();
3905
- }
3906
- };
3907
3949
  if (!isOpen) return null;
3908
3950
  const sizeClasses = SIZE_CLASSES10[size];
3909
3951
  const baseClasses = "bg-secondary-50 rounded-3xl shadow-hard-shadow-2 border border-border-100 w-full mx-4";
@@ -3914,18 +3956,105 @@ var Modal = ({
3914
3956
  dialogResetClasses,
3915
3957
  className
3916
3958
  );
3917
- return /* @__PURE__ */ jsx25(
3918
- "div",
3959
+ const normalizeUrl = (href) => /^https?:\/\//i.test(href) ? href : `https://${href}`;
3960
+ const handleActionClick = () => {
3961
+ if (actionLink) {
3962
+ window.open(normalizeUrl(actionLink), "_blank", "noopener,noreferrer");
3963
+ }
3964
+ };
3965
+ if (variant === "activity") {
3966
+ return /* @__PURE__ */ jsx25("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__ */ jsxs19(
3967
+ "dialog",
3968
+ {
3969
+ className: modalClasses,
3970
+ "aria-labelledby": titleId,
3971
+ "aria-modal": "true",
3972
+ open: true,
3973
+ children: [
3974
+ /* @__PURE__ */ jsx25("div", { className: "flex justify-end p-6 pb-0", children: !hideCloseButton && /* @__PURE__ */ jsx25(
3975
+ "button",
3976
+ {
3977
+ onClick: onClose,
3978
+ 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",
3979
+ "aria-label": "Fechar modal",
3980
+ children: /* @__PURE__ */ jsx25(X3, { size: 18 })
3981
+ }
3982
+ ) }),
3983
+ /* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-center px-6 pb-6 gap-5", children: [
3984
+ image && /* @__PURE__ */ jsx25("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx25(
3985
+ "img",
3986
+ {
3987
+ src: image,
3988
+ alt: imageAlt ?? "",
3989
+ className: "w-[122px] h-[122px] object-contain"
3990
+ }
3991
+ ) }),
3992
+ /* @__PURE__ */ jsx25(
3993
+ "h2",
3994
+ {
3995
+ id: titleId,
3996
+ className: "text-lg font-semibold text-text-950 text-center",
3997
+ children: title
3998
+ }
3999
+ ),
4000
+ description && /* @__PURE__ */ jsx25("p", { className: "text-sm font-normal text-text-400 text-center max-w-md leading-[21px]", children: description }),
4001
+ actionLink && /* @__PURE__ */ jsxs19("div", { className: "w-full", children: [
4002
+ (() => {
4003
+ const normalized = normalizeUrl(actionLink);
4004
+ const isYT = isYouTubeUrl(normalized);
4005
+ if (!isYT) return null;
4006
+ const id = getYouTubeVideoId(normalized);
4007
+ if (!id) {
4008
+ return /* @__PURE__ */ jsx25(
4009
+ Button_default,
4010
+ {
4011
+ variant: "solid",
4012
+ action: "primary",
4013
+ size: "large",
4014
+ className: "w-full",
4015
+ onClick: handleActionClick,
4016
+ children: actionLabel || "Iniciar Atividade"
4017
+ }
4018
+ );
4019
+ }
4020
+ return /* @__PURE__ */ jsx25(
4021
+ "iframe",
4022
+ {
4023
+ src: getYouTubeEmbedUrl(id),
4024
+ className: "w-full aspect-video rounded-lg",
4025
+ allowFullScreen: true,
4026
+ allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
4027
+ title: "V\xEDdeo YouTube"
4028
+ }
4029
+ );
4030
+ })(),
4031
+ !isYouTubeUrl(normalizeUrl(actionLink)) && /* @__PURE__ */ jsx25(
4032
+ Button_default,
4033
+ {
4034
+ variant: "solid",
4035
+ action: "primary",
4036
+ size: "large",
4037
+ className: "w-full",
4038
+ onClick: handleActionClick,
4039
+ children: actionLabel || "Iniciar Atividade"
4040
+ }
4041
+ )
4042
+ ] })
4043
+ ] })
4044
+ ]
4045
+ }
4046
+ ) });
4047
+ }
4048
+ return /* @__PURE__ */ jsx25("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__ */ jsxs19(
4049
+ "dialog",
3919
4050
  {
3920
- className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-xs",
3921
- onClick: handleBackdropClick,
3922
- onKeyDown: handleBackdropKeyDown,
3923
- role: "button",
3924
- tabIndex: closeOnBackdropClick ? 0 : -1,
3925
- "aria-label": "Fechar modal clicando no fundo",
3926
- children: /* @__PURE__ */ jsxs19("dialog", { className: modalClasses, "aria-labelledby": "modal-title", open: true, children: [
4051
+ className: modalClasses,
4052
+ "aria-labelledby": titleId,
4053
+ "aria-modal": "true",
4054
+ open: true,
4055
+ children: [
3927
4056
  /* @__PURE__ */ jsxs19("div", { className: "flex items-center justify-between px-6 py-6", children: [
3928
- /* @__PURE__ */ jsx25("h2", { id: "modal-title", className: "text-lg font-semibold text-text-950", children: title }),
4057
+ /* @__PURE__ */ jsx25("h2", { id: titleId, className: "text-lg font-semibold text-text-950", children: title }),
3929
4058
  !hideCloseButton && /* @__PURE__ */ jsx25(
3930
4059
  "button",
3931
4060
  {
@@ -3936,18 +4065,18 @@ var Modal = ({
3936
4065
  }
3937
4066
  )
3938
4067
  ] }),
3939
- /* @__PURE__ */ jsx25("div", { className: "px-6 pb-6", children: /* @__PURE__ */ jsx25("div", { className: "text-text-500 font-normal text-sm leading-6", children }) }),
4068
+ children && /* @__PURE__ */ jsx25("div", { className: "px-6 pb-6", children: /* @__PURE__ */ jsx25("div", { className: "text-text-500 font-normal text-sm leading-6", children }) }),
3940
4069
  footer && /* @__PURE__ */ jsx25("div", { className: "flex justify-end gap-3 px-6 pb-6", children: footer })
3941
- ] })
4070
+ ]
3942
4071
  }
3943
- );
4072
+ ) });
3944
4073
  };
3945
4074
  var Modal_default = Modal;
3946
4075
 
3947
4076
  // src/components/Accordation/Accordation.tsx
3948
4077
  import {
3949
4078
  forwardRef as forwardRef13,
3950
- useId as useId7,
4079
+ useId as useId8,
3951
4080
  useState as useState9
3952
4081
  } from "react";
3953
4082
 
@@ -5346,7 +5475,7 @@ var CardAccordation = forwardRef13(
5346
5475
  ...props
5347
5476
  }, ref) => {
5348
5477
  const [isExpanded, setIsExpanded] = useState9(defaultExpanded);
5349
- const contentId = useId7();
5478
+ const contentId = useId8();
5350
5479
  const handleToggle = () => {
5351
5480
  const newExpanded = !isExpanded;
5352
5481
  setIsExpanded(newExpanded);
@@ -5412,7 +5541,7 @@ var CardAccordation = forwardRef13(
5412
5541
 
5413
5542
  // src/components/Alternative/Alternative.tsx
5414
5543
  import { CheckCircle as CheckCircle4, XCircle as XCircle3 } from "phosphor-react";
5415
- import { forwardRef as forwardRef14, useId as useId8, useState as useState10 } from "react";
5544
+ import { forwardRef as forwardRef14, useId as useId9, useState as useState10 } from "react";
5416
5545
  import { jsx as jsx29, jsxs as jsxs23 } from "react/jsx-runtime";
5417
5546
  var AlternativesList = ({
5418
5547
  alternatives,
@@ -5426,7 +5555,7 @@ var AlternativesList = ({
5426
5555
  mode = "interactive",
5427
5556
  selectedValue
5428
5557
  }) => {
5429
- const uniqueId = useId8();
5558
+ const uniqueId = useId9();
5430
5559
  const groupName = name || `alternatives-${uniqueId}`;
5431
5560
  const [actualValue, setActualValue] = useState10(value);
5432
5561
  const isReadonly = mode === "readonly";
@@ -6194,7 +6323,7 @@ import {
6194
6323
  isValidElement as isValidElement4,
6195
6324
  Children as Children4,
6196
6325
  cloneElement as cloneElement4,
6197
- useId as useId9
6326
+ useId as useId10
6198
6327
  } from "react";
6199
6328
  import { CaretDown, Check as Check5, WarningCircle as WarningCircle5 } from "phosphor-react";
6200
6329
  import { Fragment as Fragment7, jsx as jsx33, jsxs as jsxs27 } from "react/jsx-runtime";
@@ -6300,7 +6429,7 @@ var Select = ({
6300
6429
  const store = storeRef.current;
6301
6430
  const selectRef = useRef8(null);
6302
6431
  const { open, setOpen, setValue, selectedLabel } = useStore4(store, (s) => s);
6303
- const generatedId = useId9();
6432
+ const generatedId = useId10();
6304
6433
  const selectId = id ?? `select-${generatedId}`;
6305
6434
  const findLabelForValue = (children2, targetValue) => {
6306
6435
  let found = null;
@@ -8290,7 +8419,7 @@ import {
8290
8419
  forwardRef as forwardRef20,
8291
8420
  useEffect as useEffect16,
8292
8421
  useMemo as useMemo6,
8293
- useId as useId10,
8422
+ useId as useId11,
8294
8423
  useState as useState18,
8295
8424
  useCallback as useCallback5,
8296
8425
  useRef as useRef12
@@ -9570,7 +9699,7 @@ var QuizFill = ({ paddingBottom }) => {
9570
9699
  }
9571
9700
  ];
9572
9701
  const [answers, setAnswers] = useState18({});
9573
- const baseId = useId10();
9702
+ const baseId = useId11();
9574
9703
  const getAvailableOptionsForSelect = (selectId) => {
9575
9704
  const usedOptions = Object.entries(answers).filter(([key]) => key !== selectId).map(([, value]) => value);
9576
9705
  return options.filter((option) => !usedOptions.includes(option));
@@ -10082,7 +10211,6 @@ var QuizFooter = forwardRef20(
10082
10211
  isOpen: modalResultOpen,
10083
10212
  onClose: () => setModalResultOpen(false),
10084
10213
  title: "",
10085
- closeOnBackdropClick: false,
10086
10214
  closeOnEscape: false,
10087
10215
  hideCloseButton: true,
10088
10216
  size: "md",
@@ -10967,7 +11095,6 @@ var NotificationCenter = ({
10967
11095
  title: "Notifica\xE7\xF5es",
10968
11096
  size: "md",
10969
11097
  hideCloseButton: false,
10970
- closeOnBackdropClick: true,
10971
11098
  closeOnEscape: true,
10972
11099
  children: /* @__PURE__ */ jsxs35("div", { className: "flex flex-col h-full max-h-[80vh]", children: [
10973
11100
  /* @__PURE__ */ jsxs35("div", { className: "px-0 pb-3 border-b border-border-200", children: [