@underverse-ui/underverse 0.1.11 → 0.1.13

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.d.cts CHANGED
@@ -888,6 +888,36 @@ interface AccessDeniedProps {
888
888
  }
889
889
  declare function AccessDenied({ title, description, variant, icon: Icon, className, children, }: AccessDeniedProps): react_jsx_runtime.JSX.Element;
890
890
 
891
+ type ThemeMode = "light" | "dark" | "system";
892
+ interface ThemeToggleHeadlessProps {
893
+ theme: ThemeMode;
894
+ onChange: (theme: ThemeMode) => void;
895
+ labels?: {
896
+ heading?: string;
897
+ light?: string;
898
+ dark?: string;
899
+ system?: string;
900
+ };
901
+ className?: string;
902
+ }
903
+ declare function ThemeToggleHeadless({ theme, onChange, labels, className, }: ThemeToggleHeadlessProps): react_jsx_runtime.JSX.Element;
904
+
905
+ interface LanguageOption {
906
+ code: string;
907
+ name: string;
908
+ flag?: string;
909
+ }
910
+ interface LanguageSwitcherHeadlessProps {
911
+ locales: LanguageOption[];
912
+ currentLocale: string;
913
+ onSwitch: (code: string) => void;
914
+ labels?: {
915
+ heading?: string;
916
+ };
917
+ className?: string;
918
+ }
919
+ declare function LanguageSwitcherHeadless({ locales, currentLocale, onSwitch, labels, className, }: LanguageSwitcherHeadlessProps): react_jsx_runtime.JSX.Element;
920
+
891
921
  declare function cn(...inputs: ClassValue[]): string;
892
922
 
893
923
  /**
@@ -1241,4 +1271,4 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
1241
1271
  };
1242
1272
  };
1243
1273
 
1244
- export { AccessDenied, Alert, Avatar, Badge, Badge as BadgeBase, BottomSheet, Breadcrumb, Button, ButtonLoading, type ButtonProps, Card, Carousel, CategoryTreeSelect, Checkbox, type CheckboxProps, ClientOnly, Combobox, type ComboboxProps, CompactPagination, type CompactPaginationProps, DataTable, type DataTableColumn, type DataTableQuery, DatePicker, type DatePickerProps, DateRangePicker, date as DateUtils, Drawer, DropdownMenu, FloatingContacts, Form, FormActions, FormCheckbox, FormControl, FormDescription, FormField, FormInput, FormItem, FormLabel, FormMessage, FormSubmitButton, GlobalLoading, GradientBadge, ImageUpload, InlineLoading, Input, type InputProps, InteractiveBadge, Label, LoadingBar, LoadingDots, LoadingSpinner, Modal, MultiCombobox, type MultiComboboxProps, NotificationBadge, NotificationModal, NumberInput, PageLoading, Pagination, type PaginationProps, PasswordInput, PillTabs, Popover, Progress, PulseBadge, RadioGroup, SIZE_STYLES_BTN, ScrollArea, Section, Sheet, SidebarSheet, SimplePagination, type SimplePaginationProps, SimpleTabs, Skeleton, SlideOver, Slider, SmartImage, type Sorter, StatusBadge, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TagBadge, Textarea, ToastProvider, Tooltip, type UnderverseLocale, VARIANT_STYLES_ALERT, VARIANT_STYLES_BTN, VerticalTabs, cn, getUnderverseMessages, underverseMessages, useFormField, useToast };
1274
+ export { AccessDenied, Alert, Avatar, Badge, Badge as BadgeBase, BottomSheet, Breadcrumb, Button, ButtonLoading, type ButtonProps, Card, Carousel, CategoryTreeSelect, Checkbox, type CheckboxProps, ClientOnly, Combobox, type ComboboxProps, CompactPagination, type CompactPaginationProps, DataTable, type DataTableColumn, type DataTableQuery, DatePicker, type DatePickerProps, DateRangePicker, date as DateUtils, Drawer, DropdownMenu, FloatingContacts, Form, FormActions, FormCheckbox, FormControl, FormDescription, FormField, FormInput, FormItem, FormLabel, FormMessage, FormSubmitButton, GlobalLoading, GradientBadge, ImageUpload, InlineLoading, Input, type InputProps, InteractiveBadge, Label, type LanguageOption, LanguageSwitcherHeadless as LanguageSwitcher, LanguageSwitcherHeadless, type LanguageSwitcherHeadlessProps, type LanguageSwitcherHeadlessProps as LanguageSwitcherProps, LoadingBar, LoadingDots, LoadingSpinner, Modal, MultiCombobox, type MultiComboboxProps, NotificationBadge, NotificationModal, NumberInput, PageLoading, Pagination, type PaginationProps, PasswordInput, PillTabs, Popover, Progress, PulseBadge, RadioGroup, SIZE_STYLES_BTN, ScrollArea, Section, Sheet, SidebarSheet, SimplePagination, type SimplePaginationProps, SimpleTabs, Skeleton, SlideOver, Slider, SmartImage, type Sorter, StatusBadge, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TagBadge, Textarea, type ThemeMode, ThemeToggleHeadless as ThemeToggle, ThemeToggleHeadless, type ThemeToggleHeadlessProps, type ThemeToggleHeadlessProps as ThemeToggleProps, ToastProvider, Tooltip, type UnderverseLocale, VARIANT_STYLES_ALERT, VARIANT_STYLES_BTN, VerticalTabs, cn, getUnderverseMessages, underverseMessages, useFormField, useToast };
package/dist/index.d.ts CHANGED
@@ -888,6 +888,36 @@ interface AccessDeniedProps {
888
888
  }
889
889
  declare function AccessDenied({ title, description, variant, icon: Icon, className, children, }: AccessDeniedProps): react_jsx_runtime.JSX.Element;
890
890
 
891
+ type ThemeMode = "light" | "dark" | "system";
892
+ interface ThemeToggleHeadlessProps {
893
+ theme: ThemeMode;
894
+ onChange: (theme: ThemeMode) => void;
895
+ labels?: {
896
+ heading?: string;
897
+ light?: string;
898
+ dark?: string;
899
+ system?: string;
900
+ };
901
+ className?: string;
902
+ }
903
+ declare function ThemeToggleHeadless({ theme, onChange, labels, className, }: ThemeToggleHeadlessProps): react_jsx_runtime.JSX.Element;
904
+
905
+ interface LanguageOption {
906
+ code: string;
907
+ name: string;
908
+ flag?: string;
909
+ }
910
+ interface LanguageSwitcherHeadlessProps {
911
+ locales: LanguageOption[];
912
+ currentLocale: string;
913
+ onSwitch: (code: string) => void;
914
+ labels?: {
915
+ heading?: string;
916
+ };
917
+ className?: string;
918
+ }
919
+ declare function LanguageSwitcherHeadless({ locales, currentLocale, onSwitch, labels, className, }: LanguageSwitcherHeadlessProps): react_jsx_runtime.JSX.Element;
920
+
891
921
  declare function cn(...inputs: ClassValue[]): string;
892
922
 
893
923
  /**
@@ -1241,4 +1271,4 @@ declare function getUnderverseMessages(locale?: UnderverseLocale): {
1241
1271
  };
1242
1272
  };
1243
1273
 
1244
- export { AccessDenied, Alert, Avatar, Badge, Badge as BadgeBase, BottomSheet, Breadcrumb, Button, ButtonLoading, type ButtonProps, Card, Carousel, CategoryTreeSelect, Checkbox, type CheckboxProps, ClientOnly, Combobox, type ComboboxProps, CompactPagination, type CompactPaginationProps, DataTable, type DataTableColumn, type DataTableQuery, DatePicker, type DatePickerProps, DateRangePicker, date as DateUtils, Drawer, DropdownMenu, FloatingContacts, Form, FormActions, FormCheckbox, FormControl, FormDescription, FormField, FormInput, FormItem, FormLabel, FormMessage, FormSubmitButton, GlobalLoading, GradientBadge, ImageUpload, InlineLoading, Input, type InputProps, InteractiveBadge, Label, LoadingBar, LoadingDots, LoadingSpinner, Modal, MultiCombobox, type MultiComboboxProps, NotificationBadge, NotificationModal, NumberInput, PageLoading, Pagination, type PaginationProps, PasswordInput, PillTabs, Popover, Progress, PulseBadge, RadioGroup, SIZE_STYLES_BTN, ScrollArea, Section, Sheet, SidebarSheet, SimplePagination, type SimplePaginationProps, SimpleTabs, Skeleton, SlideOver, Slider, SmartImage, type Sorter, StatusBadge, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TagBadge, Textarea, ToastProvider, Tooltip, type UnderverseLocale, VARIANT_STYLES_ALERT, VARIANT_STYLES_BTN, VerticalTabs, cn, getUnderverseMessages, underverseMessages, useFormField, useToast };
1274
+ export { AccessDenied, Alert, Avatar, Badge, Badge as BadgeBase, BottomSheet, Breadcrumb, Button, ButtonLoading, type ButtonProps, Card, Carousel, CategoryTreeSelect, Checkbox, type CheckboxProps, ClientOnly, Combobox, type ComboboxProps, CompactPagination, type CompactPaginationProps, DataTable, type DataTableColumn, type DataTableQuery, DatePicker, type DatePickerProps, DateRangePicker, date as DateUtils, Drawer, DropdownMenu, FloatingContacts, Form, FormActions, FormCheckbox, FormControl, FormDescription, FormField, FormInput, FormItem, FormLabel, FormMessage, FormSubmitButton, GlobalLoading, GradientBadge, ImageUpload, InlineLoading, Input, type InputProps, InteractiveBadge, Label, type LanguageOption, LanguageSwitcherHeadless as LanguageSwitcher, LanguageSwitcherHeadless, type LanguageSwitcherHeadlessProps, type LanguageSwitcherHeadlessProps as LanguageSwitcherProps, LoadingBar, LoadingDots, LoadingSpinner, Modal, MultiCombobox, type MultiComboboxProps, NotificationBadge, NotificationModal, NumberInput, PageLoading, Pagination, type PaginationProps, PasswordInput, PillTabs, Popover, Progress, PulseBadge, RadioGroup, SIZE_STYLES_BTN, ScrollArea, Section, Sheet, SidebarSheet, SimplePagination, type SimplePaginationProps, SimpleTabs, Skeleton, SlideOver, Slider, SmartImage, type Sorter, StatusBadge, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TagBadge, Textarea, type ThemeMode, ThemeToggleHeadless as ThemeToggle, ThemeToggleHeadless, type ThemeToggleHeadlessProps, type ThemeToggleHeadlessProps as ThemeToggleProps, ToastProvider, Tooltip, type UnderverseLocale, VARIANT_STYLES_ALERT, VARIANT_STYLES_BTN, VerticalTabs, cn, getUnderverseMessages, underverseMessages, useFormField, useToast };
package/dist/index.js CHANGED
@@ -8485,6 +8485,199 @@ function AccessDenied({
8485
8485
  ] }) });
8486
8486
  }
8487
8487
 
8488
+ // ../../components/ui/ThemeToggleHeadless.tsx
8489
+ import { Moon, Sun, Monitor } from "lucide-react";
8490
+ import { useEffect as useEffect17, useRef as useRef10, useState as useState27 } from "react";
8491
+ import { createPortal as createPortal9 } from "react-dom";
8492
+ import { Fragment as Fragment10, jsx as jsx43, jsxs as jsxs37 } from "react/jsx-runtime";
8493
+ function ThemeToggleHeadless({
8494
+ theme,
8495
+ onChange,
8496
+ labels,
8497
+ className
8498
+ }) {
8499
+ const [isOpen, setIsOpen] = useState27(false);
8500
+ const [mounted, setMounted] = useState27(false);
8501
+ const triggerRef = useRef10(null);
8502
+ const [dropdownPosition, setDropdownPosition] = useState27(null);
8503
+ useEffect17(() => setMounted(true), []);
8504
+ const themes = [
8505
+ { value: "light", label: labels?.light ?? "Light", icon: Sun },
8506
+ { value: "dark", label: labels?.dark ?? "Dark", icon: Moon },
8507
+ { value: "system", label: labels?.system ?? "System", icon: Monitor }
8508
+ ];
8509
+ const current = mounted ? themes.find((t) => t.value === theme) || themes[2] : themes[2];
8510
+ const CurrentIcon = current.icon;
8511
+ const calculatePosition = () => {
8512
+ const rect = triggerRef.current?.getBoundingClientRect();
8513
+ if (!rect) return null;
8514
+ const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
8515
+ const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
8516
+ const width = 192;
8517
+ const left = rect.right + scrollLeft - width;
8518
+ const top = rect.bottom + scrollTop + 8;
8519
+ return { top, left, width };
8520
+ };
8521
+ return /* @__PURE__ */ jsxs37("div", { className: cn("relative", className), children: [
8522
+ /* @__PURE__ */ jsx43(
8523
+ Button_default,
8524
+ {
8525
+ variant: "ghost",
8526
+ size: "icon",
8527
+ ref: triggerRef,
8528
+ onClick: () => {
8529
+ const next = !isOpen;
8530
+ if (next) {
8531
+ const pos = calculatePosition();
8532
+ if (pos) setDropdownPosition(pos);
8533
+ }
8534
+ setIsOpen(next);
8535
+ },
8536
+ className: "bg-muted hover:bg-accent",
8537
+ "aria-haspopup": "menu",
8538
+ "aria-expanded": isOpen,
8539
+ "aria-label": labels?.heading ?? "Theme",
8540
+ children: /* @__PURE__ */ jsx43(CurrentIcon, { className: "h-5 w-5" })
8541
+ }
8542
+ ),
8543
+ isOpen && /* @__PURE__ */ jsxs37(Fragment10, { children: [
8544
+ typeof window !== "undefined" && createPortal9(/* @__PURE__ */ jsx43("div", { className: "fixed inset-0 z-[9998]", onClick: () => setIsOpen(false) }), document.body),
8545
+ typeof window !== "undefined" && dropdownPosition && createPortal9(
8546
+ /* @__PURE__ */ jsx43(
8547
+ "div",
8548
+ {
8549
+ className: "z-[9999] bg-card border border-border rounded-lg shadow-lg overflow-hidden",
8550
+ style: { position: "absolute", top: dropdownPosition.top, left: dropdownPosition.left, width: dropdownPosition.width },
8551
+ onMouseDown: (e) => e.stopPropagation(),
8552
+ role: "menu",
8553
+ children: /* @__PURE__ */ jsxs37("div", { className: "p-2", children: [
8554
+ /* @__PURE__ */ jsx43("div", { className: "px-3 py-2 text-sm font-medium text-muted-foreground border-b border-border mb-2", children: labels?.heading ?? "Theme" }),
8555
+ themes.map((opt) => {
8556
+ const Icon = opt.icon;
8557
+ const active = theme === opt.value;
8558
+ return /* @__PURE__ */ jsxs37(
8559
+ Button_default,
8560
+ {
8561
+ variant: "ghost",
8562
+ size: "sm",
8563
+ onClick: () => {
8564
+ onChange(opt.value);
8565
+ setIsOpen(false);
8566
+ },
8567
+ className: cn(
8568
+ "w-full justify-start gap-3 h-auto py-2 px-3",
8569
+ active && "bg-primary/10 text-primary"
8570
+ ),
8571
+ role: "menuitemradio",
8572
+ "aria-checked": active,
8573
+ children: [
8574
+ /* @__PURE__ */ jsx43(Icon, { className: "h-4 w-4" }),
8575
+ /* @__PURE__ */ jsx43("span", { className: "flex-1 text-left", children: opt.label }),
8576
+ active && /* @__PURE__ */ jsx43("div", { className: "w-2 h-2 rounded-full bg-primary" })
8577
+ ]
8578
+ },
8579
+ opt.value
8580
+ );
8581
+ })
8582
+ ] })
8583
+ }
8584
+ ),
8585
+ document.body
8586
+ )
8587
+ ] })
8588
+ ] });
8589
+ }
8590
+
8591
+ // ../../components/ui/LanguageSwitcherHeadless.tsx
8592
+ import { useRef as useRef11, useState as useState28 } from "react";
8593
+ import { createPortal as createPortal10 } from "react-dom";
8594
+ import { Globe } from "lucide-react";
8595
+ import { Fragment as Fragment11, jsx as jsx44, jsxs as jsxs38 } from "react/jsx-runtime";
8596
+ function LanguageSwitcherHeadless({
8597
+ locales,
8598
+ currentLocale,
8599
+ onSwitch,
8600
+ labels,
8601
+ className
8602
+ }) {
8603
+ const [isOpen, setIsOpen] = useState28(false);
8604
+ const [dropdownPosition, setDropdownPosition] = useState28(null);
8605
+ const triggerButtonRef = useRef11(null);
8606
+ const currentLanguage = locales.find((l) => l.code === currentLocale) || locales[0];
8607
+ const calculatePosition = () => {
8608
+ const rect = triggerButtonRef.current?.getBoundingClientRect();
8609
+ if (!rect) return null;
8610
+ const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
8611
+ const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
8612
+ const width = 192;
8613
+ const left = rect.right + scrollLeft - width;
8614
+ const top = rect.bottom + scrollTop + 8;
8615
+ return { top, left, width };
8616
+ };
8617
+ return /* @__PURE__ */ jsxs38("div", { className: cn("relative", className), children: [
8618
+ /* @__PURE__ */ jsx44(
8619
+ Button_default,
8620
+ {
8621
+ variant: "ghost",
8622
+ size: "icon",
8623
+ ref: triggerButtonRef,
8624
+ onClick: () => {
8625
+ const next = !isOpen;
8626
+ if (next) {
8627
+ const pos = calculatePosition();
8628
+ if (pos) setDropdownPosition(pos);
8629
+ }
8630
+ setIsOpen(next);
8631
+ },
8632
+ className: "bg-muted hover:bg-accent",
8633
+ "aria-haspopup": "menu",
8634
+ "aria-expanded": isOpen,
8635
+ "aria-label": labels?.heading ?? "Language",
8636
+ title: labels?.heading ?? "Language",
8637
+ children: /* @__PURE__ */ jsx44(Globe, { className: "h-5 w-5" })
8638
+ }
8639
+ ),
8640
+ isOpen && /* @__PURE__ */ jsxs38(Fragment11, { children: [
8641
+ typeof window !== "undefined" && createPortal10(/* @__PURE__ */ jsx44("div", { className: "fixed inset-0 z-[9998]", onClick: () => setIsOpen(false) }), document.body),
8642
+ typeof window !== "undefined" && dropdownPosition && createPortal10(
8643
+ /* @__PURE__ */ jsx44(
8644
+ "div",
8645
+ {
8646
+ className: "z-[9999] bg-card border border-border rounded-lg shadow-lg overflow-hidden",
8647
+ style: { position: "absolute", top: dropdownPosition.top, left: dropdownPosition.left, width: dropdownPosition.width },
8648
+ onMouseDown: (e) => e.stopPropagation(),
8649
+ role: "menu",
8650
+ children: /* @__PURE__ */ jsxs38("div", { className: "p-2", children: [
8651
+ /* @__PURE__ */ jsx44("div", { className: "px-3 py-2 text-sm font-medium text-muted-foreground border-b border-border mb-2", children: labels?.heading ?? "Language" }),
8652
+ locales.map((language) => /* @__PURE__ */ jsxs38(
8653
+ Button_default,
8654
+ {
8655
+ variant: "ghost",
8656
+ size: "sm",
8657
+ onClick: () => {
8658
+ onSwitch(language.code);
8659
+ setIsOpen(false);
8660
+ },
8661
+ className: cn("w-full justify-start gap-3 h-auto py-2 px-3", currentLocale === language.code && "bg-primary/10 text-primary"),
8662
+ role: "menuitemradio",
8663
+ "aria-checked": currentLocale === language.code,
8664
+ children: [
8665
+ language.flag && /* @__PURE__ */ jsx44("span", { className: "text-lg", children: language.flag }),
8666
+ /* @__PURE__ */ jsx44("span", { className: "flex-1 text-left", children: language.name }),
8667
+ currentLocale === language.code && /* @__PURE__ */ jsx44("div", { className: "w-2 h-2 rounded-full bg-primary" })
8668
+ ]
8669
+ },
8670
+ language.code
8671
+ ))
8672
+ ] })
8673
+ }
8674
+ ),
8675
+ document.body
8676
+ )
8677
+ ] })
8678
+ ] });
8679
+ }
8680
+
8488
8681
  // locales/en.json
8489
8682
  var en_default = {
8490
8683
  Common: {
@@ -8658,6 +8851,8 @@ export {
8658
8851
  Input_default as Input,
8659
8852
  InteractiveBadge,
8660
8853
  Label,
8854
+ LanguageSwitcherHeadless as LanguageSwitcher,
8855
+ LanguageSwitcherHeadless,
8661
8856
  LoadingBar,
8662
8857
  LoadingDots,
8663
8858
  LoadingSpinner,
@@ -8698,6 +8893,8 @@ export {
8698
8893
  Tabs,
8699
8894
  TagBadge,
8700
8895
  Textarea_default as Textarea,
8896
+ ThemeToggleHeadless as ThemeToggle,
8897
+ ThemeToggleHeadless,
8701
8898
  Toast_default as ToastProvider,
8702
8899
  Tooltip,
8703
8900
  VARIANT_STYLES_ALERT,