@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
@@ -14,7 +14,7 @@ function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
14
14
  className={cn(
15
15
  "flex flex-col gap-6",
16
16
  "has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
17
- className
17
+ className,
18
18
  )}
19
19
  {...props}
20
20
  />
@@ -34,7 +34,7 @@ function FieldLegend({
34
34
  "mb-3 font-medium",
35
35
  "data-[variant=legend]:text-base",
36
36
  "data-[variant=label]:text-sm",
37
- className
37
+ className,
38
38
  )}
39
39
  {...props}
40
40
  />
@@ -47,33 +47,36 @@ function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
47
47
  data-slot="field-group"
48
48
  className={cn(
49
49
  "group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4",
50
- className
50
+ className,
51
51
  )}
52
52
  {...props}
53
53
  />
54
54
  );
55
55
  }
56
56
 
57
- const fieldVariants = cva("group/field data-[invalid=true]:text-destructive flex w-full gap-3", {
58
- variants: {
59
- orientation: {
60
- vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"],
61
- horizontal: [
62
- "flex-row items-center",
63
- "[&>[data-slot=field-label]]:flex-auto",
64
- "has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
65
- ],
66
- responsive: [
67
- "flex-col @md/field-group:flex-row @md/field-group:items-center [&>*]:w-full @md/field-group:[&>*]:w-auto [&>.sr-only]:w-auto",
68
- "@md/field-group:[&>[data-slot=field-label]]:flex-auto",
69
- "@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
70
- ],
57
+ const fieldVariants = cva(
58
+ "group/field data-[invalid=true]:text-destructive flex w-full gap-3",
59
+ {
60
+ variants: {
61
+ orientation: {
62
+ vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"],
63
+ horizontal: [
64
+ "flex-row items-center",
65
+ "[&>[data-slot=field-label]]:flex-auto",
66
+ "has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
67
+ ],
68
+ responsive: [
69
+ "flex-col @md/field-group:flex-row @md/field-group:items-center [&>*]:w-full @md/field-group:[&>*]:w-auto [&>.sr-only]:w-auto",
70
+ "@md/field-group:[&>[data-slot=field-label]]:flex-auto",
71
+ "@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
72
+ ],
73
+ },
74
+ },
75
+ defaultVariants: {
76
+ orientation: "vertical",
71
77
  },
72
78
  },
73
- defaultVariants: {
74
- orientation: "vertical",
75
- },
76
- });
79
+ );
77
80
 
78
81
  function Field({
79
82
  className,
@@ -95,13 +98,19 @@ function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
95
98
  return (
96
99
  <div
97
100
  data-slot="field-content"
98
- className={cn("group/field-content flex flex-1 flex-col gap-1.5 leading-snug", className)}
101
+ className={cn(
102
+ "group/field-content flex flex-1 flex-col gap-1.5 leading-snug",
103
+ className,
104
+ )}
99
105
  {...props}
100
106
  />
101
107
  );
102
108
  }
103
109
 
104
- function FieldLabel({ className, ...props }: React.ComponentProps<typeof Label>) {
110
+ function FieldLabel({
111
+ className,
112
+ ...props
113
+ }: React.ComponentProps<typeof Label>) {
105
114
  return (
106
115
  <Label
107
116
  data-slot="field-label"
@@ -109,7 +118,7 @@ function FieldLabel({ className, ...props }: React.ComponentProps<typeof Label>)
109
118
  "group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50",
110
119
  "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4",
111
120
  "has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10",
112
- className
121
+ className,
113
122
  )}
114
123
  {...props}
115
124
  />
@@ -122,7 +131,7 @@ function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
122
131
  data-slot="field-label"
123
132
  className={cn(
124
133
  "flex w-fit items-center gap-2 text-sm leading-snug font-medium group-data-[disabled=true]/field:opacity-50",
125
- className
134
+ className,
126
135
  )}
127
136
  {...props}
128
137
  />
@@ -137,7 +146,7 @@ function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
137
146
  "text-muted-foreground text-sm leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance",
138
147
  "last:mt-0 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5",
139
148
  "[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
140
- className
149
+ className,
141
150
  )}
142
151
  {...props}
143
152
  />
@@ -157,7 +166,7 @@ function FieldSeparator({
157
166
  data-content={!!children}
158
167
  className={cn(
159
168
  "relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2",
160
- className
169
+ className,
161
170
  )}
162
171
  {...props}
163
172
  >
@@ -197,7 +206,10 @@ function FieldError({
197
206
 
198
207
  return (
199
208
  <ul className="ml-4 flex list-disc flex-col gap-1">
200
- {errors.map((error, index) => error?.message && <li key={index}>{error.message}</li>)}
209
+ {errors.map(
210
+ (error, index) =>
211
+ error?.message && <li key={index}>{error.message}</li>,
212
+ )}
201
213
  </ul>
202
214
  );
203
215
  }, [children, errors]);
@@ -5,7 +5,12 @@ export type TypographyProps = { children: React.ReactNode; className?: string };
5
5
 
6
6
  export function HeadingH1({ children, className }: TypographyProps) {
7
7
  return (
8
- <h1 className={cn("scroll-m-20 text-4xl font-semibold tracking-tight text-balance", className)}>
8
+ <h1
9
+ className={cn(
10
+ "scroll-m-20 text-4xl font-semibold tracking-tight text-balance",
11
+ className,
12
+ )}
13
+ >
9
14
  {children}
10
15
  </h1>
11
16
  );
@@ -13,7 +18,12 @@ export function HeadingH1({ children, className }: TypographyProps) {
13
18
 
14
19
  export function HeadingH2({ children, className }: TypographyProps) {
15
20
  return (
16
- <h2 className={cn("scroll-m-20 text-3xl font-normal tracking-tight first:mt-0", className)}>
21
+ <h2
22
+ className={cn(
23
+ "scroll-m-20 text-3xl font-normal tracking-tight first:mt-0",
24
+ className,
25
+ )}
26
+ >
17
27
  {children}
18
28
  </h2>
19
29
  );
@@ -21,18 +31,33 @@ export function HeadingH2({ children, className }: TypographyProps) {
21
31
 
22
32
  export function HeadingH3({ children, className }: TypographyProps) {
23
33
  return (
24
- <h3 className={cn("scroll-m-20 text-xl font-normal tracking-tight", className)}>{children}</h3>
34
+ <h3
35
+ className={cn(
36
+ "scroll-m-20 text-xl font-normal tracking-tight",
37
+ className,
38
+ )}
39
+ >
40
+ {children}
41
+ </h3>
25
42
  );
26
43
  }
27
44
 
28
45
  export function HeadingH4({ children, className }: TypographyProps) {
29
46
  return (
30
- <h4 className={cn("scroll-m-20 text-lg font-light tracking-tight", className)}>{children}</h4>
47
+ <h4
48
+ className={cn("scroll-m-20 text-lg font-light tracking-tight", className)}
49
+ >
50
+ {children}
51
+ </h4>
31
52
  );
32
53
  }
33
54
 
34
55
  export function HeadingH5({ children, className }: TypographyProps) {
35
- return <h5 className={cn("scroll-m-20 font-light tracking-tight", className)}>{children}</h5>;
56
+ return (
57
+ <h5 className={cn("scroll-m-20 font-light tracking-tight", className)}>
58
+ {children}
59
+ </h5>
60
+ );
36
61
  }
37
62
 
38
63
  export function HeadingH6({ children, className }: TypographyProps) {
@@ -40,7 +65,7 @@ export function HeadingH6({ children, className }: TypographyProps) {
40
65
  <h6
41
66
  className={cn(
42
67
  "text-muted-foreground scroll-m-20 text-sm font-light tracking-tight",
43
- className
68
+ className,
44
69
  )}
45
70
  >
46
71
  {children}
@@ -45,15 +45,21 @@ const hoverCardContentVariants = cva(
45
45
  rounded: "default",
46
46
  gradientBorder: "none",
47
47
  },
48
- }
48
+ },
49
49
  );
50
50
 
51
- function HoverCard({ ...props }: React.ComponentProps<typeof HoverCardPrimitive.Root>) {
51
+ function HoverCard({
52
+ ...props
53
+ }: React.ComponentProps<typeof HoverCardPrimitive.Root>) {
52
54
  return <HoverCardPrimitive.Root data-slot="hover-card" {...props} />;
53
55
  }
54
56
 
55
- function HoverCardTrigger({ ...props }: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {
56
- return <HoverCardPrimitive.Trigger data-slot="hover-card-trigger" {...props} />;
57
+ function HoverCardTrigger({
58
+ ...props
59
+ }: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {
60
+ return (
61
+ <HoverCardPrimitive.Trigger data-slot="hover-card-trigger" {...props} />
62
+ );
57
63
  }
58
64
 
59
65
  function HoverCardContent({
@@ -68,16 +74,25 @@ function HoverCardContent({
68
74
  }: React.ComponentProps<typeof HoverCardPrimitive.Content> &
69
75
  VariantProps<typeof hoverCardContentVariants>) {
70
76
  // Auto-apply gradient border for container variant if not specified
71
- const finalGradientBorder = gradientBorder ?? (variant === "container" ? "white" : "none");
77
+ const finalGradientBorder =
78
+ gradientBorder ?? (variant === "container" ? "white" : "none");
72
79
 
73
80
  const hasGradientBorder = finalGradientBorder !== "none";
74
81
 
75
82
  // Get the gradient border classes
76
- const gradientClasses = hoverCardContentVariants({ gradientBorder: finalGradientBorder });
83
+ const gradientClasses = hoverCardContentVariants({
84
+ gradientBorder: finalGradientBorder,
85
+ });
77
86
 
78
87
  // Get the main hover card classes without gradient
79
88
  const hoverCardClasses = cn(
80
- hoverCardContentVariants({ variant, padding, rounded, gradientBorder: "none", className })
89
+ hoverCardContentVariants({
90
+ variant,
91
+ padding,
92
+ rounded,
93
+ gradientBorder: "none",
94
+ className,
95
+ }),
81
96
  );
82
97
 
83
98
  // Get the rounded class for the wrapper
@@ -85,7 +100,9 @@ function HoverCardContent({
85
100
 
86
101
  return (
87
102
  <HoverCardPrimitive.Portal
88
- container={document.querySelectorAll(".turtle-widget-root")[0] ?? undefined}
103
+ container={
104
+ document.querySelectorAll(".turtle-widget-root")[0] ?? undefined
105
+ }
89
106
  data-slot="hover-card-portal"
90
107
  >
91
108
  {hasGradientBorder ? (
@@ -96,7 +113,10 @@ function HoverCardContent({
96
113
  className={cn(gradientClasses, roundedClass, "p-[1px]")}
97
114
  {...props}
98
115
  >
99
- <div data-slot="hover-card-content-inner" className={hoverCardClasses} />
116
+ <div
117
+ data-slot="hover-card-content-inner"
118
+ className={hoverCardClasses}
119
+ />
100
120
  </HoverCardPrimitive.Content>
101
121
  ) : (
102
122
  <HoverCardPrimitive.Content
@@ -111,4 +131,9 @@ function HoverCardContent({
111
131
  );
112
132
  }
113
133
 
114
- export { HoverCard, HoverCardTrigger, HoverCardContent, hoverCardContentVariants };
134
+ export {
135
+ HoverCard,
136
+ HoverCardTrigger,
137
+ HoverCardContent,
138
+ hoverCardContentVariants,
139
+ };
@@ -8,10 +8,10 @@ const iconAnimationVariants = cva(
8
8
  {
9
9
  variants: {
10
10
  size: {
11
- default: "w-12 h-12",
12
- sm: "w-8 h-8",
13
- lg: "w-16 h-16",
14
- xl: "w-20 h-20",
11
+ default: "h-12 w-12",
12
+ sm: "h-8 w-8",
13
+ lg: "h-16 w-16",
14
+ xl: "h-20 w-20",
15
15
  },
16
16
  variant: {
17
17
  default: "bg-background",
@@ -22,7 +22,7 @@ const iconAnimationVariants = cva(
22
22
  size: "default",
23
23
  variant: "default",
24
24
  },
25
- }
25
+ },
26
26
  );
27
27
 
28
28
  export interface IconAnimationProps
@@ -44,12 +44,12 @@ const IconAnimation = React.forwardRef<HTMLDivElement, IconAnimationProps>(
44
44
  <div
45
45
  className={cn(
46
46
  "absolute inset-0 rounded-full",
47
- "bg-gradient-to-r from-transparent via-primary to-transparent",
47
+ "via-primary bg-gradient-to-r from-transparent to-transparent",
48
48
  "animate-spin",
49
49
  {
50
50
  "animate-spin": spinning,
51
51
  "animate-none": !spinning,
52
- }
52
+ },
53
53
  )}
54
54
  style={{
55
55
  background: spinning
@@ -62,21 +62,21 @@ const IconAnimation = React.forwardRef<HTMLDivElement, IconAnimationProps>(
62
62
  {/* Inner circle to create the border effect */}
63
63
  <div
64
64
  className={cn(
65
- "w-full h-full rounded-full",
66
- variant === "transparent" ? "bg-transparent" : "bg-background"
65
+ "h-full w-full rounded-full",
66
+ variant === "transparent" ? "bg-transparent" : "bg-background",
67
67
  )}
68
68
  />
69
69
  </div>
70
-
70
+
71
71
  {/* Icon container - stays fixed */}
72
72
  <div className="relative z-10 flex items-center justify-center">
73
73
  {children}
74
74
  </div>
75
75
  </div>
76
76
  );
77
- }
77
+ },
78
78
  );
79
79
 
80
80
  IconAnimation.displayName = "IconAnimation";
81
81
 
82
- export { IconAnimation, iconAnimationVariants };
82
+ export { IconAnimation, iconAnimationVariants };
@@ -1,7 +1,12 @@
1
1
  import * as React from "react";
2
2
  import { cn } from "@/lib/utils";
3
3
  import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
4
- import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
4
+ import {
5
+ Tooltip,
6
+ TooltipContent,
7
+ TooltipProvider,
8
+ TooltipTrigger,
9
+ } from "@/components/ui/tooltip";
5
10
  import { useMemo } from "react";
6
11
 
7
12
  interface IconListItem {
@@ -27,22 +32,34 @@ const sizeClasses = {
27
32
 
28
33
  const IconList = React.forwardRef<HTMLDivElement, IconListProps>(
29
34
  (
30
- { className, items, label, size = "sm", maxVisible = 6, showTooltip = false, ...props },
31
- ref
35
+ {
36
+ className,
37
+ items,
38
+ label,
39
+ size = "sm",
40
+ maxVisible = 6,
41
+ showTooltip = false,
42
+ ...props
43
+ },
44
+ ref,
32
45
  ) => {
33
- const [loadedImages, setLoadedImages] = React.useState<Set<string>>(new Set());
46
+ const [loadedImages, setLoadedImages] = React.useState<Set<string>>(
47
+ new Set(),
48
+ );
34
49
 
35
50
  if (!items || items.length === 0) return null;
36
51
 
37
52
  const uniqueItems = useMemo(() => {
38
- const normalized: IconListItem[] = items.map((item: IconListItem | string, index: number) =>
39
- typeof item === "string"
40
- ? { icon: item, name: "", id: `item-${index}` }
41
- : { ...item, id: item.id || `item-${index}` }
53
+ const normalized: IconListItem[] = items.map(
54
+ (item: IconListItem | string, index: number) =>
55
+ typeof item === "string"
56
+ ? { icon: item, name: "", id: `item-${index}` }
57
+ : { ...item, id: item.id || `item-${index}` },
42
58
  );
43
59
 
44
60
  const unique = normalized.filter(
45
- (item, index, self) => index === self.findIndex((t) => t.icon === item.icon)
61
+ (item, index, self) =>
62
+ index === self.findIndex((t) => t.icon === item.icon),
46
63
  );
47
64
 
48
65
  return unique;
@@ -61,8 +78,8 @@ const IconList = React.forwardRef<HTMLDivElement, IconListProps>(
61
78
  key={item.id || index}
62
79
  className={cn(
63
80
  sizeClasses[size],
64
- "border border-background transition-all hover:z-10 hover:scale-110",
65
- !loadedImages.has(item.icon) && "animate-pulse"
81
+ "border-background border transition-all hover:z-10 hover:scale-110",
82
+ !loadedImages.has(item.icon) && "animate-pulse",
66
83
  )}
67
84
  >
68
85
  <AvatarImage
@@ -70,13 +87,18 @@ const IconList = React.forwardRef<HTMLDivElement, IconListProps>(
70
87
  alt={item.name || "Icon"}
71
88
  onLoad={() => handleImageLoad(item.icon)}
72
89
  />
73
- <AvatarFallback className={cn("font-medium", sizeClasses[size].split(" ").pop())}>
90
+ <AvatarFallback
91
+ className={cn("font-medium", sizeClasses[size].split(" ").pop())}
92
+ >
74
93
  {item.name ? item.name.slice(0, 2).toUpperCase() : "?"}
75
94
  </AvatarFallback>
76
95
  </Avatar>
77
96
  );
78
97
 
79
- const renderWithTooltip = (content: React.ReactNode, tooltipText: string) => {
98
+ const renderWithTooltip = (
99
+ content: React.ReactNode,
100
+ tooltipText: string,
101
+ ) => {
80
102
  if (!showTooltip || !tooltipText) return content;
81
103
 
82
104
  return (
@@ -98,7 +120,9 @@ const IconList = React.forwardRef<HTMLDivElement, IconListProps>(
98
120
  aria-label={label || "Icon list"}
99
121
  {...props}
100
122
  >
101
- {label && <span className="text-xs text-muted-foreground mr-1">{label}:</span>}
123
+ {label && (
124
+ <span className="text-muted-foreground mr-1 text-xs">{label}:</span>
125
+ )}
102
126
  <div className="flex -space-x-1">
103
127
  {visibleItems.map((item, index) => (
104
128
  <div key={item.id || index} role="listitem">
@@ -111,12 +135,15 @@ const IconList = React.forwardRef<HTMLDivElement, IconListProps>(
111
135
  <Avatar
112
136
  className={cn(
113
137
  sizeClasses[size],
114
- "border border-background bg-muted hover:bg-muted/80 transition-all"
138
+ "border-background bg-muted hover:bg-muted/80 border transition-all",
115
139
  )}
116
140
  aria-label={`${remainingCount} more items`}
117
141
  >
118
142
  <AvatarFallback
119
- className={cn("font-semibold", sizeClasses[size].split(" ").pop())}
143
+ className={cn(
144
+ "font-semibold",
145
+ sizeClasses[size].split(" ").pop(),
146
+ )}
120
147
  >
121
148
  +{remainingCount}
122
149
  </AvatarFallback>
@@ -124,7 +151,7 @@ const IconList = React.forwardRef<HTMLDivElement, IconListProps>(
124
151
  hiddenItems
125
152
  .map((item) => item.name)
126
153
  .filter(Boolean)
127
- .join(", ") || `${remainingCount} more items`
154
+ .join(", ") || `${remainingCount} more items`,
128
155
  )}
129
156
  </div>
130
157
  )}
@@ -132,7 +159,7 @@ const IconList = React.forwardRef<HTMLDivElement, IconListProps>(
132
159
  </div>
133
160
  </TooltipProvider>
134
161
  );
135
- }
162
+ },
136
163
  );
137
164
 
138
165
  IconList.displayName = "IconList";
@@ -33,7 +33,7 @@ const valueVariants = cva("font-bold", {
33
33
  },
34
34
  });
35
35
 
36
- const titleVariants = cva("font-medium text-muted-foreground", {
36
+ const titleVariants = cva("text-muted-foreground font-medium", {
37
37
  variants: {
38
38
  size: {
39
39
  sm: "text-xs",
@@ -71,7 +71,7 @@ const InfoCard = React.forwardRef<HTMLDivElement, InfoCardProps>(
71
71
  className,
72
72
  ...props
73
73
  },
74
- ref
74
+ ref,
75
75
  ) => {
76
76
  return (
77
77
  <Card
@@ -83,7 +83,13 @@ const InfoCard = React.forwardRef<HTMLDivElement, InfoCardProps>(
83
83
  >
84
84
  {/* Icon & Title */}
85
85
  <div className="flex gap-2">
86
- {iconUrl && <img src={iconUrl} alt={`${title}-icon`} className="w-5 h-5 rounded-full" />}
86
+ {iconUrl && (
87
+ <img
88
+ src={iconUrl}
89
+ alt={`${title}-icon`}
90
+ className="h-5 w-5 rounded-full"
91
+ />
92
+ )}
87
93
  <p className={titleVariants({ size: titleSize })}>{title}</p>
88
94
  </div>
89
95
 
@@ -91,10 +97,12 @@ const InfoCard = React.forwardRef<HTMLDivElement, InfoCardProps>(
91
97
  <p className={cn("text-foreground")}>{value}</p>
92
98
 
93
99
  {/* Subtitle */}
94
- {subtitle && <p className="text-xs text-muted-foreground/70">{subtitle}</p>}
100
+ {subtitle && (
101
+ <p className="text-muted-foreground/70 text-xs">{subtitle}</p>
102
+ )}
95
103
  </Card>
96
104
  );
97
- }
105
+ },
98
106
  );
99
107
 
100
108
  InfoCard.displayName = "InfoCard";
@@ -29,7 +29,7 @@ function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
29
29
  // Error state.
30
30
  "has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40",
31
31
 
32
- className
32
+ className,
33
33
  )}
34
34
  {...props}
35
35
  />
@@ -41,8 +41,10 @@ const inputGroupAddonVariants = cva(
41
41
  {
42
42
  variants: {
43
43
  align: {
44
- "inline-start": "order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]",
45
- "inline-end": "order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]",
44
+ "inline-start":
45
+ "order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]",
46
+ "inline-end":
47
+ "order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]",
46
48
  "block-start":
47
49
  "order-first w-full justify-start px-3 pt-3 group-has-[>input]/input-group:pt-2.5 [.border-b]:pb-3",
48
50
  "block-end":
@@ -52,7 +54,7 @@ const inputGroupAddonVariants = cva(
52
54
  defaultVariants: {
53
55
  align: "inline-start",
54
56
  },
55
- }
57
+ },
56
58
  );
57
59
 
58
60
  function InputGroupAddon({
@@ -77,19 +79,23 @@ function InputGroupAddon({
77
79
  );
78
80
  }
79
81
 
80
- const inputGroupButtonVariants = cva("flex items-center gap-2 text-sm shadow-none", {
81
- variants: {
82
- size: {
83
- xs: "h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-2 has-[>svg]:px-2 [&>svg:not([class*='size-'])]:size-3.5",
84
- sm: "h-8 gap-1.5 rounded-md px-2.5 has-[>svg]:px-2.5",
85
- "icon-xs": "size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0",
86
- "icon-sm": "size-8 p-0 has-[>svg]:p-0",
82
+ const inputGroupButtonVariants = cva(
83
+ "flex items-center gap-2 text-sm shadow-none",
84
+ {
85
+ variants: {
86
+ size: {
87
+ xs: "h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-2 has-[>svg]:px-2 [&>svg:not([class*='size-'])]:size-3.5",
88
+ sm: "h-8 gap-1.5 rounded-md px-2.5 has-[>svg]:px-2.5",
89
+ "icon-xs":
90
+ "size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0",
91
+ "icon-sm": "size-8 p-0 has-[>svg]:p-0",
92
+ },
93
+ },
94
+ defaultVariants: {
95
+ size: "xs",
87
96
  },
88
97
  },
89
- defaultVariants: {
90
- size: "xs",
91
- },
92
- });
98
+ );
93
99
 
94
100
  function InputGroupButton({
95
101
  className,
@@ -115,33 +121,39 @@ function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
115
121
  <span
116
122
  className={cn(
117
123
  "text-muted-foreground flex items-center gap-2 text-sm [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
118
- className
124
+ className,
119
125
  )}
120
126
  {...props}
121
127
  />
122
128
  );
123
129
  }
124
130
 
125
- function InputGroupInput({ className, ...props }: React.ComponentProps<"input">) {
131
+ function InputGroupInput({
132
+ className,
133
+ ...props
134
+ }: React.ComponentProps<"input">) {
126
135
  return (
127
136
  <Input
128
137
  data-slot="input-group-control"
129
138
  className={cn(
130
139
  "flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent",
131
- className
140
+ className,
132
141
  )}
133
142
  {...props}
134
143
  />
135
144
  );
136
145
  }
137
146
 
138
- function InputGroupTextarea({ className, ...props }: React.ComponentProps<"textarea">) {
147
+ function InputGroupTextarea({
148
+ className,
149
+ ...props
150
+ }: React.ComponentProps<"textarea">) {
139
151
  return (
140
152
  <Textarea
141
153
  data-slot="input-group-control"
142
154
  className={cn(
143
155
  "flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent",
144
- className
156
+ className,
145
157
  )}
146
158
  {...props}
147
159
  />