@turtleclub/ui 0.7.0-beta.33 → 0.7.0-beta.35

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 (135) hide show
  1. package/dist/index.cjs +10331 -110
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +7227 -48026
  4. package/dist/index.js.map +1 -1
  5. package/package.json +17 -11
  6. package/.prettierrc.json +0 -4
  7. package/.turbo/turbo-build.log +0 -182
  8. package/CHANGELOG.md +0 -801
  9. package/components.json +0 -21
  10. package/src/components/charts/QUICK_REFERENCE.md +0 -323
  11. package/src/components/charts/README.md +0 -658
  12. package/src/components/charts/RECHARTS_FEATURES.md +0 -458
  13. package/src/components/charts/area-chart.tsx +0 -248
  14. package/src/components/charts/bar-chart.tsx +0 -362
  15. package/src/components/charts/index.ts +0 -4
  16. package/src/components/charts/pie-chart.tsx +0 -277
  17. package/src/components/charts/radial-chart.tsx +0 -312
  18. package/src/components/features/api-status/index.tsx +0 -23
  19. package/src/components/features/data-table/data-table.tsx +0 -538
  20. package/src/components/features/data-table/expand-toggle.tsx +0 -17
  21. package/src/components/features/data-table/fuzzy-filter.tsx +0 -34
  22. package/src/components/features/data-table/index.ts +0 -3
  23. package/src/components/features/data-table/item-info.tsx +0 -19
  24. package/src/components/features/data-table/skeleton.tsx +0 -23
  25. package/src/components/features/data-table/sort-dropdown.tsx +0 -118
  26. package/src/components/features/data-table/sortable-header.tsx +0 -37
  27. package/src/components/features/index.ts +0 -6
  28. package/src/components/features/page-heading.tsx +0 -27
  29. package/src/components/features/search-bar.tsx +0 -55
  30. package/src/components/features/segmented-navigation.tsx +0 -18
  31. package/src/components/features/sidebar-layout.tsx +0 -279
  32. package/src/components/features/turtle-tooltip.tsx +0 -67
  33. package/src/components/icons/arrow.tsx +0 -23
  34. package/src/components/icons/beta.tsx +0 -95
  35. package/src/components/icons/dot.tsx +0 -102
  36. package/src/components/icons/index.ts +0 -7
  37. package/src/components/icons/issue.tsx +0 -106
  38. package/src/components/icons/turtle.tsx +0 -156
  39. package/src/components/icons/update.tsx +0 -113
  40. package/src/components/icons/warning.tsx +0 -95
  41. package/src/components/molecules/index.ts +0 -9
  42. package/src/components/molecules/opportunity/index.ts +0 -10
  43. package/src/components/molecules/opportunity/opportunity-apr.tsx +0 -129
  44. package/src/components/molecules/opportunity/opportunity-disclaimer.tsx +0 -46
  45. package/src/components/molecules/opportunity/opportunity-rate-estimator.tsx +0 -62
  46. package/src/components/molecules/opportunity/opportunity-section.tsx +0 -113
  47. package/src/components/molecules/opportunity/opportunity-selector.tsx +0 -30
  48. package/src/components/molecules/opportunity/opportunity-type.tsx +0 -16
  49. package/src/components/molecules/route-details.tsx +0 -112
  50. package/src/components/molecules/slippage-selector.tsx +0 -200
  51. package/src/components/molecules/swap-details.tsx +0 -55
  52. package/src/components/molecules/swap-input.tsx +0 -186
  53. package/src/components/molecules/tabs.tsx +0 -79
  54. package/src/components/molecules/token-selector.tsx +0 -180
  55. package/src/components/molecules/tx-status.tsx +0 -312
  56. package/src/components/molecules/widget/asset-list/asset-filters.tsx +0 -113
  57. package/src/components/molecules/widget/asset-list/asset-list.tsx +0 -178
  58. package/src/components/molecules/widget/asset-list/asset-row.tsx +0 -45
  59. package/src/components/molecules/widget/asset-list/hooks/index.ts +0 -2
  60. package/src/components/molecules/widget/asset-list/hooks/use-asset-filtering.ts +0 -44
  61. package/src/components/molecules/widget/asset-list/hooks/use-asset-grouping.ts +0 -87
  62. package/src/components/molecules/widget/asset-list/index.ts +0 -3
  63. package/src/components/molecules/widget/base-selector.tsx +0 -121
  64. package/src/components/molecules/widget/campaign-item.tsx +0 -82
  65. package/src/components/molecules/widget/deal-item.tsx +0 -92
  66. package/src/components/molecules/widget/index.ts +0 -36
  67. package/src/components/molecules/widget/opportunity-item.tsx +0 -105
  68. package/src/components/molecules/widget/widget-item-stats.tsx +0 -50
  69. package/src/components/molecules/widget/widget-item.tsx +0 -139
  70. package/src/components/molecules/widget/widget-list-items.tsx +0 -86
  71. package/src/components/ui/alert-dialog.tsx +0 -163
  72. package/src/components/ui/animated-background/animated-background.tsx +0 -182
  73. package/src/components/ui/animated-background/index.ts +0 -1
  74. package/src/components/ui/avatar.tsx +0 -73
  75. package/src/components/ui/badge.tsx +0 -59
  76. package/src/components/ui/banner.tsx +0 -84
  77. package/src/components/ui/button.tsx +0 -100
  78. package/src/components/ui/card.tsx +0 -119
  79. package/src/components/ui/chart.tsx +0 -346
  80. package/src/components/ui/checkbox.tsx +0 -32
  81. package/src/components/ui/chip.tsx +0 -52
  82. package/src/components/ui/collapsible.tsx +0 -34
  83. package/src/components/ui/combobox.tsx +0 -730
  84. package/src/components/ui/command.tsx +0 -184
  85. package/src/components/ui/dialog.tsx +0 -129
  86. package/src/components/ui/dropdown.tsx +0 -316
  87. package/src/components/ui/field.tsx +0 -244
  88. package/src/components/ui/heading.tsx +0 -74
  89. package/src/components/ui/hover-card.tsx +0 -139
  90. package/src/components/ui/icon-animation.tsx +0 -82
  91. package/src/components/ui/icon-list.tsx +0 -168
  92. package/src/components/ui/index.ts +0 -48
  93. package/src/components/ui/info-card.tsx +0 -110
  94. package/src/components/ui/input-group.tsx +0 -170
  95. package/src/components/ui/input.tsx +0 -72
  96. package/src/components/ui/label-with-icon.tsx +0 -122
  97. package/src/components/ui/label.tsx +0 -24
  98. package/src/components/ui/multi-select.tsx +0 -1090
  99. package/src/components/ui/navigation-bar.tsx +0 -153
  100. package/src/components/ui/navigation-menu.tsx +0 -188
  101. package/src/components/ui/opportunity-details-v1.tsx +0 -104
  102. package/src/components/ui/pagination.tsx +0 -127
  103. package/src/components/ui/popover.tsx +0 -48
  104. package/src/components/ui/scroll-area.tsx +0 -64
  105. package/src/components/ui/segment-control.tsx +0 -146
  106. package/src/components/ui/select.tsx +0 -199
  107. package/src/components/ui/separator.tsx +0 -26
  108. package/src/components/ui/sheet.tsx +0 -139
  109. package/src/components/ui/sidebar.tsx +0 -728
  110. package/src/components/ui/skeleton.tsx +0 -14
  111. package/src/components/ui/slider.tsx +0 -58
  112. package/src/components/ui/sonner.tsx +0 -24
  113. package/src/components/ui/switch.tsx +0 -29
  114. package/src/components/ui/table-shadcn.tsx +0 -110
  115. package/src/components/ui/table.tsx +0 -117
  116. package/src/components/ui/textarea.tsx +0 -22
  117. package/src/components/ui/toggle-group.tsx +0 -71
  118. package/src/components/ui/toggle.tsx +0 -47
  119. package/src/components/ui/tooltip.tsx +0 -66
  120. package/src/hooks/index.ts +0 -1
  121. package/src/hooks/useIsMobile.ts +0 -77
  122. package/src/index.ts +0 -16
  123. package/src/lib/utils.ts +0 -6
  124. package/src/styles/globals.css +0 -181
  125. package/src/styles/themes/index.css +0 -9
  126. package/src/styles/themes/semantic.css +0 -117
  127. package/src/styles/tokens/colors.css +0 -124
  128. package/src/styles/tokens/index.css +0 -15
  129. package/src/styles/tokens/radius.css +0 -18
  130. package/src/styles/tokens/spacing.css +0 -58
  131. package/src/styles/tokens/typography.css +0 -87
  132. package/src/tokens/index.ts +0 -108
  133. package/tsconfig.json +0 -20
  134. package/vite.config.js +0 -49
  135. /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 };