virtual-ui-lib 1.0.26 → 1.0.28

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.
Files changed (3) hide show
  1. package/dist/index.js +145 -109
  2. package/dist/index.mjs +143 -108
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -42,7 +42,8 @@ __export(index_exports, {
42
42
  Navbar: () => Navbar,
43
43
  OTPInput: () => OTPInput,
44
44
  RatingStars: () => RatingStars,
45
- UserAvatar: () => UserAvatar
45
+ UserAvatar: () => UserAvatar,
46
+ WishlistButton: () => WishlistButton
46
47
  });
47
48
  module.exports = __toCommonJS(index_exports);
48
49
 
@@ -407,83 +408,8 @@ var GridLayout = ({
407
408
  return /* @__PURE__ */ import_react7.default.createElement("div", { style: { display: "grid", gridTemplateColumns: `repeat(${cols}, 1fr)`, gap: spacing } }, items.map(renderItem));
408
409
  };
409
410
 
410
- // src/components/Navbar/Navbar.jsx
411
- var import_react8 = __toESM(require("react"));
412
- var Navbar = ({
413
- logo = "Logo",
414
- links = [{ name: "Home", href: "#" }, { name: "About", href: "#" }, { name: "Services", href: "#" }, { name: "Contact", href: "#" }],
415
- bgColor = "#0f172a",
416
- linkColor = "#f1f5f9",
417
- hoverColor = "#7c3aed",
418
- stickyColor = "#1e293b",
419
- radius = "8px"
420
- }) => {
421
- const [isMobileMenuOpen, setMobileMenuOpen] = (0, import_react8.useState)(false);
422
- const [isSticky, setSticky] = (0, import_react8.useState)(false);
423
- (0, import_react8.useEffect)(() => {
424
- const handleScroll = () => {
425
- setSticky(window.scrollY > 50);
426
- };
427
- window.addEventListener("scroll", handleScroll);
428
- return () => window.removeEventListener("scroll", handleScroll);
429
- }, []);
430
- return /* @__PURE__ */ import_react8.default.createElement("nav", { style: {
431
- background: isSticky ? stickyColor : bgColor,
432
- position: isSticky ? "fixed" : "relative",
433
- width: "100%",
434
- padding: "10px 20px",
435
- boxShadow: isSticky ? "0 2px 10px rgba(0,0,0,0.2)" : "none",
436
- transition: "background 0.3s ease"
437
- } }, /* @__PURE__ */ import_react8.default.createElement("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" } }, /* @__PURE__ */ import_react8.default.createElement("div", { style: { color: linkColor, fontSize: "20px", fontWeight: "600" } }, logo), /* @__PURE__ */ import_react8.default.createElement("div", { style: { display: "flex", alignItems: "center" } }, /* @__PURE__ */ import_react8.default.createElement("ul", { style: { display: "flex", listStyle: "none", gap: "20px", margin: 0, padding: 0 } }, links.map((link) => /* @__PURE__ */ import_react8.default.createElement("li", { key: link.name }, /* @__PURE__ */ import_react8.default.createElement("a", { href: link.href, style: {
438
- textDecoration: "none",
439
- color: linkColor,
440
- position: "relative",
441
- fontSize: "16px",
442
- transition: "color 0.3s"
443
- }, onMouseOver: (e) => e.currentTarget.style.color = hoverColor, onMouseOut: (e) => e.currentTarget.style.color = linkColor }, link.name, /* @__PURE__ */ import_react8.default.createElement("span", { style: {
444
- position: "absolute",
445
- bottom: "-3px",
446
- left: 0,
447
- width: "100%",
448
- height: "2px",
449
- background: hoverColor,
450
- transform: "scaleX(0)",
451
- transition: "transform 0.3s ease"
452
- }, className: "underline" }))))), /* @__PURE__ */ import_react8.default.createElement("button", { onClick: () => setMobileMenuOpen(true), style: {
453
- background: "transparent",
454
- color: linkColor,
455
- border: "none",
456
- cursor: "pointer",
457
- fontSize: "16px",
458
- marginLeft: "20px"
459
- } }, "\u2630"))), isMobileMenuOpen && /* @__PURE__ */ import_react8.default.createElement("div", { style: {
460
- position: "fixed",
461
- top: 0,
462
- right: 0,
463
- width: "250px",
464
- height: "100%",
465
- background: bgColor,
466
- boxShadow: "-4px 0 10px rgba(0,0,0,0.5)",
467
- padding: "20px",
468
- transform: "translateX(0)",
469
- transition: "transform 0.3s ease"
470
- } }, /* @__PURE__ */ import_react8.default.createElement("button", { onClick: () => setMobileMenuOpen(false), style: {
471
- background: "transparent",
472
- color: linkColor,
473
- border: "none",
474
- cursor: "pointer",
475
- fontSize: "16px",
476
- marginBottom: "20px"
477
- } }, "\u2716"), /* @__PURE__ */ import_react8.default.createElement("ul", { style: { listStyle: "none", padding: 0 } }, links.map((link) => /* @__PURE__ */ import_react8.default.createElement("li", { key: link.name, style: { margin: "10px 0" } }, /* @__PURE__ */ import_react8.default.createElement("a", { href: link.href, style: {
478
- textDecoration: "none",
479
- color: linkColor,
480
- fontSize: "18px",
481
- transition: "color 0.3s"
482
- }, onMouseOver: (e) => e.currentTarget.style.color = hoverColor, onMouseOut: (e) => e.currentTarget.style.color = linkColor }, link.name))))));
483
- };
484
-
485
411
  // src/components/ImageUploadPreview/ImageUploadPreview.jsx
486
- var import_react9 = __toESM(require("react"));
412
+ var import_react8 = __toESM(require("react"));
487
413
  var ImageUploadPreview = ({
488
414
  width = "300px",
489
415
  height = "200px",
@@ -493,8 +419,8 @@ var ImageUploadPreview = ({
493
419
  borderRadius = "12px",
494
420
  onImageChange
495
421
  }) => {
496
- const [image, setImage] = (0, import_react9.useState)(null);
497
- const [error, setError] = (0, import_react9.useState)(false);
422
+ const [image, setImage] = (0, import_react8.useState)(null);
423
+ const [error, setError] = (0, import_react8.useState)(false);
498
424
  const handleImageChange = (e) => {
499
425
  const file = e.target.files[0];
500
426
  const validTypes = ["image/png", "image/jpeg", "image/jpg"];
@@ -514,7 +440,7 @@ var ImageUploadPreview = ({
514
440
  setImage(null);
515
441
  setError(false);
516
442
  };
517
- return /* @__PURE__ */ import_react9.default.createElement("div", { style: {
443
+ return /* @__PURE__ */ import_react8.default.createElement("div", { style: {
518
444
  display: "flex",
519
445
  justifyContent: "center",
520
446
  alignItems: "center",
@@ -526,7 +452,7 @@ var ImageUploadPreview = ({
526
452
  position: "relative",
527
453
  overflow: "hidden",
528
454
  transition: "border-color 0.3s"
529
- } }, !image && !error && /* @__PURE__ */ import_react9.default.createElement("input", { type: "file", onChange: handleImageChange, style: { display: "none" }, id: "file-input" }), !image && !error && /* @__PURE__ */ import_react9.default.createElement("label", { htmlFor: "file-input", style: { color: "#f1f5f9", cursor: "pointer", textAlign: "center" } }, "Upload Image"), error && /* @__PURE__ */ import_react9.default.createElement("p", { style: { color: errorColor, fontSize: "14px", textAlign: "center" } }, "Invalid image type!"), image && /* @__PURE__ */ import_react9.default.createElement("div", { style: {
455
+ } }, !image && !error && /* @__PURE__ */ import_react8.default.createElement("input", { type: "file", onChange: handleImageChange, style: { display: "none" }, id: "file-input" }), !image && !error && /* @__PURE__ */ import_react8.default.createElement("label", { htmlFor: "file-input", style: { color: "#f1f5f9", cursor: "pointer", textAlign: "center" } }, "Upload Image"), error && /* @__PURE__ */ import_react8.default.createElement("p", { style: { color: errorColor, fontSize: "14px", textAlign: "center" } }, "Invalid image type!"), image && /* @__PURE__ */ import_react8.default.createElement("div", { style: {
530
456
  position: "absolute",
531
457
  top: 0,
532
458
  left: 0,
@@ -538,14 +464,14 @@ var ImageUploadPreview = ({
538
464
  background: "rgba(0,0,0,0.6)",
539
465
  transition: "opacity 0.3s",
540
466
  opacity: 1
541
- } }, /* @__PURE__ */ import_react9.default.createElement("img", { src: image, alt: "Preview", style: {
467
+ } }, /* @__PURE__ */ import_react8.default.createElement("img", { src: image, alt: "Preview", style: {
542
468
  maxWidth: "100%",
543
469
  maxHeight: "100%",
544
470
  objectFit: "cover",
545
471
  transition: "transform 0.3s",
546
472
  borderRadius,
547
473
  cursor: "zoom-in"
548
- }, onMouseEnter: (e) => e.currentTarget.style.transform = "scale(1.05)", onMouseLeave: (e) => e.currentTarget.style.transform = "scale(1)" })), image && /* @__PURE__ */ import_react9.default.createElement("button", { onClick: handleRemove, style: {
474
+ }, onMouseEnter: (e) => e.currentTarget.style.transform = "scale(1.05)", onMouseLeave: (e) => e.currentTarget.style.transform = "scale(1)" })), image && /* @__PURE__ */ import_react8.default.createElement("button", { onClick: handleRemove, style: {
549
475
  position: "absolute",
550
476
  top: "10px",
551
477
  right: "10px",
@@ -562,23 +488,23 @@ var ImageUploadPreview = ({
562
488
  };
563
489
 
564
490
  // src/components/CopyButton/CopyButton.jsx
565
- var import_react10 = __toESM(require("react"));
491
+ var import_react9 = __toESM(require("react"));
566
492
  var CopyButton = ({
567
493
  text = "Copy",
568
494
  bg = "#2563eb",
569
495
  color = "white",
570
496
  radius = "8px",
571
- icon = /* @__PURE__ */ import_react10.default.createElement("span", { role: "img", "aria-label": "copy" }, "\u{1F4CB}"),
497
+ icon = /* @__PURE__ */ import_react9.default.createElement("span", { role: "img", "aria-label": "copy" }, "\u{1F4CB}"),
572
498
  padding = "10px 15px",
573
499
  shadow = "0 4px 14px rgba(37,99,235,0.4)"
574
500
  }) => {
575
- const [copied, setCopied] = (0, import_react10.useState)(false);
501
+ const [copied, setCopied] = (0, import_react9.useState)(false);
576
502
  const handleCopy = () => {
577
503
  navigator.clipboard.writeText(text);
578
504
  setCopied(true);
579
505
  setTimeout(() => setCopied(false), 2e3);
580
506
  };
581
- return /* @__PURE__ */ import_react10.default.createElement(
507
+ return /* @__PURE__ */ import_react9.default.createElement(
582
508
  "button",
583
509
  {
584
510
  onClick: handleCopy,
@@ -603,7 +529,7 @@ var CopyButton = ({
603
529
  };
604
530
 
605
531
  // src/components/Loader/Loader.jsx
606
- var import_react11 = __toESM(require("react"));
532
+ var import_react10 = __toESM(require("react"));
607
533
  var Loader = ({
608
534
  size = "medium",
609
535
  fullScreen = false,
@@ -612,11 +538,11 @@ var Loader = ({
612
538
  duration = "1s"
613
539
  }) => {
614
540
  const sizes = { small: "40px", medium: "60px", large: "80px" };
615
- const [fadeIn, setFadeIn] = (0, import_react11.useState)(false);
616
- (0, import_react11.useEffect)(() => {
541
+ const [fadeIn, setFadeIn] = (0, import_react10.useState)(false);
542
+ (0, import_react10.useEffect)(() => {
617
543
  setFadeIn(true);
618
544
  }, []);
619
- return /* @__PURE__ */ import_react11.default.createElement(
545
+ return /* @__PURE__ */ import_react10.default.createElement(
620
546
  "div",
621
547
  {
622
548
  style: {
@@ -629,7 +555,7 @@ var Loader = ({
629
555
  opacity: fadeIn ? 1 : 0
630
556
  }
631
557
  },
632
- /* @__PURE__ */ import_react11.default.createElement(
558
+ /* @__PURE__ */ import_react10.default.createElement(
633
559
  "div",
634
560
  {
635
561
  style: {
@@ -642,7 +568,7 @@ var Loader = ({
642
568
  }
643
569
  }
644
570
  ),
645
- /* @__PURE__ */ import_react11.default.createElement("style", null, `
571
+ /* @__PURE__ */ import_react10.default.createElement("style", null, `
646
572
  @keyframes spin {
647
573
  0% { transform: rotate(0deg); }
648
574
  100% { transform: rotate(360deg); }
@@ -652,7 +578,7 @@ var Loader = ({
652
578
  };
653
579
 
654
580
  // src/components/OTPInput/OTPInput.jsx
655
- var import_react12 = __toESM(require("react"));
581
+ var import_react11 = __toESM(require("react"));
656
582
  var OTPInput = ({
657
583
  length = 4,
658
584
  bg = "#0f172a",
@@ -666,9 +592,9 @@ var OTPInput = ({
666
592
  error = false,
667
593
  success = false
668
594
  }) => {
669
- const [otp, setOtp] = (0, import_react12.useState)(Array(length).fill(""));
670
- const inputRefs = (0, import_react12.useRef)(Array(length).fill().map(() => import_react12.default.createRef()));
671
- (0, import_react12.useEffect)(() => {
595
+ const [otp, setOtp] = (0, import_react11.useState)(Array(length).fill(""));
596
+ const inputRefs = (0, import_react11.useRef)(Array(length).fill().map(() => import_react11.default.createRef()));
597
+ (0, import_react11.useEffect)(() => {
672
598
  inputRefs.current[0].current.focus();
673
599
  }, []);
674
600
  const handleChange = (index, value) => {
@@ -698,7 +624,7 @@ var OTPInput = ({
698
624
  onChange(newOtp.join(""));
699
625
  event.preventDefault();
700
626
  };
701
- return /* @__PURE__ */ import_react12.default.createElement("div", { style: { display: "flex", justifyContent: "center", gap: "10px" }, onPaste: handlePaste }, otp.map((value, index) => /* @__PURE__ */ import_react12.default.createElement(
627
+ return /* @__PURE__ */ import_react11.default.createElement("div", { style: { display: "flex", justifyContent: "center", gap: "10px" }, onPaste: handlePaste }, otp.map((value, index) => /* @__PURE__ */ import_react11.default.createElement(
702
628
  "input",
703
629
  {
704
630
  key: index,
@@ -725,7 +651,7 @@ var OTPInput = ({
725
651
  };
726
652
 
727
653
  // src/components/RatingStars/RatingStars.jsx
728
- var import_react13 = __toESM(require("react"));
654
+ var import_react12 = __toESM(require("react"));
729
655
  var RatingStars = ({
730
656
  totalStars = 5,
731
657
  selectedColor = "#ffc107",
@@ -733,8 +659,8 @@ var RatingStars = ({
733
659
  size = "24px",
734
660
  onSelect
735
661
  }) => {
736
- const [hovered, setHovered] = (0, import_react13.useState)(0);
737
- const [selected, setSelected] = (0, import_react13.useState)(0);
662
+ const [hovered, setHovered] = (0, import_react12.useState)(0);
663
+ const [selected, setSelected] = (0, import_react12.useState)(0);
738
664
  const handleMouseEnter = (index) => {
739
665
  setHovered(index + 1);
740
666
  };
@@ -745,7 +671,7 @@ var RatingStars = ({
745
671
  setSelected(index + 1);
746
672
  if (onSelect) onSelect(index + 1);
747
673
  };
748
- return /* @__PURE__ */ import_react13.default.createElement("div", { style: { display: "flex", gap: "4px" } }, [...Array(totalStars)].map((_, index) => /* @__PURE__ */ import_react13.default.createElement(
674
+ return /* @__PURE__ */ import_react12.default.createElement("div", { style: { display: "flex", gap: "4px" } }, [...Array(totalStars)].map((_, index) => /* @__PURE__ */ import_react12.default.createElement(
749
675
  "svg",
750
676
  {
751
677
  key: index,
@@ -762,12 +688,12 @@ var RatingStars = ({
762
688
  onClick: () => handleClick(index),
763
689
  style: { transition: "color 0.2s ease" }
764
690
  },
765
- /* @__PURE__ */ import_react13.default.createElement("polygon", { points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21 12 17.77 5.82 21 7 14.14 2 9.27 8.91 8.26 12 2" })
691
+ /* @__PURE__ */ import_react12.default.createElement("polygon", { points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21 12 17.77 5.82 21 7 14.14 2 9.27 8.91 8.26 12 2" })
766
692
  )));
767
693
  };
768
694
 
769
695
  // src/components/UserAvatar/UserAvatar.jsx
770
- var import_react14 = __toESM(require("react"));
696
+ var import_react13 = __toESM(require("react"));
771
697
  var UserAvatar = ({
772
698
  size = "50px",
773
699
  src = "",
@@ -780,7 +706,7 @@ var UserAvatar = ({
780
706
  statusColor = "#22c55e",
781
707
  borderColor = "#7c3aed"
782
708
  }) => {
783
- return /* @__PURE__ */ import_react14.default.createElement(
709
+ return /* @__PURE__ */ import_react13.default.createElement(
784
710
  "div",
785
711
  {
786
712
  style: {
@@ -804,17 +730,17 @@ var UserAvatar = ({
804
730
  e.currentTarget.style.transform = "scale(1)";
805
731
  }
806
732
  },
807
- src ? /* @__PURE__ */ import_react14.default.createElement("img", { src, alt: initials, style: {
733
+ src ? /* @__PURE__ */ import_react13.default.createElement("img", { src, alt: initials, style: {
808
734
  width: "100%",
809
735
  height: "100%",
810
736
  borderRadius: "50%",
811
737
  objectFit: "cover"
812
- } }) : /* @__PURE__ */ import_react14.default.createElement("span", { style: {
738
+ } }) : /* @__PURE__ */ import_react13.default.createElement("span", { style: {
813
739
  color: textColor,
814
740
  fontSize: "20px",
815
741
  fontWeight: "700"
816
742
  } }, initials),
817
- showStatus && /* @__PURE__ */ import_react14.default.createElement("span", { style: {
743
+ showStatus && /* @__PURE__ */ import_react13.default.createElement("span", { style: {
818
744
  position: "absolute",
819
745
  bottom: "0",
820
746
  right: "0",
@@ -826,6 +752,115 @@ var UserAvatar = ({
826
752
  } })
827
753
  );
828
754
  };
755
+
756
+ // src/components/Navbar/Navbar.jsx
757
+ var import_react14 = __toESM(require("react"));
758
+ var Navbar = ({
759
+ logo = "https://via.placeholder.com/150",
760
+ links = [{ name: "Home", href: "#" }, { name: "About", href: "#" }, { name: "Services", href: "#" }, { name: "Contact", href: "#" }],
761
+ bgColor = "#0f172a",
762
+ textColor = "#f1f5f9",
763
+ linkColor = "#7c3aed",
764
+ hoverColor = "#818cf8",
765
+ sticky = false,
766
+ radius = "8px"
767
+ }) => {
768
+ const [scrolled, setScrolled] = (0, import_react14.useState)(false);
769
+ const [isOpen, setIsOpen] = (0, import_react14.useState)(false);
770
+ (0, import_react14.useEffect)(() => {
771
+ const handleScroll = () => {
772
+ setScrolled(window.scrollY > 50);
773
+ };
774
+ window.addEventListener("scroll", handleScroll);
775
+ return () => window.removeEventListener("scroll", handleScroll);
776
+ }, []);
777
+ return /* @__PURE__ */ import_react14.default.createElement("nav", { style: {
778
+ position: sticky || scrolled ? "sticky" : "relative",
779
+ top: 0,
780
+ background: bgColor,
781
+ padding: "10px 20px",
782
+ borderRadius: radius,
783
+ boxShadow: scrolled ? "0 4px 10px rgba(0,0,0,0.2)" : "none",
784
+ display: "flex",
785
+ justifyContent: "space-between",
786
+ alignItems: "center",
787
+ transition: "box-shadow 0.3s ease"
788
+ } }, /* @__PURE__ */ import_react14.default.createElement("img", { src: logo, alt: "Logo", style: { width: "120px" } }), /* @__PURE__ */ import_react14.default.createElement("div", { style: { display: "none", gap: "20px", fontFamily: "system-ui, sans-serif", color: textColor, fontSize: "16px", cursor: "pointer" }, id: "nav-links" }, links.map((link) => /* @__PURE__ */ import_react14.default.createElement("a", { key: link.name, href: link.href, style: {
789
+ color: textColor,
790
+ textDecoration: "none",
791
+ position: "relative"
792
+ }, onMouseEnter: (e) => e.target.style.color = hoverColor, onMouseLeave: (e) => e.target.style.color = textColor }, link.name, /* @__PURE__ */ import_react14.default.createElement("span", { style: {
793
+ position: "absolute",
794
+ width: "100%",
795
+ height: "2px",
796
+ background: hoverColor,
797
+ bottom: "-4px",
798
+ left: 0,
799
+ transform: "scaleX(0)",
800
+ transition: "transform 0.3s ease"
801
+ }, className: "underline" })))), /* @__PURE__ */ import_react14.default.createElement("div", { style: { display: "flex", alignItems: "center" } }, /* @__PURE__ */ import_react14.default.createElement("button", { onClick: () => setIsOpen(true), style: {
802
+ background: "transparent",
803
+ border: "none",
804
+ color: textColor,
805
+ cursor: "pointer",
806
+ fontSize: "16px"
807
+ } }, "\u2630")), isOpen && /* @__PURE__ */ import_react14.default.createElement("div", { style: {
808
+ position: "fixed",
809
+ top: 0,
810
+ right: 0,
811
+ width: "250px",
812
+ height: "100%",
813
+ background: bgColor,
814
+ transform: isOpen ? "translateX(0)" : "translateX(100%)",
815
+ transition: "transform 0.3s ease",
816
+ padding: "20px",
817
+ boxShadow: "-3px 0 10px rgba(0,0,0,0.5)",
818
+ zIndex: 1e3
819
+ } }, /* @__PURE__ */ import_react14.default.createElement("button", { onClick: () => setIsOpen(false), style: {
820
+ color: textColor,
821
+ background: "none",
822
+ border: "none",
823
+ fontSize: "24px",
824
+ cursor: "pointer"
825
+ } }, "\u2716"), /* @__PURE__ */ import_react14.default.createElement("div", { style: { marginTop: "30px" } }, links.map((link) => /* @__PURE__ */ import_react14.default.createElement("a", { key: link.name, href: link.href, style: {
826
+ display: "block",
827
+ color: textColor,
828
+ textDecoration: "none",
829
+ margin: "15px 0"
830
+ } }, link.name)))));
831
+ };
832
+
833
+ // src/components/WishlistButton/WishlistButton.jsx
834
+ var import_react15 = __toESM(require("react"));
835
+ var WishlistButton = ({
836
+ isActive = false,
837
+ size = "40px",
838
+ inactiveColor = "#d1d5db",
839
+ activeColor = "#ff3e30",
840
+ onToggle
841
+ }) => {
842
+ const [active, setActive] = (0, import_react15.useState)(isActive);
843
+ const handleClick = () => {
844
+ setActive((prev) => !prev);
845
+ if (onToggle) onToggle(!active);
846
+ };
847
+ return /* @__PURE__ */ import_react15.default.createElement("div", { onClick: handleClick, style: { cursor: "pointer", width: size, height: size, display: "flex", alignItems: "center", justifyContent: "center" } }, /* @__PURE__ */ import_react15.default.createElement(
848
+ "svg",
849
+ {
850
+ width: "100%",
851
+ height: "100%",
852
+ viewBox: "0 0 24 24",
853
+ fill: "none",
854
+ xmlns: "http://www.w3.org/2000/svg",
855
+ style: {
856
+ transition: "transform 0.2s",
857
+ transform: active ? "scale(1.2)" : "scale(1)",
858
+ fill: active ? activeColor : inactiveColor
859
+ }
860
+ },
861
+ /* @__PURE__ */ import_react15.default.createElement("path", { d: "M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" })
862
+ ));
863
+ };
829
864
  // Annotate the CommonJS export names for ESM import in node:
830
865
  0 && (module.exports = {
831
866
  AlertBanner,
@@ -841,5 +876,6 @@ var UserAvatar = ({
841
876
  Navbar,
842
877
  OTPInput,
843
878
  RatingStars,
844
- UserAvatar
879
+ UserAvatar,
880
+ WishlistButton
845
881
  });
package/dist/index.mjs CHANGED
@@ -359,83 +359,8 @@ var GridLayout = ({
359
359
  return /* @__PURE__ */ React7.createElement("div", { style: { display: "grid", gridTemplateColumns: `repeat(${cols}, 1fr)`, gap: spacing } }, items.map(renderItem));
360
360
  };
361
361
 
362
- // src/components/Navbar/Navbar.jsx
363
- import React8, { useState as useState5, useEffect as useEffect4 } from "react";
364
- var Navbar = ({
365
- logo = "Logo",
366
- links = [{ name: "Home", href: "#" }, { name: "About", href: "#" }, { name: "Services", href: "#" }, { name: "Contact", href: "#" }],
367
- bgColor = "#0f172a",
368
- linkColor = "#f1f5f9",
369
- hoverColor = "#7c3aed",
370
- stickyColor = "#1e293b",
371
- radius = "8px"
372
- }) => {
373
- const [isMobileMenuOpen, setMobileMenuOpen] = useState5(false);
374
- const [isSticky, setSticky] = useState5(false);
375
- useEffect4(() => {
376
- const handleScroll = () => {
377
- setSticky(window.scrollY > 50);
378
- };
379
- window.addEventListener("scroll", handleScroll);
380
- return () => window.removeEventListener("scroll", handleScroll);
381
- }, []);
382
- return /* @__PURE__ */ React8.createElement("nav", { style: {
383
- background: isSticky ? stickyColor : bgColor,
384
- position: isSticky ? "fixed" : "relative",
385
- width: "100%",
386
- padding: "10px 20px",
387
- boxShadow: isSticky ? "0 2px 10px rgba(0,0,0,0.2)" : "none",
388
- transition: "background 0.3s ease"
389
- } }, /* @__PURE__ */ React8.createElement("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" } }, /* @__PURE__ */ React8.createElement("div", { style: { color: linkColor, fontSize: "20px", fontWeight: "600" } }, logo), /* @__PURE__ */ React8.createElement("div", { style: { display: "flex", alignItems: "center" } }, /* @__PURE__ */ React8.createElement("ul", { style: { display: "flex", listStyle: "none", gap: "20px", margin: 0, padding: 0 } }, links.map((link) => /* @__PURE__ */ React8.createElement("li", { key: link.name }, /* @__PURE__ */ React8.createElement("a", { href: link.href, style: {
390
- textDecoration: "none",
391
- color: linkColor,
392
- position: "relative",
393
- fontSize: "16px",
394
- transition: "color 0.3s"
395
- }, onMouseOver: (e) => e.currentTarget.style.color = hoverColor, onMouseOut: (e) => e.currentTarget.style.color = linkColor }, link.name, /* @__PURE__ */ React8.createElement("span", { style: {
396
- position: "absolute",
397
- bottom: "-3px",
398
- left: 0,
399
- width: "100%",
400
- height: "2px",
401
- background: hoverColor,
402
- transform: "scaleX(0)",
403
- transition: "transform 0.3s ease"
404
- }, className: "underline" }))))), /* @__PURE__ */ React8.createElement("button", { onClick: () => setMobileMenuOpen(true), style: {
405
- background: "transparent",
406
- color: linkColor,
407
- border: "none",
408
- cursor: "pointer",
409
- fontSize: "16px",
410
- marginLeft: "20px"
411
- } }, "\u2630"))), isMobileMenuOpen && /* @__PURE__ */ React8.createElement("div", { style: {
412
- position: "fixed",
413
- top: 0,
414
- right: 0,
415
- width: "250px",
416
- height: "100%",
417
- background: bgColor,
418
- boxShadow: "-4px 0 10px rgba(0,0,0,0.5)",
419
- padding: "20px",
420
- transform: "translateX(0)",
421
- transition: "transform 0.3s ease"
422
- } }, /* @__PURE__ */ React8.createElement("button", { onClick: () => setMobileMenuOpen(false), style: {
423
- background: "transparent",
424
- color: linkColor,
425
- border: "none",
426
- cursor: "pointer",
427
- fontSize: "16px",
428
- marginBottom: "20px"
429
- } }, "\u2716"), /* @__PURE__ */ React8.createElement("ul", { style: { listStyle: "none", padding: 0 } }, links.map((link) => /* @__PURE__ */ React8.createElement("li", { key: link.name, style: { margin: "10px 0" } }, /* @__PURE__ */ React8.createElement("a", { href: link.href, style: {
430
- textDecoration: "none",
431
- color: linkColor,
432
- fontSize: "18px",
433
- transition: "color 0.3s"
434
- }, onMouseOver: (e) => e.currentTarget.style.color = hoverColor, onMouseOut: (e) => e.currentTarget.style.color = linkColor }, link.name))))));
435
- };
436
-
437
362
  // src/components/ImageUploadPreview/ImageUploadPreview.jsx
438
- import React9, { useState as useState6 } from "react";
363
+ import React8, { useState as useState5 } from "react";
439
364
  var ImageUploadPreview = ({
440
365
  width = "300px",
441
366
  height = "200px",
@@ -445,8 +370,8 @@ var ImageUploadPreview = ({
445
370
  borderRadius = "12px",
446
371
  onImageChange
447
372
  }) => {
448
- const [image, setImage] = useState6(null);
449
- const [error, setError] = useState6(false);
373
+ const [image, setImage] = useState5(null);
374
+ const [error, setError] = useState5(false);
450
375
  const handleImageChange = (e) => {
451
376
  const file = e.target.files[0];
452
377
  const validTypes = ["image/png", "image/jpeg", "image/jpg"];
@@ -466,7 +391,7 @@ var ImageUploadPreview = ({
466
391
  setImage(null);
467
392
  setError(false);
468
393
  };
469
- return /* @__PURE__ */ React9.createElement("div", { style: {
394
+ return /* @__PURE__ */ React8.createElement("div", { style: {
470
395
  display: "flex",
471
396
  justifyContent: "center",
472
397
  alignItems: "center",
@@ -478,7 +403,7 @@ var ImageUploadPreview = ({
478
403
  position: "relative",
479
404
  overflow: "hidden",
480
405
  transition: "border-color 0.3s"
481
- } }, !image && !error && /* @__PURE__ */ React9.createElement("input", { type: "file", onChange: handleImageChange, style: { display: "none" }, id: "file-input" }), !image && !error && /* @__PURE__ */ React9.createElement("label", { htmlFor: "file-input", style: { color: "#f1f5f9", cursor: "pointer", textAlign: "center" } }, "Upload Image"), error && /* @__PURE__ */ React9.createElement("p", { style: { color: errorColor, fontSize: "14px", textAlign: "center" } }, "Invalid image type!"), image && /* @__PURE__ */ React9.createElement("div", { style: {
406
+ } }, !image && !error && /* @__PURE__ */ React8.createElement("input", { type: "file", onChange: handleImageChange, style: { display: "none" }, id: "file-input" }), !image && !error && /* @__PURE__ */ React8.createElement("label", { htmlFor: "file-input", style: { color: "#f1f5f9", cursor: "pointer", textAlign: "center" } }, "Upload Image"), error && /* @__PURE__ */ React8.createElement("p", { style: { color: errorColor, fontSize: "14px", textAlign: "center" } }, "Invalid image type!"), image && /* @__PURE__ */ React8.createElement("div", { style: {
482
407
  position: "absolute",
483
408
  top: 0,
484
409
  left: 0,
@@ -490,14 +415,14 @@ var ImageUploadPreview = ({
490
415
  background: "rgba(0,0,0,0.6)",
491
416
  transition: "opacity 0.3s",
492
417
  opacity: 1
493
- } }, /* @__PURE__ */ React9.createElement("img", { src: image, alt: "Preview", style: {
418
+ } }, /* @__PURE__ */ React8.createElement("img", { src: image, alt: "Preview", style: {
494
419
  maxWidth: "100%",
495
420
  maxHeight: "100%",
496
421
  objectFit: "cover",
497
422
  transition: "transform 0.3s",
498
423
  borderRadius,
499
424
  cursor: "zoom-in"
500
- }, onMouseEnter: (e) => e.currentTarget.style.transform = "scale(1.05)", onMouseLeave: (e) => e.currentTarget.style.transform = "scale(1)" })), image && /* @__PURE__ */ React9.createElement("button", { onClick: handleRemove, style: {
425
+ }, onMouseEnter: (e) => e.currentTarget.style.transform = "scale(1.05)", onMouseLeave: (e) => e.currentTarget.style.transform = "scale(1)" })), image && /* @__PURE__ */ React8.createElement("button", { onClick: handleRemove, style: {
501
426
  position: "absolute",
502
427
  top: "10px",
503
428
  right: "10px",
@@ -514,23 +439,23 @@ var ImageUploadPreview = ({
514
439
  };
515
440
 
516
441
  // src/components/CopyButton/CopyButton.jsx
517
- import React10, { useState as useState7 } from "react";
442
+ import React9, { useState as useState6 } from "react";
518
443
  var CopyButton = ({
519
444
  text = "Copy",
520
445
  bg = "#2563eb",
521
446
  color = "white",
522
447
  radius = "8px",
523
- icon = /* @__PURE__ */ React10.createElement("span", { role: "img", "aria-label": "copy" }, "\u{1F4CB}"),
448
+ icon = /* @__PURE__ */ React9.createElement("span", { role: "img", "aria-label": "copy" }, "\u{1F4CB}"),
524
449
  padding = "10px 15px",
525
450
  shadow = "0 4px 14px rgba(37,99,235,0.4)"
526
451
  }) => {
527
- const [copied, setCopied] = useState7(false);
452
+ const [copied, setCopied] = useState6(false);
528
453
  const handleCopy = () => {
529
454
  navigator.clipboard.writeText(text);
530
455
  setCopied(true);
531
456
  setTimeout(() => setCopied(false), 2e3);
532
457
  };
533
- return /* @__PURE__ */ React10.createElement(
458
+ return /* @__PURE__ */ React9.createElement(
534
459
  "button",
535
460
  {
536
461
  onClick: handleCopy,
@@ -555,7 +480,7 @@ var CopyButton = ({
555
480
  };
556
481
 
557
482
  // src/components/Loader/Loader.jsx
558
- import React11, { useEffect as useEffect5, useState as useState8 } from "react";
483
+ import React10, { useEffect as useEffect4, useState as useState7 } from "react";
559
484
  var Loader = ({
560
485
  size = "medium",
561
486
  fullScreen = false,
@@ -564,11 +489,11 @@ var Loader = ({
564
489
  duration = "1s"
565
490
  }) => {
566
491
  const sizes = { small: "40px", medium: "60px", large: "80px" };
567
- const [fadeIn, setFadeIn] = useState8(false);
568
- useEffect5(() => {
492
+ const [fadeIn, setFadeIn] = useState7(false);
493
+ useEffect4(() => {
569
494
  setFadeIn(true);
570
495
  }, []);
571
- return /* @__PURE__ */ React11.createElement(
496
+ return /* @__PURE__ */ React10.createElement(
572
497
  "div",
573
498
  {
574
499
  style: {
@@ -581,7 +506,7 @@ var Loader = ({
581
506
  opacity: fadeIn ? 1 : 0
582
507
  }
583
508
  },
584
- /* @__PURE__ */ React11.createElement(
509
+ /* @__PURE__ */ React10.createElement(
585
510
  "div",
586
511
  {
587
512
  style: {
@@ -594,7 +519,7 @@ var Loader = ({
594
519
  }
595
520
  }
596
521
  ),
597
- /* @__PURE__ */ React11.createElement("style", null, `
522
+ /* @__PURE__ */ React10.createElement("style", null, `
598
523
  @keyframes spin {
599
524
  0% { transform: rotate(0deg); }
600
525
  100% { transform: rotate(360deg); }
@@ -604,7 +529,7 @@ var Loader = ({
604
529
  };
605
530
 
606
531
  // src/components/OTPInput/OTPInput.jsx
607
- import React12, { useEffect as useEffect6, useRef as useRef2, useState as useState9 } from "react";
532
+ import React11, { useEffect as useEffect5, useRef as useRef2, useState as useState8 } from "react";
608
533
  var OTPInput = ({
609
534
  length = 4,
610
535
  bg = "#0f172a",
@@ -618,9 +543,9 @@ var OTPInput = ({
618
543
  error = false,
619
544
  success = false
620
545
  }) => {
621
- const [otp, setOtp] = useState9(Array(length).fill(""));
622
- const inputRefs = useRef2(Array(length).fill().map(() => React12.createRef()));
623
- useEffect6(() => {
546
+ const [otp, setOtp] = useState8(Array(length).fill(""));
547
+ const inputRefs = useRef2(Array(length).fill().map(() => React11.createRef()));
548
+ useEffect5(() => {
624
549
  inputRefs.current[0].current.focus();
625
550
  }, []);
626
551
  const handleChange = (index, value) => {
@@ -650,7 +575,7 @@ var OTPInput = ({
650
575
  onChange(newOtp.join(""));
651
576
  event.preventDefault();
652
577
  };
653
- return /* @__PURE__ */ React12.createElement("div", { style: { display: "flex", justifyContent: "center", gap: "10px" }, onPaste: handlePaste }, otp.map((value, index) => /* @__PURE__ */ React12.createElement(
578
+ return /* @__PURE__ */ React11.createElement("div", { style: { display: "flex", justifyContent: "center", gap: "10px" }, onPaste: handlePaste }, otp.map((value, index) => /* @__PURE__ */ React11.createElement(
654
579
  "input",
655
580
  {
656
581
  key: index,
@@ -677,7 +602,7 @@ var OTPInput = ({
677
602
  };
678
603
 
679
604
  // src/components/RatingStars/RatingStars.jsx
680
- import React13, { useState as useState10 } from "react";
605
+ import React12, { useState as useState9 } from "react";
681
606
  var RatingStars = ({
682
607
  totalStars = 5,
683
608
  selectedColor = "#ffc107",
@@ -685,8 +610,8 @@ var RatingStars = ({
685
610
  size = "24px",
686
611
  onSelect
687
612
  }) => {
688
- const [hovered, setHovered] = useState10(0);
689
- const [selected, setSelected] = useState10(0);
613
+ const [hovered, setHovered] = useState9(0);
614
+ const [selected, setSelected] = useState9(0);
690
615
  const handleMouseEnter = (index) => {
691
616
  setHovered(index + 1);
692
617
  };
@@ -697,7 +622,7 @@ var RatingStars = ({
697
622
  setSelected(index + 1);
698
623
  if (onSelect) onSelect(index + 1);
699
624
  };
700
- return /* @__PURE__ */ React13.createElement("div", { style: { display: "flex", gap: "4px" } }, [...Array(totalStars)].map((_, index) => /* @__PURE__ */ React13.createElement(
625
+ return /* @__PURE__ */ React12.createElement("div", { style: { display: "flex", gap: "4px" } }, [...Array(totalStars)].map((_, index) => /* @__PURE__ */ React12.createElement(
701
626
  "svg",
702
627
  {
703
628
  key: index,
@@ -714,12 +639,12 @@ var RatingStars = ({
714
639
  onClick: () => handleClick(index),
715
640
  style: { transition: "color 0.2s ease" }
716
641
  },
717
- /* @__PURE__ */ React13.createElement("polygon", { points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21 12 17.77 5.82 21 7 14.14 2 9.27 8.91 8.26 12 2" })
642
+ /* @__PURE__ */ React12.createElement("polygon", { points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21 12 17.77 5.82 21 7 14.14 2 9.27 8.91 8.26 12 2" })
718
643
  )));
719
644
  };
720
645
 
721
646
  // src/components/UserAvatar/UserAvatar.jsx
722
- import React14 from "react";
647
+ import React13 from "react";
723
648
  var UserAvatar = ({
724
649
  size = "50px",
725
650
  src = "",
@@ -732,7 +657,7 @@ var UserAvatar = ({
732
657
  statusColor = "#22c55e",
733
658
  borderColor = "#7c3aed"
734
659
  }) => {
735
- return /* @__PURE__ */ React14.createElement(
660
+ return /* @__PURE__ */ React13.createElement(
736
661
  "div",
737
662
  {
738
663
  style: {
@@ -756,17 +681,17 @@ var UserAvatar = ({
756
681
  e.currentTarget.style.transform = "scale(1)";
757
682
  }
758
683
  },
759
- src ? /* @__PURE__ */ React14.createElement("img", { src, alt: initials, style: {
684
+ src ? /* @__PURE__ */ React13.createElement("img", { src, alt: initials, style: {
760
685
  width: "100%",
761
686
  height: "100%",
762
687
  borderRadius: "50%",
763
688
  objectFit: "cover"
764
- } }) : /* @__PURE__ */ React14.createElement("span", { style: {
689
+ } }) : /* @__PURE__ */ React13.createElement("span", { style: {
765
690
  color: textColor,
766
691
  fontSize: "20px",
767
692
  fontWeight: "700"
768
693
  } }, initials),
769
- showStatus && /* @__PURE__ */ React14.createElement("span", { style: {
694
+ showStatus && /* @__PURE__ */ React13.createElement("span", { style: {
770
695
  position: "absolute",
771
696
  bottom: "0",
772
697
  right: "0",
@@ -778,6 +703,115 @@ var UserAvatar = ({
778
703
  } })
779
704
  );
780
705
  };
706
+
707
+ // src/components/Navbar/Navbar.jsx
708
+ import React14, { useState as useState10, useEffect as useEffect6 } from "react";
709
+ var Navbar = ({
710
+ logo = "https://via.placeholder.com/150",
711
+ links = [{ name: "Home", href: "#" }, { name: "About", href: "#" }, { name: "Services", href: "#" }, { name: "Contact", href: "#" }],
712
+ bgColor = "#0f172a",
713
+ textColor = "#f1f5f9",
714
+ linkColor = "#7c3aed",
715
+ hoverColor = "#818cf8",
716
+ sticky = false,
717
+ radius = "8px"
718
+ }) => {
719
+ const [scrolled, setScrolled] = useState10(false);
720
+ const [isOpen, setIsOpen] = useState10(false);
721
+ useEffect6(() => {
722
+ const handleScroll = () => {
723
+ setScrolled(window.scrollY > 50);
724
+ };
725
+ window.addEventListener("scroll", handleScroll);
726
+ return () => window.removeEventListener("scroll", handleScroll);
727
+ }, []);
728
+ return /* @__PURE__ */ React14.createElement("nav", { style: {
729
+ position: sticky || scrolled ? "sticky" : "relative",
730
+ top: 0,
731
+ background: bgColor,
732
+ padding: "10px 20px",
733
+ borderRadius: radius,
734
+ boxShadow: scrolled ? "0 4px 10px rgba(0,0,0,0.2)" : "none",
735
+ display: "flex",
736
+ justifyContent: "space-between",
737
+ alignItems: "center",
738
+ transition: "box-shadow 0.3s ease"
739
+ } }, /* @__PURE__ */ React14.createElement("img", { src: logo, alt: "Logo", style: { width: "120px" } }), /* @__PURE__ */ React14.createElement("div", { style: { display: "none", gap: "20px", fontFamily: "system-ui, sans-serif", color: textColor, fontSize: "16px", cursor: "pointer" }, id: "nav-links" }, links.map((link) => /* @__PURE__ */ React14.createElement("a", { key: link.name, href: link.href, style: {
740
+ color: textColor,
741
+ textDecoration: "none",
742
+ position: "relative"
743
+ }, onMouseEnter: (e) => e.target.style.color = hoverColor, onMouseLeave: (e) => e.target.style.color = textColor }, link.name, /* @__PURE__ */ React14.createElement("span", { style: {
744
+ position: "absolute",
745
+ width: "100%",
746
+ height: "2px",
747
+ background: hoverColor,
748
+ bottom: "-4px",
749
+ left: 0,
750
+ transform: "scaleX(0)",
751
+ transition: "transform 0.3s ease"
752
+ }, className: "underline" })))), /* @__PURE__ */ React14.createElement("div", { style: { display: "flex", alignItems: "center" } }, /* @__PURE__ */ React14.createElement("button", { onClick: () => setIsOpen(true), style: {
753
+ background: "transparent",
754
+ border: "none",
755
+ color: textColor,
756
+ cursor: "pointer",
757
+ fontSize: "16px"
758
+ } }, "\u2630")), isOpen && /* @__PURE__ */ React14.createElement("div", { style: {
759
+ position: "fixed",
760
+ top: 0,
761
+ right: 0,
762
+ width: "250px",
763
+ height: "100%",
764
+ background: bgColor,
765
+ transform: isOpen ? "translateX(0)" : "translateX(100%)",
766
+ transition: "transform 0.3s ease",
767
+ padding: "20px",
768
+ boxShadow: "-3px 0 10px rgba(0,0,0,0.5)",
769
+ zIndex: 1e3
770
+ } }, /* @__PURE__ */ React14.createElement("button", { onClick: () => setIsOpen(false), style: {
771
+ color: textColor,
772
+ background: "none",
773
+ border: "none",
774
+ fontSize: "24px",
775
+ cursor: "pointer"
776
+ } }, "\u2716"), /* @__PURE__ */ React14.createElement("div", { style: { marginTop: "30px" } }, links.map((link) => /* @__PURE__ */ React14.createElement("a", { key: link.name, href: link.href, style: {
777
+ display: "block",
778
+ color: textColor,
779
+ textDecoration: "none",
780
+ margin: "15px 0"
781
+ } }, link.name)))));
782
+ };
783
+
784
+ // src/components/WishlistButton/WishlistButton.jsx
785
+ import React15, { useState as useState11 } from "react";
786
+ var WishlistButton = ({
787
+ isActive = false,
788
+ size = "40px",
789
+ inactiveColor = "#d1d5db",
790
+ activeColor = "#ff3e30",
791
+ onToggle
792
+ }) => {
793
+ const [active, setActive] = useState11(isActive);
794
+ const handleClick = () => {
795
+ setActive((prev) => !prev);
796
+ if (onToggle) onToggle(!active);
797
+ };
798
+ return /* @__PURE__ */ React15.createElement("div", { onClick: handleClick, style: { cursor: "pointer", width: size, height: size, display: "flex", alignItems: "center", justifyContent: "center" } }, /* @__PURE__ */ React15.createElement(
799
+ "svg",
800
+ {
801
+ width: "100%",
802
+ height: "100%",
803
+ viewBox: "0 0 24 24",
804
+ fill: "none",
805
+ xmlns: "http://www.w3.org/2000/svg",
806
+ style: {
807
+ transition: "transform 0.2s",
808
+ transform: active ? "scale(1.2)" : "scale(1)",
809
+ fill: active ? activeColor : inactiveColor
810
+ }
811
+ },
812
+ /* @__PURE__ */ React15.createElement("path", { d: "M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" })
813
+ ));
814
+ };
781
815
  export {
782
816
  AlertBanner,
783
817
  Button,
@@ -792,5 +826,6 @@ export {
792
826
  Navbar,
793
827
  OTPInput,
794
828
  RatingStars,
795
- UserAvatar
829
+ UserAvatar,
830
+ WishlistButton
796
831
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "virtual-ui-lib",
3
- "version": "1.0.26",
3
+ "version": "1.0.28",
4
4
  "description": "Virtual UI React Component Library",
5
5
  "author": "Ankush",
6
6
  "license": "ISC",