virtual-ui-lib 1.0.25 → 1.0.27

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 +169 -104
  2. package/dist/index.mjs +167 -103
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -41,7 +41,8 @@ __export(index_exports, {
41
41
  Loader: () => Loader,
42
42
  Navbar: () => Navbar,
43
43
  OTPInput: () => OTPInput,
44
- RatingStars: () => RatingStars
44
+ RatingStars: () => RatingStars,
45
+ UserAvatar: () => UserAvatar
45
46
  });
46
47
  module.exports = __toCommonJS(index_exports);
47
48
 
@@ -406,83 +407,8 @@ var GridLayout = ({
406
407
  return /* @__PURE__ */ import_react7.default.createElement("div", { style: { display: "grid", gridTemplateColumns: `repeat(${cols}, 1fr)`, gap: spacing } }, items.map(renderItem));
407
408
  };
408
409
 
409
- // src/components/Navbar/Navbar.jsx
410
- var import_react8 = __toESM(require("react"));
411
- var Navbar = ({
412
- logo = "Logo",
413
- links = [{ name: "Home", href: "#" }, { name: "About", href: "#" }, { name: "Services", href: "#" }, { name: "Contact", href: "#" }],
414
- bgColor = "#0f172a",
415
- linkColor = "#f1f5f9",
416
- hoverColor = "#7c3aed",
417
- stickyColor = "#1e293b",
418
- radius = "8px"
419
- }) => {
420
- const [isMobileMenuOpen, setMobileMenuOpen] = (0, import_react8.useState)(false);
421
- const [isSticky, setSticky] = (0, import_react8.useState)(false);
422
- (0, import_react8.useEffect)(() => {
423
- const handleScroll = () => {
424
- setSticky(window.scrollY > 50);
425
- };
426
- window.addEventListener("scroll", handleScroll);
427
- return () => window.removeEventListener("scroll", handleScroll);
428
- }, []);
429
- return /* @__PURE__ */ import_react8.default.createElement("nav", { style: {
430
- background: isSticky ? stickyColor : bgColor,
431
- position: isSticky ? "fixed" : "relative",
432
- width: "100%",
433
- padding: "10px 20px",
434
- boxShadow: isSticky ? "0 2px 10px rgba(0,0,0,0.2)" : "none",
435
- transition: "background 0.3s ease"
436
- } }, /* @__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: {
437
- textDecoration: "none",
438
- color: linkColor,
439
- position: "relative",
440
- fontSize: "16px",
441
- transition: "color 0.3s"
442
- }, onMouseOver: (e) => e.currentTarget.style.color = hoverColor, onMouseOut: (e) => e.currentTarget.style.color = linkColor }, link.name, /* @__PURE__ */ import_react8.default.createElement("span", { style: {
443
- position: "absolute",
444
- bottom: "-3px",
445
- left: 0,
446
- width: "100%",
447
- height: "2px",
448
- background: hoverColor,
449
- transform: "scaleX(0)",
450
- transition: "transform 0.3s ease"
451
- }, className: "underline" }))))), /* @__PURE__ */ import_react8.default.createElement("button", { onClick: () => setMobileMenuOpen(true), style: {
452
- background: "transparent",
453
- color: linkColor,
454
- border: "none",
455
- cursor: "pointer",
456
- fontSize: "16px",
457
- marginLeft: "20px"
458
- } }, "\u2630"))), isMobileMenuOpen && /* @__PURE__ */ import_react8.default.createElement("div", { style: {
459
- position: "fixed",
460
- top: 0,
461
- right: 0,
462
- width: "250px",
463
- height: "100%",
464
- background: bgColor,
465
- boxShadow: "-4px 0 10px rgba(0,0,0,0.5)",
466
- padding: "20px",
467
- transform: "translateX(0)",
468
- transition: "transform 0.3s ease"
469
- } }, /* @__PURE__ */ import_react8.default.createElement("button", { onClick: () => setMobileMenuOpen(false), style: {
470
- background: "transparent",
471
- color: linkColor,
472
- border: "none",
473
- cursor: "pointer",
474
- fontSize: "16px",
475
- marginBottom: "20px"
476
- } }, "\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: {
477
- textDecoration: "none",
478
- color: linkColor,
479
- fontSize: "18px",
480
- transition: "color 0.3s"
481
- }, onMouseOver: (e) => e.currentTarget.style.color = hoverColor, onMouseOut: (e) => e.currentTarget.style.color = linkColor }, link.name))))));
482
- };
483
-
484
410
  // src/components/ImageUploadPreview/ImageUploadPreview.jsx
485
- var import_react9 = __toESM(require("react"));
411
+ var import_react8 = __toESM(require("react"));
486
412
  var ImageUploadPreview = ({
487
413
  width = "300px",
488
414
  height = "200px",
@@ -492,8 +418,8 @@ var ImageUploadPreview = ({
492
418
  borderRadius = "12px",
493
419
  onImageChange
494
420
  }) => {
495
- const [image, setImage] = (0, import_react9.useState)(null);
496
- const [error, setError] = (0, import_react9.useState)(false);
421
+ const [image, setImage] = (0, import_react8.useState)(null);
422
+ const [error, setError] = (0, import_react8.useState)(false);
497
423
  const handleImageChange = (e) => {
498
424
  const file = e.target.files[0];
499
425
  const validTypes = ["image/png", "image/jpeg", "image/jpg"];
@@ -513,7 +439,7 @@ var ImageUploadPreview = ({
513
439
  setImage(null);
514
440
  setError(false);
515
441
  };
516
- return /* @__PURE__ */ import_react9.default.createElement("div", { style: {
442
+ return /* @__PURE__ */ import_react8.default.createElement("div", { style: {
517
443
  display: "flex",
518
444
  justifyContent: "center",
519
445
  alignItems: "center",
@@ -525,7 +451,7 @@ var ImageUploadPreview = ({
525
451
  position: "relative",
526
452
  overflow: "hidden",
527
453
  transition: "border-color 0.3s"
528
- } }, !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: {
454
+ } }, !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: {
529
455
  position: "absolute",
530
456
  top: 0,
531
457
  left: 0,
@@ -537,14 +463,14 @@ var ImageUploadPreview = ({
537
463
  background: "rgba(0,0,0,0.6)",
538
464
  transition: "opacity 0.3s",
539
465
  opacity: 1
540
- } }, /* @__PURE__ */ import_react9.default.createElement("img", { src: image, alt: "Preview", style: {
466
+ } }, /* @__PURE__ */ import_react8.default.createElement("img", { src: image, alt: "Preview", style: {
541
467
  maxWidth: "100%",
542
468
  maxHeight: "100%",
543
469
  objectFit: "cover",
544
470
  transition: "transform 0.3s",
545
471
  borderRadius,
546
472
  cursor: "zoom-in"
547
- }, 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: {
473
+ }, 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: {
548
474
  position: "absolute",
549
475
  top: "10px",
550
476
  right: "10px",
@@ -561,23 +487,23 @@ var ImageUploadPreview = ({
561
487
  };
562
488
 
563
489
  // src/components/CopyButton/CopyButton.jsx
564
- var import_react10 = __toESM(require("react"));
490
+ var import_react9 = __toESM(require("react"));
565
491
  var CopyButton = ({
566
492
  text = "Copy",
567
493
  bg = "#2563eb",
568
494
  color = "white",
569
495
  radius = "8px",
570
- icon = /* @__PURE__ */ import_react10.default.createElement("span", { role: "img", "aria-label": "copy" }, "\u{1F4CB}"),
496
+ icon = /* @__PURE__ */ import_react9.default.createElement("span", { role: "img", "aria-label": "copy" }, "\u{1F4CB}"),
571
497
  padding = "10px 15px",
572
498
  shadow = "0 4px 14px rgba(37,99,235,0.4)"
573
499
  }) => {
574
- const [copied, setCopied] = (0, import_react10.useState)(false);
500
+ const [copied, setCopied] = (0, import_react9.useState)(false);
575
501
  const handleCopy = () => {
576
502
  navigator.clipboard.writeText(text);
577
503
  setCopied(true);
578
504
  setTimeout(() => setCopied(false), 2e3);
579
505
  };
580
- return /* @__PURE__ */ import_react10.default.createElement(
506
+ return /* @__PURE__ */ import_react9.default.createElement(
581
507
  "button",
582
508
  {
583
509
  onClick: handleCopy,
@@ -602,7 +528,7 @@ var CopyButton = ({
602
528
  };
603
529
 
604
530
  // src/components/Loader/Loader.jsx
605
- var import_react11 = __toESM(require("react"));
531
+ var import_react10 = __toESM(require("react"));
606
532
  var Loader = ({
607
533
  size = "medium",
608
534
  fullScreen = false,
@@ -611,11 +537,11 @@ var Loader = ({
611
537
  duration = "1s"
612
538
  }) => {
613
539
  const sizes = { small: "40px", medium: "60px", large: "80px" };
614
- const [fadeIn, setFadeIn] = (0, import_react11.useState)(false);
615
- (0, import_react11.useEffect)(() => {
540
+ const [fadeIn, setFadeIn] = (0, import_react10.useState)(false);
541
+ (0, import_react10.useEffect)(() => {
616
542
  setFadeIn(true);
617
543
  }, []);
618
- return /* @__PURE__ */ import_react11.default.createElement(
544
+ return /* @__PURE__ */ import_react10.default.createElement(
619
545
  "div",
620
546
  {
621
547
  style: {
@@ -628,7 +554,7 @@ var Loader = ({
628
554
  opacity: fadeIn ? 1 : 0
629
555
  }
630
556
  },
631
- /* @__PURE__ */ import_react11.default.createElement(
557
+ /* @__PURE__ */ import_react10.default.createElement(
632
558
  "div",
633
559
  {
634
560
  style: {
@@ -641,7 +567,7 @@ var Loader = ({
641
567
  }
642
568
  }
643
569
  ),
644
- /* @__PURE__ */ import_react11.default.createElement("style", null, `
570
+ /* @__PURE__ */ import_react10.default.createElement("style", null, `
645
571
  @keyframes spin {
646
572
  0% { transform: rotate(0deg); }
647
573
  100% { transform: rotate(360deg); }
@@ -651,7 +577,7 @@ var Loader = ({
651
577
  };
652
578
 
653
579
  // src/components/OTPInput/OTPInput.jsx
654
- var import_react12 = __toESM(require("react"));
580
+ var import_react11 = __toESM(require("react"));
655
581
  var OTPInput = ({
656
582
  length = 4,
657
583
  bg = "#0f172a",
@@ -665,9 +591,9 @@ var OTPInput = ({
665
591
  error = false,
666
592
  success = false
667
593
  }) => {
668
- const [otp, setOtp] = (0, import_react12.useState)(Array(length).fill(""));
669
- const inputRefs = (0, import_react12.useRef)(Array(length).fill().map(() => import_react12.default.createRef()));
670
- (0, import_react12.useEffect)(() => {
594
+ const [otp, setOtp] = (0, import_react11.useState)(Array(length).fill(""));
595
+ const inputRefs = (0, import_react11.useRef)(Array(length).fill().map(() => import_react11.default.createRef()));
596
+ (0, import_react11.useEffect)(() => {
671
597
  inputRefs.current[0].current.focus();
672
598
  }, []);
673
599
  const handleChange = (index, value) => {
@@ -697,7 +623,7 @@ var OTPInput = ({
697
623
  onChange(newOtp.join(""));
698
624
  event.preventDefault();
699
625
  };
700
- 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(
626
+ 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(
701
627
  "input",
702
628
  {
703
629
  key: index,
@@ -724,7 +650,7 @@ var OTPInput = ({
724
650
  };
725
651
 
726
652
  // src/components/RatingStars/RatingStars.jsx
727
- var import_react13 = __toESM(require("react"));
653
+ var import_react12 = __toESM(require("react"));
728
654
  var RatingStars = ({
729
655
  totalStars = 5,
730
656
  selectedColor = "#ffc107",
@@ -732,8 +658,8 @@ var RatingStars = ({
732
658
  size = "24px",
733
659
  onSelect
734
660
  }) => {
735
- const [hovered, setHovered] = (0, import_react13.useState)(0);
736
- const [selected, setSelected] = (0, import_react13.useState)(0);
661
+ const [hovered, setHovered] = (0, import_react12.useState)(0);
662
+ const [selected, setSelected] = (0, import_react12.useState)(0);
737
663
  const handleMouseEnter = (index) => {
738
664
  setHovered(index + 1);
739
665
  };
@@ -744,7 +670,7 @@ var RatingStars = ({
744
670
  setSelected(index + 1);
745
671
  if (onSelect) onSelect(index + 1);
746
672
  };
747
- return /* @__PURE__ */ import_react13.default.createElement("div", { style: { display: "flex", gap: "4px" } }, [...Array(totalStars)].map((_, index) => /* @__PURE__ */ import_react13.default.createElement(
673
+ return /* @__PURE__ */ import_react12.default.createElement("div", { style: { display: "flex", gap: "4px" } }, [...Array(totalStars)].map((_, index) => /* @__PURE__ */ import_react12.default.createElement(
748
674
  "svg",
749
675
  {
750
676
  key: index,
@@ -761,9 +687,147 @@ var RatingStars = ({
761
687
  onClick: () => handleClick(index),
762
688
  style: { transition: "color 0.2s ease" }
763
689
  },
764
- /* @__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" })
690
+ /* @__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" })
765
691
  )));
766
692
  };
693
+
694
+ // src/components/UserAvatar/UserAvatar.jsx
695
+ var import_react13 = __toESM(require("react"));
696
+ var UserAvatar = ({
697
+ size = "50px",
698
+ src = "",
699
+ initials = "AB",
700
+ online = false,
701
+ busy = false,
702
+ showStatus = true,
703
+ bgColor = "#1e293b",
704
+ textColor = "#f1f5f9",
705
+ statusColor = "#22c55e",
706
+ borderColor = "#7c3aed"
707
+ }) => {
708
+ return /* @__PURE__ */ import_react13.default.createElement(
709
+ "div",
710
+ {
711
+ style: {
712
+ position: "relative",
713
+ width: size,
714
+ height: size,
715
+ borderRadius: "50%",
716
+ backgroundColor: bgColor,
717
+ display: "flex",
718
+ alignItems: "center",
719
+ justifyContent: "center",
720
+ transition: "transform 0.2s",
721
+ cursor: "pointer",
722
+ overflow: "hidden",
723
+ boxShadow: "0 4px 14px rgba(0, 0, 0, 0.2)"
724
+ },
725
+ onMouseEnter: (e) => {
726
+ e.currentTarget.style.transform = "scale(1.1)";
727
+ },
728
+ onMouseLeave: (e) => {
729
+ e.currentTarget.style.transform = "scale(1)";
730
+ }
731
+ },
732
+ src ? /* @__PURE__ */ import_react13.default.createElement("img", { src, alt: initials, style: {
733
+ width: "100%",
734
+ height: "100%",
735
+ borderRadius: "50%",
736
+ objectFit: "cover"
737
+ } }) : /* @__PURE__ */ import_react13.default.createElement("span", { style: {
738
+ color: textColor,
739
+ fontSize: "20px",
740
+ fontWeight: "700"
741
+ } }, initials),
742
+ showStatus && /* @__PURE__ */ import_react13.default.createElement("span", { style: {
743
+ position: "absolute",
744
+ bottom: "0",
745
+ right: "0",
746
+ width: "12px",
747
+ height: "12px",
748
+ borderRadius: "50%",
749
+ backgroundColor: busy ? "#fbbf24" : online ? statusColor : "#9ca3af",
750
+ border: "2px solid " + borderColor
751
+ } })
752
+ );
753
+ };
754
+
755
+ // src/components/Navbar/Navbar.jsx
756
+ var import_react14 = __toESM(require("react"));
757
+ var Navbar = ({
758
+ logo = "https://via.placeholder.com/150",
759
+ links = [{ name: "Home", href: "#" }, { name: "About", href: "#" }, { name: "Services", href: "#" }, { name: "Contact", href: "#" }],
760
+ bgColor = "#0f172a",
761
+ textColor = "#f1f5f9",
762
+ linkColor = "#7c3aed",
763
+ hoverColor = "#818cf8",
764
+ sticky = false,
765
+ radius = "8px"
766
+ }) => {
767
+ const [scrolled, setScrolled] = (0, import_react14.useState)(false);
768
+ const [isOpen, setIsOpen] = (0, import_react14.useState)(false);
769
+ (0, import_react14.useEffect)(() => {
770
+ const handleScroll = () => {
771
+ setScrolled(window.scrollY > 50);
772
+ };
773
+ window.addEventListener("scroll", handleScroll);
774
+ return () => window.removeEventListener("scroll", handleScroll);
775
+ }, []);
776
+ return /* @__PURE__ */ import_react14.default.createElement("nav", { style: {
777
+ position: sticky || scrolled ? "sticky" : "relative",
778
+ top: 0,
779
+ background: bgColor,
780
+ padding: "10px 20px",
781
+ borderRadius: radius,
782
+ boxShadow: scrolled ? "0 4px 10px rgba(0,0,0,0.2)" : "none",
783
+ display: "flex",
784
+ justifyContent: "space-between",
785
+ alignItems: "center",
786
+ transition: "box-shadow 0.3s ease"
787
+ } }, /* @__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: {
788
+ color: textColor,
789
+ textDecoration: "none",
790
+ position: "relative"
791
+ }, onMouseEnter: (e) => e.target.style.color = hoverColor, onMouseLeave: (e) => e.target.style.color = textColor }, link.name, /* @__PURE__ */ import_react14.default.createElement("span", { style: {
792
+ position: "absolute",
793
+ width: "100%",
794
+ height: "2px",
795
+ background: hoverColor,
796
+ bottom: "-4px",
797
+ left: 0,
798
+ transform: "scaleX(0)",
799
+ transition: "transform 0.3s ease"
800
+ }, className: "underline" })))), /* @__PURE__ */ import_react14.default.createElement("div", { style: { display: "flex", alignItems: "center" } }, /* @__PURE__ */ import_react14.default.createElement("button", { onClick: () => setIsOpen(true), style: {
801
+ background: "transparent",
802
+ border: "none",
803
+ color: textColor,
804
+ cursor: "pointer",
805
+ fontSize: "16px"
806
+ } }, "\u2630")), isOpen && /* @__PURE__ */ import_react14.default.createElement("div", { style: {
807
+ position: "fixed",
808
+ top: 0,
809
+ right: 0,
810
+ width: "250px",
811
+ height: "100%",
812
+ background: bgColor,
813
+ transform: isOpen ? "translateX(0)" : "translateX(100%)",
814
+ transition: "transform 0.3s ease",
815
+ padding: "20px",
816
+ boxShadow: "-3px 0 10px rgba(0,0,0,0.5)",
817
+ zIndex: 1e3
818
+ } }, /* @__PURE__ */ import_react14.default.createElement("button", { onClick: () => setIsOpen(false), style: {
819
+ color: textColor,
820
+ background: "none",
821
+ border: "none",
822
+ fontSize: "24px",
823
+ cursor: "pointer"
824
+ } }, "\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: {
825
+ display: "block",
826
+ color: textColor,
827
+ textDecoration: "none",
828
+ margin: "15px 0"
829
+ } }, link.name)))));
830
+ };
767
831
  // Annotate the CommonJS export names for ESM import in node:
768
832
  0 && (module.exports = {
769
833
  AlertBanner,
@@ -778,5 +842,6 @@ var RatingStars = ({
778
842
  Loader,
779
843
  Navbar,
780
844
  OTPInput,
781
- RatingStars
845
+ RatingStars,
846
+ UserAvatar
782
847
  });
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,9 +639,147 @@ 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
  };
645
+
646
+ // src/components/UserAvatar/UserAvatar.jsx
647
+ import React13 from "react";
648
+ var UserAvatar = ({
649
+ size = "50px",
650
+ src = "",
651
+ initials = "AB",
652
+ online = false,
653
+ busy = false,
654
+ showStatus = true,
655
+ bgColor = "#1e293b",
656
+ textColor = "#f1f5f9",
657
+ statusColor = "#22c55e",
658
+ borderColor = "#7c3aed"
659
+ }) => {
660
+ return /* @__PURE__ */ React13.createElement(
661
+ "div",
662
+ {
663
+ style: {
664
+ position: "relative",
665
+ width: size,
666
+ height: size,
667
+ borderRadius: "50%",
668
+ backgroundColor: bgColor,
669
+ display: "flex",
670
+ alignItems: "center",
671
+ justifyContent: "center",
672
+ transition: "transform 0.2s",
673
+ cursor: "pointer",
674
+ overflow: "hidden",
675
+ boxShadow: "0 4px 14px rgba(0, 0, 0, 0.2)"
676
+ },
677
+ onMouseEnter: (e) => {
678
+ e.currentTarget.style.transform = "scale(1.1)";
679
+ },
680
+ onMouseLeave: (e) => {
681
+ e.currentTarget.style.transform = "scale(1)";
682
+ }
683
+ },
684
+ src ? /* @__PURE__ */ React13.createElement("img", { src, alt: initials, style: {
685
+ width: "100%",
686
+ height: "100%",
687
+ borderRadius: "50%",
688
+ objectFit: "cover"
689
+ } }) : /* @__PURE__ */ React13.createElement("span", { style: {
690
+ color: textColor,
691
+ fontSize: "20px",
692
+ fontWeight: "700"
693
+ } }, initials),
694
+ showStatus && /* @__PURE__ */ React13.createElement("span", { style: {
695
+ position: "absolute",
696
+ bottom: "0",
697
+ right: "0",
698
+ width: "12px",
699
+ height: "12px",
700
+ borderRadius: "50%",
701
+ backgroundColor: busy ? "#fbbf24" : online ? statusColor : "#9ca3af",
702
+ border: "2px solid " + borderColor
703
+ } })
704
+ );
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
+ };
720
783
  export {
721
784
  AlertBanner,
722
785
  Button,
@@ -730,5 +793,6 @@ export {
730
793
  Loader,
731
794
  Navbar,
732
795
  OTPInput,
733
- RatingStars
796
+ RatingStars,
797
+ UserAvatar
734
798
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "virtual-ui-lib",
3
- "version": "1.0.25",
3
+ "version": "1.0.27",
4
4
  "description": "Virtual UI React Component Library",
5
5
  "author": "Ankush",
6
6
  "license": "ISC",