@windrun-huaiin/base-ui 3.2.2 → 3.2.4

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.
@@ -1487,6 +1487,106 @@ import { useLocale, useTranslations } from "next-intl";
1487
1487
  import { useRouter } from "next/navigation";
1488
1488
  import { useEffect as useEffect3, useState as useState3 } from "react";
1489
1489
  import { jsx as jsx34, jsxs as jsxs8 } from "react/jsx-runtime";
1490
+ function LanguageDetector({ i18nConfig }) {
1491
+ const [show, setShow] = useState3(false);
1492
+ const [detectedLocale, setDetectedLocale] = useState3(null);
1493
+ const currentLocale = useLocale();
1494
+ const router = useRouter();
1495
+ const t = useTranslations("languageDetection");
1496
+ const LANGUAGE_PREFERENCE_KEY = `${i18nConfig.detector.storagePrefix}-${i18nConfig.detector.storageKey}`;
1497
+ useEffect3(() => {
1498
+ const browserLang = navigator.language.split("-")[0];
1499
+ const savedPreference = localStorage.getItem(LANGUAGE_PREFERENCE_KEY);
1500
+ const preference = savedPreference ? JSON.parse(savedPreference) : null;
1501
+ const shouldShowDetector = () => {
1502
+ if (!preference) return true;
1503
+ if (preference.locale === currentLocale) return false;
1504
+ if (preference.status === "rejected" && preference.locale === browserLang) return false;
1505
+ if (preference.status === "accepted" && preference.locale === currentLocale) return false;
1506
+ const expirationMs = i18nConfig.detector.expirationDays * 24 * 60 * 60 * 1e3;
1507
+ if (Date.now() - preference.timestamp < expirationMs) return false;
1508
+ return true;
1509
+ };
1510
+ if (i18nConfig.locales.includes(browserLang) && browserLang !== currentLocale && shouldShowDetector()) {
1511
+ setDetectedLocale(browserLang);
1512
+ setShow(true);
1513
+ const timer = setTimeout(() => {
1514
+ console.log("[LanguageDetector] Auto closing after timeout");
1515
+ setShow(false);
1516
+ savePreference(browserLang, "rejected");
1517
+ }, i18nConfig.detector.autoCloseTimeout);
1518
+ return () => clearTimeout(timer);
1519
+ }
1520
+ }, [currentLocale]);
1521
+ const savePreference = (locale, status) => {
1522
+ const preference = {
1523
+ locale,
1524
+ status,
1525
+ timestamp: Date.now()
1526
+ };
1527
+ localStorage.setItem(LANGUAGE_PREFERENCE_KEY, JSON.stringify(preference));
1528
+ };
1529
+ const handleLanguageChange = () => {
1530
+ if (detectedLocale) {
1531
+ savePreference(detectedLocale, "accepted");
1532
+ const pathname = window.location.pathname;
1533
+ const newPathname = pathname.replace(`/${currentLocale}`, `/${detectedLocale}`);
1534
+ router.push(newPathname);
1535
+ setShow(false);
1536
+ }
1537
+ };
1538
+ const handleClose = () => {
1539
+ if (detectedLocale) {
1540
+ savePreference(detectedLocale, "rejected");
1541
+ }
1542
+ setShow(false);
1543
+ };
1544
+ if (!detectedLocale || !show) return null;
1545
+ return /* @__PURE__ */ jsx34("div", { className: "fixed top-16 right-4 z-40 w-[420px]", children: /* @__PURE__ */ jsx34("div", { className: `shadow-lg rounded-lg transition-all duration-300 ${show ? "translate-x-0 opacity-100" : "translate-x-full opacity-0"}
1546
+ bg-linear-to-r from-purple-100/95 via-white/95 to-purple-100/95 backdrop-blur-xs
1547
+ animate-gradient-x`, children: /* @__PURE__ */ jsxs8("div", { className: "relative px-6 py-4 overflow-hidden", children: [
1548
+ /* @__PURE__ */ jsxs8("div", { className: "relative z-10 flex flex-col gap-3", children: [
1549
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-start justify-between gap-4", children: [
1550
+ /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-1.5", children: [
1551
+ /* @__PURE__ */ jsx34("h3", { className: "text-lg font-semibold text-gray-900", children: t("title") }),
1552
+ /* @__PURE__ */ jsxs8("p", { className: "text-base text-gray-600", children: [
1553
+ t("description"),
1554
+ " ",
1555
+ /* @__PURE__ */ jsx34("span", { className: "text-purple-500 font-semibold", children: detectedLocale === "zh" ? "\u4E2D\u6587" : "English" }),
1556
+ "?"
1557
+ ] })
1558
+ ] }),
1559
+ /* @__PURE__ */ jsx34(
1560
+ "button",
1561
+ {
1562
+ onClick: handleClose,
1563
+ className: "text-gray-500 hover:text-gray-700",
1564
+ children: /* @__PURE__ */ jsx34(globalLucideIcons.X, { className: "h-5 w-5" })
1565
+ }
1566
+ )
1567
+ ] }),
1568
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3", children: [
1569
+ /* @__PURE__ */ jsx34(
1570
+ "button",
1571
+ {
1572
+ onClick: handleClose,
1573
+ className: "flex-1 px-4 py-2 text-base bg-gray-100 text-gray-600 rounded-md hover:bg-gray-200",
1574
+ children: t("close")
1575
+ }
1576
+ ),
1577
+ /* @__PURE__ */ jsx34(
1578
+ "button",
1579
+ {
1580
+ onClick: handleLanguageChange,
1581
+ className: "flex-1 px-4 py-2 text-base bg-purple-500 text-white rounded-md hover:bg-purple-600",
1582
+ children: t("changeAction")
1583
+ }
1584
+ )
1585
+ ] })
1586
+ ] }),
1587
+ /* @__PURE__ */ jsx34("div", { className: "absolute inset-0 bg-linear-to-r from-transparent via-purple-200/30 to-transparent animate-shimmer" })
1588
+ ] }) }) });
1589
+ }
1490
1590
 
1491
1591
  // src/components/language-switcher.tsx
1492
1592
  import { usePathname, useRouter as useRouter2 } from "next/navigation";
@@ -1496,6 +1596,8 @@ import { useLocale as useLocale2 } from "next-intl";
1496
1596
  import * as React30 from "react";
1497
1597
  import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
1498
1598
  import { jsx as jsx35, jsxs as jsxs9 } from "react/jsx-runtime";
1599
+ var DropdownMenu = DropdownMenuPrimitive.Root;
1600
+ var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
1499
1601
  var DropdownMenuSubTrigger = React30.forwardRef((_a, ref) => {
1500
1602
  var _b = _a, { className, inset, children } = _b, props = __objRest(_b, ["className", "inset", "children"]);
1501
1603
  return /* @__PURE__ */ jsxs9(
@@ -1670,6 +1772,49 @@ LanguageButton.displayName = "Button";
1670
1772
 
1671
1773
  // src/components/language-switcher.tsx
1672
1774
  import { jsx as jsx37, jsxs as jsxs10 } from "react/jsx-runtime";
1775
+ function LanguageSwitcher({ locales, localeLabels }) {
1776
+ const locale = useLocale2();
1777
+ const router = useRouter2();
1778
+ const pathname = usePathname();
1779
+ const handleLocaleChange = (newLocale) => {
1780
+ const newPathname = pathname.replace(`/${locale}`, `/${newLocale}`);
1781
+ router.push(newPathname);
1782
+ };
1783
+ return /* @__PURE__ */ jsxs10(DropdownMenu, { children: [
1784
+ /* @__PURE__ */ jsx37(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx37(
1785
+ LanguageButton,
1786
+ {
1787
+ variant: "ghost",
1788
+ size: "icon",
1789
+ className: "bg-linear-to-r from-purple-400 to-pink-600 hover:from-purple-500 hover:to-pink-700 text-white transform hover:scale-110 transition-all duration-300",
1790
+ children: /* @__PURE__ */ jsx37(globalLucideIcons.Globe, { className: "h-5 w-5" })
1791
+ }
1792
+ ) }),
1793
+ /* @__PURE__ */ jsx37(
1794
+ DropdownMenuContent,
1795
+ {
1796
+ align: "end",
1797
+ sideOffset: 5,
1798
+ className: "bg-white/90 dark:bg-gray-800/90 border-purple-100 dark:border-purple-800 w-[200px] p-2 backdrop-blur-xs translate-x-[50px]",
1799
+ children: /* @__PURE__ */ jsx37("div", { className: "grid grid-cols-2 gap-1", children: locales.map((loc) => /* @__PURE__ */ jsx37(
1800
+ DropdownMenuItem,
1801
+ {
1802
+ className: `
1803
+ px-2 py-2 text-sm cursor-pointer text-center justify-center
1804
+ transition-all duration-300 ease-in-out
1805
+ hover:scale-105 hover:shadow-md
1806
+ rounded-md whitespace-nowrap
1807
+ ${locale === loc ? "bg-linear-to-r from-purple-400 to-pink-600 text-white font-medium shadow-lg scale-105" : "hover:bg-linear-to-r hover:from-purple-400/10 hover:to-pink-600/10 hover:text-transparent hover:bg-clip-text"}
1808
+ `,
1809
+ onClick: () => handleLocaleChange(loc),
1810
+ children: localeLabels[loc]
1811
+ },
1812
+ loc
1813
+ )) })
1814
+ }
1815
+ )
1816
+ ] });
1817
+ }
1673
1818
 
1674
1819
  // src/components/script/google-analytics-script.tsx
1675
1820
  import Script from "next/script";
@@ -1735,6 +1880,8 @@ function MicrosoftClarityScript() {
1735
1880
  export {
1736
1881
  DefaultSiteIcon,
1737
1882
  GoogleAnalyticsScript,
1883
+ LanguageDetector,
1884
+ LanguageSwitcher,
1738
1885
  MicrosoftClarityScript,
1739
1886
  NotFoundIcon,
1740
1887
  NotFoundPage,