analytica-frontend-lib 1.0.57 → 1.0.58

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
@@ -3695,9 +3695,16 @@ var Menu = forwardRef11(
3695
3695
  useEffect5(() => {
3696
3696
  setValue(propValue ?? defaultValue);
3697
3697
  }, [defaultValue, propValue, setValue]);
3698
+ const onValueChangeRef = useRef4(onValueChange);
3699
+ const isInitializedRef = useRef4(false);
3700
+ onValueChangeRef.current = onValueChange;
3698
3701
  useEffect5(() => {
3699
- onValueChange?.(value);
3700
- }, [value, onValueChange]);
3702
+ if (isInitializedRef.current) {
3703
+ onValueChangeRef.current?.(value);
3704
+ } else {
3705
+ isInitializedRef.current = true;
3706
+ }
3707
+ }, [value]);
3701
3708
  const baseClasses = "w-full py-2 px-6 flex flex-row items-center justify-center";
3702
3709
  const variantClasses = VARIANT_CLASSES5[variant];
3703
3710
  return /* @__PURE__ */ jsx25(
@@ -3802,9 +3809,9 @@ var MenuItem = forwardRef11(
3802
3809
  {
3803
3810
  "data-variant": "breadcrumb",
3804
3811
  className: `
3805
- w-full p-2 rounded-lg hover:text-primary-600 cursor-pointer font-bold text-xs
3812
+ w-full p-2 rounded-lg hover:text-primary-600 cursor-pointer font-bold text-xs
3806
3813
  focus:outline-none focus:border-indicator-info focus:border-2
3807
- ${selectedValue === value ? "text-primary-950" : "text-text-600"}
3814
+ ${selectedValue === value ? "text-text-950" : "text-text-600"}
3808
3815
  ${className ?? ""}
3809
3816
  `,
3810
3817
  ...commonProps,
@@ -3812,8 +3819,8 @@ var MenuItem = forwardRef11(
3812
3819
  "span",
3813
3820
  {
3814
3821
  className: `
3815
- border-b border-text-600 hover:border-primary-600 text-inherit
3816
- ${selectedValue === value ? "border-b-primary-950" : "border-b-primary-600"}
3822
+ border-b border-text-600 hover:border-primary-600 text-inherit text-xs
3823
+ ${selectedValue === value ? "border-b-0 font-bold" : "border-b-primary-600"}
3817
3824
  `,
3818
3825
  children
3819
3826
  }
@@ -3934,11 +3941,21 @@ var injectStore3 = (children, store) => Children3.map(children, (child) => {
3934
3941
  var Menu_default = Menu;
3935
3942
 
3936
3943
  // src/components/Card/Card.tsx
3937
- import { forwardRef as forwardRef12, Fragment as Fragment4 } from "react";
3944
+ import {
3945
+ forwardRef as forwardRef12,
3946
+ Fragment as Fragment4,
3947
+ useState as useState8,
3948
+ useRef as useRef5
3949
+ } from "react";
3938
3950
  import {
3939
3951
  CaretRight as CaretRight2,
3940
3952
  ChatCircleText,
3941
3953
  CheckCircle as CheckCircle3,
3954
+ DotsThreeVertical,
3955
+ Play,
3956
+ SpeakerHigh,
3957
+ SpeakerLow,
3958
+ SpeakerSimpleX,
3942
3959
  XCircle as XCircle2
3943
3960
  } from "phosphor-react";
3944
3961
  import { Fragment as Fragment5, jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
@@ -4120,7 +4137,7 @@ var CardProgress = forwardRef12(
4120
4137
  {
4121
4138
  ref,
4122
4139
  className: `
4123
- w-full flex border border-border-50 bg-background rounded-xl
4140
+ w-full flex border border-border-50 bg-background rounded-xl cursor-pointer
4124
4141
  ${isHorizontal ? "flex-row h-20" : "flex-col"}
4125
4142
  ${className}
4126
4143
  `,
@@ -4170,7 +4187,7 @@ var CardTopic = forwardRef12(
4170
4187
  "div",
4171
4188
  {
4172
4189
  ref,
4173
- className: `w-full py-2 px-4 flex flex-col justify-center gap-2 bg-background border border-border-50 rounded-xl min-h-20 ${className}`,
4190
+ className: `cursor-pointer w-full py-2 px-4 flex flex-col justify-center gap-2 bg-background border border-border-50 rounded-xl min-h-20 ${className}`,
4174
4191
  ...props,
4175
4192
  children: [
4176
4193
  subHead && /* @__PURE__ */ jsx26("span", { className: "text-text-600 text-2xs flex flex-row gap-1", children: subHead.map((text, index) => /* @__PURE__ */ jsxs21(Fragment4, { children: [
@@ -4220,7 +4237,7 @@ var CardPerformance = forwardRef12(
4220
4237
  !hasProgress && /* @__PURE__ */ jsx26(
4221
4238
  CaretRight2,
4222
4239
  {
4223
- className: "size-4.5 text-text-800",
4240
+ className: "size-4.5 text-text-800 cursor-pointer",
4224
4241
  "data-testid": "caret-icon",
4225
4242
  onClick: () => onClickButton?.(valueButton)
4226
4243
  }
@@ -4304,7 +4321,7 @@ var CardResults = forwardRef12(
4304
4321
  ]
4305
4322
  }
4306
4323
  ),
4307
- /* @__PURE__ */ jsx26(CaretRight2, { className: "min-w-6 min-h-6 text-text-800" })
4324
+ /* @__PURE__ */ jsx26(CaretRight2, { className: "min-w-6 min-h-6 text-text-800 cursor-pointer" })
4308
4325
  ]
4309
4326
  }
4310
4327
  );
@@ -4346,7 +4363,7 @@ var CardStatus = forwardRef12(
4346
4363
  ]
4347
4364
  }
4348
4365
  ),
4349
- /* @__PURE__ */ jsx26(CaretRight2, { className: "min-w-6 min-h-6 text-text-800" })
4366
+ /* @__PURE__ */ jsx26(CaretRight2, { className: "min-w-6 min-h-6 text-text-800 cursor-pointer" })
4350
4367
  ]
4351
4368
  }
4352
4369
  );
@@ -4363,7 +4380,7 @@ var CardSettings = forwardRef12(
4363
4380
  children: [
4364
4381
  /* @__PURE__ */ jsx26("span", { className: "[&>svg]:size-6", children: icon }),
4365
4382
  /* @__PURE__ */ jsx26("p", { className: "w-full text-md", children: header }),
4366
- /* @__PURE__ */ jsx26(CaretRight2, { size: 24 })
4383
+ /* @__PURE__ */ jsx26(CaretRight2, { size: 24, className: "cursor-pointer" })
4367
4384
  ]
4368
4385
  }
4369
4386
  );
@@ -4390,7 +4407,7 @@ var CardSupport = forwardRef12(
4390
4407
  ]
4391
4408
  }
4392
4409
  ),
4393
- /* @__PURE__ */ jsx26(CaretRight2, { className: "text-text-800", size: 24 })
4410
+ /* @__PURE__ */ jsx26(CaretRight2, { className: "text-text-800 cursor-pointer", size: 24 })
4394
4411
  ]
4395
4412
  }
4396
4413
  );
@@ -4459,6 +4476,243 @@ var CardForum = forwardRef12(
4459
4476
  );
4460
4477
  }
4461
4478
  );
4479
+ var CardAudio = forwardRef12(
4480
+ ({
4481
+ src,
4482
+ title,
4483
+ onPlay,
4484
+ onPause,
4485
+ onEnded,
4486
+ onAudioTimeUpdate,
4487
+ loop = false,
4488
+ preload = "metadata",
4489
+ tracks,
4490
+ className,
4491
+ ...props
4492
+ }, ref) => {
4493
+ const [isPlaying, setIsPlaying] = useState8(false);
4494
+ const [currentTime, setCurrentTime] = useState8(0);
4495
+ const [duration, setDuration] = useState8(0);
4496
+ const [volume, setVolume] = useState8(1);
4497
+ const [showVolumeControl, setShowVolumeControl] = useState8(false);
4498
+ const audioRef = useRef5(null);
4499
+ const formatTime = (time) => {
4500
+ const minutes = Math.floor(time / 60);
4501
+ const seconds = Math.floor(time % 60);
4502
+ return `${minutes}:${seconds.toString().padStart(2, "0")}`;
4503
+ };
4504
+ const handlePlayPause = () => {
4505
+ if (isPlaying) {
4506
+ audioRef.current?.pause();
4507
+ setIsPlaying(false);
4508
+ onPause?.();
4509
+ } else {
4510
+ audioRef.current?.play();
4511
+ setIsPlaying(true);
4512
+ onPlay?.();
4513
+ }
4514
+ };
4515
+ const handleTimeUpdate = () => {
4516
+ const current = audioRef.current?.currentTime ?? 0;
4517
+ const total = audioRef.current?.duration ?? 0;
4518
+ setCurrentTime(current);
4519
+ setDuration(total);
4520
+ onAudioTimeUpdate?.(current, total);
4521
+ };
4522
+ const handleLoadedMetadata = () => {
4523
+ setDuration(audioRef.current?.duration ?? 0);
4524
+ };
4525
+ const handleEnded = () => {
4526
+ setIsPlaying(false);
4527
+ setCurrentTime(0);
4528
+ onEnded?.();
4529
+ };
4530
+ const handleProgressClick = (e) => {
4531
+ const rect = e.currentTarget.getBoundingClientRect();
4532
+ const clickX = e.clientX - rect.left;
4533
+ const width = rect.width;
4534
+ const percentage = clickX / width;
4535
+ const newTime = percentage * duration;
4536
+ if (audioRef.current) {
4537
+ audioRef.current.currentTime = newTime;
4538
+ }
4539
+ setCurrentTime(newTime);
4540
+ };
4541
+ const handleVolumeChange = (e) => {
4542
+ const newVolume = parseFloat(e.target.value);
4543
+ setVolume(newVolume);
4544
+ if (audioRef.current) {
4545
+ audioRef.current.volume = newVolume;
4546
+ }
4547
+ };
4548
+ const toggleVolumeControl = () => {
4549
+ setShowVolumeControl(!showVolumeControl);
4550
+ };
4551
+ const getVolumeIcon = () => {
4552
+ if (volume === 0) {
4553
+ return /* @__PURE__ */ jsx26(SpeakerSimpleX, {});
4554
+ }
4555
+ if (volume < 0.5) {
4556
+ return /* @__PURE__ */ jsx26(SpeakerLow, {});
4557
+ }
4558
+ return /* @__PURE__ */ jsx26(SpeakerHigh, {});
4559
+ };
4560
+ return /* @__PURE__ */ jsxs21(
4561
+ "div",
4562
+ {
4563
+ ref,
4564
+ className: `w-auto h-14 p-4 flex flex-row bg-background items-center gap-2 ${className}`,
4565
+ ...props,
4566
+ children: [
4567
+ /* @__PURE__ */ jsx26(
4568
+ "audio",
4569
+ {
4570
+ ref: audioRef,
4571
+ src,
4572
+ loop,
4573
+ preload,
4574
+ onTimeUpdate: handleTimeUpdate,
4575
+ onLoadedMetadata: handleLoadedMetadata,
4576
+ onEnded: handleEnded,
4577
+ "data-testid": "audio-element",
4578
+ "aria-label": title,
4579
+ children: tracks ? tracks.map((track) => /* @__PURE__ */ jsx26(
4580
+ "track",
4581
+ {
4582
+ kind: track.kind,
4583
+ src: track.src,
4584
+ srcLang: track.srcLang,
4585
+ label: track.label,
4586
+ default: track.default
4587
+ },
4588
+ track.src
4589
+ )) : /* @__PURE__ */ jsx26(
4590
+ "track",
4591
+ {
4592
+ kind: "captions",
4593
+ src: "data:text/vtt;base64,",
4594
+ srcLang: "pt",
4595
+ label: "Sem legendas dispon\xEDveis"
4596
+ }
4597
+ )
4598
+ }
4599
+ ),
4600
+ /* @__PURE__ */ jsx26(
4601
+ "button",
4602
+ {
4603
+ type: "button",
4604
+ onClick: handlePlayPause,
4605
+ disabled: !src,
4606
+ className: "cursor-pointer text-text-950 hover:text-primary-600 disabled:text-text-400 disabled:cursor-not-allowed",
4607
+ "aria-label": isPlaying ? "Pausar" : "Reproduzir",
4608
+ children: isPlaying ? /* @__PURE__ */ jsx26("div", { className: "w-6 h-6 flex items-center justify-center", children: /* @__PURE__ */ jsxs21("div", { className: "flex gap-0.5", children: [
4609
+ /* @__PURE__ */ jsx26("div", { className: "w-1 h-4 bg-current rounded-sm" }),
4610
+ /* @__PURE__ */ jsx26("div", { className: "w-1 h-4 bg-current rounded-sm" })
4611
+ ] }) }) : /* @__PURE__ */ jsx26(Play, { size: 24 })
4612
+ }
4613
+ ),
4614
+ /* @__PURE__ */ jsx26("p", { className: "text-text-800 text-sm font-medium min-w-[2.5rem]", children: formatTime(currentTime) }),
4615
+ /* @__PURE__ */ jsx26("div", { className: "flex-1 relative", "data-testid": "progress-bar", children: /* @__PURE__ */ jsx26(
4616
+ "button",
4617
+ {
4618
+ type: "button",
4619
+ className: "w-full h-2 bg-border-100 rounded-full cursor-pointer",
4620
+ onClick: handleProgressClick,
4621
+ onKeyDown: (e) => {
4622
+ if (e.key === "Enter" || e.key === " ") {
4623
+ e.preventDefault();
4624
+ handleProgressClick(
4625
+ e
4626
+ );
4627
+ }
4628
+ },
4629
+ "aria-label": "Barra de progresso do \xE1udio",
4630
+ children: /* @__PURE__ */ jsx26(
4631
+ "div",
4632
+ {
4633
+ className: "h-full bg-primary-600 rounded-full transition-all duration-100",
4634
+ style: {
4635
+ width: duration > 0 ? `${currentTime / duration * 100}%` : "0%"
4636
+ }
4637
+ }
4638
+ )
4639
+ }
4640
+ ) }),
4641
+ /* @__PURE__ */ jsx26("p", { className: "text-text-800 text-sm font-medium min-w-[2.5rem]", children: formatTime(duration) }),
4642
+ /* @__PURE__ */ jsxs21("div", { className: "relative", children: [
4643
+ /* @__PURE__ */ jsx26(
4644
+ "button",
4645
+ {
4646
+ type: "button",
4647
+ onClick: toggleVolumeControl,
4648
+ className: "cursor-pointer text-text-950 hover:text-primary-600",
4649
+ "aria-label": "Controle de volume",
4650
+ children: /* @__PURE__ */ jsx26("div", { className: "w-6 h-6 flex items-center justify-center", children: getVolumeIcon() })
4651
+ }
4652
+ ),
4653
+ showVolumeControl && /* @__PURE__ */ jsx26(
4654
+ "button",
4655
+ {
4656
+ type: "button",
4657
+ className: "absolute bottom-full right-0 mb-2 p-2 bg-background border border-border-100 rounded-lg shadow-lg focus:outline-none focus:ring-2 focus:ring-primary-500",
4658
+ onKeyDown: (e) => {
4659
+ if (e.key === "Escape") {
4660
+ setShowVolumeControl(false);
4661
+ }
4662
+ },
4663
+ children: /* @__PURE__ */ jsx26(
4664
+ "input",
4665
+ {
4666
+ type: "range",
4667
+ min: "0",
4668
+ max: "1",
4669
+ step: "0.1",
4670
+ value: volume,
4671
+ onChange: handleVolumeChange,
4672
+ onKeyDown: (e) => {
4673
+ if (e.key === "ArrowUp" || e.key === "ArrowRight") {
4674
+ e.preventDefault();
4675
+ const newVolume = Math.min(
4676
+ 1,
4677
+ Math.round((volume + 0.1) * 10) / 10
4678
+ );
4679
+ setVolume(newVolume);
4680
+ if (audioRef.current) audioRef.current.volume = newVolume;
4681
+ } else if (e.key === "ArrowDown" || e.key === "ArrowLeft") {
4682
+ e.preventDefault();
4683
+ const newVolume = Math.max(
4684
+ 0,
4685
+ Math.round((volume - 0.1) * 10) / 10
4686
+ );
4687
+ setVolume(newVolume);
4688
+ if (audioRef.current) audioRef.current.volume = newVolume;
4689
+ }
4690
+ },
4691
+ className: "w-20 h-2 bg-border-100 rounded-lg appearance-none cursor-pointer",
4692
+ style: {
4693
+ background: `linear-gradient(to right, #3b82f6 0%, #3b82f6 ${volume * 100}%, #e5e7eb ${volume * 100}%, #e5e7eb 100%)`
4694
+ },
4695
+ "aria-label": "Volume",
4696
+ "aria-valuenow": Math.round(volume * 100),
4697
+ "aria-valuemin": 0,
4698
+ "aria-valuemax": 100
4699
+ }
4700
+ )
4701
+ }
4702
+ )
4703
+ ] }),
4704
+ /* @__PURE__ */ jsx26(
4705
+ DotsThreeVertical,
4706
+ {
4707
+ size: 24,
4708
+ className: "text-text-950 cursor-pointer hover:text-primary-600"
4709
+ }
4710
+ )
4711
+ ]
4712
+ }
4713
+ );
4714
+ }
4715
+ );
4462
4716
  export {
4463
4717
  Alert_default as Alert,
4464
4718
  Badge_default as Badge,