@turtleclub/ui 0.3.0 → 0.4.0-beta.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 (190) hide show
  1. package/.turbo/turbo-build.log +46 -44
  2. package/CHANGELOG.md +12 -0
  3. package/dist/index.cjs +72 -43
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.js +8872 -7439
  6. package/dist/index.js.map +1 -1
  7. package/dist/styles.css +1 -1
  8. package/dist/types/components/features/data-table/data-table.d.ts +19 -0
  9. package/dist/types/components/features/data-table/data-table.d.ts.map +1 -0
  10. package/dist/types/components/features/data-table/expand-toggle.d.ts +5 -0
  11. package/dist/types/components/features/data-table/expand-toggle.d.ts.map +1 -0
  12. package/dist/types/components/features/data-table/fuzzy-filter.d.ts +4 -0
  13. package/dist/types/components/features/data-table/fuzzy-filter.d.ts.map +1 -0
  14. package/dist/types/components/features/data-table/index.d.ts +3 -0
  15. package/dist/types/components/features/data-table/index.d.ts.map +1 -0
  16. package/dist/types/components/features/data-table/sortable-header.d.ts +5 -0
  17. package/dist/types/components/features/data-table/sortable-header.d.ts.map +1 -0
  18. package/dist/types/components/features/page-heading.d.ts +1 -1
  19. package/dist/types/components/features/page-heading.d.ts.map +1 -1
  20. package/dist/types/components/features/sidebar-layout.d.ts.map +1 -1
  21. package/dist/types/components/icons/beta.d.ts.map +1 -1
  22. package/dist/types/components/icons/dot.d.ts.map +1 -1
  23. package/dist/types/components/icons/issue.d.ts.map +1 -1
  24. package/dist/types/components/icons/turtle.d.ts.map +1 -1
  25. package/dist/types/components/icons/update.d.ts.map +1 -1
  26. package/dist/types/components/icons/warning.d.ts.map +1 -1
  27. package/dist/types/components/molecules/opportunity/opportunity-disclaimer.d.ts.map +1 -1
  28. package/dist/types/components/molecules/opportunity/opportunity-list/hooks/use-opportunity-grouping.d.ts.map +1 -1
  29. package/dist/types/components/molecules/opportunity/opportunity-list/opportunity-list.d.ts.map +1 -1
  30. package/dist/types/components/molecules/opportunity/opportunity-rate-estimator.d.ts.map +1 -1
  31. package/dist/types/components/molecules/opportunity/opportunity-section.d.ts.map +1 -1
  32. package/dist/types/components/molecules/opportunity/opportunity-selector.d.ts +1 -1
  33. package/dist/types/components/molecules/opportunity/opportunity-selector.d.ts.map +1 -1
  34. package/dist/types/components/molecules/slippage-selector.d.ts.map +1 -1
  35. package/dist/types/components/molecules/swap-details.d.ts.map +1 -1
  36. package/dist/types/components/molecules/swap-input.d.ts.map +1 -1
  37. package/dist/types/components/molecules/tabs.d.ts +1 -1
  38. package/dist/types/components/molecules/tabs.d.ts.map +1 -1
  39. package/dist/types/components/molecules/token-selector.d.ts.map +1 -1
  40. package/dist/types/components/molecules/tx-status.d.ts.map +1 -1
  41. package/dist/types/components/molecules/widget/asset-list/asset-filters.d.ts.map +1 -1
  42. package/dist/types/components/molecules/widget/asset-list/asset-list.d.ts.map +1 -1
  43. package/dist/types/components/molecules/widget/asset-list/hooks/use-asset-filtering.d.ts.map +1 -1
  44. package/dist/types/components/molecules/widget/asset-list/hooks/use-asset-grouping.d.ts.map +1 -1
  45. package/dist/types/components/molecules/widget/campaign-item.d.ts.map +1 -1
  46. package/dist/types/components/molecules/widget/deal-item.d.ts.map +1 -1
  47. package/dist/types/components/molecules/widget/index.d.ts +1 -1
  48. package/dist/types/components/molecules/widget/index.d.ts.map +1 -1
  49. package/dist/types/components/molecules/widget/opportunity-item.d.ts.map +1 -1
  50. package/dist/types/components/ui/alert-dialog.d.ts.map +1 -1
  51. package/dist/types/components/ui/avatar.d.ts.map +1 -1
  52. package/dist/types/components/ui/badge.d.ts.map +1 -1
  53. package/dist/types/components/ui/banner.d.ts.map +1 -1
  54. package/dist/types/components/ui/button.d.ts.map +1 -1
  55. package/dist/types/components/ui/card.d.ts +1 -1
  56. package/dist/types/components/ui/card.d.ts.map +1 -1
  57. package/dist/types/components/ui/checkbox.d.ts.map +1 -1
  58. package/dist/types/components/ui/chip.d.ts.map +1 -1
  59. package/dist/types/components/ui/collapsible.d.ts.map +1 -1
  60. package/dist/types/components/ui/combobox.d.ts.map +1 -1
  61. package/dist/types/components/ui/command.d.ts.map +1 -1
  62. package/dist/types/components/ui/dialog.d.ts.map +1 -1
  63. package/dist/types/components/ui/dropdown.d.ts.map +1 -1
  64. package/dist/types/components/ui/field.d.ts.map +1 -1
  65. package/dist/types/components/ui/heading.d.ts.map +1 -1
  66. package/dist/types/components/ui/hover-card.d.ts +1 -1
  67. package/dist/types/components/ui/hover-card.d.ts.map +1 -1
  68. package/dist/types/components/ui/icon-list.d.ts.map +1 -1
  69. package/dist/types/components/ui/info-card.d.ts.map +1 -1
  70. package/dist/types/components/ui/input-group.d.ts.map +1 -1
  71. package/dist/types/components/ui/input.d.ts.map +1 -1
  72. package/dist/types/components/ui/label.d.ts.map +1 -1
  73. package/dist/types/components/ui/multi-select.d.ts.map +1 -1
  74. package/dist/types/components/ui/navigation-bar.d.ts +1 -1
  75. package/dist/types/components/ui/navigation-bar.d.ts.map +1 -1
  76. package/dist/types/components/ui/navigation-menu.d.ts.map +1 -1
  77. package/dist/types/components/ui/opportunity-details-v1.d.ts.map +1 -1
  78. package/dist/types/components/ui/popover.d.ts.map +1 -1
  79. package/dist/types/components/ui/scroll-area.d.ts.map +1 -1
  80. package/dist/types/components/ui/select.d.ts.map +1 -1
  81. package/dist/types/components/ui/separator.d.ts.map +1 -1
  82. package/dist/types/components/ui/sheet.d.ts.map +1 -1
  83. package/dist/types/components/ui/sidebar.d.ts.map +1 -1
  84. package/dist/types/components/ui/slider.d.ts.map +1 -1
  85. package/dist/types/components/ui/switch.d.ts.map +1 -1
  86. package/dist/types/components/ui/table-shadcn.d.ts.map +1 -1
  87. package/dist/types/components/ui/table.d.ts.map +1 -1
  88. package/dist/types/components/ui/toggle-group.d.ts.map +1 -1
  89. package/dist/types/components/ui/toggle.d.ts.map +1 -1
  90. package/dist/types/components/ui/tooltip.d.ts.map +1 -1
  91. package/dist/types/hooks/useIsMobile.d.ts.map +1 -1
  92. package/dist/types/lib/utils.d.ts.map +1 -1
  93. package/dist/types/tokens/index.d.ts +5 -5
  94. package/dist/types/tokens/index.d.ts.map +1 -1
  95. package/package.json +3 -2
  96. package/src/components/features/data-table/data-table.tsx +150 -0
  97. package/src/components/features/data-table/expand-toggle.tsx +17 -0
  98. package/src/components/features/data-table/fuzzy-filter.tsx +34 -0
  99. package/src/components/features/data-table/index.ts +2 -0
  100. package/src/components/features/data-table/sortable-header.tsx +37 -0
  101. package/src/components/features/page-heading.tsx +6 -1
  102. package/src/components/features/search-bar.tsx +1 -1
  103. package/src/components/features/sidebar-layout.tsx +6 -3
  104. package/src/components/icons/beta.tsx +11 -2
  105. package/src/components/icons/dot.tsx +16 -3
  106. package/src/components/icons/issue.tsx +11 -2
  107. package/src/components/icons/turtle.tsx +16 -3
  108. package/src/components/icons/update.tsx +6 -1
  109. package/src/components/icons/warning.tsx +11 -2
  110. package/src/components/molecules/opportunity/opportunity-disclaimer.tsx +13 -5
  111. package/src/components/molecules/opportunity/opportunity-list/hooks/index.ts +1 -1
  112. package/src/components/molecules/opportunity/opportunity-list/hooks/use-opportunity-filtering.ts +3 -3
  113. package/src/components/molecules/opportunity/opportunity-list/hooks/use-opportunity-grouping.ts +7 -3
  114. package/src/components/molecules/opportunity/opportunity-list/index.ts +1 -1
  115. package/src/components/molecules/opportunity/opportunity-list/opportunity-list.tsx +10 -4
  116. package/src/components/molecules/opportunity/opportunity-rate-estimator.tsx +5 -6
  117. package/src/components/molecules/opportunity/opportunity-section.tsx +23 -6
  118. package/src/components/molecules/opportunity/opportunity-selector.tsx +7 -3
  119. package/src/components/molecules/slippage-selector.tsx +44 -20
  120. package/src/components/molecules/swap-details.tsx +14 -5
  121. package/src/components/molecules/swap-input.tsx +12 -6
  122. package/src/components/molecules/tabs.tsx +16 -4
  123. package/src/components/molecules/token-selector.tsx +38 -20
  124. package/src/components/molecules/tx-status.tsx +105 -54
  125. package/src/components/molecules/widget/asset-list/asset-filters.tsx +4 -2
  126. package/src/components/molecules/widget/asset-list/asset-list.tsx +8 -3
  127. package/src/components/molecules/widget/asset-list/asset-row.tsx +1 -1
  128. package/src/components/molecules/widget/asset-list/hooks/index.ts +1 -1
  129. package/src/components/molecules/widget/asset-list/hooks/use-asset-filtering.ts +4 -2
  130. package/src/components/molecules/widget/asset-list/hooks/use-asset-grouping.ts +15 -6
  131. package/src/components/molecules/widget/base-selector.tsx +5 -5
  132. package/src/components/molecules/widget/campaign-item.tsx +12 -6
  133. package/src/components/molecules/widget/deal-item.tsx +20 -8
  134. package/src/components/molecules/widget/index.ts +4 -1
  135. package/src/components/molecules/widget/opportunity-item.tsx +22 -8
  136. package/src/components/molecules/widget/widget-item-stats.tsx +2 -2
  137. package/src/components/ui/alert-dialog.tsx +26 -9
  138. package/src/components/ui/animated-background/animated-background.tsx +14 -6
  139. package/src/components/ui/animated-background/index.ts +1 -1
  140. package/src/components/ui/avatar.tsx +12 -3
  141. package/src/components/ui/badge.tsx +5 -3
  142. package/src/components/ui/banner.tsx +9 -3
  143. package/src/components/ui/button.tsx +10 -5
  144. package/src/components/ui/card.tsx +32 -5
  145. package/src/components/ui/checkbox.tsx +5 -2
  146. package/src/components/ui/chip.tsx +10 -6
  147. package/src/components/ui/collapsible.tsx +15 -3
  148. package/src/components/ui/combobox.tsx +52 -25
  149. package/src/components/ui/command.tsx +31 -11
  150. package/src/components/ui/dialog.tsx +22 -8
  151. package/src/components/ui/dropdown.tsx +57 -20
  152. package/src/components/ui/field.tsx +40 -28
  153. package/src/components/ui/heading.tsx +31 -6
  154. package/src/components/ui/hover-card.tsx +35 -10
  155. package/src/components/ui/icon-animation.tsx +12 -12
  156. package/src/components/ui/icon-list.tsx +45 -18
  157. package/src/components/ui/info-card.tsx +13 -5
  158. package/src/components/ui/input-group.tsx +32 -20
  159. package/src/components/ui/input.tsx +5 -3
  160. package/src/components/ui/label.tsx +5 -2
  161. package/src/components/ui/multi-select.tsx +133 -61
  162. package/src/components/ui/navigation-bar.tsx +39 -22
  163. package/src/components/ui/navigation-menu.tsx +16 -9
  164. package/src/components/ui/opportunity-details-v1.tsx +9 -5
  165. package/src/components/ui/popover.tsx +10 -4
  166. package/src/components/ui/scroll-area.tsx +5 -3
  167. package/src/components/ui/select.tsx +25 -10
  168. package/src/components/ui/separator.tsx +6 -6
  169. package/src/components/ui/sheet.tsx +15 -6
  170. package/src/components/ui/sidebar.tsx +62 -26
  171. package/src/components/ui/slider.tsx +10 -5
  172. package/src/components/ui/switch.tsx +6 -3
  173. package/src/components/ui/table-shadcn.tsx +19 -9
  174. package/src/components/ui/table.tsx +12 -5
  175. package/src/components/ui/textarea.tsx +1 -1
  176. package/src/components/ui/toggle-group.tsx +12 -12
  177. package/src/components/ui/toggle.tsx +14 -14
  178. package/src/components/ui/tooltip.tsx +7 -3
  179. package/src/hooks/useIsMobile.ts +5 -2
  180. package/src/lib/utils.ts +3 -3
  181. package/src/styles/themes/index.css +1 -1
  182. package/src/styles/themes/semantic.css +51 -17
  183. package/src/styles/tokens/colors.css +54 -18
  184. package/src/styles/tokens/index.css +1 -1
  185. package/src/styles/tokens/spacing.css +39 -33
  186. package/src/styles/tokens/typography.css +61 -60
  187. package/src/tokens/index.ts +82 -82
  188. package/dist/types/components/features/data-table.d.ts +0 -9
  189. package/dist/types/components/features/data-table.d.ts.map +0 -1
  190. package/src/components/features/data-table.tsx +0 -96
@@ -1,7 +1,12 @@
1
1
  "use client";
2
2
  import * as React from "react";
3
3
  import { cn } from "@/lib/utils";
4
- import { Select, SelectContent, SelectItem, SelectTrigger } from "@/components/ui/select";
4
+ import {
5
+ Select,
6
+ SelectContent,
7
+ SelectItem,
8
+ SelectTrigger,
9
+ } from "@/components/ui/select";
5
10
  import { useEffect } from "react";
6
11
 
7
12
  interface Token {
@@ -35,10 +40,13 @@ const TokenSelector = ({
35
40
  showBalance = true,
36
41
  }: TokenSelectorProps) => {
37
42
  // Auto-select first token if no value is provided and tokens exist
38
- const effectiveValue = value || (tokens.length > 0 ? tokens[0].address : undefined);
43
+ const effectiveValue =
44
+ value || (tokens.length > 0 ? tokens[0].address : undefined);
39
45
 
40
46
  // Find the selected token to display in the trigger
41
- const selectedToken = tokens.find((token) => token.address === effectiveValue);
47
+ const selectedToken = tokens.find(
48
+ (token) => token.address === effectiveValue,
49
+ );
42
50
 
43
51
  // Handle value change and auto-select first token on mount
44
52
  useEffect(() => {
@@ -48,17 +56,21 @@ const TokenSelector = ({
48
56
  }, [value, tokens, onValueChange]);
49
57
 
50
58
  return (
51
- <Select value={effectiveValue} onValueChange={onValueChange} disabled={disabled}>
59
+ <Select
60
+ value={effectiveValue}
61
+ onValueChange={onValueChange}
62
+ disabled={disabled}
63
+ >
52
64
  <SelectTrigger
53
65
  // variant={variant}
54
66
  // size={size}
55
67
  className={cn(
56
- "w-auto min-w-[80px] bg-muted hover:bg-muted/80 rounded-md font-medium",
57
- "focus:ring-2 focus:ring-primary/20 focus:outline-none",
68
+ "bg-muted hover:bg-muted/80 w-auto min-w-[80px] rounded-md font-medium",
69
+ "focus:ring-primary/20 focus:ring-2 focus:outline-none",
58
70
  size === "xs" && "min-w-[80px] gap-2",
59
71
  size === "sm" && "min-w-[75px] gap-1.5",
60
72
  size === "default" && "min-w-[80px] gap-1.5",
61
- className
73
+ className,
62
74
  )}
63
75
  >
64
76
  {selectedToken ? (
@@ -67,15 +79,15 @@ const TokenSelector = ({
67
79
  "flex items-center",
68
80
  size === "xs" && "gap-2",
69
81
  size === "sm" && "gap-1.5",
70
- size === "default" && "gap-1.5"
82
+ size === "default" && "gap-1.5",
71
83
  )}
72
84
  >
73
85
  <span
74
86
  className={cn(
75
87
  "flex items-center justify-center",
76
- size === "xs" && "w-3.5 h-3",
77
- size === "sm" && "w-4 h-3.5",
78
- size === "default" && "w-5 h-4"
88
+ size === "xs" && "h-3 w-3.5",
89
+ size === "sm" && "h-3.5 w-4",
90
+ size === "default" && "h-4 w-5",
79
91
  )}
80
92
  >
81
93
  {selectedToken.icon}
@@ -85,7 +97,7 @@ const TokenSelector = ({
85
97
  "font-medium",
86
98
  size === "xs" && "text-xs",
87
99
  size === "sm" && "text-sm",
88
- size === "default" && "text-sm"
100
+ size === "default" && "text-sm",
89
101
  )}
90
102
  >
91
103
  {selectedToken.symbol}
@@ -97,24 +109,28 @@ const TokenSelector = ({
97
109
  "text-muted-foreground",
98
110
  size === "xs" && "text-xs",
99
111
  size === "sm" && "text-sm",
100
- size === "default" && "text-sm"
112
+ size === "default" && "text-sm",
101
113
  )}
102
114
  >
103
115
  {placeholder}
104
116
  </span>
105
117
  )}
106
118
  </SelectTrigger>
107
- <SelectContent className="border border-muted gap-2">
119
+ <SelectContent className="border-muted gap-2 border">
108
120
  {tokens.map((token) => (
109
- <SelectItem key={token.address} value={token.address} className="cursor-pointer py-2">
121
+ <SelectItem
122
+ key={token.address}
123
+ value={token.address}
124
+ className="cursor-pointer py-2"
125
+ >
110
126
  <div className="flex flex-col gap-2">
111
127
  <div className="flex items-center gap-2">
112
128
  <span
113
129
  className={cn(
114
130
  "flex items-center justify-center",
115
- size === "xs" && "w-3.5 h-3.5",
116
- size === "sm" && "w-4 h-4",
117
- size === "default" && "w-5 h-4"
131
+ size === "xs" && "h-3.5 w-3.5",
132
+ size === "sm" && "h-4 w-4",
133
+ size === "default" && "h-4 w-5",
118
134
  )}
119
135
  >
120
136
  {token.icon}
@@ -124,13 +140,15 @@ const TokenSelector = ({
124
140
  "font-medium",
125
141
  size === "xs" && "text-xs",
126
142
  size === "sm" && "text-sm",
127
- size === "default" && "text-sm"
143
+ size === "default" && "text-sm",
128
144
  )}
129
145
  >
130
146
  {token.symbol}
131
147
  </span>
132
148
  </div>
133
- {showBalance && <span className="text-white/80 text-xs">≈ {token.balance}</span>}
149
+ {showBalance && (
150
+ <span className="text-xs text-white/80">≈ {token.balance}</span>
151
+ )}
134
152
  </div>
135
153
  </SelectItem>
136
154
  ))}
@@ -49,7 +49,7 @@ const TxStatus = React.forwardRef<HTMLDivElement, TxStatusProps>(
49
49
  showActions = true,
50
50
  ...props
51
51
  },
52
- ref
52
+ ref,
53
53
  ) => {
54
54
  const defaultTitle = cancelled
55
55
  ? "Transaction Cancelled"
@@ -63,7 +63,12 @@ const TxStatus = React.forwardRef<HTMLDivElement, TxStatusProps>(
63
63
  : "Please wait while your transaction is being processed...";
64
64
 
65
65
  const ExternalLinkIcon = ({ size = "w-4 h-4" }) => (
66
- <svg className={size} fill="none" stroke="currentColor" viewBox="0 0 24 24">
66
+ <svg
67
+ className={size}
68
+ fill="none"
69
+ stroke="currentColor"
70
+ viewBox="0 0 24 24"
71
+ >
67
72
  <path
68
73
  strokeLinecap="round"
69
74
  strokeLinejoin="round"
@@ -74,8 +79,18 @@ const TxStatus = React.forwardRef<HTMLDivElement, TxStatusProps>(
74
79
  );
75
80
 
76
81
  const StepCheckIcon = () => (
77
- <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
78
- <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
82
+ <svg
83
+ className="h-4 w-4"
84
+ fill="none"
85
+ stroke="currentColor"
86
+ viewBox="0 0 24 24"
87
+ >
88
+ <path
89
+ strokeLinecap="round"
90
+ strokeLinejoin="round"
91
+ strokeWidth={2}
92
+ d="M5 13l4 4L19 7"
93
+ />
79
94
  </svg>
80
95
  );
81
96
 
@@ -88,9 +103,9 @@ const TxStatus = React.forwardRef<HTMLDivElement, TxStatusProps>(
88
103
  <Card
89
104
  ref={ref}
90
105
  className={cn(
91
- "p-4 text-center space-y-3",
92
- variant === "compact" && "p-3 space-y-2",
93
- className
106
+ "space-y-3 p-4 text-center",
107
+ variant === "compact" && "space-y-2 p-3",
108
+ className,
94
109
  )}
95
110
  {...props}
96
111
  >
@@ -102,15 +117,24 @@ const TxStatus = React.forwardRef<HTMLDivElement, TxStatusProps>(
102
117
  >
103
118
  {cancelled ? (
104
119
  <XIcon
105
- className={cn(variant === "compact" ? "w-5 h-5" : "w-6 h-6", "text-destructive")}
120
+ className={cn(
121
+ variant === "compact" ? "h-5 w-5" : "h-6 w-6",
122
+ "text-destructive",
123
+ )}
106
124
  />
107
125
  ) : completed ? (
108
126
  <CheckIcon
109
- className={cn(variant === "compact" ? "w-5 h-5" : "w-6 h-6", "text-primary")}
127
+ className={cn(
128
+ variant === "compact" ? "h-5 w-5" : "h-6 w-6",
129
+ "text-primary",
130
+ )}
110
131
  />
111
132
  ) : (
112
133
  <TurtleIcon
113
- className={cn(variant === "compact" ? "w-5 h-5" : "w-6 h-6", "text-primary")}
134
+ className={cn(
135
+ variant === "compact" ? "h-5 w-5" : "h-6 w-6",
136
+ "text-primary",
137
+ )}
114
138
  />
115
139
  )}
116
140
  </IconAnimation>
@@ -120,88 +144,110 @@ const TxStatus = React.forwardRef<HTMLDivElement, TxStatusProps>(
120
144
  <div className="space-y-1">
121
145
  <h3
122
146
  className={cn(
123
- "font-medium text-foreground",
124
- variant === "compact" ? "text-xs" : "text-sm"
147
+ "text-foreground font-medium",
148
+ variant === "compact" ? "text-xs" : "text-sm",
125
149
  )}
126
150
  >
127
151
  {title || defaultTitle}
128
152
  </h3>
129
- <p className={cn("text-muted-foreground", variant === "compact" ? "text-xs" : "text-xs")}>
153
+ <p
154
+ className={cn(
155
+ "text-muted-foreground",
156
+ variant === "compact" ? "text-xs" : "text-xs",
157
+ )}
158
+ >
130
159
  {description || defaultDescription}
131
160
  </p>
132
161
  </div>
133
162
 
134
163
  {/* Transaction summary (completed state) */}
135
164
  {completed && !cancelled && (amount || token || protocol) && (
136
- <div className="p-2 bg-muted/50 rounded-lg space-y-1">
165
+ <div className="bg-muted/50 space-y-1 rounded-lg p-2">
137
166
  {amount && token && (
138
167
  <div className="text-xs font-medium">
139
168
  {amount} {token}
140
169
  </div>
141
170
  )}
142
- {protocol && <div className="text-xs text-muted-foreground">via {protocol}</div>}
171
+ {protocol && (
172
+ <div className="text-muted-foreground text-xs">
173
+ via {protocol}
174
+ </div>
175
+ )}
143
176
  </div>
144
177
  )}
145
178
 
146
179
  {/* Transaction hash link */}
147
180
  {txHash && !cancelled && (
148
181
  <div className="space-y-1">
149
- <div className="text-xs text-muted-foreground">Transaction Hash</div>
182
+ <div className="text-muted-foreground text-xs">
183
+ Transaction Hash
184
+ </div>
150
185
  {explorerUrl ? (
151
186
  <a
152
187
  href={`${explorerUrl}/tx/${txHash}`}
153
188
  target="_blank"
154
189
  rel="noopener noreferrer"
155
- className="inline-flex items-center gap-2 text-xs text-primary hover:text-primary/80 transition-colors"
190
+ className="text-primary hover:text-primary/80 inline-flex items-center gap-2 text-xs transition-colors"
156
191
  >
157
192
  {formatTxHash(txHash)}
158
193
  <ExternalLinkIcon />
159
194
  </a>
160
195
  ) : (
161
- <div className="text-xs font-mono text-foreground">{formatTxHash(txHash)}</div>
196
+ <div className="text-foreground font-mono text-xs">
197
+ {formatTxHash(txHash)}
198
+ </div>
162
199
  )}
163
200
  </div>
164
201
  )}
165
202
 
166
203
  {/* Estimated time (pending state) */}
167
204
  {!completed && !cancelled && estimatedTime && (
168
- <div className="text-xs text-muted-foreground">Estimated time: {estimatedTime}</div>
205
+ <div className="text-muted-foreground text-xs">
206
+ Estimated time: {estimatedTime}
207
+ </div>
169
208
  )}
170
209
 
171
210
  {/* Progress steps (pending state) */}
172
211
  {!completed && !cancelled && steps.length > 0 && (
173
- <div className="space-y-2 pt-2 border-t border-border">
174
- <div className="text-xs font-medium text-muted-foreground text-left">Progress</div>
212
+ <div className="border-border space-y-2 border-t pt-2">
213
+ <div className="text-muted-foreground text-left text-xs font-medium">
214
+ Progress
215
+ </div>
175
216
  <div className="space-y-2">
176
217
  {steps.map((step, index) => (
177
218
  <div key={index} className="flex items-center gap-3 text-left">
178
219
  <div
179
220
  className={cn(
180
- "flex items-center justify-center w-5 h-5 rounded-full border-2 flex-shrink-0",
181
- step.completed && "bg-primary border-primary text-primary-foreground",
221
+ "flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full border-2",
222
+ step.completed &&
223
+ "bg-primary border-primary text-primary-foreground",
182
224
  step.current &&
183
225
  !step.completed &&
184
226
  "border-primary text-primary animate-pulse",
185
227
  !step.completed &&
186
228
  !step.current &&
187
- "border-muted-foreground/30 text-muted-foreground"
229
+ "border-muted-foreground/30 text-muted-foreground",
188
230
  )}
189
231
  >
190
232
  {step.completed ? (
191
233
  <StepCheckIcon />
192
234
  ) : step.current ? (
193
- <div className="w-2 h-2 rounded-full bg-primary animate-pulse" />
235
+ <div className="bg-primary h-2 w-2 animate-pulse rounded-full" />
194
236
  ) : (
195
- <div className="w-2 h-2 rounded-full bg-muted-foreground/30" />
237
+ <div className="bg-muted-foreground/30 h-2 w-2 rounded-full" />
196
238
  )}
197
239
  </div>
198
- <div className="flex-1 flex items-center justify-between">
240
+ <div className="flex flex-1 items-center justify-between">
199
241
  <span
200
242
  className={cn(
201
243
  "text-xs",
202
244
  step.completed && "text-foreground",
203
- step.current && !step.completed && "text-foreground font-medium",
204
- !step.completed && !step.current && "text-muted-foreground"
245
+ step.current &&
246
+ !step.completed &&
247
+ "text-foreground font-medium",
248
+ !step.completed &&
249
+ !step.current &&
250
+ "text-muted-foreground",
205
251
  )}
206
252
  >
207
253
  {step.label}
@@ -211,7 +257,7 @@ const TxStatus = React.forwardRef<HTMLDivElement, TxStatusProps>(
211
257
  href={`${explorerUrl}/tx/${step.txHash}`}
212
258
  target="_blank"
213
259
  rel="noopener noreferrer"
214
- className="inline-flex items-center gap-1 text-xs text-primary hover:text-primary/80 transition-colors ml-2"
260
+ className="text-primary hover:text-primary/80 ml-2 inline-flex items-center gap-1 text-xs transition-colors"
215
261
  title={`View transaction: ${step.txHash}`}
216
262
  >
217
263
  <span className="font-mono">
@@ -228,32 +274,37 @@ const TxStatus = React.forwardRef<HTMLDivElement, TxStatusProps>(
228
274
  )}
229
275
 
230
276
  {/* Action buttons (completed or cancelled state) */}
231
- {(completed || cancelled) && showActions && (onViewDetails || onClose) && (
232
- <div
233
- className={cn(
234
- "flex gap-2 pt-2",
235
- variant === "compact" ? "flex-col" : "flex-row justify-center"
236
- )}
237
- >
238
- {!cancelled && onViewDetails && (
239
- <Button size={variant === "compact" ? "sm" : "default"} onClick={onViewDetails}>
240
- View Details
241
- </Button>
242
- )}
243
- {onClose && (
244
- <Button
245
- variant="default"
246
- size={variant === "compact" ? "sm" : "default"}
247
- onClick={onClose}
248
- >
249
- {cancelled ? "Try Again" : "Done"}
250
- </Button>
251
- )}
252
- </div>
253
- )}
277
+ {(completed || cancelled) &&
278
+ showActions &&
279
+ (onViewDetails || onClose) && (
280
+ <div
281
+ className={cn(
282
+ "flex gap-2 pt-2",
283
+ variant === "compact" ? "flex-col" : "flex-row justify-center",
284
+ )}
285
+ >
286
+ {!cancelled && onViewDetails && (
287
+ <Button
288
+ size={variant === "compact" ? "sm" : "default"}
289
+ onClick={onViewDetails}
290
+ >
291
+ View Details
292
+ </Button>
293
+ )}
294
+ {onClose && (
295
+ <Button
296
+ variant="default"
297
+ size={variant === "compact" ? "sm" : "default"}
298
+ onClick={onClose}
299
+ >
300
+ {cancelled ? "Try Again" : "Done"}
301
+ </Button>
302
+ )}
303
+ </div>
304
+ )}
254
305
  </Card>
255
306
  );
256
- }
307
+ },
257
308
  );
258
309
 
259
310
  TxStatus.displayName = "TxStatus";
@@ -60,7 +60,7 @@ export const AssetFilters: React.FC<AssetFiltersProps> = ({
60
60
  onFiltersChange(newFilters);
61
61
  }
62
62
  },
63
- [activeFilters, onFiltersChange, variant, multipleFilters]
63
+ [activeFilters, onFiltersChange, variant, multipleFilters],
64
64
  );
65
65
 
66
66
  return (
@@ -83,7 +83,9 @@ export const AssetFilters: React.FC<AssetFiltersProps> = ({
83
83
  {filters.map((filter) => (
84
84
  <Badge
85
85
  key={filter.id}
86
- variant={activeFilters.includes(filter.id) ? "default" : "muted"}
86
+ variant={
87
+ activeFilters.includes(filter.id) ? "default" : "muted"
88
+ }
87
89
  className="bg-muted cursor-pointer rounded-full"
88
90
  onClick={() => handleFilterToggle(filter.id)}
89
91
  >
@@ -2,7 +2,10 @@
2
2
  import React, { useState } from "react";
3
3
  import { WidgetListItems } from "../widget-list-items";
4
4
  import { AssetRow } from "./asset-row";
5
- import { AssetFilters, AssetFilterItem as BaseAssetFilter } from "./asset-filters";
5
+ import {
6
+ AssetFilters,
7
+ AssetFilterItem as BaseAssetFilter,
8
+ } from "./asset-filters";
6
9
  import { useAssetFiltering, useAssetGrouping } from "./hooks";
7
10
  import { ScrollArea } from "@/components/ui/scroll-area";
8
11
  import { cn } from "@/lib/utils";
@@ -68,13 +71,15 @@ const defaultFilters: AssetFilterProp[] = [
68
71
  id: "eth",
69
72
  label: "ETH",
70
73
  filterFn: (asset) =>
71
- ["ETH"].includes(asset.symbol.toUpperCase()) || ["ETH"].includes(asset.name.toUpperCase()),
74
+ ["ETH"].includes(asset.symbol.toUpperCase()) ||
75
+ ["ETH"].includes(asset.name.toUpperCase()),
72
76
  },
73
77
  {
74
78
  id: "btc",
75
79
  label: "BTC",
76
80
  filterFn: (asset) =>
77
- ["BTC"].includes(asset.symbol.toUpperCase()) || ["BTC"].includes(asset.name.toUpperCase()),
81
+ ["BTC"].includes(asset.symbol.toUpperCase()) ||
82
+ ["BTC"].includes(asset.name.toUpperCase()),
78
83
  },
79
84
  ];
80
85
 
@@ -26,7 +26,7 @@ export const AssetRow: React.FC<AssetRowProps> = ({
26
26
  className={cn(
27
27
  "flex cursor-pointer items-center justify-between rounded-lg px-3.5 py-2.5 transition-colors",
28
28
  "hover:bg-secondary",
29
- className
29
+ className,
30
30
  )}
31
31
  >
32
32
  <div className="flex items-center gap-3">
@@ -1,2 +1,2 @@
1
1
  export * from "./use-asset-filtering";
2
- export * from "./use-asset-grouping";
2
+ export * from "./use-asset-grouping";
@@ -24,7 +24,7 @@ export function useAssetFiltering({
24
24
  (asset) =>
25
25
  asset.symbol.toLowerCase().includes(query) ||
26
26
  asset.name.toLowerCase().includes(query) ||
27
- asset.address?.toLowerCase().includes(query)
27
+ asset.address?.toLowerCase().includes(query),
28
28
  );
29
29
  }
30
30
 
@@ -34,7 +34,9 @@ export function useAssetFiltering({
34
34
  .filter((f) => activeFilterIds.includes(f.id))
35
35
  .map((f) => f.filterFn);
36
36
 
37
- result = result.filter((asset) => activeFilterFns.every((filterFn) => filterFn(asset)));
37
+ result = result.filter((asset) =>
38
+ activeFilterFns.every((filterFn) => filterFn(asset)),
39
+ );
38
40
  }
39
41
 
40
42
  return result;
@@ -9,7 +9,8 @@ interface UseAssetGroupingProps {
9
9
 
10
10
  const CHAIN_ICONS: Record<number, string> = {
11
11
  1: "https://storage.googleapis.com/turtle-assets/tokens/eth.png",
12
- 747474: "https://storage.googleapis.com/turtle-assets/partners/polygon/katana.svg",
12
+ 747474:
13
+ "https://storage.googleapis.com/turtle-assets/partners/polygon/katana.svg",
13
14
  };
14
15
 
15
16
  export function useAssetGrouping({
@@ -49,7 +50,7 @@ export function useAssetGrouping({
49
50
  acc[asset.chainId].items.push(asset);
50
51
  return acc;
51
52
  },
52
- {} as Record<string, WidgetListGroup<Asset>>
53
+ {} as Record<string, WidgetListGroup<Asset>>,
53
54
  );
54
55
 
55
56
  console.log("chainGroups", chainGroups);
@@ -59,14 +60,22 @@ export function useAssetGrouping({
59
60
  groupsArray.sort((a, b) => {
60
61
  // Get the highest balance in each group (items are already sorted)
61
62
  const maxBalanceA =
62
- a.items.length > 0 ? parseFloat(a.items[0].balanceUSD.replace(/[$,]/g, "") || "0") : 0;
63
+ a.items.length > 0
64
+ ? parseFloat(a.items[0].balanceUSD.replace(/[$,]/g, "") || "0")
65
+ : 0;
63
66
  const maxBalanceB =
64
- b.items.length > 0 ? parseFloat(b.items[0].balanceUSD.replace(/[$,]/g, "") || "0") : 0;
67
+ b.items.length > 0
68
+ ? parseFloat(b.items[0].balanceUSD.replace(/[$,]/g, "") || "0")
69
+ : 0;
65
70
 
66
71
  // If highest balances are equal, sort by number of tokens with non-zero balance
67
72
  if (maxBalanceA === maxBalanceB) {
68
- const nonZeroCountA = a.items.filter((asset) => parseFloat(asset.balance) > 0).length;
69
- const nonZeroCountB = b.items.filter((asset) => parseFloat(asset.balance) > 0).length;
73
+ const nonZeroCountA = a.items.filter(
74
+ (asset) => parseFloat(asset.balance) > 0,
75
+ ).length;
76
+ const nonZeroCountB = b.items.filter(
77
+ (asset) => parseFloat(asset.balance) > 0,
78
+ ).length;
70
79
  return nonZeroCountB - nonZeroCountA;
71
80
  }
72
81
 
@@ -47,7 +47,7 @@ const BaseSelector = ({
47
47
  size === "xs" && "h-7 min-w-[80px] gap-2 px-2.5 py-1",
48
48
  size === "sm" && "h-8 min-w-[75px] gap-1.5 px-3 py-1.5",
49
49
  size === "default" && "h-10 min-w-[80px] gap-1.5 px-3 py-2",
50
- className
50
+ className,
51
51
  )}
52
52
  role="button"
53
53
  tabIndex={0}
@@ -58,7 +58,7 @@ const BaseSelector = ({
58
58
  "flex items-center",
59
59
  size === "xs" && "gap-2",
60
60
  size === "sm" && "gap-1.5",
61
- size === "default" && "gap-1.5"
61
+ size === "default" && "gap-1.5",
62
62
  )}
63
63
  >
64
64
  {showIcon && icon && (
@@ -67,7 +67,7 @@ const BaseSelector = ({
67
67
  "flex items-center justify-center",
68
68
  size === "xs" && "h-3 w-3.5",
69
69
  size === "sm" && "h-3.5 w-4",
70
- size === "default" && "h-4 w-5"
70
+ size === "default" && "h-4 w-5",
71
71
  )}
72
72
  >
73
73
  {icon}
@@ -78,7 +78,7 @@ const BaseSelector = ({
78
78
  "font-medium",
79
79
  size === "xs" && "text-xs",
80
80
  size === "sm" && "text-sm",
81
- size === "default" && "text-sm"
81
+ size === "default" && "text-sm",
82
82
  )}
83
83
  >
84
84
  {text}
@@ -90,7 +90,7 @@ const BaseSelector = ({
90
90
  "text-muted-foreground",
91
91
  size === "xs" && "text-xs",
92
92
  size === "sm" && "text-sm",
93
- size === "default" && "text-sm"
93
+ size === "default" && "text-sm",
94
94
  )}
95
95
  >
96
96
  {placeholder}
@@ -32,8 +32,8 @@ const CampaignItem = React.forwardRef<HTMLDivElement, CampaignItemProps>(
32
32
 
33
33
  // TODO: Refactor and add default icon here, maybe turtle icon?
34
34
  const defaultIcon = (
35
- <div className="w-6 h-6 rounded-full bg-primary/20 flex items-center justify-center">
36
- <svg className="w-4 h-4" viewBox="0 0 24 24" fill="currentColor">
35
+ <div className="bg-primary/20 flex h-6 w-6 items-center justify-center rounded-full">
36
+ <svg className="h-4 w-4" viewBox="0 0 24 24" fill="currentColor">
37
37
  <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm4.59-12.42L10 14.17l-2.59-2.58L6 13l4 4 8-8z" />
38
38
  </svg>
39
39
  </div>
@@ -48,12 +48,18 @@ const CampaignItem = React.forwardRef<HTMLDivElement, CampaignItemProps>(
48
48
  <WidgetItem ref={ref} onSelect={onSelect} selected={selected} {...props}>
49
49
  <WidgetItemTop>
50
50
  <WidgetItemLeft>
51
- <LabelWithIcon icon={icon || defaultIcon} textSize="base" iconSize="lg">
51
+ <LabelWithIcon
52
+ icon={icon || defaultIcon}
53
+ textSize="base"
54
+ iconSize="lg"
55
+ >
52
56
  {name}
53
57
  </LabelWithIcon>
54
58
  </WidgetItemLeft>
55
59
  <WidgetItemRight>
56
- <span className="text-md font-semibold text-foreground">{aprRange || "N/A"}</span>
60
+ <span className="text-md text-foreground font-semibold">
61
+ {aprRange || "N/A"}
62
+ </span>
57
63
  </WidgetItemRight>
58
64
  </WidgetItemTop>
59
65
  <WidgetItemBottom>
@@ -61,13 +67,13 @@ const CampaignItem = React.forwardRef<HTMLDivElement, CampaignItemProps>(
61
67
  {chains && <IconList items={chains} label="Chains" size="sm" />}
62
68
  <WidgetItemStats stats={stats} />
63
69
  </WidgetItemLeft>
64
- <WidgetItemRight className="flex flex-col gap-1 items-end">
70
+ <WidgetItemRight className="flex flex-col items-end gap-1">
65
71
  {rewards && <IconList items={rewards} label="Rewards" size="sm" />}
66
72
  </WidgetItemRight>
67
73
  </WidgetItemBottom>
68
74
  </WidgetItem>
69
75
  );
70
- }
76
+ },
71
77
  );
72
78
 
73
79
  CampaignItem.displayName = "CampaignItem";