virtual-ui-lib 1.0.58 → 1.0.60

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.js CHANGED
@@ -37,6 +37,7 @@ __export(index_exports, {
37
37
  FileUpload: () => FileUpload,
38
38
  Loader: () => Loader,
39
39
  LoadingSpinner: () => LoadingSpinner,
40
+ Navbar: () => Navbar,
40
41
  NotificationToast: () => NotificationToast,
41
42
  OtpInput: () => OtpInput,
42
43
  PricingCard: () => PricingCard,
@@ -623,8 +624,111 @@ var FileUpload = ({ bg = "#1e293b", textColor = "#f1f5f9", accent = "#7c3aed", r
623
624
 
624
625
  // src/components/Loader/Loader.jsx
625
626
  var import_react13 = __toESM(require("react"));
626
- var Loader = ({ bg = "#0f172a", accent = "#7c3aed", size = "40px", borderRadius = "8px" }) => {
627
- return /* @__PURE__ */ import_react13.default.createElement("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", background: bg, height: size, width: size, borderRadius } }, /* @__PURE__ */ import_react13.default.createElement("div", { style: { border: `4px solid ${bg}`, borderTop: `4px solid ${accent}`, borderRadius: "50%", width: "100%", height: "100%", animation: "spin 1s linear infinite" } }));
627
+ var Loader = ({
628
+ type = "spinner",
629
+ size = 48,
630
+ accent = "#6366f1",
631
+ bg = "transparent",
632
+ label = "",
633
+ speed = 1
634
+ }) => {
635
+ const [dots, setDots] = (0, import_react13.useState)(0);
636
+ const [progress, setProgress] = (0, import_react13.useState)(0);
637
+ const alpha = (hex, op) => {
638
+ const r = parseInt(hex.slice(1, 3), 16);
639
+ const g = parseInt(hex.slice(3, 5), 16);
640
+ const b = parseInt(hex.slice(5, 7), 16);
641
+ return `rgba(${r},${g},${b},${op})`;
642
+ };
643
+ (0, import_react13.useEffect)(() => {
644
+ if (type === "dots") {
645
+ const t = setInterval(() => setDots((d) => (d + 1) % 4), 400 / speed);
646
+ return () => clearInterval(t);
647
+ }
648
+ if (type === "bar") {
649
+ const t = setInterval(() => setProgress((p) => p >= 100 ? 0 : p + 2), 30 / speed);
650
+ return () => clearInterval(t);
651
+ }
652
+ }, [type, speed]);
653
+ const dur = `${1 / speed}s`;
654
+ const wrapStyle = {
655
+ display: "inline-flex",
656
+ flexDirection: "column",
657
+ alignItems: "center",
658
+ justifyContent: "center",
659
+ gap: "12px",
660
+ background: bg,
661
+ padding: bg !== "transparent" ? "24px" : "0",
662
+ borderRadius: "16px",
663
+ fontFamily: "system-ui, sans-serif"
664
+ };
665
+ const labelEl = label ? /* @__PURE__ */ import_react13.default.createElement("span", { style: { fontSize: "13px", color: "rgba(255,255,255,0.45)", letterSpacing: "0.3px" } }, label) : null;
666
+ if (type === "spinner") return /* @__PURE__ */ import_react13.default.createElement("div", { style: wrapStyle }, /* @__PURE__ */ import_react13.default.createElement("svg", { width: size, height: size, viewBox: "0 0 48 48" }, /* @__PURE__ */ import_react13.default.createElement(
667
+ "circle",
668
+ {
669
+ cx: "24",
670
+ cy: "24",
671
+ r: "20",
672
+ fill: "none",
673
+ stroke: alpha(accent, 0.15),
674
+ strokeWidth: "4"
675
+ }
676
+ ), /* @__PURE__ */ import_react13.default.createElement(
677
+ "circle",
678
+ {
679
+ cx: "24",
680
+ cy: "24",
681
+ r: "20",
682
+ fill: "none",
683
+ stroke: accent,
684
+ strokeWidth: "4",
685
+ strokeLinecap: "round",
686
+ strokeDasharray: "31.4 94.2",
687
+ style: { transformOrigin: "center", animation: `spin ${dur} linear infinite` }
688
+ }
689
+ ), /* @__PURE__ */ import_react13.default.createElement("style", null, `@keyframes spin { to { transform: rotate(360deg); } }`)), labelEl);
690
+ if (type === "pulse") return /* @__PURE__ */ import_react13.default.createElement("div", { style: wrapStyle }, /* @__PURE__ */ import_react13.default.createElement("div", { style: { position: "relative", width: size, height: size } }, /* @__PURE__ */ import_react13.default.createElement("div", { style: {
691
+ position: "absolute",
692
+ inset: 0,
693
+ borderRadius: "50%",
694
+ background: alpha(accent, 0.2),
695
+ animation: `pulse ${dur} ease-out infinite`
696
+ } }), /* @__PURE__ */ import_react13.default.createElement("div", { style: {
697
+ position: "absolute",
698
+ inset: "25%",
699
+ borderRadius: "50%",
700
+ background: accent
701
+ } }), /* @__PURE__ */ import_react13.default.createElement("style", null, `@keyframes pulse { 0%{transform:scale(1);opacity:1} 100%{transform:scale(2);opacity:0} }`)), labelEl);
702
+ if (type === "dots") return /* @__PURE__ */ import_react13.default.createElement("div", { style: wrapStyle }, /* @__PURE__ */ import_react13.default.createElement("div", { style: { display: "flex", gap: "8px", alignItems: "center" } }, [0, 1, 2].map((i) => /* @__PURE__ */ import_react13.default.createElement("div", { key: i, style: {
703
+ width: size / 5,
704
+ height: size / 5,
705
+ borderRadius: "50%",
706
+ background: dots === i ? accent : alpha(accent, 0.25),
707
+ transition: "background 0.2s"
708
+ } }))), labelEl);
709
+ if (type === "bar") return /* @__PURE__ */ import_react13.default.createElement("div", { style: wrapStyle }, /* @__PURE__ */ import_react13.default.createElement("div", { style: {
710
+ width: size * 3,
711
+ height: size / 8,
712
+ background: alpha(accent, 0.15),
713
+ borderRadius: "99px",
714
+ overflow: "hidden"
715
+ } }, /* @__PURE__ */ import_react13.default.createElement("div", { style: {
716
+ height: "100%",
717
+ borderRadius: "99px",
718
+ background: accent,
719
+ width: `${progress}%`,
720
+ transition: "width 0.03s linear"
721
+ } })), labelEl);
722
+ if (type === "ring") return /* @__PURE__ */ import_react13.default.createElement("div", { style: wrapStyle }, /* @__PURE__ */ import_react13.default.createElement("div", { style: {
723
+ width: size,
724
+ height: size,
725
+ borderRadius: "50%",
726
+ border: `4px solid ${alpha(accent, 0.15)}`,
727
+ borderTop: `4px solid ${accent}`,
728
+ borderRight: `4px solid ${accent}`,
729
+ animation: `spin ${dur} linear infinite`
730
+ } }), /* @__PURE__ */ import_react13.default.createElement("style", null, `@keyframes spin { to { transform: rotate(360deg); } }`), labelEl);
731
+ return null;
628
732
  };
629
733
 
630
734
  // src/components/Avatar/Avatar.jsx
@@ -1012,6 +1116,255 @@ var PricingCard = ({
1012
1116
  ctaText
1013
1117
  ));
1014
1118
  };
1119
+
1120
+ // src/components/Navbar/Navbar.jsx
1121
+ var import_react20 = __toESM(require("react"));
1122
+ var Navbar = ({
1123
+ logo = "VirtualAI",
1124
+ links = ["Home", "Features", "Pricing", "Blog"],
1125
+ ctaText = "Get Started",
1126
+ accent = "#6366f1",
1127
+ bg = "#0f172a",
1128
+ onCtaClick = () => {
1129
+ },
1130
+ onLinkClick = () => {
1131
+ }
1132
+ }) => {
1133
+ const [scrolled, setScrolled] = (0, import_react20.useState)(false);
1134
+ const [menuOpen, setMenuOpen] = (0, import_react20.useState)(false);
1135
+ const [active, setActive] = (0, import_react20.useState)("Home");
1136
+ const [isMobile, setIsMobile] = (0, import_react20.useState)(false);
1137
+ const alpha = (hex, op) => {
1138
+ const r = parseInt(hex.slice(1, 3), 16);
1139
+ const g = parseInt(hex.slice(3, 5), 16);
1140
+ const b = parseInt(hex.slice(5, 7), 16);
1141
+ return `rgba(${r},${g},${b},${op})`;
1142
+ };
1143
+ (0, import_react20.useEffect)(() => {
1144
+ const checkMobile = () => setIsMobile(window.innerWidth < 768);
1145
+ checkMobile();
1146
+ window.addEventListener("resize", checkMobile);
1147
+ return () => window.removeEventListener("resize", checkMobile);
1148
+ }, []);
1149
+ (0, import_react20.useEffect)(() => {
1150
+ const handler = () => setScrolled(window.scrollY > 10);
1151
+ window.addEventListener("scroll", handler);
1152
+ return () => window.removeEventListener("scroll", handler);
1153
+ }, []);
1154
+ (0, import_react20.useEffect)(() => {
1155
+ if (!isMobile) setMenuOpen(false);
1156
+ }, [isMobile]);
1157
+ const handleLink = (link) => {
1158
+ setActive(link);
1159
+ setMenuOpen(false);
1160
+ onLinkClick(link);
1161
+ };
1162
+ return /* @__PURE__ */ import_react20.default.createElement(import_react20.default.Fragment, null, /* @__PURE__ */ import_react20.default.createElement("style", null, `
1163
+ @keyframes nbSlideDown {
1164
+ from { opacity: 0; transform: translateY(-8px); }
1165
+ to { opacity: 1; transform: translateY(0); }
1166
+ }
1167
+ .nb-link:hover { color: rgba(255,255,255,0.9) !important; background: rgba(255,255,255,0.05) !important; }
1168
+ .nb-cta:hover { opacity: 0.85 !important; }
1169
+ .nb-ham:hover { background: rgba(255,255,255,0.1) !important; }
1170
+ .nb-mlink:hover { background: rgba(255,255,255,0.06) !important; }
1171
+ `), /* @__PURE__ */ import_react20.default.createElement("nav", { style: {
1172
+ position: "sticky",
1173
+ top: 0,
1174
+ left: 0,
1175
+ right: 0,
1176
+ zIndex: 1e3,
1177
+ background: scrolled ? alpha(bg, 0.96) : bg,
1178
+ borderBottom: `1px solid ${scrolled ? "rgba(255,255,255,0.09)" : "rgba(255,255,255,0.04)"}`,
1179
+ backdropFilter: scrolled ? "blur(12px)" : "none",
1180
+ WebkitBackdropFilter: scrolled ? "blur(12px)" : "none",
1181
+ transition: "all 0.3s ease",
1182
+ fontFamily: "system-ui, -apple-system, sans-serif",
1183
+ width: "100%",
1184
+ boxSizing: "border-box"
1185
+ } }, /* @__PURE__ */ import_react20.default.createElement("div", { style: {
1186
+ maxWidth: "1200px",
1187
+ margin: "0 auto",
1188
+ padding: "0 20px",
1189
+ height: isMobile ? "56px" : "64px",
1190
+ display: "flex",
1191
+ alignItems: "center",
1192
+ justifyContent: "space-between",
1193
+ gap: "16px",
1194
+ boxSizing: "border-box"
1195
+ } }, /* @__PURE__ */ import_react20.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: "8px", cursor: "pointer", flexShrink: 0 } }, /* @__PURE__ */ import_react20.default.createElement("div", { style: {
1196
+ width: isMobile ? "26px" : "30px",
1197
+ height: isMobile ? "26px" : "30px",
1198
+ borderRadius: "8px",
1199
+ background: `linear-gradient(135deg, ${accent}, ${alpha(accent, 0.6)})`,
1200
+ display: "flex",
1201
+ alignItems: "center",
1202
+ justifyContent: "center",
1203
+ fontSize: isMobile ? "12px" : "14px",
1204
+ fontWeight: "800",
1205
+ color: "#fff",
1206
+ flexShrink: 0
1207
+ } }, logo[0]), /* @__PURE__ */ import_react20.default.createElement("span", { style: {
1208
+ fontSize: isMobile ? "14px" : "16px",
1209
+ fontWeight: "800",
1210
+ color: "#fff",
1211
+ letterSpacing: "-0.3px"
1212
+ } }, logo)), !isMobile && /* @__PURE__ */ import_react20.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: "2px", flex: 1, justifyContent: "center" } }, links.map((link) => /* @__PURE__ */ import_react20.default.createElement(
1213
+ "button",
1214
+ {
1215
+ key: link,
1216
+ className: "nb-link",
1217
+ onClick: () => handleLink(link),
1218
+ style: {
1219
+ background: active === link ? alpha(accent, 0.12) : "transparent",
1220
+ border: "none",
1221
+ padding: "7px 16px",
1222
+ borderRadius: "9px",
1223
+ fontSize: "14px",
1224
+ fontWeight: active === link ? "700" : "500",
1225
+ color: active === link ? accent : "rgba(255,255,255,0.5)",
1226
+ cursor: "pointer",
1227
+ transition: "all 0.2s",
1228
+ fontFamily: "inherit",
1229
+ whiteSpace: "nowrap"
1230
+ }
1231
+ },
1232
+ link
1233
+ ))), /* @__PURE__ */ import_react20.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: "8px", flexShrink: 0 } }, /* @__PURE__ */ import_react20.default.createElement(
1234
+ "button",
1235
+ {
1236
+ className: "nb-cta",
1237
+ onClick: onCtaClick,
1238
+ style: {
1239
+ padding: isMobile ? "7px 14px" : "9px 20px",
1240
+ borderRadius: "10px",
1241
+ border: "none",
1242
+ background: `linear-gradient(135deg, ${accent}, ${alpha(accent, 0.75)})`,
1243
+ color: "#fff",
1244
+ fontSize: isMobile ? "12px" : "13px",
1245
+ fontWeight: "700",
1246
+ cursor: "pointer",
1247
+ fontFamily: "inherit",
1248
+ transition: "opacity 0.2s",
1249
+ whiteSpace: "nowrap"
1250
+ }
1251
+ },
1252
+ ctaText
1253
+ ), isMobile && /* @__PURE__ */ import_react20.default.createElement(
1254
+ "button",
1255
+ {
1256
+ className: "nb-ham",
1257
+ onClick: () => setMenuOpen((o) => !o),
1258
+ style: {
1259
+ background: "rgba(255,255,255,0.06)",
1260
+ border: "1px solid rgba(255,255,255,0.1)",
1261
+ borderRadius: "8px",
1262
+ width: "34px",
1263
+ height: "34px",
1264
+ cursor: "pointer",
1265
+ display: "flex",
1266
+ flexDirection: "column",
1267
+ alignItems: "center",
1268
+ justifyContent: "center",
1269
+ gap: "5px",
1270
+ transition: "background 0.2s",
1271
+ flexShrink: 0,
1272
+ padding: 0
1273
+ }
1274
+ },
1275
+ /* @__PURE__ */ import_react20.default.createElement("div", { style: {
1276
+ width: "16px",
1277
+ height: "1.5px",
1278
+ background: "rgba(255,255,255,0.7)",
1279
+ borderRadius: "2px",
1280
+ transform: menuOpen ? "rotate(45deg) translate(4px, 4px)" : "none",
1281
+ transition: "transform 0.25s"
1282
+ } }),
1283
+ /* @__PURE__ */ import_react20.default.createElement("div", { style: {
1284
+ width: "16px",
1285
+ height: "1.5px",
1286
+ background: "rgba(255,255,255,0.7)",
1287
+ borderRadius: "2px",
1288
+ opacity: menuOpen ? 0 : 1,
1289
+ transition: "opacity 0.2s"
1290
+ } }),
1291
+ /* @__PURE__ */ import_react20.default.createElement("div", { style: {
1292
+ width: "16px",
1293
+ height: "1.5px",
1294
+ background: "rgba(255,255,255,0.7)",
1295
+ borderRadius: "2px",
1296
+ transform: menuOpen ? "rotate(-45deg) translate(4px, -4px)" : "none",
1297
+ transition: "transform 0.25s"
1298
+ } })
1299
+ ))), isMobile && menuOpen && /* @__PURE__ */ import_react20.default.createElement("div", { style: {
1300
+ animation: "nbSlideDown 0.2s ease",
1301
+ borderTop: "1px solid rgba(255,255,255,0.06)",
1302
+ padding: "10px 16px 16px",
1303
+ display: "flex",
1304
+ flexDirection: "column",
1305
+ gap: "3px",
1306
+ background: alpha(bg, 0.98)
1307
+ } }, links.map((link) => /* @__PURE__ */ import_react20.default.createElement(
1308
+ "button",
1309
+ {
1310
+ key: link,
1311
+ className: "nb-mlink",
1312
+ onClick: () => handleLink(link),
1313
+ style: {
1314
+ background: active === link ? alpha(accent, 0.1) : "transparent",
1315
+ border: "none",
1316
+ padding: "11px 14px",
1317
+ borderRadius: "10px",
1318
+ fontSize: "14px",
1319
+ fontWeight: active === link ? "700" : "500",
1320
+ color: active === link ? accent : "rgba(255,255,255,0.55)",
1321
+ cursor: "pointer",
1322
+ textAlign: "left",
1323
+ fontFamily: "inherit",
1324
+ width: "100%",
1325
+ transition: "all 0.15s",
1326
+ display: "flex",
1327
+ alignItems: "center",
1328
+ justifyContent: "space-between"
1329
+ }
1330
+ },
1331
+ link,
1332
+ active === link && /* @__PURE__ */ import_react20.default.createElement(
1333
+ "svg",
1334
+ {
1335
+ width: "14",
1336
+ height: "14",
1337
+ viewBox: "0 0 24 24",
1338
+ fill: "none",
1339
+ stroke: accent,
1340
+ strokeWidth: "2.5",
1341
+ strokeLinecap: "round"
1342
+ },
1343
+ /* @__PURE__ */ import_react20.default.createElement("polyline", { points: "9 18 15 12 9 6" })
1344
+ )
1345
+ )), /* @__PURE__ */ import_react20.default.createElement("div", { style: { height: "1px", background: "rgba(255,255,255,0.07)", margin: "8px 0" } }), /* @__PURE__ */ import_react20.default.createElement(
1346
+ "button",
1347
+ {
1348
+ onClick: () => {
1349
+ setMenuOpen(false);
1350
+ onCtaClick();
1351
+ },
1352
+ style: {
1353
+ background: `linear-gradient(135deg, ${accent}, ${alpha(accent, 0.75)})`,
1354
+ border: "none",
1355
+ padding: "12px",
1356
+ borderRadius: "12px",
1357
+ fontSize: "14px",
1358
+ fontWeight: "700",
1359
+ color: "#fff",
1360
+ cursor: "pointer",
1361
+ fontFamily: "inherit",
1362
+ width: "100%"
1363
+ }
1364
+ },
1365
+ ctaText
1366
+ ))));
1367
+ };
1015
1368
  // Annotate the CommonJS export names for ESM import in node:
1016
1369
  0 && (module.exports = {
1017
1370
  Avatar,
@@ -1022,6 +1375,7 @@ var PricingCard = ({
1022
1375
  FileUpload,
1023
1376
  Loader,
1024
1377
  LoadingSpinner,
1378
+ Navbar,
1025
1379
  NotificationToast,
1026
1380
  OtpInput,
1027
1381
  PricingCard,
package/dist/index.mjs CHANGED
@@ -569,9 +569,112 @@ var FileUpload = ({ bg = "#1e293b", textColor = "#f1f5f9", accent = "#7c3aed", r
569
569
  };
570
570
 
571
571
  // src/components/Loader/Loader.jsx
572
- import React13 from "react";
573
- var Loader = ({ bg = "#0f172a", accent = "#7c3aed", size = "40px", borderRadius = "8px" }) => {
574
- return /* @__PURE__ */ React13.createElement("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", background: bg, height: size, width: size, borderRadius } }, /* @__PURE__ */ React13.createElement("div", { style: { border: `4px solid ${bg}`, borderTop: `4px solid ${accent}`, borderRadius: "50%", width: "100%", height: "100%", animation: "spin 1s linear infinite" } }));
572
+ import React13, { useEffect as useEffect4, useState as useState10 } from "react";
573
+ var Loader = ({
574
+ type = "spinner",
575
+ size = 48,
576
+ accent = "#6366f1",
577
+ bg = "transparent",
578
+ label = "",
579
+ speed = 1
580
+ }) => {
581
+ const [dots, setDots] = useState10(0);
582
+ const [progress, setProgress] = useState10(0);
583
+ const alpha = (hex, op) => {
584
+ const r = parseInt(hex.slice(1, 3), 16);
585
+ const g = parseInt(hex.slice(3, 5), 16);
586
+ const b = parseInt(hex.slice(5, 7), 16);
587
+ return `rgba(${r},${g},${b},${op})`;
588
+ };
589
+ useEffect4(() => {
590
+ if (type === "dots") {
591
+ const t = setInterval(() => setDots((d) => (d + 1) % 4), 400 / speed);
592
+ return () => clearInterval(t);
593
+ }
594
+ if (type === "bar") {
595
+ const t = setInterval(() => setProgress((p) => p >= 100 ? 0 : p + 2), 30 / speed);
596
+ return () => clearInterval(t);
597
+ }
598
+ }, [type, speed]);
599
+ const dur = `${1 / speed}s`;
600
+ const wrapStyle = {
601
+ display: "inline-flex",
602
+ flexDirection: "column",
603
+ alignItems: "center",
604
+ justifyContent: "center",
605
+ gap: "12px",
606
+ background: bg,
607
+ padding: bg !== "transparent" ? "24px" : "0",
608
+ borderRadius: "16px",
609
+ fontFamily: "system-ui, sans-serif"
610
+ };
611
+ const labelEl = label ? /* @__PURE__ */ React13.createElement("span", { style: { fontSize: "13px", color: "rgba(255,255,255,0.45)", letterSpacing: "0.3px" } }, label) : null;
612
+ if (type === "spinner") return /* @__PURE__ */ React13.createElement("div", { style: wrapStyle }, /* @__PURE__ */ React13.createElement("svg", { width: size, height: size, viewBox: "0 0 48 48" }, /* @__PURE__ */ React13.createElement(
613
+ "circle",
614
+ {
615
+ cx: "24",
616
+ cy: "24",
617
+ r: "20",
618
+ fill: "none",
619
+ stroke: alpha(accent, 0.15),
620
+ strokeWidth: "4"
621
+ }
622
+ ), /* @__PURE__ */ React13.createElement(
623
+ "circle",
624
+ {
625
+ cx: "24",
626
+ cy: "24",
627
+ r: "20",
628
+ fill: "none",
629
+ stroke: accent,
630
+ strokeWidth: "4",
631
+ strokeLinecap: "round",
632
+ strokeDasharray: "31.4 94.2",
633
+ style: { transformOrigin: "center", animation: `spin ${dur} linear infinite` }
634
+ }
635
+ ), /* @__PURE__ */ React13.createElement("style", null, `@keyframes spin { to { transform: rotate(360deg); } }`)), labelEl);
636
+ if (type === "pulse") return /* @__PURE__ */ React13.createElement("div", { style: wrapStyle }, /* @__PURE__ */ React13.createElement("div", { style: { position: "relative", width: size, height: size } }, /* @__PURE__ */ React13.createElement("div", { style: {
637
+ position: "absolute",
638
+ inset: 0,
639
+ borderRadius: "50%",
640
+ background: alpha(accent, 0.2),
641
+ animation: `pulse ${dur} ease-out infinite`
642
+ } }), /* @__PURE__ */ React13.createElement("div", { style: {
643
+ position: "absolute",
644
+ inset: "25%",
645
+ borderRadius: "50%",
646
+ background: accent
647
+ } }), /* @__PURE__ */ React13.createElement("style", null, `@keyframes pulse { 0%{transform:scale(1);opacity:1} 100%{transform:scale(2);opacity:0} }`)), labelEl);
648
+ if (type === "dots") return /* @__PURE__ */ React13.createElement("div", { style: wrapStyle }, /* @__PURE__ */ React13.createElement("div", { style: { display: "flex", gap: "8px", alignItems: "center" } }, [0, 1, 2].map((i) => /* @__PURE__ */ React13.createElement("div", { key: i, style: {
649
+ width: size / 5,
650
+ height: size / 5,
651
+ borderRadius: "50%",
652
+ background: dots === i ? accent : alpha(accent, 0.25),
653
+ transition: "background 0.2s"
654
+ } }))), labelEl);
655
+ if (type === "bar") return /* @__PURE__ */ React13.createElement("div", { style: wrapStyle }, /* @__PURE__ */ React13.createElement("div", { style: {
656
+ width: size * 3,
657
+ height: size / 8,
658
+ background: alpha(accent, 0.15),
659
+ borderRadius: "99px",
660
+ overflow: "hidden"
661
+ } }, /* @__PURE__ */ React13.createElement("div", { style: {
662
+ height: "100%",
663
+ borderRadius: "99px",
664
+ background: accent,
665
+ width: `${progress}%`,
666
+ transition: "width 0.03s linear"
667
+ } })), labelEl);
668
+ if (type === "ring") return /* @__PURE__ */ React13.createElement("div", { style: wrapStyle }, /* @__PURE__ */ React13.createElement("div", { style: {
669
+ width: size,
670
+ height: size,
671
+ borderRadius: "50%",
672
+ border: `4px solid ${alpha(accent, 0.15)}`,
673
+ borderTop: `4px solid ${accent}`,
674
+ borderRight: `4px solid ${accent}`,
675
+ animation: `spin ${dur} linear infinite`
676
+ } }), /* @__PURE__ */ React13.createElement("style", null, `@keyframes spin { to { transform: rotate(360deg); } }`), labelEl);
677
+ return null;
575
678
  };
576
679
 
577
680
  // src/components/Avatar/Avatar.jsx
@@ -615,7 +718,7 @@ var DividerLine = ({
615
718
  };
616
719
 
617
720
  // src/components/Tabs/Tabs.jsx
618
- import React16, { useState as useState10 } from "react";
721
+ import React16, { useState as useState11 } from "react";
619
722
  var Tabs = ({
620
723
  tabs = [
621
724
  { label: "Tab 1", content: "Content for Tab 1" },
@@ -627,7 +730,7 @@ var Tabs = ({
627
730
  textColor = "#f1f5f9",
628
731
  radius = "8px"
629
732
  }) => {
630
- const [activeTab, setActiveTab] = useState10(0);
733
+ const [activeTab, setActiveTab] = useState11(0);
631
734
  return /* @__PURE__ */ React16.createElement("div", { style: { background: bg, borderRadius: radius, padding: "16px", boxShadow: "0 4px 20px rgba(0,0,0,0.5)", fontFamily: "system-ui, sans-serif" } }, /* @__PURE__ */ React16.createElement("div", { style: { display: "flex", borderBottom: `2px solid ${accent}` } }, tabs.map((tab, index) => /* @__PURE__ */ React16.createElement(
632
735
  "button",
633
736
  {
@@ -649,7 +752,7 @@ var Tabs = ({
649
752
  };
650
753
 
651
754
  // src/components/NotificationToast/NotificationToast.jsx
652
- import React17, { useState as useState11, useEffect as useEffect4 } from "react";
755
+ import React17, { useState as useState12, useEffect as useEffect5 } from "react";
653
756
  var NotificationToast = ({
654
757
  title = "New Message",
655
758
  message = "You have a new notification from the team.",
@@ -660,8 +763,8 @@ var NotificationToast = ({
660
763
  radius = "14px",
661
764
  showProgress = true
662
765
  }) => {
663
- const [visible, setVisible] = useState11(true);
664
- const [progress, setProgress] = useState11(100);
766
+ const [visible, setVisible] = useState12(true);
767
+ const [progress, setProgress] = useState12(100);
665
768
  const typeColors = {
666
769
  success: "#10b981",
667
770
  error: "#ef4444",
@@ -675,7 +778,7 @@ var NotificationToast = ({
675
778
  info: "M13 16h-1v-4h-1m1-4h.01M12 2a10 10 0 100 20A10 10 0 0012 2z"
676
779
  };
677
780
  const color = typeColors[type] || accent;
678
- useEffect4(() => {
781
+ useEffect5(() => {
679
782
  if (!showProgress) return;
680
783
  const step = 100 / (duration / 50);
681
784
  const timer = setInterval(() => {
@@ -769,7 +872,7 @@ var NotificationToast = ({
769
872
  };
770
873
 
771
874
  // src/components/AvatarCard/AvatarCard.jsx
772
- import React18, { useState as useState12 } from "react";
875
+ import React18, { useState as useState13 } from "react";
773
876
  var AvatarCard = ({
774
877
  name = "Aryan Sharma",
775
878
  role = "Frontend Developer",
@@ -782,7 +885,7 @@ var AvatarCard = ({
782
885
  bg = "#0f172a",
783
886
  radius = "20px"
784
887
  }) => {
785
- const [followed, setFollowed] = useState12(false);
888
+ const [followed, setFollowed] = useState13(false);
786
889
  const alpha = (hex, op) => {
787
890
  const r = parseInt(hex.slice(1, 3), 16);
788
891
  const g = parseInt(hex.slice(3, 5), 16);
@@ -959,6 +1062,255 @@ var PricingCard = ({
959
1062
  ctaText
960
1063
  ));
961
1064
  };
1065
+
1066
+ // src/components/Navbar/Navbar.jsx
1067
+ import React20, { useState as useState14, useEffect as useEffect6 } from "react";
1068
+ var Navbar = ({
1069
+ logo = "VirtualAI",
1070
+ links = ["Home", "Features", "Pricing", "Blog"],
1071
+ ctaText = "Get Started",
1072
+ accent = "#6366f1",
1073
+ bg = "#0f172a",
1074
+ onCtaClick = () => {
1075
+ },
1076
+ onLinkClick = () => {
1077
+ }
1078
+ }) => {
1079
+ const [scrolled, setScrolled] = useState14(false);
1080
+ const [menuOpen, setMenuOpen] = useState14(false);
1081
+ const [active, setActive] = useState14("Home");
1082
+ const [isMobile, setIsMobile] = useState14(false);
1083
+ const alpha = (hex, op) => {
1084
+ const r = parseInt(hex.slice(1, 3), 16);
1085
+ const g = parseInt(hex.slice(3, 5), 16);
1086
+ const b = parseInt(hex.slice(5, 7), 16);
1087
+ return `rgba(${r},${g},${b},${op})`;
1088
+ };
1089
+ useEffect6(() => {
1090
+ const checkMobile = () => setIsMobile(window.innerWidth < 768);
1091
+ checkMobile();
1092
+ window.addEventListener("resize", checkMobile);
1093
+ return () => window.removeEventListener("resize", checkMobile);
1094
+ }, []);
1095
+ useEffect6(() => {
1096
+ const handler = () => setScrolled(window.scrollY > 10);
1097
+ window.addEventListener("scroll", handler);
1098
+ return () => window.removeEventListener("scroll", handler);
1099
+ }, []);
1100
+ useEffect6(() => {
1101
+ if (!isMobile) setMenuOpen(false);
1102
+ }, [isMobile]);
1103
+ const handleLink = (link) => {
1104
+ setActive(link);
1105
+ setMenuOpen(false);
1106
+ onLinkClick(link);
1107
+ };
1108
+ return /* @__PURE__ */ React20.createElement(React20.Fragment, null, /* @__PURE__ */ React20.createElement("style", null, `
1109
+ @keyframes nbSlideDown {
1110
+ from { opacity: 0; transform: translateY(-8px); }
1111
+ to { opacity: 1; transform: translateY(0); }
1112
+ }
1113
+ .nb-link:hover { color: rgba(255,255,255,0.9) !important; background: rgba(255,255,255,0.05) !important; }
1114
+ .nb-cta:hover { opacity: 0.85 !important; }
1115
+ .nb-ham:hover { background: rgba(255,255,255,0.1) !important; }
1116
+ .nb-mlink:hover { background: rgba(255,255,255,0.06) !important; }
1117
+ `), /* @__PURE__ */ React20.createElement("nav", { style: {
1118
+ position: "sticky",
1119
+ top: 0,
1120
+ left: 0,
1121
+ right: 0,
1122
+ zIndex: 1e3,
1123
+ background: scrolled ? alpha(bg, 0.96) : bg,
1124
+ borderBottom: `1px solid ${scrolled ? "rgba(255,255,255,0.09)" : "rgba(255,255,255,0.04)"}`,
1125
+ backdropFilter: scrolled ? "blur(12px)" : "none",
1126
+ WebkitBackdropFilter: scrolled ? "blur(12px)" : "none",
1127
+ transition: "all 0.3s ease",
1128
+ fontFamily: "system-ui, -apple-system, sans-serif",
1129
+ width: "100%",
1130
+ boxSizing: "border-box"
1131
+ } }, /* @__PURE__ */ React20.createElement("div", { style: {
1132
+ maxWidth: "1200px",
1133
+ margin: "0 auto",
1134
+ padding: "0 20px",
1135
+ height: isMobile ? "56px" : "64px",
1136
+ display: "flex",
1137
+ alignItems: "center",
1138
+ justifyContent: "space-between",
1139
+ gap: "16px",
1140
+ boxSizing: "border-box"
1141
+ } }, /* @__PURE__ */ React20.createElement("div", { style: { display: "flex", alignItems: "center", gap: "8px", cursor: "pointer", flexShrink: 0 } }, /* @__PURE__ */ React20.createElement("div", { style: {
1142
+ width: isMobile ? "26px" : "30px",
1143
+ height: isMobile ? "26px" : "30px",
1144
+ borderRadius: "8px",
1145
+ background: `linear-gradient(135deg, ${accent}, ${alpha(accent, 0.6)})`,
1146
+ display: "flex",
1147
+ alignItems: "center",
1148
+ justifyContent: "center",
1149
+ fontSize: isMobile ? "12px" : "14px",
1150
+ fontWeight: "800",
1151
+ color: "#fff",
1152
+ flexShrink: 0
1153
+ } }, logo[0]), /* @__PURE__ */ React20.createElement("span", { style: {
1154
+ fontSize: isMobile ? "14px" : "16px",
1155
+ fontWeight: "800",
1156
+ color: "#fff",
1157
+ letterSpacing: "-0.3px"
1158
+ } }, logo)), !isMobile && /* @__PURE__ */ React20.createElement("div", { style: { display: "flex", alignItems: "center", gap: "2px", flex: 1, justifyContent: "center" } }, links.map((link) => /* @__PURE__ */ React20.createElement(
1159
+ "button",
1160
+ {
1161
+ key: link,
1162
+ className: "nb-link",
1163
+ onClick: () => handleLink(link),
1164
+ style: {
1165
+ background: active === link ? alpha(accent, 0.12) : "transparent",
1166
+ border: "none",
1167
+ padding: "7px 16px",
1168
+ borderRadius: "9px",
1169
+ fontSize: "14px",
1170
+ fontWeight: active === link ? "700" : "500",
1171
+ color: active === link ? accent : "rgba(255,255,255,0.5)",
1172
+ cursor: "pointer",
1173
+ transition: "all 0.2s",
1174
+ fontFamily: "inherit",
1175
+ whiteSpace: "nowrap"
1176
+ }
1177
+ },
1178
+ link
1179
+ ))), /* @__PURE__ */ React20.createElement("div", { style: { display: "flex", alignItems: "center", gap: "8px", flexShrink: 0 } }, /* @__PURE__ */ React20.createElement(
1180
+ "button",
1181
+ {
1182
+ className: "nb-cta",
1183
+ onClick: onCtaClick,
1184
+ style: {
1185
+ padding: isMobile ? "7px 14px" : "9px 20px",
1186
+ borderRadius: "10px",
1187
+ border: "none",
1188
+ background: `linear-gradient(135deg, ${accent}, ${alpha(accent, 0.75)})`,
1189
+ color: "#fff",
1190
+ fontSize: isMobile ? "12px" : "13px",
1191
+ fontWeight: "700",
1192
+ cursor: "pointer",
1193
+ fontFamily: "inherit",
1194
+ transition: "opacity 0.2s",
1195
+ whiteSpace: "nowrap"
1196
+ }
1197
+ },
1198
+ ctaText
1199
+ ), isMobile && /* @__PURE__ */ React20.createElement(
1200
+ "button",
1201
+ {
1202
+ className: "nb-ham",
1203
+ onClick: () => setMenuOpen((o) => !o),
1204
+ style: {
1205
+ background: "rgba(255,255,255,0.06)",
1206
+ border: "1px solid rgba(255,255,255,0.1)",
1207
+ borderRadius: "8px",
1208
+ width: "34px",
1209
+ height: "34px",
1210
+ cursor: "pointer",
1211
+ display: "flex",
1212
+ flexDirection: "column",
1213
+ alignItems: "center",
1214
+ justifyContent: "center",
1215
+ gap: "5px",
1216
+ transition: "background 0.2s",
1217
+ flexShrink: 0,
1218
+ padding: 0
1219
+ }
1220
+ },
1221
+ /* @__PURE__ */ React20.createElement("div", { style: {
1222
+ width: "16px",
1223
+ height: "1.5px",
1224
+ background: "rgba(255,255,255,0.7)",
1225
+ borderRadius: "2px",
1226
+ transform: menuOpen ? "rotate(45deg) translate(4px, 4px)" : "none",
1227
+ transition: "transform 0.25s"
1228
+ } }),
1229
+ /* @__PURE__ */ React20.createElement("div", { style: {
1230
+ width: "16px",
1231
+ height: "1.5px",
1232
+ background: "rgba(255,255,255,0.7)",
1233
+ borderRadius: "2px",
1234
+ opacity: menuOpen ? 0 : 1,
1235
+ transition: "opacity 0.2s"
1236
+ } }),
1237
+ /* @__PURE__ */ React20.createElement("div", { style: {
1238
+ width: "16px",
1239
+ height: "1.5px",
1240
+ background: "rgba(255,255,255,0.7)",
1241
+ borderRadius: "2px",
1242
+ transform: menuOpen ? "rotate(-45deg) translate(4px, -4px)" : "none",
1243
+ transition: "transform 0.25s"
1244
+ } })
1245
+ ))), isMobile && menuOpen && /* @__PURE__ */ React20.createElement("div", { style: {
1246
+ animation: "nbSlideDown 0.2s ease",
1247
+ borderTop: "1px solid rgba(255,255,255,0.06)",
1248
+ padding: "10px 16px 16px",
1249
+ display: "flex",
1250
+ flexDirection: "column",
1251
+ gap: "3px",
1252
+ background: alpha(bg, 0.98)
1253
+ } }, links.map((link) => /* @__PURE__ */ React20.createElement(
1254
+ "button",
1255
+ {
1256
+ key: link,
1257
+ className: "nb-mlink",
1258
+ onClick: () => handleLink(link),
1259
+ style: {
1260
+ background: active === link ? alpha(accent, 0.1) : "transparent",
1261
+ border: "none",
1262
+ padding: "11px 14px",
1263
+ borderRadius: "10px",
1264
+ fontSize: "14px",
1265
+ fontWeight: active === link ? "700" : "500",
1266
+ color: active === link ? accent : "rgba(255,255,255,0.55)",
1267
+ cursor: "pointer",
1268
+ textAlign: "left",
1269
+ fontFamily: "inherit",
1270
+ width: "100%",
1271
+ transition: "all 0.15s",
1272
+ display: "flex",
1273
+ alignItems: "center",
1274
+ justifyContent: "space-between"
1275
+ }
1276
+ },
1277
+ link,
1278
+ active === link && /* @__PURE__ */ React20.createElement(
1279
+ "svg",
1280
+ {
1281
+ width: "14",
1282
+ height: "14",
1283
+ viewBox: "0 0 24 24",
1284
+ fill: "none",
1285
+ stroke: accent,
1286
+ strokeWidth: "2.5",
1287
+ strokeLinecap: "round"
1288
+ },
1289
+ /* @__PURE__ */ React20.createElement("polyline", { points: "9 18 15 12 9 6" })
1290
+ )
1291
+ )), /* @__PURE__ */ React20.createElement("div", { style: { height: "1px", background: "rgba(255,255,255,0.07)", margin: "8px 0" } }), /* @__PURE__ */ React20.createElement(
1292
+ "button",
1293
+ {
1294
+ onClick: () => {
1295
+ setMenuOpen(false);
1296
+ onCtaClick();
1297
+ },
1298
+ style: {
1299
+ background: `linear-gradient(135deg, ${accent}, ${alpha(accent, 0.75)})`,
1300
+ border: "none",
1301
+ padding: "12px",
1302
+ borderRadius: "12px",
1303
+ fontSize: "14px",
1304
+ fontWeight: "700",
1305
+ color: "#fff",
1306
+ cursor: "pointer",
1307
+ fontFamily: "inherit",
1308
+ width: "100%"
1309
+ }
1310
+ },
1311
+ ctaText
1312
+ ))));
1313
+ };
962
1314
  export {
963
1315
  Avatar,
964
1316
  AvatarCard,
@@ -968,6 +1320,7 @@ export {
968
1320
  FileUpload,
969
1321
  Loader,
970
1322
  LoadingSpinner,
1323
+ Navbar,
971
1324
  NotificationToast,
972
1325
  OtpInput,
973
1326
  PricingCard,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "virtual-ui-lib",
3
- "version": "1.0.58",
3
+ "version": "1.0.60",
4
4
  "description": "Virtual UI React Component Library",
5
5
  "author": "Ankush",
6
6
  "license": "ISC",