@vvedantb/ui 0.1.1 → 0.1.2

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 (74) hide show
  1. package/LICENSE +21 -21
  2. package/package.json +3 -2
  3. package/src/ai-elements/artifact.tsx +99 -99
  4. package/src/ai-elements/attachments.tsx +366 -366
  5. package/src/ai-elements/chain-of-thought.tsx +212 -212
  6. package/src/ai-elements/code-block.tsx +478 -478
  7. package/src/ai-elements/conversation.tsx +157 -157
  8. package/src/ai-elements/image.tsx +25 -25
  9. package/src/ai-elements/inline-citation.tsx +252 -252
  10. package/src/ai-elements/message.tsx +269 -269
  11. package/src/ai-elements/model-selector.tsx +211 -211
  12. package/src/ai-elements/prompt-input.tsx +1018 -1018
  13. package/src/ai-elements/queue.tsx +251 -251
  14. package/src/ai-elements/reasoning.tsx +178 -178
  15. package/src/ai-elements/shimmer.tsx +56 -56
  16. package/src/ai-elements/sources.tsx +77 -77
  17. package/src/ai-elements/speech-input.tsx +290 -290
  18. package/src/ai-elements/suggestion.tsx +191 -191
  19. package/src/css.d.ts +2 -2
  20. package/src/index.ts +96 -96
  21. package/src/motion/presets.ts +35 -35
  22. package/src/motion/presets.vibot.ts +105 -105
  23. package/src/ui/_menu-classes.ts +30 -30
  24. package/src/ui/_menu-classes.vibot.ts +33 -33
  25. package/src/ui/accordion.tsx +81 -81
  26. package/src/ui/accordion.verve.tsx +56 -56
  27. package/src/ui/badge.tsx +34 -34
  28. package/src/ui/breadcrumb.tsx +83 -83
  29. package/src/ui/button-group.tsx +84 -84
  30. package/src/ui/button.tsx +57 -57
  31. package/src/ui/card.tsx +27 -27
  32. package/src/ui/carousel.tsx +211 -211
  33. package/src/ui/checkbox.tsx +27 -27
  34. package/src/ui/clear-input.tsx +170 -170
  35. package/src/ui/clear-input.vibot.tsx +76 -76
  36. package/src/ui/clearInputDissolve.ts +214 -214
  37. package/src/ui/collapsible.tsx +7 -7
  38. package/src/ui/command.tsx +148 -148
  39. package/src/ui/context-menu.tsx +173 -173
  40. package/src/ui/dialog.tsx +149 -149
  41. package/src/ui/dropdown-menu.tsx +178 -178
  42. package/src/ui/hover-card.tsx +31 -31
  43. package/src/ui/input-group.tsx +162 -162
  44. package/src/ui/input-group.verve.tsx +150 -150
  45. package/src/ui/input.tsx +21 -21
  46. package/src/ui/kbd.tsx +18 -18
  47. package/src/ui/label.tsx +20 -20
  48. package/src/ui/labeled-switch-row.tsx +53 -53
  49. package/src/ui/modalTransition.ts +85 -85
  50. package/src/ui/pagination.tsx +47 -47
  51. package/src/ui/popover.tsx +33 -33
  52. package/src/ui/progress.tsx +25 -25
  53. package/src/ui/radix-select.tsx +202 -202
  54. package/src/ui/scroll-area.tsx +55 -55
  55. package/src/ui/scroll-area.verve.tsx +43 -43
  56. package/src/ui/search-input.tsx +29 -29
  57. package/src/ui/select.tsx +163 -163
  58. package/src/ui/separator.tsx +28 -28
  59. package/src/ui/sheet.tsx +87 -87
  60. package/src/ui/skeleton.tsx +18 -18
  61. package/src/ui/sonner.css +16 -16
  62. package/src/ui/sonner.tsx +47 -47
  63. package/src/ui/spinner.tsx +27 -27
  64. package/src/ui/surface-classes.ts +55 -55
  65. package/src/ui/switch.tsx +26 -26
  66. package/src/ui/table.tsx +123 -123
  67. package/src/ui/tabs.tsx +140 -140
  68. package/src/ui/tabsSliding.ts +56 -56
  69. package/src/ui/textarea.tsx +21 -21
  70. package/src/ui/time-picker.tsx +170 -170
  71. package/src/ui/tooltip.tsx +25 -25
  72. package/src/ui/visually-hidden.tsx +3 -3
  73. package/src/utils/cn.ts +16 -16
  74. package/src/utils/ref.ts +10 -10
package/src/ui/sonner.tsx CHANGED
@@ -1,47 +1,47 @@
1
- import { Toaster, type ToasterProps } from "sonner";
2
- import "./sonner.css";
3
-
4
- // sonner toaster aligned with flat tonal surfaces `unstyled: true` strips sonner's default visual styling so our classes are
5
- // the single source of truth toast surfaces use `glass, panel, strong` (flat
6
- // popover fill) plus `smooth-shadow-ring-md` `!font, sans` is forced on the toaster section because sonner sets its own
7
- // `font, family` on `[data, sonner, toaster]` from a stylesheet that ships with
8
- // the package (loaded after our globals), so plain inheritance from `<body>`
9
- // loses the cascade the `!important` here guarantees instrument sans wins, toasts inherit from the section, so this single class covers everything variant icons (success / error / warning / info) are tinted via a
10
- // `data, icon` descendant selector, leaving the rest of the toast neutral callers should pass `theme` from `next, themes` so sonner's internal
11
- // `data, theme` attribute matches the active app theme (used by its focus
12
- // ring and a few internal states that aren't reachable via classnames) stacking: `expand={false}` keeps toasts collapsed (offset + scale) hovering
13
- // the stack expands them `sonner.css` hides back, toast content while collapsed
14
- // because `unstyled` disables sonner's built, in `data, styled` stack rules
15
- function SonnerToaster(props: ToasterProps) {
16
- return (
17
- <Toaster
18
- expand={false}
19
- visibleToasts={4}
20
- gap={12}
21
- className="toaster group !font-sans"
22
- toastOptions={{
23
- unstyled: true,
24
- classNames: {
25
- toast:
26
- "group toast glass-panel-strong flex w-full items-center gap-3 rounded-lg px-4 py-3 text-sm text-foreground smooth-shadow-ring-md",
27
- title: "font-medium leading-snug",
28
- description: "text-[13px] leading-snug text-muted",
29
- actionButton:
30
- "rounded-lg bg-accent px-2.5 py-1 text-xs font-medium text-accent-foreground transition-opacity hover:opacity-90",
31
- cancelButton:
32
- "rounded-lg bg-surface-secondary px-2.5 py-1 text-xs font-medium text-muted transition-colors hover:bg-surface-tertiary",
33
- closeButton:
34
- "rounded-lg bg-default px-2.5 py-1 text-xs font-medium text-foreground transition-colors hover:bg-default/78",
35
- loader: "text-muted",
36
- success: "[&_[data-icon]]:text-success",
37
- error: "[&_[data-icon]]:text-danger",
38
- warning: "[&_[data-icon]]:text-warning",
39
- info: "[&_[data-icon]]:text-accent",
40
- },
41
- }}
42
- {...props}
43
- />
44
- );
45
- }
46
-
47
- export { SonnerToaster };
1
+ import { Toaster, type ToasterProps } from "sonner";
2
+ import "./sonner.css";
3
+
4
+ // sonner toaster aligned with flat tonal surfaces `unstyled: true` strips sonner's default visual styling so our classes are
5
+ // the single source of truth toast surfaces use `glass, panel, strong` (flat
6
+ // popover fill) plus `smooth-shadow-ring-md` `!font, sans` is forced on the toaster section because sonner sets its own
7
+ // `font, family` on `[data, sonner, toaster]` from a stylesheet that ships with
8
+ // the package (loaded after our globals), so plain inheritance from `<body>`
9
+ // loses the cascade the `!important` here guarantees instrument sans wins, toasts inherit from the section, so this single class covers everything variant icons (success / error / warning / info) are tinted via a
10
+ // `data, icon` descendant selector, leaving the rest of the toast neutral callers should pass `theme` from `next, themes` so sonner's internal
11
+ // `data, theme` attribute matches the active app theme (used by its focus
12
+ // ring and a few internal states that aren't reachable via classnames) stacking: `expand={false}` keeps toasts collapsed (offset + scale) hovering
13
+ // the stack expands them `sonner.css` hides back, toast content while collapsed
14
+ // because `unstyled` disables sonner's built, in `data, styled` stack rules
15
+ function SonnerToaster(props: ToasterProps) {
16
+ return (
17
+ <Toaster
18
+ expand={false}
19
+ visibleToasts={4}
20
+ gap={12}
21
+ className="toaster group !font-sans"
22
+ toastOptions={{
23
+ unstyled: true,
24
+ classNames: {
25
+ toast:
26
+ "group toast glass-panel-strong flex w-full items-center gap-3 rounded-lg px-4 py-3 text-sm text-foreground smooth-shadow-ring-md",
27
+ title: "font-medium leading-snug",
28
+ description: "text-[13px] leading-snug text-muted",
29
+ actionButton:
30
+ "rounded-lg bg-accent px-2.5 py-1 text-xs font-medium text-accent-foreground transition-opacity hover:opacity-90",
31
+ cancelButton:
32
+ "rounded-lg bg-surface-secondary px-2.5 py-1 text-xs font-medium text-muted transition-colors hover:bg-surface-tertiary",
33
+ closeButton:
34
+ "rounded-lg bg-default px-2.5 py-1 text-xs font-medium text-foreground transition-colors hover:bg-default/78",
35
+ loader: "text-muted",
36
+ success: "[&_[data-icon]]:text-success",
37
+ error: "[&_[data-icon]]:text-danger",
38
+ warning: "[&_[data-icon]]:text-warning",
39
+ info: "[&_[data-icon]]:text-accent",
40
+ },
41
+ }}
42
+ {...props}
43
+ />
44
+ );
45
+ }
46
+
47
+ export { SonnerToaster };
@@ -1,27 +1,27 @@
1
- import { IconLoader2 } from "@tabler/icons-react";
2
- import { cn } from "../utils/cn";
3
-
4
- const sizeClasses = {
5
- sm: "size-4",
6
- md: "size-6",
7
- lg: "size-8",
8
- };
9
-
10
- function Spinner({
11
- size = "md",
12
- className,
13
- ...props
14
- }: Omit<React.ComponentPropsWithoutRef<"svg">, "size" | "stroke"> & {
15
- size?: "sm" | "md" | "lg";
16
- }) {
17
- return (
18
- <IconLoader2
19
- role="status"
20
- aria-label="Loading"
21
- className={cn("animate-spin text-muted", sizeClasses[size], className)}
22
- {...props}
23
- />
24
- );
25
- }
26
-
27
- export { Spinner };
1
+ import { IconLoader2 } from "@tabler/icons-react";
2
+ import { cn } from "../utils/cn";
3
+
4
+ const sizeClasses = {
5
+ sm: "size-4",
6
+ md: "size-6",
7
+ lg: "size-8",
8
+ };
9
+
10
+ function Spinner({
11
+ size = "md",
12
+ className,
13
+ ...props
14
+ }: Omit<React.ComponentPropsWithoutRef<"svg">, "size" | "stroke"> & {
15
+ size?: "sm" | "md" | "lg";
16
+ }) {
17
+ return (
18
+ <IconLoader2
19
+ role="status"
20
+ aria-label="Loading"
21
+ className={cn("animate-spin text-muted", sizeClasses[size], className)}
22
+ {...props}
23
+ />
24
+ );
25
+ }
26
+
27
+ export { Spinner };
@@ -1,55 +1,55 @@
1
- export const overlaySurfaceClass =
2
- "bg-overlay text-overlay-foreground smooth-shadow-ring-xl";
3
-
4
- export const modalBackdropClass = "bg-backdrop backdrop-blur-md";
5
-
6
- export const staticSurfaceClass =
7
- "bg-surface-secondary text-surface-foreground border-0 shadow-none backdrop-blur-none";
8
-
9
- export const flatElevatedSurfaceClass =
10
- "bg-surface text-surface-foreground border-0 shadow-none backdrop-blur-none";
11
-
12
- export const flatElevatedSurfaceHoverClass =
13
- "transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-secondary";
14
-
15
- export const flatElevatedSurfaceFocusClass = "focus-within:outline-hidden";
16
-
17
- export const chatInputContainerClass =
18
- "bg-surface-secondary text-foreground shadow-none backdrop-blur-none";
19
-
20
- export const flatPanelSubtleClass =
21
- "bg-surface-secondary text-foreground border-0 shadow-none backdrop-blur-none";
22
-
23
- export const flatPanelSubtleHoverClass =
24
- "transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-tertiary";
25
-
26
- export const flatInteractiveClass =
27
- "border-0 bg-transparent shadow-none backdrop-blur-none transition-[background-color,transform] duration-200 ease-smooth active:duration-100 active:ease-out active:scale-[0.97] hover:bg-surface-secondary hover:text-foreground";
28
-
29
- export const segmentActiveClass = "bg-segment text-segment-foreground";
30
-
31
- export const segmentActiveStateClass =
32
- "data-[state=active]:bg-segment data-[state=active]:text-segment-foreground";
33
-
34
- export const segmentOpenStateClass =
35
- "data-[state=open]:bg-segment data-[state=open]:text-segment-foreground";
36
-
37
- export const segmentExpandedStateClass =
38
- "aria-expanded:bg-segment aria-expanded:text-segment-foreground";
39
-
40
- export const defaultActiveClass = "bg-default text-default-foreground";
41
-
42
- export const defaultSelectedStateClass =
43
- "data-[state=selected]:bg-default data-[state=selected]:text-default-foreground";
44
-
45
- export const defaultActiveStateClass =
46
- "data-[state=active]:bg-default data-[state=active]:text-default-foreground";
47
-
48
- export const menuItemHighlightClass =
49
- "focus:bg-surface-tertiary focus:text-foreground data-highlighted:bg-surface-tertiary data-highlighted:text-foreground";
50
-
51
- export const menuItemEmphasisHighlightClass =
52
- "focus:bg-default focus:text-default-foreground data-highlighted:bg-default data-highlighted:text-default-foreground data-[state=open]:bg-default data-[state=open]:text-default-foreground";
53
-
54
- export const menuListSelectedClass =
55
- "data-[selected=true]:bg-default data-[selected=true]:text-default-foreground";
1
+ export const overlaySurfaceClass =
2
+ "bg-overlay text-overlay-foreground smooth-shadow-ring-xl";
3
+
4
+ export const modalBackdropClass = "bg-backdrop backdrop-blur-md";
5
+
6
+ export const staticSurfaceClass =
7
+ "bg-surface-secondary text-surface-foreground border-0 shadow-none backdrop-blur-none";
8
+
9
+ export const flatElevatedSurfaceClass =
10
+ "bg-surface text-surface-foreground border-0 shadow-none backdrop-blur-none";
11
+
12
+ export const flatElevatedSurfaceHoverClass =
13
+ "transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-secondary";
14
+
15
+ export const flatElevatedSurfaceFocusClass = "focus-within:outline-hidden";
16
+
17
+ export const chatInputContainerClass =
18
+ "bg-surface-secondary text-foreground shadow-none backdrop-blur-none";
19
+
20
+ export const flatPanelSubtleClass =
21
+ "bg-surface-secondary text-foreground border-0 shadow-none backdrop-blur-none";
22
+
23
+ export const flatPanelSubtleHoverClass =
24
+ "transition-[background-color,transform] duration-150 ease-out active:scale-[0.99] hover:bg-surface-tertiary";
25
+
26
+ export const flatInteractiveClass =
27
+ "border-0 bg-transparent shadow-none backdrop-blur-none transition-[background-color,transform] duration-200 ease-smooth active:duration-100 active:ease-out active:scale-[0.97] hover:bg-surface-secondary hover:text-foreground";
28
+
29
+ export const segmentActiveClass = "bg-segment text-segment-foreground";
30
+
31
+ export const segmentActiveStateClass =
32
+ "data-[state=active]:bg-segment data-[state=active]:text-segment-foreground";
33
+
34
+ export const segmentOpenStateClass =
35
+ "data-[state=open]:bg-segment data-[state=open]:text-segment-foreground";
36
+
37
+ export const segmentExpandedStateClass =
38
+ "aria-expanded:bg-segment aria-expanded:text-segment-foreground";
39
+
40
+ export const defaultActiveClass = "bg-default text-default-foreground";
41
+
42
+ export const defaultSelectedStateClass =
43
+ "data-[state=selected]:bg-default data-[state=selected]:text-default-foreground";
44
+
45
+ export const defaultActiveStateClass =
46
+ "data-[state=active]:bg-default data-[state=active]:text-default-foreground";
47
+
48
+ export const menuItemHighlightClass =
49
+ "focus:bg-surface-tertiary focus:text-foreground data-highlighted:bg-surface-tertiary data-highlighted:text-foreground";
50
+
51
+ export const menuItemEmphasisHighlightClass =
52
+ "focus:bg-default focus:text-default-foreground data-highlighted:bg-default data-highlighted:text-default-foreground data-[state=open]:bg-default data-[state=open]:text-default-foreground";
53
+
54
+ export const menuListSelectedClass =
55
+ "data-[selected=true]:bg-default data-[selected=true]:text-default-foreground";
package/src/ui/switch.tsx CHANGED
@@ -1,26 +1,26 @@
1
- import * as React from "react";
2
- import * as SwitchPrimitive from "@radix-ui/react-switch";
3
- import { cn } from "../utils/cn";
4
-
5
- const Switch = React.forwardRef<
6
- React.ComponentRef<typeof SwitchPrimitive.Root>,
7
- React.ComponentPropsWithoutRef<typeof SwitchPrimitive.Root>
8
- >(({ className, ...props }, ref) => (
9
- <SwitchPrimitive.Root
10
- className={cn(
11
- "peer relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border border-border bg-default transition-[background-color,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-accent data-[state=checked]:bg-accent data-[state=unchecked]:bg-default before:absolute before:inset-[-8px] before:content-['']",
12
- className,
13
- )}
14
- {...props}
15
- ref={ref}
16
- >
17
- <SwitchPrimitive.Thumb
18
- className={cn(
19
- "pointer-events-none block size-4 rounded-full bg-background ring-0 transition-[transform,background-color] duration-200 ease-smooth data-[state=checked]:translate-x-4 data-[state=checked]:bg-accent-foreground data-[state=unchecked]:translate-x-0",
20
- )}
21
- />
22
- </SwitchPrimitive.Root>
23
- ));
24
- Switch.displayName = SwitchPrimitive.Root.displayName;
25
-
26
- export { Switch };
1
+ import * as React from "react";
2
+ import * as SwitchPrimitive from "@radix-ui/react-switch";
3
+ import { cn } from "../utils/cn";
4
+
5
+ const Switch = React.forwardRef<
6
+ React.ComponentRef<typeof SwitchPrimitive.Root>,
7
+ React.ComponentPropsWithoutRef<typeof SwitchPrimitive.Root>
8
+ >(({ className, ...props }, ref) => (
9
+ <SwitchPrimitive.Root
10
+ className={cn(
11
+ "peer relative inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border border-border bg-default transition-[background-color,border-color] duration-200 ease-smooth focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-accent data-[state=checked]:bg-accent data-[state=unchecked]:bg-default before:absolute before:inset-[-8px] before:content-['']",
12
+ className,
13
+ )}
14
+ {...props}
15
+ ref={ref}
16
+ >
17
+ <SwitchPrimitive.Thumb
18
+ className={cn(
19
+ "pointer-events-none block size-4 rounded-full bg-background ring-0 transition-[transform,background-color] duration-200 ease-smooth data-[state=checked]:translate-x-4 data-[state=checked]:bg-accent-foreground data-[state=unchecked]:translate-x-0",
20
+ )}
21
+ />
22
+ </SwitchPrimitive.Root>
23
+ ));
24
+ Switch.displayName = SwitchPrimitive.Root.displayName;
25
+
26
+ export { Switch };
package/src/ui/table.tsx CHANGED
@@ -1,123 +1,123 @@
1
- import * as React from "react";
2
- import { cn } from "../utils/cn";
3
-
4
- const Table = React.forwardRef<
5
- HTMLTableElement,
6
- React.HTMLAttributes<HTMLTableElement>
7
- >(({ className, ...props }, ref) => (
8
- <div className="relative w-full overflow-auto rounded-lg max-sm:min-w-0 max-sm:max-w-full">
9
- <table
10
- ref={ref}
11
- className={cn("w-full caption-bottom text-sm", className)}
12
- {...props}
13
- />
14
- </div>
15
- ));
16
- Table.displayName = "Table";
17
-
18
- const TableHeader = React.forwardRef<
19
- HTMLTableSectionElement,
20
- React.HTMLAttributes<HTMLTableSectionElement>
21
- >(({ className, ...props }, ref) => (
22
- <thead
23
- ref={ref}
24
- className={cn("[&_tr]:border-b [&_tr]:border-separator", className)}
25
- {...props}
26
- />
27
- ));
28
- TableHeader.displayName = "TableHeader";
29
-
30
- const TableBody = React.forwardRef<
31
- HTMLTableSectionElement,
32
- React.HTMLAttributes<HTMLTableSectionElement>
33
- >(({ className, ...props }, ref) => (
34
- <tbody
35
- ref={ref}
36
- className={cn("[&_tr:last-child]:border-0", className)}
37
- {...props}
38
- />
39
- ));
40
- TableBody.displayName = "TableBody";
41
-
42
- const TableFooter = React.forwardRef<
43
- HTMLTableSectionElement,
44
- React.HTMLAttributes<HTMLTableSectionElement>
45
- >(({ className, ...props }, ref) => (
46
- <tfoot
47
- ref={ref}
48
- className={cn(
49
- "border-t border-separator bg-surface-secondary/30 font-medium [&>tr]:last:border-b-0",
50
- className,
51
- )}
52
- {...props}
53
- />
54
- ));
55
- TableFooter.displayName = "TableFooter";
56
-
57
- const TableRow = React.forwardRef<
58
- HTMLTableRowElement,
59
- React.HTMLAttributes<HTMLTableRowElement>
60
- >(({ className, ...props }, ref) => (
61
- <tr
62
- ref={ref}
63
- className={cn(
64
- "border-b border-separator transition-colors duration-200 ease-smooth hover:bg-surface-tertiary/50 data-[state=selected]:bg-surface-secondary",
65
- className,
66
- )}
67
- {...props}
68
- />
69
- ));
70
- TableRow.displayName = "TableRow";
71
-
72
- const TableHead = React.forwardRef<
73
- HTMLTableCellElement,
74
- React.ThHTMLAttributes<HTMLTableCellElement>
75
- >(({ className, ...props }, ref) => (
76
- <th
77
- ref={ref}
78
- className={cn(
79
- "h-11 px-4 text-left align-middle text-xs font-semibold uppercase tracking-widest text-muted [&:has([role=checkbox])]:pr-0",
80
- className,
81
- )}
82
- {...props}
83
- />
84
- ));
85
- TableHead.displayName = "TableHead";
86
-
87
- const TableCell = React.forwardRef<
88
- HTMLTableCellElement,
89
- React.TdHTMLAttributes<HTMLTableCellElement>
90
- >(({ className, ...props }, ref) => (
91
- <td
92
- ref={ref}
93
- className={cn(
94
- "p-4 align-middle text-sm [&:has([role=checkbox])]:pr-0",
95
- className,
96
- )}
97
- {...props}
98
- />
99
- ));
100
- TableCell.displayName = "TableCell";
101
-
102
- const TableCaption = React.forwardRef<
103
- HTMLTableCaptionElement,
104
- React.HTMLAttributes<HTMLTableCaptionElement>
105
- >(({ className, ...props }, ref) => (
106
- <caption
107
- ref={ref}
108
- className={cn("mt-4 text-sm text-muted", className)}
109
- {...props}
110
- />
111
- ));
112
- TableCaption.displayName = "TableCaption";
113
-
114
- export {
115
- Table,
116
- TableHeader,
117
- TableBody,
118
- TableFooter,
119
- TableHead,
120
- TableRow,
121
- TableCell,
122
- TableCaption,
123
- };
1
+ import * as React from "react";
2
+ import { cn } from "../utils/cn";
3
+
4
+ const Table = React.forwardRef<
5
+ HTMLTableElement,
6
+ React.HTMLAttributes<HTMLTableElement>
7
+ >(({ className, ...props }, ref) => (
8
+ <div className="relative w-full overflow-auto rounded-lg max-sm:min-w-0 max-sm:max-w-full">
9
+ <table
10
+ ref={ref}
11
+ className={cn("w-full caption-bottom text-sm", className)}
12
+ {...props}
13
+ />
14
+ </div>
15
+ ));
16
+ Table.displayName = "Table";
17
+
18
+ const TableHeader = React.forwardRef<
19
+ HTMLTableSectionElement,
20
+ React.HTMLAttributes<HTMLTableSectionElement>
21
+ >(({ className, ...props }, ref) => (
22
+ <thead
23
+ ref={ref}
24
+ className={cn("[&_tr]:border-b [&_tr]:border-separator", className)}
25
+ {...props}
26
+ />
27
+ ));
28
+ TableHeader.displayName = "TableHeader";
29
+
30
+ const TableBody = React.forwardRef<
31
+ HTMLTableSectionElement,
32
+ React.HTMLAttributes<HTMLTableSectionElement>
33
+ >(({ className, ...props }, ref) => (
34
+ <tbody
35
+ ref={ref}
36
+ className={cn("[&_tr:last-child]:border-0", className)}
37
+ {...props}
38
+ />
39
+ ));
40
+ TableBody.displayName = "TableBody";
41
+
42
+ const TableFooter = React.forwardRef<
43
+ HTMLTableSectionElement,
44
+ React.HTMLAttributes<HTMLTableSectionElement>
45
+ >(({ className, ...props }, ref) => (
46
+ <tfoot
47
+ ref={ref}
48
+ className={cn(
49
+ "border-t border-separator bg-surface-secondary/30 font-medium [&>tr]:last:border-b-0",
50
+ className,
51
+ )}
52
+ {...props}
53
+ />
54
+ ));
55
+ TableFooter.displayName = "TableFooter";
56
+
57
+ const TableRow = React.forwardRef<
58
+ HTMLTableRowElement,
59
+ React.HTMLAttributes<HTMLTableRowElement>
60
+ >(({ className, ...props }, ref) => (
61
+ <tr
62
+ ref={ref}
63
+ className={cn(
64
+ "border-b border-separator transition-colors duration-200 ease-smooth hover:bg-surface-tertiary/50 data-[state=selected]:bg-surface-secondary",
65
+ className,
66
+ )}
67
+ {...props}
68
+ />
69
+ ));
70
+ TableRow.displayName = "TableRow";
71
+
72
+ const TableHead = React.forwardRef<
73
+ HTMLTableCellElement,
74
+ React.ThHTMLAttributes<HTMLTableCellElement>
75
+ >(({ className, ...props }, ref) => (
76
+ <th
77
+ ref={ref}
78
+ className={cn(
79
+ "h-11 px-4 text-left align-middle text-xs font-semibold uppercase tracking-widest text-muted [&:has([role=checkbox])]:pr-0",
80
+ className,
81
+ )}
82
+ {...props}
83
+ />
84
+ ));
85
+ TableHead.displayName = "TableHead";
86
+
87
+ const TableCell = React.forwardRef<
88
+ HTMLTableCellElement,
89
+ React.TdHTMLAttributes<HTMLTableCellElement>
90
+ >(({ className, ...props }, ref) => (
91
+ <td
92
+ ref={ref}
93
+ className={cn(
94
+ "p-4 align-middle text-sm [&:has([role=checkbox])]:pr-0",
95
+ className,
96
+ )}
97
+ {...props}
98
+ />
99
+ ));
100
+ TableCell.displayName = "TableCell";
101
+
102
+ const TableCaption = React.forwardRef<
103
+ HTMLTableCaptionElement,
104
+ React.HTMLAttributes<HTMLTableCaptionElement>
105
+ >(({ className, ...props }, ref) => (
106
+ <caption
107
+ ref={ref}
108
+ className={cn("mt-4 text-sm text-muted", className)}
109
+ {...props}
110
+ />
111
+ ));
112
+ TableCaption.displayName = "TableCaption";
113
+
114
+ export {
115
+ Table,
116
+ TableHeader,
117
+ TableBody,
118
+ TableFooter,
119
+ TableHead,
120
+ TableRow,
121
+ TableCell,
122
+ TableCaption,
123
+ };