@windrun-huaiin/base-ui 3.2.1 → 3.2.3
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/components/index.d.mts +31 -1
- package/dist/components/index.d.ts +31 -1
- package/dist/components/index.js +163 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +160 -0
- package/dist/components/index.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +161 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +158 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/language-detector.tsx +1 -1
- package/src/components/language-switcher.tsx +1 -1
- package/src/components/script/google-analytics-script.tsx +2 -2
- package/src/components/script/microsoft-clarity-script.tsx +2 -2
@@ -130,6 +130,34 @@ declare function getIconElement(icon: string | undefined): React__default.ReactE
|
|
130
130
|
declare const DefaultSiteIcon: () => react_jsx_runtime.JSX.Element;
|
131
131
|
declare const NotFoundIcon: () => react_jsx_runtime.JSX.Element;
|
132
132
|
|
133
|
+
type I18nConfig = {
|
134
|
+
locales: readonly string[];
|
135
|
+
detector: {
|
136
|
+
storagePrefix: string;
|
137
|
+
storageKey: string;
|
138
|
+
autoCloseTimeout: number;
|
139
|
+
expirationDays: number;
|
140
|
+
};
|
141
|
+
};
|
142
|
+
interface LanguageDetectorProps {
|
143
|
+
i18nConfig: I18nConfig;
|
144
|
+
}
|
145
|
+
declare function LanguageDetector({ i18nConfig }: LanguageDetectorProps): react_jsx_runtime.JSX.Element | null;
|
146
|
+
|
147
|
+
/**
|
148
|
+
* @license
|
149
|
+
* MIT License
|
150
|
+
* Copyright (c) 2025 D8ger
|
151
|
+
*
|
152
|
+
* This source code is licensed under the MIT license found in the
|
153
|
+
* LICENSE file in the root directory of this source tree.
|
154
|
+
*/
|
155
|
+
interface LanguageSwitcherProps {
|
156
|
+
locales: readonly string[];
|
157
|
+
localeLabels: Record<string, string>;
|
158
|
+
}
|
159
|
+
declare function LanguageSwitcher({ locales, localeLabels }: LanguageSwitcherProps): react_jsx_runtime.JSX.Element;
|
160
|
+
|
133
161
|
declare function GoogleAnalyticsScript(): react_jsx_runtime.JSX.Element | null;
|
134
162
|
declare function useGoogleAnalytics(): {
|
135
163
|
trackEvent: (event: string, data?: Record<string, unknown>) => void;
|
@@ -141,4 +169,6 @@ declare global {
|
|
141
169
|
}
|
142
170
|
}
|
143
171
|
|
144
|
-
|
172
|
+
declare function MicrosoftClarityScript(): react_jsx_runtime.JSX.Element | null;
|
173
|
+
|
174
|
+
export { DefaultSiteIcon, GoogleAnalyticsScript, LanguageDetector, LanguageSwitcher, MicrosoftClarityScript, NotFoundIcon, NotFoundPage, getGlobalIcon, getIconElement, globalLucideIcons, useGoogleAnalytics };
|
@@ -130,6 +130,34 @@ declare function getIconElement(icon: string | undefined): React__default.ReactE
|
|
130
130
|
declare const DefaultSiteIcon: () => react_jsx_runtime.JSX.Element;
|
131
131
|
declare const NotFoundIcon: () => react_jsx_runtime.JSX.Element;
|
132
132
|
|
133
|
+
type I18nConfig = {
|
134
|
+
locales: readonly string[];
|
135
|
+
detector: {
|
136
|
+
storagePrefix: string;
|
137
|
+
storageKey: string;
|
138
|
+
autoCloseTimeout: number;
|
139
|
+
expirationDays: number;
|
140
|
+
};
|
141
|
+
};
|
142
|
+
interface LanguageDetectorProps {
|
143
|
+
i18nConfig: I18nConfig;
|
144
|
+
}
|
145
|
+
declare function LanguageDetector({ i18nConfig }: LanguageDetectorProps): react_jsx_runtime.JSX.Element | null;
|
146
|
+
|
147
|
+
/**
|
148
|
+
* @license
|
149
|
+
* MIT License
|
150
|
+
* Copyright (c) 2025 D8ger
|
151
|
+
*
|
152
|
+
* This source code is licensed under the MIT license found in the
|
153
|
+
* LICENSE file in the root directory of this source tree.
|
154
|
+
*/
|
155
|
+
interface LanguageSwitcherProps {
|
156
|
+
locales: readonly string[];
|
157
|
+
localeLabels: Record<string, string>;
|
158
|
+
}
|
159
|
+
declare function LanguageSwitcher({ locales, localeLabels }: LanguageSwitcherProps): react_jsx_runtime.JSX.Element;
|
160
|
+
|
133
161
|
declare function GoogleAnalyticsScript(): react_jsx_runtime.JSX.Element | null;
|
134
162
|
declare function useGoogleAnalytics(): {
|
135
163
|
trackEvent: (event: string, data?: Record<string, unknown>) => void;
|
@@ -141,4 +169,6 @@ declare global {
|
|
141
169
|
}
|
142
170
|
}
|
143
171
|
|
144
|
-
|
172
|
+
declare function MicrosoftClarityScript(): react_jsx_runtime.JSX.Element | null;
|
173
|
+
|
174
|
+
export { DefaultSiteIcon, GoogleAnalyticsScript, LanguageDetector, LanguageSwitcher, MicrosoftClarityScript, NotFoundIcon, NotFoundPage, getGlobalIcon, getIconElement, globalLucideIcons, useGoogleAnalytics };
|
package/dist/components/index.js
CHANGED
@@ -62,6 +62,9 @@ var components_exports = {};
|
|
62
62
|
__export(components_exports, {
|
63
63
|
DefaultSiteIcon: () => DefaultSiteIcon,
|
64
64
|
GoogleAnalyticsScript: () => GoogleAnalyticsScript,
|
65
|
+
LanguageDetector: () => LanguageDetector,
|
66
|
+
LanguageSwitcher: () => LanguageSwitcher,
|
67
|
+
MicrosoftClarityScript: () => MicrosoftClarityScript,
|
65
68
|
NotFoundIcon: () => NotFoundIcon,
|
66
69
|
NotFoundPage: () => NotFoundPage,
|
67
70
|
getGlobalIcon: () => getGlobalIcon,
|
@@ -1444,6 +1447,106 @@ var import_next_intl = require("next-intl");
|
|
1444
1447
|
var import_navigation = require("next/navigation");
|
1445
1448
|
var import_react33 = require("react");
|
1446
1449
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
1450
|
+
function LanguageDetector({ i18nConfig }) {
|
1451
|
+
const [show, setShow] = (0, import_react33.useState)(false);
|
1452
|
+
const [detectedLocale, setDetectedLocale] = (0, import_react33.useState)(null);
|
1453
|
+
const currentLocale = (0, import_next_intl.useLocale)();
|
1454
|
+
const router = (0, import_navigation.useRouter)();
|
1455
|
+
const t = (0, import_next_intl.useTranslations)("languageDetection");
|
1456
|
+
const LANGUAGE_PREFERENCE_KEY = `${i18nConfig.detector.storagePrefix}-${i18nConfig.detector.storageKey}`;
|
1457
|
+
(0, import_react33.useEffect)(() => {
|
1458
|
+
const browserLang = navigator.language.split("-")[0];
|
1459
|
+
const savedPreference = localStorage.getItem(LANGUAGE_PREFERENCE_KEY);
|
1460
|
+
const preference = savedPreference ? JSON.parse(savedPreference) : null;
|
1461
|
+
const shouldShowDetector = () => {
|
1462
|
+
if (!preference) return true;
|
1463
|
+
if (preference.locale === currentLocale) return false;
|
1464
|
+
if (preference.status === "rejected" && preference.locale === browserLang) return false;
|
1465
|
+
if (preference.status === "accepted" && preference.locale === currentLocale) return false;
|
1466
|
+
const expirationMs = i18nConfig.detector.expirationDays * 24 * 60 * 60 * 1e3;
|
1467
|
+
if (Date.now() - preference.timestamp < expirationMs) return false;
|
1468
|
+
return true;
|
1469
|
+
};
|
1470
|
+
if (i18nConfig.locales.includes(browserLang) && browserLang !== currentLocale && shouldShowDetector()) {
|
1471
|
+
setDetectedLocale(browserLang);
|
1472
|
+
setShow(true);
|
1473
|
+
const timer = setTimeout(() => {
|
1474
|
+
console.log("[LanguageDetector] Auto closing after timeout");
|
1475
|
+
setShow(false);
|
1476
|
+
savePreference(browserLang, "rejected");
|
1477
|
+
}, i18nConfig.detector.autoCloseTimeout);
|
1478
|
+
return () => clearTimeout(timer);
|
1479
|
+
}
|
1480
|
+
}, [currentLocale]);
|
1481
|
+
const savePreference = (locale, status) => {
|
1482
|
+
const preference = {
|
1483
|
+
locale,
|
1484
|
+
status,
|
1485
|
+
timestamp: Date.now()
|
1486
|
+
};
|
1487
|
+
localStorage.setItem(LANGUAGE_PREFERENCE_KEY, JSON.stringify(preference));
|
1488
|
+
};
|
1489
|
+
const handleLanguageChange = () => {
|
1490
|
+
if (detectedLocale) {
|
1491
|
+
savePreference(detectedLocale, "accepted");
|
1492
|
+
const pathname = window.location.pathname;
|
1493
|
+
const newPathname = pathname.replace(`/${currentLocale}`, `/${detectedLocale}`);
|
1494
|
+
router.push(newPathname);
|
1495
|
+
setShow(false);
|
1496
|
+
}
|
1497
|
+
};
|
1498
|
+
const handleClose = () => {
|
1499
|
+
if (detectedLocale) {
|
1500
|
+
savePreference(detectedLocale, "rejected");
|
1501
|
+
}
|
1502
|
+
setShow(false);
|
1503
|
+
};
|
1504
|
+
if (!detectedLocale || !show) return null;
|
1505
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "fixed top-16 right-4 z-40 w-[420px]", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: `shadow-lg rounded-lg transition-all duration-300 ${show ? "translate-x-0 opacity-100" : "translate-x-full opacity-0"}
|
1506
|
+
bg-linear-to-r from-purple-100/95 via-white/95 to-purple-100/95 backdrop-blur-xs
|
1507
|
+
animate-gradient-x`, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "relative px-6 py-4 overflow-hidden", children: [
|
1508
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "relative z-10 flex flex-col gap-3", children: [
|
1509
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-start justify-between gap-4", children: [
|
1510
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
|
1511
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("h3", { className: "text-lg font-semibold text-gray-900", children: t("title") }),
|
1512
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("p", { className: "text-base text-gray-600", children: [
|
1513
|
+
t("description"),
|
1514
|
+
" ",
|
1515
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "text-purple-500 font-semibold", children: detectedLocale === "zh" ? "\u4E2D\u6587" : "English" }),
|
1516
|
+
"?"
|
1517
|
+
] })
|
1518
|
+
] }),
|
1519
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
1520
|
+
"button",
|
1521
|
+
{
|
1522
|
+
onClick: handleClose,
|
1523
|
+
className: "text-gray-500 hover:text-gray-700",
|
1524
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(globalLucideIcons.X, { className: "h-5 w-5" })
|
1525
|
+
}
|
1526
|
+
)
|
1527
|
+
] }),
|
1528
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex items-center gap-3", children: [
|
1529
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
1530
|
+
"button",
|
1531
|
+
{
|
1532
|
+
onClick: handleClose,
|
1533
|
+
className: "flex-1 px-4 py-2 text-base bg-gray-100 text-gray-600 rounded-md hover:bg-gray-200",
|
1534
|
+
children: t("close")
|
1535
|
+
}
|
1536
|
+
),
|
1537
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
1538
|
+
"button",
|
1539
|
+
{
|
1540
|
+
onClick: handleLanguageChange,
|
1541
|
+
className: "flex-1 px-4 py-2 text-base bg-purple-500 text-white rounded-md hover:bg-purple-600",
|
1542
|
+
children: t("changeAction")
|
1543
|
+
}
|
1544
|
+
)
|
1545
|
+
] })
|
1546
|
+
] }),
|
1547
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "absolute inset-0 bg-linear-to-r from-transparent via-purple-200/30 to-transparent animate-shimmer" })
|
1548
|
+
] }) }) });
|
1549
|
+
}
|
1447
1550
|
|
1448
1551
|
// src/components/language-switcher.tsx
|
1449
1552
|
var import_navigation2 = require("next/navigation");
|
@@ -1453,6 +1556,8 @@ var import_next_intl2 = require("next-intl");
|
|
1453
1556
|
var React30 = __toESM(require("react"));
|
1454
1557
|
var DropdownMenuPrimitive = __toESM(require("@radix-ui/react-dropdown-menu"));
|
1455
1558
|
var import_jsx_runtime35 = require("react/jsx-runtime");
|
1559
|
+
var DropdownMenu = DropdownMenuPrimitive.Root;
|
1560
|
+
var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
1456
1561
|
var DropdownMenuSubTrigger = React30.forwardRef((_a, ref) => {
|
1457
1562
|
var _b = _a, { className, inset, children } = _b, props = __objRest(_b, ["className", "inset", "children"]);
|
1458
1563
|
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
@@ -1627,6 +1732,49 @@ LanguageButton.displayName = "Button";
|
|
1627
1732
|
|
1628
1733
|
// src/components/language-switcher.tsx
|
1629
1734
|
var import_jsx_runtime37 = require("react/jsx-runtime");
|
1735
|
+
function LanguageSwitcher({ locales, localeLabels }) {
|
1736
|
+
const locale = (0, import_next_intl2.useLocale)();
|
1737
|
+
const router = (0, import_navigation2.useRouter)();
|
1738
|
+
const pathname = (0, import_navigation2.usePathname)();
|
1739
|
+
const handleLocaleChange = (newLocale) => {
|
1740
|
+
const newPathname = pathname.replace(`/${locale}`, `/${newLocale}`);
|
1741
|
+
router.push(newPathname);
|
1742
|
+
};
|
1743
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(DropdownMenu, { children: [
|
1744
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
1745
|
+
LanguageButton,
|
1746
|
+
{
|
1747
|
+
variant: "ghost",
|
1748
|
+
size: "icon",
|
1749
|
+
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",
|
1750
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(globalLucideIcons.Globe, { className: "h-5 w-5" })
|
1751
|
+
}
|
1752
|
+
) }),
|
1753
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
1754
|
+
DropdownMenuContent,
|
1755
|
+
{
|
1756
|
+
align: "end",
|
1757
|
+
sideOffset: 5,
|
1758
|
+
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]",
|
1759
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "grid grid-cols-2 gap-1", children: locales.map((loc) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
1760
|
+
DropdownMenuItem,
|
1761
|
+
{
|
1762
|
+
className: `
|
1763
|
+
px-2 py-2 text-sm cursor-pointer text-center justify-center
|
1764
|
+
transition-all duration-300 ease-in-out
|
1765
|
+
hover:scale-105 hover:shadow-md
|
1766
|
+
rounded-md whitespace-nowrap
|
1767
|
+
${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"}
|
1768
|
+
`,
|
1769
|
+
onClick: () => handleLocaleChange(loc),
|
1770
|
+
children: localeLabels[loc]
|
1771
|
+
},
|
1772
|
+
loc
|
1773
|
+
)) })
|
1774
|
+
}
|
1775
|
+
)
|
1776
|
+
] });
|
1777
|
+
}
|
1630
1778
|
|
1631
1779
|
// src/components/script/google-analytics-script.tsx
|
1632
1780
|
var import_script = __toESM(require("next/script"));
|
@@ -1677,10 +1825,25 @@ function useGoogleAnalytics() {
|
|
1677
1825
|
var import_script2 = __toESM(require("next/script"));
|
1678
1826
|
var import_jsx_runtime39 = require("react/jsx-runtime");
|
1679
1827
|
var microsoftClarityId = process.env.NEXT_PUBLIC_MICROSOFT_CLARITY_ID;
|
1828
|
+
function MicrosoftClarityScript() {
|
1829
|
+
if (process.env.NODE_ENV !== "production") {
|
1830
|
+
return null;
|
1831
|
+
}
|
1832
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_script2.default, { id: "microsoft-clarity", strategy: "afterInteractive", children: `
|
1833
|
+
(function(c,l,a,r,i,t,y){
|
1834
|
+
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
|
1835
|
+
t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
|
1836
|
+
y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
|
1837
|
+
})(window, document, "clarity", "script", "${microsoftClarityId}");
|
1838
|
+
` });
|
1839
|
+
}
|
1680
1840
|
// Annotate the CommonJS export names for ESM import in node:
|
1681
1841
|
0 && (module.exports = {
|
1682
1842
|
DefaultSiteIcon,
|
1683
1843
|
GoogleAnalyticsScript,
|
1844
|
+
LanguageDetector,
|
1845
|
+
LanguageSwitcher,
|
1846
|
+
MicrosoftClarityScript,
|
1684
1847
|
NotFoundIcon,
|
1685
1848
|
NotFoundPage,
|
1686
1849
|
getGlobalIcon,
|