@windrun-huaiin/base-ui 3.2.2 → 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 +29 -1
- package/dist/components/index.d.ts +29 -1
- package/dist/components/index.js +149 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +147 -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 +147 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +145 -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/dist/index.d.mts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, BadgeProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonProps, Calendar, CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Label, LanguageButton, LanguageButtonProps, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Slider, SonnerToaster, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toast, ToastAction, ToastActionElement, ToastClose, ToastDescription, ToastProps, ToastProvider, ToastTitle, ToastToaster, ToastViewport, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, navigationMenuTriggerStyle, reducer, toast, toggleVariants, useFormField, useIsMobile, useSidebar, useToast } from './ui/index.mjs';
|
2
|
-
export { DefaultSiteIcon, GoogleAnalyticsScript, MicrosoftClarityScript, NotFoundIcon, NotFoundPage, getGlobalIcon, getIconElement, globalLucideIcons, useGoogleAnalytics } from './components/index.mjs';
|
2
|
+
export { DefaultSiteIcon, GoogleAnalyticsScript, LanguageDetector, LanguageSwitcher, MicrosoftClarityScript, NotFoundIcon, NotFoundPage, getGlobalIcon, getIconElement, globalLucideIcons, useGoogleAnalytics } from './components/index.mjs';
|
3
3
|
export { IconConfig, IconConfigProvider, SiteIcon } from './lib/index.mjs';
|
4
4
|
import 'react';
|
5
5
|
import '@radix-ui/react-accordion';
|
package/dist/index.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AspectRatio, Avatar, AvatarFallback, AvatarImage, Badge, BadgeProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonProps, Calendar, CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselApi, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Label, LanguageButton, LanguageButtonProps, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Slider, SonnerToaster, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toast, ToastAction, ToastActionElement, ToastClose, ToastDescription, ToastProps, ToastProvider, ToastTitle, ToastToaster, ToastViewport, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, navigationMenuTriggerStyle, reducer, toast, toggleVariants, useFormField, useIsMobile, useSidebar, useToast } from './ui/index.js';
|
2
|
-
export { DefaultSiteIcon, GoogleAnalyticsScript, MicrosoftClarityScript, NotFoundIcon, NotFoundPage, getGlobalIcon, getIconElement, globalLucideIcons, useGoogleAnalytics } from './components/index.js';
|
2
|
+
export { DefaultSiteIcon, GoogleAnalyticsScript, LanguageDetector, LanguageSwitcher, MicrosoftClarityScript, NotFoundIcon, NotFoundPage, getGlobalIcon, getIconElement, globalLucideIcons, useGoogleAnalytics } from './components/index.js';
|
3
3
|
export { IconConfig, IconConfigProvider, SiteIcon } from './lib/index.js';
|
4
4
|
import 'react';
|
5
5
|
import '@radix-ui/react-accordion';
|
package/dist/index.js
CHANGED
@@ -192,6 +192,8 @@ __export(index_exports, {
|
|
192
192
|
InputOTPSlot: () => InputOTPSlot,
|
193
193
|
Label: () => Label3,
|
194
194
|
LanguageButton: () => LanguageButton,
|
195
|
+
LanguageDetector: () => LanguageDetector,
|
196
|
+
LanguageSwitcher: () => LanguageSwitcher,
|
195
197
|
Menubar: () => Menubar,
|
196
198
|
MenubarCheckboxItem: () => MenubarCheckboxItem,
|
197
199
|
MenubarContent: () => MenubarContent,
|
@@ -5720,11 +5722,154 @@ var import_next_intl = require("next-intl");
|
|
5720
5722
|
var import_navigation = require("next/navigation");
|
5721
5723
|
var import_react33 = require("react");
|
5722
5724
|
var import_jsx_runtime81 = require("react/jsx-runtime");
|
5725
|
+
function LanguageDetector({ i18nConfig }) {
|
5726
|
+
const [show, setShow] = (0, import_react33.useState)(false);
|
5727
|
+
const [detectedLocale, setDetectedLocale] = (0, import_react33.useState)(null);
|
5728
|
+
const currentLocale = (0, import_next_intl.useLocale)();
|
5729
|
+
const router = (0, import_navigation.useRouter)();
|
5730
|
+
const t = (0, import_next_intl.useTranslations)("languageDetection");
|
5731
|
+
const LANGUAGE_PREFERENCE_KEY = `${i18nConfig.detector.storagePrefix}-${i18nConfig.detector.storageKey}`;
|
5732
|
+
(0, import_react33.useEffect)(() => {
|
5733
|
+
const browserLang = navigator.language.split("-")[0];
|
5734
|
+
const savedPreference = localStorage.getItem(LANGUAGE_PREFERENCE_KEY);
|
5735
|
+
const preference = savedPreference ? JSON.parse(savedPreference) : null;
|
5736
|
+
const shouldShowDetector = () => {
|
5737
|
+
if (!preference) return true;
|
5738
|
+
if (preference.locale === currentLocale) return false;
|
5739
|
+
if (preference.status === "rejected" && preference.locale === browserLang) return false;
|
5740
|
+
if (preference.status === "accepted" && preference.locale === currentLocale) return false;
|
5741
|
+
const expirationMs = i18nConfig.detector.expirationDays * 24 * 60 * 60 * 1e3;
|
5742
|
+
if (Date.now() - preference.timestamp < expirationMs) return false;
|
5743
|
+
return true;
|
5744
|
+
};
|
5745
|
+
if (i18nConfig.locales.includes(browserLang) && browserLang !== currentLocale && shouldShowDetector()) {
|
5746
|
+
setDetectedLocale(browserLang);
|
5747
|
+
setShow(true);
|
5748
|
+
const timer = setTimeout(() => {
|
5749
|
+
console.log("[LanguageDetector] Auto closing after timeout");
|
5750
|
+
setShow(false);
|
5751
|
+
savePreference(browserLang, "rejected");
|
5752
|
+
}, i18nConfig.detector.autoCloseTimeout);
|
5753
|
+
return () => clearTimeout(timer);
|
5754
|
+
}
|
5755
|
+
}, [currentLocale]);
|
5756
|
+
const savePreference = (locale, status) => {
|
5757
|
+
const preference = {
|
5758
|
+
locale,
|
5759
|
+
status,
|
5760
|
+
timestamp: Date.now()
|
5761
|
+
};
|
5762
|
+
localStorage.setItem(LANGUAGE_PREFERENCE_KEY, JSON.stringify(preference));
|
5763
|
+
};
|
5764
|
+
const handleLanguageChange = () => {
|
5765
|
+
if (detectedLocale) {
|
5766
|
+
savePreference(detectedLocale, "accepted");
|
5767
|
+
const pathname = window.location.pathname;
|
5768
|
+
const newPathname = pathname.replace(`/${currentLocale}`, `/${detectedLocale}`);
|
5769
|
+
router.push(newPathname);
|
5770
|
+
setShow(false);
|
5771
|
+
}
|
5772
|
+
};
|
5773
|
+
const handleClose = () => {
|
5774
|
+
if (detectedLocale) {
|
5775
|
+
savePreference(detectedLocale, "rejected");
|
5776
|
+
}
|
5777
|
+
setShow(false);
|
5778
|
+
};
|
5779
|
+
if (!detectedLocale || !show) return null;
|
5780
|
+
return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "fixed top-16 right-4 z-40 w-[420px]", children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: `shadow-lg rounded-lg transition-all duration-300 ${show ? "translate-x-0 opacity-100" : "translate-x-full opacity-0"}
|
5781
|
+
bg-linear-to-r from-purple-100/95 via-white/95 to-purple-100/95 backdrop-blur-xs
|
5782
|
+
animate-gradient-x`, children: /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "relative px-6 py-4 overflow-hidden", children: [
|
5783
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "relative z-10 flex flex-col gap-3", children: [
|
5784
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "flex items-start justify-between gap-4", children: [
|
5785
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
|
5786
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("h3", { className: "text-lg font-semibold text-gray-900", children: t("title") }),
|
5787
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("p", { className: "text-base text-gray-600", children: [
|
5788
|
+
t("description"),
|
5789
|
+
" ",
|
5790
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { className: "text-purple-500 font-semibold", children: detectedLocale === "zh" ? "\u4E2D\u6587" : "English" }),
|
5791
|
+
"?"
|
5792
|
+
] })
|
5793
|
+
] }),
|
5794
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
5795
|
+
"button",
|
5796
|
+
{
|
5797
|
+
onClick: handleClose,
|
5798
|
+
className: "text-gray-500 hover:text-gray-700",
|
5799
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(globalLucideIcons.X, { className: "h-5 w-5" })
|
5800
|
+
}
|
5801
|
+
)
|
5802
|
+
] }),
|
5803
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "flex items-center gap-3", children: [
|
5804
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
5805
|
+
"button",
|
5806
|
+
{
|
5807
|
+
onClick: handleClose,
|
5808
|
+
className: "flex-1 px-4 py-2 text-base bg-gray-100 text-gray-600 rounded-md hover:bg-gray-200",
|
5809
|
+
children: t("close")
|
5810
|
+
}
|
5811
|
+
),
|
5812
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)(
|
5813
|
+
"button",
|
5814
|
+
{
|
5815
|
+
onClick: handleLanguageChange,
|
5816
|
+
className: "flex-1 px-4 py-2 text-base bg-purple-500 text-white rounded-md hover:bg-purple-600",
|
5817
|
+
children: t("changeAction")
|
5818
|
+
}
|
5819
|
+
)
|
5820
|
+
] })
|
5821
|
+
] }),
|
5822
|
+
/* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "absolute inset-0 bg-linear-to-r from-transparent via-purple-200/30 to-transparent animate-shimmer" })
|
5823
|
+
] }) }) });
|
5824
|
+
}
|
5723
5825
|
|
5724
5826
|
// src/components/language-switcher.tsx
|
5725
5827
|
var import_navigation2 = require("next/navigation");
|
5726
5828
|
var import_next_intl2 = require("next-intl");
|
5727
5829
|
var import_jsx_runtime82 = require("react/jsx-runtime");
|
5830
|
+
function LanguageSwitcher({ locales, localeLabels }) {
|
5831
|
+
const locale = (0, import_next_intl2.useLocale)();
|
5832
|
+
const router = (0, import_navigation2.useRouter)();
|
5833
|
+
const pathname = (0, import_navigation2.usePathname)();
|
5834
|
+
const handleLocaleChange = (newLocale) => {
|
5835
|
+
const newPathname = pathname.replace(`/${locale}`, `/${newLocale}`);
|
5836
|
+
router.push(newPathname);
|
5837
|
+
};
|
5838
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)(DropdownMenu, { children: [
|
5839
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
5840
|
+
LanguageButton,
|
5841
|
+
{
|
5842
|
+
variant: "ghost",
|
5843
|
+
size: "icon",
|
5844
|
+
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",
|
5845
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(globalLucideIcons.Globe, { className: "h-5 w-5" })
|
5846
|
+
}
|
5847
|
+
) }),
|
5848
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
5849
|
+
DropdownMenuContent,
|
5850
|
+
{
|
5851
|
+
align: "end",
|
5852
|
+
sideOffset: 5,
|
5853
|
+
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]",
|
5854
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "grid grid-cols-2 gap-1", children: locales.map((loc) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(
|
5855
|
+
DropdownMenuItem,
|
5856
|
+
{
|
5857
|
+
className: `
|
5858
|
+
px-2 py-2 text-sm cursor-pointer text-center justify-center
|
5859
|
+
transition-all duration-300 ease-in-out
|
5860
|
+
hover:scale-105 hover:shadow-md
|
5861
|
+
rounded-md whitespace-nowrap
|
5862
|
+
${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"}
|
5863
|
+
`,
|
5864
|
+
onClick: () => handleLocaleChange(loc),
|
5865
|
+
children: localeLabels[loc]
|
5866
|
+
},
|
5867
|
+
loc
|
5868
|
+
)) })
|
5869
|
+
}
|
5870
|
+
)
|
5871
|
+
] });
|
5872
|
+
}
|
5728
5873
|
|
5729
5874
|
// src/components/script/google-analytics-script.tsx
|
5730
5875
|
var import_script = __toESM(require("next/script"));
|
@@ -5921,6 +6066,8 @@ function MicrosoftClarityScript() {
|
|
5921
6066
|
InputOTPSlot,
|
5922
6067
|
Label,
|
5923
6068
|
LanguageButton,
|
6069
|
+
LanguageDetector,
|
6070
|
+
LanguageSwitcher,
|
5924
6071
|
Menubar,
|
5925
6072
|
MenubarCheckboxItem,
|
5926
6073
|
MenubarContent,
|