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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/dist/index.cjs +10331 -110
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +7652 -47844
  4. package/dist/index.js.map +1 -1
  5. package/dist/types/components/features/sidebar-layout.d.ts +2 -0
  6. package/dist/types/components/features/sidebar-layout.d.ts.map +1 -1
  7. package/dist/types/components/ui/chart.d.ts +1 -1
  8. package/dist/types/components/ui/chart.d.ts.map +1 -1
  9. package/package.json +26 -22
  10. package/.prettierrc.json +0 -4
  11. package/.turbo/turbo-build.log +0 -182
  12. package/CHANGELOG.md +0 -795
  13. package/components.json +0 -21
  14. package/src/components/charts/QUICK_REFERENCE.md +0 -323
  15. package/src/components/charts/README.md +0 -658
  16. package/src/components/charts/RECHARTS_FEATURES.md +0 -458
  17. package/src/components/charts/area-chart.tsx +0 -248
  18. package/src/components/charts/bar-chart.tsx +0 -362
  19. package/src/components/charts/index.ts +0 -4
  20. package/src/components/charts/pie-chart.tsx +0 -277
  21. package/src/components/charts/radial-chart.tsx +0 -312
  22. package/src/components/features/api-status/index.tsx +0 -23
  23. package/src/components/features/data-table/data-table.tsx +0 -538
  24. package/src/components/features/data-table/expand-toggle.tsx +0 -17
  25. package/src/components/features/data-table/fuzzy-filter.tsx +0 -34
  26. package/src/components/features/data-table/index.ts +0 -3
  27. package/src/components/features/data-table/item-info.tsx +0 -19
  28. package/src/components/features/data-table/skeleton.tsx +0 -23
  29. package/src/components/features/data-table/sort-dropdown.tsx +0 -118
  30. package/src/components/features/data-table/sortable-header.tsx +0 -37
  31. package/src/components/features/index.ts +0 -6
  32. package/src/components/features/page-heading.tsx +0 -27
  33. package/src/components/features/search-bar.tsx +0 -55
  34. package/src/components/features/segmented-navigation.tsx +0 -18
  35. package/src/components/features/sidebar-layout.tsx +0 -193
  36. package/src/components/features/turtle-tooltip.tsx +0 -67
  37. package/src/components/icons/arrow.tsx +0 -23
  38. package/src/components/icons/beta.tsx +0 -95
  39. package/src/components/icons/dot.tsx +0 -102
  40. package/src/components/icons/index.ts +0 -7
  41. package/src/components/icons/issue.tsx +0 -106
  42. package/src/components/icons/turtle.tsx +0 -156
  43. package/src/components/icons/update.tsx +0 -113
  44. package/src/components/icons/warning.tsx +0 -95
  45. package/src/components/molecules/index.ts +0 -9
  46. package/src/components/molecules/opportunity/index.ts +0 -10
  47. package/src/components/molecules/opportunity/opportunity-apr.tsx +0 -129
  48. package/src/components/molecules/opportunity/opportunity-disclaimer.tsx +0 -46
  49. package/src/components/molecules/opportunity/opportunity-rate-estimator.tsx +0 -62
  50. package/src/components/molecules/opportunity/opportunity-section.tsx +0 -113
  51. package/src/components/molecules/opportunity/opportunity-selector.tsx +0 -30
  52. package/src/components/molecules/opportunity/opportunity-type.tsx +0 -16
  53. package/src/components/molecules/route-details.tsx +0 -112
  54. package/src/components/molecules/slippage-selector.tsx +0 -200
  55. package/src/components/molecules/swap-details.tsx +0 -55
  56. package/src/components/molecules/swap-input.tsx +0 -186
  57. package/src/components/molecules/tabs.tsx +0 -79
  58. package/src/components/molecules/token-selector.tsx +0 -180
  59. package/src/components/molecules/tx-status.tsx +0 -312
  60. package/src/components/molecules/widget/asset-list/asset-filters.tsx +0 -113
  61. package/src/components/molecules/widget/asset-list/asset-list.tsx +0 -178
  62. package/src/components/molecules/widget/asset-list/asset-row.tsx +0 -45
  63. package/src/components/molecules/widget/asset-list/hooks/index.ts +0 -2
  64. package/src/components/molecules/widget/asset-list/hooks/use-asset-filtering.ts +0 -44
  65. package/src/components/molecules/widget/asset-list/hooks/use-asset-grouping.ts +0 -87
  66. package/src/components/molecules/widget/asset-list/index.ts +0 -3
  67. package/src/components/molecules/widget/base-selector.tsx +0 -121
  68. package/src/components/molecules/widget/campaign-item.tsx +0 -82
  69. package/src/components/molecules/widget/deal-item.tsx +0 -92
  70. package/src/components/molecules/widget/index.ts +0 -36
  71. package/src/components/molecules/widget/opportunity-item.tsx +0 -105
  72. package/src/components/molecules/widget/widget-item-stats.tsx +0 -50
  73. package/src/components/molecules/widget/widget-item.tsx +0 -139
  74. package/src/components/molecules/widget/widget-list-items.tsx +0 -86
  75. package/src/components/ui/alert-dialog.tsx +0 -163
  76. package/src/components/ui/animated-background/animated-background.tsx +0 -182
  77. package/src/components/ui/animated-background/index.ts +0 -1
  78. package/src/components/ui/avatar.tsx +0 -73
  79. package/src/components/ui/badge.tsx +0 -59
  80. package/src/components/ui/banner.tsx +0 -84
  81. package/src/components/ui/button.tsx +0 -100
  82. package/src/components/ui/card.tsx +0 -119
  83. package/src/components/ui/chart.tsx +0 -346
  84. package/src/components/ui/checkbox.tsx +0 -32
  85. package/src/components/ui/chip.tsx +0 -52
  86. package/src/components/ui/collapsible.tsx +0 -34
  87. package/src/components/ui/combobox.tsx +0 -730
  88. package/src/components/ui/command.tsx +0 -184
  89. package/src/components/ui/dialog.tsx +0 -129
  90. package/src/components/ui/dropdown.tsx +0 -316
  91. package/src/components/ui/field.tsx +0 -244
  92. package/src/components/ui/heading.tsx +0 -74
  93. package/src/components/ui/hover-card.tsx +0 -139
  94. package/src/components/ui/icon-animation.tsx +0 -82
  95. package/src/components/ui/icon-list.tsx +0 -168
  96. package/src/components/ui/index.ts +0 -48
  97. package/src/components/ui/info-card.tsx +0 -110
  98. package/src/components/ui/input-group.tsx +0 -170
  99. package/src/components/ui/input.tsx +0 -72
  100. package/src/components/ui/label-with-icon.tsx +0 -122
  101. package/src/components/ui/label.tsx +0 -24
  102. package/src/components/ui/multi-select.tsx +0 -1090
  103. package/src/components/ui/navigation-bar.tsx +0 -153
  104. package/src/components/ui/navigation-menu.tsx +0 -188
  105. package/src/components/ui/opportunity-details-v1.tsx +0 -104
  106. package/src/components/ui/pagination.tsx +0 -127
  107. package/src/components/ui/popover.tsx +0 -48
  108. package/src/components/ui/scroll-area.tsx +0 -64
  109. package/src/components/ui/segment-control.tsx +0 -146
  110. package/src/components/ui/select.tsx +0 -199
  111. package/src/components/ui/separator.tsx +0 -26
  112. package/src/components/ui/sheet.tsx +0 -139
  113. package/src/components/ui/sidebar.tsx +0 -728
  114. package/src/components/ui/skeleton.tsx +0 -14
  115. package/src/components/ui/slider.tsx +0 -58
  116. package/src/components/ui/sonner.tsx +0 -24
  117. package/src/components/ui/switch.tsx +0 -29
  118. package/src/components/ui/table-shadcn.tsx +0 -110
  119. package/src/components/ui/table.tsx +0 -117
  120. package/src/components/ui/textarea.tsx +0 -22
  121. package/src/components/ui/toggle-group.tsx +0 -71
  122. package/src/components/ui/toggle.tsx +0 -47
  123. package/src/components/ui/tooltip.tsx +0 -66
  124. package/src/hooks/index.ts +0 -1
  125. package/src/hooks/useIsMobile.ts +0 -77
  126. package/src/index.ts +0 -16
  127. package/src/lib/utils.ts +0 -6
  128. package/src/styles/globals.css +0 -181
  129. package/src/styles/themes/index.css +0 -9
  130. package/src/styles/themes/semantic.css +0 -117
  131. package/src/styles/tokens/colors.css +0 -124
  132. package/src/styles/tokens/index.css +0 -15
  133. package/src/styles/tokens/radius.css +0 -18
  134. package/src/styles/tokens/spacing.css +0 -58
  135. package/src/styles/tokens/typography.css +0 -87
  136. package/src/tokens/index.ts +0 -108
  137. package/tsconfig.json +0 -20
  138. package/vite.config.js +0 -49
  139. /package/{src/images/enso.png → dist/enso-22FJ4GNK.png} +0 -0
@@ -1,129 +0,0 @@
1
- import React from "react";
2
- import {
3
- HoverCard,
4
- HoverCardContent,
5
- HoverCardTrigger,
6
- } from "../../ui/hover-card";
7
- import { InfoIcon } from "lucide-react";
8
- import { LabelWithIcon, Separator } from "../../ui";
9
- import NumberFlow, { type Value } from "@number-flow/react";
10
-
11
- // TODO: Extract aprBreakdown to a type
12
- interface OpportunityAprProps {
13
- apr: Value;
14
- aprBreakdown: {
15
- iconUrl: string;
16
- name: string;
17
- description: string;
18
- apr: string;
19
- boost: boolean;
20
- }[];
21
- showBoostedRewardsDescription?: boolean;
22
- showBoostedRewards?: boolean;
23
- }
24
-
25
- const OpportunityApr = ({
26
- apr,
27
- aprBreakdown,
28
- showBoostedRewards = false,
29
- showBoostedRewardsDescription = false,
30
- }: OpportunityAprProps) => {
31
- const boostedRewards = aprBreakdown.filter((item) => item.boost);
32
- return (
33
- <HoverCard>
34
- <HoverCardTrigger asChild>
35
- <span className="text-accent inline-flex items-center gap-1 text-2xl font-semibold">
36
- <NumberFlow
37
- value={apr}
38
- format={{
39
- style: "percent",
40
- minimumFractionDigits: 2,
41
- maximumFractionDigits: 2,
42
- }}
43
- />
44
- <InfoIcon
45
- size={16}
46
- className="text-muted-foreground cursor-pointer font-bold"
47
- />
48
- </span>
49
- </HoverCardTrigger>
50
- <HoverCardContent>
51
- <h3 className="text-accent text-sm">Rewards</h3>
52
- <div className="flex flex-col gap-2">
53
- {aprBreakdown
54
- .filter((item) => !item.boost)
55
- .map((item) => (
56
- <div key={item.name} className="flex justify-between">
57
- <LabelWithIcon
58
- textSize="xs"
59
- icon={item.iconUrl}
60
- iconSize="sm"
61
- className="text-muted-foreground"
62
- >
63
- {item.name}
64
- </LabelWithIcon>
65
- <span className="text-accent text-sm font-semibold">
66
- <NumberFlow
67
- value={parseFloat(item.apr) / 100}
68
- format={{
69
- style: "percent",
70
- minimumFractionDigits: 2,
71
- maximumFractionDigits: 3,
72
- }}
73
- />
74
- </span>
75
- </div>
76
- ))}
77
- <Separator />
78
- <div className="flex justify-between">
79
- <span className="text-accent text-sm">Net Reward Rate</span>
80
- <span className="text-accent text-sm font-semibold">
81
- <NumberFlow
82
- value={apr}
83
- format={{
84
- style: "percent",
85
- minimumFractionDigits: 3,
86
- maximumFractionDigits: 3,
87
- }}
88
- />
89
- </span>
90
- </div>
91
- {showBoostedRewards && boostedRewards.length > 0 && (
92
- <>
93
- <Separator />
94
- <h3 className="text-accent text-sm">Boosted Rewards</h3>
95
- <div className="flex justify-between">
96
- <span className="text-accent text-sm font-semibold">
97
- {boostedRewards.map((item) => (
98
- <div key={item.name} className="flex flex-col gap-2">
99
- <LabelWithIcon
100
- textSize="xs"
101
- icon={item.iconUrl}
102
- iconSize="sm"
103
- className="text-muted-foreground"
104
- >
105
- {item.description}
106
- </LabelWithIcon>
107
- {showBoostedRewardsDescription && item.description && (
108
- <span className="text-muted-foreground text-xs">
109
- {item.description}
110
- </span>
111
- )}
112
- </div>
113
- ))}
114
- </span>
115
- </div>
116
- </>
117
- )}
118
- {/* <p className="text-sm text-muted-foreground text-center">
119
- All reward amounts displayed in this app are the amounts after fees, please note that
120
- the reward rate is not guaranteed and may change over time. The APR is the annualized
121
- return on investment for the opportunity.
122
- </p> */}
123
- </div>
124
- </HoverCardContent>
125
- </HoverCard>
126
- );
127
- };
128
-
129
- export { OpportunityApr };
@@ -1,46 +0,0 @@
1
- import {
2
- BanknoteIcon,
3
- GiftIcon,
4
- MessageSquareTextIcon,
5
- SproutIcon,
6
- } from "lucide-react";
7
- import React from "react";
8
-
9
- const OpportunityDisclaimer = () => {
10
- const diclaimers = [
11
- {
12
- icon: <MessageSquareTextIcon size={16} />,
13
- description:
14
- "Lorem ipsum dolor sit, amet consectetur adipisicing elit. Porro expedita amet hic beatae similique vero recusandae necessitatibus",
15
- },
16
- {
17
- icon: <SproutIcon size={16} />,
18
- description: "Lend your USDT with Morpho and earn USDT rewards",
19
- },
20
- {
21
- icon: <GiftIcon size={16} />,
22
- description:
23
- "Rewards are automatically distributed every block and accrue to your position",
24
- },
25
- // {
26
- // icon: <BanknoteIcon size={16} />,
27
- // description: "Request withdraw at anytime and get USDT immediately",
28
- // },
29
- ];
30
- return (
31
- <div className="flex w-full flex-col gap-3">
32
- {diclaimers.map((disclaimer) => (
33
- <div key={disclaimer.description} className="flex gap-3">
34
- <div className="text-muted-foreground flex h-4 w-4 flex-shrink-0 items-center justify-center">
35
- {disclaimer.icon}
36
- </div>
37
- <p className="text-muted-foreground flex-1 text-xs">
38
- {disclaimer.description}
39
- </p>
40
- </div>
41
- ))}
42
- </div>
43
- );
44
- };
45
-
46
- export { OpportunityDisclaimer };
@@ -1,62 +0,0 @@
1
- import { useMemo } from "react";
2
-
3
- export interface OpportunityRateEstimatorProps {
4
- value: {
5
- symbol: string;
6
- price: number;
7
- depositedAmountUsd: number;
8
- apr: number;
9
- };
10
- }
11
-
12
- const OpportunityRateEstimator = ({ value }: OpportunityRateEstimatorProps) => {
13
- const { depositedAmountUsd, apr, symbol, price } = value;
14
-
15
- const result = useMemo(() => {
16
- // Validar que tengamos todos los valores necesarios
17
- if (!depositedAmountUsd || !apr || !price) {
18
- return {
19
- monthlyReward: "0.0000",
20
- monthlyRewardUsd: "0.00",
21
- yearlyReward: "0.0000",
22
- yearlyRewardUsd: "0.00",
23
- };
24
- }
25
-
26
- // Calcular rewards anuales en USD
27
- const yearlyRewardsUsd = depositedAmountUsd * (apr / 100);
28
-
29
- // Convertir rewards USD a cantidad de reward token
30
- const yearlyRewardsToken = yearlyRewardsUsd / price;
31
-
32
- // Calcular rewards mensuales
33
- const monthlyRewardsUsd = yearlyRewardsUsd / 12;
34
- const monthlyRewardsToken = yearlyRewardsToken / 12;
35
-
36
- return {
37
- monthlyReward: monthlyRewardsToken.toFixed(4),
38
- monthlyRewardUsd: monthlyRewardsUsd.toFixed(2),
39
- yearlyReward: yearlyRewardsToken.toFixed(4),
40
- yearlyRewardUsd: yearlyRewardsUsd.toFixed(2),
41
- };
42
- }, [depositedAmountUsd, apr, price]);
43
-
44
- return (
45
- <div className="mx-4 mb-4 space-y-1">
46
- <div className="flex justify-between">
47
- <span className="text-muted-foreground text-sm">Monthly</span>
48
- <span className="text-muted-foreground text-sm">
49
- {result.monthlyReward || 0} {symbol} (${result.monthlyRewardUsd || 0})
50
- </span>
51
- </div>
52
- <div className="flex justify-between">
53
- <span className="text-muted-foreground text-sm">Yearly</span>
54
- <span className="text-muted-foreground text-sm">
55
- {result.yearlyReward || 0} {symbol} (${result.yearlyRewardUsd || 0})
56
- </span>
57
- </div>
58
- </div>
59
- );
60
- };
61
-
62
- export { OpportunityRateEstimator };
@@ -1,113 +0,0 @@
1
- import * as React from "react";
2
- import { cn } from "@/lib/utils";
3
- import { Card } from "@/components/ui/card";
4
- import { OpportunityApr } from "./opportunity-apr";
5
- import {
6
- OpportunityRateEstimator,
7
- OpportunityRateEstimatorProps,
8
- } from "./opportunity-rate-estimator";
9
- import { OpportunityType } from "./opportunity-type";
10
- import { Separator } from "@/components/ui";
11
- import { OpportunityDisclaimer } from "./opportunity-disclaimer";
12
- import { OpportunitySelector } from "./opportunity-selector";
13
- import { Wallet } from "lucide-react";
14
- import { BaseSelector, iconUrlToImg } from "../widget";
15
-
16
- interface OpportunitySectionProps extends React.HTMLAttributes<HTMLDivElement> {
17
- value: {
18
- name: string;
19
- icon: string;
20
- vaultSymbol: string;
21
- totalApr: string;
22
- aprBreakdown: {
23
- iconUrl: string;
24
- name: string;
25
- description: string;
26
- boost: boolean;
27
- apr: string;
28
- }[];
29
- tvlUsd: string;
30
- depositDetails: OpportunityRateEstimatorProps["value"];
31
- type: "Boosted Deal" | "Turtle Campaign";
32
- };
33
- opportunitySelector: "old" | "new";
34
- hideDisclaimer?: boolean;
35
- onOpportunityClick?: () => void;
36
- }
37
-
38
- const OpportunitySection = React.forwardRef<
39
- HTMLDivElement,
40
- OpportunitySectionProps
41
- >(
42
- (
43
- {
44
- className,
45
- value,
46
- onOpportunityClick,
47
- hideDisclaimer,
48
- opportunitySelector,
49
- ...props
50
- },
51
- ref,
52
- ) => {
53
- return (
54
- <div className="text-foreground space-y-2">
55
- <Card
56
- variant="shadow"
57
- gradient="white"
58
- ref={ref}
59
- className={cn("space-y-3", className)}
60
- {...props}
61
- >
62
- <div className="flex justify-between p-4">
63
- <OpportunityApr
64
- apr={parseFloat(value.totalApr) / 100}
65
- aprBreakdown={value.aprBreakdown}
66
- showBoostedRewardsDescription={false}
67
- showBoostedRewards={true}
68
- />
69
- {opportunitySelector === "new" && (
70
- <OpportunitySelector
71
- iconUrl={value.icon}
72
- name={value.name}
73
- onClick={onOpportunityClick}
74
- />
75
- )}
76
- {opportunitySelector === "old" && (
77
- <BaseSelector
78
- icon={iconUrlToImg(value.icon, value.vaultSymbol)}
79
- text={value.name}
80
- onClick={onOpportunityClick}
81
- size="sm"
82
- />
83
- )}
84
- </div>
85
- {/* <OpportunityRateEstimator value={value.depositDetails} /> */}
86
- </Card>
87
- {/* Disclaimer */}
88
- {!hideDisclaimer && (
89
- <Card
90
- ref={ref}
91
- variant="border"
92
- gradient="white"
93
- className={cn("space-y-3", className)}
94
- {...props}
95
- >
96
- <div className="flex flex-col items-center justify-between gap-3">
97
- <div className="flex w-full justify-between p-1">
98
- <OpportunityType type={value.type} />
99
- <span className="text-foreground text-sm font-semibold">
100
- TVL: {value.tvlUsd}
101
- </span>
102
- </div>
103
- <Separator />
104
- <OpportunityDisclaimer />
105
- </div>
106
- </Card>
107
- )}
108
- </div>
109
- );
110
- },
111
- );
112
-
113
- export { OpportunitySection };
@@ -1,30 +0,0 @@
1
- import { Card, LabelWithIcon } from "@/components/ui";
2
- import { ChevronDownIcon } from "lucide-react";
3
- import React from "react";
4
-
5
- interface OpportunitySelectorProps {
6
- iconUrl: string;
7
- name: string;
8
- onClick: () => void;
9
- }
10
- const OpportunitySelector = ({
11
- iconUrl,
12
- name,
13
- onClick,
14
- }: OpportunitySelectorProps) => {
15
- return (
16
- <Card
17
- variant="border"
18
- rounded="full"
19
- onClick={onClick}
20
- className="flex cursor-pointer items-center justify-between gap-3"
21
- >
22
- <LabelWithIcon icon={iconUrl} textSize="sm" iconSize="base">
23
- {name}
24
- </LabelWithIcon>
25
- <ChevronDownIcon className="text-muted-foreground h-4 w-4" />
26
- </Card>
27
- );
28
- };
29
-
30
- export { OpportunitySelector };
@@ -1,16 +0,0 @@
1
- import { Badge } from "@/components/ui/badge";
2
- import { HandCoinsIcon } from "lucide-react";
3
- import React from "react";
4
-
5
- interface OpportunityTypeProps {
6
- type: "Boosted Deal" | "Turtle Campaign";
7
- }
8
- const OpportunityType = ({ type }: OpportunityTypeProps) => {
9
- return (
10
- <Badge variant="muted" className="gap-2">
11
- <HandCoinsIcon size={16} /> {type}
12
- </Badge>
13
- );
14
- };
15
-
16
- export { OpportunityType };
@@ -1,112 +0,0 @@
1
- import * as React from "react";
2
- import { Card, CardContent } from "../ui/card";
3
- import { LabelWithIcon } from "../ui/label-with-icon";
4
- import { ScrollArea } from "../ui/scroll-area";
5
- import { ChevronsRight } from "lucide-react";
6
- import ensoLogo from "../../images/enso.png";
7
- import { useMemo } from "react";
8
-
9
- // Local type definitions (no dependency on @turtleclub/hooks)
10
- export interface SimpleToken {
11
- icon?: React.ReactNode | string;
12
- symbol: string;
13
- }
14
-
15
- export interface TokenStep {
16
- in: SimpleToken;
17
- out: SimpleToken | null;
18
- type: "approve" | "swap" | "deposit";
19
- amount?: string;
20
- }
21
-
22
- interface RouteDetailsProps {
23
- value: {
24
- steps: TokenStep[];
25
- };
26
- className?: string;
27
- }
28
-
29
- export const RouteDetails = ({ value, className }: RouteDetailsProps) => {
30
- const { steps } = value;
31
-
32
- const isLongRoute = useMemo(() => {
33
- return steps.length > 2;
34
- }, [steps]);
35
-
36
- const defaultIcon = (symbol: string) => (
37
- <div className="bg-primary/20 flex size-3 items-center justify-center rounded-full">
38
- <span className="text-primary text-xs font-bold">{symbol.charAt(0)}</span>
39
- </div>
40
- );
41
-
42
- const capitalize = (str: string) => {
43
- return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
44
- };
45
-
46
- if (steps.length === 0) return null;
47
-
48
- return (
49
- <div className="text-foreground px-3 pb-3">
50
- <div className="text-sm font-medium">Swap Route</div>
51
- <div className="mb-1 flex items-center gap-1 text-[10px]">
52
- <span className="text-sm opacity-50">Powered by</span>
53
- <img src={ensoLogo} className="w-10" alt="Enso" />
54
- </div>
55
- {/* Route visualization */}
56
- <ScrollArea className="mt-2 rounded-md whitespace-nowrap">
57
- <div className="grid w-full auto-cols-fr grid-flow-col items-center gap-2 py-2">
58
- {steps.map((step, index) => (
59
- <React.Fragment key={`${step.in.symbol}-${step.type}-${index}`}>
60
- <Card variant="border" className="border-muted-foreground/60">
61
- <CardContent className="space-y-2 pt-4">
62
- {/* Type */}
63
- <div className="text-secondary-foreground text-sm">
64
- {capitalize(step.type)}
65
- </div>
66
-
67
- <div className="flex flex-row items-center gap-2">
68
- {/* Token in */}
69
- <LabelWithIcon
70
- icon={step.in.icon || defaultIcon(step.in.symbol)}
71
- textSize="xs"
72
- iconSize="xs"
73
- >
74
- {!isLongRoute && (
75
- <span className="hidden gap-2 sm:block">
76
- {step.in.symbol}
77
- </span>
78
- )}
79
- {step.type === "approve" && (
80
- <span className="gap-2"> {step.amount}</span>
81
- )}
82
- </LabelWithIcon>
83
-
84
- {step.type !== "approve" && (
85
- <>
86
- {/* Arrow between tokens */}
87
- <ChevronsRight className="text-primary size-4 shrink-0" />
88
-
89
- {/* Token out */}
90
- <LabelWithIcon
91
- icon={step.out.icon || defaultIcon(step.out.symbol)}
92
- textSize="xs"
93
- iconSize="xs"
94
- >
95
- {!isLongRoute && (
96
- <span className="hidden gap-2 sm:block">
97
- {step.in.symbol}
98
- </span>
99
- )}
100
- </LabelWithIcon>
101
- </>
102
- )}
103
- </div>
104
- </CardContent>
105
- </Card>
106
- </React.Fragment>
107
- ))}
108
- </div>
109
- </ScrollArea>
110
- </div>
111
- );
112
- };