diff --git a/packages/ui/.eslintrc.json b/packages/ui/.eslintrc.json
index ff2d152f73..0702626e84 100644
--- a/packages/ui/.eslintrc.json
+++ b/packages/ui/.eslintrc.json
@@ -32,6 +32,8 @@
},
"rules": {
"prettier/prettier": ["error", {}, { "usePrettierrc": true }],
+ "@typescript-eslint/no-unused-vars": "warn",
+ "unused-imports/no-unused-imports": "warn",
"import/order": [
"error",
{
@@ -83,7 +85,6 @@
],
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-explicit-any": "warn",
- "@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/sort-type-constituents": "error",
"no-console": ["error", { "allow": ["warn", "error"] }],
"react/self-closing-comp": ["error", { "component": true, "html": true }],
@@ -91,7 +92,6 @@
"react-hooks/rules-of-hooks": "error",
"react/display-name": "off",
"react/prop-types": "off",
- "unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": [
"warn",
{
diff --git a/packages/ui/app/_components/CustomTooltip.tsx b/packages/ui/app/_components/CustomTooltip.tsx
new file mode 100644
index 0000000000..dda934f529
--- /dev/null
+++ b/packages/ui/app/_components/CustomTooltip.tsx
@@ -0,0 +1,36 @@
+import { Info } from 'lucide-react';
+
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipProvider,
+ TooltipTrigger
+} from '@ui/components/ui/tooltip';
+
+const CustomTooltip = ({
+ content,
+ color
+}: {
+ content: string;
+ color?: string;
+}) => (
+
+
+
+
+
+
+
+
+ {content}
+
+
+
+);
+
+export default CustomTooltip;
diff --git a/packages/ui/app/_components/Navbar.tsx b/packages/ui/app/_components/Navbar.tsx
index 080b927906..26c64c5473 100644
--- a/packages/ui/app/_components/Navbar.tsx
+++ b/packages/ui/app/_components/Navbar.tsx
@@ -12,7 +12,7 @@ import { http, createConfig, useChainId } from 'wagmi';
import { base, mode } from 'wagmi/chains';
import { coinbaseWallet } from 'wagmi/connectors';
-import { useStore } from 'ui/store/Store';
+import { useStore } from '@ui/store/Store';
import ConnectButton from './ConnectButton';
import DynamicSubNav from './DynamicSubNav';
diff --git a/packages/ui/app/_components/dashboards/CollateralSwapPopup.tsx b/packages/ui/app/_components/dashboards/CollateralSwapPopup.tsx
index 8ad9dd1197..dce68e9dc8 100644
--- a/packages/ui/app/_components/dashboards/CollateralSwapPopup.tsx
+++ b/packages/ui/app/_components/dashboards/CollateralSwapPopup.tsx
@@ -47,7 +47,7 @@ import MaxDeposit from './MaxDeposit';
import SwapTo from './SwapTo';
import { SlippageDropdown } from '../SlippageDropdown';
-import { collateralSwapAbi } from '@ionicprotocol/sdk';
+import { collateralSwapAbi } from '@ionicprotocol/sdk/src';
createConfig({
integrator: 'ionic',
diff --git a/packages/ui/app/_components/dashboards/InfoRows.tsx b/packages/ui/app/_components/dashboards/InfoRows.tsx
index 44e5297ee5..add1c2cc65 100644
--- a/packages/ui/app/_components/dashboards/InfoRows.tsx
+++ b/packages/ui/app/_components/dashboards/InfoRows.tsx
@@ -19,9 +19,10 @@ import BorrowPopover from '../markets/BorrowPopover';
import SupplyPopover from '../markets/SupplyPopover';
import { PopupMode } from '../popup/page';
-import type { FlywheelReward } from 'types/dist';
import type { Address } from 'viem';
+import type { FlywheelReward } from '@ionicprotocol/types';
+
export enum InfoMode {
SUPPLY = 0,
BORROW = 1
diff --git a/packages/ui/app/_components/markets/FeaturedMarketTile.tsx b/packages/ui/app/_components/markets/FeaturedMarketTile.tsx
index a5b21b6e2d..fc235a14a3 100644
--- a/packages/ui/app/_components/markets/FeaturedMarketTile.tsx
+++ b/packages/ui/app/_components/markets/FeaturedMarketTile.tsx
@@ -2,8 +2,7 @@
'use client';
import type { Dispatch, SetStateAction } from 'react';
-import { useStore } from 'ui/store/Store';
-
+import { useStore } from '@ui/store/Store';
import { handleSwitchOriginChain } from '@ui/utils/NetworkChecker';
import WrapEthSwaps from './WrapEthSwaps';
diff --git a/packages/ui/app/_components/markets/NetworkSelector.tsx b/packages/ui/app/_components/markets/NetworkSelector.tsx
index 6d90803bcd..56a0592ff7 100644
--- a/packages/ui/app/_components/markets/NetworkSelector.tsx
+++ b/packages/ui/app/_components/markets/NetworkSelector.tsx
@@ -1,99 +1,145 @@
-/* eslint-disable @next/next/no-img-element */
-'use client';
-/* eslint-disable @typescript-eslint/no-explicit-any */
import React from 'react';
-import dynamic from 'next/dynamic';
+import Image from 'next/image';
import Link from 'next/link';
-import { usePathname } from 'next/navigation';
-
-import { useStore } from 'ui/store/Store';
+import { usePathname, useSearchParams } from 'next/navigation';
+import { Button } from '@ui/components/ui/button';
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipProvider,
+ TooltipTrigger
+} from '@ui/components/ui/tooltip';
import { pools } from '@ui/constants/index';
+import { useStore } from '@ui/store/Store';
+
interface INetworkSelector {
- chain?: string;
dropdownSelectedChain: number;
nopool?: boolean;
enabledChains?: number[];
upcomingChains?: string[];
}
+const NETWORK_ORDER = ['Mode', 'Base', 'Optimism', 'Fraxtal', 'Lisk', 'BoB'];
function NetworkSelector({
dropdownSelectedChain,
nopool = false,
enabledChains,
- chain,
upcomingChains
}: INetworkSelector) {
const pathname = usePathname();
+ const searchParams = useSearchParams();
const setDropChain = useStore((state) => state.setDropChain);
+
+ const orderedNetworks = NETWORK_ORDER.map((networkName) =>
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ Object.entries(pools).find(([_, pool]) => pool.name === networkName)
+ ).filter(
+ (entry): entry is [string, any] =>
+ entry !== undefined &&
+ (!enabledChains || enabledChains.includes(+entry[0]))
+ );
+
+ const getUrlWithParams = (chainId: string) => {
+ const params = new URLSearchParams(searchParams.toString());
+ params.set('chain', chainId);
+ if (!nopool && !params.has('pool')) {
+ params.set('pool', '0');
+ }
+ if (nopool && params.has('pool')) {
+ params.delete('pool');
+ }
+ return `${pathname}?${params.toString()}`;
+ };
+
return (
-
-
-
{' '}
- {pools[dropdownSelectedChain].name}
-
- {Object.entries(pools)
- .filter(([chainId]) =>
- enabledChains
- ? enabledChains?.includes(+chainId) &&
- +chainId !== dropdownSelectedChain
- : +chainId !== dropdownSelectedChain
- )
- .sort((a, b) => {
- const sortingOrder = ['Mode', 'Base', 'Optimism', 'Fraxtal', 'Bob'];
- const indexA = sortingOrder.indexOf(a[1].name);
- const indexB = sortingOrder.indexOf(b[1].name);
+
+ {orderedNetworks.map(([chainId, network], idx) => {
+ const isSelected = +chainId === +dropdownSelectedChain;
+
+ return (
+
+
+
+
+
+
+
+
+
+ {network.name}
+ Active
+
+
+
+ );
+ })}
- if (indexA === -1 || indexB === -1) {
- return 0; // if the network name is not found, don't change the order
- }
- return indexA - indexB;
- })
- .map(([chainId, network], idx: number) => (
-
setDropChain(chainId)}
- >
-
{' '}
- {network.name}
-
- ))}
- {!!upcomingChains &&
- upcomingChains.map((upcomingChain, idx) => (
-
-
{' '}
- {upcomingChain}
-
-
- ))}
+ {upcomingChains?.map((upcomingChain, idx) => (
+
+
+
+
+
+
+
+
+
+ {upcomingChain}
+ Coming Soon
+
+
+
+ ))}
);
}
-export default dynamic(() => Promise.resolve(NetworkSelector), { ssr: false });
+export default NetworkSelector;
diff --git a/packages/ui/app/_components/markets/PoolRows.tsx b/packages/ui/app/_components/markets/PoolRows.tsx
index 12eb1f7782..f8cc89fc94 100644
--- a/packages/ui/app/_components/markets/PoolRows.tsx
+++ b/packages/ui/app/_components/markets/PoolRows.tsx
@@ -4,8 +4,6 @@ import { useEffect, useMemo, type Dispatch, type SetStateAction } from 'react';
import Link from 'next/link';
-import { useStore } from 'ui/store/Store';
-
import {
FLYWHEEL_TYPE_MAP,
pools,
@@ -15,6 +13,7 @@ import { useMultiIonic } from '@ui/context/MultiIonicContext';
import { useBorrowCapsDataForAsset } from '@ui/hooks/ionic/useBorrowCapsDataForAsset';
import type { LoopMarketData } from '@ui/hooks/useLoopMarkets';
import { useMerklApr } from '@ui/hooks/useMerklApr';
+import { useStore } from '@ui/store/Store';
import type { MarketData } from '@ui/types/TokensDataMap';
import { handleSwitchOriginChain } from '@ui/utils/NetworkChecker';
diff --git a/packages/ui/app/_components/xION/Quote.tsx b/packages/ui/app/_components/xION/Quote.tsx
index f85a108720..a2292d90c1 100644
--- a/packages/ui/app/_components/xION/Quote.tsx
+++ b/packages/ui/app/_components/xION/Quote.tsx
@@ -3,12 +3,13 @@
import { useEffect } from 'react';
import { Options } from '@layerzerolabs/lz-v2-utilities';
-import { xErc20LayerZeroAbi } from 'sdk/src';
import { formatEther, type Hex, type Address } from 'viem';
import { useReadContract } from 'wagmi';
import { BridgingContractAddress, getToken } from '@ui/utils/getStakingTokens';
+import { xErc20LayerZeroAbi } from '@ionicprotocol/sdk';
+
export const lzOptions = Options.newOptions()
.addExecutorLzReceiveOption(100_000, 0)
.toHex();
diff --git a/packages/ui/app/dashboard/page.tsx b/packages/ui/app/dashboard/page.tsx
index c2647c02d1..a7038e6222 100644
--- a/packages/ui/app/dashboard/page.tsx
+++ b/packages/ui/app/dashboard/page.tsx
@@ -513,10 +513,7 @@ export default function Dashboard() {
pool={pool || '0'}
setOpen={setOpen}
/> */}
-
+
{/*
diff --git a/packages/ui/app/globals.css b/packages/ui/app/globals.css
index 913982ffc0..781608232e 100644
--- a/packages/ui/app/globals.css
+++ b/packages/ui/app/globals.css
@@ -29,9 +29,11 @@
0% {
transform: scale(1);
}
+
50% {
transform: scale(1.05);
}
+
100% {
transform: scale(1);
}
@@ -41,55 +43,68 @@
.grid-cols-21 {
grid-template-columns: repeat(21, minmax(0, 1fr));
}
+
.grid-cols-19 {
grid-template-columns: repeat(19, minmax(0, 1fr));
}
+
.grid-cols-20 {
grid-template-columns: repeat(20, minmax(0, 1fr));
}
+
.grid-cols-18 {
grid-template-columns: repeat(18, minmax(0, 1fr));
}
+
.grid-cols-15 {
grid-template-columns: repeat(15, minmax(0, 1fr));
}
+
.grid-cols-13 {
grid-template-columns: repeat(13, minmax(0, 1fr));
}
+
.col-span-15 {
grid-column: span 15 / span 15;
}
+
input[type='number']::-webkit-inner-spin-button,
input[type='number']::-webkit-outer-spin-button {
-webkit-appearance: none;
appearance: none;
}
-
+
.amount-field {
color: #fff;
}
+
.amount-field::-webkit-input-placeholder {
/* WebKit, Blink, Edge */
color: rgb(255 255 255 / 0.5);
}
+
.amount-field:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
color: rgb(255 255 255 / 0.5);
opacity: 1;
}
+
.amount-field::-moz-placeholder {
/* Mozilla Firefox 19+ */
color: rgb(255 255 255 / 0.5);
opacity: 1;
}
+
.amount-field:-ms-input-placeholder {
/* Internet Explorer 10-11 */
color: rgb(255 255 255 / 0.5);
}
+
.amount-field::-ms-input-placeholder {
/* Microsoft Edge */
color: rgb(255 255 255 / 0.5);
}
+
.amount-field::placeholder {
/* Most modern browsers support this now. */
color: rgb(255 255 255 / 0.5);
@@ -98,12 +113,20 @@
.expand {
animation: expand 2s linear infinite;
}
+
.pause {
animation-play-state: paused;
/* animation-duration: 40s; */
}
+
+ .react-calendar__tile--now:enabled:hover,
+ .react-calendar__tile--now:enabled:focus {
+ @apply bg-[#ffffa9];
+ }
}
+
+
.bg-pink {
background: #ff007f;
}
@@ -168,16 +191,19 @@
.btn-green {
@apply font-bold rounded-md px-3 py-1 text-center transition-colors bg-accent text-darkone;
}
+
.btn-green[disabled] {
@apply bg-stone-500;
}
.popover-container {
- @apply relative;
+ @apply relative;
}
+
.popover-container .popover {
transform-origin: 50% 0;
}
+
.popover-container:hover .popover {
@apply opacity-100 visible;
}
@@ -209,11 +235,13 @@
.nav-btn.nav-opened {
background: transparent;
}
+
.nav-btn.nav-opened:before {
bottom: 0;
margin: 0;
transform: rotate(45deg);
}
+
.nav-btn.nav-opened:after {
top: 0;
margin: 0;
@@ -224,6 +252,7 @@
bottom: 100%;
margin-bottom: 3px;
}
+
.nav-btn:after {
top: 100%;
margin-top: 3px;
@@ -270,6 +299,7 @@
vertical-align: middle;
background: #3bff89ff;
}
+
.success-icon:before {
width: 6px;
height: 2px;
@@ -278,6 +308,7 @@
transform-origin: 0 0;
transform: rotate(45deg);
}
+
.success-icon:after {
width: 12px;
height: 2px;
@@ -304,9 +335,11 @@
vertical-align: middle;
background: #df1515;
}
+
.error-icon:before {
transform: rotate(45deg);
}
+
.error-icon:after {
transform: rotate(-45deg);
}
@@ -336,12 +369,15 @@
transition: background 0.15s;
cursor: pointer;
}
+
.toggle.is-on {
background: #3bff89ff;
}
+
.toggle.is-on:before {
transform: translateX(20px);
}
+
.toggle:before {
content: '';
display: block;
@@ -364,6 +400,7 @@
.animate-fade-in {
opacity: 0;
}
+
.animate-fade-in.animated {
opacity: 1;
}
@@ -372,18 +409,17 @@
transform: scale(0.8);
opacity: 0;
}
+
.animate-pop-in.animated {
transform: scale(1);
opacity: 1;
}
.bg-health-ratio-gradient {
- background: linear-gradient(
- 90deg,
- #ff3864 8.12%,
- #f1f996 60.25%,
- #39ff88 98.45%
- );
+ background: linear-gradient(90deg,
+ #ff3864 8.12%,
+ #f1f996 60.25%,
+ #39ff88 98.45%);
}
.shadow-health-ratio-handle {
@@ -406,12 +442,69 @@
@apply w-[1px] bg-white/30 mx-auto my-1 self-stretch;
}
-body {
- color: rgb(var(--foreground-rgb));
- background: linear-gradient(
- to bottom,
- transparent,
- rgb(var(--background-end-rgb))
- )
- rgb(var(--background-start-rgb));
+@layer base {
+ :root {
+ --background: 0 0% 100%;
+ --foreground: 240 10% 3.9%;
+ --card: 0 0% 100%;
+ --card-foreground: 240 10% 3.9%;
+ --popover: 0 0% 100%;
+ --popover-foreground: 240 10% 3.9%;
+ --primary: 240 5.9% 10%;
+ --primary-foreground: 0 0% 98%;
+ --secondary: 240 4.8% 95.9%;
+ --secondary-foreground: 240 5.9% 10%;
+ --muted: 240 4.8% 95.9%;
+ --muted-foreground: 240 3.8% 46.1%;
+ --accent: 240 4.8% 95.9%;
+ --accent-foreground: 240 5.9% 10%;
+ --destructive: 0 84.2% 60.2%;
+ --destructive-foreground: 0 0% 98%;
+ --border: 240 5.9% 90%;
+ --input: 240 5.9% 90%;
+ --ring: 240 10% 3.9%;
+ --chart-1: 12 76% 61%;
+ --chart-2: 173 58% 39%;
+ --chart-3: 197 37% 24%;
+ --chart-4: 43 74% 66%;
+ --chart-5: 27 87% 67%;
+ --radius: 0.5rem;
+ }
+
+ .dark {
+ --background: 240 10% 3.9%;
+ --foreground: 0 0% 98%;
+ --card: 240 10% 3.9%;
+ --card-foreground: 0 0% 98%;
+ --popover: 240 10% 3.9%;
+ --popover-foreground: 0 0% 98%;
+ --primary: 0 0% 98%;
+ --primary-foreground: 240 5.9% 10%;
+ --secondary: 240 3.7% 15.9%;
+ --secondary-foreground: 0 0% 98%;
+ --muted: 240 3.7% 15.9%;
+ --muted-foreground: 240 5% 64.9%;
+ --accent: 240 3.7% 15.9%;
+ --accent-foreground: 0 0% 98%;
+ --destructive: 0 62.8% 30.6%;
+ --destructive-foreground: 0 0% 98%;
+ --border: 240 3.7% 15.9%;
+ --input: 240 3.7% 15.9%;
+ --ring: 240 4.9% 83.9%;
+ --chart-1: 220 70% 50%;
+ --chart-2: 160 60% 45%;
+ --chart-3: 30 80% 55%;
+ --chart-4: 280 65% 60%;
+ --chart-5: 340 75% 55%;
+ }
}
+
+@layer base {
+ * {
+ @apply border-border;
+ }
+
+ body {
+ @apply bg-background text-foreground;
+ }
+}
\ No newline at end of file
diff --git a/packages/ui/app/layout.tsx b/packages/ui/app/layout.tsx
index 894ea7d29b..a336db2d32 100644
--- a/packages/ui/app/layout.tsx
+++ b/packages/ui/app/layout.tsx
@@ -269,6 +269,15 @@ export default function RootLayout({
Dune
+
+
+ ID
+
+
-
+
diff --git a/packages/ui/app/market/details/[asset]/page.tsx b/packages/ui/app/market/details/[asset]/page.tsx
index d746875f03..3676d5bf19 100644
--- a/packages/ui/app/market/details/[asset]/page.tsx
+++ b/packages/ui/app/market/details/[asset]/page.tsx
@@ -20,7 +20,7 @@ import React, { useEffect, useMemo, useState } from 'react';
import { Doughnut, Line } from 'react-chartjs-2';
import { mode } from 'viem/chains';
import { useBalance, useAccount } from 'wagmi';
-// import { useGetMaxBorrow } from 'ui/app/util/utils';
+// import { useGetMaxBorrow } from '@ui/app/util/utils';
//-------------------Interfaces------------
interface IProp {
params: { asset: string };
@@ -59,10 +59,10 @@ import {
// ];
// const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042'];
import { INFO } from '@ui/constants/index';
-import Popup, { PopupMode } from 'ui/app/_components/popup/page';
+import Popup, { PopupMode } from '@ui/app/_components/popup/page';
import { extractAndConvertStringTOValue } from '@ui/utils/stringToValue';
import { handleSwitchOriginChain } from '@ui/utils/NetworkChecker';
-import Swap from 'ui/app/_components/popup/Swap';
+import Swap from '@ui/app/_components/popup/Swap';
import { MarketData, PoolData } from '@ui/types/TokensDataMap';
import { useFusePoolData } from '@ui/hooks/useFusePoolData';
import { useLoopMarkets } from '@ui/hooks/useLoopMarkets';
@@ -71,7 +71,7 @@ import { Address, formatEther, formatUnits } from 'viem';
import { useBorrowCapsDataForAsset } from '@ui/hooks/fuse/useBorrowCapsDataForAsset';
import { useUsdPrice } from '@ui/hooks/useAllUsdPrices';
import { useSupplyCapsDataForAsset } from '@ui/hooks/fuse/useSupplyCapsDataForPool';
-import BorrowAmount from 'ui/app/_components/markets/BorrowAmount';
+import BorrowAmount from '@ui/app/_components/markets/BorrowAmount';
// import { useBorrowAPYs } from '@ui/hooks/useBorrowAPYs';
// import { useSupplyAPYs } from '@ui/hooks/useSupplyAPYs';
diff --git a/packages/ui/app/market/page.tsx b/packages/ui/app/market/page.tsx
index d8020c5e73..38d26d3168 100644
--- a/packages/ui/app/market/page.tsx
+++ b/packages/ui/app/market/page.tsx
@@ -141,10 +141,20 @@ export default function Market() {
{/* //............................................ */}
-
+
import('../_components/xION/TxPopup'), {
ssr: false
});
diff --git a/packages/ui/components.json b/packages/ui/components.json
new file mode 100644
index 0000000000..3cce526aeb
--- /dev/null
+++ b/packages/ui/components.json
@@ -0,0 +1,16 @@
+{
+ "$schema": "https://ui.shadcn.com/schema.json",
+ "style": "default",
+ "rsc": true,
+ "tsx": true,
+ "tailwind": {
+ "config": "tailwind.config.ts",
+ "css": "app/globals.css",
+ "baseColor": "slate",
+ "cssVariables": true
+ },
+ "aliases": {
+ "components": "@ui/components",
+ "utils": "@ui/lib/utils"
+ }
+}
\ No newline at end of file
diff --git a/packages/ui/components/ui/button.tsx b/packages/ui/components/ui/button.tsx
new file mode 100644
index 0000000000..7b59cd0ccb
--- /dev/null
+++ b/packages/ui/components/ui/button.tsx
@@ -0,0 +1,57 @@
+import * as React from 'react';
+
+import { Slot } from '@radix-ui/react-slot';
+import { cva, type VariantProps } from 'class-variance-authority';
+
+import { cn } from '@ui/lib/utils';
+
+const buttonVariants = cva(
+ 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-xl text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
+ {
+ variants: {
+ variant: {
+ default: 'bg-primary text-primary-foreground hover:bg-primary/90',
+ destructive:
+ 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
+ outline:
+ 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
+ secondary:
+ 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
+ ghost: 'hover:bg-accent hover:text-accent-foreground',
+ link: 'text-primary underline-offset-4 hover:underline'
+ },
+ size: {
+ default: 'h-10 px-4 py-2',
+ sm: 'h-9 rounded-xl px-3',
+ lg: 'h-11 rounded-xl px-8',
+ icon: 'h-10 w-10'
+ }
+ },
+ defaultVariants: {
+ variant: 'default',
+ size: 'default'
+ }
+ }
+);
+
+export interface ButtonProps
+ extends React.ButtonHTMLAttributes
,
+ VariantProps {
+ asChild?: boolean;
+}
+
+const Button = React.forwardRef(
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
+ const Comp = asChild ? Slot : 'button';
+ return (
+
+ );
+ }
+);
+Button.displayName = 'Button';
+
+export { Button, buttonVariants };
diff --git a/packages/ui/components/ui/tooltip.tsx b/packages/ui/components/ui/tooltip.tsx
new file mode 100644
index 0000000000..c57c81fbb9
--- /dev/null
+++ b/packages/ui/components/ui/tooltip.tsx
@@ -0,0 +1,31 @@
+'use client';
+
+import * as React from 'react';
+
+import * as TooltipPrimitive from '@radix-ui/react-tooltip';
+
+import { cn } from '@ui/lib/utils';
+
+const TooltipProvider = TooltipPrimitive.Provider;
+
+const Tooltip = TooltipPrimitive.Root;
+
+const TooltipTrigger = TooltipPrimitive.Trigger;
+
+const TooltipContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, sideOffset = 4, ...props }, ref) => (
+
+));
+TooltipContent.displayName = TooltipPrimitive.Content.displayName;
+
+export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
diff --git a/packages/ui/hooks/leverage/usePositions.ts b/packages/ui/hooks/leverage/usePositions.ts
index 9ebbcf24c9..fc1ef6fb3c 100644
--- a/packages/ui/hooks/leverage/usePositions.ts
+++ b/packages/ui/hooks/leverage/usePositions.ts
@@ -2,7 +2,7 @@ import { useQuery } from '@tanstack/react-query';
import { useMultiIonic } from '@ui/context/MultiIonicContext';
-import type { NewPosition, OpenPosition } from 'types/dist';
+import type { NewPosition, OpenPosition } from '@ionicprotocol/types';
export const usePositionsQuery = (chain: number) => {
const { address, getSdk } = useMultiIonic();
diff --git a/packages/ui/hooks/useSugarAPR.ts b/packages/ui/hooks/useSugarAPR.ts
index 0f9b938893..f4e999f740 100644
--- a/packages/ui/hooks/useSugarAPR.ts
+++ b/packages/ui/hooks/useSugarAPR.ts
@@ -2,7 +2,7 @@ import { formatEther } from 'viem';
import { mode } from 'viem/chains';
import { useReadContract } from 'wagmi';
-import { lpSugarAbi } from 'ui/app/stake/abi/lpSugar';
+import { lpSugarAbi } from '@ui/app/stake/abi/lpSugar';
import { useAllUsdPrices } from './useAllUsdPrices';
import { useIonPrice, useTokenPrice } from './useDexScreenerPrices';
diff --git a/packages/ui/lib/utils.ts b/packages/ui/lib/utils.ts
new file mode 100644
index 0000000000..2819a830d2
--- /dev/null
+++ b/packages/ui/lib/utils.ts
@@ -0,0 +1,6 @@
+import { clsx, type ClassValue } from 'clsx';
+import { twMerge } from 'tailwind-merge';
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs));
+}
diff --git a/packages/ui/package.json b/packages/ui/package.json
index 5a40476f2d..bdd184acae 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -16,6 +16,8 @@
"@lifi/sdk": "^3.3.1",
"@lifi/widget": "^3.8.2",
"@netlify/plugin-nextjs": "^5.8.1",
+ "@radix-ui/react-slot": "^1.1.0",
+ "@radix-ui/react-tooltip": "^1.1.3",
"@reown/appkit": "^1.2.0",
"@reown/appkit-adapter-wagmi": "^1.2.0",
"@sentry/nextjs": "^8.35.0",
@@ -23,6 +25,9 @@
"@tanstack/react-query": "^5.59.16",
"@wagmi/connectors": "^5.3.3",
"chart.js": "^4.4.3",
+ "class-variance-authority": "^0.7.0",
+ "clsx": "^2.1.1",
+ "lucide-react": "^0.454.0",
"mathjs": "^13.2.0",
"millify": "^6.1.0",
"next": "^14.2.5",
@@ -34,7 +39,9 @@
"react-dom": "^18.3.1",
"react-hot-toast": "^2.4.1",
"react-loader-spinner": "^6.1.6",
+ "tailwind-merge": "^2.5.4",
"tailwind-scrollbar-hide": "^1.1.7",
+ "tailwindcss-animate": "^1.0.7",
"viem": "^2.21.34",
"wagmi": "^2.12.25",
"zustand": "^4.5.4"
diff --git a/packages/ui/public/img/logo/CAMP.png b/packages/ui/public/img/logo/CAMP.png
new file mode 100644
index 0000000000..19ff7d627f
Binary files /dev/null and b/packages/ui/public/img/logo/CAMP.png differ
diff --git a/packages/ui/public/img/logo/FX.png b/packages/ui/public/img/logo/FX.png
new file mode 100644
index 0000000000..c2e78f0347
Binary files /dev/null and b/packages/ui/public/img/logo/FX.png differ
diff --git a/packages/ui/public/img/logo/INK.png b/packages/ui/public/img/logo/INK.png
new file mode 100644
index 0000000000..db0d1b01fa
Binary files /dev/null and b/packages/ui/public/img/logo/INK.png differ
diff --git a/packages/ui/public/img/logo/KROMA.png b/packages/ui/public/img/logo/KROMA.png
new file mode 100644
index 0000000000..37f73bc30b
Binary files /dev/null and b/packages/ui/public/img/logo/KROMA.png differ
diff --git a/packages/ui/public/img/logo/UNICHAIN.png b/packages/ui/public/img/logo/UNICHAIN.png
new file mode 100644
index 0000000000..6d3513a65f
Binary files /dev/null and b/packages/ui/public/img/logo/UNICHAIN.png differ
diff --git a/packages/ui/public/img/logo/WORLDCHAIN.png b/packages/ui/public/img/logo/WORLDCHAIN.png
new file mode 100644
index 0000000000..ade796d527
Binary files /dev/null and b/packages/ui/public/img/logo/WORLDCHAIN.png differ
diff --git a/packages/ui/public/img/pyth.svg b/packages/ui/public/img/pyth.svg
new file mode 100644
index 0000000000..d9ee541f47
--- /dev/null
+++ b/packages/ui/public/img/pyth.svg
@@ -0,0 +1,56 @@
+
\ No newline at end of file
diff --git a/packages/ui/store/Store.ts b/packages/ui/store/Store.ts
index 642200dba0..2b44adbca1 100644
--- a/packages/ui/store/Store.ts
+++ b/packages/ui/store/Store.ts
@@ -1,9 +1,9 @@
// import type { Dispatch, SetStateAction } from 'react';
import { create } from 'zustand';
-import type { BorrowPopoverProps } from 'ui/app/_components/markets/BorrowPopover';
-import type { SupplyPopoverProps } from 'ui/app/_components/markets/SupplyPopover';
-// import type { PopupMode } from 'ui/app/_components/popup/page';
+import type { BorrowPopoverProps } from '@ui/app/_components/markets/BorrowPopover';
+import type { SupplyPopoverProps } from '@ui/app/_components/markets/SupplyPopover';
+// import type { PopupMode } from '@ui/app/_components/popup/page';
interface IFeaturedBorrow extends BorrowPopoverProps {
// asset: string;
diff --git a/packages/ui/tailwind.config.ts b/packages/ui/tailwind.config.ts
index dbf59a162b..04c437131b 100644
--- a/packages/ui/tailwind.config.ts
+++ b/packages/ui/tailwind.config.ts
@@ -6,8 +6,8 @@ const config: Config = {
'./components/**/*.{js,ts,jsx,tsx,mdx}',
'./app/**/*.{js,ts,jsx,tsx,mdx}'
],
- darkMode: 'class',
- plugins: [require('tailwind-scrollbar-hide')],
+ darkMode: ['class', 'class'],
+ plugins: [require('tailwind-scrollbar-hide'), require('tailwindcss-animate')],
theme: {
extend: {
backgroundImage: {
@@ -20,7 +20,43 @@ const config: Config = {
darkone: '#0a0a0aff',
grayUnselect: '#2c2e33ff',
graylite: '#34363dff',
- grayone: '#212126ff'
+ grayone: '#212126ff',
+ background: 'hsl(var(--background))',
+ foreground: 'hsl(var(--foreground))',
+ card: {
+ DEFAULT: 'hsl(var(--card))',
+ foreground: 'hsl(var(--card-foreground))'
+ },
+ popover: {
+ DEFAULT: 'hsl(var(--popover))',
+ foreground: 'hsl(var(--popover-foreground))'
+ },
+ primary: {
+ DEFAULT: 'hsl(var(--primary))',
+ foreground: 'hsl(var(--primary-foreground))'
+ },
+ secondary: {
+ DEFAULT: 'hsl(var(--secondary))',
+ foreground: 'hsl(var(--secondary-foreground))'
+ },
+ muted: {
+ DEFAULT: 'hsl(var(--muted))',
+ foreground: 'hsl(var(--muted-foreground))'
+ },
+ destructive: {
+ DEFAULT: 'hsl(var(--destructive))',
+ foreground: 'hsl(var(--destructive-foreground))'
+ },
+ border: 'hsl(var(--border))',
+ input: 'hsl(var(--input))',
+ ring: 'hsl(var(--ring))',
+ chart: {
+ '1': 'hsl(var(--chart-1))',
+ '2': 'hsl(var(--chart-2))',
+ '3': 'hsl(var(--chart-3))',
+ '4': 'hsl(var(--chart-4))',
+ '5': 'hsl(var(--chart-5))'
+ }
},
fontFamily: {
inter: ['Inter', 'sans-serif']
@@ -37,6 +73,11 @@ const config: Config = {
transform: 'translateX(-100%)'
}
}
+ },
+ borderRadius: {
+ lg: 'var(--radius)',
+ md: 'calc(var(--radius) - 2px)',
+ sm: 'calc(var(--radius) - 4px)'
}
}
}
diff --git a/packages/ui/tsconfig.json b/packages/ui/tsconfig.json
index fd42cf5308..8447041315 100644
--- a/packages/ui/tsconfig.json
+++ b/packages/ui/tsconfig.json
@@ -18,8 +18,13 @@
{
"name": "next"
}
- ]
+ ],
+ "baseUrl": ".",
+ "paths": {
+ "@ui/*": ["./*"],
+ "@/app/_components/*": ["app/_components/*"]
+ }
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
-}
+}
\ No newline at end of file
diff --git a/packages/ui/utils/NetworkChecker.ts b/packages/ui/utils/NetworkChecker.ts
index 6a9b1ce4ac..38abcdae0f 100644
--- a/packages/ui/utils/NetworkChecker.ts
+++ b/packages/ui/utils/NetworkChecker.ts
@@ -1,6 +1,6 @@
import { switchChain } from '@wagmi/core';
-import { wagmiAdapter } from 'ui/app/layout';
+import { wagmiAdapter } from '@ui/app/layout';
export const handleSwitchOriginChain = async (
selectedDropdownChain: number,
diff --git a/yarn.lock b/yarn.lock
index fa61d08e36..fcbfae20f9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2211,6 +2211,8 @@ __metadata:
"@lifi/sdk": "npm:^3.3.1"
"@lifi/widget": "npm:^3.8.2"
"@netlify/plugin-nextjs": "npm:^5.8.1"
+ "@radix-ui/react-slot": "npm:^1.1.0"
+ "@radix-ui/react-tooltip": "npm:^1.1.3"
"@reown/appkit": "npm:^1.2.0"
"@reown/appkit-adapter-wagmi": "npm:^1.2.0"
"@sentry/nextjs": "npm:^8.35.0"
@@ -2222,6 +2224,8 @@ __metadata:
"@wagmi/connectors": "npm:^5.3.3"
autoprefixer: "npm:^10.4.19"
chart.js: "npm:^4.4.3"
+ class-variance-authority: "npm:^0.7.0"
+ clsx: "npm:^2.1.1"
eslint: "npm:^8"
eslint-config-next: "npm:^14.1.4"
eslint-config-prettier: "npm:^9.0.0"
@@ -2232,6 +2236,7 @@ __metadata:
eslint-plugin-sort-keys: "npm:^2.3.5"
eslint-plugin-typescript-sort-keys: "npm:^3.0.0"
eslint-plugin-unused-imports: "npm:^3.0.0"
+ lucide-react: "npm:^0.454.0"
mathjs: "npm:^13.2.0"
millify: "npm:^6.1.0"
next: "npm:^14.2.5"
@@ -2244,8 +2249,10 @@ __metadata:
react-dom: "npm:^18.3.1"
react-hot-toast: "npm:^2.4.1"
react-loader-spinner: "npm:^6.1.6"
+ tailwind-merge: "npm:^2.5.4"
tailwind-scrollbar-hide: "npm:^1.1.7"
tailwindcss: "npm:^3.4.4"
+ tailwindcss-animate: "npm:^1.0.7"
typescript: "npm:^5.5.3"
viem: "npm:^2.21.34"
wagmi: "npm:^2.12.25"
@@ -5174,6 +5181,19 @@ __metadata:
languageName: node
linkType: hard
+"@radix-ui/react-context@npm:1.1.1":
+ version: 1.1.1
+ resolution: "@radix-ui/react-context@npm:1.1.1"
+ peerDependencies:
+ "@types/react": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 10/f6469583bf11cc7bff3ea5c95c56b0774a959512adead00dc64b0527cca01b90b476ca39a64edfd7e18e428e17940aa0339116b1ce5b6e8eab513cfd1065d391
+ languageName: node
+ linkType: hard
+
"@radix-ui/react-dialog@npm:^1.0.5":
version: 1.1.1
resolution: "@radix-ui/react-dialog@npm:1.1.1"
@@ -5242,6 +5262,29 @@ __metadata:
languageName: node
linkType: hard
+"@radix-ui/react-dismissable-layer@npm:1.1.1":
+ version: 1.1.1
+ resolution: "@radix-ui/react-dismissable-layer@npm:1.1.1"
+ dependencies:
+ "@radix-ui/primitive": "npm:1.1.0"
+ "@radix-ui/react-compose-refs": "npm:1.1.0"
+ "@radix-ui/react-primitive": "npm:2.0.0"
+ "@radix-ui/react-use-callback-ref": "npm:1.1.0"
+ "@radix-ui/react-use-escape-keydown": "npm:1.1.0"
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: 10/4f2346846f15f3482b8b6cd850448838d01520366deef840d8e80f5a3443aa7f21f86bd5b9a26f2709dcf94f1ec3f2bdfe80d5c37cba504c41e487c7ff8af3de
+ languageName: node
+ linkType: hard
+
"@radix-ui/react-focus-guards@npm:1.1.0":
version: 1.1.0
resolution: "@radix-ui/react-focus-guards@npm:1.1.0"
@@ -5372,6 +5415,26 @@ __metadata:
languageName: node
linkType: hard
+"@radix-ui/react-portal@npm:1.1.2":
+ version: 1.1.2
+ resolution: "@radix-ui/react-portal@npm:1.1.2"
+ dependencies:
+ "@radix-ui/react-primitive": "npm:2.0.0"
+ "@radix-ui/react-use-layout-effect": "npm:1.1.0"
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: 10/2f737dc0445f02f512f814ba140227e1a049b3d215d79e22ead412c9befe830292c48a559a8ad1514a474ae8f0c4c43954dfbe294b93a0279d8747d08f7b7924
+ languageName: node
+ linkType: hard
+
"@radix-ui/react-presence@npm:1.1.0":
version: 1.1.0
resolution: "@radix-ui/react-presence@npm:1.1.0"
@@ -5392,6 +5455,26 @@ __metadata:
languageName: node
linkType: hard
+"@radix-ui/react-presence@npm:1.1.1":
+ version: 1.1.1
+ resolution: "@radix-ui/react-presence@npm:1.1.1"
+ dependencies:
+ "@radix-ui/react-compose-refs": "npm:1.1.0"
+ "@radix-ui/react-use-layout-effect": "npm:1.1.0"
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: 10/1ae074efae47ab52a63239a5936fddb334b2f66ed91e74bfe8b1ae591e5db01fa7e9ddb1412002cc043066d40478ba05187a27eb2684dcd68dea545993f9ee20
+ languageName: node
+ linkType: hard
+
"@radix-ui/react-primitive@npm:2.0.0":
version: 2.0.0
resolution: "@radix-ui/react-primitive@npm:2.0.0"
@@ -5504,7 +5587,7 @@ __metadata:
languageName: node
linkType: hard
-"@radix-ui/react-slot@npm:1.1.0":
+"@radix-ui/react-slot@npm:1.1.0, @radix-ui/react-slot@npm:^1.1.0":
version: 1.1.0
resolution: "@radix-ui/react-slot@npm:1.1.0"
dependencies:
@@ -5575,6 +5658,36 @@ __metadata:
languageName: node
linkType: hard
+"@radix-ui/react-tooltip@npm:^1.1.3":
+ version: 1.1.3
+ resolution: "@radix-ui/react-tooltip@npm:1.1.3"
+ dependencies:
+ "@radix-ui/primitive": "npm:1.1.0"
+ "@radix-ui/react-compose-refs": "npm:1.1.0"
+ "@radix-ui/react-context": "npm:1.1.1"
+ "@radix-ui/react-dismissable-layer": "npm:1.1.1"
+ "@radix-ui/react-id": "npm:1.1.0"
+ "@radix-ui/react-popper": "npm:1.2.0"
+ "@radix-ui/react-portal": "npm:1.1.2"
+ "@radix-ui/react-presence": "npm:1.1.1"
+ "@radix-ui/react-primitive": "npm:2.0.0"
+ "@radix-ui/react-slot": "npm:1.1.0"
+ "@radix-ui/react-use-controllable-state": "npm:1.1.0"
+ "@radix-ui/react-visually-hidden": "npm:1.1.0"
+ peerDependencies:
+ "@types/react": "*"
+ "@types/react-dom": "*"
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ "@types/react-dom":
+ optional: true
+ checksum: 10/6a0eeabee30173b3d885c12c666614d673352037c0018a57e4cf220d4da73b6ebefa8610fe26a99d83fc00672a2b7417d8dc194096dd106865de1326d8cd9166
+ languageName: node
+ linkType: hard
+
"@radix-ui/react-use-callback-ref@npm:1.1.0":
version: 1.1.0
resolution: "@radix-ui/react-use-callback-ref@npm:1.1.0"
@@ -10790,6 +10903,15 @@ __metadata:
languageName: node
linkType: hard
+"class-variance-authority@npm:^0.7.0":
+ version: 0.7.0
+ resolution: "class-variance-authority@npm:0.7.0"
+ dependencies:
+ clsx: "npm:2.0.0"
+ checksum: 10/06646e82953e577fb8834100d763f1e5ecb808b8a1fba6244e94b20603865b134ff2296e30432449793baaeb02282cce617afba6981afe18b6846f1f8e9485ca
+ languageName: node
+ linkType: hard
+
"clean-deep@npm:3.4.0":
version: 3.4.0
resolution: "clean-deep@npm:3.4.0"
@@ -10998,6 +11120,13 @@ __metadata:
languageName: node
linkType: hard
+"clsx@npm:2.0.0":
+ version: 2.0.0
+ resolution: "clsx@npm:2.0.0"
+ checksum: 10/943766d1b02fee3538c871e56638d87f973fbc2d6291ce221215ea436fdecb9be97ad323f411839c2d52c45640c449b1a53fbfe7e8b3d529b4e263308b630c9a
+ languageName: node
+ linkType: hard
+
"clsx@npm:^1.2.1":
version: 1.2.1
resolution: "clsx@npm:1.2.1"
@@ -18084,6 +18213,15 @@ __metadata:
languageName: node
linkType: hard
+"lucide-react@npm:^0.454.0":
+ version: 0.454.0
+ resolution: "lucide-react@npm:0.454.0"
+ peerDependencies:
+ react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc
+ checksum: 10/90b40271182e15fefc9cbc6aca4645a49691f73b1887daffb0c9d048f61c89a1c1d7eac1096a37ba627bdce91e8aa49fcf43a5cf0ebd255117ce848d71a56dd1
+ languageName: node
+ linkType: hard
+
"luxon@npm:^3.2.1":
version: 3.5.0
resolution: "luxon@npm:3.5.0"
@@ -23916,6 +24054,13 @@ __metadata:
languageName: node
linkType: hard
+"tailwind-merge@npm:^2.5.4":
+ version: 2.5.4
+ resolution: "tailwind-merge@npm:2.5.4"
+ checksum: 10/2bf6585a30c0ab2e4e8c4bfe0d0a14edbf8e1d88bb8ce68c79f7185e8a7e410893903a98f5819cf8843f1afbe87639e1989af28456cbb0240ddec3468f303727
+ languageName: node
+ linkType: hard
+
"tailwind-scrollbar-hide@npm:^1.1.7":
version: 1.1.7
resolution: "tailwind-scrollbar-hide@npm:1.1.7"
@@ -23923,6 +24068,15 @@ __metadata:
languageName: node
linkType: hard
+"tailwindcss-animate@npm:^1.0.7":
+ version: 1.0.7
+ resolution: "tailwindcss-animate@npm:1.0.7"
+ peerDependencies:
+ tailwindcss: "*"
+ checksum: 10/ef176fbb0bf9dca84178b35b6a9615cd756358ea80be9c575456d12ecd7f3c431e9e571915c7df72959dc798a730959e9a4739d59eab55d8cc6db390870ff0d2
+ languageName: node
+ linkType: hard
+
"tailwindcss@npm:^3.4.4":
version: 3.4.10
resolution: "tailwindcss@npm:3.4.10"