@gv-tech/ui-web 2.6.0

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.
Files changed (56) hide show
  1. package/package.json +88 -0
  2. package/src/accordion.tsx +58 -0
  3. package/src/alert-dialog.tsx +121 -0
  4. package/src/alert.tsx +49 -0
  5. package/src/aspect-ratio.tsx +7 -0
  6. package/src/avatar.tsx +40 -0
  7. package/src/badge.tsx +34 -0
  8. package/src/breadcrumb.tsx +105 -0
  9. package/src/button.tsx +47 -0
  10. package/src/calendar.tsx +163 -0
  11. package/src/card.tsx +46 -0
  12. package/src/carousel.tsx +234 -0
  13. package/src/chart.tsx +296 -0
  14. package/src/checkbox.tsx +31 -0
  15. package/src/collapsible.tsx +15 -0
  16. package/src/command.tsx +154 -0
  17. package/src/context-menu.tsx +208 -0
  18. package/src/dialog.tsx +95 -0
  19. package/src/drawer.tsx +110 -0
  20. package/src/dropdown-menu.tsx +212 -0
  21. package/src/form.tsx +160 -0
  22. package/src/hooks/use-theme.ts +15 -0
  23. package/src/hooks/use-toast.ts +189 -0
  24. package/src/hover-card.tsx +35 -0
  25. package/src/index.ts +474 -0
  26. package/src/input.tsx +23 -0
  27. package/src/label.tsx +21 -0
  28. package/src/lib/utils.ts +6 -0
  29. package/src/menubar.tsx +244 -0
  30. package/src/navigation-menu.tsx +143 -0
  31. package/src/pagination.tsx +107 -0
  32. package/src/popover.tsx +45 -0
  33. package/src/progress.tsx +28 -0
  34. package/src/radio-group.tsx +41 -0
  35. package/src/resizable.tsx +59 -0
  36. package/src/scroll-area.tsx +42 -0
  37. package/src/search.tsx +87 -0
  38. package/src/select.tsx +169 -0
  39. package/src/separator.tsx +24 -0
  40. package/src/setupTests.ts +114 -0
  41. package/src/sheet.tsx +136 -0
  42. package/src/skeleton.tsx +10 -0
  43. package/src/slider.tsx +27 -0
  44. package/src/sonner.tsx +32 -0
  45. package/src/switch.tsx +31 -0
  46. package/src/table.tsx +104 -0
  47. package/src/tabs.tsx +62 -0
  48. package/src/text.tsx +55 -0
  49. package/src/textarea.tsx +25 -0
  50. package/src/theme-provider.tsx +15 -0
  51. package/src/theme-toggle.tsx +92 -0
  52. package/src/toast.tsx +111 -0
  53. package/src/toaster.tsx +27 -0
  54. package/src/toggle-group.tsx +55 -0
  55. package/src/toggle.tsx +24 -0
  56. package/src/tooltip.tsx +51 -0
package/src/table.tsx ADDED
@@ -0,0 +1,104 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+
5
+ import {
6
+ TableBaseProps,
7
+ TableBodyBaseProps,
8
+ TableCaptionBaseProps,
9
+ TableCellBaseProps,
10
+ TableFooterBaseProps,
11
+ TableHeadBaseProps,
12
+ TableHeaderBaseProps,
13
+ TableRowBaseProps,
14
+ } from '@gv-tech/ui-core';
15
+ import { cn } from './lib/utils';
16
+
17
+ const Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement> & TableBaseProps>(
18
+ ({ className, ...props }, ref) => (
19
+ <div className="relative w-full overflow-auto">
20
+ <table ref={ref} className={cn('w-full caption-bottom text-sm', className)} {...props} />
21
+ </div>
22
+ ),
23
+ );
24
+ Table.displayName = 'Table';
25
+
26
+ const TableHeader = React.forwardRef<
27
+ HTMLTableSectionElement,
28
+ React.HTMLAttributes<HTMLTableSectionElement> & TableHeaderBaseProps
29
+ >(({ className, ...props }, ref) => <thead ref={ref} className={cn('[&_tr]:border-b', className)} {...props} />);
30
+ TableHeader.displayName = 'TableHeader';
31
+
32
+ const TableBody = React.forwardRef<
33
+ HTMLTableSectionElement,
34
+ React.HTMLAttributes<HTMLTableSectionElement> & TableBodyBaseProps
35
+ >(({ className, ...props }, ref) => (
36
+ <tbody ref={ref} className={cn('[&_tr:last-child]:border-0', className)} {...props} />
37
+ ));
38
+ TableBody.displayName = 'TableBody';
39
+
40
+ const TableFooter = React.forwardRef<
41
+ HTMLTableSectionElement,
42
+ React.HTMLAttributes<HTMLTableSectionElement> & TableFooterBaseProps
43
+ >(({ className, ...props }, ref) => (
44
+ <tfoot ref={ref} className={cn('border-t bg-muted/50 font-medium [&>tr]:last:border-b-0', className)} {...props} />
45
+ ));
46
+ TableFooter.displayName = 'TableFooter';
47
+
48
+ const TableRow = React.forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTMLTableRowElement> & TableRowBaseProps>(
49
+ ({ className, ...props }, ref) => (
50
+ <tr
51
+ ref={ref}
52
+ className={cn('border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted', className)}
53
+ {...props}
54
+ />
55
+ ),
56
+ );
57
+ TableRow.displayName = 'TableRow';
58
+
59
+ const TableHead = React.forwardRef<
60
+ HTMLTableCellElement,
61
+ React.ThHTMLAttributes<HTMLTableCellElement> & TableHeadBaseProps
62
+ >(({ className, ...props }, ref) => (
63
+ <th
64
+ ref={ref}
65
+ className={cn(
66
+ 'h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',
67
+ className,
68
+ )}
69
+ {...props}
70
+ />
71
+ ));
72
+ TableHead.displayName = 'TableHead';
73
+
74
+ const TableCell = React.forwardRef<
75
+ HTMLTableCellElement,
76
+ React.TdHTMLAttributes<HTMLTableCellElement> & TableCellBaseProps
77
+ >(({ className, ...props }, ref) => (
78
+ <td
79
+ ref={ref}
80
+ className={cn('p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]', className)}
81
+ {...props}
82
+ />
83
+ ));
84
+ TableCell.displayName = 'TableCell';
85
+
86
+ const TableCaption = React.forwardRef<
87
+ HTMLTableCaptionElement,
88
+ React.HTMLAttributes<HTMLTableCaptionElement> & TableCaptionBaseProps
89
+ >(({ className, ...props }, ref) => (
90
+ <caption ref={ref} className={cn('mt-4 text-sm text-muted-foreground', className)} {...props} />
91
+ ));
92
+ TableCaption.displayName = 'TableCaption';
93
+
94
+ export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };
95
+ export type {
96
+ TableBodyBaseProps as TableBodyProps,
97
+ TableCaptionBaseProps as TableCaptionProps,
98
+ TableCellBaseProps as TableCellProps,
99
+ TableFooterBaseProps as TableFooterProps,
100
+ TableHeaderBaseProps as TableHeaderProps,
101
+ TableHeadBaseProps as TableHeadProps,
102
+ TableBaseProps as TableProps,
103
+ TableRowBaseProps as TableRowProps,
104
+ };
package/src/tabs.tsx ADDED
@@ -0,0 +1,62 @@
1
+ 'use client';
2
+
3
+ import * as TabsPrimitive from '@radix-ui/react-tabs';
4
+ import * as React from 'react';
5
+
6
+ import { TabsBaseProps, TabsContentBaseProps, TabsListBaseProps, TabsTriggerBaseProps } from '@gv-tech/ui-core';
7
+ import { cn } from './lib/utils';
8
+
9
+ const Tabs = TabsPrimitive.Root;
10
+
11
+ const TabsList = React.forwardRef<
12
+ React.ElementRef<typeof TabsPrimitive.List>,
13
+ React.ComponentPropsWithoutRef<typeof TabsPrimitive.List> & TabsListBaseProps
14
+ >(({ className, ...props }, ref) => (
15
+ <TabsPrimitive.List
16
+ ref={ref}
17
+ className={cn(
18
+ 'inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground',
19
+ className,
20
+ )}
21
+ {...props}
22
+ />
23
+ ));
24
+ TabsList.displayName = TabsPrimitive.List.displayName;
25
+
26
+ const TabsTrigger = React.forwardRef<
27
+ React.ElementRef<typeof TabsPrimitive.Trigger>,
28
+ React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger> & TabsTriggerBaseProps
29
+ >(({ className, ...props }, ref) => (
30
+ <TabsPrimitive.Trigger
31
+ ref={ref}
32
+ className={cn(
33
+ 'inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow',
34
+ className,
35
+ )}
36
+ {...props}
37
+ />
38
+ ));
39
+ TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
40
+
41
+ const TabsContent = React.forwardRef<
42
+ React.ElementRef<typeof TabsPrimitive.Content>,
43
+ React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content> & TabsContentBaseProps
44
+ >(({ className, ...props }, ref) => (
45
+ <TabsPrimitive.Content
46
+ ref={ref}
47
+ className={cn(
48
+ 'mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
49
+ className,
50
+ )}
51
+ {...props}
52
+ />
53
+ ));
54
+ TabsContent.displayName = TabsPrimitive.Content.displayName;
55
+
56
+ export { Tabs, TabsContent, TabsList, TabsTrigger };
57
+ export type {
58
+ TabsContentBaseProps as TabsContentProps,
59
+ TabsListBaseProps as TabsListProps,
60
+ TabsBaseProps as TabsProps,
61
+ TabsTriggerBaseProps as TabsTriggerProps,
62
+ };
package/src/text.tsx ADDED
@@ -0,0 +1,55 @@
1
+ import { cva, type VariantProps } from 'class-variance-authority';
2
+ import * as React from 'react';
3
+
4
+ import type { TextBaseProps } from '@gv-tech/ui-core';
5
+ import { cn } from './lib/utils';
6
+
7
+ const textVariants = cva('', {
8
+ variants: {
9
+ variant: {
10
+ h1: 'scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl',
11
+ h2: 'scroll-m-20 text-3xl font-semibold tracking-tight',
12
+ h3: 'scroll-m-20 text-2xl font-semibold tracking-tight',
13
+ h4: 'scroll-m-20 text-xl font-semibold tracking-tight',
14
+ body: 'leading-7',
15
+ bodySmall: 'text-sm leading-6',
16
+ caption: 'text-xs text-muted-foreground',
17
+ label: 'text-sm font-medium leading-none',
18
+ overline: 'text-xs font-semibold uppercase tracking-widest text-muted-foreground',
19
+ },
20
+ },
21
+ defaultVariants: {
22
+ variant: 'body',
23
+ },
24
+ });
25
+
26
+ // Map variant to the most semantic HTML element
27
+ const variantElementMap: Record<string, keyof React.JSX.IntrinsicElements> = {
28
+ h1: 'h1',
29
+ h2: 'h2',
30
+ h3: 'h3',
31
+ h4: 'h4',
32
+ body: 'p',
33
+ bodySmall: 'p',
34
+ caption: 'span',
35
+ label: 'label',
36
+ overline: 'span',
37
+ };
38
+
39
+ export interface TextProps extends React.HTMLAttributes<HTMLElement>, VariantProps<typeof textVariants>, TextBaseProps {
40
+ as?: keyof React.JSX.IntrinsicElements;
41
+ }
42
+
43
+ const Text = React.forwardRef<HTMLElement, TextProps>(
44
+ ({ className, variant = 'body', as, children, ...props }, ref) => {
45
+ const Comp = (as || variantElementMap[variant ?? 'body'] || 'p') as React.ElementType;
46
+ return (
47
+ <Comp ref={ref} className={cn(textVariants({ variant, className }))} {...props}>
48
+ {children}
49
+ </Comp>
50
+ );
51
+ },
52
+ );
53
+ Text.displayName = 'Text';
54
+
55
+ export { Text, textVariants };
@@ -0,0 +1,25 @@
1
+ 'use client';
2
+
3
+ import * as React from 'react';
4
+
5
+ import { TextareaBaseProps } from '@gv-tech/ui-core';
6
+ import { cn } from './lib/utils';
7
+
8
+ export interface TextareaProps
9
+ extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, keyof TextareaBaseProps>, TextareaBaseProps {}
10
+
11
+ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(({ className, ...props }, ref) => {
12
+ return (
13
+ <textarea
14
+ className={cn(
15
+ 'flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
16
+ className,
17
+ )}
18
+ ref={ref}
19
+ {...props}
20
+ />
21
+ );
22
+ });
23
+ Textarea.displayName = 'Textarea';
24
+
25
+ export { Textarea };
@@ -0,0 +1,15 @@
1
+ 'use client';
2
+
3
+ import { ThemeProviderBaseProps } from '@gv-tech/ui-core';
4
+ import type { ThemeProviderProps as NextThemesProviderProps } from 'next-themes';
5
+ import { ThemeProvider as NextThemesProvider } from 'next-themes';
6
+
7
+ export type ThemeProviderProps = NextThemesProviderProps & ThemeProviderBaseProps;
8
+
9
+ export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
10
+ return (
11
+ <NextThemesProvider attribute="class" defaultTheme="system" enableSystem {...props}>
12
+ {children}
13
+ </NextThemesProvider>
14
+ );
15
+ }
@@ -0,0 +1,92 @@
1
+ 'use client';
2
+
3
+ import { ThemeToggleBaseProps } from '@gv-tech/ui-core';
4
+ import { Moon, Sun, SunMoon } from 'lucide-react';
5
+ import { Button } from './button';
6
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from './dropdown-menu';
7
+ import { useTheme } from './hooks/use-theme';
8
+ import { cn } from './lib/utils';
9
+
10
+ export type ThemeToggleProps = ThemeToggleBaseProps;
11
+
12
+ export function ThemeToggle({ variant = 'binary', onThemeChange, customTheme, className }: ThemeToggleProps) {
13
+ const { theme: nextTheme, setTheme: setNextTheme, resolvedTheme } = useTheme();
14
+
15
+ // Use customTheme if provided, otherwise fallback to next-themes
16
+ const currentTheme = customTheme ?? nextTheme;
17
+
18
+ // Determine the effective theme for icon rendering
19
+ const effectiveTheme = customTheme ? customTheme : resolvedTheme;
20
+ const isDark = effectiveTheme === 'dark';
21
+ const isSystem = currentTheme === 'system';
22
+
23
+ const handleThemeChange = (newTheme: string) => {
24
+ if (onThemeChange) {
25
+ onThemeChange(newTheme);
26
+ } else {
27
+ setNextTheme(newTheme);
28
+ }
29
+ };
30
+
31
+ const IconToggle = () => (
32
+ <>
33
+ <Sun
34
+ className={cn(
35
+ 'h-[1.2rem] w-[1.2rem] transition-all',
36
+ !isSystem && !isDark ? 'rotate-0 scale-100' : '-rotate-90 scale-0',
37
+ )}
38
+ />
39
+ <Moon
40
+ className={cn(
41
+ 'absolute h-[1.2rem] w-[1.2rem] transition-all',
42
+ !isSystem && isDark ? 'rotate-0 scale-100' : 'rotate-90 scale-0',
43
+ )}
44
+ />
45
+ <SunMoon
46
+ className={cn(
47
+ 'absolute h-[1.2rem] w-[1.2rem] transition-all',
48
+ isSystem ? 'rotate-0 scale-100' : 'rotate-90 scale-0',
49
+ )}
50
+ />
51
+ <span className="sr-only">Toggle theme</span>
52
+ </>
53
+ );
54
+
55
+ if (variant === 'ternary') {
56
+ return (
57
+ <DropdownMenu>
58
+ <DropdownMenuTrigger asChild>
59
+ <Button variant="ghost" size="icon" className={cn('relative h-9 w-9', className)}>
60
+ <IconToggle />
61
+ </Button>
62
+ </DropdownMenuTrigger>
63
+ <DropdownMenuContent align="end">
64
+ <DropdownMenuItem onClick={() => handleThemeChange('light')}>
65
+ <Sun className="mr-2 h-4 w-4" />
66
+ <span>Light</span>
67
+ </DropdownMenuItem>
68
+ <DropdownMenuItem onClick={() => handleThemeChange('dark')}>
69
+ <Moon className="mr-2 h-4 w-4" />
70
+ <span>Dark</span>
71
+ </DropdownMenuItem>
72
+ <DropdownMenuItem onClick={() => handleThemeChange('system')}>
73
+ <SunMoon className="mr-2 h-4 w-4" />
74
+ <span>System</span>
75
+ </DropdownMenuItem>
76
+ </DropdownMenuContent>
77
+ </DropdownMenu>
78
+ );
79
+ }
80
+
81
+ return (
82
+ <Button
83
+ variant="ghost"
84
+ size="icon"
85
+ className={cn('relative h-9 w-9', className)}
86
+ onClick={() => handleThemeChange(currentTheme === 'dark' ? 'light' : 'dark')}
87
+ aria-label="Toggle theme"
88
+ >
89
+ <IconToggle />
90
+ </Button>
91
+ );
92
+ }
package/src/toast.tsx ADDED
@@ -0,0 +1,111 @@
1
+ import * as ToastPrimitives from '@radix-ui/react-toast';
2
+ import { cva, type VariantProps } from 'class-variance-authority';
3
+ import { X } from 'lucide-react';
4
+ import * as React from 'react';
5
+
6
+ import { cn } from './lib/utils';
7
+
8
+ const ToastProvider = ToastPrimitives.Provider;
9
+
10
+ const ToastViewport = React.forwardRef<
11
+ React.ElementRef<typeof ToastPrimitives.Viewport>,
12
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>
13
+ >(({ className, ...props }, ref) => (
14
+ <ToastPrimitives.Viewport
15
+ ref={ref}
16
+ className={cn(
17
+ 'fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]',
18
+ className,
19
+ )}
20
+ {...props}
21
+ />
22
+ ));
23
+ ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
24
+
25
+ const toastVariants = cva(
26
+ 'group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full',
27
+ {
28
+ variants: {
29
+ variant: {
30
+ default: 'border bg-background text-foreground',
31
+ destructive: 'destructive group border-destructive bg-destructive text-destructive-foreground',
32
+ },
33
+ },
34
+ defaultVariants: {
35
+ variant: 'default',
36
+ },
37
+ },
38
+ );
39
+
40
+ const Toast = React.forwardRef<
41
+ React.ElementRef<typeof ToastPrimitives.Root>,
42
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> & VariantProps<typeof toastVariants>
43
+ >(({ className, variant, ...props }, ref) => {
44
+ return <ToastPrimitives.Root ref={ref} className={cn(toastVariants({ variant }), className)} {...props} />;
45
+ });
46
+ Toast.displayName = ToastPrimitives.Root.displayName;
47
+
48
+ const ToastAction = React.forwardRef<
49
+ React.ElementRef<typeof ToastPrimitives.Action>,
50
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Action>
51
+ >(({ className, ...props }, ref) => (
52
+ <ToastPrimitives.Action
53
+ ref={ref}
54
+ className={cn(
55
+ 'inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive',
56
+ className,
57
+ )}
58
+ {...props}
59
+ />
60
+ ));
61
+ ToastAction.displayName = ToastPrimitives.Action.displayName;
62
+
63
+ const ToastClose = React.forwardRef<
64
+ React.ElementRef<typeof ToastPrimitives.Close>,
65
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close>
66
+ >(({ className, ...props }, ref) => (
67
+ <ToastPrimitives.Close
68
+ ref={ref}
69
+ className={cn(
70
+ 'absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600',
71
+ className,
72
+ )}
73
+ toast-close=""
74
+ {...props}
75
+ >
76
+ <X className="h-4 w-4" />
77
+ </ToastPrimitives.Close>
78
+ ));
79
+ ToastClose.displayName = ToastPrimitives.Close.displayName;
80
+
81
+ const ToastTitle = React.forwardRef<
82
+ React.ElementRef<typeof ToastPrimitives.Title>,
83
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Title>
84
+ >(({ className, ...props }, ref) => (
85
+ <ToastPrimitives.Title ref={ref} className={cn('text-sm font-semibold [&+div]:text-xs', className)} {...props} />
86
+ ));
87
+ ToastTitle.displayName = ToastPrimitives.Title.displayName;
88
+
89
+ const ToastDescription = React.forwardRef<
90
+ React.ElementRef<typeof ToastPrimitives.Description>,
91
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Description>
92
+ >(({ className, ...props }, ref) => (
93
+ <ToastPrimitives.Description ref={ref} className={cn('text-sm opacity-90', className)} {...props} />
94
+ ));
95
+ ToastDescription.displayName = ToastPrimitives.Description.displayName;
96
+
97
+ type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>;
98
+
99
+ type ToastActionElement = React.ReactElement<typeof ToastAction>;
100
+
101
+ export {
102
+ Toast,
103
+ ToastAction,
104
+ ToastClose,
105
+ ToastDescription,
106
+ ToastProvider,
107
+ ToastTitle,
108
+ ToastViewport,
109
+ type ToastActionElement,
110
+ type ToastProps,
111
+ };
@@ -0,0 +1,27 @@
1
+ 'use client';
2
+
3
+ import { ToasterBaseProps } from '@gv-tech/ui-core';
4
+ import { useToast } from './hooks/use-toast';
5
+ import { Toast, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport } from './toast';
6
+
7
+ export function Toaster({ ...props }: ToasterBaseProps) {
8
+ const { toasts } = useToast();
9
+
10
+ return (
11
+ <ToastProvider {...props}>
12
+ {toasts.map(function ({ id, title, description, action, ...props }) {
13
+ return (
14
+ <Toast key={id} {...props}>
15
+ <div className="grid gap-1">
16
+ {title && <ToastTitle>{title}</ToastTitle>}
17
+ {description && <ToastDescription>{description}</ToastDescription>}
18
+ </div>
19
+ {action}
20
+ <ToastClose />
21
+ </Toast>
22
+ );
23
+ })}
24
+ <ToastViewport />
25
+ </ToastProvider>
26
+ );
27
+ }
@@ -0,0 +1,55 @@
1
+ 'use client';
2
+
3
+ import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
4
+ import { type VariantProps } from 'class-variance-authority';
5
+ import * as React from 'react';
6
+
7
+ import { toggleVariants } from '@gv-tech/ui-core';
8
+ import { cn } from './lib/utils';
9
+
10
+ const ToggleGroupContext = React.createContext<VariantProps<typeof toggleVariants>>({
11
+ size: 'default',
12
+ variant: 'default',
13
+ });
14
+
15
+ export type ToggleGroupProps = React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root> &
16
+ VariantProps<typeof toggleVariants>;
17
+
18
+ const ToggleGroup = React.forwardRef<React.ElementRef<typeof ToggleGroupPrimitive.Root>, ToggleGroupProps>(
19
+ ({ className, variant, size, children, ...props }, ref) => (
20
+ <ToggleGroupPrimitive.Root ref={ref} className={cn('flex items-center justify-center gap-1', className)} {...props}>
21
+ <ToggleGroupContext.Provider value={{ variant, size }}>{children}</ToggleGroupContext.Provider>
22
+ </ToggleGroupPrimitive.Root>
23
+ ),
24
+ );
25
+
26
+ ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
27
+
28
+ export type ToggleGroupItemProps = React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> &
29
+ VariantProps<typeof toggleVariants>;
30
+
31
+ const ToggleGroupItem = React.forwardRef<React.ElementRef<typeof ToggleGroupPrimitive.Item>, ToggleGroupItemProps>(
32
+ ({ className, children, variant, size, ...props }, ref) => {
33
+ const context = React.useContext(ToggleGroupContext);
34
+
35
+ return (
36
+ <ToggleGroupPrimitive.Item
37
+ ref={ref}
38
+ className={cn(
39
+ toggleVariants({
40
+ variant: context.variant || variant,
41
+ size: context.size || size,
42
+ }),
43
+ className,
44
+ )}
45
+ {...props}
46
+ >
47
+ {children}
48
+ </ToggleGroupPrimitive.Item>
49
+ );
50
+ },
51
+ );
52
+
53
+ ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
54
+
55
+ export { ToggleGroup, ToggleGroupItem };
package/src/toggle.tsx ADDED
@@ -0,0 +1,24 @@
1
+ 'use client';
2
+
3
+ import * as TogglePrimitive from '@radix-ui/react-toggle';
4
+ import { VariantProps } from 'class-variance-authority';
5
+ import * as React from 'react';
6
+
7
+ import { ToggleBaseProps, toggleVariants } from '@gv-tech/ui-core';
8
+ import { cn } from './lib/utils';
9
+
10
+ export interface ToggleProps
11
+ extends
12
+ React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root>,
13
+ Omit<VariantProps<typeof toggleVariants>, 'size' | 'variant'>,
14
+ ToggleBaseProps {}
15
+
16
+ const Toggle = React.forwardRef<React.ElementRef<typeof TogglePrimitive.Root>, ToggleProps>(
17
+ ({ className, variant, size, ...props }, ref) => (
18
+ <TogglePrimitive.Root ref={ref} className={cn(toggleVariants({ variant, size, className }))} {...props} />
19
+ ),
20
+ );
21
+
22
+ Toggle.displayName = TogglePrimitive.Root.displayName;
23
+
24
+ export { Toggle, toggleVariants };
@@ -0,0 +1,51 @@
1
+ 'use client';
2
+
3
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
4
+ import * as React from 'react';
5
+
6
+ import {
7
+ TooltipBaseProps,
8
+ TooltipContentBaseProps,
9
+ TooltipProviderBaseProps,
10
+ TooltipTriggerBaseProps,
11
+ } from '@gv-tech/ui-core';
12
+ import { cn } from './lib/utils';
13
+
14
+ export type TooltipProviderProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Provider> &
15
+ TooltipProviderBaseProps;
16
+
17
+ const TooltipProvider = ({ delayDuration = 0, ...props }: TooltipProviderProps) => (
18
+ <TooltipPrimitive.Provider delayDuration={delayDuration} {...props} />
19
+ );
20
+
21
+ export type TooltipProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Root> & TooltipBaseProps;
22
+
23
+ const Tooltip = ({ ...props }: TooltipProps) => <TooltipPrimitive.Root {...props} />;
24
+
25
+ export type TooltipTriggerProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Trigger> &
26
+ TooltipTriggerBaseProps;
27
+
28
+ const TooltipTrigger = React.forwardRef<React.ElementRef<typeof TooltipPrimitive.Trigger>, TooltipTriggerProps>(
29
+ ({ className, ...props }, ref) => <TooltipPrimitive.Trigger ref={ref} className={className} {...props} />,
30
+ );
31
+ TooltipTrigger.displayName = TooltipPrimitive.Trigger.displayName;
32
+
33
+ export type TooltipContentProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> &
34
+ TooltipContentBaseProps;
35
+
36
+ const TooltipContent = React.forwardRef<React.ElementRef<typeof TooltipPrimitive.Content>, TooltipContentProps>(
37
+ ({ className, sideOffset = 4, ...props }, ref) => (
38
+ <TooltipPrimitive.Content
39
+ ref={ref}
40
+ sideOffset={sideOffset}
41
+ className={cn(
42
+ 'z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
43
+ className,
44
+ )}
45
+ {...props}
46
+ />
47
+ ),
48
+ );
49
+ TooltipContent.displayName = TooltipPrimitive.Content.displayName;
50
+
51
+ export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };