@turtleclub/ui 0.7.0-beta.32 → 0.7.0-beta.34

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 (139) hide show
  1. package/dist/index.cjs +10331 -110
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +7652 -47844
  4. package/dist/index.js.map +1 -1
  5. package/dist/types/components/features/sidebar-layout.d.ts +2 -0
  6. package/dist/types/components/features/sidebar-layout.d.ts.map +1 -1
  7. package/dist/types/components/ui/chart.d.ts +1 -1
  8. package/dist/types/components/ui/chart.d.ts.map +1 -1
  9. package/package.json +26 -22
  10. package/.prettierrc.json +0 -4
  11. package/.turbo/turbo-build.log +0 -182
  12. package/CHANGELOG.md +0 -795
  13. package/components.json +0 -21
  14. package/src/components/charts/QUICK_REFERENCE.md +0 -323
  15. package/src/components/charts/README.md +0 -658
  16. package/src/components/charts/RECHARTS_FEATURES.md +0 -458
  17. package/src/components/charts/area-chart.tsx +0 -248
  18. package/src/components/charts/bar-chart.tsx +0 -362
  19. package/src/components/charts/index.ts +0 -4
  20. package/src/components/charts/pie-chart.tsx +0 -277
  21. package/src/components/charts/radial-chart.tsx +0 -312
  22. package/src/components/features/api-status/index.tsx +0 -23
  23. package/src/components/features/data-table/data-table.tsx +0 -538
  24. package/src/components/features/data-table/expand-toggle.tsx +0 -17
  25. package/src/components/features/data-table/fuzzy-filter.tsx +0 -34
  26. package/src/components/features/data-table/index.ts +0 -3
  27. package/src/components/features/data-table/item-info.tsx +0 -19
  28. package/src/components/features/data-table/skeleton.tsx +0 -23
  29. package/src/components/features/data-table/sort-dropdown.tsx +0 -118
  30. package/src/components/features/data-table/sortable-header.tsx +0 -37
  31. package/src/components/features/index.ts +0 -6
  32. package/src/components/features/page-heading.tsx +0 -27
  33. package/src/components/features/search-bar.tsx +0 -55
  34. package/src/components/features/segmented-navigation.tsx +0 -18
  35. package/src/components/features/sidebar-layout.tsx +0 -193
  36. package/src/components/features/turtle-tooltip.tsx +0 -67
  37. package/src/components/icons/arrow.tsx +0 -23
  38. package/src/components/icons/beta.tsx +0 -95
  39. package/src/components/icons/dot.tsx +0 -102
  40. package/src/components/icons/index.ts +0 -7
  41. package/src/components/icons/issue.tsx +0 -106
  42. package/src/components/icons/turtle.tsx +0 -156
  43. package/src/components/icons/update.tsx +0 -113
  44. package/src/components/icons/warning.tsx +0 -95
  45. package/src/components/molecules/index.ts +0 -9
  46. package/src/components/molecules/opportunity/index.ts +0 -10
  47. package/src/components/molecules/opportunity/opportunity-apr.tsx +0 -129
  48. package/src/components/molecules/opportunity/opportunity-disclaimer.tsx +0 -46
  49. package/src/components/molecules/opportunity/opportunity-rate-estimator.tsx +0 -62
  50. package/src/components/molecules/opportunity/opportunity-section.tsx +0 -113
  51. package/src/components/molecules/opportunity/opportunity-selector.tsx +0 -30
  52. package/src/components/molecules/opportunity/opportunity-type.tsx +0 -16
  53. package/src/components/molecules/route-details.tsx +0 -112
  54. package/src/components/molecules/slippage-selector.tsx +0 -200
  55. package/src/components/molecules/swap-details.tsx +0 -55
  56. package/src/components/molecules/swap-input.tsx +0 -186
  57. package/src/components/molecules/tabs.tsx +0 -79
  58. package/src/components/molecules/token-selector.tsx +0 -180
  59. package/src/components/molecules/tx-status.tsx +0 -312
  60. package/src/components/molecules/widget/asset-list/asset-filters.tsx +0 -113
  61. package/src/components/molecules/widget/asset-list/asset-list.tsx +0 -178
  62. package/src/components/molecules/widget/asset-list/asset-row.tsx +0 -45
  63. package/src/components/molecules/widget/asset-list/hooks/index.ts +0 -2
  64. package/src/components/molecules/widget/asset-list/hooks/use-asset-filtering.ts +0 -44
  65. package/src/components/molecules/widget/asset-list/hooks/use-asset-grouping.ts +0 -87
  66. package/src/components/molecules/widget/asset-list/index.ts +0 -3
  67. package/src/components/molecules/widget/base-selector.tsx +0 -121
  68. package/src/components/molecules/widget/campaign-item.tsx +0 -82
  69. package/src/components/molecules/widget/deal-item.tsx +0 -92
  70. package/src/components/molecules/widget/index.ts +0 -36
  71. package/src/components/molecules/widget/opportunity-item.tsx +0 -105
  72. package/src/components/molecules/widget/widget-item-stats.tsx +0 -50
  73. package/src/components/molecules/widget/widget-item.tsx +0 -139
  74. package/src/components/molecules/widget/widget-list-items.tsx +0 -86
  75. package/src/components/ui/alert-dialog.tsx +0 -163
  76. package/src/components/ui/animated-background/animated-background.tsx +0 -182
  77. package/src/components/ui/animated-background/index.ts +0 -1
  78. package/src/components/ui/avatar.tsx +0 -73
  79. package/src/components/ui/badge.tsx +0 -59
  80. package/src/components/ui/banner.tsx +0 -84
  81. package/src/components/ui/button.tsx +0 -100
  82. package/src/components/ui/card.tsx +0 -119
  83. package/src/components/ui/chart.tsx +0 -346
  84. package/src/components/ui/checkbox.tsx +0 -32
  85. package/src/components/ui/chip.tsx +0 -52
  86. package/src/components/ui/collapsible.tsx +0 -34
  87. package/src/components/ui/combobox.tsx +0 -730
  88. package/src/components/ui/command.tsx +0 -184
  89. package/src/components/ui/dialog.tsx +0 -129
  90. package/src/components/ui/dropdown.tsx +0 -316
  91. package/src/components/ui/field.tsx +0 -244
  92. package/src/components/ui/heading.tsx +0 -74
  93. package/src/components/ui/hover-card.tsx +0 -139
  94. package/src/components/ui/icon-animation.tsx +0 -82
  95. package/src/components/ui/icon-list.tsx +0 -168
  96. package/src/components/ui/index.ts +0 -48
  97. package/src/components/ui/info-card.tsx +0 -110
  98. package/src/components/ui/input-group.tsx +0 -170
  99. package/src/components/ui/input.tsx +0 -72
  100. package/src/components/ui/label-with-icon.tsx +0 -122
  101. package/src/components/ui/label.tsx +0 -24
  102. package/src/components/ui/multi-select.tsx +0 -1090
  103. package/src/components/ui/navigation-bar.tsx +0 -153
  104. package/src/components/ui/navigation-menu.tsx +0 -188
  105. package/src/components/ui/opportunity-details-v1.tsx +0 -104
  106. package/src/components/ui/pagination.tsx +0 -127
  107. package/src/components/ui/popover.tsx +0 -48
  108. package/src/components/ui/scroll-area.tsx +0 -64
  109. package/src/components/ui/segment-control.tsx +0 -146
  110. package/src/components/ui/select.tsx +0 -199
  111. package/src/components/ui/separator.tsx +0 -26
  112. package/src/components/ui/sheet.tsx +0 -139
  113. package/src/components/ui/sidebar.tsx +0 -728
  114. package/src/components/ui/skeleton.tsx +0 -14
  115. package/src/components/ui/slider.tsx +0 -58
  116. package/src/components/ui/sonner.tsx +0 -24
  117. package/src/components/ui/switch.tsx +0 -29
  118. package/src/components/ui/table-shadcn.tsx +0 -110
  119. package/src/components/ui/table.tsx +0 -117
  120. package/src/components/ui/textarea.tsx +0 -22
  121. package/src/components/ui/toggle-group.tsx +0 -71
  122. package/src/components/ui/toggle.tsx +0 -47
  123. package/src/components/ui/tooltip.tsx +0 -66
  124. package/src/hooks/index.ts +0 -1
  125. package/src/hooks/useIsMobile.ts +0 -77
  126. package/src/index.ts +0 -16
  127. package/src/lib/utils.ts +0 -6
  128. package/src/styles/globals.css +0 -181
  129. package/src/styles/themes/index.css +0 -9
  130. package/src/styles/themes/semantic.css +0 -117
  131. package/src/styles/tokens/colors.css +0 -124
  132. package/src/styles/tokens/index.css +0 -15
  133. package/src/styles/tokens/radius.css +0 -18
  134. package/src/styles/tokens/spacing.css +0 -58
  135. package/src/styles/tokens/typography.css +0 -87
  136. package/src/tokens/index.ts +0 -108
  137. package/tsconfig.json +0 -20
  138. package/vite.config.js +0 -49
  139. /package/{src/images/enso.png → dist/enso-22FJ4GNK.png} +0 -0
@@ -1,139 +0,0 @@
1
- import * as React from "react";
2
- import { cn } from "@/lib/utils";
3
- import { Card } from "@/components/ui/card";
4
-
5
- interface WidgetItemProps extends React.ComponentProps<"div"> {
6
- onSelect?: () => void;
7
- selected?: boolean;
8
- children: React.ReactNode;
9
- }
10
-
11
- const WidgetItem = React.forwardRef<HTMLDivElement, WidgetItemProps>(
12
- ({ className, onSelect, selected = false, children, ...props }, ref) => {
13
- return (
14
- <Card
15
- ref={ref}
16
- variant="border"
17
- // gradient="white"
18
- className={cn(
19
- "bg-background w-full cursor-pointer p-4 transition-all duration-200 hover:shadow-md",
20
- selected &&
21
- "ring-primary border-text-foreground/60 ring-2 ring-offset-2",
22
- className,
23
- )}
24
- onClick={onSelect}
25
- {...props}
26
- >
27
- <div className="flex flex-col gap-2">{children}</div>
28
- </Card>
29
- );
30
- },
31
- );
32
-
33
- WidgetItem.displayName = "WidgetItem";
34
-
35
- // Top section component
36
- interface WidgetItemTopProps extends React.ComponentProps<"div"> {
37
- children: React.ReactNode;
38
- }
39
-
40
- const WidgetItemTop = React.forwardRef<HTMLDivElement, WidgetItemTopProps>(
41
- ({ className, children, ...props }, ref) => {
42
- return (
43
- <div
44
- ref={ref}
45
- className={cn("flex items-start justify-between gap-4", className)}
46
- {...props}
47
- >
48
- {children}
49
- </div>
50
- );
51
- },
52
- );
53
-
54
- WidgetItemTop.displayName = "WidgetItemTop";
55
-
56
- // Bottom section component
57
- interface WidgetItemBottomProps extends React.ComponentProps<"div"> {
58
- children: React.ReactNode;
59
- }
60
-
61
- const WidgetItemBottom = React.forwardRef<
62
- HTMLDivElement,
63
- WidgetItemBottomProps
64
- >(({ className, children, ...props }, ref) => {
65
- return (
66
- <div
67
- ref={ref}
68
- className={cn("flex items-end justify-between gap-4", className)}
69
- {...props}
70
- >
71
- {children}
72
- </div>
73
- );
74
- });
75
-
76
- WidgetItemBottom.displayName = "WidgetItemBottom";
77
-
78
- // Left section component
79
- interface WidgetItemLeftProps extends React.ComponentProps<"div"> {
80
- children: React.ReactNode;
81
- }
82
-
83
- const WidgetItemLeft = React.forwardRef<HTMLDivElement, WidgetItemLeftProps>(
84
- ({ className, children, ...props }, ref) => {
85
- return (
86
- <div
87
- ref={ref}
88
- className={cn(
89
- "flex min-w-0 flex-1 flex-col items-start justify-start gap-1",
90
- className,
91
- )}
92
- {...props}
93
- >
94
- {children}
95
- </div>
96
- );
97
- },
98
- );
99
-
100
- WidgetItemLeft.displayName = "WidgetItemLeft";
101
-
102
- // Right section component
103
- interface WidgetItemRightProps extends React.ComponentProps<"div"> {
104
- children: React.ReactNode;
105
- }
106
-
107
- const WidgetItemRight = React.forwardRef<HTMLDivElement, WidgetItemRightProps>(
108
- ({ className, children, ...props }, ref) => {
109
- return (
110
- <div
111
- ref={ref}
112
- className={cn(
113
- "flex flex-col items-end justify-between gap-1",
114
- className,
115
- )}
116
- {...props}
117
- >
118
- {children}
119
- </div>
120
- );
121
- },
122
- );
123
-
124
- WidgetItemRight.displayName = "WidgetItemRight";
125
-
126
- export {
127
- WidgetItem,
128
- WidgetItemTop,
129
- WidgetItemBottom,
130
- WidgetItemLeft,
131
- WidgetItemRight,
132
- };
133
- export type {
134
- WidgetItemProps,
135
- WidgetItemTopProps,
136
- WidgetItemBottomProps,
137
- WidgetItemLeftProps,
138
- WidgetItemRightProps,
139
- };
@@ -1,86 +0,0 @@
1
- import { ReactNode, useMemo } from "react";
2
- import { cn } from "@/lib/utils";
3
- import { LabelWithIcon } from "@/components/ui/label-with-icon";
4
-
5
- export interface WidgetListGroup<T> {
6
- id: string;
7
- icon?: string;
8
- title?: string;
9
- items: T[];
10
- }
11
-
12
- export interface WidgetListItemsProps<T> {
13
- // Groups of items to display (can be a single group for ungrouped content)
14
- groups: WidgetListGroup<T>[];
15
- // Function to render each item
16
- renderItem: (item: T) => ReactNode;
17
- // Optional filter function to filter items
18
- filterFn?: (item: T) => boolean;
19
- // Optional function to get unique key for each item
20
- getItemKey?: (item: T) => string;
21
- // Optional className for the container
22
- className?: string;
23
- // Optional className for each group
24
- groupClassName?: string;
25
- // Optional className for each item
26
- itemClassName?: string;
27
- // Whether to show group headers
28
- showGroupHeaders?: boolean;
29
- // Optional empty state
30
- emptyState?: ReactNode;
31
- }
32
-
33
- export const WidgetListItems = <T,>({
34
- groups,
35
- renderItem,
36
- filterFn,
37
- getItemKey,
38
- className,
39
- groupClassName,
40
- itemClassName,
41
- showGroupHeaders = true,
42
- emptyState = (
43
- <div className="text-muted-foreground py-8 text-center">No items found</div>
44
- ),
45
- }: WidgetListItemsProps<T>) => {
46
- // Filter items in each group
47
- const filteredGroups = useMemo(() => {
48
- return groups
49
- .map((group) => ({
50
- ...group,
51
- items: filterFn ? group.items.filter(filterFn) : group.items,
52
- }))
53
- .filter((group) => group.items.length > 0);
54
- }, [groups, filterFn]);
55
-
56
- // Check if we have any items to display
57
- const hasItems = filteredGroups.some((group) => group.items.length > 0);
58
-
59
- if (!hasItems) {
60
- return <div className={className}>{emptyState}</div>;
61
- }
62
-
63
- return (
64
- <div className={cn("mb-5 space-y-5 px-2.5", className)}>
65
- {filteredGroups.map((group) => (
66
- <div key={group.id} className={cn("space-y-2", groupClassName)}>
67
- {showGroupHeaders && group.title && (
68
- <LabelWithIcon icon={group.icon} textSize="sm" iconSize="base">
69
- {group.title}
70
- </LabelWithIcon>
71
- )}
72
- <div className="space-y-1">
73
- {group.items.map((item, index) => (
74
- <div
75
- key={getItemKey ? getItemKey(item) : `${group.id}-${index}`}
76
- className={cn("rounded-lg transition-colors", itemClassName)}
77
- >
78
- {renderItem(item)}
79
- </div>
80
- ))}
81
- </div>
82
- </div>
83
- ))}
84
- </div>
85
- );
86
- };
@@ -1,163 +0,0 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
5
-
6
- import { cn } from "@/lib/utils";
7
- import { buttonVariants } from "@/components/ui/button";
8
-
9
- function AlertDialog({
10
- ...props
11
- }: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {
12
- return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />;
13
- }
14
-
15
- function AlertDialogTrigger({
16
- ...props
17
- }: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {
18
- return (
19
- <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
20
- );
21
- }
22
-
23
- function AlertDialogPortal({
24
- ...props
25
- }: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {
26
- return (
27
- <AlertDialogPrimitive.Portal
28
- data-slot="alert-dialog-portal"
29
- {...props}
30
- container={
31
- document.querySelectorAll(".turtle-widget-root")[0] ?? undefined
32
- }
33
- />
34
- );
35
- }
36
-
37
- function AlertDialogOverlay({
38
- className,
39
- ...props
40
- }: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {
41
- return (
42
- <AlertDialogPrimitive.Overlay
43
- data-slot="alert-dialog-overlay"
44
- className={cn(
45
- "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
46
- className,
47
- )}
48
- {...props}
49
- />
50
- );
51
- }
52
-
53
- function AlertDialogContent({
54
- className,
55
- ...props
56
- }: React.ComponentProps<typeof AlertDialogPrimitive.Content>) {
57
- return (
58
- <AlertDialogPortal>
59
- <AlertDialogOverlay />
60
- <AlertDialogPrimitive.Content
61
- data-slot="alert-dialog-content"
62
- className={cn(
63
- "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 border-border fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-10 shadow-lg duration-200 sm:max-w-lg",
64
- className,
65
- )}
66
- {...props}
67
- />
68
- </AlertDialogPortal>
69
- );
70
- }
71
-
72
- function AlertDialogHeader({
73
- className,
74
- ...props
75
- }: React.ComponentProps<"div">) {
76
- return (
77
- <div
78
- data-slot="alert-dialog-header"
79
- className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
80
- {...props}
81
- />
82
- );
83
- }
84
-
85
- function AlertDialogFooter({
86
- className,
87
- ...props
88
- }: React.ComponentProps<"div">) {
89
- return (
90
- <div
91
- data-slot="alert-dialog-footer"
92
- className={cn(
93
- "flex flex-col-reverse gap-2 sm:flex-row sm:justify-evenly",
94
- className,
95
- )}
96
- {...props}
97
- />
98
- );
99
- }
100
-
101
- function AlertDialogTitle({
102
- className,
103
- ...props
104
- }: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {
105
- return (
106
- <AlertDialogPrimitive.Title
107
- data-slot="alert-dialog-title"
108
- className={cn("text-lg font-semibold", className)}
109
- {...props}
110
- />
111
- );
112
- }
113
-
114
- function AlertDialogDescription({
115
- className,
116
- ...props
117
- }: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {
118
- return (
119
- <AlertDialogPrimitive.Description
120
- data-slot="alert-dialog-description"
121
- className={cn("text-muted-foreground text-sm", className)}
122
- {...props}
123
- />
124
- );
125
- }
126
-
127
- function AlertDialogAction({
128
- className,
129
- ...props
130
- }: React.ComponentProps<typeof AlertDialogPrimitive.Action>) {
131
- return (
132
- <AlertDialogPrimitive.Action
133
- className={cn(buttonVariants({ variant: "green" }), className)}
134
- {...props}
135
- />
136
- );
137
- }
138
-
139
- function AlertDialogCancel({
140
- className,
141
- ...props
142
- }: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) {
143
- return (
144
- <AlertDialogPrimitive.Cancel
145
- className={cn(buttonVariants({ variant: "default" }), className)}
146
- {...props}
147
- />
148
- );
149
- }
150
-
151
- export {
152
- AlertDialog,
153
- AlertDialogPortal,
154
- AlertDialogOverlay,
155
- AlertDialogTrigger,
156
- AlertDialogContent,
157
- AlertDialogHeader,
158
- AlertDialogFooter,
159
- AlertDialogTitle,
160
- AlertDialogDescription,
161
- AlertDialogAction,
162
- AlertDialogCancel,
163
- };
@@ -1,182 +0,0 @@
1
- "use client";
2
- import { ReactNode, useEffect, useState } from "react";
3
- import * as React from "react";
4
- import { motion } from "framer-motion";
5
- import { cn } from "@/lib/utils";
6
-
7
- export function AnimatedBackground({
8
- children,
9
- className,
10
- containerClassName,
11
- accentColor = "#73F36C",
12
- backgroundColor = "#141514",
13
- }: {
14
- children: ReactNode;
15
- className?: string;
16
- containerClassName?: string;
17
- accentColor?: string;
18
- backgroundColor?: string;
19
- }) {
20
- return (
21
- <div className={cn("block h-screen w-full", className)}>
22
- <div className="relative h-full w-full" style={{ backgroundColor }}>
23
- <div
24
- className={cn(
25
- "relative z-10 flex h-full items-center justify-center",
26
- containerClassName,
27
- )}
28
- >
29
- {children}
30
- </div>
31
-
32
- {/* Animated background elements */}
33
- <div className="absolute inset-0 size-full overflow-hidden">
34
- {/* Animated rectangles */}
35
- {[
36
- "left-full sm:left-1/2 top-[-50px] md:top-[-100px] h-[200px] w-[450px] md:w-[1000px] rotate-180 md:rotate-0 translate-x-[-75%] sm:translate-x-[-90%]",
37
- "right-[-150px] top-[-300px] md:top-[-250px] size-[400px]",
38
- "bottom-[-280px] md:bottom-[-450px] lg:bottom-[-350px] right-[-220px] md:right-[-400px] size-[400px] md:size-[600px]",
39
- "bottom-[-300px] left-[-240px] md:left-1/2 h-[400px] w-[400px] rotate-180 md:rotate-0 md:-translate-x-full md:w-[800px]",
40
- "right-[70px] md:left-[-190px] lg:left-[-150px] bottom-[-200px] md:top-1/2 h-[400px] w-[600px] sm:w-[750px] md:w-[300px] md:-translate-y-full z-[-1] md:z-0",
41
- ].map((classes, index) => (
42
- <div
43
- key={index}
44
- className={`absolute ${classes}`}
45
- style={{
46
- background: `radial-gradient(circle, ${accentColor}80 0%, transparent 70%)`,
47
- borderRadius: "50%",
48
- filter: "blur(40px)",
49
- }}
50
- />
51
- ))}
52
-
53
- {/* Grid lines */}
54
- <GridLines accentColor={accentColor} />
55
-
56
- {/* Floating particles */}
57
- <div className="absolute inset-0">
58
- {Array.from({ length: 15 }).map((_, i) => (
59
- <Particle key={i} accentColor={accentColor} />
60
- ))}
61
- </div>
62
- </div>
63
- </div>
64
- </div>
65
- );
66
- }
67
-
68
- // Grid lines component
69
- function GridLines({ accentColor }: { accentColor: string }) {
70
- return (
71
- <div className="grid-lines absolute inset-0 opacity-20">
72
- {/* Horizontal lines */}
73
- {Array.from({ length: 10 }).map((_, i) => (
74
- <motion.div
75
- key={`h-${i}`}
76
- className="absolute h-px w-full"
77
- style={{
78
- top: `${(i + 1) * 10}%`,
79
- backgroundColor: `${accentColor}60`, // 60 = opacity ~37%
80
- }}
81
- initial={{ scaleX: 0 }}
82
- animate={{
83
- scaleX: 1,
84
- opacity: [0.1, 0.3, 0.1],
85
- }}
86
- transition={{
87
- duration: 3,
88
- repeat: Infinity,
89
- repeatType: "reverse",
90
- delay: i * 0.2,
91
- }}
92
- />
93
- ))}
94
-
95
- {/* Vertical lines */}
96
- {Array.from({ length: 10 }).map((_, i) => (
97
- <motion.div
98
- key={`v-${i}`}
99
- className="absolute h-full w-px"
100
- style={{
101
- left: `${(i + 1) * 10}%`,
102
- backgroundColor: `${accentColor}60`, // 60 = opacity ~37%
103
- }}
104
- initial={{ scaleY: 0 }}
105
- animate={{
106
- scaleY: 1,
107
- opacity: [0.1, 0.3, 0.1],
108
- }}
109
- transition={{
110
- duration: 3,
111
- repeat: Infinity,
112
- repeatType: "reverse",
113
- delay: i * 0.2,
114
- }}
115
- />
116
- ))}
117
- </div>
118
- );
119
- }
120
- // Floating particle
121
- function Particle({ accentColor }: { accentColor: string }) {
122
- const [isClient, setIsClient] = useState(false);
123
- const [state, setState] = useState({
124
- size: 4, // default size
125
- startX: 50,
126
- startY: 50,
127
- duration: 15,
128
- xMovements: [0, 0, 0],
129
- yMovements: [0, 0, 0],
130
- });
131
-
132
- useEffect(() => {
133
- // Mark as client-side and apply randomness
134
- setIsClient(true);
135
- setState({
136
- size: Math.random() * 6 + 2,
137
- startX: Math.random() * 100,
138
- startY: Math.random() * 100,
139
- duration: Math.random() * 15 + 10,
140
- xMovements: [
141
- Math.random() * 100 - 50,
142
- Math.random() * 100 - 50,
143
- Math.random() * 100 - 50,
144
- ],
145
- yMovements: [
146
- Math.random() * 100 - 50,
147
- Math.random() * 100 - 50,
148
- Math.random() * 100 - 50,
149
- ],
150
- });
151
- }, []);
152
-
153
- // Don't render until client-side
154
- if (!isClient) {
155
- return null;
156
- }
157
-
158
- return (
159
- <motion.div
160
- className="absolute rounded-full"
161
- style={{
162
- width: state.size,
163
- height: state.size,
164
- left: `${state.startX}%`,
165
- top: `${state.startY}%`,
166
- backgroundColor: `${accentColor}B3`, // B3 = opacity ~70%
167
- boxShadow: `0 0 10px 2px ${accentColor}99`, // 99 = opacity ~60%
168
- }}
169
- animate={{
170
- x: state.xMovements,
171
- y: state.yMovements,
172
- opacity: [0.2, 0.8, 0.2],
173
- scale: [1, 1.2, 1],
174
- }}
175
- transition={{
176
- duration: state.duration,
177
- repeat: Infinity,
178
- repeatType: "reverse",
179
- }}
180
- />
181
- );
182
- }
@@ -1 +0,0 @@
1
- export { AnimatedBackground } from "./animated-background";
@@ -1,73 +0,0 @@
1
- import * as React from "react";
2
- import * as AvatarPrimitive from "@radix-ui/react-avatar";
3
-
4
- import { cn } from "@/lib/utils";
5
-
6
- const AvatarSize = {
7
- xs: "size-4",
8
- sm: "size-6",
9
- md: "size-8",
10
- lg: "size-10",
11
- xl: "size-12",
12
- } as const;
13
-
14
- function Avatar({
15
- className,
16
- size = "md",
17
- ...props
18
- }: React.ComponentProps<typeof AvatarPrimitive.Root> & {
19
- size?: keyof typeof AvatarSize;
20
- }) {
21
- return (
22
- <AvatarPrimitive.Root
23
- data-slot="avatar"
24
- className={cn("relative flex size-8 shrink-0 overflow-hidden rounded-full", className)}
25
- {...props}
26
- />
27
- );
28
- }
29
-
30
- function AvatarImage({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
31
- return (
32
- <AvatarPrimitive.Image
33
- data-slot="avatar-image"
34
- className={cn("aspect-square size-full", className)}
35
- {...props}
36
- />
37
- );
38
- }
39
-
40
- function AvatarFallback({
41
- className,
42
- ...props
43
- }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
44
- return (
45
- <AvatarPrimitive.Fallback
46
- data-slot="avatar-fallback"
47
- className={cn("bg-muted flex size-full items-center justify-center rounded-full", className)}
48
- {...props}
49
- />
50
- );
51
- }
52
-
53
- function TurtleAvatar({
54
- src,
55
- alt,
56
- fallback,
57
- ...rest
58
- }: AvatarPrimitive.AvatarProps & {
59
- src?: string;
60
- alt?: string;
61
- fallback?: React.ReactNode;
62
- }) {
63
- return (
64
- <Avatar {...rest}>
65
- <AvatarImage src={src} alt={alt} />
66
- <AvatarFallback className="border-gradient-primary bg-primary/10 opacity-50">
67
- {fallback}
68
- </AvatarFallback>
69
- </Avatar>
70
- );
71
- }
72
-
73
- export { TurtleAvatar, Avatar, AvatarImage, AvatarFallback };
@@ -1,59 +0,0 @@
1
- import * as React from "react";
2
- import { Slot } from "@radix-ui/react-slot";
3
- import { cva, type VariantProps } from "class-variance-authority";
4
-
5
- import { cn } from "@/lib/utils";
6
-
7
- const badgeVariants = cva(
8
- "bg-neutral-alpha-5 aria-invalid:ring-destructive/20 inline-flex w-fit shrink-0 items-center justify-center gap-2 rounded-full whitespace-nowrap transition-all [&>svg]:pointer-events-none [&>svg]:size-3",
9
- {
10
- variants: {
11
- variant: {
12
- default:
13
- "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
14
- warning: "[a&]:hover:bg-secondary/90 text-amber-600",
15
- destructive:
16
- "text-destructive [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20",
17
- success: "text-primary [a&]:hover:bg-primary/90",
18
- muted: "text-muted-foreground",
19
- },
20
- size: {
21
- sm: "px-2.5 py-0.5 text-[10px]",
22
- default: "px-3.5 py-1 text-xs",
23
- lg: "px-5 py-2 text-sm",
24
- },
25
- border: {
26
- default: "",
27
- subtle: "border-border border",
28
- color: "border border-inherit",
29
- gradient: "border-gradient-white border",
30
- },
31
- },
32
- defaultVariants: {
33
- variant: "default",
34
- size: "default",
35
- },
36
- },
37
- );
38
-
39
- function Badge({
40
- className,
41
- variant,
42
- size,
43
- border,
44
- asChild = false,
45
- ...props
46
- }: React.ComponentProps<"span"> &
47
- VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
48
- const Comp = asChild ? Slot : "span";
49
-
50
- return (
51
- <Comp
52
- data-slot="badge"
53
- className={cn(badgeVariants({ variant, size, border }), className)}
54
- {...props}
55
- />
56
- );
57
- }
58
-
59
- export { Badge, badgeVariants };